使用opencv mat处理AVFrame导致编码错误

时间:2014-11-13 13:55:36

标签: c++ opencv ffmpeg encode mat

我尝试使用ffmpeg解码视频文件,抓取AVFrame对象,将其转换为opencv mat对象,进行一些处理然后将其转换回AVFrame对象并将其编码回视频文件。

嗯,程序可以运行,但结果不好。

我继续得到错误,例如"顶部块在7 19",#34;错误时解码MB 7 19,字节流358",#34;隐藏294 DC P帧中的294AC,294 MV误差"等

结果视频一闪而过。像这样,  enter image description here

我猜它是因为我的AVFrame对Mat和Mat到AVFrame方法,而且这里是

//unspecified function
temp_rgb_frame = avcodec_alloc_frame(); 
int numBytes = avpicture_get_size(PIX_FMT_RGB24, width, height); 
uint8_t * frame2_buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t)); 
avpicture_fill((AVPicture*)temp_rgb_frame, frame2_buffer, PIX_FMT_RGB24, width, height);

void CoreProcessor::Mat2AVFrame(cv::Mat **input, AVFrame *output)
{
    //create a AVPicture frame from the opencv Mat input image
    avpicture_fill((AVPicture *)temp_rgb_frame,
        (uint8_t *)(*input)->data,
        AV_PIX_FMT_RGB24,
        (*input)->cols,
        (*input)->rows);

    //convert the frame to the color space and pixel format specified in the sws context

    sws_scale(
        rgb_to_yuv_context, 
        temp_rgb_frame->data,
        temp_rgb_frame->linesize,
        0, height, 
        ((AVPicture *)output)->data, 
        ((AVPicture *)output)->linesize);

    (*input)->release();

}

void CoreProcessor::AVFrame2Mat(AVFrame *pFrame, cv::Mat **mat)
{
    sws_scale(
        yuv_to_rgb_context, 
        ((AVPicture*)pFrame)->data, 
        ((AVPicture*)pFrame)->linesize, 
        0, height, 
        ((AVPicture *)temp_rgb_frame)->data,
        ((AVPicture *)temp_rgb_frame)->linesize);

    *mat = new cv::Mat(pFrame->height, pFrame->width, CV_8UC3, temp_rgb_frame->data[0]);
}

void CoreProcessor::process_frame(AVFrame *pFrame)
{
    cv::Mat *mat = NULL;
    AVFrame2Mat(pFrame, &mat);
    Mat2AVFrame(&mat, pFrame);
}

我在记忆中做错了吗?因为如果我删除处理部分,只需解码然后对帧进行编码,结果就是正确的。

1 个答案:

答案 0 :(得分:1)

好吧,事实证明我在初始化temp_rgb_frame时犯了一个错误,如果应该这样,

temp_rgb_frame = avcodec_alloc_frame();
int numBytes = avpicture_get_size(PIX_FMT_RGB24, width, height);
uint8_t * frame2_buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));
avpicture_fill((AVPicture*)temp_rgb_frame, frame2_buffer, PIX_FMT_RGB24, width, height);