mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 21:42:25 +00:00
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.
This commit is contained in:
parent
8af858cf8f
commit
4668330bdc
3 changed files with 48 additions and 28 deletions
|
@ -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);
|
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))
|
if (!tsmux_write_ts_header (mux->packet_buf, pi, &payload_len, &payload_offs))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -331,6 +331,50 @@ tsmux_stream_bytes_in_buffer (TsMuxStream * stream)
|
||||||
return stream->bytes_avail;
|
return stream->bytes_avail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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:
|
* tsmux_stream_get_data:
|
||||||
* @stream: a #TsMuxStream
|
* @stream: a #TsMuxStream
|
||||||
|
@ -350,33 +394,6 @@ tsmux_stream_get_data (TsMuxStream * stream, guint8 * buf, guint len)
|
||||||
if (stream->state == TSMUX_STREAM_STATE_HEADER) {
|
if (stream->state == TSMUX_STREAM_STATE_HEADER) {
|
||||||
guint8 pes_hdr_length;
|
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);
|
pes_hdr_length = tsmux_stream_pes_header_length (stream);
|
||||||
|
|
||||||
/* Submitted buffer must be at least as large as the PES header */
|
/* Submitted buffer must be at least as large as the PES header */
|
||||||
|
|
|
@ -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_in_buffer (TsMuxStream *stream);
|
||||||
gint tsmux_stream_bytes_avail (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);
|
gboolean tsmux_stream_get_data (TsMuxStream *stream, guint8 *buf, guint len);
|
||||||
|
|
||||||
guint64 tsmux_stream_get_pts (TsMuxStream *stream);
|
guint64 tsmux_stream_get_pts (TsMuxStream *stream);
|
||||||
|
|
Loading…
Reference in a new issue