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

📄 mkv.cpp

📁 video linux conference
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        if ( ep == NULL )            return VLC_EGENERIC;        el = ep->Get();        i_level = ep->GetLevel();        if( el == NULL && pp_block != NULL )        {            /* update the index */#define idx p_indexes[i_index - 1]            if( i_index > 0 && idx.i_time == -1 )            {                idx.i_time        = (*pp_block).GlobalTimecode() / (mtime_t)1000;                idx.b_key         = *pi_ref1 == -1 ? VLC_TRUE : VLC_FALSE;            }#undef idx            return VLC_SUCCESS;        }        if( el == NULL )        {            if( ep->GetLevel() > 1 )            {                ep->Up();                continue;            }            msg_Warn( &sys.demuxer, "EOF" );            return VLC_EGENERIC;        }        /* do parsing */        switch ( i_level )        {        case 1:            if( MKV_IS_ID( el, KaxCluster ) )            {                cluster = (KaxCluster*)el;                i_cluster_pos = cluster->GetElementPosition();                /* add it to the index */                if( i_index == 0 ||                    ( i_index > 0 && p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )                {                    IndexAppendCluster( cluster );                }                // reset silent tracks                for (size_t i=0; i<tracks.size(); i++)                {                    tracks[i]->b_silent = VLC_FALSE;                }                ep->Down();            }            else if( MKV_IS_ID( el, KaxCues ) )            {                msg_Warn( &sys.demuxer, "find KaxCues FIXME" );                return VLC_EGENERIC;            }            else            {                msg_Dbg( &sys.demuxer, "unknown (%s)", typeid( el ).name() );            }            break;        case 2:            if( MKV_IS_ID( el, KaxClusterTimecode ) )            {                KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;                ctc.ReadData( es.I_O(), SCOPE_ALL_DATA );                cluster->InitTimecode( uint64( ctc ), i_timescale );            }            else if( MKV_IS_ID( el, KaxClusterSilentTracks ) )            {                ep->Down();            }            else if( MKV_IS_ID( el, KaxBlockGroup ) )            {                i_block_pos = el->GetElementPosition();                ep->Down();            }            break;        case 3:            if( MKV_IS_ID( el, KaxBlock ) )            {                pp_block = (KaxBlock*)el;                pp_block->ReadData( es.I_O() );                pp_block->SetParent( *cluster );                ep->Keep();            }            else if( MKV_IS_ID( el, KaxBlockDuration ) )            {                KaxBlockDuration &dur = *(KaxBlockDuration*)el;                dur.ReadData( es.I_O() );                *pi_duration = uint64( dur );            }            else if( MKV_IS_ID( el, KaxReferenceBlock ) )            {                KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;                ref.ReadData( es.I_O() );                if( *pi_ref1 == -1 )                {                    *pi_ref1 = int64( ref );                }                else                {                    *pi_ref2 = int64( ref );                }            }            else if( MKV_IS_ID( el, KaxClusterSilentTrackNumber ) )            {                KaxClusterSilentTrackNumber &track_num = *(KaxClusterSilentTrackNumber*)el;                track_num.ReadData( es.I_O() );                // find the track                for (size_t i=0; i<tracks.size(); i++)                {                    if ( tracks[i]->i_number == uint32(track_num))                    {                        tracks[i]->b_silent = VLC_TRUE;                        break;                    }                }            }            break;        default:            msg_Err( &sys.demuxer, "invalid level = %d", i_level );            return VLC_EGENERIC;        }    }}static block_t *MemToBlock( demux_t *p_demux, uint8_t *p_mem, int i_mem){    block_t *p_block;    if( !(p_block = block_New( p_demux, i_mem ) ) ) return NULL;    memcpy( p_block->p_buffer, p_mem, i_mem );    //p_block->i_rate = p_input->stream.control.i_rate;    return p_block;}static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,                         mtime_t i_duration ){    demux_sys_t        *p_sys = p_demux->p_sys;    matroska_segment_c *p_segment = p_sys->p_current_segment->Segment();    size_t          i_track;    unsigned int    i;    vlc_bool_t      b;#define tk  p_segment->tracks[i_track]    for( i_track = 0; i_track < p_segment->tracks.size(); i_track++ )    {        if( tk->i_number == block->TrackNum() )        {            break;        }    }    if( i_track >= p_segment->tracks.size() )    {        msg_Err( p_demux, "invalid track number=%d", block->TrackNum() );        return;    }    if( tk->fmt.i_cat != NAV_ES && tk->p_es == NULL )    {        msg_Err( p_demux, "unknown track number=%d", block->TrackNum() );        return;    }    if( i_pts < p_sys->i_start_pts && tk->fmt.i_cat == AUDIO_ES )    {        return; /* discard audio packets that shouldn't be rendered */    }    if ( tk->fmt.i_cat != NAV_ES )    {        es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );        if( !b )        {            tk->b_inited = VLC_FALSE;            return;        }    }    /* First send init data */    if( !tk->b_inited && tk->i_data_init > 0 )    {        block_t *p_init;        msg_Dbg( p_demux, "sending header (%d bytes)", tk->i_data_init );        p_init = MemToBlock( p_demux, tk->p_data_init, tk->i_data_init );        if( p_init ) es_out_Send( p_demux->out, tk->p_es, p_init );    }    tk->b_inited = VLC_TRUE;    for( i = 0; i < block->NumberFrames(); i++ )    {        block_t *p_block;        DataBuffer &data = block->GetBuffer(i);        p_block = MemToBlock( p_demux, data.Buffer(), data.Size() );        if( p_block == NULL )        {            break;        }#if defined(HAVE_ZLIB_H)        if( tk->i_compression_type )        {            p_block = block_zlib_decompress( VLC_OBJECT(p_demux), p_block );        }#endif        if ( tk->fmt.i_cat == NAV_ES )        {            // TODO handle the start/stop times of this packet            if ( p_sys->b_ui_hooked )            {                vlc_mutex_lock( &p_sys->p_ev->lock );                memcpy( &p_sys->pci_packet, &p_block->p_buffer[1], sizeof(pci_t) );                p_sys->SwapButtons();                p_sys->b_pci_packet_set = true;                vlc_mutex_unlock( &p_sys->p_ev->lock );                block_Release( p_block );            }            return;        }        // TODO implement correct timestamping when B frames are used        if( tk->fmt.i_cat != VIDEO_ES )        {            p_block->i_dts = p_block->i_pts = i_pts;        }        else        {            p_block->i_dts = i_pts;            p_block->i_pts = 0;        }        if( strcmp( tk->psz_codec, "S_VOBSUB" ) )        {            p_block->i_length = i_duration * 1000;        }        es_out_Send( p_demux->out, tk->p_es, p_block );        /* use time stamp only for first block */        i_pts = 0;    }#undef tk}matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( EbmlStream *p_estream ){    int i_upper_lvl = 0;    size_t i;    EbmlElement *p_l0, *p_l1, *p_l2;    bool b_keep_stream = false, b_keep_segment;    // verify the EBML Header    p_l0 = p_estream->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL);    if (p_l0 == NULL)    {        return NULL;    }    p_l0->SkipData(*p_estream, EbmlHead_Context);    delete p_l0;    // find all segments in this file    p_l0 = p_estream->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFFLL);    if (p_l0 == NULL)    {        return NULL;    }    matroska_stream_c *p_stream1 = new matroska_stream_c( *this );    while (p_l0 != 0)    {        if (EbmlId(*p_l0) == KaxSegment::ClassInfos.GlobalId)        {            EbmlParser  *ep;            matroska_segment_c *p_segment1 = new matroska_segment_c( *this, *p_estream );            b_keep_segment = false;            ep = new EbmlParser(p_estream, p_l0, &demuxer );            p_segment1->ep = ep;            p_segment1->segment = (KaxSegment*)p_l0;            while ((p_l1 = ep->Get()))            {                if (MKV_IS_ID(p_l1, KaxInfo))                {                    // find the families of this segment                    KaxInfo *p_info = static_cast<KaxInfo*>(p_l1);                    p_info->Read(*p_estream, KaxInfo::ClassInfos.Context, i_upper_lvl, p_l2, true);                    for( i = 0; i < p_info->ListSize(); i++ )                    {                        EbmlElement *l = (*p_info)[i];                        if( MKV_IS_ID( l, KaxSegmentUID ) )                        {                            KaxSegmentUID *p_uid = static_cast<KaxSegmentUID*>(l);                            b_keep_segment = (FindSegment( *p_uid ) == NULL);                            if ( !b_keep_segment )                                break; // this segment is already known                            opened_segments.push_back( p_segment1 );                            delete p_segment1->p_segment_uid;                            p_segment1->p_segment_uid = new KaxSegmentUID(*p_uid);                        }                        else if( MKV_IS_ID( l, KaxPrevUID ) )                        {                            p_segment1->p_prev_segment_uid = new KaxPrevUID( *static_cast<KaxPrevUID*>(l) );                        }                        else if( MKV_IS_ID( l, KaxNextUID ) )                        {                            p_segment1->p_next_segment_uid = new KaxNextUID( *static_cast<KaxNextUID*>(l) );                        }                        else if( MKV_IS_ID( l, KaxSegmentFamily ) )                        {                            KaxSegmentFamily *p_fam = new KaxSegmentFamily( *static_cast<KaxSegmentFamily*>(l) );                            p_segment1->families.push_back( *p_fam );                        }                    }                    break;                }            }            if ( b_keep_segment )            {                b_keep_stream = true;                p_stream1->segments.push_back( p_segment1 );            }            else                delete p_segment1;        }        p_l0->SkipData(*p_estream, EbmlHead_Context);        p_l0 = p_estream->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFL);    }    if ( !b_keep_stream )    {        delete p_stream1;        p_stream1 = NULL;    }    return p_stream1;}bool matroska_segment_c::Select( mtime_t i_start_time ){    size_t i_track;    /* add all es */    msg_Dbg( &sys.demuxer, "found %d es", tracks.size() );    sys.b_pci_packet_set = false;    for( i_track = 0; i_track < tracks.size(); i_track++ )    {        if( tracks[i_track]->fmt.i_cat == UNKNOWN_ES )        {            msg_Warn( &sys.demuxer, "invalid track[%d, n=%d]", i_track, tracks[i_track]->i_number );            tracks[i_track]->p_es = NULL;            continue;        }        if( !strcmp( tracks[i_track]->psz_codec, "V_MS/VFW/FOURCC" ) )        {            if( tracks[i_track]->i_extra_data < (int)sizeof( BITMAPINFOHEADER ) )            {                msg_Err( &sys.demuxer, "missing/invalid BITMAPINFOHEADER" );                tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );            }            else            {                BITMAPINFOHEADER *p_bih = (BITMAPINFOHEADER*)tracks[i_track]->p_extra_data;                tracks[i_track]->fmt.video.i_width = GetDWLE( &p_bih->biWidth );                tracks[i_track]->fmt.video.i_height= GetDWLE( &p_bih->biHeight );                tracks[i_track]->fmt.i_codec       = GetFOURCC( &p_bih->biCompression );                tracks[i_track]->fmt.i_extra       = GetDWLE( &p_bih->biSize ) - sizeof( BITMAPINFOHEADER );                if( tracks[i_track]->fmt.i_extra > 0 )                {                    tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->fmt.i_extra );                    memcpy( tracks[i_track]->fmt.p_extra, &p_bih[1], tracks[i_track]->fmt.i_extra );                }            }        }        else if( !strcmp( tracks[i_track]->psz_codec, "V_MPEG1" ) ||                 !strcmp( tracks[i_track]->psz_codec, "V_MPEG2" ) )        {            tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'v' );        }        else if( !strncmp( tracks[i_track]->psz_codec, "V_MPEG4", 7 ) )        {     

⌨️ 快捷键说明

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