我使用FFmpeg API将一些帧编码到MP4中,但MP4无法在Windows Media Player中播放。
与使用ffprobe的普通MP4相比,我发现有问题的MP4的FOURCC是'H264',而正常的MP4是'AVC1'。 根据{{3}},'AVC1'有起始码,但'H264'没有。我还了解到,当解复用MP4时,我们应在H.264流之前手动添加sps和pps。
现在我不知道如何将启动代码或sps / pps添加到我的MP4,请帮我一把。 如何生成可以在Windows Media Player中播放的MP4?
我曾尝试添加h264比特流过滤器但它不起作用。以下代码:
AVBitStreamFilterContext *bsfc = NULL;
bsfc = av_bitstream_filter_init("h264_mp4toannexb");
if (bsfc == NULL) {
printf("bsfc is NULL\n");
}
av_bitstream_filter_filter(bsfc, codec_ctx, NULL, &(pkt->data), &(pkt->size), pkt->data, pkt->size, 0);
av_bitstream_filter_close(bsfc);
经过大量尝试后,我发现手动将sps和pps添加到codec_ctx-> extradata有效:
unsigned char sps_pps[23] = { 0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x29, 0xac, 0x1b, 0x1a, 0x12, 0xe0, 0x51, 0x90,
0x00, 0x00, 0x00, 0x01, 0x68, 0xea, 0x43, 0xcb };
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");
ERR_NULL_EXIT
}
memcpy(codec_ctx->extradata, sps_pps, 23);
上面的代码提到了@szatmary
的答案现在生成的MP4可以在Windows Media Player中播放。但是出现了一个新问题,因为我不知道sps / pps的正确值是什么。这导致Windows资源管理器中显示的框架的宽度和高度不正确。所以我需要设置正确的sps / pps。我还阅读了sps / pps的文档但是因为一些参数有可变位而感到困惑。那么有人能告诉我如何正确设置sps / pps吗?
答案 0 :(得分:4)
我终于发现问题的根本解决方案是在调用avcodec_open2之前添加一行代码。
codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
如果设置了codec_ctx->标志,编码器会在avcodec_open2()函数中设置sps / pps。
如果您想了解有关sps / pps的更多信息,可以参考以下网站。
Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream