1 /**********************************************************************************************/
2 /* The MIT License                                                                            */
3 /*                                                                                            */
4 /* Copyright 2016-2017 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
5 /*                                                                                            */
6 /* Permission is hereby granted, free of charge, to any person obtaining a copy               */
7 /* of this software and associated documentation files (the "Software"), to deal              */
8 /* in the Software without restriction, including without limitation the rights               */
9 /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
10 /* copies of the Software, and to permit persons to whom the Software is                      */
11 /* furnished to do so, subject to the following conditions:                                   */
12 /*                                                                                            */
13 /* The above copyright notice and this permission notice shall be included in                 */
14 /* all copies or substantial portions of the Software.                                        */
15 /*                                                                                            */
16 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
17 /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
18 /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
19 /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
20 /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
21 /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
22 /* THE SOFTWARE.                                                                              */
23 /**********************************************************************************************/
24 #ifndef LIBCAPTION_MPEG_H
25 #define LIBCAPTION_MPEG_H
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #include "caption.h"
31 #include "cea708.h"
32 #include "scc.h"
33 #include <float.h>
34 #include <stddef.h>
35 ////////////////////////////////////////////////////////////////////////////////
36 #define STREAM_TYPE_H262 0x02
37 #define STREAM_TYPE_H264 0x1B
38 #define STREAM_TYPE_H265 0x24
39 #define H262_SEI_PACKET 0xB2
40 #define H264_SEI_PACKET 0x06
41 #define H265_SEI_PACKET 0x27 // There is also 0x28
42 #define MAX_NALU_SIZE (6 * 1024 * 1024)
43 #define MAX_REFRENCE_FRAMES 64
44 typedef struct {
45     size_t size;
46     uint8_t data[MAX_NALU_SIZE + 1];
47     double dts, cts;
48     libcaption_stauts_t status;
49     // Priority queue for out of order frame processing
50     // Should probablly be a linked list
51     size_t front;
52     size_t latent;
53     cea708_t cea708[MAX_REFRENCE_FRAMES];
54 } mpeg_bitstream_t;
55 
56 void mpeg_bitstream_init(mpeg_bitstream_t* packet);
57 ////////////////////////////////////////////////////////////////////////////////
58 // TODO make convenience functions for flv/mp4
59 /*! \brief
60     \param
61 */
62 size_t mpeg_bitstream_parse(mpeg_bitstream_t* packet, caption_frame_t* frame, const uint8_t* data, size_t size, unsigned stream_type, double dts, double cts);
63 /*! \brief
64     \param
65 */
mpeg_bitstream_status(mpeg_bitstream_t * packet)66 static inline libcaption_stauts_t mpeg_bitstream_status(mpeg_bitstream_t* packet) { return packet->status; }
67 /*! \brief
68         Flushes latent packets caused by out or order frames.
69         Returns number of latent frames remaining, 0 when complete;
70     \param
71 */
72 size_t mpeg_bitstream_flush(mpeg_bitstream_t* packet, caption_frame_t* frame);
73 ////////////////////////////////////////////////////////////////////////////////
74 typedef enum {
75     sei_type_buffering_period = 0,
76     sei_type_pic_timing = 1,
77     sei_type_pan_scan_rect = 2,
78     sei_type_filler_payload = 3,
79     sei_type_user_data_registered_itu_t_t35 = 4,
80     sei_type_user_data_unregistered = 5,
81     sei_type_recovery_point = 6,
82     sei_type_dec_ref_pic_marking_repetition = 7,
83     sei_type_spare_pic = 8,
84     sei_type_scene_info = 9,
85     sei_type_sub_seq_info = 10,
86     sei_type_sub_seq_layer_characteristics = 11,
87     sei_type_sub_seq_characteristics = 12,
88     sei_type_full_frame_freeze = 13,
89     sei_type_full_frame_freeze_release = 14,
90     sei_type_full_frame_snapshot = 15,
91     sei_type_progressive_refinement_segment_start = 16,
92     sei_type_progressive_refinement_segment_end = 17,
93     sei_type_motion_constrained_slice_group_set = 18,
94     sei_type_film_grain_characteristics = 19,
95     sei_type_deblocking_filter_display_preference = 20,
96     sei_type_stereo_video_info = 21,
97 } sei_msgtype_t;
98 ////////////////////////////////////////////////////////////////////////////////
99 typedef struct _sei_message_t {
100     size_t size;
101     sei_msgtype_t type;
102     struct _sei_message_t* next;
103 } sei_message_t;
104 
105 typedef struct {
106     double timestamp;
107     sei_message_t* head;
108     sei_message_t* tail;
109 } sei_t;
110 
111 /*! \brief
112     \param
113 */
114 void sei_init(sei_t* sei, double timestamp);
115 /*! \brief
116     \param
117 */
118 void sei_free(sei_t* sei);
119 /*! \brief
120     \param
121 */
122 void sei_cat(sei_t* to, sei_t* from, int itu_t_t35);
123 /*! \brief
124     \param
125 */
126 void sei_message_append(sei_t* sei, sei_message_t* msg);
127 /*! \brief
128     \param
129 */
130 libcaption_stauts_t sei_parse(sei_t* sei, const uint8_t* data, size_t size, double timestamp);
131 /*! \brief
132     \param
133 */
sei_message_head(sei_t * sei)134 static inline sei_message_t* sei_message_head(sei_t* sei) { return sei->head; }
135 /*! \brief
136     \param
137 */
sei_message_tail(sei_t * sei)138 static inline sei_message_t* sei_message_tail(sei_t* sei) { return sei->tail; }
139 /*! \brief
140     \param
141 */
142 sei_message_t* sei_message_next(sei_message_t* msg);
143 /*! \brief
144     \param
145 */
146 sei_msgtype_t sei_message_type(sei_message_t* msg);
147 /*! \brief
148     \param
149 */
150 size_t sei_message_size(sei_message_t* msg);
151 /*! \brief
152     \param
153 */
154 uint8_t* sei_message_data(sei_message_t* msg);
155 /*! \brief
156     \param
157 */
158 sei_message_t* sei_message_new(sei_msgtype_t type, uint8_t* data, size_t size);
159 /*! \brief
160     \param
161 */
sei_message_copy(sei_message_t * msg)162 static inline sei_message_t* sei_message_copy(sei_message_t* msg)
163 {
164     return sei_message_new(sei_message_type(msg), sei_message_data(msg), sei_message_size(msg));
165 }
166 /**
167 Free message and all accoiated data. Messaged added to sei_t by using sei_append_message MUST NOT be freed
168 These messages will be freed by calling sei_free()
169 */
170 /*! \brief
171     \param
172 */
173 void sei_message_free(sei_message_t* msg);
174 ////////////////////////////////////////////////////////////////////////////////
175 /*! \brief
176     \param
177 */
178 size_t sei_render_size(sei_t* sei);
179 /*! \brief
180     \param
181 */
182 size_t sei_render(sei_t* sei, uint8_t* data);
183 /*! \brief
184     \param
185 */
186 void sei_dump(sei_t* sei);
187 /*! \brief
188     \param
189 */
190 void sei_dump_messages(sei_message_t* head, double timestamp);
191 ////////////////////////////////////////////////////////////////////////////////
192 /*! \brief
193     \param
194 */
195 libcaption_stauts_t sei_from_scc(sei_t* sei, const scc_t* scc);
196 /*! \brief
197     \param
198 */
199 libcaption_stauts_t sei_from_caption_frame(sei_t* sei, caption_frame_t* frame);
200 /*! \brief
201     \param
202 */
203 libcaption_stauts_t sei_from_caption_clear(sei_t* sei);
204 /*! \brief
205     \param
206 */
207 libcaption_stauts_t sei_to_caption_frame(sei_t* sei, caption_frame_t* frame);
208 ////////////////////////////////////////////////////////////////////////////////
209 #ifdef __cplusplus
210 }
211 #endif
212 #endif
213