我正在尝试使用ffmpeg解码视频文件,抓取AVFrame对象,将其转换为opencv mat对象,进行一些处理,然后将其转换回AVFrame对象,并将其编码回视频文件。
好的,程序可以运行,但是会产生不好的结果。
我不断收到诸如“在7 19时无法用于请求的帧内模式的顶部块不可用”,“在解码MB 7 19时出错,字节流358”,“在P帧中隐藏294 DC,294AC,294 MV错误”之类的错误。
结果视频四处可见。像这样,
我猜是因为我的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);
}
我的内存有问题吗?因为如果我删除处理部分,只需解码然后编码帧,结果是正确的。
最佳答案
好吧,事实证明我在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);
关于c++ - 使用OpenCV Mat处理AVFrame导致编码错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26910524/