ffmpeg - 当我用 ffmpeg 解码 h264 720p 时输出黑色

标签 ffmpeg decode h.264

首先,对不起我的英语。当我在 ardrone2.0 中解码 h264 720p 时,我的输出是黑色的,我什么都看不到。

我尝试更改 pCodecCtx->pix_fmt = AV_PIX_FMT_BGR24; 的值至pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;pCodecCtxH264->pix_fmt = AV_PIX_FMT_BGR24; 的值至pCodecCtxH264->pix_fmt = AV_PIX_FMT_YUV420P;但我的程序崩溃了。我究竟做错了什么?。谢谢,请看我的部分代码:

av_register_all();
avcodec_register_all();
avformat_network_init();

// 1.2. Open video file
if(avformat_open_input(&pFormatCtx, drone_addr, NULL, NULL) != 0) {
  mexPrintf("No conecct with Drone");
  EndVideo();
  return;
}

pCodec    = avcodec_find_decoder(AV_CODEC_ID_H264);

pCodecCtx = avcodec_alloc_context3(pCodec);
pCodecCtx->pix_fmt = AV_PIX_FMT_BGR24;
pCodecCtx->skip_frame = AVDISCARD_DEFAULT;
pCodecCtx->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
pCodecCtx->err_recognition = AV_EF_CAREFUL;
pCodecCtx->skip_loop_filter = AVDISCARD_DEFAULT;
pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCtx->codec_id = AV_CODEC_ID_H264;
pCodecCtx->skip_idct = AVDISCARD_DEFAULT;
pCodecCtx->width = 1280;
pCodecCtx->height = 720;

pCodecH264 = avcodec_find_decoder(AV_CODEC_ID_H264);
pCodecCtxH264 = avcodec_alloc_context3(pCodecH264);


pCodecCtxH264->pix_fmt = AV_PIX_FMT_BGR24;
pCodecCtxH264->skip_frame = AVDISCARD_DEFAULT;
pCodecCtxH264->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
pCodecCtxH264->err_recognition = AV_EF_CAREFUL;
pCodecCtxH264->skip_loop_filter = AVDISCARD_DEFAULT;
pCodecCtxH264->workaround_bugs = FF_BUG_AUTODETECT;
pCodecCtxH264->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCtxH264->codec_id = AV_CODEC_ID_H264;
pCodecCtxH264->skip_idct = AVDISCARD_DEFAULT;

if(avcodec_open2(pCodecCtxH264, pCodecH264, &optionsDict) < 0)
{
   mexPrintf("Error opening H264 codec");
   return ;
}

pFrame_BGR24 = av_frame_alloc();


if(pFrame_BGR24 == NULL) {
   mexPrintf("Could not allocate pFrame_BGR24\n");
   return ;
}

// Determine required buffer size and allocate buffer

buffer_BGR24 = 
(uint8_t *)av_mallocz(av_image_get_buffer_size(AV_PIX_FMT_BGR24, 
pCodecCtx->width, ((pCodecCtx->height == 720) ? 720 : pCodecCtx->height) * 
sizeof(uint8_t)*3,1));

// Assign buffer to image planes

av_image_fill_arrays(pFrame_BGR24->data, pFrame_BGR24->linesize,
buffer_BGR24,AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height,1);

// format conversion context
pConvertCtx_BGR24 = sws_getContext(pCodecCtx->width, pCodecCtx->height, 
pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,  AV_PIX_FMT_BGR24, 
                                 SWS_BILINEAR | SWS_ACCURATE_RND, 0, 0, 0);

// 1.6. get video frames
pFrame = av_frame_alloc();

av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
}

//Captura un frame
void video::capture(mxArray *plhs[]) {

  if(av_read_frame(pFormatCtx, &packet) < 0){
      mexPrintf("Error al leer frame");
      return;
  }
   do {
       do {
          rest = avcodec_send_packet(pCodecCtxH264, &packet);
       } while(rest == AVERROR(EAGAIN));

       if(rest == AVERROR_EOF || rest == AVERROR(EINVAL)) {
                printf("AVERROR(EAGAIN): %d, AVERROR_EOF: %d, 
                AVERROR(EINVAL): %d\n", AVERROR(EAGAIN), AVERROR_EOF, 
                AVERROR(EINVAL));
            printf("fe_read_frame: Frame getting error (%d)!\n", rest);
            return;
       }

       rest = avcodec_receive_frame(pCodecCtxH264, pFrame);
   } while(rest == AVERROR(EAGAIN));

   if(rest == AVERROR_EOF || rest == AVERROR(EINVAL)) {

    // An error or EOF occured,index break out and return what
    // we have so far.
      printf("AVERROR(EAGAIN): %d, AVERROR_EOF: %d, AVERROR(EINVAL): %d\n", 
      AVERROR(EAGAIN), AVERROR_EOF, AVERROR(EINVAL));
        printf("fe_read_frame: EOF or some othere decoding error (%d)!\n", 
        rest);
        return;
   }


   // 2.1.1. convert frame to GRAYSCALE [or BGR] for OpenCV
   sws_scale(pConvertCtx_BGR24,   (const uint8_t* const*)pFrame->data, 
       pFrame->linesize, 0,pCodecCtx->height,   pFrame_BGR24->data,   
             pFrame_BGR24->linesize);
//}
   av_packet_unref(&packet);
   av_init_packet(&packet);
   mwSize dims[] = {(pCodecCtx->width)*((pCodecCtx->height == 720) ? 720 : 
   pCodecCtx->height)*sizeof(uint8_t)*3};
   plhs[0] = mxCreateNumericArray(1,dims,mxUINT8_CLASS, mxREAL);
    //plhs[0]=mxCreateDoubleMatrix(pCodecCtx->height,pCodecCtx-
    >width,mxREAL);
   point=mxGetPr(plhs[0]);
   memcpy(point, pFrame_BGR24->data[0],(pCodecCtx->width)*(pCodecCtx-
    >height)*sizeof(uint8_t)*3);
}

最佳答案

转到调试器并查看您的 memcpy。我不确定它是否适用于您想要的所有尺寸。此外,可能还有更多的内存问题。例如,尝试查看 buffer_BGR24 和 pFrame 的值是多少。我敢打赌,有时它们不会返回正确的值。在代码中检查它们。

关于ffmpeg - 当我用 ffmpeg 解码 h264 720p 时输出黑色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47652575/

相关文章:

ffmpeg。输入过程结束时出现段错误

c - 不兼容的指针类型错误、sws_scale、ffmpeg

json - 无法从JSON解码int字段

perl - 在perl中转换jis解码/编码

video - 使用 FPGA 捕获 CMOS 视频,编码并通过以太网发送

linux - 将 ffmpeg 包含到项目时出错

ffmpeg - 在整个视频期间显示的标题

java - 从 LSB 插入中检索该位

video - H264有什么缺点?

iphone - 硬件加速 h.264 解码到 iOS 中的纹理、覆盖或类似内容