Opened 9 years ago

Last modified 12 months ago

#4525 new enhancement

Multi-program structure of input is not preserved in MPEG-TS output

Reported by: Stefano Sabatini Owned by:
Priority: wish Component: ffmpeg
Version: git-master Keywords: mpegts
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Multi-programs MPEGTS input are correctly handled, and there is an API to set the Program structure.

For example consider this output:

$ ffprobe multi-programs.ts 
ffprobe version N-71578-g57865a9 Copyright (c) 2007-2015 the FFmpeg developers
  built with gcc 4.8 (Ubuntu/Linaro 4.8.1-10ubuntu9)
  configuration: --extra-cflags=-I/home/stefano/include --extra-ldflags=-L/home/stefano/lib --enable-libopenjpeg --enable-pic --enable-fontconfig --enable-libass --enable-version3 --prefix=/home/stefano --disable-shared --enable-static --enable-debug=3 --enable-pthreads --disable-optimizations --enable-libvorbis --enable-gpl --enable-nonfree --enable-libmp3lame --enable-libtheora --enable-gpl --enable-x11grab --enable-frei0r --enable-libfaac --enable-libcaca --enable-libflite --enable-libzmq --enable-libfreetype --enable-libopencv --enable-libgme --enable-libcdio --enable-libvo-aacenc --enable-libx264 --enable-ladspa --enable-libquvi --enable-opengl --enable-libvpx --enable-libxcb
  libavutil      54. 23.100 / 54. 23.100
  libavcodec     56. 35.101 / 56. 35.101
  libavformat    56. 30.100 / 56. 30.100
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 14.100 /  5. 14.100
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mpegts, from 'multi-programs.ts':
  Duration: 00:05:00.03, start: 0.000278, bitrate: 1216 kb/s
  Program 1 
    Stream #0:0[0x65]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 4:3 DAR 16:9], 10 fps, 10 tbr, 90k tbn, 20 tbc
  Program 2 
    Stream #0:1[0x6f]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 4:3 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc
  Program 3 
    Stream #0:2[0x79]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 30 fps, 29.92 tbr, 90k tbn, 60 tbc

But programs are not handled in the mpegts muxer at the present time, so even when using the API the corresponding program structure is not stored in the MPEGTS output.

With ffmpeg we get this behavior:

$ ffmpeg -i multi-programs.ts -codec copy -map 0 multi-programs.out.ts
ffmpeg version N-71578-g57865a9 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 4.8 (Ubuntu/Linaro 4.8.1-10ubuntu9)
  configuration: --extra-cflags=-I/home/stefano/include --extra-ldflags=-L/home/stefano/lib --enable-libopenjpeg --enable-pic --enable-fontconfig --enable-libass --enable-version3 --prefix=/home/stefano --disable-shared --enable-static --enable-debug=3 --enable-pthreads --disable-optimizations --enable-libvorbis --enable-gpl --enable-nonfree --enable-libmp3lame --enable-libtheora --enable-gpl --enable-x11grab --enable-frei0r --enable-libfaac --enable-libcaca --enable-libflite --enable-libzmq --enable-libfreetype --enable-libopencv --enable-libgme --enable-libcdio --enable-libvo-aacenc --enable-libx264 --enable-ladspa --enable-libquvi --enable-opengl --enable-libvpx --enable-libxcb
  libavutil      54. 23.100 / 54. 23.100
  libavcodec     56. 35.101 / 56. 35.101
  libavformat    56. 30.100 / 56. 30.100
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 14.100 /  5. 14.100
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mpegts, from 'multi-programs.ts':
  Duration: 00:05:00.03, start: 0.000278, bitrate: 1216 kb/s
  Program 1 
    Stream #0:0[0x65]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 4:3 DAR 16:9], 10 fps, 10 tbr, 90k tbn, 20 tbc
  Program 2 
    Stream #0:1[0x6f]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 4:3 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc
  Program 3 
    Stream #0:2[0x79]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 30 fps, 29.92 tbr, 90k tbn, 60 tbc
Output #0, mpegts, to 'multi-programs.out.ts':
  Metadata:
    encoder         : Lavf56.30.100
    Stream #0:0: Video: h264 ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 4:3 DAR 16:9], q=2-31, 10 fps, 10 tbr, 90k tbn, 10 tbc
    Stream #0:1: Video: h264 ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 4:3 DAR 16:9], q=2-31, 30 fps, 30 tbr, 90k tbn, 30 tbc
    Stream #0:2: Video: h264 ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 1:1 DAR 4:3], q=2-31, 30 fps, 29.92 tbr, 90k tbn, 30 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
  Stream #0:2 -> #0:2 (copy)
