AVFrame and SDL2 for screen capture - c

In that last question, I realized I cannot use both SDL and SDL2. Definitely I choose SDL2 over its precedent.
I had written the following code to capture screen and convert it to an AVFrame for video creation:
AVFrame *frame = av_frame_alloc();
...
SDL_Surface *screen = SDL_SetVideoMode(width,height, 0, 0);
SDL_Overlay *bmp = SDL_CreateYUVOverlay(width,height, SDL_YV12_OVERLAY, screen);
if(av_frame_make_writable(frame) < 0)
exit(1);
SDL_LockYUVOverlay(bmp);
memcpy(frame->data[0], bmp->pixels[0], bmp->pitches[0]);
memcpy(frame->data[1], bmp->pixels[1], bmp->pitches[1]);
memcpy(frame->data[2], bmp->pixels[2], bmp->pitches[2]);
SDL_UnlockYUVOverlay(bmp);
The problem is that SDL2 does not support SDL_Overlay. The alternative methods are good for playing a video not capturing it. How should I modify this code to replace SDL_Overlay and make it suitable for SDL2?

Related

What is a simple example of using Pango to render text into an image using a FreeType font?

I want to render text using Pango, but I can't find example code that does not use Cairo. Can someone give me a simple example of Pango usage with a FreeType backend? This is how I think it should roughly work, but as you can see in the code, there are some things I don't understand yet.
// context and font stuff
PangoFontMap *fontmap = pango_ft2_font_map_new();
// do I have to initialize the fontmap?
PangoContext *context = pango_font_map_create_context(fontmap);
PangoFontDescription *desc = pango_font_description_new();
pango_font_description_set_style(desc, PANGO_STYLE_NORMAL); // not bold or italic
pango_font_description_set_size(desc, 12); // 12pt font
PangoFont *font = pango_context_load_font(context, desc);
// target bitmap
FT_Bitmap bitmap;
// how do I say how big the bitmap should be? write it into the struct?
FT_Bitmap_New(&bitmap);
// text
char *text = "Hello World";
PangoAttrList *attrs = pango_attr_list_new();
GList *items = pango_itemize(context, text, 0, strlen(text), attrs, NULL);
// do I have to initialize this?
PangoGlyphString *glyphs = pango_glyph_string_new();
pango_shape(text, strlen(text),
/* PangoAnalysis here – where do I get that? */, glyphs);
pango_ft2_render(&bitmap, font, PangoGlyphString *glyphs,
0, 0/*or does this have to be height-1?*/);
I'd take a look at the source code of pango-view, the "toy" app included in pango to demonstrate its capabilities. It can render in all pango modes
pango text-rendering

How to replace GDK_INCLUDE_INFERIORS?

Since most of the gdk_gc_* methods are deprecated in GTK+ 3, how does one paint on sub-windows using Cairo only? Below is a simple example of what I would like to achieve:
GdkWindow *tl_window = parent_widget->window;
GdkGC *gc = gdk_gc_new(tl_window1->window);
gdk_gc_set_subwindow(gc, GDK_INCLUDE_INFERIORS);
gdk_gc_set_exposures(gc, FALSE);
do_my_painting(tl_window, gc);
gdk_gc_unref(gc);
http://developer.gnome.org/gdk/stable/gdk-Graphics-Contexts.html#gdk-gc-set-subwindow says GDK_INCLUDE_INFERIORS will be used on sources. So I assume the trick is to create a source of the window and then ... well then ... I'm stuck.
Found a solution myself
GtkWidget *tl_window = gtk_widget_get_toplevel(widget);
cairo_t *cairo = gdk_cairo_create(gtk_widget_get_window(tl_window));
cairo_surface_t *source_surface = cairo_get_target(cairo);
cairo_t *cairo_new = cairo_create(source_surface);
cairo_set_source_surface(cairo, cairo_get_target(cairo_new), 0, 0);
do_my_painting(cairo_new);
cairo_paint(cairo);
cairo_destroy(cairo);
(do I mis a destroy of cairo_new here ?)
I also found the next link (did not test it) http://mail.gnome.org/archives/commits-list/2010-August/msg03385.html where they seem to use a pixmap instead of a surface.

Can't set video mode for SDL screen on embedded device

