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 vlc_tick_t
*p_subpackets_timecode
;
108 block_t
*p_sipr_packet
;
109 int i_sipr_subpacket_count
;
110 vlc_tick_t i_last_dts
;
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
, vlc_tick_t i_dts
, unsigned i_flags
);
157 static void DemuxAudio( demux_t
*, real_track_t
*tk
, vlc_tick_t i_pts
, unsigned i_flags
);
159 static int ControlSeekByte( demux_t
*, int64_t i_bytes
);
160 static int ControlSeekTime( demux_t
*, vlc_tick_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_TICK_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 )
286 return VLC_DEMUXER_EOF
;
288 if( memcmp( header
, "DATA", 4 ) )
289 return VLC_DEMUXER_EOF
;
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 )
304 return VLC_DEMUXER_EOF
;
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 vlc_tick_t i_pts
= VLC_TICK_0
+ VLC_TICK_FROM_MS(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?)" );
315 return VLC_DEMUXER_SUCCESS
;
318 p_sys
->i_buffer
= vlc_stream_Read( p_demux
->s
, p_sys
->buffer
, i_size
);
319 if( p_sys
->i_buffer
< i_size
)
320 return VLC_DEMUXER_EOF
;
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
);
332 return VLC_DEMUXER_SUCCESS
;
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 vlc_tick_t i_pcr
= VLC_TICK_INVALID
;
347 for( int i
= 0; i
< p_sys
->i_track
; i
++ )
349 tk
= p_sys
->track
[i
];
351 if( i_pcr
== VLC_TICK_INVALID
|| ( tk
->i_last_dts
!= VLC_TICK_INVALID
&& tk
->i_last_dts
< i_pcr
) )
352 i_pcr
= tk
->i_last_dts
;
354 if( i_pcr
!= VLC_TICK_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
);
359 return VLC_DEMUXER_SUCCESS
;
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_TICK_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_TICK_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_TICK_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_TICK_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
);
488 case DEMUX_CAN_PAUSE
:
489 case DEMUX_SET_PAUSE_STATE
:
490 case DEMUX_CAN_CONTROL_PACE
:
491 case DEMUX_GET_PTS_DELAY
:
492 return demux_vaControlHelper( p_demux
->s
, p_sys
->i_data_offset
,
493 p_sys
->i_data_size
, 0, 1, i_query
, args
);
502 /*****************************************************************************
504 *****************************************************************************/
505 static void CheckPcr( demux_t
*p_demux
, real_track_t
*tk
, vlc_tick_t i_dts
)
507 demux_sys_t
*p_sys
= p_demux
->p_sys
;
509 if( i_dts
!= VLC_TICK_INVALID
)
510 tk
->i_last_dts
= i_dts
;
512 if( p_sys
->i_pcr
!= VLC_TICK_INVALID
|| i_dts
== VLC_TICK_INVALID
)
515 p_sys
->i_pcr
= i_dts
;
516 es_out_SetPCR( p_demux
->out
, p_sys
->i_pcr
);
519 static void DemuxVideo( demux_t
*p_demux
, real_track_t
*tk
, vlc_tick_t i_dts
, unsigned i_flags
)
521 demux_sys_t
*p_sys
= p_demux
->p_sys
;
523 const uint8_t *p_data
= p_sys
->buffer
;
524 int i_data
= p_sys
->i_buffer
;
528 uint8_t i_hdr
= R8( &p_data
, &i_data
);
529 uint8_t i_type
= i_hdr
>> 6;
538 R8( &p_data
, &i_data
);
545 else if( i_type
== 3 )
547 i_len
= RLength( &p_data
, &i_data
);
548 i_pos
= RLength( &p_data
, &i_data
);
549 i_frame_num
= R8( &p_data
, &i_data
);
555 assert( i_type
== 0 || i_type
== 2 );
556 i_seq
= R8( &p_data
, &i_data
);
557 i_len
= RLength( &p_data
, &i_data
);
559 i_pos
= RLength( &p_data
, &i_data
);
560 i_frame_num
= R8( &p_data
, &i_data
);
563 if( (i_seq
& 0x7f) == 1 || tk
->i_frame_num
!= i_frame_num
)
565 tk
->i_frame_slice
= 0;
566 tk
->i_frame_slice_count
= 2 * (i_hdr
& 0x3f) + 1;
567 tk
->i_frame_pos
= 2*4 * tk
->i_frame_slice_count
+ 1;
568 tk
->i_frame_size
= i_len
+ 2*4 * tk
->i_frame_slice_count
+ 1;
569 tk
->i_frame_num
= i_frame_num
;
572 block_Release( tk
->p_frame
);
574 tk
->p_frame
= block_Alloc( tk
->i_frame_size
);
577 tk
->i_frame_size
= 0;
581 tk
->p_frame
->i_dts
= i_dts
;
582 tk
->p_frame
->i_pts
= VLC_TICK_INVALID
;
584 tk
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_I
;
586 i_dts
= VLC_TICK_INVALID
;
592 i_frame_data
= i_len
;
596 i_frame_data
= i_data
;
597 if( i_type
== 2 && i_frame_data
> i_pos
)
598 i_frame_data
= i_pos
;
600 if( i_frame_data
> i_data
)
605 if( tk
->i_frame_slice
> tk
->i_frame_slice_count
|| !tk
->p_frame
)
609 SetDWLE( &tk
->p_frame
->p_buffer
[2*4*(tk
->i_frame_slice
-1) + 1 + 0], 1 );
610 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) );
612 if( tk
->i_frame_pos
+ i_frame_data
> tk
->i_frame_size
)
615 memcpy( &tk
->p_frame
->p_buffer
[tk
->i_frame_pos
], p_data
, i_frame_data
);
616 RVoid( &p_data
, &i_data
, i_frame_data
);
617 tk
->i_frame_pos
+= i_frame_data
;
619 if( i_type
!= 0 || tk
->i_frame_pos
>= tk
->i_frame_size
)
621 /* Fix the buffer once the real number of slice is known */
622 tk
->p_frame
->p_buffer
[0] = tk
->i_frame_slice
- 1;
623 tk
->p_frame
->i_buffer
= tk
->i_frame_pos
- 2*4*( tk
->i_frame_slice_count
- tk
->i_frame_slice
);
625 memmove( &tk
->p_frame
->p_buffer
[1+2*4*tk
->i_frame_slice
],
626 &tk
->p_frame
->p_buffer
[1+2*4*tk
->i_frame_slice_count
],
627 tk
->i_frame_pos
- (2*4*tk
->i_frame_slice_count
+ 1) );
630 CheckPcr( p_demux
, tk
, tk
->p_frame
->i_dts
);
631 es_out_Send( p_demux
->out
, tk
->p_es
, tk
->p_frame
);
633 tk
->i_frame_size
= 0;
639 static void DemuxAudioMethod1( demux_t
*p_demux
, real_track_t
*tk
, vlc_tick_t i_pts
, unsigned int i_flags
)
641 demux_sys_t
*p_sys
= p_demux
->p_sys
;
642 uint8_t *p_buf
= p_sys
->buffer
;
645 if( (i_flags
& 2) || p_sys
->b_seek
)
648 tk
->i_out_subpacket
= 0;
649 p_sys
->b_seek
= false;
652 if( tk
->fmt
.i_codec
== VLC_CODEC_COOK
||
653 tk
->fmt
.i_codec
== VLC_CODEC_ATRAC3
)
655 const int i_num
= tk
->i_frame_size
/ tk
->i_subpacket_size
;
656 const int y
= tk
->i_subpacket
/ ( tk
->i_frame_size
/ tk
->i_subpacket_size
);
658 for( int i
= 0; i
< i_num
; i
++ )
660 int i_index
= tk
->i_subpacket_h
* i
+
661 ((tk
->i_subpacket_h
+ 1) / 2) * (y
&1) + (y
>>1);
662 if( i_index
>= tk
->i_subpackets
)
665 block_t
*p_block
= block_Alloc( tk
->i_subpacket_size
);
668 if( &p_buf
[tk
->i_subpacket_size
] > &p_sys
->buffer
[p_sys
->i_buffer
] )
671 memcpy( p_block
->p_buffer
, p_buf
, tk
->i_subpacket_size
);
673 p_block
->i_pts
= VLC_TICK_INVALID
;
675 p_buf
+= tk
->i_subpacket_size
;
677 if( tk
->p_subpackets
[i_index
] != NULL
)
679 msg_Dbg(p_demux
, "p_subpackets[ %d ] not null!", i_index
);
680 block_Release( tk
->p_subpackets
[i_index
] );
683 tk
->p_subpackets
[i_index
] = p_block
;
684 if( tk
->i_subpacket
== 0 )
685 tk
->p_subpackets_timecode
[0] = i_pts
;
691 const int y
= tk
->i_subpacket
/ (tk
->i_subpacket_h
/ 2);
692 assert( tk
->fmt
.i_codec
== VLC_CODEC_RA_288
);
694 for( int i
= 0; i
< tk
->i_subpacket_h
/ 2; i
++ )
696 int i_index
= (i
* 2 * tk
->i_frame_size
/ tk
->i_coded_frame_size
) + y
;
697 if( i_index
>= tk
->i_subpackets
)
700 block_t
*p_block
= block_Alloc( tk
->i_coded_frame_size
);
703 if( &p_buf
[tk
->i_coded_frame_size
] > &p_sys
->buffer
[p_sys
->i_buffer
] )
706 memcpy( p_block
->p_buffer
, p_buf
, tk
->i_coded_frame_size
);
708 p_block
->i_pts
= i_index
== 0 ? i_pts
: VLC_TICK_INVALID
;
710 p_buf
+= tk
->i_coded_frame_size
;
712 if( tk
->p_subpackets
[i_index
] != NULL
)
714 msg_Dbg(p_demux
, "p_subpackets[ %d ] not null!", i_index
);
715 block_Release( tk
->p_subpackets
[i_index
] );
718 tk
->p_subpackets
[i_index
] = p_block
;
723 while( tk
->i_out_subpacket
!= tk
->i_subpackets
&&
724 tk
->p_subpackets
[tk
->i_out_subpacket
] )
726 block_t
*p_block
= tk
->p_subpackets
[tk
->i_out_subpacket
];
727 tk
->p_subpackets
[tk
->i_out_subpacket
] = NULL
;
729 if( tk
->p_subpackets_timecode
[tk
->i_out_subpacket
] )
732 p_block
->i_pts
= tk
->p_subpackets_timecode
[tk
->i_out_subpacket
];
734 tk
->p_subpackets_timecode
[tk
->i_out_subpacket
] = 0;
736 tk
->i_out_subpacket
++;
738 CheckPcr( p_demux
, tk
, p_block
->i_pts
);
739 es_out_Send( p_demux
->out
, tk
->p_es
, p_block
);
742 if( tk
->i_subpacket
== tk
->i_subpackets
&&
743 tk
->i_out_subpacket
!= tk
->i_subpackets
)
745 msg_Warn( p_demux
, "i_subpacket != i_out_subpacket, "
746 "this shouldn't happen" );
749 if( tk
->i_subpacket
== tk
->i_subpackets
)
752 tk
->i_out_subpacket
= 0;
756 static void DemuxAudioMethod2( demux_t
*p_demux
, real_track_t
*tk
, vlc_tick_t i_pts
)
758 demux_sys_t
*p_sys
= p_demux
->p_sys
;
760 if( p_sys
->i_buffer
< 2 )
763 unsigned i_sub
= (p_sys
->buffer
[1] >> 4)&0x0f;
764 if( p_sys
->i_buffer
< 2+2*i_sub
)
767 uint8_t *p_sub
= &p_sys
->buffer
[2+2*i_sub
];
769 for( unsigned i
= 0; i
< i_sub
; i
++ )
771 const int i_sub_size
= GetWBE( &p_sys
->buffer
[2+i
*2] );
772 block_t
*p_block
= block_Alloc( i_sub_size
);
776 if( &p_sub
[i_sub_size
] > &p_sys
->buffer
[p_sys
->i_buffer
] )
779 memcpy( p_block
->p_buffer
, p_sub
, i_sub_size
);
783 p_block
->i_pts
= i
== 0 ? i_pts
: VLC_TICK_INVALID
;
785 CheckPcr( p_demux
, tk
, p_block
->i_pts
);
786 es_out_Send( p_demux
->out
, tk
->p_es
, p_block
);
789 static void DemuxAudioMethod3( demux_t
*p_demux
, real_track_t
*tk
, vlc_tick_t i_pts
)
791 demux_sys_t
*p_sys
= p_demux
->p_sys
;
793 if( p_sys
->i_buffer
<= 0 )
796 block_t
*p_block
= block_Alloc( p_sys
->i_buffer
);
800 if( tk
->fmt
.i_codec
== VLC_CODEC_A52
)
802 uint8_t *p_src
= p_sys
->buffer
;
803 uint8_t *p_dst
= p_block
->p_buffer
;
806 while( p_dst
< &p_block
->p_buffer
[p_sys
->i_buffer
- 1])
816 memcpy( p_block
->p_buffer
, p_sys
->buffer
, p_sys
->i_buffer
);
819 p_block
->i_pts
= i_pts
;
821 CheckPcr( p_demux
, tk
, p_block
->i_pts
);
822 es_out_Send( p_demux
->out
, tk
->p_es
, p_block
);
825 // Sipr packet re-ordering code and index table borrowed from
826 // the MPlayer Realmedia demuxer.
827 static const uint8_t sipr_swap_index_table
[38][2] = {
828 { 0, 63 }, { 1, 22 }, { 2, 44 }, { 3, 90 },
829 { 5, 81 }, { 7, 31 }, { 8, 86 }, { 9, 58 },
830 { 10, 36 }, { 12, 68 }, { 13, 39 }, { 14, 73 },
831 { 15, 53 }, { 16, 69 }, { 17, 57 }, { 19, 88 },
832 { 20, 34 }, { 21, 71 }, { 24, 46 }, { 25, 94 },
833 { 26, 54 }, { 28, 75 }, { 29, 50 }, { 32, 70 },
834 { 33, 92 }, { 35, 74 }, { 38, 85 }, { 40, 56 },
835 { 42, 87 }, { 43, 65 }, { 45, 59 }, { 48, 79 },
836 { 49, 93 }, { 51, 89 }, { 55, 95 }, { 61, 76 },
837 { 67, 83 }, { 77, 80 }
840 static void SiprPacketReorder(uint8_t *buf
, int sub_packet_h
, int framesize
)
842 int n
, bs
= sub_packet_h
* framesize
* 2 / 96; // nibbles per subpacket
844 for (n
= 0; n
< 38; n
++) {
846 int i
= bs
* sipr_swap_index_table
[n
][0];
847 int o
= bs
* sipr_swap_index_table
[n
][1];
849 /* swap 4 bit-nibbles of block 'i' with 'o' */
850 for (j
= 0; j
< bs
; j
++, i
++, o
++) {
851 int x
= (buf
[i
>> 1] >> (4 * (i
& 1))) & 0xF,
852 y
= (buf
[o
>> 1] >> (4 * (o
& 1))) & 0xF;
854 buf
[o
>> 1] = (x
<< (4 * (o
& 1))) |
855 (buf
[o
>> 1] & (0xF << (4 * !(o
& 1))));
856 buf
[i
>> 1] = (y
<< (4 * (i
& 1))) |
857 (buf
[i
>> 1] & (0xF << (4 * !(i
& 1))));
862 static void DemuxAudioSipr( demux_t
*p_demux
, real_track_t
*tk
, vlc_tick_t i_pts
)
864 demux_sys_t
*p_sys
= p_demux
->p_sys
;
865 block_t
*p_block
= tk
->p_sipr_packet
;
867 if( p_sys
->i_buffer
< tk
->i_frame_size
868 || tk
->i_sipr_subpacket_count
>= tk
->i_subpacket_h
)
873 p_block
= block_Alloc( tk
->i_frame_size
* tk
->i_subpacket_h
);
876 tk
->p_sipr_packet
= p_block
;
878 memcpy( p_block
->p_buffer
+ tk
->i_sipr_subpacket_count
* tk
->i_frame_size
,
879 p_sys
->buffer
, tk
->i_frame_size
);
880 if (!tk
->i_sipr_subpacket_count
)
883 p_block
->i_pts
= i_pts
;
886 if( ++tk
->i_sipr_subpacket_count
< tk
->i_subpacket_h
)
889 SiprPacketReorder(p_block
->p_buffer
, tk
->i_subpacket_h
, tk
->i_frame_size
);
890 CheckPcr( p_demux
, tk
, p_block
->i_pts
);
891 es_out_Send( p_demux
->out
, tk
->p_es
, p_block
);
892 tk
->i_sipr_subpacket_count
= 0;
893 tk
->p_sipr_packet
= NULL
;
896 static void DemuxAudio( demux_t
*p_demux
, real_track_t
*tk
, vlc_tick_t i_pts
, unsigned i_flags
)
898 switch( tk
->fmt
.i_codec
)
901 case VLC_CODEC_ATRAC3
:
902 case VLC_CODEC_RA_288
:
903 DemuxAudioMethod1( p_demux
, tk
, i_pts
, i_flags
);
906 DemuxAudioMethod2( p_demux
, tk
, i_pts
);
909 DemuxAudioSipr( p_demux
, tk
, i_pts
);
912 DemuxAudioMethod3( p_demux
, tk
, i_pts
);
917 /*****************************************************************************
918 * Helpers: seek/control
919 *****************************************************************************/
920 static int ControlGoToIndex( demux_t
*p_demux
, real_index_t
*p_index
)
922 demux_sys_t
*p_sys
= p_demux
->p_sys
;
924 p_sys
->b_seek
= true;
925 p_sys
->i_pcr
= INT64_C(1000) * p_index
->i_time_offset
;
926 for( int i
= 0; i
< p_sys
->i_track
; i
++ )
927 p_sys
->track
[i
]->i_last_dts
= 0;
928 return vlc_stream_Seek( p_demux
->s
, p_index
->i_file_offset
);
930 static int ControlSeekTime( demux_t
*p_demux
, vlc_tick_t i_time
)
932 demux_sys_t
*p_sys
= p_demux
->p_sys
;
933 real_index_t
*p_index
= p_sys
->p_index
;
935 while( p_index
->i_file_offset
!= 0 )
937 if( p_index
->i_time_offset
* INT64_C(1000) > i_time
)
939 if( p_index
!= p_sys
->p_index
)
945 if( p_index
->i_file_offset
== 0 )
947 return ControlGoToIndex( p_demux
, p_index
);
949 static int ControlSeekByte( demux_t
*p_demux
, int64_t i_bytes
)
951 demux_sys_t
*p_sys
= p_demux
->p_sys
;
952 real_index_t
*p_index
= p_sys
->p_index
;
954 while( p_index
->i_file_offset
!= 0 )
956 if( p_index
->i_file_offset
> i_bytes
)
958 if( p_index
!= p_sys
->p_index
)
964 if( p_index
->i_file_offset
== 0 )
966 return ControlGoToIndex( p_demux
, p_index
);
969 /*****************************************************************************
970 * Helpers: header reading
971 *****************************************************************************/
974 * This function will read a Pascal string with size stored in 2 bytes from
977 * FIXME what is the right charset ?
979 static char *StreamReadString2( stream_t
*s
)
983 if( vlc_stream_Read( s
, p_tmp
, 2 ) < 2 )
986 const int i_length
= GetWBE( p_tmp
);
990 char *psz_string
= malloc( i_length
+ 1 );
991 if( unlikely(psz_string
== NULL
) )
994 if( vlc_stream_Read( s
, psz_string
, i_length
) < i_length
)
1000 psz_string
[i_length
] = '\0';
1001 EnsureUTF8( psz_string
);
1006 * This function will read a pascal string with size stored in 1 byte from a
1009 * FIXME what is the right charset ?
1011 static char *MemoryReadString1( const uint8_t **pp_data
, int *pi_data
)
1013 const uint8_t *p_data
= *pp_data
;
1014 int i_data
= *pi_data
;
1016 char *psz_string
= NULL
;
1021 int i_length
= *p_data
++; i_data
--;
1022 if( i_length
> i_data
)
1027 psz_string
= strndup( (const char*)p_data
, i_length
);
1029 EnsureUTF8( psz_string
);
1042 * This function parses(skip) the .RMF identification chunk.
1044 static int HeaderRMF( demux_t
*p_demux
)
1046 uint8_t p_buffer
[8];
1048 if( vlc_stream_Read( p_demux
->s
, p_buffer
, 8 ) < 8 )
1049 return VLC_EGENERIC
;
1051 msg_Dbg( p_demux
, " - file version=0x%x num headers=%d",
1052 GetDWBE( &p_buffer
[0] ), GetDWBE( &p_buffer
[4] ) );
1056 * This function parses the PROP properties chunk.
1058 static int HeaderPROP( demux_t
*p_demux
)
1060 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1062 uint8_t p_buffer
[40];
1065 if( vlc_stream_Read( p_demux
->s
, p_buffer
, 40 ) < 40 )
1066 return VLC_EGENERIC
;
1068 msg_Dbg( p_demux
, " - max bitrate=%d avg bitrate=%d",
1069 GetDWBE(&p_buffer
[0]), GetDWBE(&p_buffer
[4]) );
1070 msg_Dbg( p_demux
, " - max packet size=%d avg bitrate=%d",
1071 GetDWBE(&p_buffer
[8]), GetDWBE(&p_buffer
[12]) );
1072 msg_Dbg( p_demux
, " - packets count=%d", GetDWBE(&p_buffer
[16]) );
1073 msg_Dbg( p_demux
, " - duration=%d ms", GetDWBE(&p_buffer
[20]) );
1074 msg_Dbg( p_demux
, " - preroll=%d ms", GetDWBE(&p_buffer
[24]) );
1075 msg_Dbg( p_demux
, " - index offset=%d", GetDWBE(&p_buffer
[28]) );
1076 msg_Dbg( p_demux
, " - data offset=%d", GetDWBE(&p_buffer
[32]) );
1077 msg_Dbg( p_demux
, " - num streams=%d", GetWBE(&p_buffer
[36]) );
1079 /* set the duration for export in control */
1080 p_sys
->i_our_duration
= GetDWBE(&p_buffer
[20]);
1082 p_sys
->i_index_offset
= GetDWBE(&p_buffer
[28]);
1084 i_flags
= GetWBE(&p_buffer
[38]);
1085 msg_Dbg( p_demux
, " - flags=0x%x %s%s%s",
1087 i_flags
&0x0001 ? "PN_SAVE_ENABLED " : "",
1088 i_flags
&0x0002 ? "PN_PERFECT_PLAY_ENABLED " : "",
1089 i_flags
&0x0004 ? "PN_LIVE_BROADCAST" : "" );
1094 * This functions parses the CONT commentairs chunk.
1096 static int HeaderCONT( demux_t
*p_demux
)
1098 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1101 p_sys
->psz_title
= StreamReadString2( p_demux
->s
);
1102 if( p_sys
->psz_title
)
1103 msg_Dbg( p_demux
, " - title=`%s'", p_sys
->psz_title
);
1106 p_sys
->psz_artist
= StreamReadString2( p_demux
->s
);
1107 if( p_sys
->psz_artist
)
1108 msg_Dbg( p_demux
, " - artist=`%s'", p_sys
->psz_artist
);
1111 p_sys
->psz_copyright
= StreamReadString2( p_demux
->s
);
1112 if( p_sys
->psz_copyright
)
1113 msg_Dbg( p_demux
, " - copyright=`%s'", p_sys
->psz_copyright
);
1116 p_sys
->psz_description
= StreamReadString2( p_demux
->s
);
1117 if( p_sys
->psz_description
)
1118 msg_Dbg( p_demux
, " - comment=`%s'", p_sys
->psz_description
);
1123 * This function parses the MDPR (Media properties) chunk.
1125 static int HeaderMDPR( demux_t
*p_demux
)
1127 uint8_t p_buffer
[30];
1129 if( vlc_stream_Read( p_demux
->s
, p_buffer
, 30 ) < 30 )
1130 return VLC_EGENERIC
;
1132 const int i_num
= GetWBE( &p_buffer
[0] );
1133 msg_Dbg( p_demux
, " - id=0x%x", i_num
);
1134 msg_Dbg( p_demux
, " - max bitrate=%d avg bitrate=%d",
1135 GetDWBE(&p_buffer
[2]), GetDWBE(&p_buffer
[6]) );
1136 msg_Dbg( p_demux
, " - max packet size=%d avg packet size=%d",
1137 GetDWBE(&p_buffer
[10]), GetDWBE(&p_buffer
[14]) );
1138 msg_Dbg( p_demux
, " - start time=%d", GetDWBE(&p_buffer
[18]) );
1139 msg_Dbg( p_demux
, " - preroll=%d", GetDWBE(&p_buffer
[22]) );
1140 msg_Dbg( p_demux
, " - duration=%d", GetDWBE(&p_buffer
[26]) );
1143 const uint8_t *p_peek
;
1144 int i_peek_org
= vlc_stream_Peek( p_demux
->s
, &p_peek
, 2 * 256 );
1145 int i_peek
= i_peek_org
;
1147 return VLC_EGENERIC
;
1149 char *psz_name
= MemoryReadString1( &p_peek
, &i_peek
);
1152 msg_Dbg( p_demux
, " - name=`%s'", psz_name
);
1155 char *psz_mime
= MemoryReadString1( &p_peek
, &i_peek
);
1158 msg_Dbg( p_demux
, " - mime=`%s'", psz_mime
);
1161 const int i_skip
= i_peek_org
- i_peek
;
1162 if( i_skip
> 0 && vlc_stream_Read( p_demux
->s
, NULL
, i_skip
) < i_skip
)
1163 return VLC_EGENERIC
;
1166 if( vlc_stream_Read( p_demux
->s
, p_buffer
, 4 ) < 4 )
1167 return VLC_EGENERIC
;
1169 const uint32_t i_size
= GetDWBE( p_buffer
);
1172 CodecParse( p_demux
, i_size
, i_num
);
1173 unsigned size
= vlc_stream_Read( p_demux
->s
, NULL
, i_size
);
1175 return VLC_EGENERIC
;
1180 * This function parses DATA chunk (it contains the actual movie data).
1182 static int HeaderDATA( demux_t
*p_demux
, uint32_t i_size
)
1184 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1185 uint8_t p_buffer
[8];
1187 if( vlc_stream_Read( p_demux
->s
, p_buffer
, 8 ) < 8 )
1188 return VLC_EGENERIC
;
1190 p_sys
->i_data_offset
= vlc_stream_Tell( p_demux
->s
) - 10;
1191 p_sys
->i_data_size
= i_size
;
1192 p_sys
->i_data_packets_count
= GetDWBE( p_buffer
);
1193 p_sys
->i_data_packets
= 0;
1194 p_sys
->i_data_offset_next
= GetDWBE( &p_buffer
[4] );
1196 msg_Dbg( p_demux
, " - packets count=%d next=%u",
1197 p_sys
->i_data_packets_count
,
1198 (unsigned int)p_sys
->i_data_offset_next
);
1202 * This function parses the INDX (movie index chunk).
1203 * It is optional but seeking without it is ... hard.
1205 static void HeaderINDX( demux_t
*p_demux
)
1207 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1210 uint32_t i_index_count
;
1212 if( p_sys
->i_index_offset
== 0 )
1215 if( vlc_stream_Seek( p_demux
->s
, p_sys
->i_index_offset
)
1216 || vlc_stream_Read( p_demux
->s
, buffer
, 20 ) < 20 )
1219 const uint32_t i_id
= VLC_FOURCC( buffer
[0], buffer
[1], buffer
[2], buffer
[3] );
1220 const uint32_t i_size
= GetDWBE( &buffer
[4] );
1221 int i_version
= GetWBE( &buffer
[8] );
1223 msg_Dbg( p_demux
, "Real index %4.4s size=%d version=%d",
1224 (char*)&i_id
, i_size
, i_version
);
1226 if( (i_size
< 20) && (i_id
!= VLC_FOURCC('I','N','D','X')) )
1229 i_index_count
= GetDWBE( &buffer
[10] );
1231 msg_Dbg( p_demux
, "Real Index : num : %d ", i_index_count
);
1233 if( i_index_count
>= ( 0xffffffff / sizeof(*p_sys
->p_index
) ) )
1236 if( GetDWBE( &buffer
[16] ) > 0 )
1237 msg_Dbg( p_demux
, "Real Index: Does next index exist? %d ",
1238 GetDWBE( &buffer
[16] ) );
1240 /* One extra entry is allocated (that MUST be set to 0) to identify the
1242 * TODO add a clean entry count (easier to build index on the fly) */
1243 p_sys
->p_index
= calloc( i_index_count
+ 1, sizeof(*p_sys
->p_index
) );
1244 if( !p_sys
->p_index
)
1247 for( unsigned int i
= 0; i
< i_index_count
; i
++ )
1249 uint8_t p_entry
[14];
1251 if( vlc_stream_Read( p_demux
->s
, p_entry
, 14 ) < 14 )
1254 if( GetWBE( &p_entry
[0] ) != 0 )
1256 msg_Dbg( p_demux
, "Real Index: invaild version of index entry %d ",
1257 GetWBE( &p_entry
[0] ) );
1261 real_index_t
*p_idx
= &p_sys
->p_index
[i
];
1263 p_idx
->i_time_offset
= GetDWBE( &p_entry
[2] );
1264 p_idx
->i_file_offset
= GetDWBE( &p_entry
[6] );
1265 p_idx
->i_frame_index
= GetDWBE( &p_entry
[10] );
1269 "Real Index: time %"PRIu32
" file %"PRIu32
" frame %"PRIu32
,
1270 p_idx
->i_time_offset
,
1271 p_idx
->i_file_offset
,
1272 p_idx
->i_frame_index
);
1279 * This function parses the complete RM headers and move the
1280 * stream pointer to the data to be read.
1282 static int HeaderRead( demux_t
*p_demux
)
1284 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1288 const int64_t i_stream_position
= vlc_stream_Tell( p_demux
->s
);
1289 uint8_t header
[100]; /* FIXME */
1291 /* Read the header */
1292 if( vlc_stream_Read( p_demux
->s
, header
, 10 ) < 10 )
1293 return VLC_EGENERIC
;
1295 const uint32_t i_id
= VLC_FOURCC( header
[0], header
[1],
1296 header
[2], header
[3] );
1297 const uint32_t i_size
= GetDWBE( &header
[4] );
1298 const int i_version
= GetWBE( &header
[8] );
1300 msg_Dbg( p_demux
, "object %4.4s size=%d version=%d",
1301 (char*)&i_id
, i_size
, i_version
);
1304 if( i_size
< 10 && i_id
!= VLC_FOURCC('D','A','T','A') )
1306 msg_Dbg( p_demux
, "invalid size for object %4.4s", (char*)&i_id
);
1307 return VLC_EGENERIC
;
1313 case VLC_FOURCC('.','R','M','F'):
1314 i_ret
= HeaderRMF( p_demux
);
1316 case VLC_FOURCC('P','R','O','P'):
1317 i_ret
= HeaderPROP( p_demux
);
1319 case VLC_FOURCC('C','O','N','T'):
1320 i_ret
= HeaderCONT( p_demux
);
1322 case VLC_FOURCC('M','D','P','R'):
1323 i_ret
= HeaderMDPR( p_demux
);
1325 case VLC_FOURCC('D','A','T','A'):
1326 i_ret
= HeaderDATA( p_demux
, i_size
);
1329 /* unknown header */
1330 msg_Dbg( p_demux
, "unknown chunk" );
1331 i_ret
= VLC_SUCCESS
;
1337 if( i_id
== VLC_FOURCC('D','A','T','A') ) /* In this case, parsing is finished */
1340 /* Skip unread data */
1341 const int64_t i_stream_current
= vlc_stream_Tell( p_demux
->s
);
1342 const int64_t i_stream_skip
= (i_stream_position
+ i_size
) - i_stream_current
;
1344 if( i_stream_skip
> 0 )
1346 if( vlc_stream_Read( p_demux
->s
, NULL
, i_stream_skip
) != i_stream_skip
)
1347 return VLC_EGENERIC
;
1349 else if( i_stream_skip
< 0 )
1351 return VLC_EGENERIC
;
1355 /* read index if possible */
1356 if( p_sys
->i_index_offset
> 0 )
1358 const int64_t i_position
= vlc_stream_Tell( p_demux
->s
);
1360 HeaderINDX( p_demux
);
1362 if( vlc_stream_Seek( p_demux
->s
, i_position
) )
1363 return VLC_EGENERIC
;
1368 static void CodecMetaRead( demux_t
*p_demux
, const uint8_t **pp_data
, int *pi_data
)
1370 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1373 p_sys
->psz_title
= MemoryReadString1( pp_data
, pi_data
);
1374 if( p_sys
->psz_title
)
1375 msg_Dbg( p_demux
, " - title=`%s'", p_sys
->psz_title
);
1378 p_sys
->psz_artist
= MemoryReadString1( pp_data
, pi_data
);
1379 if( p_sys
->psz_artist
)
1380 msg_Dbg( p_demux
, " - artist=`%s'", p_sys
->psz_artist
);
1383 p_sys
->psz_copyright
= MemoryReadString1( pp_data
, pi_data
);
1384 if( p_sys
->psz_copyright
)
1385 msg_Dbg( p_demux
, " - copyright=`%s'", p_sys
->psz_copyright
);
1388 p_sys
->psz_description
= MemoryReadString1( pp_data
, pi_data
);
1389 if( p_sys
->psz_description
)
1390 msg_Dbg( p_demux
, " - Comment=`%s'", p_sys
->psz_description
);
1393 static int CodecVideoParse( demux_t
*p_demux
, int i_tk_id
, const uint8_t *p_data
, int i_data
)
1395 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1398 return VLC_EGENERIC
;
1402 es_format_Init( &fmt
, VIDEO_ES
,
1403 VLC_FOURCC( p_data
[8], p_data
[9], p_data
[10], p_data
[11] ) );
1404 fmt
.video
.i_width
= GetWBE( &p_data
[12] );
1405 fmt
.video
.i_height
= GetWBE( &p_data
[14] );
1406 fmt
.video
.i_visible_width
= fmt
.video
.i_width
;
1407 fmt
.video
.i_visible_height
= fmt
.video
.i_height
;
1408 fmt
.video
.i_frame_rate
= (GetWBE( &p_data
[22] ) << 16) | GetWBE( &p_data
[24] );
1409 fmt
.video
.i_frame_rate_base
= 1 << 16;
1411 fmt
.i_extra
= i_data
- 26;
1412 fmt
.p_extra
= malloc( fmt
.i_extra
);
1416 memcpy( fmt
.p_extra
, &p_data
[26], fmt
.i_extra
);
1418 //msg_Dbg( p_demux, " - video 0x%08x 0x%08x", dw0, dw1 );
1421 switch( GetDWBE( &p_data
[30] ) )
1425 fmt
.i_codec
= VLC_CODEC_RV13
;
1431 fmt
.i_codec
= VLC_CODEC_RV20
;
1434 fmt
.i_codec
= VLC_CODEC_RV30
;
1437 fmt
.i_codec
= VLC_CODEC_RV40
;
1440 msg_Dbg( p_demux
, " - video %4.4s %dx%d - %8.8x",
1441 (char*)&fmt
.i_codec
, fmt
.video
.i_width
, fmt
.video
.i_height
, GetDWBE( &p_data
[30] ) );
1443 real_track_t
*tk
= malloc( sizeof( *tk
) );
1446 es_format_Clean( &fmt
);
1449 tk
->i_out_subpacket
= 0;
1450 tk
->i_subpacket
= 0;
1451 tk
->i_subpackets
= 0;
1452 tk
->p_subpackets
= NULL
;
1453 tk
->p_subpackets_timecode
= NULL
;
1456 tk
->i_frame_num
= -1;
1457 tk
->i_frame_size
= 0;
1460 tk
->p_sipr_packet
= NULL
;
1461 tk
->p_es
= es_out_Add( p_demux
->out
, &fmt
);
1463 TAB_APPEND( p_sys
->i_track
, p_sys
->track
, tk
);
1466 static int CodecAudioParse( demux_t
*p_demux
, int i_tk_id
, const uint8_t *p_data
, int i_data
)
1468 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1472 return VLC_EGENERIC
;
1475 int i_coded_frame_size
= 0;
1476 int i_subpacket_h
= 0;
1477 int i_frame_size
= 0;
1478 int i_subpacket_size
= 0;
1479 char p_genr
[4] = {0,0,0,0};
1480 int i_version
= GetWBE( &p_data
[4] );
1481 int i_extra_codec
= 0;
1483 msg_Dbg( p_demux
, " - audio version=%d", i_version
);
1485 es_format_Init( &fmt
, AUDIO_ES
, 0 );
1487 RVoid( &p_data
, &i_data
, 6 ); /* 4 + version */
1488 if( i_version
== 3 ) /* RMF version 3 or .ra version 3 */
1490 RVoid( &p_data
, &i_data
, 2 + 10 + 4 );
1493 CodecMetaRead( p_demux
, &p_data
, &i_data
);
1495 RVoid( &p_data
, &i_data
, 1 + 1 );
1497 memcpy( &fmt
.i_codec
, p_data
, 4 );
1498 RVoid( &p_data
, &i_data
, 4 );
1500 fmt
.audio
.i_channels
= 1; /* This is always the case in rm3 */
1501 fmt
.audio
.i_rate
= 8000;
1503 msg_Dbg( p_demux
, " - audio codec=%4.4s channels=%d rate=%dHz",
1504 (char*)&fmt
.i_codec
, fmt
.audio
.i_channels
, fmt
.audio
.i_rate
);
1506 else /* RMF version 4/5 or .ra version 4 */
1508 RVoid( &p_data
, &i_data
, 2 + 4 + 4 + 2 + 4 );
1509 i_flavor
= R16( &p_data
, &i_data
);
1510 i_coded_frame_size
= R32( &p_data
, &i_data
);
1511 RVoid( &p_data
, &i_data
, 4 + 4 + 4 );
1512 i_subpacket_h
= R16( &p_data
, &i_data
);
1513 i_frame_size
= R16( &p_data
, &i_data
);
1514 i_subpacket_size
= R16( &p_data
, &i_data
);
1515 if( !i_frame_size
|| !i_coded_frame_size
)
1517 es_format_Clean( &fmt
);
1518 return VLC_EGENERIC
;
1521 RVoid( &p_data
, &i_data
, 2 + (i_version
== 5 ? 6 : 0 ) );
1523 fmt
.audio
.i_rate
= R16( &p_data
, &i_data
);
1524 RVoid( &p_data
, &i_data
, 2 );
1525 fmt
.audio
.i_bitspersample
= R16( &p_data
, &i_data
);
1526 fmt
.audio
.i_channels
= R16( &p_data
, &i_data
);
1527 fmt
.audio
.i_blockalign
= i_frame_size
;
1529 if( i_version
== 5 )
1533 memcpy( p_genr
, &p_data
[0], 4 );
1534 memcpy( &fmt
.i_codec
, &p_data
[4], 4 );
1536 RVoid( &p_data
, &i_data
, 8 );
1538 else /* version 4 */
1541 RVoid( &p_data
, &i_data
, 1 + *p_data
);
1542 if( i_data
>= 1 + 4 )
1543 memcpy( &fmt
.i_codec
, &p_data
[1], 4 );
1545 RVoid( &p_data
, &i_data
, 1 + *p_data
);
1548 msg_Dbg( p_demux
, " - audio codec=%4.4s channels=%d rate=%dHz",
1549 (char*)&fmt
.i_codec
, fmt
.audio
.i_channels
, fmt
.audio
.i_rate
);
1551 RVoid( &p_data
, &i_data
, 3 );
1553 if( p_sys
->b_real_audio
)
1555 CodecMetaRead( p_demux
, &p_data
, &i_data
);
1559 if( i_version
== 5 )
1560 RVoid( &p_data
, &i_data
, 1 );
1561 i_extra_codec
= R32( &p_data
, &i_data
);
1565 switch( fmt
.i_codec
)
1567 case VLC_FOURCC('l','p','c','J'):
1568 case VLC_FOURCC('1','4','_','4'):
1569 fmt
.i_codec
= VLC_CODEC_RA_144
;
1570 fmt
.audio
.i_blockalign
= 0x14 ;
1573 case VLC_FOURCC('2','8','_','8'):
1574 if( i_coded_frame_size
<= 0 )
1576 es_format_Clean( &fmt
);
1577 return VLC_EGENERIC
;
1579 fmt
.i_codec
= VLC_CODEC_RA_288
;
1580 fmt
.audio
.i_blockalign
= i_coded_frame_size
;
1583 case VLC_FOURCC( 'a','5','2',' ' ):
1584 case VLC_FOURCC( 'd','n','e','t' ):
1585 fmt
.i_codec
= VLC_CODEC_A52
;
1588 case VLC_FOURCC( 'r','a','a','c' ):
1589 case VLC_FOURCC( 'r','a','c','p' ):
1590 fmt
.i_codec
= VLC_CODEC_MP4A
;
1592 if( i_extra_codec
> 0 )
1595 RVoid( &p_data
, &i_data
, 1 );
1597 if( i_extra_codec
> 0 )
1599 fmt
.p_extra
= malloc( i_extra_codec
);
1600 if( !fmt
.p_extra
|| i_extra_codec
> i_data
)
1602 free( fmt
.p_extra
);
1606 fmt
.i_extra
= i_extra_codec
;
1607 memcpy( fmt
.p_extra
, p_data
, fmt
.i_extra
);
1611 case VLC_CODEC_SIPR
:
1612 fmt
.i_codec
= VLC_CODEC_SIPR
;
1615 msg_Dbg( p_demux
, " - unsupported sipr flavorc=%i", i_flavor
);
1616 es_format_Clean( &fmt
);
1617 return VLC_EGENERIC
;
1620 i_subpacket_size
= i_subpacket_size_sipr
[i_flavor
];
1621 // The libavcodec sipr decoder requires stream bitrate
1622 // to be set during initialization so that the correct mode
1624 fmt
.i_bitrate
= fmt
.audio
.i_rate
;
1625 msg_Dbg( p_demux
, " - sipr flavor=%i", i_flavor
);
1628 case VLC_CODEC_COOK
:
1629 case VLC_CODEC_ATRAC3
:
1630 if( i_subpacket_size
<= 0 || i_frame_size
/ i_subpacket_size
<= 0 )
1632 es_format_Clean( &fmt
);
1633 return VLC_EGENERIC
;
1635 if( !memcmp( p_genr
, "genr", 4 ) )
1636 fmt
.audio
.i_blockalign
= i_subpacket_size
;
1638 fmt
.audio
.i_blockalign
= i_coded_frame_size
;
1640 if( i_extra_codec
> 0 )
1642 fmt
.p_extra
= malloc( i_extra_codec
);
1643 if( !fmt
.p_extra
|| i_extra_codec
> i_data
)
1645 free( fmt
.p_extra
);
1649 fmt
.i_extra
= i_extra_codec
;
1650 memcpy( fmt
.p_extra
, p_data
, fmt
.i_extra
);
1655 case VLC_FOURCC('r','a','l','f'):
1657 msg_Dbg( p_demux
, " - unknown audio codec=%4.4s",
1658 (char*)&fmt
.i_codec
);
1659 es_format_Clean( &fmt
);
1660 return VLC_EGENERIC
;
1662 msg_Dbg( p_demux
, " - extra data=%d", fmt
.i_extra
);
1665 real_track_t
*tk
= malloc( sizeof( *tk
) );
1668 es_format_Clean( &fmt
);
1673 tk
->i_frame_size
= 0;
1676 tk
->i_subpacket_h
= i_subpacket_h
;
1677 tk
->i_subpacket_size
= i_subpacket_size
;
1678 tk
->i_coded_frame_size
= i_coded_frame_size
;
1679 tk
->i_frame_size
= i_frame_size
;
1681 tk
->i_out_subpacket
= 0;
1682 tk
->i_subpacket
= 0;
1683 tk
->i_subpackets
= 0;
1684 tk
->p_subpackets
= NULL
;
1685 tk
->p_subpackets_timecode
= NULL
;
1687 tk
->p_sipr_packet
= NULL
;
1688 tk
->i_sipr_subpacket_count
= 0;
1690 if( fmt
.i_codec
== VLC_CODEC_COOK
||
1691 fmt
.i_codec
== VLC_CODEC_ATRAC3
)
1694 i_subpacket_h
* i_frame_size
/ tk
->i_subpacket_size
;
1696 xcalloc( tk
->i_subpackets
, sizeof(block_t
*) );
1697 tk
->p_subpackets_timecode
=
1698 xcalloc( tk
->i_subpackets
, sizeof( int64_t ) );
1700 else if( fmt
.i_codec
== VLC_CODEC_RA_288
)
1703 i_subpacket_h
* i_frame_size
/ tk
->i_coded_frame_size
;
1705 xcalloc( tk
->i_subpackets
, sizeof(block_t
*) );
1706 tk
->p_subpackets_timecode
=
1707 xcalloc( tk
->i_subpackets
, sizeof( int64_t ) );
1710 /* Check if the calloc went correctly */
1711 if( tk
->i_subpacket
> 0 && ( !tk
->p_subpackets
|| !tk
->p_subpackets_timecode
) )
1713 free( tk
->p_subpackets_timecode
);
1714 free( tk
->p_subpackets
);
1716 msg_Err( p_demux
, "Can't alloc subpacket" );
1717 return VLC_EGENERIC
;
1721 tk
->p_es
= es_out_Add( p_demux
->out
, &fmt
);
1723 TAB_APPEND( p_sys
->i_track
, p_sys
->track
, tk
);
1729 static int CodecParse( demux_t
*p_demux
, int i_len
, int i_num
)
1731 const uint8_t *p_peek
;
1733 msg_Dbg( p_demux
, " - specific data len=%d", i_len
);
1734 if( vlc_stream_Peek( p_demux
->s
, &p_peek
, i_len
) < i_len
)
1735 return VLC_EGENERIC
;
1737 if( i_len
>= 8 && !memcmp( &p_peek
[4], "VIDO", 4 ) )
1739 return CodecVideoParse( p_demux
, i_num
, p_peek
, i_len
);
1741 else if( i_len
>= 4 && !memcmp( &p_peek
[0], ".ra\xfd", 4 ) )
1743 return CodecAudioParse( p_demux
, i_num
, p_peek
, i_len
);
1748 /*****************************************************************************
1749 * Helpers: memory buffer fct.
1750 *****************************************************************************/
1751 static void RVoid( const uint8_t **pp_data
, int *pi_data
, int i_size
)
1753 if( i_size
> *pi_data
)
1759 #define RX(name, type, size, code ) \
1760 static type name( const uint8_t **pp_data, int *pi_data ) { \
1761 if( *pi_data < (size) ) \
1764 RVoid( pp_data, pi_data, size ); \
1767 RX(R8
, uint8_t, 1, **pp_data
)
1768 RX(R16
, uint16_t, 2, GetWBE( *pp_data
) )
1769 RX(R32
, uint32_t, 4, GetDWBE( *pp_data
) )
1770 static int RLength( const uint8_t **pp_data
, int *pi_data
)
1772 const int v0
= R16( pp_data
, pi_data
) & 0x7FFF;
1775 return (v0
<< 16) | R16( pp_data
, pi_data
);