Aaron Boxer | bbbdc2c | 2017-07-19 10:14:21 -0400 | [diff] [blame] | 1 | /* GStreamer JPEG 2000 Parser |
| 2 | * |
| 3 | * Copyright (C) <2016> Milos Seleceni |
| 4 | * @author Milos Seleceni <milos.seleceni@comprimato.com> |
| 5 | * |
| 6 | * Copyright (C) <2016-2017> Grok Image Compression Inc. |
| 7 | * @author Aaron Boxer <boxerab@gmail.com> |
| 8 | * |
| 9 | * This library is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU Library General Public |
| 11 | * License as published by the Free Software Foundation; either |
| 12 | * version 2 of the License, or (at your option) any later version. |
| 13 | * |
| 14 | * This library is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | * Library General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU Library General Public |
| 20 | * License along with this library; if not, write to the |
| 21 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
| 22 | * Boston, MA 02110-1301, USA. |
| 23 | */ |
| 24 | |
| 25 | #ifdef HAVE_CONFIG_H |
| 26 | #include "config.h" |
| 27 | #endif |
| 28 | |
| 29 | #include <stdio.h> |
| 30 | #include "mpegtsmux_jpeg2000.h" |
| 31 | #include <string.h> |
| 32 | #include <gst/audio/audio.h> |
| 33 | #include <gst/base/gstbytewriter.h> |
| 34 | #include <gst/gst.h> |
| 35 | |
| 36 | #define GST_CAT_DEFAULT mpegtsmux_debug |
| 37 | |
| 38 | GstBuffer * |
| 39 | mpegtsmux_prepare_jpeg2000 (GstBuffer * buf, MpegTsPadData * data, |
| 40 | MpegTsMux * mux) |
| 41 | { |
| 42 | j2k_private_data *private_data = data->prepare_data; |
| 43 | GstByteWriter wr; |
| 44 | GstBuffer *out_buf = NULL; |
| 45 | guint8 *elsm_header = NULL; |
| 46 | const guint header_size = private_data->interlace ? 48 : 38; |
| 47 | GstClockTime seconds = buf->pts / GST_SECOND; |
| 48 | GstClockTime minutes = seconds / 60; |
| 49 | GstClockTime hours = minutes / 60; |
| 50 | |
| 51 | /* interlaced not supported */ |
| 52 | if (private_data->interlace) { |
| 53 | GST_ERROR_OBJECT (mux, "Interlaced not supported"); |
| 54 | return NULL; |
| 55 | } |
| 56 | |
| 57 | seconds = seconds % 60; |
| 58 | minutes = minutes % 60; |
| 59 | hours = hours % 24; |
| 60 | |
| 61 | /* ??? Hack for missing frame number index in buffer offset */ |
| 62 | /* guint8 frame_number = private_data->frame_number % 60; */ |
| 63 | gst_byte_writer_init_with_size (&wr, header_size, FALSE); |
| 64 | |
| 65 | /* Elementary stream header box 'elsm' == 0x656c736d */ |
| 66 | gst_byte_writer_put_uint32_be (&wr, 0x656c736d); |
| 67 | /* Framerate box 'frat' == 0x66726174 */ |
| 68 | gst_byte_writer_put_uint32_be (&wr, 0x66726174); |
| 69 | /* put framerate denominator */ |
| 70 | gst_byte_writer_put_uint16_be (&wr, private_data->den); |
| 71 | /* put framerate numerator */ |
| 72 | gst_byte_writer_put_uint16_be (&wr, private_data->num); |
| 73 | /* Maximum bitrate box 'brat' == 0x62726174 */ |
| 74 | gst_byte_writer_put_uint32_be (&wr, 0x62726174); |
| 75 | /* put Maximum bitrate */ |
| 76 | gst_byte_writer_put_uint32_be (&wr, private_data->max_bitrate); |
| 77 | /* put size of first codestream */ |
| 78 | /* private_data->AUF[0] */ |
| 79 | gst_byte_writer_put_uint32_be (&wr, gst_buffer_get_size (buf)); |
| 80 | |
| 81 | /* ToDo: the if block below is never called, because we do not support muxing J2K-over-mpeg-TS interlaced data |
| 82 | * If we ever do, then the code below will need to tested and perhaps modified |
| 83 | */ |
| 84 | if (private_data->interlace) { |
| 85 | /* put size of second codestream */ |
| 86 | gst_byte_writer_put_uint32_be (&wr, gst_buffer_get_size (buf)); |
| 87 | /* Time Code Box 'fiel' == 0x6669656c */ |
| 88 | gst_byte_writer_put_uint32_be (&wr, 0x6669656c); |
| 89 | /* put Fic */ |
| 90 | gst_byte_writer_put_uint8 (&wr, private_data->Fic); |
| 91 | /* put Fio */ |
| 92 | gst_byte_writer_put_uint8 (&wr, private_data->Fio); |
| 93 | } |
| 94 | |
| 95 | /* Time Code Box 'tcod' == 0x74636f64 */ |
| 96 | gst_byte_writer_put_uint32_be (&wr, 0x74636f64); |
| 97 | |
| 98 | /* put HHMMSSFF */ |
| 99 | gst_byte_writer_put_uint8 (&wr, (guint8) hours); |
| 100 | gst_byte_writer_put_uint8 (&wr, (guint8) minutes); |
| 101 | gst_byte_writer_put_uint8 (&wr, (guint8) seconds); |
| 102 | gst_byte_writer_put_uint8 (&wr, 0x0); |
| 103 | /* ??? Hack for missing frame number index in buffer offset */ |
| 104 | /* private_data->frame_number++; */ |
| 105 | |
| 106 | /* Broadcast Color Box 'bcol' == 0x62636f6c */ |
| 107 | gst_byte_writer_put_uint32_be (&wr, 0x62636f6c); |
| 108 | /* put color spec */ |
| 109 | gst_byte_writer_put_uint8 (&wr, private_data->color_spec); |
| 110 | /* put reserved 8-bit */ |
| 111 | gst_byte_writer_put_uint8 (&wr, 0xff); |
| 112 | /* Allocate ELSM header size only; gst_buffer_copy_into will add gst_buffer_get_size (buf) bytes to out_buf */ |
| 113 | out_buf = gst_buffer_new_and_alloc (header_size); |
| 114 | |
| 115 | /* Copy ELSM header */ |
| 116 | elsm_header = gst_byte_writer_reset_and_get_data (&wr); |
| 117 | gst_buffer_fill (out_buf, 0, elsm_header, header_size); |
| 118 | g_free (elsm_header); |
| 119 | /* Copy complete frame */ |
| 120 | gst_buffer_copy_into (out_buf, buf, |
| 121 | GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_TIMESTAMPS | |
| 122 | GST_BUFFER_COPY_MEMORY, 0, -1); |
| 123 | GST_DEBUG_OBJECT (mux, "Prepared J2K PES of size %d", |
| 124 | (int) gst_buffer_get_size (out_buf)); |
| 125 | |
| 126 | return out_buf; |
| 127 | } |
| 128 | |
| 129 | void |
| 130 | mpegtsmux_free_jpeg2000 (gpointer prepare_data) |
| 131 | { |
| 132 | /* Free prepare data memory object */ |
| 133 | g_free (prepare_data); |
| 134 | } |