1 /*****************************************************************************
2 * util.cpp : matroska demuxer
3 *****************************************************************************
4 * Copyright (C) 2003-2004 VLC authors and VideoLAN
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Steve Lhomme <steve.lhomme@free.fr>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
29 /*****************************************************************************
31 *****************************************************************************/
34 int32_t zlib_decompress_extra( demux_t * p_demux, mkv_track_t * tk )
39 uint8_t * p_new_extra = NULL;
41 msg_Dbg(p_demux,"Inflating private data");
43 d_stream.zalloc = Z_NULL;
44 d_stream.zfree = Z_NULL;
45 d_stream.opaque = Z_NULL;
46 if( inflateInit( &d_stream ) != Z_OK )
48 msg_Err( p_demux, "Couldn't initiate inflation ignore track %d",
50 free(tk->p_extra_data);
55 d_stream.next_in = tk->p_extra_data;
56 d_stream.avail_in = tk->i_extra_data;
60 p_new_extra = (uint8_t *) realloc(p_new_extra, n*1024);
63 msg_Err( p_demux, "Couldn't allocate buffer to inflate data, ignore track %d",
65 inflateEnd( &d_stream );
66 free(tk->p_extra_data);
70 d_stream.next_out = &p_new_extra[(n - 1) * 1024];
71 d_stream.avail_out = 1024;
72 result = inflate(&d_stream, Z_NO_FLUSH);
73 if( result != Z_OK && result != Z_STREAM_END )
75 msg_Err( p_demux, "Zlib decompression failed. Result: %d", result );
76 inflateEnd( &d_stream );
78 free(tk->p_extra_data);
83 while ( d_stream.avail_out == 0 && d_stream.avail_in != 0 &&
84 result != Z_STREAM_END );
86 free( tk->p_extra_data );
87 tk->i_extra_data = d_stream.total_out;
88 p_new_extra = (uint8_t *) realloc(p_new_extra, tk->i_extra_data);
91 msg_Err( p_demux, "Couldn't allocate buffer to inflate data, ignore track %d",
93 inflateEnd( &d_stream );
99 tk->p_extra_data = p_new_extra;
101 inflateEnd( &d_stream );
105 block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) {
106 int result, dstsize, n;
111 d_stream.zalloc = (alloc_func)0;
112 d_stream.zfree = (free_func)0;
113 d_stream.opaque = (voidpf)0;
114 result = inflateInit(&d_stream);
117 msg_Dbg( p_this, "inflateInit() failed. Result: %d", result );
121 d_stream.next_in = (Bytef *)p_in_block->p_buffer;
122 d_stream.avail_in = p_in_block->i_buffer;
124 p_block = block_Alloc( 0 );
129 p_block = block_Realloc( p_block, 0, n * 1000 );
130 dst = (unsigned char *)p_block->p_buffer;
131 d_stream.next_out = (Bytef *)&dst[(n - 1) * 1000];
132 d_stream.avail_out = 1000;
133 result = inflate(&d_stream, Z_NO_FLUSH);
134 if( ( result != Z_OK ) && ( result != Z_STREAM_END ) )
136 msg_Err( p_this, "Zlib decompression failed. Result: %d", result );
137 inflateEnd( &d_stream );
138 block_Release( p_block );
142 while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) &&
143 ( result != Z_STREAM_END ) );
145 dstsize = d_stream.total_out;
146 inflateEnd( &d_stream );
148 p_block = block_Realloc( p_block, 0, dstsize );
149 p_block->i_buffer = dstsize;
150 block_Release( p_in_block );
156 /* Utility function for BlockDecode */
157 block_t *MemToBlock( uint8_t *p_mem, size_t i_mem, size_t offset)
159 if( unlikely( i_mem > SIZE_MAX - offset ) )
162 block_t *p_block = block_Alloc( i_mem + offset );
163 if( likely(p_block != NULL) )
165 memcpy( p_block->p_buffer + offset, p_mem, i_mem );
171 void handle_real_audio(demux_t * p_demux, mkv_track_t * p_tk, block_t * p_blk, mtime_t i_pts)
173 uint8_t * p_frame = p_blk->p_buffer;
174 Cook_PrivateTrackData * p_sys = (Cook_PrivateTrackData *) p_tk->p_sys;
175 size_t size = p_blk->i_buffer;
177 if( p_tk->i_last_dts == VLC_TS_INVALID )
179 for( size_t i = 0; i < p_sys->i_subpackets; i++)
180 if( p_sys->p_subpackets[i] )
182 block_Release(p_sys->p_subpackets[i]);
183 p_sys->p_subpackets[i] = NULL;
185 p_sys->i_subpacket = 0;
187 if ( !( p_blk->i_flags & BLOCK_FLAG_TYPE_I) )
189 msg_Dbg( p_demux, "discard non-key preroll block in track %d at%"PRId64,
190 p_tk->i_number, i_pts );
195 if( p_tk->fmt.i_codec == VLC_CODEC_COOK ||
196 p_tk->fmt.i_codec == VLC_CODEC_ATRAC3 )
198 const uint16_t i_num = p_sys->i_frame_size / p_sys->i_subpacket_size;
199 const size_t y = p_sys->i_subpacket / ( p_sys->i_frame_size / p_sys->i_subpacket_size );
201 for( uint16_t i = 0; i < i_num; i++ )
203 size_t i_index = (size_t) p_sys->i_sub_packet_h * i +
204 ((p_sys->i_sub_packet_h + 1) / 2) * (y&1) + (y>>1);
205 if( i_index >= p_sys->i_subpackets )
208 block_t *p_block = block_Alloc( p_sys->i_subpacket_size );
212 if( size < p_sys->i_subpacket_size )
215 memcpy( p_block->p_buffer, p_frame, p_sys->i_subpacket_size );
216 p_block->i_dts = VLC_TS_INVALID;
217 p_block->i_pts = VLC_TS_INVALID;
218 if( !p_sys->i_subpacket )
221 p_block->i_pts = i_pts;
224 p_frame += p_sys->i_subpacket_size;
225 size -= p_sys->i_subpacket_size;
227 p_sys->i_subpacket++;
228 p_sys->p_subpackets[i_index] = p_block;
235 if( p_sys->i_subpacket == p_sys->i_subpackets )
237 for( size_t i = 0; i < p_sys->i_subpackets; i++)
239 es_out_Send( p_demux->out, p_tk->p_es, p_sys->p_subpackets[i]);
240 p_sys->p_subpackets[i] = NULL;
242 p_sys->i_subpacket = 0;
246 int32_t Cook_PrivateTrackData::Init()
248 i_subpackets = (size_t) i_sub_packet_h * (size_t) i_frame_size / (size_t) i_subpacket_size;
249 p_subpackets = (block_t**) calloc(i_subpackets, sizeof(block_t*));
251 if( unlikely( !p_subpackets ) )
260 Cook_PrivateTrackData::~Cook_PrivateTrackData()
262 for( size_t i = 0; i < i_subpackets; i++ )
263 if( p_subpackets[i] )
264 block_Release( p_subpackets[i] );
266 free( p_subpackets );
269 static inline void fill_wvpk_block(uint16_t version, uint32_t block_samples, uint32_t flags,
270 uint32_t crc, uint8_t * src, size_t srclen, uint8_t * dst)
272 const uint8_t wvpk_header[] = {'w','v','p','k', /* ckId */
273 0x0, 0x0, 0x0, 0x0, /* ckSize */
274 0x0, 0x0, /* version */
277 0xFF, 0xFF, 0xFF, 0xFF, /* total_samples */
278 0x0, 0x0, 0x0, 0x0 }; /* block_index */
279 memcpy( dst, wvpk_header, sizeof( wvpk_header ) );
280 SetDWLE( dst + 4, srclen + 24 );
281 SetWLE( dst + 8, version );
282 SetDWLE( dst + 20, block_samples );
283 SetDWLE( dst + 24, flags );
284 SetDWLE( dst + 28, crc );
285 memcpy( dst + 32, src, srclen );
288 block_t * packetize_wavpack( mkv_track_t * p_tk, uint8_t * buffer, size_t size)
290 uint16_t version = 0x403;
291 uint32_t block_samples;
294 block_t * p_block = NULL;
296 if( p_tk->i_extra_data >= 2 )
297 version = GetWLE( p_tk->p_extra_data );
302 block_samples = GetDWLE(buffer);
304 flags = GetDWLE(buffer);
307 /* Check if WV_INITIAL_BLOCK and WV_FINAL_BLOCK are present */
308 if( ( flags & 0x1800 ) == 0x1800 )
310 crc = GetDWLE(buffer+4);
314 p_block = block_Alloc( size + 32 );
318 fill_wvpk_block(version, block_samples, flags, crc, buffer, size, p_block->p_buffer);
323 size_t total_size = 0;
325 p_block = block_Alloc( 0 );
331 flags = GetDWLE(buffer);
333 crc = GetDWLE(buffer);
335 uint32_t bsz = GetDWLE(buffer);
339 bsz = (bsz < size)?bsz:size;
341 total_size += bsz + 32;
343 assert(total_size >= p_block->i_buffer);
345 p_block = block_Realloc( p_block, 0, total_size );
350 fill_wvpk_block(version, block_samples, flags, crc, buffer, bsz,
351 p_block->p_buffer + total_size - bsz - 32 );