• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * SPDX-License-Identifier: LGPL-2.0-or-later
25  */
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30 
31 #include <stdio.h>
32 #include "gstbasetsmuxjpeg2000.h"
33 #include <string.h>
34 #include <gst/audio/audio.h>
35 #include <gst/base/gstbytewriter.h>
36 #include <gst/gst.h>
37 
38 #define GST_CAT_DEFAULT gst_base_ts_mux_debug
39 
40 GstBuffer *
gst_base_ts_mux_prepare_jpeg2000(GstBuffer * buf,GstBaseTsMuxPad * pad,GstBaseTsMux * mux)41 gst_base_ts_mux_prepare_jpeg2000 (GstBuffer * buf, GstBaseTsMuxPad * pad,
42     GstBaseTsMux * mux)
43 {
44   j2k_private_data *private_data = pad->prepare_data;
45   GstByteWriter wr;
46   GstBuffer *out_buf = NULL;
47   guint8 *elsm_header = NULL;
48   const guint header_size = private_data->interlace ? 48 : 38;
49   GstClockTime seconds = buf->pts / GST_SECOND;
50   GstClockTime minutes = seconds / 60;
51   GstClockTime hours = minutes / 60;
52 
53   /* interlaced not supported */
54   if (private_data->interlace) {
55     GST_ERROR_OBJECT (mux, "Interlaced not supported");
56     return NULL;
57   }
58 
59   seconds = seconds % 60;
60   minutes = minutes % 60;
61   hours = hours % 24;
62 
63   /* ??? Hack for missing frame number index in buffer offset */
64   /* guint8 frame_number = private_data->frame_number % 60; */
65   gst_byte_writer_init_with_size (&wr, header_size, FALSE);
66 
67   /* Elementary stream header box 'elsm' == 0x656c736d */
68   gst_byte_writer_put_uint32_be (&wr, 0x656c736d);
69   /* Framerate box 'frat' == 0x66726174 */
70   gst_byte_writer_put_uint32_be (&wr, 0x66726174);
71   /* put framerate denominator */
72   gst_byte_writer_put_uint16_be (&wr, private_data->den);
73   /* put framerate numerator */
74   gst_byte_writer_put_uint16_be (&wr, private_data->num);
75   /* Maximum bitrate box 'brat' == 0x62726174 */
76   gst_byte_writer_put_uint32_be (&wr, 0x62726174);
77   /* put Maximum bitrate */
78   gst_byte_writer_put_uint32_be (&wr, private_data->max_bitrate);
79   /* put size of first codestream */
80   /* private_data->AUF[0] */
81   gst_byte_writer_put_uint32_be (&wr, gst_buffer_get_size (buf));
82 
83   /* ToDo: the if block below is never called, because we do not support muxing J2K-over-mpeg-TS interlaced data
84    * If we ever do, then the code below will need to tested and perhaps modified
85    */
86   if (private_data->interlace) {
87     /* put size of second codestream */
88     gst_byte_writer_put_uint32_be (&wr, gst_buffer_get_size (buf));
89     /* Time Code Box 'fiel' == 0x6669656c */
90     gst_byte_writer_put_uint32_be (&wr, 0x6669656c);
91     /* put Fic */
92     gst_byte_writer_put_uint8 (&wr, private_data->Fic);
93     /* put Fio */
94     gst_byte_writer_put_uint8 (&wr, private_data->Fio);
95   }
96 
97   /* Time Code Box 'tcod' == 0x74636f64 */
98   gst_byte_writer_put_uint32_be (&wr, 0x74636f64);
99 
100   /* put HHMMSSFF */
101   gst_byte_writer_put_uint8 (&wr, (guint8) hours);
102   gst_byte_writer_put_uint8 (&wr, (guint8) minutes);
103   gst_byte_writer_put_uint8 (&wr, (guint8) seconds);
104   gst_byte_writer_put_uint8 (&wr, 0x0);
105   /* ??? Hack for missing frame number index in buffer offset */
106   /* private_data->frame_number++; */
107 
108   /* Broadcast Color Box 'bcol' == 0x62636f6c */
109   gst_byte_writer_put_uint32_be (&wr, 0x62636f6c);
110   /* put color spec */
111   gst_byte_writer_put_uint8 (&wr, private_data->color_spec);
112   /* put reserved 8-bit */
113   gst_byte_writer_put_uint8 (&wr, 0xff);
114   /* Allocate ELSM header size only; gst_buffer_copy_into will add gst_buffer_get_size (buf) bytes to out_buf */
115   out_buf = gst_buffer_new_and_alloc (header_size);
116 
117   /* Copy ELSM header */
118   elsm_header = gst_byte_writer_reset_and_get_data (&wr);
119   gst_buffer_fill (out_buf, 0, elsm_header, header_size);
120   g_free (elsm_header);
121   /* Copy complete frame */
122   gst_buffer_copy_into (out_buf, buf,
123       GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_TIMESTAMPS |
124       GST_BUFFER_COPY_MEMORY, 0, -1);
125   GST_DEBUG_OBJECT (mux, "Prepared J2K PES of size %d",
126       (int) gst_buffer_get_size (out_buf));
127 
128   return out_buf;
129 }
130 
131 void
gst_base_ts_mux_free_jpeg2000(gpointer prepare_data)132 gst_base_ts_mux_free_jpeg2000 (gpointer prepare_data)
133 {
134   /*  Free prepare data memory object */
135   g_free (prepare_data);
136 }
137