From 4668330bdc810256027637cf9aac3178e769d6b9 Mon Sep 17 00:00:00 2001 From: Andoni Morales Alastruey Date: Wed, 1 Sep 2010 22:05:43 +0200 Subject: [PATCH] mpegtsmux: Initialize PES packet before getting the header size. The PES header length is calculated before setting the dynamic flags, returning a wrong value. Small frames that should be sent in a single TS packet are spawned to a new packet because of that error. For audio streams where a single frame can cope in one TS packet it introduces a huge overhead. For a 100B packet, we prepare a TS packet with a payload of(100+9)B. Then, we write the TS header using this value in tsmux_write_ts_header, and call tsmux_stream_get_data(). The dynamic flags where not set yet and now tsmux_stream_pes_header_length() returns 14B instead of 9B. The payload of the TS packet is 114B, 5B more than what was calculated. 109B are sent in a first packet and the remaining 5B are sent in another one. Fixes bug #628548. --- gst/mpegtsmux/tsmux/tsmux.c | 4 ++- gst/mpegtsmux/tsmux/tsmuxstream.c | 71 ++++++++++++++++++++++++--------------- gst/mpegtsmux/tsmux/tsmuxstream.h | 1 + 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/gst/mpegtsmux/tsmux/tsmux.c b/gst/mpegtsmux/tsmux/tsmux.c index a512186..1a50e72 100644 --- a/gst/mpegtsmux/tsmux/tsmux.c +++ b/gst/mpegtsmux/tsmux/tsmux.c @@ -767,8 +767,10 @@ tsmux_write_stream_packet (TsMux * mux, TsMuxStream * stream) } } - pi->stream_avail = tsmux_stream_bytes_avail (stream); pi->packet_start_unit_indicator = tsmux_stream_at_pes_start (stream); + if (pi->packet_start_unit_indicator) + tsmux_stream_initialize_pes_packet (stream); + pi->stream_avail = tsmux_stream_bytes_avail (stream); if (!tsmux_write_ts_header (mux->packet_buf, pi, &payload_len, &payload_offs)) return FALSE; diff --git a/gst/mpegtsmux/tsmux/tsmuxstream.c b/gst/mpegtsmux/tsmux/tsmuxstream.c index 3d848b4..62c244f 100644 --- a/gst/mpegtsmux/tsmux/tsmuxstream.c +++ b/gst/mpegtsmux/tsmux/tsmuxstream.c @@ -332,6 +332,50 @@ tsmux_stream_bytes_in_buffer (TsMuxStream * stream) } /** + * tsmux_stream_initialize_pes_packet: + * @stream: a #TsMuxStream + * + * Initializes the PES packet. + * + * Returns: TRUE if we the packet was initialized. + */ +gboolean +tsmux_stream_initialize_pes_packet (TsMuxStream * stream) +{ + if (stream->state != TSMUX_STREAM_STATE_HEADER) + return TRUE; + + if (stream->pes_payload_size != 0) { + /* Use prescribed fixed PES payload size */ + stream->cur_pes_payload_size = stream->pes_payload_size; + tsmux_stream_find_pts_dts_within (stream, stream->cur_pes_payload_size, + &stream->pts, &stream->dts); + } else if (stream->is_video_stream) { + /* Unbounded for video streams */ + stream->cur_pes_payload_size = 0; + tsmux_stream_find_pts_dts_within (stream, + tsmux_stream_bytes_in_buffer (stream), &stream->pts, &stream->dts); + } else { + /* Output a PES packet of all currently available bytes otherwise */ + stream->cur_pes_payload_size = tsmux_stream_bytes_in_buffer (stream); + tsmux_stream_find_pts_dts_within (stream, stream->cur_pes_payload_size, + &stream->pts, &stream->dts); + } + + stream->pi.flags &= ~(TSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS | + TSMUX_PACKET_FLAG_PES_WRITE_PTS); + + if (stream->pts != -1 && stream->dts != -1) + stream->pi.flags |= TSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS; + else { + if (stream->pts != -1) + stream->pi.flags |= TSMUX_PACKET_FLAG_PES_WRITE_PTS; + } + + return TRUE; +} + +/** * tsmux_stream_get_data: * @stream: a #TsMuxStream * @buf: a buffer to hold the result @@ -350,33 +394,6 @@ tsmux_stream_get_data (TsMuxStream * stream, guint8 * buf, guint len) if (stream->state == TSMUX_STREAM_STATE_HEADER) { guint8 pes_hdr_length; - if (stream->pes_payload_size != 0) { - /* Use prescribed fixed PES payload size */ - stream->cur_pes_payload_size = stream->pes_payload_size; - tsmux_stream_find_pts_dts_within (stream, stream->cur_pes_payload_size, - &stream->pts, &stream->dts); - } else if (stream->is_video_stream) { - /* Unbounded for video streams */ - stream->cur_pes_payload_size = 0; - tsmux_stream_find_pts_dts_within (stream, - tsmux_stream_bytes_in_buffer (stream), &stream->pts, &stream->dts); - } else { - /* Output a PES packet of all currently available bytes otherwise */ - stream->cur_pes_payload_size = tsmux_stream_bytes_in_buffer (stream); - tsmux_stream_find_pts_dts_within (stream, stream->cur_pes_payload_size, - &stream->pts, &stream->dts); - } - - stream->pi.flags &= ~(TSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS | - TSMUX_PACKET_FLAG_PES_WRITE_PTS); - - if (stream->pts != -1 && stream->dts != -1) - stream->pi.flags |= TSMUX_PACKET_FLAG_PES_WRITE_PTS_DTS; - else { - if (stream->pts != -1) - stream->pi.flags |= TSMUX_PACKET_FLAG_PES_WRITE_PTS; - } - pes_hdr_length = tsmux_stream_pes_header_length (stream); /* Submitted buffer must be at least as large as the PES header */ diff --git a/gst/mpegtsmux/tsmux/tsmuxstream.h b/gst/mpegtsmux/tsmux/tsmuxstream.h index 4ee6ae1..b384d39 100644 --- a/gst/mpegtsmux/tsmux/tsmuxstream.h +++ b/gst/mpegtsmux/tsmux/tsmuxstream.h @@ -212,6 +212,7 @@ void tsmux_stream_get_es_descrs (TsMuxStream *stream, guint8 *buf, guint16 *l gint tsmux_stream_bytes_in_buffer (TsMuxStream *stream); gint tsmux_stream_bytes_avail (TsMuxStream *stream); +gboolean tsmux_stream_initialize_pes_packet (TsMuxStream *stream); gboolean tsmux_stream_get_data (TsMuxStream *stream, guint8 *buf, guint len); guint64 tsmux_stream_get_pts (TsMuxStream *stream); -- 2.7.4