1 /*****************************************************************************
2 * real.c: Real demuxer.
3 *****************************************************************************
4 * Copyright (C) 2004, 2006-2007 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
25 * Status of this demuxer:
29 * version v3 w/ 14_4/lpcJ is ok.
30 * version v4/5: - atrac3 is ok.
32 * - raac, racp are ok.
33 * - dnet is twisted "The byte order of the data is reversed
34 * from standard AC3" but ok
37 * - ralf is unsupported, but hardly any sample exist.
38 * - mp3 is unsupported, one sample exists...
42 * v3 and v4/5 headers are parsed.
46 /*****************************************************************************
48 *****************************************************************************/
54 #define VLC_MODULE_LICENSE VLC_LICENSE_GPL_2_PLUS
55 #include <vlc_common.h>
56 #include <vlc_plugin.h>
58 #include <vlc_demux.h>
59 #include <vlc_charset.h>
64 /*****************************************************************************
66 *****************************************************************************/
67 static int Open ( vlc_object_t
* );
68 static void Close ( vlc_object_t
* );
71 set_description( N_("Real demuxer" ) )
72 set_capability( "demux", 0 )
73 set_category( CAT_INPUT
)
74 set_subcategory( SUBCAT_INPUT_DEMUX
)
75 set_callbacks( Open
, Close
)
76 add_shortcut( "real", "rm" )
79 /*****************************************************************************
81 *****************************************************************************/
90 unsigned i_frame_size
;
95 int i_frame_slice_count
;
100 int i_coded_frame_size
;
104 block_t
**p_subpackets
;
105 mtime_t
*p_subpackets_timecode
;
108 block_t
*p_sipr_packet
;
109 int i_sipr_subpacket_count
;
115 uint32_t i_file_offset
;
116 uint32_t i_time_offset
;
117 uint32_t i_frame_index
;
122 int64_t i_data_offset
;
124 uint32_t i_data_packets_count
;
125 uint32_t i_data_packets
;
126 int64_t i_data_offset_next
;
130 int64_t i_our_duration
;
135 char* psz_description
;
138 real_track_t
**track
;
141 uint8_t buffer
[65536];
145 int64_t i_index_offset
;
147 real_index_t
*p_index
;
150 static const unsigned char i_subpacket_size_sipr
[4] = { 29, 19, 37, 20 };
152 static int Demux( demux_t
* );
153 static int Control( demux_t
*, int i_query
, va_list args
);
156 static void DemuxVideo( demux_t
*, real_track_t
*tk
, mtime_t i_dts
, unsigned i_flags
);
157 static void DemuxAudio( demux_t
*, real_track_t
*tk
, mtime_t i_pts
, unsigned i_flags
);
159 static int ControlSeekByte( demux_t
*, int64_t i_bytes
);
160 static int ControlSeekTime( demux_t
*, mtime_t i_time
);
162 static int HeaderRead( demux_t
*p_demux
);
163 static int CodecParse( demux_t
*p_demux
, int i_len
, int i_num
);
165 static void RVoid( const uint8_t **pp_data
, int *pi_data
, int i_size
);
166 static int RLength( const uint8_t **pp_data
, int *pi_data
);
167 static uint8_t R8( const uint8_t **pp_data
, int *pi_data
);
168 static uint16_t R16( const uint8_t **pp_data
, int *pi_data
);
169 static uint32_t R32( const uint8_t **pp_data
, int *pi_data
);
170 static void SiprPacketReorder(uint8_t *buf
, int sub_packet_h
, int framesize
);
172 /*****************************************************************************
174 *****************************************************************************/
175 static int Open( vlc_object_t
*p_this
)
177 demux_t
*p_demux
= (demux_t
*)p_this
;
180 const uint8_t *p_peek
;
181 bool b_real_audio
= false;
183 if( vlc_stream_Peek( p_demux
->s
, &p_peek
, 10 ) < 10 )
187 if( !memcmp( p_peek
, ".ra", 3 ) )
189 msg_Err( p_demux
, ".ra files unsupported" );
192 /* Real Media Format */
193 else if( memcmp( p_peek
, ".RMF", 4 ) )
198 /* Fill p_demux field */
199 p_demux
->pf_demux
= Demux
;
200 p_demux
->pf_control
= Control
;
202 p_demux
->p_sys
= p_sys
= calloc( 1, sizeof( *p_sys
) );
206 p_sys
->i_data_offset
= 0;
209 p_sys
->i_pcr
= VLC_TS_INVALID
;
211 p_sys
->b_seek
= false;
212 p_sys
->b_real_audio
= b_real_audio
;
214 /* Parse the headers */
215 /* Real Audio files */
218 CodecParse( p_demux
, 32, 0 ); /* At least 32 */
219 return VLC_EGENERIC
; /* We don't know how to read
220 correctly the data yet */
223 else if( HeaderRead( p_demux
) )
225 msg_Err( p_demux
, "invalid header" );
233 /*****************************************************************************
235 *****************************************************************************/
236 static void Close( vlc_object_t
*p_this
)
238 demux_t
*p_demux
= (demux_t
*)p_this
;
239 demux_sys_t
*p_sys
= p_demux
->p_sys
;
241 for( int i
= 0; i
< p_sys
->i_track
; i
++ )
243 real_track_t
*tk
= p_sys
->track
[i
];
245 es_format_Clean( &tk
->fmt
);
248 block_Release( tk
->p_frame
);
250 for( int j
= 0; j
< tk
->i_subpackets
; j
++ )
252 if( tk
->p_subpackets
[ j
] )
253 block_Release( tk
->p_subpackets
[ j
] );
255 free( tk
->p_subpackets
);
256 free( tk
->p_subpackets_timecode
);
257 if( tk
->p_sipr_packet
)
258 block_Release( tk
->p_sipr_packet
);
261 if( p_sys
->i_track
> 0 )
262 free( p_sys
->track
);
264 free( p_sys
->psz_title
);
265 free( p_sys
->psz_artist
);
266 free( p_sys
->psz_copyright
);
267 free( p_sys
->psz_description
);
268 free( p_sys
->p_index
);
274 /*****************************************************************************
276 *****************************************************************************/
277 static int Demux( demux_t
*p_demux
)
279 demux_sys_t
*p_sys
= p_demux
->p_sys
;
282 if( p_sys
->i_data_packets
>= p_sys
->i_data_packets_count
&&
283 p_sys
->i_data_packets_count
)
285 if( vlc_stream_Read( p_demux
->s
, header
, 18 ) < 18 )
288 if( memcmp( header
, "DATA", 4 ) )
291 p_sys
->i_data_offset
= vlc_stream_Tell( p_demux
->s
) - 18;
292 p_sys
->i_data_size
= GetDWBE( &header
[4] );
293 p_sys
->i_data_packets_count
= GetDWBE( &header
[10] );
294 p_sys
->i_data_packets
= 0;
295 p_sys
->i_data_offset_next
= GetDWBE( &header
[14] );
297 msg_Dbg( p_demux
, "entering new DATA packets=%d next=%u",
298 p_sys
->i_data_packets_count
,
299 (unsigned int)p_sys
->i_data_offset_next
);
302 /* Read Packet Header */
303 if( vlc_stream_Read( p_demux
->s
, header
, 12 ) < 12 )
305 //const int i_version = GetWBE( &header[0] );
306 const size_t i_size
= GetWBE( &header
[2] ) - 12;
307 const int i_id
= GetWBE( &header
[4] );
308 const int64_t i_pts
= VLC_TS_0
+ 1000 * GetDWBE( &header
[6] );
309 const int i_flags
= header
[11]; /* flags 0x02 -> keyframe */
311 p_sys
->i_data_packets
++;
312 if( i_size
> sizeof(p_sys
->buffer
) )
314 msg_Err( p_demux
, "Got a NUKK size to read. (Invalid format?)" );
318 p_sys
->i_buffer
= vlc_stream_Read( p_demux
->s
, p_sys
->buffer
, i_size
);
319 if( p_sys
->i_buffer
< i_size
)
322 real_track_t
*tk
= NULL
;
323 for( int i
= 0; i
< p_sys
->i_track
; i
++ )
325 if( p_sys
->track
[i
]->i_id
== i_id
)
326 tk
= p_sys
->track
[i
];
331 msg_Warn( p_demux
, "unknown track id(0x%x)", i_id
);
335 if( tk
->fmt
.i_cat
== VIDEO_ES
)
337 DemuxVideo( p_demux
, tk
, i_pts
, i_flags
);
341 assert( tk
->fmt
.i_cat
== AUDIO_ES
);
342 DemuxAudio( p_demux
, tk
, i_pts
, i_flags
);
346 mtime_t i_pcr
= VLC_TS_INVALID
;
347 for( int i
= 0; i
< p_sys
->i_track
; i
++ )
349 tk
= p_sys
->track
[i
];
351 if( i_pcr
<= VLC_TS_INVALID
|| ( tk
->i_last_dts
> VLC_TS_INVALID
&& tk
->i_last_dts
< i_pcr
) )
352 i_pcr
= tk
->i_last_dts
;
354 if( i_pcr
> VLC_TS_INVALID
&& i_pcr
!= p_sys
->i_pcr
)
356 p_sys
->i_pcr
= i_pcr
;
357 es_out_SetPCR( p_demux
->out
, p_sys
->i_pcr
);
362 /*****************************************************************************
364 *****************************************************************************/
365 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
367 demux_sys_t
*p_sys
= p_demux
->p_sys
;
376 bool *b
= va_arg( args
, bool * );
378 if( stream_Size( p_demux
->s
) == 0 )
379 *b
= true; /* FIXME: kludge for Real-dialectal RTSP */
381 if( p_sys
->p_index
== NULL
)
384 if( vlc_stream_Control( p_demux
->s
, STREAM_CAN_SEEK
, &b
) )
390 case DEMUX_GET_POSITION
:
391 pf
= va_arg( args
, double * );
393 /* read stream size maybe failed in rtsp streaming,
394 so use duration to determin the position at first */
395 if( p_sys
->i_our_duration
> 0 )
397 if( p_sys
->i_pcr
> VLC_TS_INVALID
)
398 *pf
= (double)p_sys
->i_pcr
/ 1000.0 / p_sys
->i_our_duration
;
404 i64
= stream_Size( p_demux
->s
);
406 *pf
= (double)1.0*vlc_stream_Tell( p_demux
->s
) / (double)i64
;
412 pi64
= va_arg( args
, int64_t * );
414 if( p_sys
->i_our_duration
> 0 )
416 *pi64
= p_sys
->i_pcr
> VLC_TS_INVALID
? p_sys
->i_pcr
: 0;
420 /* same as GET_POSTION */
421 i64
= stream_Size( p_demux
->s
);
422 if( p_sys
->i_our_duration
> 0 && i64
> 0 )
424 *pi64
= (int64_t)( 1000.0 * p_sys
->i_our_duration
* vlc_stream_Tell( p_demux
->s
) / i64
);
431 case DEMUX_SET_POSITION
:
432 f
= va_arg( args
, double );
433 i64
= (int64_t) ( stream_Size( p_demux
->s
) * f
);
435 if( !p_sys
->p_index
&& i64
!= 0 )
438 msg_Err( p_demux
,"Seek No Index Real File failed!" );
439 return VLC_EGENERIC
; // no index!
443 /* it is a rtsp stream , it is specials in access/rtsp/... */
444 msg_Dbg(p_demux
, "Seek in real rtsp stream!");
445 p_sys
->i_pcr
= VLC_TS_0
+ INT64_C(1000) * ( p_sys
->i_our_duration
* f
);
446 p_sys
->b_seek
= true;
447 return vlc_stream_Seek( p_demux
->s
, p_sys
->i_pcr
- VLC_TS_0
);
449 return ControlSeekByte( p_demux
, i64
);
452 if( !p_sys
->p_index
)
455 i64
= va_arg( args
, int64_t );
456 return ControlSeekTime( p_demux
, i64
);
458 case DEMUX_GET_LENGTH
:
459 pi64
= va_arg( args
, int64_t * );
461 if( p_sys
->i_our_duration
<= 0 )
467 /* our stored duration is in ms, so... */
468 *pi64
= INT64_C(1000) * p_sys
->i_our_duration
;
473 vlc_meta_t
*p_meta
= va_arg( args
, vlc_meta_t
* );
475 /* the core will crash if we provide NULL strings, so check
476 * every string first */
477 if( p_sys
->psz_title
)
478 vlc_meta_SetTitle( p_meta
, p_sys
->psz_title
);
479 if( p_sys
->psz_artist
)
480 vlc_meta_SetArtist( p_meta
, p_sys
->psz_artist
);
481 if( p_sys
->psz_copyright
)
482 vlc_meta_SetCopyright( p_meta
, p_sys
->psz_copyright
);
483 if( p_sys
->psz_description
)
484 vlc_meta_SetDescription( p_meta
, p_sys
->psz_description
);
495 /*****************************************************************************
497 *****************************************************************************/
498 static void CheckPcr( demux_t
*p_demux
, real_track_t
*tk
, mtime_t i_dts
)
500 demux_sys_t
*p_sys
= p_demux
->p_sys
;
502 if( i_dts
> VLC_TS_INVALID
)
503 tk
->i_last_dts
= i_dts
;
505 if( p_sys
->i_pcr
> VLC_TS_INVALID
|| i_dts
<= VLC_TS_INVALID
)
508 p_sys
->i_pcr
= i_dts
;
509 es_out_SetPCR( p_demux
->out
, p_sys
->i_pcr
);
512 static void DemuxVideo( demux_t
*p_demux
, real_track_t
*tk
, mtime_t i_dts
, unsigned i_flags
)
514 demux_sys_t
*p_sys
= p_demux
->p_sys
;
516 const uint8_t *p_data
= p_sys
->buffer
;
517 int i_data
= p_sys
->i_buffer
;
521 uint8_t i_hdr
= R8( &p_data
, &i_data
);
522 uint8_t i_type
= i_hdr
>> 6;
531 R8( &p_data
, &i_data
);
538 else if( i_type
== 3 )
540 i_len
= RLength( &p_data
, &i_data
);
541 i_pos
= RLength( &p_data
, &i_data
);
542 i_frame_num
= R8( &p_data
, &i_data
);
548 assert( i_type
== 0 || i_type
== 2 );
549 i_seq
= R8( &p_data
, &i_data
);
550 i_len
= RLength( &p_data
, &i_data
);
552 i_pos
= RLength( &p_data
, &i_data
);
553 i_frame_num
= R8( &p_data
, &i_data
);
556 if( (i_seq
& 0x7f) == 1 || tk
->i_frame_num
!= i_frame_num
)
558 tk
->i_frame_slice
= 0;
559 tk
->i_frame_slice_count
= 2 * (i_hdr
& 0x3f) + 1;
560 tk
->i_frame_pos
= 2*4 * tk
->i_frame_slice_count
+ 1;
561 tk
->i_frame_size
= i_len
+ 2*4 * tk
->i_frame_slice_count
+ 1;
562 tk
->i_frame_num
= i_frame_num
;
565 block_Release( tk
->p_frame
);
567 tk
->p_frame
= block_Alloc( tk
->i_frame_size
);
570 tk
->i_frame_size
= 0;
574 tk
->p_frame
->i_dts
= i_dts
;
575 tk
->p_frame
->i_pts
= VLC_TS_INVALID
;
577 tk
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_I
;
579 i_dts
= VLC_TS_INVALID
;
585 i_frame_data
= i_len
;
589 i_frame_data
= i_data
;
590 if( i_type
== 2 && i_frame_data
> i_pos
)
591 i_frame_data
= i_pos
;
593 if( i_frame_data
> i_data
)
598 if( tk
->i_frame_slice
> tk
->i_frame_slice_count
|| !tk
->p_frame
)
602 SetDWLE( &tk
->p_frame
->p_buffer
[2*4*(tk
->i_frame_slice
-1) + 1 + 0], 1 );
603 SetDWLE( &tk
->p_frame
->p_buffer
[2*4*(tk
->i_frame_slice
-1) + 1 + 4], tk
->i_frame_pos
- (2*4 * tk
->i_frame_slice_count
+ 1) );
605 if( tk
->i_frame_pos
+ i_frame_data
> tk
->i_frame_size
)
608 memcpy( &tk
->p_frame
->p_buffer
[tk
->i_frame_pos
], p_data
, i_frame_data
);
609 RVoid( &p_data
, &i_data
, i_frame_data
);
610 tk
->i_frame_pos
+= i_frame_data
;
612 if( i_type
!= 0 || tk
->i_frame_pos
>= tk
->i_frame_size
)
614 /* Fix the buffer once the real number of slice is known */
615 tk
->p_frame
->p_buffer
[0] = tk
->i_frame_slice
- 1;
616 tk
->p_frame
->i_buffer
= tk
->i_frame_pos
- 2*4*( tk
->i_frame_slice_count
- tk
->i_frame_slice
);
618 memmove( &tk
->p_frame
->p_buffer
[1+2*4*tk
->i_frame_slice
],
619 &tk
->p_frame
->p_buffer
[1+2*4*tk
->i_frame_slice_count
],
620 tk
->i_frame_pos
- (2*4*tk
->i_frame_slice_count
+ 1) );
623 CheckPcr( p_demux
, tk
, tk
->p_frame
->i_dts
);
624 es_out_Send( p_demux
->out
, tk
->p_es
, tk
->p_frame
);
626 tk
->i_frame_size
= 0;
632 static void DemuxAudioMethod1( demux_t
*p_demux
, real_track_t
*tk
, mtime_t i_pts
, unsigned int i_flags
)
634 demux_sys_t
*p_sys
= p_demux
->p_sys
;
635 uint8_t *p_buf
= p_sys
->buffer
;
638 if( (i_flags
& 2) || p_sys
->b_seek
)
641 tk
->i_out_subpacket
= 0;
642 p_sys
->b_seek
= false;
645 if( tk
->fmt
.i_codec
== VLC_CODEC_COOK
||
646 tk
->fmt
.i_codec
== VLC_CODEC_ATRAC3
)
648 const int i_num
= tk
->i_frame_size
/ tk
->i_subpacket_size
;
649 const int y
= tk
->i_subpacket
/ ( tk
->i_frame_size
/ tk
->i_subpacket_size
);
651 for( int i
= 0; i
< i_num
; i
++ )
653 int i_index
= tk
->i_subpacket_h
* i
+
654 ((tk
->i_subpacket_h
+ 1) / 2) * (y
&1) + (y
>>1);
655 if( i_index
>= tk
->i_subpackets
)
658 block_t
*p_block
= block_Alloc( tk
->i_subpacket_size
);
661 if( &p_buf
[tk
->i_subpacket_size
] > &p_sys
->buffer
[p_sys
->i_buffer
] )
664 memcpy( p_block
->p_buffer
, p_buf
, tk
->i_subpacket_size
);
666 p_block
->i_pts
= VLC_TS_INVALID
;
668 p_buf
+= tk
->i_subpacket_size
;
670 if( tk
->p_subpackets
[i_index
] != NULL
)
672 msg_Dbg(p_demux
, "p_subpackets[ %d ] not null!", i_index
);
673 block_Release( tk
->p_subpackets
[i_index
] );
676 tk
->p_subpackets
[i_index
] = p_block
;
677 if( tk
->i_subpacket
== 0 )
678 tk
->p_subpackets_timecode
[0] = i_pts
;
684 const int y
= tk
->i_subpacket
/ (tk
->i_subpacket_h
/ 2);
685 assert( tk
->fmt
.i_codec
== VLC_CODEC_RA_288
);
687 for( int i
= 0; i
< tk
->i_subpacket_h
/ 2; i
++ )
689 int i_index
= (i
* 2 * tk
->i_frame_size
/ tk
->i_coded_frame_size
) + y
;
690 if( i_index
>= tk
->i_subpackets
)
693 block_t
*p_block
= block_Alloc( tk
->i_coded_frame_size
);
696 if( &p_buf
[tk
->i_coded_frame_size
] > &p_sys
->buffer
[p_sys
->i_buffer
] )
699 memcpy( p_block
->p_buffer
, p_buf
, tk
->i_coded_frame_size
);
701 p_block
->i_pts
= i_index
== 0 ? i_pts
: VLC_TS_INVALID
;
703 p_buf
+= tk
->i_coded_frame_size
;
705 if( tk
->p_subpackets
[i_index
] != NULL
)
707 msg_Dbg(p_demux
, "p_subpackets[ %d ] not null!", i_index
);
708 block_Release( tk
->p_subpackets
[i_index
] );
711 tk
->p_subpackets
[i_index
] = p_block
;
716 while( tk
->i_out_subpacket
!= tk
->i_subpackets
&&
717 tk
->p_subpackets
[tk
->i_out_subpacket
] )
719 block_t
*p_block
= tk
->p_subpackets
[tk
->i_out_subpacket
];
720 tk
->p_subpackets
[tk
->i_out_subpacket
] = NULL
;
722 if( tk
->p_subpackets_timecode
[tk
->i_out_subpacket
] )
725 p_block
->i_pts
= tk
->p_subpackets_timecode
[tk
->i_out_subpacket
];
727 tk
->p_subpackets_timecode
[tk
->i_out_subpacket
] = 0;
729 tk
->i_out_subpacket
++;
731 CheckPcr( p_demux
, tk
, p_block
->i_pts
);
732 es_out_Send( p_demux
->out
, tk
->p_es
, p_block
);
735 if( tk
->i_subpacket
== tk
->i_subpackets
&&
736 tk
->i_out_subpacket
!= tk
->i_subpackets
)
738 msg_Warn( p_demux
, "i_subpacket != i_out_subpacket, "
739 "this shouldn't happen" );
742 if( tk
->i_subpacket
== tk
->i_subpackets
)
745 tk
->i_out_subpacket
= 0;
749 static void DemuxAudioMethod2( demux_t
*p_demux
, real_track_t
*tk
, mtime_t i_pts
)
751 demux_sys_t
*p_sys
= p_demux
->p_sys
;
753 if( p_sys
->i_buffer
< 2 )
756 unsigned i_sub
= (p_sys
->buffer
[1] >> 4)&0x0f;
757 if( p_sys
->i_buffer
< 2+2*i_sub
)
760 uint8_t *p_sub
= &p_sys
->buffer
[2+2*i_sub
];
762 for( unsigned i
= 0; i
< i_sub
; i
++ )
764 const int i_sub_size
= GetWBE( &p_sys
->buffer
[2+i
*2] );
765 block_t
*p_block
= block_Alloc( i_sub_size
);
769 if( &p_sub
[i_sub_size
] > &p_sys
->buffer
[p_sys
->i_buffer
] )
772 memcpy( p_block
->p_buffer
, p_sub
, i_sub_size
);
776 p_block
->i_pts
= i
== 0 ? i_pts
: VLC_TS_INVALID
;
778 CheckPcr( p_demux
, tk
, p_block
->i_pts
);
779 es_out_Send( p_demux
->out
, tk
->p_es
, p_block
);
782 static void DemuxAudioMethod3( demux_t
*p_demux
, real_track_t
*tk
, mtime_t i_pts
)
784 demux_sys_t
*p_sys
= p_demux
->p_sys
;
786 if( p_sys
->i_buffer
<= 0 )
789 block_t
*p_block
= block_Alloc( p_sys
->i_buffer
);
793 if( tk
->fmt
.i_codec
== VLC_CODEC_A52
)
795 uint8_t *p_src
= p_sys
->buffer
;
796 uint8_t *p_dst
= p_block
->p_buffer
;
799 while( p_dst
< &p_block
->p_buffer
[p_sys
->i_buffer
- 1])
809 memcpy( p_block
->p_buffer
, p_sys
->buffer
, p_sys
->i_buffer
);
812 p_block
->i_pts
= i_pts
;
814 CheckPcr( p_demux
, tk
, p_block
->i_pts
);
815 es_out_Send( p_demux
->out
, tk
->p_es
, p_block
);
818 // Sipr packet re-ordering code and index table borrowed from
819 // the MPlayer Realmedia demuxer.
820 static const uint8_t sipr_swap_index_table
[38][2] = {
821 { 0, 63 }, { 1, 22 }, { 2, 44 }, { 3, 90 },
822 { 5, 81 }, { 7, 31 }, { 8, 86 }, { 9, 58 },
823 { 10, 36 }, { 12, 68 }, { 13, 39 }, { 14, 73 },
824 { 15, 53 }, { 16, 69 }, { 17, 57 }, { 19, 88 },
825 { 20, 34 }, { 21, 71 }, { 24, 46 }, { 25, 94 },
826 { 26, 54 }, { 28, 75 }, { 29, 50 }, { 32, 70 },
827 { 33, 92 }, { 35, 74 }, { 38, 85 }, { 40, 56 },
828 { 42, 87 }, { 43, 65 }, { 45, 59 }, { 48, 79 },
829 { 49, 93 }, { 51, 89 }, { 55, 95 }, { 61, 76 },
830 { 67, 83 }, { 77, 80 }
833 static void SiprPacketReorder(uint8_t *buf
, int sub_packet_h
, int framesize
)
835 int n
, bs
= sub_packet_h
* framesize
* 2 / 96; // nibbles per subpacket
837 for (n
= 0; n
< 38; n
++) {
839 int i
= bs
* sipr_swap_index_table
[n
][0];
840 int o
= bs
* sipr_swap_index_table
[n
][1];
842 /* swap 4 bit-nibbles of block 'i' with 'o' */
843 for (j
= 0; j
< bs
; j
++, i
++, o
++) {
844 int x
= (buf
[i
>> 1] >> (4 * (i
& 1))) & 0xF,
845 y
= (buf
[o
>> 1] >> (4 * (o
& 1))) & 0xF;
847 buf
[o
>> 1] = (x
<< (4 * (o
& 1))) |
848 (buf
[o
>> 1] & (0xF << (4 * !(o
& 1))));
849 buf
[i
>> 1] = (y
<< (4 * (i
& 1))) |
850 (buf
[i
>> 1] & (0xF << (4 * !(i
& 1))));
855 static void DemuxAudioSipr( demux_t
*p_demux
, real_track_t
*tk
, mtime_t i_pts
)
857 demux_sys_t
*p_sys
= p_demux
->p_sys
;
858 block_t
*p_block
= tk
->p_sipr_packet
;
860 if( p_sys
->i_buffer
< tk
->i_frame_size
861 || tk
->i_sipr_subpacket_count
>= tk
->i_subpacket_h
)
866 p_block
= block_Alloc( tk
->i_frame_size
* tk
->i_subpacket_h
);
869 tk
->p_sipr_packet
= p_block
;
871 memcpy( p_block
->p_buffer
+ tk
->i_sipr_subpacket_count
* tk
->i_frame_size
,
872 p_sys
->buffer
, tk
->i_frame_size
);
873 if (!tk
->i_sipr_subpacket_count
)
876 p_block
->i_pts
= i_pts
;
879 if( ++tk
->i_sipr_subpacket_count
< tk
->i_subpacket_h
)
882 SiprPacketReorder(p_block
->p_buffer
, tk
->i_subpacket_h
, tk
->i_frame_size
);
883 CheckPcr( p_demux
, tk
, p_block
->i_pts
);
884 es_out_Send( p_demux
->out
, tk
->p_es
, p_block
);
885 tk
->i_sipr_subpacket_count
= 0;
886 tk
->p_sipr_packet
= NULL
;
889 static void DemuxAudio( demux_t
*p_demux
, real_track_t
*tk
, mtime_t i_pts
, unsigned i_flags
)
891 switch( tk
->fmt
.i_codec
)
894 case VLC_CODEC_ATRAC3
:
895 case VLC_CODEC_RA_288
:
896 DemuxAudioMethod1( p_demux
, tk
, i_pts
, i_flags
);
899 DemuxAudioMethod2( p_demux
, tk
, i_pts
);
902 DemuxAudioSipr( p_demux
, tk
, i_pts
);
905 DemuxAudioMethod3( p_demux
, tk
, i_pts
);
910 /*****************************************************************************
911 * Helpers: seek/control
912 *****************************************************************************/
913 static int ControlGoToIndex( demux_t
*p_demux
, real_index_t
*p_index
)
915 demux_sys_t
*p_sys
= p_demux
->p_sys
;
917 p_sys
->b_seek
= true;
918 p_sys
->i_pcr
= INT64_C(1000) * p_index
->i_time_offset
;
919 for( int i
= 0; i
< p_sys
->i_track
; i
++ )
920 p_sys
->track
[i
]->i_last_dts
= 0;
921 return vlc_stream_Seek( p_demux
->s
, p_index
->i_file_offset
);
923 static int ControlSeekTime( demux_t
*p_demux
, mtime_t i_time
)
925 demux_sys_t
*p_sys
= p_demux
->p_sys
;
926 real_index_t
*p_index
= p_sys
->p_index
;
928 while( p_index
->i_file_offset
!= 0 )
930 if( p_index
->i_time_offset
* INT64_C(1000) > i_time
)
932 if( p_index
!= p_sys
->p_index
)
938 if( p_index
->i_file_offset
== 0 )
940 return ControlGoToIndex( p_demux
, p_index
);
942 static int ControlSeekByte( demux_t
*p_demux
, int64_t i_bytes
)
944 demux_sys_t
*p_sys
= p_demux
->p_sys
;
945 real_index_t
*p_index
= p_sys
->p_index
;
947 while( p_index
->i_file_offset
!= 0 )
949 if( p_index
->i_file_offset
> i_bytes
)
951 if( p_index
!= p_sys
->p_index
)
957 if( p_index
->i_file_offset
== 0 )
959 return ControlGoToIndex( p_demux
, p_index
);
962 /*****************************************************************************
963 * Helpers: header reading
964 *****************************************************************************/
967 * This function will read a Pascal string with size stored in 2 bytes from
970 * FIXME what is the right charset ?
972 static char *StreamReadString2( stream_t
*s
)
976 if( vlc_stream_Read( s
, p_tmp
, 2 ) < 2 )
979 const int i_length
= GetWBE( p_tmp
);
983 char *psz_string
= malloc( i_length
+ 1 );
984 if( unlikely(psz_string
== NULL
) )
987 if( vlc_stream_Read( s
, psz_string
, i_length
) < i_length
)
993 psz_string
[i_length
] = '\0';
994 EnsureUTF8( psz_string
);
999 * This function will read a pascal string with size stored in 1 byte from a
1002 * FIXME what is the right charset ?
1004 static char *MemoryReadString1( const uint8_t **pp_data
, int *pi_data
)
1006 const uint8_t *p_data
= *pp_data
;
1007 int i_data
= *pi_data
;
1009 char *psz_string
= NULL
;
1014 int i_length
= *p_data
++; i_data
--;
1015 if( i_length
> i_data
)
1020 psz_string
= strndup( (const char*)p_data
, i_length
);
1022 EnsureUTF8( psz_string
);
1035 * This function parses(skip) the .RMF identification chunk.
1037 static int HeaderRMF( demux_t
*p_demux
)
1039 uint8_t p_buffer
[8];
1041 if( vlc_stream_Read( p_demux
->s
, p_buffer
, 8 ) < 8 )
1042 return VLC_EGENERIC
;
1044 msg_Dbg( p_demux
, " - file version=0x%x num headers=%d",
1045 GetDWBE( &p_buffer
[0] ), GetDWBE( &p_buffer
[4] ) );
1049 * This function parses the PROP properties chunk.
1051 static int HeaderPROP( demux_t
*p_demux
)
1053 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1055 uint8_t p_buffer
[40];
1058 if( vlc_stream_Read( p_demux
->s
, p_buffer
, 40 ) < 40 )
1059 return VLC_EGENERIC
;
1061 msg_Dbg( p_demux
, " - max bitrate=%d avg bitrate=%d",
1062 GetDWBE(&p_buffer
[0]), GetDWBE(&p_buffer
[4]) );
1063 msg_Dbg( p_demux
, " - max packet size=%d avg bitrate=%d",
1064 GetDWBE(&p_buffer
[8]), GetDWBE(&p_buffer
[12]) );
1065 msg_Dbg( p_demux
, " - packets count=%d", GetDWBE(&p_buffer
[16]) );
1066 msg_Dbg( p_demux
, " - duration=%d ms", GetDWBE(&p_buffer
[20]) );
1067 msg_Dbg( p_demux
, " - preroll=%d ms", GetDWBE(&p_buffer
[24]) );
1068 msg_Dbg( p_demux
, " - index offset=%d", GetDWBE(&p_buffer
[28]) );
1069 msg_Dbg( p_demux
, " - data offset=%d", GetDWBE(&p_buffer
[32]) );
1070 msg_Dbg( p_demux
, " - num streams=%d", GetWBE(&p_buffer
[36]) );
1072 /* set the duration for export in control */
1073 p_sys
->i_our_duration
= GetDWBE(&p_buffer
[20]);
1075 p_sys
->i_index_offset
= GetDWBE(&p_buffer
[28]);
1077 i_flags
= GetWBE(&p_buffer
[38]);
1078 msg_Dbg( p_demux
, " - flags=0x%x %s%s%s",
1080 i_flags
&0x0001 ? "PN_SAVE_ENABLED " : "",
1081 i_flags
&0x0002 ? "PN_PERFECT_PLAY_ENABLED " : "",
1082 i_flags
&0x0004 ? "PN_LIVE_BROADCAST" : "" );
1087 * This functions parses the CONT commentairs chunk.
1089 static int HeaderCONT( demux_t
*p_demux
)
1091 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1094 p_sys
->psz_title
= StreamReadString2( p_demux
->s
);
1095 if( p_sys
->psz_title
)
1096 msg_Dbg( p_demux
, " - title=`%s'", p_sys
->psz_title
);
1099 p_sys
->psz_artist
= StreamReadString2( p_demux
->s
);
1100 if( p_sys
->psz_artist
)
1101 msg_Dbg( p_demux
, " - artist=`%s'", p_sys
->psz_artist
);
1104 p_sys
->psz_copyright
= StreamReadString2( p_demux
->s
);
1105 if( p_sys
->psz_copyright
)
1106 msg_Dbg( p_demux
, " - copyright=`%s'", p_sys
->psz_copyright
);
1109 p_sys
->psz_description
= StreamReadString2( p_demux
->s
);
1110 if( p_sys
->psz_description
)
1111 msg_Dbg( p_demux
, " - comment=`%s'", p_sys
->psz_description
);
1116 * This function parses the MDPR (Media properties) chunk.
1118 static int HeaderMDPR( demux_t
*p_demux
)
1120 uint8_t p_buffer
[30];
1122 if( vlc_stream_Read( p_demux
->s
, p_buffer
, 30 ) < 30 )
1123 return VLC_EGENERIC
;
1125 const int i_num
= GetWBE( &p_buffer
[0] );
1126 msg_Dbg( p_demux
, " - id=0x%x", i_num
);
1127 msg_Dbg( p_demux
, " - max bitrate=%d avg bitrate=%d",
1128 GetDWBE(&p_buffer
[2]), GetDWBE(&p_buffer
[6]) );
1129 msg_Dbg( p_demux
, " - max packet size=%d avg packet size=%d",
1130 GetDWBE(&p_buffer
[10]), GetDWBE(&p_buffer
[14]) );
1131 msg_Dbg( p_demux
, " - start time=%d", GetDWBE(&p_buffer
[18]) );
1132 msg_Dbg( p_demux
, " - preroll=%d", GetDWBE(&p_buffer
[22]) );
1133 msg_Dbg( p_demux
, " - duration=%d", GetDWBE(&p_buffer
[26]) );
1136 const uint8_t *p_peek
;
1137 int i_peek_org
= vlc_stream_Peek( p_demux
->s
, &p_peek
, 2 * 256 );
1138 int i_peek
= i_peek_org
;
1140 return VLC_EGENERIC
;
1142 char *psz_name
= MemoryReadString1( &p_peek
, &i_peek
);
1145 msg_Dbg( p_demux
, " - name=`%s'", psz_name
);
1148 char *psz_mime
= MemoryReadString1( &p_peek
, &i_peek
);
1151 msg_Dbg( p_demux
, " - mime=`%s'", psz_mime
);
1154 const int i_skip
= i_peek_org
- i_peek
;
1155 if( i_skip
> 0 && vlc_stream_Read( p_demux
->s
, NULL
, i_skip
) < i_skip
)
1156 return VLC_EGENERIC
;
1159 if( vlc_stream_Read( p_demux
->s
, p_buffer
, 4 ) < 4 )
1160 return VLC_EGENERIC
;
1162 const uint32_t i_size
= GetDWBE( p_buffer
);
1165 CodecParse( p_demux
, i_size
, i_num
);
1166 unsigned size
= vlc_stream_Read( p_demux
->s
, NULL
, i_size
);
1168 return VLC_EGENERIC
;
1173 * This function parses DATA chunk (it contains the actual movie data).
1175 static int HeaderDATA( demux_t
*p_demux
, uint32_t i_size
)
1177 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1178 uint8_t p_buffer
[8];
1180 if( vlc_stream_Read( p_demux
->s
, p_buffer
, 8 ) < 8 )
1181 return VLC_EGENERIC
;
1183 p_sys
->i_data_offset
= vlc_stream_Tell( p_demux
->s
) - 10;
1184 p_sys
->i_data_size
= i_size
;
1185 p_sys
->i_data_packets_count
= GetDWBE( p_buffer
);
1186 p_sys
->i_data_packets
= 0;
1187 p_sys
->i_data_offset_next
= GetDWBE( &p_buffer
[4] );
1189 msg_Dbg( p_demux
, " - packets count=%d next=%u",
1190 p_sys
->i_data_packets_count
,
1191 (unsigned int)p_sys
->i_data_offset_next
);
1195 * This function parses the INDX (movie index chunk).
1196 * It is optional but seeking without it is ... hard.
1198 static void HeaderINDX( demux_t
*p_demux
)
1200 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1203 uint32_t i_index_count
;
1205 if( p_sys
->i_index_offset
== 0 )
1208 if( vlc_stream_Seek( p_demux
->s
, p_sys
->i_index_offset
)
1209 || vlc_stream_Read( p_demux
->s
, buffer
, 20 ) < 20 )
1212 const uint32_t i_id
= VLC_FOURCC( buffer
[0], buffer
[1], buffer
[2], buffer
[3] );
1213 const uint32_t i_size
= GetDWBE( &buffer
[4] );
1214 int i_version
= GetWBE( &buffer
[8] );
1216 msg_Dbg( p_demux
, "Real index %4.4s size=%d version=%d",
1217 (char*)&i_id
, i_size
, i_version
);
1219 if( (i_size
< 20) && (i_id
!= VLC_FOURCC('I','N','D','X')) )
1222 i_index_count
= GetDWBE( &buffer
[10] );
1224 msg_Dbg( p_demux
, "Real Index : num : %d ", i_index_count
);
1226 if( i_index_count
>= ( 0xffffffff / sizeof(*p_sys
->p_index
) ) )
1229 if( GetDWBE( &buffer
[16] ) > 0 )
1230 msg_Dbg( p_demux
, "Real Index: Does next index exist? %d ",
1231 GetDWBE( &buffer
[16] ) );
1233 /* One extra entry is allocated (that MUST be set to 0) to identify the
1235 * TODO add a clean entry count (easier to build index on the fly) */
1236 p_sys
->p_index
= calloc( i_index_count
+ 1, sizeof(*p_sys
->p_index
) );
1237 if( !p_sys
->p_index
)
1240 for( unsigned int i
= 0; i
< i_index_count
; i
++ )
1242 uint8_t p_entry
[14];
1244 if( vlc_stream_Read( p_demux
->s
, p_entry
, 14 ) < 14 )
1247 if( GetWBE( &p_entry
[0] ) != 0 )
1249 msg_Dbg( p_demux
, "Real Index: invaild version of index entry %d ",
1250 GetWBE( &p_entry
[0] ) );
1254 real_index_t
*p_idx
= &p_sys
->p_index
[i
];
1256 p_idx
->i_time_offset
= GetDWBE( &p_entry
[2] );
1257 p_idx
->i_file_offset
= GetDWBE( &p_entry
[6] );
1258 p_idx
->i_frame_index
= GetDWBE( &p_entry
[10] );
1262 "Real Index: time %"PRIu32
" file %"PRIu32
" frame %"PRIu32
,
1263 p_idx
->i_time_offset
,
1264 p_idx
->i_file_offset
,
1265 p_idx
->i_frame_index
);
1272 * This function parses the complete RM headers and move the
1273 * stream pointer to the data to be read.
1275 static int HeaderRead( demux_t
*p_demux
)
1277 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1281 const int64_t i_stream_position
= vlc_stream_Tell( p_demux
->s
);
1282 uint8_t header
[100]; /* FIXME */
1284 /* Read the header */
1285 if( vlc_stream_Read( p_demux
->s
, header
, 10 ) < 10 )
1286 return VLC_EGENERIC
;
1288 const uint32_t i_id
= VLC_FOURCC( header
[0], header
[1],
1289 header
[2], header
[3] );
1290 const uint32_t i_size
= GetDWBE( &header
[4] );
1291 const int i_version
= GetWBE( &header
[8] );
1293 msg_Dbg( p_demux
, "object %4.4s size=%d version=%d",
1294 (char*)&i_id
, i_size
, i_version
);
1297 if( i_size
< 10 && i_id
!= VLC_FOURCC('D','A','T','A') )
1299 msg_Dbg( p_demux
, "invalid size for object %4.4s", (char*)&i_id
);
1300 return VLC_EGENERIC
;
1306 case VLC_FOURCC('.','R','M','F'):
1307 i_ret
= HeaderRMF( p_demux
);
1309 case VLC_FOURCC('P','R','O','P'):
1310 i_ret
= HeaderPROP( p_demux
);
1312 case VLC_FOURCC('C','O','N','T'):
1313 i_ret
= HeaderCONT( p_demux
);
1315 case VLC_FOURCC('M','D','P','R'):
1316 i_ret
= HeaderMDPR( p_demux
);
1318 case VLC_FOURCC('D','A','T','A'):
1319 i_ret
= HeaderDATA( p_demux
, i_size
);
1322 /* unknown header */
1323 msg_Dbg( p_demux
, "unknown chunk" );
1324 i_ret
= VLC_SUCCESS
;
1330 if( i_id
== VLC_FOURCC('D','A','T','A') ) /* In this case, parsing is finished */
1333 /* Skip unread data */
1334 const int64_t i_stream_current
= vlc_stream_Tell( p_demux
->s
);
1335 const int64_t i_stream_skip
= (i_stream_position
+ i_size
) - i_stream_current
;
1337 if( i_stream_skip
> 0 )
1339 if( vlc_stream_Read( p_demux
->s
, NULL
, i_stream_skip
) != i_stream_skip
)
1340 return VLC_EGENERIC
;
1342 else if( i_stream_skip
< 0 )
1344 return VLC_EGENERIC
;
1348 /* read index if possible */
1349 if( p_sys
->i_index_offset
> 0 )
1351 const int64_t i_position
= vlc_stream_Tell( p_demux
->s
);
1353 HeaderINDX( p_demux
);
1355 if( vlc_stream_Seek( p_demux
->s
, i_position
) )
1356 return VLC_EGENERIC
;
1361 static void CodecMetaRead( demux_t
*p_demux
, const uint8_t **pp_data
, int *pi_data
)
1363 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1366 p_sys
->psz_title
= MemoryReadString1( pp_data
, pi_data
);
1367 if( p_sys
->psz_title
)
1368 msg_Dbg( p_demux
, " - title=`%s'", p_sys
->psz_title
);
1371 p_sys
->psz_artist
= MemoryReadString1( pp_data
, pi_data
);
1372 if( p_sys
->psz_artist
)
1373 msg_Dbg( p_demux
, " - artist=`%s'", p_sys
->psz_artist
);
1376 p_sys
->psz_copyright
= MemoryReadString1( pp_data
, pi_data
);
1377 if( p_sys
->psz_copyright
)
1378 msg_Dbg( p_demux
, " - copyright=`%s'", p_sys
->psz_copyright
);
1381 p_sys
->psz_description
= MemoryReadString1( pp_data
, pi_data
);
1382 if( p_sys
->psz_description
)
1383 msg_Dbg( p_demux
, " - Comment=`%s'", p_sys
->psz_description
);
1386 static int CodecVideoParse( demux_t
*p_demux
, int i_tk_id
, const uint8_t *p_data
, int i_data
)
1388 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1391 return VLC_EGENERIC
;
1395 es_format_Init( &fmt
, VIDEO_ES
,
1396 VLC_FOURCC( p_data
[8], p_data
[9], p_data
[10], p_data
[11] ) );
1397 fmt
.video
.i_width
= GetWBE( &p_data
[12] );
1398 fmt
.video
.i_height
= GetWBE( &p_data
[14] );
1399 fmt
.video
.i_visible_width
= fmt
.video
.i_width
;
1400 fmt
.video
.i_visible_height
= fmt
.video
.i_height
;
1401 fmt
.video
.i_frame_rate
= (GetWBE( &p_data
[22] ) << 16) | GetWBE( &p_data
[24] );
1402 fmt
.video
.i_frame_rate_base
= 1 << 16;
1404 fmt
.i_extra
= i_data
- 26;
1405 fmt
.p_extra
= malloc( fmt
.i_extra
);
1409 memcpy( fmt
.p_extra
, &p_data
[26], fmt
.i_extra
);
1411 //msg_Dbg( p_demux, " - video 0x%08x 0x%08x", dw0, dw1 );
1414 switch( GetDWBE( &p_data
[30] ) )
1418 fmt
.i_codec
= VLC_CODEC_RV13
;
1424 fmt
.i_codec
= VLC_CODEC_RV20
;
1427 fmt
.i_codec
= VLC_CODEC_RV30
;
1430 fmt
.i_codec
= VLC_CODEC_RV40
;
1433 msg_Dbg( p_demux
, " - video %4.4s %dx%d - %8.8x",
1434 (char*)&fmt
.i_codec
, fmt
.video
.i_width
, fmt
.video
.i_height
, GetDWBE( &p_data
[30] ) );
1436 real_track_t
*tk
= malloc( sizeof( *tk
) );
1439 es_format_Clean( &fmt
);
1442 tk
->i_out_subpacket
= 0;
1443 tk
->i_subpacket
= 0;
1444 tk
->i_subpackets
= 0;
1445 tk
->p_subpackets
= NULL
;
1446 tk
->p_subpackets_timecode
= NULL
;
1449 tk
->i_frame_num
= -1;
1450 tk
->i_frame_size
= 0;
1453 tk
->p_sipr_packet
= NULL
;
1454 tk
->p_es
= es_out_Add( p_demux
->out
, &fmt
);
1456 TAB_APPEND( p_sys
->i_track
, p_sys
->track
, tk
);
1459 static int CodecAudioParse( demux_t
*p_demux
, int i_tk_id
, const uint8_t *p_data
, int i_data
)
1461 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1465 return VLC_EGENERIC
;
1468 int i_coded_frame_size
= 0;
1469 int i_subpacket_h
= 0;
1470 int i_frame_size
= 0;
1471 int i_subpacket_size
= 0;
1472 char p_genr
[4] = {0,0,0,0};
1473 int i_version
= GetWBE( &p_data
[4] );
1474 int i_extra_codec
= 0;
1476 msg_Dbg( p_demux
, " - audio version=%d", i_version
);
1478 es_format_Init( &fmt
, AUDIO_ES
, 0 );
1480 RVoid( &p_data
, &i_data
, 6 ); /* 4 + version */
1481 if( i_version
== 3 ) /* RMF version 3 or .ra version 3 */
1483 RVoid( &p_data
, &i_data
, 2 + 10 + 4 );
1486 CodecMetaRead( p_demux
, &p_data
, &i_data
);
1488 RVoid( &p_data
, &i_data
, 1 + 1 );
1490 memcpy( &fmt
.i_codec
, p_data
, 4 );
1491 RVoid( &p_data
, &i_data
, 4 );
1493 fmt
.audio
.i_channels
= 1; /* This is always the case in rm3 */
1494 fmt
.audio
.i_rate
= 8000;
1496 msg_Dbg( p_demux
, " - audio codec=%4.4s channels=%d rate=%dHz",
1497 (char*)&fmt
.i_codec
, fmt
.audio
.i_channels
, fmt
.audio
.i_rate
);
1499 else /* RMF version 4/5 or .ra version 4 */
1501 RVoid( &p_data
, &i_data
, 2 + 4 + 4 + 2 + 4 );
1502 i_flavor
= R16( &p_data
, &i_data
);
1503 i_coded_frame_size
= R32( &p_data
, &i_data
);
1504 RVoid( &p_data
, &i_data
, 4 + 4 + 4 );
1505 i_subpacket_h
= R16( &p_data
, &i_data
);
1506 i_frame_size
= R16( &p_data
, &i_data
);
1507 i_subpacket_size
= R16( &p_data
, &i_data
);
1508 if( !i_frame_size
|| !i_coded_frame_size
)
1510 es_format_Clean( &fmt
);
1511 return VLC_EGENERIC
;
1514 RVoid( &p_data
, &i_data
, 2 + (i_version
== 5 ? 6 : 0 ) );
1516 fmt
.audio
.i_rate
= R16( &p_data
, &i_data
);
1517 RVoid( &p_data
, &i_data
, 2 );
1518 fmt
.audio
.i_bitspersample
= R16( &p_data
, &i_data
);
1519 fmt
.audio
.i_channels
= R16( &p_data
, &i_data
);
1520 fmt
.audio
.i_blockalign
= i_frame_size
;
1522 if( i_version
== 5 )
1526 memcpy( p_genr
, &p_data
[0], 4 );
1527 memcpy( &fmt
.i_codec
, &p_data
[4], 4 );
1529 RVoid( &p_data
, &i_data
, 8 );
1531 else /* version 4 */
1534 RVoid( &p_data
, &i_data
, 1 + *p_data
);
1535 if( i_data
>= 1 + 4 )
1536 memcpy( &fmt
.i_codec
, &p_data
[1], 4 );
1538 RVoid( &p_data
, &i_data
, 1 + *p_data
);
1541 msg_Dbg( p_demux
, " - audio codec=%4.4s channels=%d rate=%dHz",
1542 (char*)&fmt
.i_codec
, fmt
.audio
.i_channels
, fmt
.audio
.i_rate
);
1544 RVoid( &p_data
, &i_data
, 3 );
1546 if( p_sys
->b_real_audio
)
1548 CodecMetaRead( p_demux
, &p_data
, &i_data
);
1552 if( i_version
== 5 )
1553 RVoid( &p_data
, &i_data
, 1 );
1554 i_extra_codec
= R32( &p_data
, &i_data
);
1558 switch( fmt
.i_codec
)
1560 case VLC_FOURCC('l','p','c','J'):
1561 case VLC_FOURCC('1','4','_','4'):
1562 fmt
.i_codec
= VLC_CODEC_RA_144
;
1563 fmt
.audio
.i_blockalign
= 0x14 ;
1566 case VLC_FOURCC('2','8','_','8'):
1567 if( i_coded_frame_size
<= 0 )
1569 es_format_Clean( &fmt
);
1570 return VLC_EGENERIC
;
1572 fmt
.i_codec
= VLC_CODEC_RA_288
;
1573 fmt
.audio
.i_blockalign
= i_coded_frame_size
;
1576 case VLC_FOURCC( 'a','5','2',' ' ):
1577 case VLC_FOURCC( 'd','n','e','t' ):
1578 fmt
.i_codec
= VLC_CODEC_A52
;
1581 case VLC_FOURCC( 'r','a','a','c' ):
1582 case VLC_FOURCC( 'r','a','c','p' ):
1583 fmt
.i_codec
= VLC_CODEC_MP4A
;
1585 if( i_extra_codec
> 0 )
1588 RVoid( &p_data
, &i_data
, 1 );
1590 if( i_extra_codec
> 0 )
1592 fmt
.p_extra
= malloc( i_extra_codec
);
1593 if( !fmt
.p_extra
|| i_extra_codec
> i_data
)
1595 free( fmt
.p_extra
);
1599 fmt
.i_extra
= i_extra_codec
;
1600 memcpy( fmt
.p_extra
, p_data
, fmt
.i_extra
);
1604 case VLC_CODEC_SIPR
:
1605 fmt
.i_codec
= VLC_CODEC_SIPR
;
1608 msg_Dbg( p_demux
, " - unsupported sipr flavorc=%i", i_flavor
);
1609 es_format_Clean( &fmt
);
1610 return VLC_EGENERIC
;
1613 i_subpacket_size
= i_subpacket_size_sipr
[i_flavor
];
1614 // The libavcodec sipr decoder requires stream bitrate
1615 // to be set during initialization so that the correct mode
1617 fmt
.i_bitrate
= fmt
.audio
.i_rate
;
1618 msg_Dbg( p_demux
, " - sipr flavor=%i", i_flavor
);
1621 case VLC_CODEC_COOK
:
1622 case VLC_CODEC_ATRAC3
:
1623 if( i_subpacket_size
<= 0 || i_frame_size
/ i_subpacket_size
<= 0 )
1625 es_format_Clean( &fmt
);
1626 return VLC_EGENERIC
;
1628 if( !memcmp( p_genr
, "genr", 4 ) )
1629 fmt
.audio
.i_blockalign
= i_subpacket_size
;
1631 fmt
.audio
.i_blockalign
= i_coded_frame_size
;
1633 if( i_extra_codec
> 0 )
1635 fmt
.p_extra
= malloc( i_extra_codec
);
1636 if( !fmt
.p_extra
|| i_extra_codec
> i_data
)
1638 free( fmt
.p_extra
);
1642 fmt
.i_extra
= i_extra_codec
;
1643 memcpy( fmt
.p_extra
, p_data
, fmt
.i_extra
);
1648 case VLC_FOURCC('r','a','l','f'):
1650 msg_Dbg( p_demux
, " - unknown audio codec=%4.4s",
1651 (char*)&fmt
.i_codec
);
1652 es_format_Clean( &fmt
);
1653 return VLC_EGENERIC
;
1655 msg_Dbg( p_demux
, " - extra data=%d", fmt
.i_extra
);
1658 real_track_t
*tk
= malloc( sizeof( *tk
) );
1661 es_format_Clean( &fmt
);
1666 tk
->i_frame_size
= 0;
1669 tk
->i_subpacket_h
= i_subpacket_h
;
1670 tk
->i_subpacket_size
= i_subpacket_size
;
1671 tk
->i_coded_frame_size
= i_coded_frame_size
;
1672 tk
->i_frame_size
= i_frame_size
;
1674 tk
->i_out_subpacket
= 0;
1675 tk
->i_subpacket
= 0;
1676 tk
->i_subpackets
= 0;
1677 tk
->p_subpackets
= NULL
;
1678 tk
->p_subpackets_timecode
= NULL
;
1680 tk
->p_sipr_packet
= NULL
;
1681 tk
->i_sipr_subpacket_count
= 0;
1683 if( fmt
.i_codec
== VLC_CODEC_COOK
||
1684 fmt
.i_codec
== VLC_CODEC_ATRAC3
)
1687 i_subpacket_h
* i_frame_size
/ tk
->i_subpacket_size
;
1689 xcalloc( tk
->i_subpackets
, sizeof(block_t
*) );
1690 tk
->p_subpackets_timecode
=
1691 xcalloc( tk
->i_subpackets
, sizeof( int64_t ) );
1693 else if( fmt
.i_codec
== VLC_CODEC_RA_288
)
1696 i_subpacket_h
* i_frame_size
/ tk
->i_coded_frame_size
;
1698 xcalloc( tk
->i_subpackets
, sizeof(block_t
*) );
1699 tk
->p_subpackets_timecode
=
1700 xcalloc( tk
->i_subpackets
, sizeof( int64_t ) );
1703 /* Check if the calloc went correctly */
1704 if( tk
->i_subpacket
> 0 && ( !tk
->p_subpackets
|| !tk
->p_subpackets_timecode
) )
1706 free( tk
->p_subpackets_timecode
);
1707 free( tk
->p_subpackets
);
1709 msg_Err( p_demux
, "Can't alloc subpacket" );
1710 return VLC_EGENERIC
;
1714 tk
->p_es
= es_out_Add( p_demux
->out
, &fmt
);
1716 TAB_APPEND( p_sys
->i_track
, p_sys
->track
, tk
);
1722 static int CodecParse( demux_t
*p_demux
, int i_len
, int i_num
)
1724 const uint8_t *p_peek
;
1726 msg_Dbg( p_demux
, " - specific data len=%d", i_len
);
1727 if( vlc_stream_Peek( p_demux
->s
, &p_peek
, i_len
) < i_len
)
1728 return VLC_EGENERIC
;
1730 if( i_len
>= 8 && !memcmp( &p_peek
[4], "VIDO", 4 ) )
1732 return CodecVideoParse( p_demux
, i_num
, p_peek
, i_len
);
1734 else if( i_len
>= 4 && !memcmp( &p_peek
[0], ".ra\xfd", 4 ) )
1736 return CodecAudioParse( p_demux
, i_num
, p_peek
, i_len
);
1741 /*****************************************************************************
1742 * Helpers: memory buffer fct.
1743 *****************************************************************************/
1744 static void RVoid( const uint8_t **pp_data
, int *pi_data
, int i_size
)
1746 if( i_size
> *pi_data
)
1752 #define RX(name, type, size, code ) \
1753 static type name( const uint8_t **pp_data, int *pi_data ) { \
1754 if( *pi_data < (size) ) \
1757 RVoid( pp_data, pi_data, size ); \
1760 RX(R8
, uint8_t, 1, **pp_data
)
1761 RX(R16
, uint16_t, 2, GetWBE( *pp_data
) )
1762 RX(R32
, uint32_t, 4, GetDWBE( *pp_data
) )
1763 static int RLength( const uint8_t **pp_data
, int *pi_data
)
1765 const int v0
= R16( pp_data
, pi_data
) & 0x7FFF;
1768 return (v0
<< 16) | R16( pp_data
, pi_data
);