ffmpeg:从 alsa/madi 捕获到 mpeg-ts 时保留时间戳

ffmpeg:从 alsa/madi 捕获到 mpeg-ts 时保留时间戳

编码为 mpeg-ts/aac 时,从 ALSA/MADI 输入(包含时间戳)捕获时是否可以保留原始时间戳?MADI 源由第三方提供给我们。

FFMpeg 版本:4.2.2

起初,这似乎是一项简单的任务,但我无法让它正常工作。源代码提供了一个纪元时间戳(第一行显示系统的当前时间戳作为参考):

$ date +%s && ffprobe -show_entries stream -f alsa -i RME-5556
1589812196
ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers
  built with gcc 7 (GCC)
  configuration: --prefix=/software/ffmpeg-4.2.2-aeef8c6f --enable-pic --enable-pthreads --disable-shared --enable-static --enable-gpl --enable-nonfree --enable-libmp3lame --enable-libx264 --enable-libvorbis --enable-libx265 --enable-libtheora --enable-libxvid --enable-libfdk_aac --disable-crystalhd --enable-avfilter --enable-postproc --enable-bzlib --extra-cflags=-I/compile/lame-3.100-4190d36b/include --extra-cflags=-I/compile/faad2-2.8.8-0a416c66/include --extra-cflags=-I/compile/faac-1.29.9.2-d0f85fb8/include --extra-cflags=-I/compile/xvidcore-1.3.7-b5c2cdca/include --extra-cflags=-I/compile/libogg-1.3.4-de57aa91/include --extra-cflags=-I/compile/libtheora-1.1.1-7256273f/include --extra-cflags=-I/compile/alsa-lib-1.2.1.2-babf7811/include --extra-ldflags=-L/compile/lame-3.100-4190d36b/lib --extra-ldflags=-L/compile/faad2-2.8.8-0a416c66/lib --extra-ldflags=-L/compile/faac-1.29.9.2-d0f85fb8/lib --extra-ldflags=-L/compile/xvidcore-1.3.7-b5c2cdca/lib --extra-ldflags=-L/compile/libogg-1.3.4-de57aa91/lib --extra-ldflags=-L/compile/libtheora-1.1.1-7256273f/lib --extra-ldflags=-L/compile/alsa-lib-1.2.1.2-babf7811/lib --enable-rpath --pkg-config-flags=--static --extra-ldflags=-lpthread --extra-ldflags=-lm
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, alsa, from 'RME-5556':
  Duration: N/A, start: 1589812196.319736, bitrate: 1536 kb/s
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
[STREAM]
index=0
codec_name=pcm_s16le
codec_long_name=PCM signed 16-bit little-endian
profile=unknown
codec_type=audio
codec_time_base=1/48000
codec_tag_string=[0][0][0][0]
codec_tag=0x0000
sample_fmt=s16
sample_rate=48000
channels=2
channel_layout=unknown
bits_per_sample=16
id=N/A
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/1000000
start_pts=1589812196319736
start_time=1589812196.319736
duration_ts=N/A
duration=N/A
bit_rate=1536000
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
[/STREAM]

但是当使用以下命令进行编码时,会显示一个“奇怪的”start_time。

编码一些帧:

$ ffmpeg -hide_banner -v verbose -f alsa -y -i RME-5556 -copyts -acodec aac -ar 48000 -b:a 256k -ac 2 -frames 100 -f mpegts -mpegts_copyts 1 test.ts
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, alsa, from 'RME-5556':
  Duration: N/A, start: 1589813372.332589, bitrate: 1536 kb/s
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Applying unspecific -frames to non video streams, maybe you meant -vframes ?
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le (native) -> aac (native))
Press [q] to stop, [?] for help
[graph_0_in_0_0 @ 0x3c5e040] tb:1/48000 samplefmt:s16 samplerate:48000 chlayout:0x3
[format_out_0_0 @ 0x3c5e400] auto-inserting filter 'auto_resampler_0' between the filter 'Parsed_anull_0' and the filter 'format_out_0_0'
[auto_resampler_0 @ 0x3c61680] ch:2 chl:stereo fmt:s16 r:48000Hz -> ch:2 chl:stereo fmt:fltp r:48000Hz
[mpegts @ 0x3c52500] frame size not set
[mpegts @ 0x3c52500] muxrate VBR, pcr every 9 pkts, sdt every 200, pat/pmt every 40 pkts
Output #0, mpegts, to 'test.ts':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Audio: aac (LC), 48000 Hz, stereo, fltp, delay 1024, 256 kb/s
    Metadata:
      encoder         : Lavc58.54.100 aac
No more output streams to write to, finishing.  0.0kbits/s speed=7.84e+08x    
size=      76kB time=441614:49:34.45 bitrate=   0.0kbits/s speed=7.43e+08x    
video:0kB audio:66kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 14.145925%
Input file #0 (RME-5556):
  Input stream #0:0 (audio): 101 packets read (413696 bytes); 101 frames decoded (103424 samples); 
  Total: 101 packets (413696 bytes) demuxed
Output file #0 (test.ts):
  Output stream #0:0 (audio): 101 frames encoded (103424 samples); 100 packets muxed (67857 bytes); 
  Total: 100 packets (67857 bytes) muxed
[AVIOContext @ 0x3c4eac0] Statistics: 0 seeks, 1 writeouts
[aac @ 0x3c53980] Qavg: 197.511

分析一下:

$ ffprobe -hide_banner -loglevel warning -show_entries program test.ts 
[PROGRAM]
program_id=1
program_num=1
nb_streams=1
pmt_pid=4096
pcr_pid=256
start_pts=7366767433
start_time=7366.767433
end_pts=7368906744
end_time=7368.906744
TAG:service_name=Service01
TAG:service_provider=FFmpeg
[STREAM]
index=0
codec_name=aac
codec_long_name=AAC (Advanced Audio Coding)
profile=LC
codec_type=audio
codec_time_base=1/48000
codec_tag_string=[15][0][0][0]
codec_tag=0x000f
sample_fmt=fltp
sample_rate=48000
channels=2
channel_layout=stereo
bits_per_sample=0
id=0x100
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/90000
start_pts=663009069
start_time=7366.767433
duration_ts=192538
duration=2.139311
bit_rate=262125
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
...
[/STREAM]
[/PROGRAM]

所以start_pts设置了,但值很奇怪。这是什么问题?

我尝试并注意到的是:

  • -copyts编码时,定义后输入中会显示正确的时间戳(上面输出中的 441614:49:34.45)
  • 不同time_base之处:time_base=1/1000000输入不同,time_base=1/90000输出文件不同。这会是个问题吗?
  • -mpegts_copyts 1似乎是我正在寻找的选项,但似乎没有任何作用。
  • 我尝试了许多选项,例如试验-af setpts=-copytb-enc_time_base,但都没有任何成功。

由于时间戳似乎因某些因素而偏离,它可能与 time_base 值或某种类型有关?我尝试time_base=1/90000使用enc_time_base或更改报告,copytb但不起作用(所以我可能误解了)

我是否遗漏了什么?

感谢任何提示或建议!

答案1

ALSA 的输入时间戳为 64 位,而 MPEG-TS 将时间戳存储为 33 位(有额外的位可用于更高的精度但不扩大范围)。

因此,在您的编码运行中,初始时间为,1589813372.332589代表 PTS 为1589813372332589。转换为时间基数 90000,即 ~,143083203509933但使用 33 位宽度,余数保留为663010989。与实际起始 PTS 的差异是由于编码器添加并在解码后丢弃的 AAC 启动样本。

相关内容