asf.c
来自「VLC媒体播放程序」· C语言 代码 · 共 830 行 · 第 1/2 页
C
830 行
i_time_begin = GetMoviePTS( p_sys ); } else { i_length = GetMoviePTS( p_sys ) - i_time_begin; if( i_length < 0 || i_length >= 40 * 1000 ) { break; } } } p_sys->i_time = GetMoviePTS( p_sys ); if( p_sys->i_time >= 0 ) { input_ClockManageRef( p_input, p_input->stream.p_selected_program, p_sys->i_time * 9 / 100 ); } return( 1 );}/***************************************************************************** * Close: frees unused data *****************************************************************************/static void Close( vlc_object_t * p_this ){ input_thread_t *p_input = (input_thread_t *)p_this; demux_sys_t *p_sys = p_input->p_demux_data; int i_stream; msg_Dbg( p_input, "freeing all memory" ); vlc_meta_Delete( p_sys->meta ); ASF_FreeObjectRoot( p_input->s, p_sys->p_root ); for( i_stream = 0; i_stream < 128; i_stream++ ) { asf_stream_t *p_stream = p_sys->stream[i_stream]; if( p_stream ) { if( p_stream->p_frame ) { block_ChainRelease( p_stream->p_frame ); } free( p_stream ); } } free( p_sys );}/***************************************************************************** * Control: *****************************************************************************/static int Control( input_thread_t *p_input, int i_query, va_list args ){ demux_sys_t *p_sys = p_input->p_demux_data; int64_t *pi64; vlc_meta_t **pp_meta; switch( i_query ) { case DEMUX_GET_LENGTH: pi64 = (int64_t*)va_arg( args, int64_t * ); *pi64 = p_sys->i_length; return VLC_SUCCESS; case DEMUX_GET_META: pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** ); *pp_meta = vlc_meta_Duplicate( p_sys->meta ); return VLC_SUCCESS; default: return demux_vaControlDefault( p_input, i_query, args ); }}/***************************************************************************** * *****************************************************************************/static mtime_t GetMoviePTS( demux_sys_t *p_sys ){ mtime_t i_time; int i_stream; i_time = -1; for( i_stream = 0; i_stream < 128 ; i_stream++ ) { asf_stream_t *p_stream = p_sys->stream[i_stream]; if( p_stream && p_stream->p_es && p_stream->i_time > 0) { if( i_time < 0 ) { i_time = p_stream->i_time; } else { i_time = __MIN( i_time, p_stream->i_time ); } } } return( i_time );}#define GETVALUE2b( bits, var, def ) \ switch( (bits)&0x03 ) \ { \ case 1: var = p_peek[i_skip]; i_skip++; break; \ case 2: var = GetWLE( p_peek + i_skip ); i_skip+= 2; break; \ case 3: var = GetDWLE( p_peek + i_skip ); i_skip+= 4; break; \ case 0: \ default: var = def; break;\ }static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ){ demux_sys_t *p_sys = p_input->p_demux_data; int i_data_packet_min = p_sys->p_fp->i_min_data_packet_size; uint8_t *p_peek; int i_skip; int i_packet_size_left; int i_packet_flags; int i_packet_property; int b_packet_multiple_payload; int i_packet_length; int i_packet_sequence; int i_packet_padding_length; uint32_t i_packet_send_time; uint16_t i_packet_duration; int i_payload; int i_payload_count; int i_payload_length_type; if( stream_Peek( p_input->s, &p_peek,i_data_packet_min)<i_data_packet_min ) { // EOF ? msg_Warn( p_input, "cannot peek while getting new packet, EOF ?" ); return( 0 ); } i_skip = 0; /* *** parse error correction if present *** */ if( p_peek[0]&0x80 ) { unsigned int i_error_correction_length_type; unsigned int i_error_correction_data_length; unsigned int i_opaque_data_present; i_error_correction_data_length = p_peek[0] & 0x0f; // 4bits i_opaque_data_present = ( p_peek[0] >> 4 )& 0x01; // 1bit i_error_correction_length_type = ( p_peek[0] >> 5 ) & 0x03; // 2bits i_skip += 1; // skip error correction flags if( i_error_correction_length_type != 0x00 || i_opaque_data_present != 0 || i_error_correction_data_length != 0x02 ) { goto loop_error_recovery; } i_skip += i_error_correction_data_length; } else { msg_Warn( p_input, "p_peek[0]&0x80 != 0x80" ); } /* sanity check */ if( i_skip + 2 >= i_data_packet_min ) { goto loop_error_recovery; } i_packet_flags = p_peek[i_skip]; i_skip++; i_packet_property = p_peek[i_skip]; i_skip++; b_packet_multiple_payload = i_packet_flags&0x01; /* read some value */ GETVALUE2b( i_packet_flags >> 5, i_packet_length, i_data_packet_min ); GETVALUE2b( i_packet_flags >> 1, i_packet_sequence, 0 ); GETVALUE2b( i_packet_flags >> 3, i_packet_padding_length, 0 ); i_packet_send_time = GetDWLE( p_peek + i_skip ); i_skip += 4; i_packet_duration = GetWLE( p_peek + i_skip ); i_skip += 2;// i_packet_size_left = i_packet_length; // XXX donn閑s reellement lu /* FIXME I have to do that for some file, I don't known why */ i_packet_size_left = i_data_packet_min; if( b_packet_multiple_payload ) { i_payload_count = p_peek[i_skip] & 0x3f; i_payload_length_type = ( p_peek[i_skip] >> 6 )&0x03; i_skip++; } else { i_payload_count = 1; i_payload_length_type = 0x02; // unused } for( i_payload = 0; i_payload < i_payload_count ; i_payload++ ) { asf_stream_t *p_stream; int i_stream_number; int i_media_object_number; int i_media_object_offset; int i_replicated_data_length; int i_payload_data_length; int i_payload_data_pos; int i_sub_payload_data_length; int i_tmp; mtime_t i_pts; mtime_t i_pts_delta; if( i_skip >= i_packet_size_left ) { /* prevent some segfault with invalid file */ break; } i_stream_number = p_peek[i_skip] & 0x7f; i_skip++; GETVALUE2b( i_packet_property >> 4, i_media_object_number, 0 ); GETVALUE2b( i_packet_property >> 2, i_tmp, 0 ); GETVALUE2b( i_packet_property, i_replicated_data_length, 0 ); if( i_replicated_data_length > 1 ) // should be at least 8 bytes { i_pts = (mtime_t)GetDWLE( p_peek + i_skip + 4 ) * 1000; i_skip += i_replicated_data_length; i_pts_delta = 0; i_media_object_offset = i_tmp; if( i_skip >= i_packet_size_left ) { break; } } else if( i_replicated_data_length == 1 ) { msg_Dbg( p_input, "found compressed payload" ); i_pts = (mtime_t)i_tmp * 1000; i_pts_delta = (mtime_t)p_peek[i_skip] * 1000; i_skip++; i_media_object_offset = 0; } else { i_pts = (mtime_t)i_packet_send_time * 1000; i_pts_delta = 0; i_media_object_offset = i_tmp; } i_pts = __MAX( i_pts - p_sys->p_fp->i_preroll * 1000, 0 ); if( b_packet_multiple_payload ) { GETVALUE2b( i_payload_length_type, i_payload_data_length, 0 ); } else { i_payload_data_length = i_packet_length - i_packet_padding_length - i_skip; } if( i_payload_data_length < 0 || i_skip + i_payload_data_length > i_packet_size_left ) { break; }#if 0 msg_Dbg( p_input, "payload(%d/%d) stream_number:%d media_object_number:%d media_object_offset:%d replicated_data_length:%d payload_data_length %d", i_payload + 1, i_payload_count, i_stream_number, i_media_object_number, i_media_object_offset, i_replicated_data_length, i_payload_data_length );#endif if( !( p_stream = p_sys->stream[i_stream_number] ) ) { msg_Warn( p_input, "undeclared stream[Id 0x%x]", i_stream_number ); i_skip += i_payload_data_length; continue; // over payload } if( !p_stream->p_es ) { i_skip += i_payload_data_length; continue; } for( i_payload_data_pos = 0; i_payload_data_pos < i_payload_data_length && i_packet_size_left > 0; i_payload_data_pos += i_sub_payload_data_length ) { block_t *p_frag; int i_read; // read sub payload length if( i_replicated_data_length == 1 ) { i_sub_payload_data_length = p_peek[i_skip]; i_skip++; i_payload_data_pos++; } else { i_sub_payload_data_length = i_payload_data_length; } /* FIXME I don't use i_media_object_number, sould I ? */ if( p_stream->p_frame && i_media_object_offset == 0 ) { /* send complete packet to decoder */ block_t *p_gather = block_ChainGather( p_stream->p_frame ); es_out_Send( p_input->p_es_out, p_stream->p_es, p_gather ); p_stream->p_frame = NULL; } i_read = i_sub_payload_data_length + i_skip; if( ( p_frag = stream_Block( p_input->s, i_read ) ) == NULL ) { msg_Warn( p_input, "cannot read data" ); return( 0 ); } i_packet_size_left -= i_read; p_frag->p_buffer += i_skip; p_frag->i_buffer -= i_skip; if( p_stream->p_frame == NULL ) { p_stream->i_time = ( (mtime_t)i_pts + i_payload * (mtime_t)i_pts_delta ); p_frag->i_pts = input_ClockGetTS( p_input, p_input->stream.p_selected_program, p_stream->i_time * 9 /100 ); if( p_stream->i_cat != VIDEO_ES ) p_frag->i_dts = p_frag->i_pts; else { p_frag->i_dts = p_frag->i_pts; p_frag->i_pts = 0; } } block_ChainAppend( &p_stream->p_frame, p_frag ); i_skip = 0; if( i_packet_size_left > 0 ) { if( stream_Peek( p_input->s, &p_peek, i_packet_size_left ) < i_packet_size_left ) { // EOF ? msg_Warn( p_input, "cannot peek, EOF ?" ); return( 0 ); } } } } if( i_packet_size_left > 0 ) { if( stream_Read( p_input->s, NULL, i_packet_size_left ) < i_packet_size_left ) { msg_Warn( p_input, "cannot skip data, EOF ?" ); return( 0 ); } } return( 1 );loop_error_recovery: msg_Warn( p_input, "unsupported packet header" ); if( p_sys->p_fp->i_min_data_packet_size != p_sys->p_fp->i_max_data_packet_size ) { msg_Err( p_input, "unsupported packet header, fatal error" ); return( -1 ); } stream_Read( p_input->s, NULL, i_data_packet_min ); return( 1 );}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?