/**
* SECTION:element-rtpj2kpay
+ * @title: rtpj2kpay
*
* Payload encode JPEG 2000 images into RTP packets according to RFC 5371
* and RFC 5372.
* codestream. A "packetization unit" is defined as either a JPEG 2000 main header,
* a JPEG 2000 tile-part header, or a JPEG 2000 packet.
*
- *
*/
#ifdef HAVE_CONFIG_H
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("image/x-jpc")
+ GST_STATIC_CAPS ("image/x-jpc, " GST_RTP_J2K_SAMPLING_LIST)
);
+
static GstStaticPadTemplate gst_rtp_j2k_pay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
" media = (string) \"video\", "
" payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
" clock-rate = (int) 90000, "
- " encoding-name = (string) \"JPEG2000\"")
+ GST_RTP_J2K_SAMPLING_LIST "," " encoding-name = (string) \"JPEG2000\"")
);
GST_DEBUG_CATEGORY_STATIC (rtpj2kpay_debug);
gst_rtp_j2k_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps)
{
GstStructure *caps_structure = gst_caps_get_structure (caps, 0);
- GstRtpJ2KPay *pay;
- gint width = 0, height = 0;
gboolean res;
+ gint width = 0, height = 0;
+ const gchar *sampling = NULL;
- pay = GST_RTP_J2K_PAY (basepayload);
+ gboolean has_width = gst_structure_get_int (caps_structure, "width", &width);
+ gboolean has_height =
+ gst_structure_get_int (caps_structure, "height", &height);
- /* these properties are not mandatory, we can get them from the stream */
- if (gst_structure_get_int (caps_structure, "height", &height)) {
- pay->height = height;
- }
- if (gst_structure_get_int (caps_structure, "width", &width)) {
- pay->width = width;
- }
+
+ /* sampling is a required field */
+ sampling = gst_structure_get_string (caps_structure, "sampling");
gst_rtp_base_payload_set_options (basepayload, "video", TRUE, "JPEG2000",
90000);
- res = gst_rtp_base_payload_set_outcaps (basepayload, NULL);
+ if (has_width && has_height)
+ res = gst_rtp_base_payload_set_outcaps (basepayload,
+ "sampling", G_TYPE_STRING, sampling, "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height, NULL);
+ else
+ res =
+ gst_rtp_base_payload_set_outcaps (basepayload, "sampling",
+ G_TYPE_STRING, sampling, NULL);
return res;
}
typedef struct
{
RtpJ2KHeader header;
- gboolean multi_tile_part;
+ gboolean multi_tile;
gboolean bitstream;
guint next_sot;
gboolean force_packet;
/* Isot */
tile = GST_READ_UINT16_BE (&data[offset + 2]);
- if (!state->multi_tile_part) {
-
- /* tile is marked as valid */
- state->header.T = 0;
-
- /* we have detected multiple tile parts in this rtp packet : tile bit is now invalid */
- if (state->header.tile != tile) {
+ if (!state->multi_tile) {
+ /* we have detected multiple tiles in this rtp packet : tile bit is now invalid */
+ if (state->header.T == 0 && state->header.tile != tile) {
state->header.T = 1;
- state->multi_tile_part = TRUE;
+ state->multi_tile = TRUE;
+ } else {
+ state->header.T = 0;
}
}
state->header.tile = tile;
state.header.mh_id = 0; /* always 0 for now */
state.header.T = 1; /* invalid tile, because we always begin with the main header */
state.header.priority = 255; /* always 255 for now */
- state.header.tile = -1; /* no tile number */
+ state.header.tile = 0xffff; /* no tile number */
state.header.offset = 0; /* offset of 0 */
- state.multi_tile_part = FALSE;
+ state.multi_tile = FALSE;
state.bitstream = FALSE;
state.next_sot = 0;
state.force_packet = FALSE;
/* make subbuffer of j2k data */
paybuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL,
offset, data_size);
- gst_rtp_copy_meta (GST_ELEMENT_CAST (basepayload), outbuf, paybuf,
- g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
+ gst_rtp_copy_video_meta (basepayload, outbuf, paybuf);
outbuf = gst_buffer_append (outbuf, paybuf);
gst_buffer_list_add (list, outbuf);
/* reset multi_tile */
- state.multi_tile_part = FALSE;
+ state.multi_tile = FALSE;
/* set MHF to zero if there is no more main header to process */
offset = pos;
} while (offset < map.size);
+ gst_buffer_unmap (buffer, &map);
gst_buffer_unref (buffer);
/* push the whole buffer list at once */