2011-07-20 89 views
2

我想使用ffmpeg庫將一系列.jpg文件編碼到視頻中,並且我似乎無法獲取要編碼的幀。 (我必須使用ffmpeg庫,從命令行使用ffmpeg不是我的選擇)FFmpeg:avcodec_encode_video()和JPEG圖像

除了我試圖打開JPG文件作爲AVFrames的部分,我的代碼更多或與ffmpeg庫中的api-example.c中的相同。當我像例子一樣填充框架時,一切都按預期工作。在下面的代碼中,我無法編碼任何幀。顯然這個問題與我如何打開JPG文件有關,但我無法弄清楚是什麼。

我打開圖像是這樣的:

AVFrame* open_image(const char* imageFileName, int width, int height, long * bufSize) 
{ 
    AVFormatContext *pFormatCtx; 

    if(av_open_input_file(&pFormatCtx, imageFileName, NULL, 0, NULL)!=0) 
    { 
     printf("Can't open image file '%s'\n", imageFileName); 
     return NULL; 
    }  

    AVCodecContext *pCodecCtx; 

    pCodecCtx = pFormatCtx->streams[0]->codec; 
    pCodecCtx->width = width; 
    pCodecCtx->height = height; 
    pCodecCtx->pix_fmt = PIX_FMT_YUV420P; 

    // Find the decoder for the video stream 
    AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id); 
    if (!pCodec) 
    { 
     printf("Codec not found\n"); 
     return NULL; 
    } 

    // Open codec 
    if(avcodec_open(pCodecCtx, pCodec)<0) 
    { 
     printf("Could not open codec\n"); 
     return NULL; 
    } 

    AVFrame *pFrame = avcodec_alloc_frame(); 
    if (!pFrame) 
    { 
     LOGV(TAG, "Can't allocate memory for AVFrame\n"); 
     return NULL; 
    } 

    int frameFinished; 
    int numBytes; 

    // Determine required buffer size and allocate buffer 
    numBytes = avpicture_get_size(PIX_FMT_YUVJ420P, pCodecCtx->width, pCodecCtx->height); 

    // *** 
    *bufSize = numBytes; 
    // *** 

    uint8_t *buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t)); 

    avpicture_fill((AVPicture *) pFrame, buffer, PIX_FMT_YUVJ420P, pCodecCtx->width, pCodecCtx->height); 

    // Read frame 

    AVPacket packet; 

    int framesNumber = 0; 
    while (av_read_frame(pFormatCtx, &packet) >= 0) 
    { 
     if(packet.stream_index != 0) 
      continue; 

     int ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); 
     if (ret > 0) 
     { 
      sprintf(buf, "Frame is decoded, size %d", ret); 
      LOGV(TAG, buf); 
      pFrame->quality = 4; 
      return pFrame; 
     } 
     else { 
      // printf("Error [%d] while decoding frame: %s\n", ret, strerror(AVERROR(ret))); 
      sprintf(buf, "Error %d decoding frame: %s", ret, strerror(AVERROR(ret))); 
      LOGV(TAG, buf); 
     } 
    } 
} 

...,並試圖對其進行編碼是這樣的:

DIR * dir = opendir(path); 
int i = 0; 

if (dir != NULL) { 

    for(struct dirent *ent = readdir(dir); ent != NULL; ent = readdir(dir)) { 
     fflush(stdout); 

     printf("%s/%s", path, ent->d_name); 
     LOGV(TAG, filename); 

     // If not a jpg file, pass it over 
     const char * ext = strrchr(filename, '.'); 
     if((!ext) || (strcmp(ext, ".jpg"))) { 
      continue; 
     } 

     /*** NOTE: Is this where I've gone wrong? Bufsize is set in open_image based on av_picture_size() */ 
     long bufSize = 0L; 
     AVFrame * frame = open_image(filename, width, height, &bufSize); 
     if(frame) { 
      // This is what it needs to do, and it does not work. 
      // Causes: 
      // Wrong format? 
      // Wrong buffer size? 
      uint8_t * picBuf = (uint8_t *)malloc(bufSize); 

      out_size = avcodec_encode_video(c, picBuf, bufSize, frame); 

      printf("encoding frame %3d (size=%5d)\n", i++, out_size); 
      /** On the first image, out_size is 0. On the next, it's -1, and fails. */ 

      if(out_size < 0) { 
       printf("Error encoding frame"); 
       return -6; 
      } 

      fwrite(picBuf, 1, bufSize, f); 

      free(picBuf); 
      av_free(frame); 
     } 
     else { 
      printf("Couldn't open image"); 
      return -5; 
     } 
    } 

    closedir(dir); 
} 
else { 
    printf("Couldn't open directory %s\n", path); 
    return -4; 
} 

有人能指出我在正確的方向?

回答

1

你得到的錯誤究竟是什麼?在打開編碼環境以查看其支持的像素格式後,檢查編碼環境,您可能必須使用sws_scale轉換爲編碼器支持的格式。