mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-20 06:08:14 +00:00
rtph264pay: do DTS and PTS correctly
This commit is contained in:
parent
0525fa1850
commit
d65de434f5
1 changed files with 33 additions and 27 deletions
|
@ -697,7 +697,7 @@ next_start_code (const guint8 * data, guint size)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_rtp_h264_pay_decode_nal (GstRtpH264Pay * payloader,
|
gst_rtp_h264_pay_decode_nal (GstRtpH264Pay * payloader,
|
||||||
const guint8 * data, guint size, GstClockTime timestamp)
|
const guint8 * data, guint size, GstClockTime dts, GstClockTime pts)
|
||||||
{
|
{
|
||||||
const guint8 *sps = NULL, *pps = NULL;
|
const guint8 *sps = NULL, *pps = NULL;
|
||||||
guint sps_len = 0, pps_len = 0;
|
guint sps_len = 0, pps_len = 0;
|
||||||
|
@ -725,8 +725,8 @@ gst_rtp_h264_pay_decode_nal (GstRtpH264Pay * payloader,
|
||||||
sps = data;
|
sps = data;
|
||||||
sps_len = len;
|
sps_len = len;
|
||||||
/* remember when we last saw SPS */
|
/* remember when we last saw SPS */
|
||||||
if (timestamp != -1)
|
if (pts != -1)
|
||||||
payloader->last_spspps = timestamp;
|
payloader->last_spspps = pts;
|
||||||
} else if (PPS_TYPE_ID == type) {
|
} else if (PPS_TYPE_ID == type) {
|
||||||
/* encoder the entire PPS NAL in base64 */
|
/* encoder the entire PPS NAL in base64 */
|
||||||
GST_DEBUG ("Found PPS %x %x %x Len = %u",
|
GST_DEBUG ("Found PPS %x %x %x Len = %u",
|
||||||
|
@ -735,8 +735,8 @@ gst_rtp_h264_pay_decode_nal (GstRtpH264Pay * payloader,
|
||||||
pps = data;
|
pps = data;
|
||||||
pps_len = len;
|
pps_len = len;
|
||||||
/* remember when we last saw PPS */
|
/* remember when we last saw PPS */
|
||||||
if (timestamp != -1)
|
if (pts != -1)
|
||||||
payloader->last_spspps = timestamp;
|
payloader->last_spspps = pts;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("NAL: %x %x %x Len = %u", (header >> 7),
|
GST_DEBUG ("NAL: %x %x %x Len = %u", (header >> 7),
|
||||||
(header >> 5) & 3, type, len);
|
(header >> 5) & 3, type, len);
|
||||||
|
@ -812,12 +812,12 @@ gst_rtp_h264_pay_decode_nal (GstRtpH264Pay * payloader,
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
|
gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
|
||||||
const guint8 * data, guint size, GstClockTime timestamp,
|
const guint8 * data, guint size, GstClockTime dts, GstClockTime pts,
|
||||||
GstBuffer * buffer_orig, gboolean end_of_au);
|
GstBuffer * buffer_orig, gboolean end_of_au);
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload,
|
gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload,
|
||||||
GstRtpH264Pay * rtph264pay, GstClockTime timestamp)
|
GstRtpH264Pay * rtph264pay, GstClockTime dts, GstClockTime pts)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GList *walk;
|
GList *walk;
|
||||||
|
@ -830,7 +830,7 @@ gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload,
|
||||||
/* resend SPS */
|
/* resend SPS */
|
||||||
gst_buffer_map (sps_buf, &map, GST_MAP_READ);
|
gst_buffer_map (sps_buf, &map, GST_MAP_READ);
|
||||||
ret = gst_rtp_h264_pay_payload_nal (basepayload,
|
ret = gst_rtp_h264_pay_payload_nal (basepayload,
|
||||||
map.data, map.size, timestamp, sps_buf, FALSE);
|
map.data, map.size, dts, pts, sps_buf, FALSE);
|
||||||
gst_buffer_unmap (sps_buf, &map);
|
gst_buffer_unmap (sps_buf, &map);
|
||||||
/* Not critical here; but throw a warning */
|
/* Not critical here; but throw a warning */
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
|
@ -843,22 +843,22 @@ gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload,
|
||||||
/* resend PPS */
|
/* resend PPS */
|
||||||
gst_buffer_map (pps_buf, &map, GST_MAP_READ);
|
gst_buffer_map (pps_buf, &map, GST_MAP_READ);
|
||||||
ret = gst_rtp_h264_pay_payload_nal (basepayload,
|
ret = gst_rtp_h264_pay_payload_nal (basepayload,
|
||||||
map.data, map.size, timestamp, pps_buf, FALSE);
|
map.data, map.size, dts, pts, pps_buf, FALSE);
|
||||||
gst_buffer_unmap (pps_buf, &map);
|
gst_buffer_unmap (pps_buf, &map);
|
||||||
/* Not critical here; but throw a warning */
|
/* Not critical here; but throw a warning */
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
GST_WARNING ("Problem pushing PPS");
|
GST_WARNING ("Problem pushing PPS");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timestamp != -1)
|
if (pts != -1)
|
||||||
rtph264pay->last_spspps = timestamp;
|
rtph264pay->last_spspps = pts;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
|
gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
|
||||||
const guint8 * data, guint size, GstClockTime timestamp,
|
const guint8 * data, guint size, GstClockTime dts, GstClockTime pts,
|
||||||
GstBuffer * buffer_orig, gboolean end_of_au)
|
GstBuffer * buffer_orig, gboolean end_of_au)
|
||||||
{
|
{
|
||||||
GstRtpH264Pay *rtph264pay;
|
GstRtpH264Pay *rtph264pay;
|
||||||
|
@ -888,11 +888,11 @@ gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
|
||||||
|
|
||||||
GST_LOG_OBJECT (rtph264pay,
|
GST_LOG_OBJECT (rtph264pay,
|
||||||
"now %" GST_TIME_FORMAT ", last SPS/PPS %" GST_TIME_FORMAT,
|
"now %" GST_TIME_FORMAT ", last SPS/PPS %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (timestamp), GST_TIME_ARGS (rtph264pay->last_spspps));
|
GST_TIME_ARGS (pts), GST_TIME_ARGS (rtph264pay->last_spspps));
|
||||||
|
|
||||||
/* calculate diff between last SPS/PPS in milliseconds */
|
/* calculate diff between last SPS/PPS in milliseconds */
|
||||||
if (timestamp > rtph264pay->last_spspps)
|
if (pts > rtph264pay->last_spspps)
|
||||||
diff = timestamp - rtph264pay->last_spspps;
|
diff = pts - rtph264pay->last_spspps;
|
||||||
else
|
else
|
||||||
diff = 0;
|
diff = 0;
|
||||||
|
|
||||||
|
@ -913,10 +913,10 @@ gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (send_spspps || rtph264pay->send_spspps) {
|
if (send_spspps || rtph264pay->send_spspps) {
|
||||||
/* we need to send SPS/PPS now first. FIXME, don't use the timestamp for
|
/* we need to send SPS/PPS now first. FIXME, don't use the pts for
|
||||||
* checking when we need to send SPS/PPS but convert to running_time first. */
|
* checking when we need to send SPS/PPS but convert to running_time first. */
|
||||||
rtph264pay->send_spspps = FALSE;
|
rtph264pay->send_spspps = FALSE;
|
||||||
ret = gst_rtp_h264_pay_send_sps_pps (basepayload, rtph264pay, timestamp);
|
ret = gst_rtp_h264_pay_send_sps_pps (basepayload, rtph264pay, dts, pts);
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -950,7 +950,8 @@ gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* timestamp the outbuffer */
|
/* timestamp the outbuffer */
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
GST_BUFFER_PTS (outbuf) = pts;
|
||||||
|
GST_BUFFER_DTS (outbuf) = dts;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (rtph264pay->buffer_list) {
|
if (rtph264pay->buffer_list) {
|
||||||
|
@ -1034,7 +1035,8 @@ gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
|
||||||
|
|
||||||
gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
|
gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
GST_BUFFER_DTS (outbuf) = dts;
|
||||||
|
GST_BUFFER_PTS (outbuf) = pts;
|
||||||
payload = gst_rtp_buffer_get_payload (&rtp);
|
payload = gst_rtp_buffer_get_payload (&rtp);
|
||||||
|
|
||||||
if (limitedSize == size) {
|
if (limitedSize == size) {
|
||||||
|
@ -1112,7 +1114,7 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
guint nal_len, i;
|
guint nal_len, i;
|
||||||
GstMapInfo map;
|
GstMapInfo map;
|
||||||
const guint8 *data, *nal_data;
|
const guint8 *data, *nal_data;
|
||||||
GstClockTime timestamp;
|
GstClockTime dts, pts;
|
||||||
GArray *nal_queue;
|
GArray *nal_queue;
|
||||||
guint pushed = 0;
|
guint pushed = 0;
|
||||||
gboolean bytestream;
|
gboolean bytestream;
|
||||||
|
@ -1124,7 +1126,8 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
bytestream = (rtph264pay->scan_mode == GST_H264_SCAN_MODE_BYTESTREAM);
|
bytestream = (rtph264pay->scan_mode == GST_H264_SCAN_MODE_BYTESTREAM);
|
||||||
|
|
||||||
if (bytestream) {
|
if (bytestream) {
|
||||||
timestamp = gst_adapter_prev_timestamp (rtph264pay->adapter, NULL);
|
dts = gst_adapter_prev_dts (rtph264pay->adapter, NULL);
|
||||||
|
pts = gst_adapter_prev_pts (rtph264pay->adapter, NULL);
|
||||||
gst_adapter_push (rtph264pay->adapter, buffer);
|
gst_adapter_push (rtph264pay->adapter, buffer);
|
||||||
size = gst_adapter_available (rtph264pay->adapter);
|
size = gst_adapter_available (rtph264pay->adapter);
|
||||||
data = gst_adapter_map (rtph264pay->adapter, size);
|
data = gst_adapter_map (rtph264pay->adapter, size);
|
||||||
|
@ -1132,13 +1135,16 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
"got %" G_GSIZE_FORMAT " bytes (%" G_GSIZE_FORMAT ")", size,
|
"got %" G_GSIZE_FORMAT " bytes (%" G_GSIZE_FORMAT ")", size,
|
||||||
gst_buffer_get_size (buffer));
|
gst_buffer_get_size (buffer));
|
||||||
|
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (timestamp))
|
if (!GST_CLOCK_TIME_IS_VALID (dts))
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
dts = GST_BUFFER_DTS (buffer);
|
||||||
|
if (!GST_CLOCK_TIME_IS_VALID (pts))
|
||||||
|
pts = GST_BUFFER_PTS (buffer);
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_map (buffer, &map, GST_MAP_READ);
|
gst_buffer_map (buffer, &map, GST_MAP_READ);
|
||||||
data = map.data;
|
data = map.data;
|
||||||
size = map.size;
|
size = map.size;
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
pts = GST_BUFFER_PTS (buffer);
|
||||||
|
dts = GST_BUFFER_DTS (buffer);
|
||||||
GST_DEBUG_OBJECT (basepayload, "got %" G_GSIZE_FORMAT " bytes", size);
|
GST_DEBUG_OBJECT (basepayload, "got %" G_GSIZE_FORMAT " bytes", size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1182,7 +1188,7 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
gst_rtp_h264_pay_payload_nal (basepayload, data, nal_len, timestamp,
|
gst_rtp_h264_pay_payload_nal (basepayload, data, nal_len, dts, pts,
|
||||||
buffer, end_of_au);
|
buffer, end_of_au);
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
break;
|
break;
|
||||||
|
@ -1264,7 +1270,7 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
* go parse it for SPS/PPS to enrich the caps */
|
* go parse it for SPS/PPS to enrich the caps */
|
||||||
/* order: make sure to check nal */
|
/* order: make sure to check nal */
|
||||||
update =
|
update =
|
||||||
gst_rtp_h264_pay_decode_nal (rtph264pay, data, nal_len, timestamp)
|
gst_rtp_h264_pay_decode_nal (rtph264pay, data, nal_len, dts, pts)
|
||||||
|| update;
|
|| update;
|
||||||
}
|
}
|
||||||
/* move to next NAL packet */
|
/* move to next NAL packet */
|
||||||
|
@ -1315,7 +1321,7 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
|
|
||||||
/* put the data in one or more RTP packets */
|
/* put the data in one or more RTP packets */
|
||||||
ret =
|
ret =
|
||||||
gst_rtp_h264_pay_payload_nal (basepayload, data, size, timestamp,
|
gst_rtp_h264_pay_payload_nal (basepayload, data, size, dts, pts,
|
||||||
buffer, end_of_au);
|
buffer, end_of_au);
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue