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!