⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asf.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
        if( i_payload_data_length < 0 || i_skip + i_payload_data_length > i_packet_size_left )        {            break;        }#if 0         msg_Dbg( p_demux,                  "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( ( tk = p_sys->track[i_stream_number] ) == NULL )        {            msg_Warn( p_demux,                      "undeclared stream[Id 0x%x]", i_stream_number );            i_skip += i_payload_data_length;            continue;   // over payload        }        if( !tk->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( tk->p_frame && i_media_object_offset == 0 )            {                /* send complete packet to decoder */                block_t *p_gather = block_ChainGather( tk->p_frame );                es_out_Send( p_demux->out, tk->p_es, p_gather );                tk->p_frame = NULL;            }            i_read = i_sub_payload_data_length + i_skip;            if( ( p_frag = stream_Block( p_demux->s, i_read ) ) == NULL )            {                msg_Warn( p_demux, "cannot read data" );                return 0;            }            i_packet_size_left -= i_read;            p_frag->p_buffer += i_skip;            p_frag->i_buffer -= i_skip;            if( tk->p_frame == NULL )            {                tk->i_time =                    ( (mtime_t)i_pts + i_payload * (mtime_t)i_pts_delta );                p_frag->i_pts = tk->i_time;                if( tk->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( &tk->p_frame, p_frag );            i_skip = 0;            if( i_packet_size_left > 0 )            {                if( stream_Peek( p_demux->s, &p_peek, i_packet_size_left )                                                         < i_packet_size_left )                {                    msg_Warn( p_demux, "cannot peek, EOF ?" );                    return 0;                }            }        }    }    if( i_packet_size_left > 0 )    {        if( stream_Read( p_demux->s, NULL, i_packet_size_left )                                                         < i_packet_size_left )        {            msg_Warn( p_demux, "cannot skip data, EOF ?" );            return 0;        }    }    return 1;loop_error_recovery:    msg_Warn( p_demux, "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_demux, "unsupported packet header, fatal error" );        return -1;    }    stream_Read( p_demux->s, NULL, i_data_packet_min );    return 1;}/***************************************************************************** * *****************************************************************************/static int DemuxInit( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    vlc_bool_t  b_seekable;    int         i;    unsigned int    i_stream;    asf_object_content_description_t *p_cd;    /* init context */    p_sys->i_time   = -1;    p_sys->i_length = 0;    p_sys->i_bitrate = 0;    p_sys->p_root   = NULL;    p_sys->p_fp     = NULL;    p_sys->i_track  = 0;    for( i = 0; i < 128; i++ )    {        p_sys->track[i] = NULL;    }    p_sys->i_data_begin = -1;    p_sys->i_data_end   = -1;    p_sys->meta         = NULL;    /* Now load all object ( except raw data ) */    stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b_seekable );    if( (p_sys->p_root = ASF_ReadObjectRoot( p_demux->s, b_seekable )) == NULL )    {        msg_Warn( p_demux, "ASF plugin discarded (not a valid file)" );        return VLC_EGENERIC;    }    p_sys->p_fp = p_sys->p_root->p_fp;    if( p_sys->p_fp->i_min_data_packet_size != p_sys->p_fp->i_max_data_packet_size )    {        msg_Warn( p_demux, "ASF plugin discarded (invalid file_properties object)" );        goto error;    }    p_sys->i_track = ASF_CountObject( p_sys->p_root->p_hdr,                                      &asf_object_stream_properties_guid );    if( p_sys->i_track <= 0 )    {        msg_Warn( p_demux, "ASF plugin discarded (cannot find any stream!)" );        goto error;    }    msg_Dbg( p_demux, "found %d streams", p_sys->i_track );    for( i_stream = 0; i_stream < p_sys->i_track; i_stream ++ )    {        asf_track_t    *tk;        asf_object_stream_properties_t *p_sp;        vlc_bool_t b_access_selected;        p_sp = ASF_FindObject( p_sys->p_root->p_hdr,                               &asf_object_stream_properties_guid,                               i_stream );        tk = p_sys->track[p_sp->i_stream_number] = malloc( sizeof( asf_track_t ) );        memset( tk, 0, sizeof( asf_track_t ) );        tk->i_time = -1;        tk->p_sp = p_sp;        tk->p_es = NULL;        tk->p_frame = NULL;        /* Check (in case of mms) if this track is selected (ie will receive data) */        if( !stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_GET_PRIVATE_ID_STATE,                             p_sp->i_stream_number, &b_access_selected ) &&            !b_access_selected )        {            tk->i_cat = UNKNOWN_ES;            msg_Dbg( p_demux, "ignoring not selected stream(ID:%d) (by access)",                     p_sp->i_stream_number );            continue;        }        if( ASF_CmpGUID( &p_sp->i_stream_type, &asf_object_stream_type_audio ) &&            p_sp->i_type_specific_data_length >= sizeof( WAVEFORMATEX ) - 2 )        {            es_format_t fmt;            uint8_t *p_data = p_sp->p_type_specific_data;            int i_format;            es_format_Init( &fmt, AUDIO_ES, 0 );            i_format = GetWLE( &p_data[0] );            wf_tag_to_fourcc( i_format, &fmt.i_codec, NULL );            fmt.audio.i_channels        = GetWLE(  &p_data[2] );            fmt.audio.i_rate      = GetDWLE( &p_data[4] );            fmt.i_bitrate         = GetDWLE( &p_data[8] ) * 8;            fmt.audio.i_blockalign      = GetWLE(  &p_data[12] );            fmt.audio.i_bitspersample   = GetWLE(  &p_data[14] );            if( p_sp->i_type_specific_data_length > sizeof( WAVEFORMATEX ) &&                i_format != WAVE_FORMAT_MPEGLAYER3 &&                i_format != WAVE_FORMAT_MPEG )            {                fmt.i_extra = __MIN( GetWLE( &p_data[16] ),                                     p_sp->i_type_specific_data_length -                                     sizeof( WAVEFORMATEX ) );                fmt.p_extra = malloc( fmt.i_extra );                memcpy( fmt.p_extra, &p_data[sizeof( WAVEFORMATEX )],                        fmt.i_extra );            }            tk->i_cat = AUDIO_ES;            tk->p_es = es_out_Add( p_demux->out, &fmt );            es_format_Clean( &fmt );            msg_Dbg( p_demux, "added new audio stream(codec:0x%x,ID:%d)",                    GetWLE( p_data ), p_sp->i_stream_number );        }        else if( ASF_CmpGUID( &p_sp->i_stream_type,                              &asf_object_stream_type_video ) &&                 p_sp->i_type_specific_data_length >= 11 +                 sizeof( BITMAPINFOHEADER ) )        {            es_format_t  fmt;            uint8_t      *p_data = &p_sp->p_type_specific_data[11];            es_format_Init( &fmt, VIDEO_ES,                            VLC_FOURCC( p_data[16], p_data[17],                                        p_data[18], p_data[19] ) );            fmt.video.i_width = GetDWLE( p_data + 4 );            fmt.video.i_height= GetDWLE( p_data + 8 );            if( p_sp->i_type_specific_data_length > 11 +                sizeof( BITMAPINFOHEADER ) )            {                fmt.i_extra = __MIN( GetDWLE( p_data ),                                     p_sp->i_type_specific_data_length - 11 -                                     sizeof( BITMAPINFOHEADER ) );                fmt.p_extra = malloc( fmt.i_extra );                memcpy( fmt.p_extra, &p_data[sizeof( BITMAPINFOHEADER )],                        fmt.i_extra );            }            /* Look for an aspect ratio */            if( p_sys->p_root->p_metadata )            {                asf_object_metadata_t *p_meta = p_sys->p_root->p_metadata;                int i, i_aspect_x = 0, i_aspect_y = 0;                for( i = 0; i < p_meta->i_record_entries_count; i++ )                {                    if( !strcmp( p_meta->record[i].psz_name, "AspectRatioX" ) )                    {                        if( (!i_aspect_x && !p_meta->record[i].i_stream) ||                            p_meta->record[i].i_stream ==                            p_sp->i_stream_number )                            i_aspect_x = p_meta->record[i].i_val;                    }                    if( !strcmp( p_meta->record[i].psz_name, "AspectRatioY" ) )                    {                        if( (!i_aspect_y && !p_meta->record[i].i_stream) ||                            p_meta->record[i].i_stream ==                            p_sp->i_stream_number )                            i_aspect_y = p_meta->record[i].i_val;                    }                }                if( i_aspect_x && i_aspect_y )                {                    fmt.video.i_aspect = i_aspect_x *                        (int64_t)fmt.video.i_width * VOUT_ASPECT_FACTOR /                        fmt.video.i_height / i_aspect_y;                }	    }            tk->i_cat = VIDEO_ES;            tk->p_es = es_out_Add( p_demux->out, &fmt );            es_format_Clean( &fmt );            msg_Dbg( p_demux, "added new video stream(ID:%d)",                     p_sp->i_stream_number );        }        else        {            tk->i_cat = UNKNOWN_ES;            msg_Dbg( p_demux, "ignoring unknown stream(ID:%d)",                     p_sp->i_stream_number );        }    }    p_sys->i_data_begin = p_sys->p_root->p_data->i_object_pos + 50;    if( p_sys->p_root->p_data->i_object_size != 0 )    { /* local file */        p_sys->i_data_end = p_sys->p_root->p_data->i_object_pos +                                    p_sys->p_root->p_data->i_object_size;    }    else    { /* live/broacast */        p_sys->i_data_end = -1;    }    /* go to first packet */    stream_Seek( p_demux->s, p_sys->i_data_begin );    /* try to calculate movie time */    if( p_sys->p_fp->i_data_packets_count > 0 )    {        int64_t i_count;        int64_t i_size = stream_Size( p_demux->s );        if( p_sys->i_data_end > 0 && i_size > p_sys->i_data_end )        {            i_size = p_sys->i_data_end;        }        /* real number of packets */        i_count = ( i_size - p_sys->i_data_begin ) /                  p_sys->p_fp->i_min_data_packet_size;        /* calculate the time duration in micro-s */        p_sys->i_length = (mtime_t)p_sys->p_fp->i_play_duration / 10 *                   (mtime_t)i_count /                   (mtime_t)p_sys->p_fp->i_data_packets_count;        if( p_sys->i_length > 0 )        {            p_sys->i_bitrate = 8 * i_size * (int64_t)1000000 / p_sys->i_length;        }    }    /* Create meta information */    p_sys->meta = vlc_meta_New();    if( ( p_cd = ASF_FindObject( p_sys->p_root->p_hdr,                                 &asf_object_content_description_guid, 0 ) ) )    {        if( p_cd->psz_title && *p_cd->psz_title )        {            vlc_meta_Add( p_sys->meta, VLC_META_TITLE, p_cd->psz_title );        }        if( p_cd->psz_author && *p_cd->psz_author )        {             vlc_meta_Add( p_sys->meta, VLC_META_AUTHOR, p_cd->psz_author );        }        if( p_cd->psz_copyright && *p_cd->psz_copyright )        {            vlc_meta_Add( p_sys->meta, VLC_META_COPYRIGHT, p_cd->psz_copyright );        }        if( p_cd->psz_description && *p_cd->psz_description )        {            vlc_meta_Add( p_sys->meta, VLC_META_DESCRIPTION, p_cd->psz_description );        }        if( p_cd->psz_rating && *p_cd->psz_rating )        {            vlc_meta_Add( p_sys->meta, VLC_META_RATING, p_cd->psz_rating );        }    }    for( i_stream = 0, i = 0; i < 128; i++ )    {        asf_object_codec_list_t *p_cl = ASF_FindObject( p_sys->p_root->p_hdr,                                                        &asf_object_codec_list_guid, 0 );        if( p_sys->track[i] )        {            vlc_meta_t *tk = vlc_meta_New();            TAB_APPEND( p_sys->meta->i_track, p_sys->meta->track, tk );            if( p_cl && i_stream < p_cl->i_codec_entries_count )            {                if( p_cl->codec[i_stream].psz_name &&                    *p_cl->codec[i_stream].psz_name )                {                    vlc_meta_Add( tk, VLC_META_CODEC_NAME,                                  p_cl->codec[i_stream].psz_name );                }                if( p_cl->codec[i_stream].psz_description &&                    *p_cl->codec[i_stream].psz_description )                {                    vlc_meta_Add( tk, VLC_META_CODEC_DESCRIPTION,                                  p_cl->codec[i_stream].psz_description );                }            }            i_stream++;        }    }    es_out_Control( p_demux->out, ES_OUT_RESET_PCR );    return VLC_SUCCESS;error:    ASF_FreeObjectRoot( p_demux->s, p_sys->p_root );    return VLC_EGENERIC;}/***************************************************************************** * *****************************************************************************/static void DemuxEnd( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    int         i;    if( p_sys->p_root )    {        ASF_FreeObjectRoot( p_demux->s, p_sys->p_root );        p_sys->p_root = NULL;    }    if( p_sys->meta )    {        vlc_meta_Delete( p_sys->meta );        p_sys->meta = NULL;    }    for( i = 0; i < 128; i++ )    {        asf_track_t *tk = p_sys->track[i];        if( tk )        {            if( tk->p_frame )            {                block_ChainRelease( tk->p_frame );            }            if( tk->p_es )            {                es_out_Del( p_demux->out, tk->p_es );            }            free( tk );        }        p_sys->track[i] = 0;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -