@athoik
with dvbvideosink.patch xvid is not smooth anymore.
According to http://www.bretl.com/mpeghtml/DTS.HTM,
The Decode Time Stamp (DTS) indicates the time at which an access unit should be instantaneously removed from the receiver buffer and decoded. It differs from the Presentation Time Stamp (PTS) only when picture reordering is used for B pictures. If DTS is used, PTS must also be provided in the bit stream.
I did mistake when writing both DTS and PTS to PES:
if (pts && dts)
+ {
+ pes_header[9] = 0x61 | ((pts >> 29) & 0xE);
should be:
if (pts && dts)
+ {
+ pes_header[9] = 0x31 | ((pts >> 29) & 0xE);
I did test this(DTS written only when PTS is available) and still no sound/picture on divx3.
When DTS is written to PES header instead of PTS only then divx3 works.
So I'm suggesting following workaround:
diff --git a/gstdvbvideosink.c b/gstdvbvideosink.c
index d8d5635..52647ea 100755
--- a/gstdvbvideosink.c
+++ b/gstdvbvideosink.c
@@ -176,12 +176,14 @@ GST_STATIC_PAD_TEMPLATE (
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (
- "video/mpeg, "
#ifdef HAVE_MPEG4
- "mpegversion = (int) { 1, 2, 4 }, "
-#else
- "mpegversion = (int) { 1, 2 }, "
+ "video/mpeg, "
+ "mpegversion = (int) 4, "
+ "parsed = (boolean)true, "
+ VIDEO_CAPS "; "
#endif
+ "video/mpeg, "
+ "mpegversion = (int) { 1, 2 }, "
VIDEO_CAPS "; "
#ifdef HAVE_H264
"video/x-h264, "
@@ -323,6 +325,9 @@ static void gst_dvbvideosink_init(GstDVBVideoSink *self)
self->pesheader_buffer = NULL;
self->codec_data = NULL;
self->codec_type = CT_H264;
+#if GST_VERSION_MAJOR >= 1
+ self->use_dts = FALSE;
+#endif
#ifdef PACK_UNPACKED_XVID_DIVX5_BITSTREAM
self->must_pack_bitstream = FALSE;
self->num_non_keyframes = 0;
@@ -815,6 +820,9 @@ static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffe
}
}
#endif
+ /* remove dummy packed B-Frame */
+ if (self->codec_type == CT_MPEG4_PART2 && data_len <= 7)
+ goto ok;
pes_header[0] = 0;
pes_header[1] = 0;
@@ -837,7 +845,7 @@ static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffe
#if GST_VERSION_MAJOR < 1
if (GST_BUFFER_TIMESTAMP(buffer) != GST_CLOCK_TIME_NONE)
#else
- if (GST_BUFFER_PTS(buffer) != GST_CLOCK_TIME_NONE)
+ if ((self->use_dts && GST_BUFFER_DTS_IS_VALID(buffer)) || (!self->use_dts && GST_BUFFER_PTS_IS_VALID(buffer)))
#endif
{
pes_header[7] = 0x80; /* pts */
@@ -846,7 +854,10 @@ static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffe
#if GST_VERSION_MAJOR < 1
pes_set_pts(GST_BUFFER_TIMESTAMP(buffer), pes_header);
#else
- pes_set_pts(GST_BUFFER_PTS(buffer), pes_header);
+ if (self->use_dts)
+ pes_set_pts(GST_BUFFER_DTS(buffer), pes_header);
+ else
+ pes_set_pts(GST_BUFFER_PTS(buffer), pes_header);
#endif
if (self->codec_data)
@@ -1220,7 +1231,7 @@ static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffe
#if GST_VERSION_MAJOR < 1
if (GST_BUFFER_TIMESTAMP(buffer) != GST_CLOCK_TIME_NONE)
#else
- if (GST_BUFFER_PTS(buffer) != GST_CLOCK_TIME_NONE)
+ if ((self->use_dts && GST_BUFFER_DTS_IS_VALID(buffer)) || (!self->use_dts && GST_BUFFER_PTS_IS_VALID(buffer)))
#endif
{
self->pts_written = TRUE;
@@ -1495,6 +1506,9 @@ static gboolean gst_dvbvideosink_set_caps(GstBaseSink *basesink, GstCaps *caps)
B_SET_BITS("'100000'", 0x20, 5, 0);
streamtype = 13;
self->codec_type = CT_DIVX311;
+#if GST_VERSION_MAJOR >= 1
+ self->use_dts = TRUE;
+#endif
GST_INFO_OBJECT (self, "MIMETYPE video/x-divx vers. 3 -> VIDEO_SET_STREAMTYPE, 13");
#if GST_VERSION_MAJOR >= 1
gst_buffer_unmap(self->codec_data, &map);
diff --git a/gstdvbvideosink.h b/gstdvbvideosink.h
index e21d14d..40d1f20 100644
--- a/gstdvbvideosink.h
+++ b/gstdvbvideosink.h
@@ -80,6 +80,9 @@ struct _GstDVBVideoSink
GstBuffer *codec_data;
t_codec_type codec_type;
+#if GST_VERSION_MAJOR >= 1
+ gboolean use_dts;
+#endif
#ifdef PACK_UNPACKED_XVID_DIVX5_BITSTREAM
/* data needed to pack bitstream (divx5 / xvid) */