/src/vlc/modules/packetizer/hxxx_common.c
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * hxxx_common.c: AVC/HEVC packetizers shared code |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2001-2015 VLC authors and VideoLAN |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify it |
7 | | * under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation; either version 2.1 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public License |
17 | | * along with this program; if not, write to the Free Software Foundation, |
18 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
19 | | *****************************************************************************/ |
20 | | #ifdef HAVE_CONFIG_H |
21 | | # include "config.h" |
22 | | #endif |
23 | | |
24 | | #include <vlc_common.h> |
25 | | #include <vlc_block.h> |
26 | | #include <vlc_codec.h> |
27 | | |
28 | | #include "hxxx_common.h" |
29 | | #include "../codec/cc.h" |
30 | | |
31 | | /**************************************************************************** |
32 | | * Closed captions handling |
33 | | ****************************************************************************/ |
34 | | struct cc_storage_t |
35 | | { |
36 | | uint32_t i_flags; |
37 | | vlc_tick_t i_dts; |
38 | | vlc_tick_t i_pts; |
39 | | cc_data_t current; |
40 | | cc_data_t next; |
41 | | }; |
42 | | |
43 | | cc_storage_t * cc_storage_new( void ) |
44 | 18.9k | { |
45 | 18.9k | cc_storage_t *p_ccs = malloc( sizeof(*p_ccs) ); |
46 | 18.9k | if( likely(p_ccs) ) |
47 | 18.9k | { |
48 | 18.9k | p_ccs->i_pts = VLC_TICK_INVALID; |
49 | 18.9k | p_ccs->i_dts = VLC_TICK_INVALID; |
50 | 18.9k | p_ccs->i_flags = 0; |
51 | 18.9k | cc_Init( &p_ccs->current ); |
52 | 18.9k | cc_Init( &p_ccs->next ); |
53 | 18.9k | } |
54 | 18.9k | return p_ccs; |
55 | 18.9k | } |
56 | | |
57 | | void cc_storage_delete( cc_storage_t *p_ccs ) |
58 | 18.9k | { |
59 | 18.9k | cc_Exit( &p_ccs->current ); |
60 | 18.9k | cc_Exit( &p_ccs->next ); |
61 | 18.9k | free( p_ccs ); |
62 | 18.9k | } |
63 | | |
64 | | void cc_storage_reset( cc_storage_t *p_ccs ) |
65 | 146k | { |
66 | 146k | cc_Flush( &p_ccs->next ); |
67 | 146k | } |
68 | | |
69 | | void cc_storage_append( cc_storage_t *p_ccs, bool b_top_field_first, |
70 | | const uint8_t *p_buf, size_t i_buf ) |
71 | 4.59k | { |
72 | 4.59k | cc_Extract( &p_ccs->next, CC_PAYLOAD_GA94, b_top_field_first, p_buf, i_buf ); |
73 | 4.59k | } |
74 | | |
75 | | void cc_storage_commit( cc_storage_t *p_ccs, block_t *p_pic ) |
76 | 398k | { |
77 | 398k | p_ccs->i_pts = p_pic->i_pts; |
78 | 398k | p_ccs->i_dts = p_pic->i_dts; |
79 | 398k | p_ccs->i_flags = p_pic->i_flags; |
80 | 398k | p_ccs->current = p_ccs->next; |
81 | 398k | cc_Flush( &p_ccs->next ); |
82 | 398k | } |
83 | | |
84 | | block_t * cc_storage_get_current( cc_storage_t *p_ccs, decoder_cc_desc_t *p_desc ) |
85 | 0 | { |
86 | 0 | block_t *p_block; |
87 | |
|
88 | 0 | if( !p_ccs->current.b_reorder && p_ccs->current.i_data <= 0 ) |
89 | 0 | return NULL; |
90 | | |
91 | 0 | p_block = block_Alloc( p_ccs->current.i_data); |
92 | 0 | if( p_block ) |
93 | 0 | { |
94 | 0 | memcpy( p_block->p_buffer, p_ccs->current.p_data, p_ccs->current.i_data ); |
95 | 0 | p_block->i_dts = |
96 | 0 | p_block->i_pts = p_ccs->current.b_reorder ? p_ccs->i_pts : p_ccs->i_dts; |
97 | 0 | p_block->i_flags = p_ccs->i_flags & BLOCK_FLAG_TYPE_MASK; |
98 | |
|
99 | 0 | p_desc->i_608_channels = p_ccs->current.i_608channels; |
100 | 0 | p_desc->i_708_channels = p_ccs->current.i_708channels; |
101 | 0 | p_desc->i_reorder_depth = p_ccs->current.b_reorder ? 4 : -1; |
102 | 0 | } |
103 | 0 | cc_Flush( &p_ccs->current ); |
104 | |
|
105 | 0 | return p_block; |
106 | 0 | } |
107 | | |
108 | | /**************************************************************************** |
109 | | * PacketizeXXC1: Takes VCL blocks of data and creates annexe B type NAL stream |
110 | | * Will always use 4 byte 0 0 0 1 startcodes |
111 | | * Will prepend a SPS and PPS before each keyframe |
112 | | ****************************************************************************/ |
113 | | block_t *PacketizeXXC1( void *p_private, struct vlc_logger *logger, |
114 | | uint8_t i_nal_length_size, block_t **pp_block, |
115 | | pf_annexb_nal_parse pf_nal_parser, |
116 | | pf_annexb_nal_drain pf_nal_drain ) |
117 | 0 | { |
118 | 0 | block_t *p_block; |
119 | 0 | block_t *p_ret = NULL; |
120 | 0 | uint8_t *p; |
121 | |
|
122 | 0 | if( !pp_block ) |
123 | 0 | return pf_nal_drain ? pf_nal_drain( p_private ) : NULL; |
124 | | |
125 | 0 | if( !*pp_block ) |
126 | 0 | return NULL; |
127 | 0 | if( (*pp_block)->i_flags&(BLOCK_FLAG_CORRUPTED) ) |
128 | 0 | { |
129 | 0 | block_Release( *pp_block ); |
130 | 0 | return NULL; |
131 | 0 | } |
132 | | |
133 | 0 | p_block = *pp_block; |
134 | 0 | *pp_block = NULL; |
135 | |
|
136 | 0 | for( p = p_block->p_buffer; p < &p_block->p_buffer[p_block->i_buffer]; ) |
137 | 0 | { |
138 | 0 | bool b_dummy; |
139 | 0 | int i_size = 0; |
140 | 0 | int i; |
141 | |
|
142 | 0 | if( &p_block->p_buffer[p_block->i_buffer] - p < i_nal_length_size ) |
143 | 0 | break; |
144 | | |
145 | 0 | for( i = 0; i < i_nal_length_size; i++ ) |
146 | 0 | { |
147 | 0 | i_size = (i_size << 8) | (*p++); |
148 | 0 | } |
149 | |
|
150 | 0 | if( i_size <= 0 || |
151 | 0 | i_size > ( p_block->p_buffer + p_block->i_buffer - p ) ) |
152 | 0 | { |
153 | 0 | vlc_error( logger, "Broken frame : size %d is too big", i_size ); |
154 | 0 | break; |
155 | 0 | } |
156 | | |
157 | | /* Convert AVC to AnnexB */ |
158 | 0 | block_t *p_nal; |
159 | | /* If data exactly match remaining bytes (1 NAL only or trailing one) */ |
160 | 0 | if( i_size == p_block->p_buffer + p_block->i_buffer - p ) |
161 | 0 | { |
162 | 0 | p_block->i_buffer = i_size; |
163 | 0 | p_block->p_buffer = p; |
164 | 0 | p_nal = block_Realloc( p_block, 4, i_size ); |
165 | 0 | if( p_nal ) |
166 | 0 | p_block = NULL; |
167 | 0 | } |
168 | 0 | else |
169 | 0 | { |
170 | 0 | p_nal = block_Alloc( 4 + i_size ); |
171 | 0 | if( p_nal ) |
172 | 0 | { |
173 | 0 | p_nal->i_dts = p_block->i_dts; |
174 | 0 | p_nal->i_pts = p_block->i_pts; |
175 | | /* Copy nalu */ |
176 | 0 | memcpy( &p_nal->p_buffer[4], p, i_size ); |
177 | 0 | } |
178 | 0 | p += i_size; |
179 | 0 | } |
180 | |
|
181 | 0 | if( !p_nal ) |
182 | 0 | break; |
183 | | |
184 | | /* Add start code */ |
185 | 0 | p_nal->p_buffer[0] = 0x00; |
186 | 0 | p_nal->p_buffer[1] = 0x00; |
187 | 0 | p_nal->p_buffer[2] = 0x00; |
188 | 0 | p_nal->p_buffer[3] = 0x01; |
189 | | |
190 | | /* Parse the NAL */ |
191 | 0 | block_t *p_pic; |
192 | 0 | if( ( p_pic = pf_nal_parser( p_private, &b_dummy, p_nal ) ) ) |
193 | 0 | { |
194 | 0 | block_ChainAppend( &p_ret, p_pic ); |
195 | 0 | } |
196 | |
|
197 | 0 | if( !p_block ) |
198 | 0 | break; |
199 | 0 | } |
200 | |
|
201 | 0 | if( p_block ) |
202 | 0 | block_Release( p_block ); |
203 | |
|
204 | 0 | return p_ret; |
205 | 0 | } |