如何让 ffmpeg 确信输入是原始 H264?

如何让 ffmpeg 确信输入是原始 H264?

我有一个原始的 H.264 视频流(以十六进制开头00 00 01 FC ...,一个 3 字节的起始码,后跟一个 NAL 单元)。ffmpeg 处理它但它真的不想......

让我们测试一下

假设文件名为avcfile.raw,我想将该视频包装到容器中。

> ffmpeg -i avcfile.raw -c copy out.mp4
...
avcfile.raw: Invalid data found when processing input

我们将文件重命名为avcfile.h264

> ffmpeg -i avcfile.h264 -c copy out.mp4
...
Output file #0 (out.mp4):
   Output stream #0:0 (video): 230 packets muxed (77103 bytes);
   Total: 230 packets (77103 bytes) muxed

它真的神奇地有效!

那么我该如何说服ffmpeg他们处理我的文件没有将其重命名为.h264扩展名?

我尝试了所有这些论点都无济于事:-f h264 -err_detect ignore_err -flags +global_header。 的全部目的不就是-f做我要求的事情吗?

为什么我需要这个

最终目标是管道将原始 H264 流ffmpeg从标准输出,如下所示:

somenetworkstreamer | ffmpeg -i pipe: -f h264 -c copy out.mp4

...问题就在这里——我无法给未命名的管道提供扩展.h264

有什么想法吗?ffmpeg还有其他我不知道的“强制格式”开关吗?我可以在流的开头附加一些魔法字节吗?

一些 -loglevel 调试输出

当它起作用时(例如ffmpeg -i file.h264 -

Splitting the commandline.
Reading option '-i' ... matched as input url with argument 'file.h264'.
Reading option '-c' ... matched as option 'c' (codec name) with argument 'copy'.
...
Reading option 'out.mp4' ... matched as output url.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option loglevel (set logging level) with argument debug.
Successfully parsed a group of options.
Parsing a group of options: input url file.h264.
Successfully parsed a group of options.
Opening an input file: teste.h264.
[NULL @ 0x871230] Opening 'teste.h264' for reading
[file @ 0x8719c0] Setting default whitelist 'file,crypto'
[h264 @ 0x871230] Format h264 detected only with low score of 1, misdetection possible!
[h264 @ 0x871230] Before avformat_find_stream_info() pos: 0 bytes read:77103 seeks:0 nb_streams:1
[AVBSFContext @ 0x878350] Invalid NAL unit 0, skipping.
[AVBSFContext @ 0x878350] nal_unit_type: 7(SPS), nal_ref_idc: 1
[AVBSFContext @ 0x878350] nal_unit_type: 8(PPS), nal_ref_idc: 1
[AVBSFContext @ 0x878350] nal_unit_type: 5(IDR), nal_ref_idc: 1
[AVBSFContext @ 0x878350] Invalid NAL unit 0, skipping.
[h264 @ 0x872430] Invalid NAL unit 0, skipping.
[h264 @ 0x872430] nal_unit_type: 7(SPS), nal_ref_idc: 1
[h264 @ 0x872430] nal_unit_type: 8(PPS), nal_ref_idc: 1
[h264 @ 0x872430] nal_unit_type: 5(IDR), nal_ref_idc: 1
[h264 @ 0x872430] Invalid NAL unit 0, skipping.
[h264 @ 0x872430] Format yuv420p chosen by get_format().
[h264 @ 0x872430] Reinit context to 1920x1088, pix_fmt: yuv420p
[h264 @ 0x872430] nal_unit_type: 1(Coded slice of a non-IDR picture), nal_ref_idc: 1
[h264 @ 0x872430] Invalid NAL unit 8, skipping.
...
Input #0, h264, from 'file.h264':
  Duration: N/A, bitrate: N/A
    Stream #0:0, 64, 1/1200000: Video: h264 (Main), 1 reference frame, yuv420p(progressive, left), 1920x1080 (1920x1088), 0/1, 12.17 fps, 12 tbr, 1200k tbn, 24 tbc
Successfully opened the file.
Parsing a group of options: output url out.mp4.
Applying option c (codec name) with argument copy.
Successfully parsed a group of options.
Opening an output file: out.mp4.
[file @ 0x9620f0] Setting default whitelist 'file,crypto'
Successfully opened the file.
Output #0, mp4, to 'out.mp4':
  Metadata:
    encoder         : Lavf58.20.100
    Stream #0:0, 0, 1/1200000: Video: h264 (Main), 1 reference frame (avc1 / 0x31637661), yuv420p(progressive, left), 1920x1080 (0x0), 0/1, q=2-31, 12.17 fps, 12 tbr, 1200k tbn, 1200k tbc
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
cur_dts is invalid (this is harmless if it occurs once at the start per stream)
[mp4 @ 0x8760d0] Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly
No more output streams to write to, finishing.
frame=  230 fps=0.0 q=-1.0 Lsize=      79kB time=00:00:18.90 bitrate=  34.1kbits/s speed= 945x
video:75kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 4.431734%
Input file #0 (file.h264):
  Input stream #0:0 (video): 230 packets read (77103 bytes);
  Total: 230 packets (77103 bytes) demuxed
Output file #0 (out.mp4):
  Output stream #0:0 (video): 230 packets muxed (77103 bytes);
  Total: 230 packets (77103 bytes) muxed
0 frames successfully decoded, 0 decoding errors

当它不存在时(例如ffmpeg -i file.raw -

Splitting the commandline.
Reading option '-i' ... matched as input url with argument 'file.raw'.
Reading option '-c' ... matched as option 'c' (codec name) with argument 'copy'.
Reading option '-err_detect' ...Routing option err_detect to both codec and muxer layer
 matched as AVOption 'err_detect' with argument 'ignore_err'.
Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument 'debug'.
Reading option '-flags' ... matched as AVOption 'flags' with argument '+global_header'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'h264'.
Reading option '-c' ... matched as option 'c' (codec name) with argument 'copy'.
Reading option 'out.mp4' ... matched as output url.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option loglevel (set logging level) with argument debug.
Successfully parsed a group of options.
Parsing a group of options: input url file.raw.
Successfully parsed a group of options.
Opening an input file: file.raw.
[NULL @ 0x201f270] Opening 'file.raw' for reading
[file @ 0x201fa00] Setting default whitelist 'file,crypto'
[AVIOContext @ 0x2027bd0] Statistics: 77108 bytes read, 0 seeks
file.raw: Invalid data found when processing input

是的,你甚至没有尝试调用 H264...

版本

我已经尝试使用 ffmpeg 4.1.6 和 4.3.2

答案1

哦,对了,所有与输入相关的参数都需要删除使用 ffmpeg 的输入参数。

文档状态:

作为一般规则,选项将应用于下一个指定的文件。因此,顺序很重要,您可以在命令行上多次使用相同的选项。然后,每次出现都会应用于下一个输入或输出文件。此规则的例外是全局选项(例如详细程度),应首先指定。

这有效:

ffmpeg -f h264 -i avcfile.h264 -c copy out.mp4

somenetworkstreamer | ffmpeg -f h264 -i pipe: -c copy out.mp4

相关内容