SDL2.0 Alternative for SDL_Overlay

匿名 (未验证) 提交于 2019-12-03 01:55:01

问题:

So I've been trying to go through the following tutorial on ffmpeg: http://dranger.com/ffmpeg/tutorial02.html

However, when I try to compile using gcc, I get the following output:

root:/Users/mbrodeur/Downloads/HACKATHON CONTENT/Tutorials-> gcc -o tutorial02 tutorial02.c -lavutil -lavformat -lavcodec -lz -lavutil -lm -lswscale -D_THREAD_SAFE -lSDL2 tutorial02.c: In function main’: tutorial02.c:41: error: SDL_Overlay undeclared (first use in this function) tutorial02.c:41: error: (Each undeclared identifier is reported only once tutorial02.c:41: error: for each function it appears in.) tutorial02.c:41: error: bmp undeclared (first use in this function) tutorial02.c:98: warning: assignment makes pointer from integer without a cast tutorial02.c:110: error: SDL_YV12_OVERLAY undeclared (first use in this function)

Now, I read that SDL_Overlay is no longer used in SDL2, so therein lies the problem. I've been poking around, but can't seem to find anything helpful. Is there a replacement for SDL_Overlay? Is it necessary?

SDL_Overlay is used in the following context:

SDL_Overlay     *bmp; bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,                        SDL_YV12_OVERLAY, screen);

回答1:

Try SDL_CreateTexture() with a YUV pixel format that matches the layout and planar-ity of your decoded frames.

Or use libswscale to convert ffmpeg's YUV buffers to RGB.

EDIT: SDL2 >= 2.0.1 has SDL_UpdateYUVTexture() for updating planar YUV textures so you don't have to manually coalesce libav's buffers any more.



回答2:

I have updated the tutorial to work with SDL 2.0.1. It replaces SDL_Overlay with SDL_Texture in YV12 format.

int main(int argc, char *argv[]) {     AVFormatContext *pFormatCtx = NULL;     int videoStream;     unsigned i;     AVCodecContext *pCodecCtxOrig = NULL;     AVCodecContext *pCodecCtx = NULL;     AVCodec *pCodec = NULL;     AVFrame *pFrame = NULL;     AVPacket packet;     int frameFinished;     struct SwsContext *sws_ctx = NULL;     SDL_Event event;     SDL_Window *screen;     SDL_Renderer *renderer;     SDL_Texture *texture;     Uint8 *yPlane, *uPlane, *vPlane;     size_t yPlaneSz, uvPlaneSz;     int uvPitch;      if (argc \n");         exit(1);     }     // Register all formats and codecs     av_register_all();      if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());         exit(1);     }      // Open video file     if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0)         return -1; // Couldn't open file      // Retrieve stream information     if (avformat_find_stream_info(pFormatCtx, NULL) nb_streams; i++)         if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {             videoStream = i;             break;         }     if (videoStream == -1)         return -1; // Didn't find a video stream      // Get a pointer to the codec context for the video stream     pCodecCtxOrig = pFormatCtx->streams[videoStream]->codec;     // Find the decoder for the video stream     pCodec = avcodec_find_decoder(pCodecCtxOrig->codec_id);     if (pCodec == NULL) {         fprintf(stderr, "Unsupported codec!\n");         return -1; // Codec not found     }      // Copy context     pCodecCtx = avcodec_alloc_context3(pCodec);     if (avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) {         fprintf(stderr, "Couldn't copy codec context");         return -1; // Error copying codec context     }      // Open codec     if (avcodec_open2(pCodecCtx, pCodec, NULL) width,             pCodecCtx->height,             0         );      if (!screen) {         fprintf(stderr, "SDL: could not create window - exiting\n");         exit(1);     }      renderer = SDL_CreateRenderer(screen, -1, 0);     if (!renderer) {         fprintf(stderr, "SDL: could not create renderer - exiting\n");         exit(1);     }      // Allocate a place to put our YUV image on that screen     texture = SDL_CreateTexture(             renderer,             SDL_PIXELFORMAT_YV12,             SDL_TEXTUREACCESS_STREAMING,             pCodecCtx->width,             pCodecCtx->height         );     if (!texture) {         fprintf(stderr, "SDL: could not create texture - exiting\n");         exit(1);     }      // initialize SWS context for software scaling     sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,             pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,             PIX_FMT_YUV420P,             SWS_BILINEAR,             NULL,             NULL,             NULL);      // set up YV12 pixel array (12 bits per pixel)     yPlaneSz = pCodecCtx->width * pCodecCtx->height;     uvPlaneSz = pCodecCtx->width * pCodecCtx->height / 4;     yPlane = (Uint8*)malloc(yPlaneSz);     uPlane = (Uint8*)malloc(uvPlaneSz);     vPlane = (Uint8*)malloc(uvPlaneSz);     if (!yPlane || !uPlane || !vPlane) {         fprintf(stderr, "Could not allocate pixel buffers - exiting\n");         exit(1);     }      uvPitch = pCodecCtx->width / 2;     while (av_read_frame(pFormatCtx, &packet) >= 0) {         // Is this a packet from the video stream?         if (packet.stream_index == videoStream) {             // Decode video frame             avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);              // Did we get a video frame?             if (frameFinished) {                 AVPicture pict;                 pict.data[0] = yPlane;                 pict.data[1] = uPlane;                 pict.data[2] = vPlane;                 pict.linesize[0] = pCodecCtx->width;                 pict.linesize[1] = uvPitch;                 pict.linesize[2] = uvPitch;                  // Convert the image into YUV format that SDL uses                 sws_scale(sws_ctx, (uint8_t const * const *) pFrame->data,                         pFrame->linesize, 0, pCodecCtx->height, pict.data,                         pict.linesize);                  SDL_UpdateYUVTexture(                         texture,                         NULL,                         yPlane,                         pCodecCtx->width,                         uPlane,                         uvPitch,                         vPlane,                         uvPitch                     );                  SDL_RenderClear(renderer);                 SDL_RenderCopy(renderer, texture, NULL, NULL);                 SDL_RenderPresent(renderer);              }         }          // Free the packet that was allocated by av_read_frame         av_free_packet(&packet);         SDL_PollEvent(&event);         switch (event.type) {         case SDL_QUIT:             SDL_DestroyTexture(texture);             SDL_DestroyRenderer(renderer);             SDL_DestroyWindow(screen);             SDL_Quit();             exit(0);             break;         default:             break;         }      }      // Free the YUV frame     av_frame_free(&pFrame);     free(yPlane);     free(uPlane);     free(vPlane);      // Close the codec     avcodec_close(pCodecCtx);     avcodec_close(pCodecCtxOrig);      // Close the video file     avformat_close_input(&pFormatCtx);      return 0; }


回答3:

I got this problem too. I used SDL 1.2 since I didn't know how to replace SDL_Overlay in SDL2.0. If you are on Mac 10.10, you can use this patch http://www.emaculation.com/doku.php/compiling_sheepshaver_basilisk#tidbits

patch Then in /src/video/x11/SDL_x11sym.h, replace line 168 and 169 to this

SDL_X11_SYM(int,_XData32,(Display *dpy,register _Xconst long *data,unsigned len),(dpy,data,len),return) SDL_X11_SYM(void,_XRead32,(Display *dpy,register long *data,long len),(dpy,data,len), return)

It worked with me.



回答4:

The tutorial https://github.com/chelyaev/ffmpeg-tutorial links against SDL1 http://www.libsdl.org/download-1.2.php and they should have mentioned it(or they did and I haven't seen it).All works perfectly with SDL1.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!