使用ffmpeg解码h264 720p时输出黑色

时间:2017-12-05 11:30:12

标签: 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);
}

1 个答案:

答案 0 :(得分:0)

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