为什么通过FFmpeg API生成的MP4无法在Windows Media Player中播放?

时间:2017-09-08 08:36:31

标签: video ffmpeg mp4 h.264 video-encoding

我使用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吗?

1 个答案:

答案 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