2013-07-10 51 views
11

Vì vậy, tôi đã cố gắng để đi qua các hướng dẫn sau trên ffmpeg: http://dranger.com/ffmpeg/tutorial02.htmlSDL2.0 Alternative cho SDL_Overlay

Tuy nhiên, khi tôi cố gắng biên dịch sử dụng gcc, tôi nhận được kết quả như sau:

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) 

Bây giờ, tôi đọc rằng SDL_Overlay không còn được sử dụng trong SDL2 nữa, do đó, nó nằm trong vấn đề. Tôi đã poking xung quanh, nhưng dường như không thể tìm thấy bất cứ điều gì hữu ích. Có thay thế cho SDL_Overlay không? Có cần thiết không?

SDL_Overlay được sử dụng trong bối cảnh sau đây:

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

Không liên quan, nhưng bạn có thể muốn xem phiên bản [cập nhật mã nguồn] (https://github.com/chelyaev/ffmpeg-tutorial) của hướng dẫn. – LordNeckbeard

+0

Cảm ơn, tôi không biết trang đó đã tồn tại. Thật không may, nguồn cập nhật vẫn không giải quyết được vấn đề của tôi. – Josh

+1

Bạn có arround cập nhật các hướng dẫn và nhận được mã để làm việc với sdl2? Nếu vậy bạn có thể chia sẻ? Cảm ơn trước. : D – jofra

Trả lời

5

Hãy thử SDL_CreateTexture() với một định dạng pixel YUV phù hợp với cách bố trí và phẳng-ity của khung giải mã của bạn.

Hoặc sử dụng libswscale để chuyển đổi bộ đệm YUV của ffmpeg thành RGB.

EDIT: SDL2> = 2.0.1 có SDL_UpdateYUVTexture() để cập nhật kết cấu YUV phẳng, do đó bạn không cần phải bằng tay kết thành một khối đệm libav 's nữa.

+0

"Đây là một chức năng khá chậm, được thiết kế để sử dụng với kết cấu tĩnh". Có vẻ như không phù hợp với video? –

+0

@MikeVersteeg: Bạn đang đọc cái đó ở đâu? – genpfault

+0

Trong SDL_UpdateTexture (https://wiki.libsdl.org/SDL_UpdateTexture), được liên kết đến từ liên kết của bạn ở trên (mà tôi giả định có nghĩa là nó có nguồn gốc từ SDL_UpdateTexture). Tôi mới tham gia OpenGL nhưng nghĩ rằng viết văn bản là một trong những cách nhanh nhất, vì vậy tôi ngạc nhiên như bạn .. Có lẽ việc thực hiện SDL là chậm trong chính nó? Không có vấn đề gì, điều này không có vẻ giống như câu trả lời đúng cho câu hỏi như tôi giả định OP muốn hiển thị video. –

1

Tôi cũng gặp sự cố này. Tôi đã sử dụng SDL 1.2 vì tôi không biết cách thay thế SDL_Overlay trong SDL2.0. Nếu bạn đang ở trên máy Mac 10.10, bạn có thể sử dụng bản vá này http://www.emaculation.com/doku.php/compiling_sheepshaver_basilisk#tidbits

patch < no-CGDirectPaletteRef.patch Sau đó, trong /src/video/x11/SDL_x11sym.h, thay thế dòng 168 và 169 này

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)

Nó đã làm việc với tôi.

14

Tôi đã cập nhật hướng dẫn để làm việc với SDL 2.0.1. Nó thay thế SDL_Overlay bằng SDL_Texture ở định dạng YV12.

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 < 2) { 
     fprintf(stderr, "Usage: test <file>\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) < 0) 
     return -1; // Couldn't find stream information 

    // Dump information about file onto standard error 
    av_dump_format(pFormatCtx, 0, argv[1], 0); 

    // Find the first video stream 
    videoStream = -1; 
    for (i = 0; i < pFormatCtx->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) < 0) 
     return -1; // Could not open codec 

    // Allocate video frame 
    pFrame = av_frame_alloc(); 

    // Make a screen to put our video 
    screen = SDL_CreateWindow(
      "FFmpeg Tutorial", 
      SDL_WINDOWPOS_UNDEFINED, 
      SDL_WINDOWPOS_UNDEFINED, 
      pCodecCtx->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; 
} 
+1

Bạn đã cập nhật các hướng dẫn khác chưa? Chia sẻ tâm trí? Tôi đang sử dụng SDL 2.0, vì tôi không thể tìm thấy cần thiết bao gồm trên 1.2 tệp tải xuống. 1 cho nỗ lực. –