mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-08 18:39:54 +00:00
gstrtpjpegpay: Added Define Restart Interval (DRI) Marker
Added ability to detect and respond to a JPEG-defined DRI marker
This commit is contained in:
parent
8e73da10b3
commit
0f3151c73b
1 changed files with 62 additions and 2 deletions
|
@ -88,6 +88,7 @@ typedef enum _RtpJpegMarker RtpJpegMarker;
|
||||||
* @JPEG_MARKER_DHT: Define Huffman Table marker
|
* @JPEG_MARKER_DHT: Define Huffman Table marker
|
||||||
* @JPEG_MARKER_SOS: Start of Scan marker
|
* @JPEG_MARKER_SOS: Start of Scan marker
|
||||||
* @JPEG_MARKER_EOI: End of Image marker
|
* @JPEG_MARKER_EOI: End of Image marker
|
||||||
|
* @JPEG_MARKER_DRI: Define Restart Interval marker
|
||||||
*
|
*
|
||||||
* Identifers for markers in JPEG header
|
* Identifers for markers in JPEG header
|
||||||
*/
|
*/
|
||||||
|
@ -102,6 +103,7 @@ enum _RtpJpegMarker
|
||||||
JPEG_MARKER_DHT = 0xC4,
|
JPEG_MARKER_DHT = 0xC4,
|
||||||
JPEG_MARKER_SOS = 0xDA,
|
JPEG_MARKER_SOS = 0xDA,
|
||||||
JPEG_MARKER_EOI = 0xD9,
|
JPEG_MARKER_EOI = 0xD9,
|
||||||
|
JPEG_MARKER_DRI = 0xDD
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_JPEG_QUANT 255
|
#define DEFAULT_JPEG_QUANT 255
|
||||||
|
@ -182,6 +184,36 @@ typedef struct
|
||||||
const guint8 *data;
|
const guint8 *data;
|
||||||
} RtpQuantTable;
|
} RtpQuantTable;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RtpRestartMarkerHeader:
|
||||||
|
* @restartInterval: number of MCUs that appear between restart markers
|
||||||
|
* @restartFirstLastCount: a combination of the first packet mark in the chunk
|
||||||
|
* last packet mark in the chunk and the position of the
|
||||||
|
* first restart interval in the current "chunk"
|
||||||
|
*
|
||||||
|
* 0 1 2 3
|
||||||
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Restart Interval |F|L| Restart Count |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
*
|
||||||
|
* The restart marker header is implemented according to the following
|
||||||
|
* methodology specified in section 3.1.7 of rfc2435.txt.
|
||||||
|
*
|
||||||
|
* "If the restart intervals in a frame are not guaranteed to be aligned
|
||||||
|
* with packet boundaries, the F (first) and L (last) bits MUST be set
|
||||||
|
* to 1 and the Restart Count MUST be set to 0x3FFF. This indicates
|
||||||
|
* that a receiver MUST reassemble the entire frame before decoding it."
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
guint16 restartInterval;
|
||||||
|
guint16 restartFirstLastCount;
|
||||||
|
} RtpRestartMarkerHeader;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
guint8 id;
|
guint8 id;
|
||||||
|
@ -536,6 +568,7 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
GstFlowReturn ret = GST_FLOW_ERROR;
|
||||||
RtpJpegHeader jpeg_header;
|
RtpJpegHeader jpeg_header;
|
||||||
RtpQuantHeader quant_header;
|
RtpQuantHeader quant_header;
|
||||||
|
RtpRestartMarkerHeader restart_marker_header;
|
||||||
RtpQuantTable tables[15] = { {0, NULL}, };
|
RtpQuantTable tables[15] = { {0, NULL}, };
|
||||||
CompInfo info[3] = { {0,}, };
|
CompInfo info[3] = { {0,}, };
|
||||||
guint quant_data_size;
|
guint quant_data_size;
|
||||||
|
@ -546,7 +579,7 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
guint jpeg_header_size = 0;
|
guint jpeg_header_size = 0;
|
||||||
guint offset;
|
guint offset;
|
||||||
gboolean frame_done;
|
gboolean frame_done;
|
||||||
gboolean sos_found, sof_found, dqt_found;
|
gboolean sos_found, sof_found, dqt_found, dri_found;
|
||||||
gint i;
|
gint i;
|
||||||
GstBufferList *list = NULL;
|
GstBufferList *list = NULL;
|
||||||
GstBufferListIterator *it = NULL;
|
GstBufferListIterator *it = NULL;
|
||||||
|
@ -566,6 +599,7 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
sos_found = FALSE;
|
sos_found = FALSE;
|
||||||
dqt_found = FALSE;
|
dqt_found = FALSE;
|
||||||
sof_found = FALSE;
|
sof_found = FALSE;
|
||||||
|
dri_found = FALSE;
|
||||||
|
|
||||||
while (!sos_found && (offset < size)) {
|
while (!sos_found && (offset < size)) {
|
||||||
GST_LOG_OBJECT (pay, "checking from offset %u", offset);
|
GST_LOG_OBJECT (pay, "checking from offset %u", offset);
|
||||||
|
@ -597,6 +631,14 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
case JPEG_MARKER_SOI:
|
case JPEG_MARKER_SOI:
|
||||||
GST_LOG_OBJECT (pay, "SOI found");
|
GST_LOG_OBJECT (pay, "SOI found");
|
||||||
break;
|
break;
|
||||||
|
case JPEG_MARKER_DRI:
|
||||||
|
GST_LOG_OBJECT (pay, "DRI found");
|
||||||
|
restart_marker_header.restartInterval=g_htons((data[offset+2] << 8) | (data[offset + 3]));
|
||||||
|
restart_marker_header.restartFirstLastCount=g_htons(0xFFFF);
|
||||||
|
if (restart_marker_header.restartInterval > 0) {
|
||||||
|
dri_found = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -615,6 +657,9 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
data += jpeg_header_size;
|
data += jpeg_header_size;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|
||||||
|
if (dri_found)
|
||||||
|
pay->type += 64;
|
||||||
|
|
||||||
/* prepare stuff for the jpeg header */
|
/* prepare stuff for the jpeg header */
|
||||||
jpeg_header.type_spec = 0;
|
jpeg_header.type_spec = 0;
|
||||||
jpeg_header.type = pay->type;
|
jpeg_header.type = pay->type;
|
||||||
|
@ -659,6 +704,9 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
|
|
||||||
bytes_left = sizeof (jpeg_header) + quant_data_size + size;
|
bytes_left = sizeof (jpeg_header) + quant_data_size + size;
|
||||||
|
|
||||||
|
if (dri_found)
|
||||||
|
bytes_left += sizeof (restart_marker_header);
|
||||||
|
|
||||||
frame_done = FALSE;
|
frame_done = FALSE;
|
||||||
do {
|
do {
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
|
@ -666,8 +714,13 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
guint payload_size = (bytes_left < mtu ? bytes_left : mtu);
|
guint payload_size = (bytes_left < mtu ? bytes_left : mtu);
|
||||||
|
|
||||||
if (pay->buffer_list) {
|
if (pay->buffer_list) {
|
||||||
|
if (dri_found){
|
||||||
|
outbuf = gst_rtp_buffer_new_allocate (sizeof (jpeg_header) +
|
||||||
|
sizeof (restart_marker_header) + quant_data_size, 0, 0);
|
||||||
|
} else {
|
||||||
outbuf = gst_rtp_buffer_new_allocate (sizeof (jpeg_header) +
|
outbuf = gst_rtp_buffer_new_allocate (sizeof (jpeg_header) +
|
||||||
quant_data_size, 0, 0);
|
quant_data_size, 0, 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
outbuf = gst_rtp_buffer_new_allocate (payload_size, 0, 0);
|
outbuf = gst_rtp_buffer_new_allocate (payload_size, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -692,6 +745,13 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
payload += sizeof (jpeg_header);
|
payload += sizeof (jpeg_header);
|
||||||
payload_size -= sizeof (jpeg_header);
|
payload_size -= sizeof (jpeg_header);
|
||||||
|
|
||||||
|
if (dri_found)
|
||||||
|
{
|
||||||
|
memcpy (payload, &restart_marker_header, sizeof (restart_marker_header));
|
||||||
|
payload += sizeof (restart_marker_header);
|
||||||
|
payload_size -= sizeof (restart_marker_header);
|
||||||
|
}
|
||||||
|
|
||||||
/* only send quant table with first packet */
|
/* only send quant table with first packet */
|
||||||
if (G_UNLIKELY (quant_data_size > 0)) {
|
if (G_UNLIKELY (quant_data_size > 0)) {
|
||||||
memcpy (payload, &quant_header, sizeof (quant_header));
|
memcpy (payload, &quant_header, sizeof (quant_header));
|
||||||
|
|
Loading…
Reference in a new issue