mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
rtpj2kpay: manage fragmented headers correctly
J2K main header framentation across multiple RTP packets is now handled correctly https://bugzilla.gnome.org/show_bug.cgi?id=745187
This commit is contained in:
parent
d2765be120
commit
84ff5511de
1 changed files with 36 additions and 15 deletions
|
@ -188,6 +188,13 @@ typedef struct
|
||||||
gboolean force_packet;
|
gboolean force_packet;
|
||||||
} RtpJ2KState;
|
} RtpJ2KState;
|
||||||
|
|
||||||
|
|
||||||
|
/* Note: The standard recommends that headers be put in their own RTP packets, so we follow
|
||||||
|
* this recommendation in the code. Also, this method groups together all J2K packets
|
||||||
|
* for a tile part and treats this group as a packetization unit. According to the RFC,
|
||||||
|
* only an individual J2K packet is considered a packetization unit.
|
||||||
|
*/
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
find_pu_end (GstRtpJ2KPay * pay, const guint8 * data, guint size,
|
find_pu_end (GstRtpJ2KPay * pay, const guint8 * data, guint size,
|
||||||
guint offset, RtpJ2KState * state)
|
guint offset, RtpJ2KState * state)
|
||||||
|
@ -230,14 +237,18 @@ find_pu_end (GstRtpJ2KPay * pay, const guint8 * data, guint size,
|
||||||
switch (marker) {
|
switch (marker) {
|
||||||
case GST_J2K_MARKER_SOC:
|
case GST_J2K_MARKER_SOC:
|
||||||
GST_LOG_OBJECT (pay, "found SOC at %u", offset);
|
GST_LOG_OBJECT (pay, "found SOC at %u", offset);
|
||||||
state->header.MHF = 1;
|
/* start off by assuming that we will fit the entire header
|
||||||
|
into the RTP payload */
|
||||||
|
state->header.MHF = 3;
|
||||||
break;
|
break;
|
||||||
case GST_J2K_MARKER_SOT:
|
case GST_J2K_MARKER_SOT:
|
||||||
{
|
{
|
||||||
guint len, Psot;
|
guint len, Psot;
|
||||||
|
|
||||||
GST_LOG_OBJECT (pay, "found SOT at %u", offset);
|
GST_LOG_OBJECT (pay, "found SOT at %u", offset);
|
||||||
/* we found SOT but also had a header first */
|
/* SOT for first tile part in code stream:
|
||||||
|
force close of current RTP packet, so that it
|
||||||
|
only contains main header */
|
||||||
if (state->header.MHF) {
|
if (state->header.MHF) {
|
||||||
state->force_packet = TRUE;
|
state->force_packet = TRUE;
|
||||||
return offset - 2;
|
return offset - 2;
|
||||||
|
@ -424,19 +435,27 @@ gst_rtp_j2k_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
header = gst_rtp_buffer_get_payload (&rtp);
|
header = gst_rtp_buffer_get_payload (&rtp);
|
||||||
|
|
||||||
pu_size -= data_size;
|
pu_size -= data_size;
|
||||||
if (pu_size == 0) {
|
|
||||||
/* reached the end of a packetization unit */
|
/* reached the end of a packetization unit */
|
||||||
if (state.header.MHF) {
|
if (pu_size == 0 && end >= map.size) {
|
||||||
/* we were doing a header, see if all fit in one packet or if
|
|
||||||
* we had to fragment it */
|
|
||||||
if (offset == 0)
|
|
||||||
state.header.MHF = 3;
|
|
||||||
else
|
|
||||||
state.header.MHF = 2;
|
|
||||||
}
|
|
||||||
if (end >= map.size)
|
|
||||||
gst_rtp_buffer_set_marker (&rtp, TRUE);
|
gst_rtp_buffer_set_marker (&rtp, TRUE);
|
||||||
}
|
}
|
||||||
|
/* If we were processing a header, see if all fits in one RTP packet
|
||||||
|
or if we have to fragment it */
|
||||||
|
if (state.header.MHF) {
|
||||||
|
switch (state.header.MHF) {
|
||||||
|
case 3:
|
||||||
|
if (pu_size > 0)
|
||||||
|
state.header.MHF = 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (pu_size == 0)
|
||||||
|
state.header.MHF = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RtpJ2KHeader:
|
* RtpJ2KHeader:
|
||||||
|
@ -478,11 +497,13 @@ gst_rtp_j2k_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
|
|
||||||
gst_buffer_list_add (list, outbuf);
|
gst_buffer_list_add (list, outbuf);
|
||||||
|
|
||||||
/* reset header for next round */
|
|
||||||
state.header.MHF = 0;
|
|
||||||
state.header.T = 1;
|
state.header.T = 1;
|
||||||
state.header.tile = 0;
|
state.header.tile = 0;
|
||||||
|
|
||||||
|
/* set MHF to zero if there is no more main header to process */
|
||||||
|
if (state.header.MHF & 2)
|
||||||
|
state.header.MHF = 0;
|
||||||
|
|
||||||
offset += data_size;
|
offset += data_size;
|
||||||
state.header.offset = offset;
|
state.header.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue