0

I have two *.mpg files. I'd like to concatenate them by picking the video stream (MPEG-2) and the MP2 audio stream. My problem is that the streams are always reencoded. I'd like to avoid this, but I'm failing for many hours now trying different kind of things.

Input files:

Input #0, mpeg, from 'D:\a.mpg':
  Duration: 01:25:54.05, start: 0.500000, bitrate: 4528 kb/s
    Stream #0:0[0x1bf]: Data: dvd_nav_packet
    Stream #0:1[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 192 kb/s
    Stream #0:2[0x80]: Audio: ac3, 48000 Hz, stereo, fltp, 384 kb/s
    Stream #0:3[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, top first), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
Input #1, mpeg, from 'D:\b.mpg':
  Duration: 00:12:53.11, start: 0.500000, bitrate: 4486 kb/s
    Stream #1:0[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 192 kb/s
    Stream #1:1[0x80]: Audio: ac3, 48000 Hz, stereo, fltp, 384 kb/s
    Stream #1:2[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, top first), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc

FFmpeg args: (one of the many tried)

-i "d:\a.mpg" -i "d:\b.mpg" -filter_complex "[0:3][0:1][1:2][1:0]concat=n=2:v=1:a=1[v][a]" -map [v] -map [a]  "d:\c.mpg"

Output:

Stream mapping:
  Stream #0:1 (mp2) -> concat:in0:a0
  Stream #0:3 (mpeg2video) -> concat:in0:v0
  Stream #1:0 (mp2) -> concat:in1:a0
  Stream #1:2 (mpeg2video) -> concat:in1:v0
  concat:out:v0 -> Stream #0:0 (mpeg1video)
  concat:out:a0 -> Stream #0:1 (mp2)

As you can see, the output is "mpeg1video" even though the stream should just be copied. However, specifying "-c copy" isn't valid with a complex filter. "-f mpeg" and "-f dvd" for the output file also do not work. The latter does create an MPEG-2 video stream, but it causes reencoding, too, even though it's not necessary.

I do know the "-f concat" input format, but what am I missing trying to go this way? I know that FFmpeg is able to mux MPEG-2 video and MP2 audio into an .mpg file (PS format, not TS) because, if I just remux from input.ts to output.mpg specifying -c copy, it just copies the streams as intended. This shows that, if there's an MPEG-2 video stream, an MP2 audio stream and the destination file name's extension is ".mpg" it automatically uses the right muxer w/o reencoding. However, not in the case above.

Thanks for reading so far.

1

Two things: 1) unless you expressly set codec options to copy, FFmpeg will pick the default encoder, which means streams won't be copied. 2) The ffmpeg command you have shown uses the concat filter. The use of a filter on a stream necessitates that those streams will be re-encoded. That's because filters work on decoded frames, not the encoded ones present in the source(s). The streams which aren't processed by any filter can still be copied over.

Here, you'll have to use the concat demuxer, which you indicated you know of. But for the sake of completeness...

#1 Make a text file that says

file 'a.mpg'
file 'b.mpg'

#2 Concat

ffmpeg -f concat -i list.txt -c copy -map 0:v -map 0:a:0 c.mpg
  • Thanks Mulvya. I understand partially. I'm not sure why frames are decoded at all. The concat filter doesn't need decoded frames because it just concatenates the streams. Consequently, no encoding should be necessary afterwards. Does it mean that, every time a complex filter is used, FFmpeg decodes the frames in order to pass them to the filter(s)? (even though it's not required) Thx for the concat demuxer hints; that's how I did it. In the meantime, I've used mkvmerge to concat the files. Worked. Though I'm still interested for learning it for the future. – user674865 Dec 14 '16 at 13:04
  • Most filters work on image raster or audio samples, so it's by design. So, even though the concat filter itself doesn't need it, the frames still have to be decoded because filters before or after in the chain may need to. In the former case, decoded frames are needed, and in the latter, a decoder would have to be called in between filters, and as I understand it, that may be not worth it, if it's even possible in the current architecture. Only streams fed somewhere in the filter complex are decoded. – Gyan Dec 14 '16 at 13:13
  • Now I know why I could have tried everything to avoid reencoding. ;) Thank you. – user674865 Dec 14 '16 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy