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

📄 ty.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* if it's not a continue blk, then set PTS */    if( subrec_type != 0x02 )    {        /*msg_Dbg(p_demux, "Video rec %d type 0x%02X", p_sys->i_cur_rec,                   subrec_type);*/        /* if it's a GOP header, make sure it's legal         * (if we have enough data) */        /* Some ty files don't have this bit set         * and it causes problems */        if (subrec_type == 0x0c && l_rec_size >= 6)            p_block_in->p_buffer[5] |= 0x08;        /* store the TY PTS if there is one */        if (subrec_type == 0x07) {            p_sys->l_last_ty_pts = rec_hdr->l_ty_pts;            /* should we use audio or video PTS? */            //p_sys->l_last_ty_pts_sync = p_sys->lastAudioPTS;        } else {            /* yes I know this is a cheap hack.  It's the timestamp               used for display and skipping fwd/back, so it               doesn't have to be accurate to the millisecond.               I adjust it here by roughly one 1/30 sec.  Yes it               will be slightly off for UK streams, but it's OK.             */            p_sys->l_last_ty_pts += 35000000;            //p_sys->l_last_ty_pts += 33366667;        }        /* set PTS for this block before we send */        if (p_sys->lastVideoPTS > 0)        {            p_block_in->i_pts = p_sys->lastVideoPTS;            /* PTS gets used ONCE.              * Any subsequent frames we get BEFORE next PES             * header will have their PTS computed in the codec */            p_sys->lastVideoPTS = 0;        }    }    /* Register the CC decoders when needed */    for( i = 0; i < 4; i++ )    {        static const vlc_fourcc_t fcc[4] = {            VLC_FOURCC('c', 'c', '1', ' '),            VLC_FOURCC('c', 'c', '2', ' '),            VLC_FOURCC('c', 'c', '3', ' '),            VLC_FOURCC('c', 'c', '4', ' ')        };        static const char *ppsz_description[4] = {            N_("Closed captions 1"),            N_("Closed captions 2"),            N_("Closed captions 3"),            N_("Closed captions 4"),        };        es_format_t fmt;        if( !p_sys->cc.pb_present[i] || p_sys->p_cc[i] )            continue;        es_format_Init( &fmt, SPU_ES, fcc[i] );        fmt.psz_description = strdup( _(ppsz_description[i]) );        fmt.i_group = TY_ES_GROUP;        p_sys->p_cc[i] = es_out_Add( p_demux->out, &fmt );        es_format_Clean( &fmt );    }    /* Send the CC data */    if( p_block_in->i_pts > 0 && p_sys->cc.i_data > 0 )    {        int i_cc_count;        block_t *p_cc = block_New( p_demux, p_sys->cc.i_data );        p_cc->i_flags |= BLOCK_FLAG_TYPE_I;        p_cc->i_pts = p_block_in->i_pts;        memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data );        for( i = 0, i_cc_count = 0; i < 4; i++ )            i_cc_count += p_sys->p_cc[i] ? 1 : 0;        for( i = 0; i < 4; i++ )        {            if( !p_sys->p_cc[i] )                continue;            if( i_cc_count > 1 )                es_out_Send( p_demux->out, p_sys->p_cc[i], block_Duplicate( p_cc ) );            else                es_out_Send( p_demux->out, p_sys->p_cc[i], p_cc );        }        cc_Flush( &p_sys->cc );    }    //msg_Dbg(p_demux, "sending rec %d as video type 0x%02x",            //p_sys->i_cur_rec, subrec_type);    es_out_Send(p_demux->out, p_sys->p_video, p_block_in);    return 0;}static int DemuxRecAudio( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_block_in ){    demux_sys_t *p_sys = p_demux->p_sys;    const int subrec_type = rec_hdr->subrec_type;    const long l_rec_size = rec_hdr->l_rec_size;    int esOffset1;    assert( rec_hdr->rec_type == 0xc0 );    if( !p_block_in )        return -1;#if 0        int i;        fprintf( stderr, "Audio Packet Header " );        for( i = 0 ; i < 24 ; i++ )            fprintf( stderr, "%2.2x ", p_block_in->p_buffer[i] );        fprintf( stderr, "\n" );#endif    if( subrec_type == 2 )    {        /* SA or DTiVo Audio Data, no PES (continued block)         * ================================================         */        /* continue PES if previous was incomplete */        if (p_sys->i_pes_buf_cnt > 0)        {            const int i_need = p_sys->i_Pes_Length - p_sys->i_pes_buf_cnt;            msg_Dbg(p_demux, "continuing PES header");            /* do we have enough data to complete? */            if (i_need >= l_rec_size)            {                /* don't have complete PES hdr; save what we have and return */                memcpy(&p_sys->pes_buffer[p_sys->i_pes_buf_cnt],                        p_block_in->p_buffer, l_rec_size);                p_sys->i_pes_buf_cnt += l_rec_size;                /* */                block_Release(p_block_in);                return 0;            }            /* we have enough; reconstruct this p_frame with the new hdr */            memcpy(&p_sys->pes_buffer[p_sys->i_pes_buf_cnt],                   p_block_in->p_buffer, i_need);            /* advance the block past the PES header (don't want to send it) */            p_block_in->p_buffer += i_need;            p_block_in->i_buffer -= i_need;            /* get the PTS out of this PES header (MPEG or AC3) */            if (p_sys->audio_type == TIVO_AUDIO_MPEG)                esOffset1 = find_es_header(ty_MPEGAudioPacket,                        p_sys->pes_buffer, 5);            else                esOffset1 = find_es_header(ty_AC3AudioPacket,                        p_sys->pes_buffer, 5);            if (esOffset1 < 0)            {                /* god help us; something's really wrong */                msg_Err(p_demux, "can't find audio PES header in packet");            }            else            {                p_sys->lastAudioPTS = get_pts(                     &p_sys->pes_buffer[ esOffset1 + p_sys->i_Pts_Offset ] );                p_block_in->i_pts = p_sys->lastAudioPTS;            }            p_sys->i_pes_buf_cnt = 0;        }        /* S2 DTivo has AC3 packets with 2 padding bytes at end.  This is         * not allowed in the AC3 spec and will cause problems.  So here         * we try to trim things. */        /* Also, S1 DTivo has alternating short / long AC3 packets.  That         * is, one packet is short (incomplete) and the next packet has         * the first one's missing data, plus all of its own.  Strange. */        if (p_sys->audio_type == TIVO_AUDIO_AC3 &&                p_sys->tivo_series == TIVO_SERIES2) {            if (p_sys->l_ac3_pkt_size + p_block_in->i_buffer >                    AC3_PKT_LENGTH) {                p_block_in->i_buffer -= 2;                p_sys->l_ac3_pkt_size = 0;            } else {                p_sys->l_ac3_pkt_size += p_block_in->i_buffer;            }        }    }    else if( subrec_type == 0x03 )    {        /* MPEG Audio with PES Header, either SA or DTiVo   */        /* ================================================ */        esOffset1 = find_es_header( ty_MPEGAudioPacket,                p_block_in->p_buffer, 5 );        /*msg_Dbg(p_demux, "buffer has %#02x %#02x %#02x %#02x",           p_block_in->p_buffer[0], p_block_in->p_buffer[1],           p_block_in->p_buffer[2], p_block_in->p_buffer[3]);        msg_Dbg(p_demux, "audio ES hdr at offset %d", esOffset1);*/        /* SA PES Header, No Audio Data                     */        /* ================================================ */        if ( ( esOffset1 == 0 ) && ( l_rec_size == 16 ) )        {            p_sys->lastAudioPTS = get_pts( &p_block_in->p_buffer[                        SA_PTS_OFFSET ] );            if (p_sys->firstAudioPTS < 0)                p_sys->firstAudioPTS = p_sys->lastAudioPTS;            block_Release(p_block_in);            return 0;            /*msg_Dbg(p_demux, "SA Audio PTS %lld",                       p_sys->lastAudioPTS );*/        }        /* DTiVo Audio with PES Header                      */        /* ================================================ */        /* Check for complete PES */        if (check_sync_pes(p_demux, p_block_in, esOffset1,                            l_rec_size) == -1)        {            /* partial PES header found, nothing else.              * we're done. */            block_Release(p_block_in);            return 0;        }#if 0        msg_Dbg(p_demux, "packet buffer has "                 "%02x %02x %02x %02x %02x %02x %02x %02x "                 "%02x %02x %02x %02x %02x %02x %02x %02x",                 p_block_in->p_buffer[0], p_block_in->p_buffer[1],                 p_block_in->p_buffer[2], p_block_in->p_buffer[3],                 p_block_in->p_buffer[4], p_block_in->p_buffer[5],                 p_block_in->p_buffer[6], p_block_in->p_buffer[7],                 p_block_in->p_buffer[8], p_block_in->p_buffer[9],                 p_block_in->p_buffer[10], p_block_in->p_buffer[11],                 p_block_in->p_buffer[12], p_block_in->p_buffer[13],                 p_block_in->p_buffer[14], p_block_in->p_buffer[15]);#endif    }    else if( subrec_type == 0x04 )    {        /* SA Audio with no PES Header                      */        /* ================================================ */        /*msg_Dbg(p_demux,                "Adding SA Audio Packet Size %ld", l_rec_size ); */        if (p_sys->lastAudioPTS > 0)            p_block_in->i_pts = p_sys->lastAudioPTS;    }    else if( subrec_type == 0x09 )    {        /* DTiVo AC3 Audio Data with PES Header             */        /* ================================================ */        esOffset1 = find_es_header( ty_AC3AudioPacket,                p_block_in->p_buffer, 5 );#if 0        msg_Dbg(p_demux, "buffer has "                 "%02x %02x %02x %02x %02x %02x %02x %02x "                 "%02x %02x %02x %02x %02x %02x %02x %02x",                 p_block_in->p_buffer[0], p_block_in->p_buffer[1],                 p_block_in->p_buffer[2], p_block_in->p_buffer[3],                 p_block_in->p_buffer[4], p_block_in->p_buffer[5],                 p_block_in->p_buffer[6], p_block_in->p_buffer[7],                 p_block_in->p_buffer[8], p_block_in->p_buffer[9],                 p_block_in->p_buffer[10], p_block_in->p_buffer[11],                 p_block_in->p_buffer[12], p_block_in->p_buffer[13],                 p_block_in->p_buffer[14], p_block_in->p_buffer[15]);        msg_Dbg(p_demux, "audio ES AC3 hdr at offset %d", esOffset1);#endif        /* Check for complete PES */        if (check_sync_pes(p_demux, p_block_in, esOffset1,                            l_rec_size) == -1)        {            /* partial PES header found, nothing else.  we're done. */            block_Release(p_block_in);            return 0;        }        /* S2 DTivo has invalid long AC3 packets */        if (p_sys->tivo_series == TIVO_SERIES2) {            if (p_block_in->i_buffer > AC3_PKT_LENGTH) {                p_block_in->i_buffer -= 2;                p_sys->l_ac3_pkt_size = 0;            } else {                p_sys->l_ac3_pkt_size = p_block_in->i_buffer;            }        }    }    else    {        /* Unsupported/Unknown */        block_Release(p_block_in);        return 0;    }    /* set PCR before we send (if PTS found) */    if( p_block_in->i_pts > 0 )        es_out_Control( p_demux->out, ES_OUT_SET_PCR,                        p_block_in->i_pts );    /* Send data */    es_out_Send( p_demux->out, p_sys->p_audio, p_block_in );    return 0;}static int DemuxRecCc( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_block_in ){    demux_sys_t *p_sys = p_demux->p_sys;    int i_field;    int i_channel;    if( p_block_in )        block_Release(p_block_in);    if( rec_hdr->rec_type == 0x01 )        i_field = 0;    else if( rec_hdr->rec_type == 0x02 )        i_field = 1;    else        return 0;    /* XDS data (extract programs infos) transmitted on field 2 only */    if( i_field == 1 )        DemuxDecodeXds( p_demux, rec_hdr->ex1, rec_hdr->ex2 );    if( p_sys->cc.i_data + 3 > CC_MAX_DATA_SIZE )        return 0;    p_sys->cc.p_data[p_sys->cc.i_data+0] = i_field;    p_sys->cc.p_data[p_sys->cc.i_data+1] = rec_hdr->ex1;    p_sys->cc.p_data[p_sys->cc.i_data+2] = rec_hdr->ex2;    p_sys->cc.i_data += 3;    i_channel = cc_Channel( i_field, &p_sys->cc.p_data[p_sys->cc.i_data-3 + 1] );    if( i_channel >= 0 && i_channel < 4 )        p_sys->cc.pb_present[i_channel] = true;    return 0;}/* seek to a position within the stream, if possible */static int ty_stream_seek_pct(demux_t *p_demux, double seek_pct){    demux_sys_t *p_sys = p_demux->p_sys;    int64_t seek_pos = p_sys->i_stream_size * seek_pct;    int i, i_cur_part;    long l_skip_amt;    /* if we're not seekable, there's nothing to do */    if (!p_sys->b_seekable)        return VLC_EGENERIC;    /* figure out which part & chunk we want & go there */    i_cur_part = seek_pos / TIVO_PART_LENGTH;    p_sys->i_cur_chunk = seek_pos / CHUNK_SIZE;        /* try to read the part header (master chunk) if it's there */    if ( stream_Seek( p_demux->s, i_cur_part * TIVO_PART_LENGTH ))    {        /* can't seek stream */        return VLC_EGENERIC;    }    parse_master(p_demux);    /* now for the actual chunk */    if ( stream_Seek( p_demux->s, p_sys->i_cur_chunk * CHUNK_SIZE))    {        /* can't seek stream */

⌨️ 快捷键说明

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