codec/esout: add support for CEA708
[vlc.git] / modules / packetizer / hxxx_common.c
blob45b33fdc1aa47f805d53839d73f1a12275b947a3
1 /*****************************************************************************
2 * hxxx_common.c: AVC/HEVC packetizers shared code
3 *****************************************************************************
4 * Copyright (C) 2001-2015 VLC authors and VideoLAN
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.
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.
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
24 #include <vlc_common.h>
25 #include <vlc_block.h>
26 #include <vlc_codec.h>
28 #include "hxxx_common.h"
29 #include "../codec/cc.h"
31 /****************************************************************************
32 * Closed captions handling
33 ****************************************************************************/
34 struct cc_storage_t
36 uint32_t i_flags;
37 mtime_t i_dts;
38 mtime_t i_pts;
39 cc_data_t current;
40 cc_data_t next;
43 cc_storage_t * cc_storage_new( void )
45 cc_storage_t *p_ccs = malloc( sizeof(*p_ccs) );
46 if( likely(p_ccs) )
48 p_ccs->i_pts = VLC_TS_INVALID;
49 p_ccs->i_dts = VLC_TS_INVALID;
50 p_ccs->i_flags = 0;
51 cc_Init( &p_ccs->current );
52 cc_Init( &p_ccs->next );
54 return p_ccs;
57 void cc_storage_delete( cc_storage_t *p_ccs )
59 cc_Exit( &p_ccs->current );
60 cc_Exit( &p_ccs->next );
61 free( p_ccs );
64 void cc_storage_reset( cc_storage_t *p_ccs )
66 cc_Flush( &p_ccs->next );
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 )
72 cc_Extract( &p_ccs->next, CC_PAYLOAD_GA94, b_top_field_first, p_buf, i_buf );
75 void cc_storage_commit( cc_storage_t *p_ccs, block_t *p_pic )
77 p_ccs->i_pts = p_pic->i_pts;
78 p_ccs->i_dts = p_pic->i_dts;
79 p_ccs->i_flags = p_pic->i_flags;
80 p_ccs->current = p_ccs->next;
81 cc_Flush( &p_ccs->next );
84 block_t * cc_storage_get_current( cc_storage_t *p_ccs, decoder_cc_desc_t *p_desc )
86 block_t *p_block;
88 if( !p_ccs->current.b_reorder && p_ccs->current.i_data <= 0 )
89 return NULL;
91 p_block = block_Alloc( p_ccs->current.i_data);
92 if( p_block )
94 memcpy( p_block->p_buffer, p_ccs->current.p_data, p_ccs->current.i_data );
95 p_block->i_dts =
96 p_block->i_pts = p_ccs->current.b_reorder ? p_ccs->i_pts : p_ccs->i_dts;
97 p_block->i_flags = p_ccs->i_flags & BLOCK_FLAG_TYPE_MASK;
99 p_desc->i_608_channels = p_ccs->current.i_608channels;
100 p_desc->i_708_channels = p_ccs->current.i_708channels;
101 p_desc->i_reorder_depth = p_ccs->current.b_reorder ? 4 : -1;
103 cc_Flush( &p_ccs->current );
105 return p_block;
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( decoder_t *p_dec, uint8_t i_nal_length_size,
114 block_t **pp_block, pf_annexb_nal_packetizer pf_nal_parser )
116 block_t *p_block;
117 block_t *p_ret = NULL;
118 uint8_t *p;
120 if( !pp_block || !*pp_block )
121 return NULL;
122 if( (*pp_block)->i_flags&(BLOCK_FLAG_CORRUPTED) )
124 block_Release( *pp_block );
125 return NULL;
128 p_block = *pp_block;
129 *pp_block = NULL;
131 for( p = p_block->p_buffer; p < &p_block->p_buffer[p_block->i_buffer]; )
133 bool b_dummy;
134 int i_size = 0;
135 int i;
137 if( &p_block->p_buffer[p_block->i_buffer] - p < i_nal_length_size )
138 break;
140 for( i = 0; i < i_nal_length_size; i++ )
142 i_size = (i_size << 8) | (*p++);
145 if( i_size <= 0 ||
146 i_size > ( p_block->p_buffer + p_block->i_buffer - p ) )
148 msg_Err( p_dec, "Broken frame : size %d is too big", i_size );
149 break;
152 /* Convert AVC to AnnexB */
153 block_t *p_nal;
154 /* If data exactly match remaining bytes (1 NAL only or trailing one) */
155 if( i_size == p_block->p_buffer + p_block->i_buffer - p )
157 p_block->i_buffer = i_size;
158 p_block->p_buffer = p;
159 p_nal = block_Realloc( p_block, 4, i_size );
160 if( p_nal )
161 p_block = NULL;
163 else
165 p_nal = block_Alloc( 4 + i_size );
166 if( p_nal )
168 p_nal->i_dts = p_block->i_dts;
169 p_nal->i_pts = p_block->i_pts;
170 /* Copy nalu */
171 memcpy( &p_nal->p_buffer[4], p, i_size );
173 p += i_size;
176 if( !p_nal )
177 break;
179 /* Add start code */
180 p_nal->p_buffer[0] = 0x00;
181 p_nal->p_buffer[1] = 0x00;
182 p_nal->p_buffer[2] = 0x00;
183 p_nal->p_buffer[3] = 0x01;
185 /* Parse the NAL */
186 block_t *p_pic;
187 if( ( p_pic = pf_nal_parser( p_dec, &b_dummy, p_nal ) ) )
189 block_ChainAppend( &p_ret, p_pic );
192 if( !p_block )
193 break;
196 if( p_block )
197 block_Release( p_block );
199 return p_ret;