How to use gstreamer to re-mux a single title out of a DVD without re-encoding
Michael Jones
jonesmz at jonesmz.com
Sun Mar 12 19:52:47 UTC 2023
Question also posted on stackoverflow:
https://stackoverflow.com/questions/75714501/use-gstreamer-to-remux-a-single-title-out-of-a-dvd-without-re-encoding
I am trying to re-mux the video of a specific title out of a DVD into
a video file, without decoding then re-encoding the video.
I have this pipeline that works exactly the way I want for audio, and
theoretically would work the way I want for video, but drops most
video buffers due to the error:
matroskamux matroska-mux.c:4035:gst_matros
ka_mux_write_data:<mux:video_0>
Invalid buffer timestamp; dropping buffer
The resulting video file plays, but is a slideshow, as one would
expect given all the dropped video buffers.
Here's the pipeline in question
#!/bin/bash
TITLE=2
DVD=~/BATTSTAR_GALAC_S1_D2.iso
GST_DEBUG=2 \
gst-launch-1.0 -v -e \
dvdreadsrc title=${TITLE} device=${DVD} \
! mpegpsdemux name=demux \
\
multiqueue name=queue \
demux. ! 'video/mpeg' ! queue. \
demux. ! 'audio/x-private1-ac3' ! queue. \
\
matroskamux name=mux \
queue. ! mpegvideoparse ! mux. \
queue. ! ac3parse ! mux. \
\
mux. ! filesink location=~/test.mkv
Here's another version of the same pipeline where I tried to inject
timestamping, which also does not work (not like I know what I'm
doing...)
#!/bin/bash
TITLE=2
DVD=~/BATTSTAR_GALAC_S1_D2.iso
GST_DEBUG=2 \
gst-launch-1.0 -v -e \
dvdreadsrc do-timestamp=true ! title=${TITLE} device=${DVD} \
! mpegpsdemux name=demux ignore-scr=true \
\
multiqueue name=queue \
demux. ! 'video/mpeg' ! queue. \
demux. ! 'audio/x-private1-ac3' ! queue. \
\
matroskamux name=mux \
queue. ! mpegvideoparse disable-passthrough=true ! mux. \
queue. ! ac3parse disable-passthrough=true ! mux. \
\
mux. ! filesink location=~/test.mkv
Thinking that perhaps something is wrong with the multiqueue, or with
synchronizing the video and the audio, I can still reproduce the
choppy video (dropped buffers) by removing the audio component of the
pipeline and switching from multiqueue to queue (not queue2, that ends
the pipeline before it gets to the end, I don't know why other than
speculating a bug).
#!/bin/bash
TITLE=2
DVD=~/BATTSTAR_GALAC_S1_D2.iso
GST_DEBUG=1 \
gst-launch-1.0 -v -e \
dvdreadsrc title=${TITLE} device=${DVD} \
! mpegpsdemux name=demux \
\
queue name=videoqueue \
demux. ! 'video/mpeg' ! videoqueue. \
\
matroskamux name=mux \
videoqueue. ! mpegvideoparse ! mux. \
\
mux. ! filesink location=~/test.mkv
Since I speculate a bug in queue2, what if I remove the queue
entirely? Still has the problem.
#!/bin/bash
TITLE=2
DVD=~/BATTSTAR_GALAC_S1_D2.iso
GST_DEBUG=1 \
gst-launch-1.0 -v -e \
dvdreadsrc title=${TITLE} device=${DVD} \
! mpegpsdemux \
! mpegvideoparse \
! matroskamux \
! filesink location=~/test.mkv
An important note is that I can play the video JUST FINE with gstreamer, e.g.
#!/bin/bash
TITLE=2
DVD=~/BATTSTAR_GALAC_S1_D2.iso
GST_DEBUG=2 \
gst-launch-1.0 -v -e \
dvdreadsrc title=${TITLE} device=${DVD} \
! mpegpsdemux \
! mpegvideoparse \
! mpeg2dec \
! autovideosink
and the same with working audio and video
#!/bin/bash
TITLE=2
DVD=~/BATTSTAR_GALAC_S1_D2.iso
GST_DEBUG=2 \
gst-launch-1.0 -v -e \
dvdreadsrc title=${TITLE} device=${DVD} \
! mpegpsdemux name=demux \
\
multiqueue name=queue \
demux. ! 'video/mpeg' ! queue. \
demux. ! 'audio/x-private1-ac3' ! queue. \
\
queue. ! mpegvideoparse ! mpeg2dec ! autovideosink \
queue. ! ac3parse ! a52dec ! autoaudiosink
So this is not a problem of the source video being bad, it's entirely
something that's missing from the pipeline.
I can even play the video while re-muxing it, and the on-screen video
is smooth, but the file saved to disk is choppy
#!/bin/bash
TITLE=2
DVD=~/BATTSTAR_GALAC_S1_D2.iso
GST_DEBUG=2 \
gst-launch-1.0 -v -e \
dvdreadsrc title=${TITLE} device=${DVD} \
! mpegpsdemux name=demux \
\
tee name=vtee \
tee name=atee \
demux. ! mpegvideoparse ! vtee. \
demux. ! ac3parse ! atee. \
\
multiqueue name=playqueue \
multiqueue name=convqueue \
vtee. ! playqueue. \
vtee. ! convqueue. \
atee. ! playqueue. \
atee. ! convqueue. \
\
playqueue. ! decodebin ! autovideosink \
playqueue. ! decodebin ! autoaudiosink \
\
matroskamux name=mux \
convqueue. ! mux. \
convqueue. ! mux. \
\
mux. ! filesink location=~/test.mkv
I can also extract the VOB file I want, and use filesrc instead of
dvdreadsrc, with the same result.
And here's a version of the pipeline that decodes the mpeg video and
then re-encodes mpeg video. This version produces a video file that is
not a slideshow, but has the problem of needing to re-encode the
video. I don't want to re-encode the video, I want to take it "as is".
#!/bin/bash
TITLE=2
DVD=~/BATTSTAR_GALAC_S1_D2.iso
GST_DEBUG=2 \
gst-launch-1.0 -v -e \
dvdreadsrc title=${TITLE} device=${DVD} \
! mpegpsdemux name=demux \
\
multiqueue name=queue \
demux. ! 'video/mpeg' ! queue. \
demux. ! 'audio/x-private1-ac3' ! queue. \
\
matroskamux name=mux \
queue. ! mpegvideoparse ! mpeg2dec ! mpeg2enc ! mux. \
queue. ! ac3parse ! mux. \
\
mux. ! filesink location=~/test.mkv
Note that I'm using gstreamer version 1.20.4, compiled and installed
on Gentoo Linux. It is possible that the 1.22 release series may have
a fix for my problem, but I don't see anything on the release notes
that make me think this was addressed:
https://gstreamer.freedesktop.org/releases/1.22/
________________________________
So what am I missing from my pipeline that prevents the buffers read
from the DVD from having a valid timestamp when they get to the
matroskamux ?
My best guess is that I need to insert something between
mpegvideoparse and the matroskmamux, but I don't know what it would
be.
More information about the gstreamer-devel
mailing list