Press [q] to stop, [?] for help
frame= 2988 fps=0.0 q=-1.0 Lq=-1.0 q=-1.0 size=   47966kB time=00:05:00.02 bitrate=1309.7kbits/s    
video:42075kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 14.001903%
$ ffprobe multi-programs.out.ts 
ffprobe version N-71578-g57865a9 Copyright (c) 2007-2015 the FFmpeg developers
  built with gcc 4.8 (Ubuntu/Linaro 4.8.1-10ubuntu9)
  configuration: --extra-cflags=-I/home/stefano/include --extra-ldflags=-L/home/stefano/lib --enable-libopenjpeg --enable-pic --enable-fontconfig --enable-libass --enable-version3 --prefix=/home/stefano --disable-shared --enable-static --enable-debug=3 --enable-pthreads --disable-optimizations --enable-libvorbis --enable-gpl --enable-nonfree --enable-libmp3lame --enable-libtheora --enable-gpl --enable-x11grab --enable-frei0r --enable-libfaac --enable-libcaca --enable-libflite --enable-libzmq --enable-libfreetype --enable-libopencv --enable-libgme --enable-libcdio --enable-libvo-aacenc --enable-libx264 --enable-ladspa --enable-libquvi --enable-opengl --enable-libvpx --enable-libxcb
  libavutil      54. 23.100 / 54. 23.100
  libavcodec     56. 35.101 / 56. 35.101
  libavformat    56. 30.100 / 56. 30.100
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 14.100 /  5. 14.100
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mpegts, from 'multi-programs.out.ts':
  Duration: 00:05:00.03, start: 1.400000, bitrate: 1309 kb/s
  Program 1 
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 4:3 DAR 16:9], 10 fps, 10 tbr, 90k tbn, 20 tbc
    Stream #0:1[0x101]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 4:3 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:2[0x102]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 30 fps, 29.92 tbr, 90k tbn, 60 tbc

that is only a single program containing all the streams is written to the output.

Change History (4)

comment:1 by Carl Eugen Hoyos, 8 years ago

Keywords: program removed
Priority: normalwish

comment:2 by droid-xx, 3 years ago

Summary: Add multi-program support in mpegts muxerMulti-program structure of input is not preserved in MPEG-TS output

@saste I hope you don't mind me changing the title so as to make this bug report more clear.

The mentioned commit doesn't fix this particular case. This ticket refers to the original program structure of the input being completely lost upon transfer, i.e. all programs in a MPTS input are merged under a single program containing all streams from all input programs, effectively making an SPTS output. The same issue is described in #4734.

Example, a multi-program TS like this:

MyProgram
- Stream 1
- Stream 2
- Stream 3
OtherProgram
- Stream 4
- Stream 5
- Stream 6
- Stream 7
YetAnotherProgram
- Stream 8
- Stream 9

...will result in a single-program TS like this:

Service01
- Stream 1
- Stream 2
- Stream 3
- Stream 4
- Stream 5
- Stream 6
- Stream 7
- Stream 8
- Stream 9

Now if one also adds the -map_metadata 0:p option, the only difference in the resulting output will be the following:

MyProgram
- Stream 1
- Stream 2
- Stream 3
- Stream 4
- Stream 5
- Stream 6
- Stream 7
- Stream 8
- Stream 9

Which means that only the information of the first service is preserved, under which all other services are merged. All the remaining services are removed from the resulting SDT.

Unfortunately this is one of the many problems of the mpegts muxer regarding the loss of all kinds of information in the output. Other problem is the loss of almost all tables as per #9114, another is the loss of several other descriptors upon copying, e.g. all audio-related descriptors are dropped, etc.

comment:3 by Carl Eugen Hoyos, 3 years ago

Component: avformatffmpeg

comment:4 by Mike G, 12 months ago

I wish ffmpeg had a true "copy" handling for MPTS. Many times I just want to remux MPTS into a different protocol while keeping all the descriptors the same. You can get close by manually mapping, like

ffmpeg -i  INPUT -codec copy -flush_packets 0 -map p:3 -map p:4 -map p:5 -map p:6 -program title=Prog3:st=0:st=1:st=2 -program title=Prog4:st=6:st=3 -program title=Prog5:st=8:st=4 -program title=Prog6:st=7:st=5 -f mpegts OUTPUT

There is an issue with for live streams (like UDP/RTP) since FFmpeg may change the stream index (st) on subsequent probes, so you can't predict st=NN arg for bulky MPTS. If -program could take a PID argument, it would be worth a bounty.

A typical use case could be taking a broadcast TS and send out SRT, but while keeping everything about the source intact.

Last edited 12 months ago by Mike G (previous) (diff)
Note: See TracTickets for help on using tickets.