SDL 2.0 and ffmpeg. How to render texture in new version. |
SDL 2.0 and ffmpeg. How to render texture in new version. |
Gabriele Greco
Guest
|
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
|
Gabriele Greco, thank You very much!!!!
|
|||||||||||
|
SDL 2.0 and ffmpeg. How to render texture in new version. |
mehrdad_58
|
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
|
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
|
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
|
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
|
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. |
|||||||||||
|