| /* 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); |
| } |