I've been hacking away on an ARM based device (Freescale i.MX27 ADS) with a built-in screen for the past few days. The device is running a modified, minimal GNU/Linux system, with no window management or graphical server. By default, the device is only supposed to run the one application that came with it.
I've never done any graphical programming before, so this is a learning experience for me. I tried writing a simple SDL program to run on the device, which would read a bitmap, and display the image on the embedded device's screen.
The problem I'm having is that no matter what resolution, depth, or flags I try, the video mode always fails to apply, and I get nothing.
I know my code isn't the problem, but I'm going to post it anyway.
#include "SDL/SDL.h"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_DEPTH 24
int main(int argc, char *argv[])
{
SDL_Surface *screen;
if(!SDL_Init(SDL_INIT_VIDEO))
{
printf("Unable to initialize SDL.\n");
return 1;
}
// It always fails right here
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, SDL_SWSURFACE);
if(screen == NULL)
{
printf("Unable to set video mode.\n");
return 1;
}
SDL_Surface* image;
SDL_Surface* temp;
temp = SDL_LoadBMP("hello.bmp");
if(temp == NULL)
{
printf("Unable to load bitmap.\n");
return 1;
}
image = SDL_DisplayFormat(temp);
SDL_FreeSurface(temp);
SDL_Rect src, dest;
src.x = 0;
src.y = 0;
src.w = image->w;
src.h = image->h;
dest.x = 100;
dest.y = 100;
dest.w = image->w;
dest.h = image->h;
SDL_BlitSurface(image, &src, screen, &dest);
printf("Program finished.\n\n");
return 0;
}
From what I can tell, the application that's supposed to run on this device uses Qtopia. Again, I'm new to graphics programming, so I have no idea how one should control graphical output in an embedded environment like this.
Any ideas?
My code was hiding the fact that the problem was with initializing SDL, not setting the video mode. SDL wasn't initializing because my embedded system has no X server, and no mouse. After setting SDL_NOMOUSE, the problem was resolved.

Are 2 simultaneous webcam windows possible with openCV?

I am applying common image transforms to my live webcam capture. I want to display the original webcam in one window and the image with the transforms applied to in another window. However, I am getting same image (filtered) on both windows, I am wondering if I am limited by the OpenCV API or if I am missing something? My code snippet looks like -
/* allocate resources */
cvNamedWindow("Original", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Filtered", CV_WINDOW_AUTOSIZE);
CvCapture* capture = cvCaptureFromCAM(0);
do {
IplImage* img = cvQueryFrame(capture);
cvShowImage("Original", img);
Filters* filters = new Filters(img);
IplImage* dst = filters->doSobel();
cvShowImage("Filtered", dst);
cvWaitKey(10);
} while (1);
/* deallocate resources */
cvDestroyWindow("Original");
cvDestroyWindow("Filtered");
cvReleaseCapture(&capture);
Its possible! Try copying img to another IplImage before sending it to processing and see if that works first.
Yes, I know what you're going to say. But just try that first and see if it does what you want. The code below is just to illustrate what you should do, I don't know if it will work:
/* allocate resources */
cvNamedWindow("Original", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Filtered", CV_WINDOW_AUTOSIZE);
CvCapture* capture = cvCaptureFromCAM(0);
do {
IplImage* img = cvQueryFrame(capture);
cvShowImage("Original", img);
IplImage* img_cpy = cvCreateImage(cvGetSize(img), 8, 3);
img_cpy = cvCloneImage(img);
Filters* filters = new Filters(img_cpy);
IplImage* dst = filters->doSobel();
cvShowImage("Filtered", dst);
/* Be aware that if you release img_cpy here it might not display
* the data on the window. On the other hand, not doing it now will
* cause a memory leak.
*/
//cvReleaseImage( &img_cpy );
cvWaitKey(10);
} while (1);
/* deallocate resources */
cvDestroyWindow("Original");
cvDestroyWindow("Filtered");
cvReleaseCapture(&capture);

How to stretch a bitmap in C and SDL?

I am making a game for my CS class and the sprites I have found online are too small. How do you 'stretch' a bitmap... make them bigger using SDL? (I need to increase there size 50%, there all the same size.) A snippet of example code would be appreciated.
This question does not specify SDL version, and even though SDL2 was not available when the question was written, an SDL2 answer would add completeness here i believe.
Unlike SDL1.2, scaling is possible in SDL2 using the API method SDL_RenderCopyEx. No additional libs besides the basic SDL2 lib are needed.
int SDL_RenderCopyEx(SDL_Renderer* renderer,
SDL_Texture* texture,
const SDL_Rect* srcrect,
const SDL_Rect* dstrect,
const double angle,
const SDL_Point* center,
const SDL_RendererFlip flip)
By setting the size of dstrect one can scale the texture to an integer number of pixels. It is also possible to rotate and flip the texture at the same time.
Reference: https://wiki.libsdl.org/SDL_RenderCopyEx
Create your textures as usual:
surface = IMG_Load(filePath);
texture = SDL_CreateTextureFromSurface(renderer, surface);
And when it's time to render it, call SDL_RenderCopyEx instead of SDL_RenderCopy
You're going to get a better looking result using software that is designed for this task. A good option is ImageMagick. It can be used from the command line or programatically.
For example, from the command line you just enter:
convert sprite.bmp -resize 150% bigsprite.bmp
If for some strange reason you want to write your own bilinear resize, this guy looks like he knows what he is doing.
have you tried?
SDL_Rect src, dest;
src.x = 0;
src.y = 0;
src.w = image->w;
src.h = image->h;
dest.x = 100;
dest.y = 100;
dest.w = image->w*1.5;
dest.h = image->h*1.5;
SDL_BlitSurface(image, &src, screen, &dest);
Use for stretch the undocumented function of SDL:
extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect,
SDL_Surface *dst, SDL_Rect *dstrect);
Like:
SDL_SoftStretch(image, &src, screen, &dest);

Resources