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;
188 if( p_tk->fmt.i_codec == VLC_CODEC_COOK ||
189 p_tk->fmt.i_codec == VLC_CODEC_ATRAC3 )
191 const uint16_t i_num = p_sys->i_frame_size / p_sys->i_subpacket_size;
192 const size_t y = p_sys->i_subpacket / ( p_sys->i_frame_size / p_sys->i_subpacket_size );
194 for( uint16_t i = 0; i < i_num; i++ )
196 size_t i_index = (size_t) p_sys->i_sub_packet_h * i +
197 ((p_sys->i_sub_packet_h + 1) / 2) * (y&1) + (y>>1);
198 if( i_index >= p_sys->i_subpackets )
201 block_t *p_block = block_Alloc( p_sys->i_subpacket_size );
205 if( size < p_sys->i_subpacket_size )
208 memcpy( p_block->p_buffer, p_frame, p_sys->i_subpacket_size );
209 p_block->i_dts = VLC_TS_INVALID;
210 p_block->i_pts = VLC_TS_INVALID;
211 if( !p_sys->i_subpacket )
214 p_block->i_pts = i_pts + VLC_TS_0;
217 p_frame += p_sys->i_subpacket_size;
218 size -= p_sys->i_subpacket_size;
220 p_sys->i_subpacket++;
221 p_sys->p_subpackets[i_index] = p_block;
228 if( p_sys->i_subpacket == p_sys->i_subpackets )
230 for( size_t i = 0; i < p_sys->i_subpackets; i++)
232 es_out_Send( p_demux->out, p_tk->p_es, p_sys->p_subpackets[i]);
233 p_sys->p_subpackets[i] = NULL;
235 p_sys->i_subpacket = 0;
239 int32_t Cook_PrivateTrackData::Init()
241 i_subpackets = (size_t) i_sub_packet_h * (size_t) i_frame_size / (size_t) i_subpacket_size;
242 p_subpackets = (block_t**) calloc(i_subpackets, sizeof(block_t*));
244 if( unlikely( !p_subpackets ) )
253 Cook_PrivateTrackData::~Cook_PrivateTrackData()
255 for( size_t i = 0; i < i_subpackets; i++ )
256 if( p_subpackets[i] )
257 block_Release( p_subpackets[i] );
259 free( p_subpackets );
262 static inline void fill_wvpk_block(uint16_t version, uint32_t block_samples, uint32_t flags,
263 uint32_t crc, uint8_t * src, size_t srclen, uint8_t * dst)
265 const uint8_t wvpk_header[] = {'w','v','p','k', /* ckId */
266 0x0, 0x0, 0x0, 0x0, /* ckSize */
267 0x0, 0x0, /* version */
270 0xFF, 0xFF, 0xFF, 0xFF, /* total_samples */
271 0x0, 0x0, 0x0, 0x0 }; /* block_index */
272 memcpy( dst, wvpk_header, sizeof( wvpk_header ) );
273 SetDWLE( dst + 4, srclen + 24 );
274 SetWLE( dst + 8, version );
275 SetDWLE( dst + 20, block_samples );
276 SetDWLE( dst + 24, flags );
277 SetDWLE( dst + 28, crc );
278 memcpy( dst + 32, src, srclen );
281 block_t * packetize_wavpack( mkv_track_t * p_tk, uint8_t * buffer, size_t size)
283 uint16_t version = 0x403;
284 uint32_t block_samples;
287 block_t * p_block = NULL;
289 if( p_tk->i_extra_data >= 2 )
290 version = GetWLE( p_tk->p_extra_data );
295 block_samples = GetDWLE(buffer);
297 flags = GetDWLE(buffer);
300 /* Check if WV_INITIAL_BLOCK and WV_FINAL_BLOCK are present */
301 if( ( flags & 0x1800 ) == 0x1800 )
303 crc = GetDWLE(buffer+4);
307 p_block = block_Alloc( size + 32 );
311 fill_wvpk_block(version, block_samples, flags, crc, buffer, size, p_block->p_buffer);
316 size_t total_size = 0;
318 p_block = block_Alloc( 0 );
324 flags = GetDWLE(buffer);
326 crc = GetDWLE(buffer);
328 uint32_t bsz = GetDWLE(buffer);
332 bsz = (bsz < size)?bsz:size;
334 total_size += bsz + 32;
336 assert(total_size >= p_block->i_buffer);
338 p_block = block_Realloc( p_block, 0, total_size );
343 fill_wvpk_block(version, block_samples, flags, crc, buffer, bsz,
344 p_block->p_buffer + total_size - bsz - 32 );