您好,登录后才能下订单哦!
问题描述
设置该标志位,在解码过程中似乎并没有任何的效果,本意是通过设置该标志位AV_CODEC_FLAG_GLOBAL_HEADER
通过AVCodecContext在解码过程中,从extradata中读取SPS/PPS,然后将信息填充到每一帧之前,然后正确解码
变量说明
/**
* Place global headers in extradata instead of every keyframe.
*将全局头部信息放在extradata指针中,而不是每一个关键帧中
*/
#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22)
1)libx264.c:static av_cold int X264_init(AVCodecContext *avctx)
该变量主要出现在该函数的以下两个地方
1 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
x4->params.b_repeat_headers = 0;
说明
b_repeat_headers的意思是将SPS/PPS添加到每一个关键帧之前,0代表不添加
如果设置了videosteam 的codec中设置了AV_CODEC_FLAG_GLOBAL_HEADER就会导致x264_param_t参数中的b_repeat_header赋值为0,
这样每个关键帧前面就不会添加SPS/PPS,如果在探测码流的时候,无法获取正确的SPS/PPS,就会导致解码失败。
0x00000001或者0x000001是起始码,0x67是sps的开头,0x68是pps的开头。
2 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
x264_nal_t *nal;
uint8_t *p;
int nnal, s, i;
s = x264_encoder_headers(x4->enc, &nal, &nnal);
avctx->extradata = p = av_mallocz(s + AV_INPUT_BUFFER_PADDING_SIZE);
if (!p)
return AVERROR(ENOMEM);
for (i = 0; i < nnal; i++) {
/* Don't put the SEI in extradata. */
if (nal[i].i_type == NAL_SEI) {
av_log(avctx, AV_LOG_INFO, "%s\n", nal[i].p_payload+25);
x4->sei_size = nal[i].i_payload;
x4->sei = av_malloc(x4->sei_size);
if (!x4->sei)
return AVERROR(ENOMEM);
memcpy(x4->sei, nal[i].p_payload, nal[i].i_payload);
continue;
}
memcpy(p, nal[i].p_payload, nal[i].i_payload);
p += nal[i].i_payload;
}
avctx->extradata_size = p - avctx->extradata;
}
相关信息说明
1)http://www.cnblogs.com/wanggang123/p/6128719.html指出如果要求打开编码器之后
AVCodecContext extradata存有 SPS,PPS 信息需要加上如下代码
AVCodecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER
暂时用不上,因为当前是解码,默认情况下AVCodecContext extradata在探测码流(avformat_find_stream_info)
会自动将SPS,PPS填充到extradata字符串中,通过avcodec_parameters_to_context函数,将codecpar内容
传递给AVCodecContext
2)http://blog.csdn.net/ET_Endeavoring/article/details/77949850指出需要对AVCodecContext结构体进行如下的设置
AVCodecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER
FFmpeg才会在调用avcodec_open2函数里面,将SPS,PPS信息写入header
如下代码提供手动填充extradata的方式
unsigned char sps_pps[23] = { 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x0a, 0xf8, 0x0f, 0x00, 0x44, 0xbe, 0x8,
0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x38, 0x80 };
codec_ctx->extradata_size = 23;
codec_ctx->extradata = (uint8_t*)av_malloc(23 + AV_INPUT_BUFFER_PADDING_SIZE);
if (codec_ctx->extradata == NULL) {
printf("could not av_malloc the video params extradata!\n");
return -1;
}
memcpy(codec_ctx->extradata, sps_pps, 23);
实际上,在解码的时候,手动填充无效
3)http://blog.csdn.net/passionkk/article/details/75528653指出了在实时视频传输时,需要发送
SPS/PPS数据,必须设置
param.b_repeat_headers = 1; // 重复SPS/PPS放到关键帧前面
种种情况下,codec中不能设置AV_CODEC_FLAG_GLOBAL_HEADER标志,从上面的代码,就可以知道
如果设置了videosteam 的codec中设置了AV_CODEC_FLAG_GLOBAL_HEADER就会导致x264_param_t参数中的b_repeat_header赋值为0,
这样每个关键帧前面就不会添加SPS/PPS,如果在探测码流的时候,无法获取正确的SPS/PPS,就会导致解码失败。
0x00000001或者0x000001是起始码,0x67是sps的开头,0x68是pps的开头。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。