Encoding ffmpeg API h264编码视频不能在所有平台上播放

Encoding ffmpeg API h264编码视频不能在所有平台上播放,encoding,ffmpeg,h.264,libavcodec,Encoding,Ffmpeg,H.264,Libavcodec,编辑:在以前的版本中,我使用了非常旧的ffmpeg API。我现在使用最新的库。问题只是略有变化,从“主要”变为“高” 我使用FFMPEG-C API在C++中创建MP4视频。 我希望生成的视频具有“受限基线”的配置文件,以便生成的视频可以在尽可能多的平台上播放,尤其是移动平台,但我每次都会获得“高”配置文件,即使我将编解码器配置文件硬编码为FF\u profile\u H264\u受限基线。因此,视频不能在我们所有的测试平台上播放 以下是“ffprobe video.mp4-show_stre

编辑:在以前的版本中,我使用了非常旧的ffmpeg API。我现在使用最新的库。问题只是略有变化,从“主要”变为“高”

我使用FFMPEG-C API在C++中创建MP4视频。 我希望生成的视频具有“受限基线”的配置文件,以便生成的视频可以在尽可能多的平台上播放,尤其是移动平台,但我每次都会获得“高”配置文件,即使我将编解码器配置文件硬编码为FF\u profile\u H264\u受限基线。因此,视频不能在我们所有的测试平台上播放

以下是“ffprobe video.mp4-show_streams”介绍我的视频流的内容:

  Metadata:
major_brand     : isom
minor_version   : 512
compatible_brands: isomiso2avc1mp41
creation_time   : 1970-01-01 00:00:00
encoder         : Lavf53.5.0
  Duration: 00:00:13.20, start: 0.000000, bitrate: 553 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 320x180,
424 kb/s, 15 fps, 15 tbr, 15 tbn, 30 tbc
Metadata:
  creation_time   : 1970-01-01 00:00:00
  handler_name    : VideoHandler
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, s16, 12
kb/s
Metadata:
  creation_time   : 1970-01-01 00:00:00
  handler_name    : SoundHandler
-------VIDEO STREAM--------
[STREAM] 
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10

profile=High <-- This should be "Constrained Baseline"

codec_type=video
codec_time_base=1/30
codec_tag_string=avc1
codec_tag=0x31637661
width=320
height=180
has_b_frames=0
sample_aspect_ratio=N/A
display_aspect_ratio=N/A
pix_fmt=yuv420p
level=30
timecode=N/A
is_avc=1
nal_length_size=4
id=N/A
r_frame_rate=15/1
avg_frame_rate=15/1
time_base=1/15
start_time=0.000000
duration=13.200000
bit_rate=424252
nb_frames=198
nb_read_frames=N/A
nb_read_packets=N/A
TAG:creation_time=1970-01-01 00:00:00
TAG:language=und
TAG:handler_name=VideoHandler
[/STREAM]
-------AUDIO STREAM--------
[STREAM]
index=1
codec_name=aac
codec_long_name=Advanced Audio Coding
profile=unknown
codec_type=audio
codec_time_base=1/44100
codec_tag_string=mp4a
codec_tag=0x6134706d
sample_fmt=s16
sample_rate=44100
channels=2
bits_per_sample=0
id=N/A
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/44100
start_time=0.000000
duration=13.165714
bit_rate=125301
nb_frames=567
nb_read_frames=N/A
nb_read_packets=N/A
TAG:creation_time=1970-01-01 00:00:00
TAG:language=und
TAG:handler_name=SoundHandler
[/STREAM]
其他信息:

// We need to set the level and profile to get videos that play (hopefully) on all platforms
c->level = 30;
c->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;
// Set profile to baseline
av_opt_set(c->priv_data, "profile", "baseline", AV_OPT_SEARCH_CHILDREN);
作为参考视频,我使用Mozilla提供的gizmo.mp4作为示例,在每个平台/浏览器上播放。它肯定有“受约束的基线”配置文件,并且肯定能在我们所有的测试智能手机上工作。我们自创的视频并不适用于所有平台,我相信这是因为我们的个人资料

我也使用<强> Qt FASTLASE.exe 在创建MP4之后将头移到文件的开始,因为这不能直接以C++的方式完成。这可能是问题所在吗


显然,我做错了什么,但我不知道会是什么。我会感谢每一个提示;)

我有解决办法。在ffmpeg bug跟踪器中花了一些时间和讨论,并浏览了一些配置文件设置示例之后,我终于找到了解决方案

需要使用av_opt_set(codecContext->priv_data,“profile”,“baseline”(或任何其他所需的配置文件),av_opt_SEARCH_CHILDREN)

因此,在我的情况下,这将是:

错误:

// We need to set the level and profile to get videos that play (hopefully) on all platforms
c->level = 30;
c->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;
// Set profile to baseline
av_opt_set(c->priv_data, "profile", "baseline", AV_OPT_SEARCH_CHILDREN);
正确:

// We need to set the level and profile to get videos that play (hopefully) on all platforms
c->level = 30;
c->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;
// Set profile to baseline
av_opt_set(c->priv_data, "profile", "baseline", AV_OPT_SEARCH_CHILDREN);

完全不直观,与API的其他用法相反,但这是ffmpeg的理念。你不需要理解它,你只需要理解如何使用它;)

您可能应该在ffmpeg邮件列表中提交错误报告。正如您所期望的,这应该是基线或基线约束的信号。我更新了我的ffmpeg版本,问题已从“主要”轻微更改为现在的“高”配置文件@如果这个问题无法解决,SilverbackNet就可以了。有趣的是,当您通过命令行使用ffmpeg.exe并设置“-vprofile baseline”时,它会按预期工作。我们使用的ffmpeg.exe和C库都使用相同的ffmpeg版本。这意味着问题不在库本身,这是个好消息。你所需要做的就是查看ffmpeg(可执行文件)的源代码,看看它们是如何将h264正确设置为基线的。我试过了,但理解ffmpeg源代码中到底发生了什么可能需要几周的时间。当然没有检查某些值是否为“基线”(我用TextCrawler查看了一下)。为什么选择配置文件基线?你的意思是,配置文件约束的视频不能在某些设备上正常播放吗?“基线”实际上在生成的文件中被约束为基线。据我所知,基线和约束_基线是h264的两个不同配置文件。你的看法是什么?我同意你的看法,至少基线配置文件有不同的级别。但正如我所说,将“基线”放入“profile”字段会生成一个基线受约束的文件。我从来没有真正为更多的事情烦恼过,因为它起作用了。