summaryrefslogtreecommitdiff
path: root/gst/mpegtsmux
diff options
context:
space:
mode:
authorAaron Boxer <boxerab@gmail.com>2017-07-19 10:14:21 -0400
committerSebastian Dröge <sebastian@centricular.com>2017-07-21 09:33:31 +0300
commitbbbdc2cd7ed282edabb6715a0b9b72d23676ee0f (patch)
treedb3a202dd0c96cff9b176ecc86cf6cc1db2d2b9c /gst/mpegtsmux
parent3e0db49f5b83e2b4ad4386c11c64a5d391c79256 (diff)
tsmux/tsdemux: Add support for JPEG2000
Based on patches by Milos Seleceni. https://bugzilla.gnome.org/show_bug.cgi?id=753323
Diffstat (limited to 'gst/mpegtsmux')
-rw-r--r--gst/mpegtsmux/Makefile.am6
-rw-r--r--gst/mpegtsmux/mpegtsmux.c122
-rw-r--r--gst/mpegtsmux/mpegtsmux_jpeg2000.c134
-rw-r--r--gst/mpegtsmux/mpegtsmux_jpeg2000.h63
-rw-r--r--gst/mpegtsmux/tsmux/tsmux.c2
-rw-r--r--gst/mpegtsmux/tsmux/tsmuxstream.c75
-rw-r--r--gst/mpegtsmux/tsmux/tsmuxstream.h11
7 files changed, 408 insertions, 5 deletions
diff --git a/gst/mpegtsmux/Makefile.am b/gst/mpegtsmux/Makefile.am
index 18d58d1ad..27c31c27b 100644
--- a/gst/mpegtsmux/Makefile.am
+++ b/gst/mpegtsmux/Makefile.am
@@ -6,7 +6,8 @@ libgstmpegtsmux_la_SOURCES = \
mpegtsmux.c \
mpegtsmux_aac.c \
mpegtsmux_ttxt.c \
- mpegtsmux_opus.c
+ mpegtsmux_opus.c \
+ mpegtsmux_jpeg2000.c
libgstmpegtsmux_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) $(GST_CFLAGS)
@@ -21,4 +22,5 @@ noinst_HEADERS = \
mpegtsmux.h \
mpegtsmux_aac.h \
mpegtsmux_ttxt.h \
- mpegtsmux_opus.h
+ mpegtsmux_opus.h \
+ mpegtsmux_jpeg2000.h
diff --git a/gst/mpegtsmux/mpegtsmux.c b/gst/mpegtsmux/mpegtsmux.c
index 67c2b72bc..98e97c3cf 100644
--- a/gst/mpegtsmux/mpegtsmux.c
+++ b/gst/mpegtsmux/mpegtsmux.c
@@ -98,6 +98,9 @@
#include "mpegtsmux_aac.h"
#include "mpegtsmux_ttxt.h"
#include "mpegtsmux_opus.h"
+#include "mpegtsmux_jpeg2000.h"
+#include <gst/videoparsers/gstjpeg2000parse.h>
+#include <gst/video/video-color.h>
GST_DEBUG_CATEGORY (mpegtsmux_debug);
#define GST_CAT_DEFAULT mpegtsmux_debug
@@ -125,6 +128,7 @@ static GstStaticPadTemplate mpegtsmux_sink_factory =
"mpegversion = (int) { 1, 2, 4 }, "
"systemstream = (boolean) false; "
"video/x-dirac;"
+ "image/x-jpc;"
"video/x-h264,stream-format=(string)byte-stream,"
"alignment=(string){au, nal}; "
"video/x-h265,stream-format=(string)byte-stream,"
@@ -149,7 +153,8 @@ static GstStaticPadTemplate mpegtsmux_sink_factory =
"audio/x-opus, "
"channels = (int) [1, 8], "
"channel-mapping-family = (int) {0, 1};"
- "subpicture/x-dvb; application/x-teletext; meta/x-klv, parsed=true"));
+ "subpicture/x-dvb; application/x-teletext; meta/x-klv, parsed=true;"
+ "image/x-jpc, profile = (int)[0, 49151];"));
static GstStaticPadTemplate mpegtsmux_src_factory =
GST_STATIC_PAD_TEMPLATE ("src",
@@ -588,6 +593,11 @@ mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data)
const GValue *value = NULL;
GstBuffer *codec_data = NULL;
guint8 opus_channel_config_code = 0;
+ guint16 profile = 0;
+ guint8 main_level = 0;
+ guint32 max_rate = 0;
+ guint8 color_spec = 0;
+ j2k_private_data *private_data = NULL;
pad = ts_data->collect.pad;
caps = gst_pad_get_current_caps (pad);
@@ -739,6 +749,94 @@ mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data)
ts_data->prepare_func = mpegtsmux_prepare_opus;
} else if (strcmp (mt, "meta/x-klv") == 0) {
st = TSMUX_ST_PS_KLV;
+ } else if (strcmp (mt, "image/x-jpc") == 0) {
+ /*
+ * See this document for more details on standard:
+ *
+ * https://www.itu.int/rec/T-REC-H.222.0-201206-S/en
+ * Annex S describes J2K details
+ * Page 104 of this document describes J2k video descriptor
+ */
+
+ const GValue *vProfile = gst_structure_get_value (s, "profile");
+ const GValue *vMainlevel = gst_structure_get_value (s, "main-level");
+ const GValue *vFramerate = gst_structure_get_value (s, "framerate");
+ const GValue *vColorimetry = gst_structure_get_value (s, "colorimetry");
+ private_data = g_new0 (j2k_private_data, 1);
+ profile = g_value_get_uint (vProfile);
+ if (profile != GST_JPEG2000_PARSE_PROFILE_BC_SINGLE) {
+ /* for now, we will relax the condition that the profile must equal GST_JPEG2000_PARSE_PROFILE_BC_SINGLE */
+ /*GST_ERROR_OBJECT (pad, "Invalid JPEG 2000 profile %d", profile);
+ goto not_negotiated; */
+ }
+ /* for now, we will relax the condition that the main level must be present */
+ if (vMainlevel) {
+ main_level = g_value_get_uint (vMainlevel);
+ if (main_level > 11) {
+ GST_ERROR_OBJECT (pad, "Invalid main level %d", main_level);
+ goto not_negotiated;
+ }
+ if (main_level >= 6) {
+ max_rate = 2 ^ (main_level - 6) * 1600 * 1000000;
+ } else {
+ switch (main_level) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ max_rate = 200 * 1000000;
+ break;
+ case 4:
+ max_rate = 400 * 1000000;
+ break;
+ case 5:
+ max_rate = 800 * 1000000;
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ /*GST_ERROR_OBJECT (pad, "Missing main level");
+ goto not_negotiated; */
+ }
+ /* We always mux video in J2K-over-MPEG-TS non-interlaced mode */
+ private_data->interlace = FALSE;
+ private_data->den = 0;
+ private_data->num = 0;
+ private_data->max_bitrate = max_rate;
+ private_data->color_spec = 1;
+ /* these two fields are not used, since we always mux as non-interlaced */
+ private_data->Fic = 1;
+ private_data->Fio = 0;
+
+ /* Get Framerate */
+ if (vFramerate != NULL) {
+ /* Data for ELSM header */
+ private_data->num = gst_value_get_fraction_numerator (vFramerate);
+ private_data->den = gst_value_get_fraction_denominator (vFramerate);
+ }
+ /* Get Colorimetry */
+ if (vColorimetry) {
+ const char *colorimetry = g_value_get_string (vColorimetry);
+ color_spec = GST_MPEGTS_JPEG2000_COLORSPEC_SRGB; /* RGB as default */
+ if (g_str_equal (colorimetry, GST_VIDEO_COLORIMETRY_BT601)) {
+ color_spec = GST_MPEGTS_JPEG2000_COLORSPEC_REC601;
+ } else {
+ if (g_str_equal (colorimetry, GST_VIDEO_COLORIMETRY_BT709)
+ || g_str_equal (colorimetry, GST_VIDEO_COLORIMETRY_SMPTE240M)) {
+ color_spec = GST_MPEGTS_JPEG2000_COLORSPEC_REC709;
+ }
+ }
+ private_data->color_spec = color_spec;
+ } else {
+ GST_ERROR_OBJECT (pad, "Colorimetry not present in caps");
+ goto not_negotiated;
+ }
+ st = TSMUX_ST_VIDEO_JP2K;
+ ts_data->prepare_func = mpegtsmux_prepare_jpeg2000;
+ ts_data->prepare_data = private_data;
+ ts_data->free_func = mpegtsmux_free_jpeg2000;
}
if (st != TSMUX_ST_RESERVED) {
@@ -749,10 +847,29 @@ mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data)
}
if (ts_data->stream != NULL) {
+ const char *interlace_mode = gst_structure_get_string (s, "interlace-mode");
gst_structure_get_int (s, "rate", &ts_data->stream->audio_sampling);
gst_structure_get_int (s, "channels", &ts_data->stream->audio_channels);
gst_structure_get_int (s, "bitrate", &ts_data->stream->audio_bitrate);
+ /* frame rate */
+ gst_structure_get_fraction (s, "framerate", &ts_data->stream->num,
+ &ts_data->stream->den);
+
+ /* Interlace mode */
+ ts_data->stream->interlace_mode = FALSE;
+ if (interlace_mode) {
+ ts_data->stream->interlace_mode =
+ g_str_equal (interlace_mode, "interleaved");
+ }
+ /* Width and Height */
+ gst_structure_get_int (s, "width", &ts_data->stream->horizontal_size);
+ gst_structure_get_int (s, "height", &ts_data->stream->vertical_size);
+
+ ts_data->stream->color_spec = color_spec;
+ ts_data->stream->max_bitrate = max_rate;
+ ts_data->stream->profile_and_level = profile | main_level;
+
ts_data->stream->opus_channel_config_code = opus_channel_config_code;
tsmux_stream_set_buffer_release_func (ts_data->stream, release_buffer_cb);
@@ -784,13 +901,12 @@ mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data)
}
GST_OBJECT_UNLOCK (mux);
#endif
-
gst_caps_unref (caps);
return ret;
-
/* ERRORS */
not_negotiated:
{
+ g_free (private_data);
GST_DEBUG_OBJECT (pad, "Sink pad caps were not set before pushing");
if (caps)
gst_caps_unref (caps);
diff --git a/gst/mpegtsmux/mpegtsmux_jpeg2000.c b/gst/mpegtsmux/mpegtsmux_jpeg2000.c
new file mode 100644
index 000000000..2e8db8c46
--- /dev/null
+++ b/gst/mpegtsmux/mpegtsmux_jpeg2000.c
@@ -0,0 +1,134 @@
+/* GStreamer JPEG 2000 Parser
+ *
+ * Copyright (C) <2016> Milos Seleceni
+ * @author Milos Seleceni <milos.seleceni@comprimato.com>
+ *
+ * Copyright (C) <2016-2017> Grok Image Compression Inc.
+ * @author Aaron Boxer <boxerab@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include "mpegtsmux_jpeg2000.h"
+#include <string.h>
+#include <gst/audio/audio.h>
+#include <gst/base/gstbytewriter.h>
+#include <gst/gst.h>
+
+#define GST_CAT_DEFAULT mpegtsmux_debug
+
+GstBuffer *
+mpegtsmux_prepare_jpeg2000 (GstBuffer * buf, MpegTsPadData * data,
+ MpegTsMux * mux)
+{
+ j2k_private_data *private_data = data->prepare_data;
+ GstByteWriter wr;
+ GstBuffer *out_buf = NULL;
+ guint8 *elsm_header = NULL;
+ const guint header_size = private_data->interlace ? 48 : 38;
+ GstClockTime seconds = buf->pts / GST_SECOND;
+ GstClockTime minutes = seconds / 60;
+ GstClockTime hours = minutes / 60;
+
+ /* interlaced not supported */
+ if (private_data->interlace) {
+ GST_ERROR_OBJECT (mux, "Interlaced not supported");
+ return NULL;
+ }
+
+ seconds = seconds % 60;
+ minutes = minutes % 60;
+ hours = hours % 24;
+
+ /* ??? Hack for missing frame number index in buffer offset */
+ /* guint8 frame_number = private_data->frame_number % 60; */
+ gst_byte_writer_init_with_size (&wr, header_size, FALSE);
+
+ /* Elementary stream header box 'elsm' == 0x656c736d */
+ gst_byte_writer_put_uint32_be (&wr, 0x656c736d);
+ /* Framerate box 'frat' == 0x66726174 */
+ gst_byte_writer_put_uint32_be (&wr, 0x66726174);
+ /* put framerate denominator */
+ gst_byte_writer_put_uint16_be (&wr, private_data->den);
+ /* put framerate numerator */
+ gst_byte_writer_put_uint16_be (&wr, private_data->num);
+ /* Maximum bitrate box 'brat' == 0x62726174 */
+ gst_byte_writer_put_uint32_be (&wr, 0x62726174);
+ /* put Maximum bitrate */
+ gst_byte_writer_put_uint32_be (&wr, private_data->max_bitrate);
+ /* put size of first codestream */
+ /* private_data->AUF[0] */
+ gst_byte_writer_put_uint32_be (&wr, gst_buffer_get_size (buf));
+
+ /* ToDo: the if block below is never called, because we do not support muxing J2K-over-mpeg-TS interlaced data
+ * If we ever do, then the code below will need to tested and perhaps modified
+ */
+ if (private_data->interlace) {
+ /* put size of second codestream */
+ gst_byte_writer_put_uint32_be (&wr, gst_buffer_get_size (buf));
+ /* Time Code Box 'fiel' == 0x6669656c */
+ gst_byte_writer_put_uint32_be (&wr, 0x6669656c);
+ /* put Fic */
+ gst_byte_writer_put_uint8 (&wr, private_data->Fic);
+ /* put Fio */
+ gst_byte_writer_put_uint8 (&wr, private_data->Fio);
+ }
+
+ /* Time Code Box 'tcod' == 0x74636f64 */
+ gst_byte_writer_put_uint32_be (&wr, 0x74636f64);
+
+ /* put HHMMSSFF */
+ gst_byte_writer_put_uint8 (&wr, (guint8) hours);
+ gst_byte_writer_put_uint8 (&wr, (guint8) minutes);
+ gst_byte_writer_put_uint8 (&wr, (guint8) seconds);
+ gst_byte_writer_put_uint8 (&wr, 0x0);
+ /* ??? Hack for missing frame number index in buffer offset */
+ /* private_data->frame_number++; */
+
+ /* Broadcast Color Box 'bcol' == 0x62636f6c */
+ gst_byte_writer_put_uint32_be (&wr, 0x62636f6c);
+ /* put color spec */
+ gst_byte_writer_put_uint8 (&wr, private_data->color_spec);
+ /* put reserved 8-bit */
+ gst_byte_writer_put_uint8 (&wr, 0xff);
+ /* Allocate ELSM header size only; gst_buffer_copy_into will add gst_buffer_get_size (buf) bytes to out_buf */
+ out_buf = gst_buffer_new_and_alloc (header_size);
+
+ /* Copy ELSM header */
+ elsm_header = gst_byte_writer_reset_and_get_data (&wr);
+ gst_buffer_fill (out_buf, 0, elsm_header, header_size);
+ g_free (elsm_header);
+ /* Copy complete frame */
+ gst_buffer_copy_into (out_buf, buf,
+ GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_TIMESTAMPS |
+ GST_BUFFER_COPY_MEMORY, 0, -1);
+ GST_DEBUG_OBJECT (mux, "Prepared J2K PES of size %d",
+ (int) gst_buffer_get_size (out_buf));
+
+ return out_buf;
+}
+
+void
+mpegtsmux_free_jpeg2000 (gpointer prepare_data)
+{
+ /* Free prepare data memory object */
+ g_free (prepare_data);
+}
diff --git a/gst/mpegtsmux/mpegtsmux_jpeg2000.h b/gst/mpegtsmux/mpegtsmux_jpeg2000.h
new file mode 100644
index 000000000..37ed433b7
--- /dev/null
+++ b/gst/mpegtsmux/mpegtsmux_jpeg2000.h
@@ -0,0 +1,63 @@
+/* GStreamer JPEG 2000 Parser
+ *
+ * Copyright (C) <2016> Milos Seleceni
+ * @author Milos Seleceni <milos.seleceni@comprimato.com>
+ *
+ * Copyright (C) <2016-2017> Grok Image Compression Inc.
+ * @author Aaron Boxer <boxerab@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MPEGTSMUX_JPEG2000_H__
+#define __MPEGTSMUX_JPEG2000_H__
+
+#include "mpegtsmux.h"
+
+/* color specifications for JPEG 2000 stream over MPEG TS */
+typedef enum
+{
+ GST_MPEGTS_JPEG2000_COLORSPEC_UNKNOWN,
+ GST_MPEGTS_JPEG2000_COLORSPEC_SRGB,
+ GST_MPEGTS_JPEG2000_COLORSPEC_REC601,
+ GST_MPEGTS_JPEG2000_COLORSPEC_REC709,
+ GST_MPEGTS_JPEG2000_COLORSPEC_CIELUV,
+ GST_MPEGTS_JPEG2000_COLORSPEC_CIEXYZ,
+ GST_MPEGTS_JPEG2000_COLORSPEC_REC2020,
+ GST_MPEGTS_JPEG2000_COLORSPEC_SMPTE2084
+} GstMpegTsJpeg2000ColorSpec;
+
+
+typedef struct j2k_private_data
+{
+ gboolean interlace;
+ guint16 den;
+ guint16 num;
+ /* Maximum bitrate box */
+ guint32 max_bitrate;
+ /* Field Coding Box */
+ guint8 Fic;
+ guint8 Fio;
+ /* Broadcast color box */
+ guint8 color_spec;
+} j2k_private_data;
+
+GstBuffer *mpegtsmux_prepare_jpeg2000 (GstBuffer * buf, MpegTsPadData * data,
+ MpegTsMux * mux);
+
+void mpegtsmux_free_jpeg2000 (gpointer prepare_data);
+
+#endif /* __MPEGTSMUX_JPEG2000_H__ */
diff --git a/gst/mpegtsmux/tsmux/tsmux.c b/gst/mpegtsmux/tsmux/tsmux.c
index ee2870498..24ae7e2b8 100644
--- a/gst/mpegtsmux/tsmux/tsmux.c
+++ b/gst/mpegtsmux/tsmux/tsmux.c
@@ -1104,6 +1104,8 @@ tsmux_write_stream_packet (TsMux * mux, TsMuxStream * stream)
gst_buffer_unmap (buf, &map);
+ GST_DEBUG_OBJECT (mux, "Writing PES of size %d",
+ (int) gst_buffer_get_size (buf));
res = tsmux_packet_out (mux, buf, cur_pcr);
/* Reset all dynamic flags */
diff --git a/gst/mpegtsmux/tsmux/tsmuxstream.c b/gst/mpegtsmux/tsmux/tsmuxstream.c
index f719d8f3f..4cbd21770 100644
--- a/gst/mpegtsmux/tsmux/tsmuxstream.c
+++ b/gst/mpegtsmux/tsmux/tsmuxstream.c
@@ -84,6 +84,7 @@
#include <string.h>
#include <gst/mpegts/mpegts.h>
+#include <gst/base/gstbytewriter.h>
#include "tsmuxcommon.h"
#include "tsmuxstream.h"
@@ -144,6 +145,11 @@ tsmux_stream_new (guint16 pid, TsMuxStreamType stream_type)
stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
stream->is_video_stream = TRUE;
break;
+ case TSMUX_ST_VIDEO_JP2K:
+ stream->id = 0xBD;
+ stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
+ stream->is_video_stream = TRUE;
+ break;
case TSMUX_ST_AUDIO_AAC:
case TSMUX_ST_AUDIO_MPEG1:
case TSMUX_ST_AUDIO_MPEG2:
@@ -768,6 +774,75 @@ tsmux_stream_get_es_descrs (TsMuxStream * stream,
descriptor = gst_mpegts_descriptor_from_registration ("drac", NULL, 0);
g_ptr_array_add (pmt_stream->descriptors, descriptor);
break;
+ case TSMUX_ST_VIDEO_JP2K:
+ {
+ /* J2K video descriptor
+ * descriptor_tag 8 uimsbf
+ * descriptor_length 8 uimsbf
+ * profile_and_level 16 uimsbf
+ * horizontal_size 32 uimsbf
+ * vertical_size 32 uimsbf
+ * max_bit_rate 32 uimsbf
+ * max_buffer_size 32 uimsbf
+ * DEN_frame_rate 16 uimsbf
+ * NUM_frame_rate 16 uimsbf
+ * color_specification 8 bslbf
+ * still_mode 1 bslbf
+ * interlace_video 1 bslbf
+ * reserved 6 bslbf
+ * private_data_byte 8 bslbf
+ */
+ gint8 still_interlace_reserved = 0x00;
+ int wr_size = 0;
+ guint8 *add_info = NULL;
+ guint8 level = stream->profile_and_level & 0xF;
+ guint32 max_buffer_size = 0;
+ GstByteWriter writer;
+ gst_byte_writer_init_with_size (&writer, 32, FALSE);
+
+ switch (level) {
+ case 1:
+ case 2:
+ case 3:
+ max_buffer_size = 1250000;
+ break;
+ case 4:
+ max_buffer_size = 2500000;
+ break;
+ case 5:
+ max_buffer_size = 5000000;
+ break;
+ case 6:
+ max_buffer_size = 10000000;
+ break;
+ default:
+ break;
+ }
+
+ gst_byte_writer_put_uint16_be (&writer, stream->profile_and_level);
+ gst_byte_writer_put_uint32_be (&writer, stream->horizontal_size);
+ gst_byte_writer_put_uint32_be (&writer, stream->vertical_size);
+ gst_byte_writer_put_uint32_be (&writer, max_buffer_size);
+ gst_byte_writer_put_uint32_be (&writer, stream->max_bitrate);
+ gst_byte_writer_put_uint16_be (&writer, stream->den);
+ gst_byte_writer_put_uint16_be (&writer, stream->num);
+ gst_byte_writer_put_uint8 (&writer, stream->color_spec);
+
+ if (stream->interlace_mode)
+ still_interlace_reserved |= 0x40;
+
+ gst_byte_writer_put_uint8 (&writer, still_interlace_reserved);
+ gst_byte_writer_put_uint8 (&writer, 0x00); /* private data byte */
+
+ wr_size = gst_byte_writer_get_size (&writer);
+ add_info = gst_byte_writer_reset_and_get_data (&writer);
+
+ descriptor =
+ gst_mpegts_descriptor_from_custom (GST_MTS_DESC_J2K_VIDEO, add_info,
+ wr_size);
+ g_ptr_array_add (pmt_stream->descriptors, descriptor);
+ }
+ break;
case TSMUX_ST_PS_AUDIO_AC3:
{
guint8 add_info[6];
diff --git a/gst/mpegtsmux/tsmux/tsmuxstream.h b/gst/mpegtsmux/tsmux/tsmuxstream.h
index 2766718ed..8befbe5f4 100644
--- a/gst/mpegtsmux/tsmux/tsmuxstream.h
+++ b/gst/mpegtsmux/tsmux/tsmuxstream.h
@@ -134,6 +134,7 @@ enum TsMuxStreamType {
TSMUX_ST_VIDEO_MPEG4 = 0x10,
TSMUX_ST_VIDEO_H264 = 0x1b,
TSMUX_ST_VIDEO_HEVC = 0x24,
+ TSMUX_ST_VIDEO_JP2K = 0x21,
/* private stream types */
TSMUX_ST_PS_AUDIO_AC3 = 0x81,
@@ -216,6 +217,16 @@ struct TsMuxStream {
/* Opus */
gboolean is_opus;
guint8 opus_channel_config_code;
+ /* Jpeg2000 */
+ gint32 horizontal_size;
+ gint32 vertical_size;
+ gint32 den;
+ gint32 num;
+ /* Maximum bitrate box */
+ guint32 max_bitrate;
+ guint16 profile_and_level;
+ gboolean interlace_mode;
+ guint8 color_spec;
};
/* stream management */