The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
SDL 2.0 and ffmpeg. How to render texture in new version.
bukka.wh


Joined: 14 Jan 2014
Posts: 10
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!
SDL 2.0 and ffmpeg. How to render texture in new version.
Gabriele Greco
Guest

Quote:


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
bukka.wh


Joined: 14 Jan 2014
Posts: 10
Gabriele Greco, thank You very much!!!! Smile
SDL 2.0 and ffmpeg. How to render texture in new version.
mehrdad_58


Joined: 27 Oct 2013
Posts: 6
Location: Tehran
Hi
Check waave project


Sent from Yahoo! Mail on Android From: bukka.wh;
To: ;
Subject: [SDL] SDL 2.0 and ffmpeg. How to render texture in new version.
Sent: Wed, Jan 15, 2014 4:17:04 PM


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!
SDL 2.0 and ffmpeg. How to render texture in new version.
mehrdad_58


Joined: 27 Oct 2013
Posts: 6
Location: Tehran
By waave project i mean
Waave.sourceforge.net
Sent from Yahoo! Mail on Android From: bukka.wh;
To: ;
Subject: [SDL] SDL 2.0 and ffmpeg. How to render texture in new version.
Sent: Wed, Jan 15, 2014 4:17:04 PM


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!
bukka.wh


Joined: 14 Jan 2014
Posts: 10
mehrdad_58, thanks!
So, I can launch it on Android? (I didn't found out how to build it on Android((((
Everytinh is not okay(((((
bukka.wh


Joined: 14 Jan 2014
Posts: 10
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.
SDL 2.0 and ffmpeg. How to render texture in new version.
mehrdad_58


Joined: 27 Oct 2013
Posts: 6
Location: Tehran
Hi bukka
Waave project is an implementation of video player by using ffmpeg and sdl
Have a look at following link:
Waave.sourceforge.net
Sent from Yahoo! Mail on Android From: bukka.wh;
To: ;
Subject: Re: [SDL] SDL 2.0 and ffmpeg. How to render texture in new version.
Sent: Sat, Jan 18, 2014 12:39:32 PM


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.