我已经编写了一个库,可以与python一起使用,以从缓冲区中的视频中提取帧以进行某些处理。我使用ffmpeg中的示例使用libavcodec构建我的库。 这似乎对于大多数视频都工作正常。但是我在某些视频中看到我的媒体库没有提取所有帧(远小于FPS)。
似乎数据包可能会出现混乱,并且docoder无法处理它。我不断收到很多以下错误
pid = 100 pes_code = 0x1e0
nal_unit_type:9,nal_ref_idc:0
nal_unit_type:1,nal_ref_idc:2
deblocking_filter_idc 7超出范围
decode_slice_header错误
没有框架!
我按照以下步骤设置解码器。
//open input file, allocate context
if ((ret = avformat_open_input(&format_ctx, in_filename, 0, 0)) < 0) {
PyErr_SetString(ExtractorError, "Could not open input file!");
goto end;
}
if ((ret = avformat_find_stream_info(format_ctx, 0)) < 0) {
PyErr_SetString(ExtractorError, "Failed to retrieve input stream information!");
goto end;
}
av_dump_format(format_ctx, 0, in_filename, 0);
// Get the video index from the stream
for(int i=0; i<format_ctx->nb_streams ;i++ )
{
if( format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO )
{
video_stream_index = i;
break;
}
}
/* if video stream not availabe */
if((video_stream_index) == -1)
{
PyErr_SetString(ExtractorError, "video stream to retreive fps is not found!");
return NULL;
}
long duration = format_ctx->duration + (format_ctx->duration <= INT64_MAX - 5000 ? 5000 : 0);
float duration_in_secs = (float)duration / AV_TIME_BASE;
stream_mapping_size = format_ctx->nb_streams;
stream_mapping = av_mallocz_array(stream_mapping_size, sizeof(*stream_mapping));
if (!stream_mapping) {
ret = AVERROR(ENOMEM);
goto end;
}
AVCodec *pCodec = NULL;
AVCodecParameters *in_codecpar = NULL;
for (i = 0; i < format_ctx->nb_streams; i++) {
AVStream *in_stream = format_ctx->streams[i];
in_codecpar = in_stream->codecpar;
if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
stream_mapping[i] = -1;
continue;
}
if (in_codecpar->codec_type == AVMEDIA_TYPE_VIDEO){
pCodec = avcodec_find_decoder(in_codecpar->codec_id);
stream_mapping[i] = stream_index++;
break;
}
}
if(!pCodec){
PyErr_SetString(ExtractorError, "error, no pCodec!");
return NULL;
}
// convert CodecParam to CodecCtx
AVCodecContext *pCodecCtx = avcodec_alloc_context3(pCodec);
if (!pCodecCtx) {
PyErr_SetString(ExtractorError, "Failed to convert codecParam to CodecCtx!");
return NULL;
}
ret = avcodec_parameters_to_context(pCodecCtx, in_codecpar);
if (ret < 0)
goto end;
//open video decoder
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
{
logging("EXTRACTOR: failed to open codec through avcodec_open2\n");
return NULL;
}
为了对其进行测试,我使用了ffmpeg的以下命令从同一视频中提取帧,并且效果很好。
ffmpeg -i〜/ thuuz / extractor / 03000.ts -f image2 -qscale:v 7 ffmpeg-detect-%03d.jpg -hide_banner -v quiet
我没有传递正确的编解码器参数吗?请让我知道一些有关如何调试此问题的信息。 非常感谢。