SDL 2.0 and ffmpeg. How to render texture in new version

Hi!
I am trying to create videoplayer using SDL. I have decoded video stream with ffmpeg and I want to render decoded packages into SDLTexture.
All tutorials of how to do this are based on older version of SDL - 1.2. In SDL 2.0 SDL_Overlay is not present. Instead, as I have understood, we should use SDLTexture. I have read libSDL Wikia, tried to change my code to new version, but have no succes. Please, help me! Here is code for version 1.2

Code:
SDL_Overlay* bmp = SDL_CreateYUVOverlay(codec_context->width, codec_context->height, SDL_YV12_OVERLAY, screen);
struct SwsContext* img_convert_context;
img_convert_context = sws_getCachedContext(NULL,
codec_context->width, codec_context->height,
codec_context->pix_fmt,
codec_context->width, codec_context->height,
PIX_FMT_YUV420P, SWS_BICUBIC,
NULL, NULL, NULL);
if (img_convert_context == NULL)
{
fprintf(stderr, “Cannot initialize the conversion context\n”);
return -1;
}

AVFrame* frame = avcodec_alloc_frame();
AVPacket packet;
while (av_read_frame(format_context, &packet) >= 0) {
if (packet.stream_index == video_stream)
{
// Video stream packet
int frame_finished;
avcodec_decode_video2(codec_context, frame, &frame_finished, &packet);
if (frame_finished)
{
SDL_LockYUVOverlay(bmp);

            // Convert frame to YV12 pixel format for display in SDL overlay
           
            AVPicture pict;
            pict.data[0] = bmp->pixels[0];
            pict.data[1] = bmp->pixels[2];  // it's because YV12
            pict.data[2] = bmp->pixels[1];
           
            pict.linesize[0] = bmp->pitches[0];
            pict.linesize[1] = bmp->pitches[2];
            pict.linesize[2] = bmp->pitches[1];
           
            sws_scale(img_convert_context,
                                    frame->data, frame->linesize,
                                    0, codec_context->height,
                                    pict.data, pict.linesize);
           
            SDL_UnlockYUVOverlay(bmp);
           
            SDL_Rect rect;
            rect.x = 0;
            rect.y = 0;
            rect.w = codec_context->width;
            rect.h = codec_context->height;
            SDL_DisplayYUVOverlay(bmp, &rect);
    }

}

// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);

And here is my edited code, but nothing is working

Code:

// Create wndow
SDL_Window *window = SDL_CreateWindow(
“YUV speed test”,
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
codec_context->width, codec_context->height,
SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE);

// Create renderer
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);

// Create texture
SDL_Texture* bmp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12,SDL_TEXTUREACCESS_STREAMING, codec_context->width, codec_context->height);
// Create context fo pixel conver
struct SwsContext* img_convert_context;
img_convert_context = sws_getCachedContext(
NULL,
codec_context->width, codec_context->height,
codec_context->pix_fmt,
codec_context->width, codec_context->height,
PIX_FMT_YUV420P, SWS_BICUBIC,
NULL, NULL, NULL);
AVFrame* frame = avcodec_alloc_frame();
AVPacket packet;
while (av_read_frame(format_context, &packet) >= 0)
{
if (packet.stream_index == video_stream)
{
// Video stream packet
int frame_finished;
avcodec_decode_video2(codec_context, frame, &frame_finished, &packet);

if (frame_finished)
{
	AVPicture pict;
	// Lock my texture
	SDL_LockTexture(bmp, NULL, pict.data,  pict.linesize);


	sws_scale(img_convert_context,
		frame->data, frame->linesize,
		0, codec_context->height,
		pict.data, pict.linesize);
	SDL_UnlockTexture(bmp);
	SDL_Rect rect;
	rect.x = 0;
	rect.y = 0;
	rect.w = codec_context->width;
	rect.h = codec_context->height;
	// Draw texture
	SDL_UpdateTexture(bmp,&rect,pict.data,  pict.linesize);
}

}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);

THANKS!

And here is my edited code, but nothing is working

I hope you are using SDL 2.0.1+ since it gives you an addictional function
very helpful to avoid an unneeded data copy every frame,
SDL_UpdateYUVTexture.

You don’t need texture streaming access, and you can get rid of sws scale
except if you want to apply particular effects to the texture

So, create your texture with:

SDL_Texture* bmp = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_YV12,SDL_TEXTUREACCESS_STATIC codec_context->width,
codec_context->height);

After:
avcodec_decode_video2(codec_context, frame, &frame_finished, &packet);

if (frame_finished) {
SDL_UpdateYUVTexture(bmp, NULL, frame->data[0], frame->linesize[0],
frame->data[1], frame->linesize[1],
frame->data[2], frame->linesize[2]);
}

Then in a timely synchronized way you have to display it (assuming the
window is the right size):

SDL_RenderCopy(renderer, bmp, NULL, NULL);
SDL_RenderPresent(renderer);–
Bye,
Gabry

Gabriele Greco, thank You very much!!! :slight_smile:

Hi
Check waave projectSent from Yahoo! Mail on Android

By waave project i mean
Waave.sourceforge.netSent from Yahoo! Mail on Android

mehrdad_58, thanks!
So, I can launch it on Android? (I didn’t found out how to build it on Android((((

When I am trying to use SDL_UpdateYUVTexture I got error:
error: undefined reference to ‘SDL_UpdateYUVTexture’.

I am creating video player for Android, use SDL 2.0.1. I am working in Eclipse.

Hi bukka
Waave project is an implementation? of video player by using ffmpeg? and sdl

Have a look at following link:

Waave.sourceforge.netSent from Yahoo! Mail on Android