?? real.c
字號:
{ stream_Read( p_demux->s, header, 8 ); p_sys->i_data_offset = stream_Tell( p_demux->s ) - 10; p_sys->i_data_size = i_size; p_sys->i_data_packets_count = GetDWBE( header ); p_sys->i_data_packets = 0; p_sys->i_data_offset_next = GetDWBE( &header[4] ); msg_Dbg( p_demux, " - packets count=%d next=%u", p_sys->i_data_packets_count, (uint32_t)p_sys->i_data_offset_next ); /* we have finished the header */ break; } else { /* unknow header */ msg_Dbg( p_demux, "unknown chunk" ); } if( i_skip < 0 ) return VLC_EGENERIC; stream_Read( p_demux->s, NULL, i_skip ); } /* TODO read index if possible */ if ( p_sys->i_index_offset > 0 ) { int64_t pos; pos = stream_Tell( p_demux->s ); ReadRealIndex( p_demux ); stream_Seek( p_demux->s, pos ); } return VLC_SUCCESS;}static const uint8_t * MetaRead( demux_t *p_demux, const uint8_t *p_peek ){ demux_sys_t *p_sys = p_demux->p_sys; int i_len; char *psz; /* Title */ i_len = *p_peek ; p_peek++; if( i_len > 0 ) { psz = malloc( i_len + 1 ); memcpy( psz, p_peek, i_len ); psz[i_len] = '\0'; EnsureUTF8( psz ); msg_Dbg( p_demux, " - title=`%s'", psz ); p_sys->psz_title = psz; } p_peek += i_len; /* Authors */ i_len = *p_peek ; p_peek++; if( i_len > 0 ) { psz = malloc( i_len + 1 ); memcpy( psz, p_peek, i_len ); psz[i_len] = '\0'; EnsureUTF8( psz ); msg_Dbg( p_demux, " - artist=`%s'", psz ); p_sys->psz_artist = psz; } p_peek += i_len; /* Copyright */ i_len = *p_peek ; p_peek++; if( i_len > 0 ) { psz = malloc( i_len + 1 ); memcpy( psz, p_peek, i_len ); psz[i_len] = '\0'; EnsureUTF8( psz ); msg_Dbg( p_demux, " - Copyright=`%s'", psz ); p_sys->psz_copyright = psz; } p_peek += i_len; /* Comment */ i_len = *p_peek ; p_peek++; if( i_len > 0 ) { psz = malloc( i_len + 1 ); memcpy( psz, p_peek, i_len ); psz[i_len] = '\0'; EnsureUTF8( psz ); msg_Dbg( p_demux, " - Comment=`%s'", psz ); p_sys->psz_description = psz; } p_peek += i_len; return p_peek;}static int ReadCodecSpecificData( demux_t *p_demux, int i_len, int i_num ){ demux_sys_t *p_sys = p_demux->p_sys; es_format_t fmt; real_track_t *tk; const uint8_t *p_peek; msg_Dbg( p_demux, " - specific data len=%d", i_len ); if( stream_Peek(p_demux->s, &p_peek, i_len) < i_len ) return VLC_EGENERIC; if( ( i_len >= 8 ) && !memcmp( &p_peek[4], "VIDO", 4 ) ) { es_format_Init( &fmt, VIDEO_ES, VLC_FOURCC( p_peek[8], p_peek[9], p_peek[10], p_peek[11] ) ); fmt.video.i_width = GetWBE( &p_peek[12] ); fmt.video.i_height= GetWBE( &p_peek[14] ); fmt.i_extra = 8; fmt.p_extra = malloc( 8 ); ((uint32_t*)fmt.p_extra)[0] = GetDWBE( &p_peek[26] ); ((uint32_t*)fmt.p_extra)[1] = GetDWBE( &p_peek[30] ); msg_Dbg( p_demux, " - video 0x%08x 0x%08x", ((uint32_t*)fmt.p_extra)[0], ((uint32_t*)fmt.p_extra)[1] ); if( GetDWBE( &p_peek[30] ) == 0x10003000 || GetDWBE( &p_peek[30] ) == 0x10003001 ) { fmt.i_codec = VLC_FOURCC( 'R','V','1','3' ); } else if( GetDWBE( &p_peek[30] ) == 0x20001000 || GetDWBE( &p_peek[30] ) == 0x20100001 || GetDWBE( &p_peek[30] ) == 0x20200002 ) { fmt.i_codec = VLC_FOURCC( 'R','V','2','0' ); } else if( GetDWBE( &p_peek[30] ) == 0x30202002 ) { fmt.i_codec = VLC_FOURCC( 'R','V','3','0' ); } else if( GetDWBE( &p_peek[30] ) == 0x40000000 ) { fmt.i_codec = VLC_FOURCC( 'R','V','4','0' ); } msg_Dbg( p_demux, " - video %4.4s %dx%d", (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height ); tk = malloc( sizeof( real_track_t ) ); tk->i_out_subpacket = 0; tk->i_subpacket = 0; tk->i_subpackets = 0; tk->p_subpackets = NULL; tk->p_subpackets_timecode = NULL; tk->i_id = i_num; tk->fmt = fmt; tk->i_frame = 0; tk->p_frame = NULL; tk->p_es = es_out_Add( p_demux->out, &fmt ); TAB_APPEND( p_sys->i_track, p_sys->track, tk ); } else if( !strncmp( (char *)p_peek, ".ra\xfd", 4 ) ) { int i_header_size = 0; int i_flavor = 0; int i_coded_frame_size = 0; int i_subpacket_h = 0; int i_frame_size = 0; int i_subpacket_size = 0; char p_genr[4]; int i_version = GetWBE( &p_peek[4] ); /* [0..3] = '.','r','a',0xfd */ msg_Dbg( p_demux, " - audio version=%d", i_version ); p_peek += 6; /* 4 + version */ es_format_Init( &fmt, AUDIO_ES, 0 ); if( i_version == 3 ) /* RMF version 3 or .ra version 3 */ { i_header_size = GetWBE( p_peek ); p_peek += 2; /* Size from now */ p_peek += 10; /* Unknown */ msg_Dbg( p_demux, "Data Size: %i", GetDWBE( p_peek ) ); p_peek += 4; /* Data Size */ /* Meta Datas */ p_peek = MetaRead( p_demux, p_peek ); p_peek ++; /* Unknown */ p_peek ++; /* FourCC length = 4 */ memcpy( (char *)&fmt.i_codec, p_peek, 4 ); p_peek += 4; /* FourCC*/ fmt.audio.i_channels = 1; /* This is always the case in rm3 */ fmt.audio.i_rate = 8000; msg_Dbg( p_demux, " - audio codec=%4.4s channels=%d rate=%dHz", (char*)&fmt.i_codec, fmt.audio.i_channels, fmt.audio.i_rate ); } else /* RMF version 4/5 or .ra version 4 */ { p_peek += 2; /* 00 00 */ p_peek += 4; /* .ra4 or .ra5 */ p_peek += 4; /* data size */ p_peek += 2; /* version (4 or 5) */ i_header_size = GetDWBE( p_peek ); p_peek += 4; /* header size */ i_flavor = GetWBE( p_peek ); p_peek += 2; /* codec flavor */ i_coded_frame_size = GetDWBE( p_peek ); p_peek += 4; /* coded frame size*/ p_peek += 4; /* ?? */ p_peek += 4; /* ?? */ p_peek += 4; /* ?? */ i_subpacket_h = GetWBE( p_peek ); p_peek += 2; /* 1 */ i_frame_size = GetWBE( p_peek ); p_peek += 2; /* frame size */ i_subpacket_size = GetWBE( p_peek ); p_peek += 2; /* subpacket_size */ if( (!i_subpacket_size && !p_sys->b_is_real_audio ) || !i_frame_size || !i_coded_frame_size ) return VLC_EGENERIC; p_peek += 2; /* ?? */ if( i_version == 5 ) p_peek += 6; /* 0, srate, 0 */ fmt.audio.i_rate = GetWBE( p_peek ); p_peek += 2; /* Sample Rate */ p_peek += 2; /* ?? */ fmt.audio.i_bitspersample = GetWBE( p_peek ); p_peek += 2;/* Sure?*/ fmt.audio.i_channels = GetWBE( p_peek ); p_peek += 2; /* Channels */ fmt.audio.i_blockalign = i_frame_size; if( i_version == 5 ) { memcpy( (char *)p_genr, p_peek, 4 ); p_peek += 4; /* genr */ memcpy( (char *)&fmt.i_codec, p_peek, 4 ); p_peek += 4; } else /* version 4 */ { p_peek += 1 + p_peek[0]; /* Inteleaver ID string and lenth */ memcpy( (char *)&fmt.i_codec, p_peek + 1, 4 ); /* FourCC */ p_peek += 1 + p_peek[0]; } msg_Dbg( p_demux, " - audio codec=%4.4s channels=%d rate=%dHz", (char*)&fmt.i_codec, fmt.audio.i_channels, fmt.audio.i_rate ); p_peek += 3; /* ?? */ if( p_sys->b_is_real_audio ) { p_peek = MetaRead( p_demux, p_peek ); } else { if( i_version == 5 ) p_peek++; /* Extra Data then: DWord + byte[] */ fmt.i_extra = GetDWBE( p_peek ); p_peek += 4; } } switch( fmt.i_codec ) { case VLC_FOURCC('l','p','c','J'): fmt.i_codec = VLC_FOURCC( '1','4','_','4' ); case VLC_FOURCC('1','4','_','4'): fmt.audio.i_blockalign = 0x14 ; break; case VLC_FOURCC('2','8','_','8'): fmt.i_extra = 0; fmt.audio.i_blockalign = i_coded_frame_size; break; case VLC_FOURCC( 'd','n','e','t' ): fmt.i_codec = VLC_FOURCC( 'a','5','2',' ' ); break; case VLC_FOURCC( 'r','a','a','c' ): case VLC_FOURCC( 'r','a','c','p' ): fmt.i_codec = VLC_FOURCC( 'm','p','4','a' ); if( fmt.i_extra > 0 ) { fmt.i_extra--; p_peek++; } if( fmt.i_extra > 0 ) { fmt.p_extra = malloc( fmt.i_extra ); if( fmt.p_extra == NULL ) { msg_Err( p_demux, "Error in the extra data" ); return VLC_EGENERIC; } memcpy( fmt.p_extra, p_peek, fmt.i_extra ); } break; case VLC_FOURCC('s','i','p','r'): fmt.audio.i_flavor = i_flavor; case VLC_FOURCC('c','o','o','k'): case VLC_FOURCC('a','t','r','c'): if( !memcmp( p_genr, "genr", 4 ) ) fmt.audio.i_blockalign = i_subpacket_size; else fmt.audio.i_blockalign = i_coded_frame_size; if( fmt.i_extra > 0 ) { fmt.p_extra = malloc( fmt.i_extra ); if( fmt.p_extra == NULL ) { msg_Err( p_demux, "Error in the extra data" ); return VLC_EGENERIC; } memcpy( fmt.p_extra, p_peek, fmt.i_extra ); } break; case VLC_FOURCC('r','a','l','f'): msg_Dbg( p_demux, " - audio codec not supported=%4.4s", (char*)&fmt.i_codec ); break; default: msg_Dbg( p_demux, " - unknown audio codec=%4.4s", (char*)&fmt.i_codec ); break; } if( fmt.i_codec != 0 ) { msg_Dbg( p_demux, " - extra data=%d", fmt.i_extra ); tk = malloc( sizeof( real_track_t ) ); tk->i_id = i_num; tk->fmt = fmt; tk->i_frame = 0; tk->p_frame = NULL; tk->i_subpacket_h = i_subpacket_h; tk->i_subpacket_size = i_subpacket_size; tk->i_coded_frame_size = i_coded_frame_size; tk->i_frame_size = i_frame_size; tk->i_out_subpacket = 0; tk->i_subpacket = 0; tk->i_subpackets = 0; tk->p_subpackets = NULL; tk->p_subpackets_timecode = NULL; if( fmt.i_codec == VLC_FOURCC('c','o','o','k') || fmt.i_codec == VLC_FOURCC('a','t','r','c') ) { tk->i_subpackets = i_subpacket_h * i_frame_size / tk->i_subpacket_size; tk->p_subpackets = calloc( tk->i_subpackets, sizeof(block_t *) ); tk->p_subpackets_timecode = calloc( tk->i_subpackets , sizeof( int64_t ) ); } else if( fmt.i_codec == VLC_FOURCC('2','8','_','8') ) { tk->i_subpackets = i_subpacket_h * i_frame_size / tk->i_coded_frame_size; tk->p_subpackets = calloc( tk->i_subpackets, sizeof(block_t *) ); tk->p_subpackets_timecode = calloc( tk->i_subpackets , sizeof( int64_t ) ); } /* Check if the calloc went correctly */ if( tk->p_subpackets == NULL ) { tk->i_subpackets = 0; msg_Err( p_demux, "Can't alloc subpacket" ); return VLC_EGENERIC; } tk->p_es = es_out_Add( p_demux->out, &fmt ); TAB_APPEND( p_sys->i_track, p_sys->track, tk ); } } return VLC_SUCCESS;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -