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

标签 video ffmpeg mp4 h.264 video-encoding

我使用 FFmpeg API 将一些帧编码为 MP4,但该 MP4 无法在 Windows Media Player 中播放。

通过使用ffprobe与正常MP4进行比较,我发现有问题的MP4的FOURCC是“H264”,而正常MP4是“AVC1”。 根据H.264 Video Types ,“AVC1”有起始码,但“H264”没有。我还了解到,在解复用 MP4 时,我们应该在 H.264 流之前手动添加 sps 和 pps。

现在我不知道如何向我的 MP4 添加起始码或 sps/pps,请帮我。 我应该如何生成可以在 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);

经过多次尝试,发现在codec_ctx->extradata中手动添加sps和pps有效:

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 吗?

最佳答案

我终于找到了根本的解决办法,就是在调用avcodec_open2之前添加一行代码。

codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

如果您设置了 codec_ctx->flags,编码器将在 avcodec_open2() 函数中设置 sps/pps。

如果您想了解更多关于sps/pps的信息,可以引用以下网站。

Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream

关于video - 为什么通过FFmpeg API生成的MP4无法在Windows Media Player中播放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46112161/

相关文章:

ffmpeg - ffmpegpalettgen rgb565可能吗?

youtube - 为什么手机(不限于iPhone)上的YouTube音频出现乱码?

ffmpeg - 为什么将音频添加到 mp4 需要很长时间?

android - 在 Android 中使用 .amp 扩展名访问 mpeg-4 编码的 RTSP 直播流(Axis 服务器)

python - 如何使用python和openCV从.yuv视频文件(YUV420)中提取帧?

audio - FFMpeg:如何合并视频和音频并将视频尾部对齐到音频长度?

java - 使用 Xuggler 设置视频中每帧的持续时间

ios - 如何改变视频播放的速度

ios - 使用ffmpeg转换时视频向左旋转90度

video - 使用 ffmpeg 进行屏幕录制和视频编码