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

📄 ty.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
                /* set PCR before we send */                if( p_block_in->i_pts > 0 )                    es_out_Control( p_demux->out, ES_OUT_SET_PCR,                                    p_block_in->i_pts );                es_out_Send( p_demux->out, p_sys->p_audio, p_block_in );            }   /* if DTiVo */        }   /* if subrec == 0x03 */        /* SA Audio with no PES Header                      */        /* ================================================ */        if ( subrec_type == 0x04 )        {            /*msg_Dbg(p_demux,                    "Adding SA Audio Packet Size %ld", l_rec_size ); */            /* set PCR before we send */            if (p_sys->lastAudioPTS > 0)            {                p_block_in->i_pts = p_sys->lastAudioPTS;                es_out_Control( p_demux->out, ES_OUT_SET_PCR,                                p_block_in->i_pts );            }            es_out_Send( p_demux->out, p_sys->p_audio, p_block_in );        }        /* DTiVo AC3 Audio Data with PES Header             */        /* ================================================ */        if ( subrec_type == 0x09 )        {            find_es_header( ty_AC3AudioPacket, p_block_in->p_buffer,                            l_rec_size, &esOffset1 );            /*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 AC3 hdr at offset %d", esOffset1);*/            /* 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. */                p_sys->i_cur_rec++;                return 1;            }            /* 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 );            }            es_out_Send( p_demux->out, p_sys->p_audio, p_block_in );        }    } /* end "if audio" */    /* ================================================================ */    /* Closed Caption                                                   */    /* ================================================================ */    else if ( rec_type == 0x01 )    {        /*msg_Dbg(p_demux, "CC1 %02x %02x [%c%c]", rec_hdr->ex1,                   rec_hdr->ex2, rec_hdr->ex1, rec_hdr->ex2 );*/        /* construct a 'user-data' MPEG packet */        lastCC[ 0x00 ] = 0x00;        lastCC[ 0x01 ] = 0x00;        lastCC[ 0x02 ] = 0x01;        lastCC[ 0x03 ] = 0xb2;        lastCC[ 0x04 ] = 'T';    /* vcdimager code says this byte should be 0x11 */        lastCC[ 0x05 ] = 'Y';    /* (no other notes there) */        lastCC[ 0x06 ] = 0x01;        lastCC[ 0x07 ] = rec_hdr->ex1;        lastCC[ 0x08 ] = rec_hdr->ex2;        /* not sure what to send, because VLC doesn't yet support         * teletext type of subtitles (only supports the full-sentence type) */        /*p_block_in = block_NewEmpty(); ????        es_out_Send( p_demux->out, p_sys->p_subt_es, p_block_in );*/    }    else if ( rec_type == 0x02 )    {        /*msg_Dbg(p_demux, "CC2 %02x %02x", rec_hdr->ex1, rec_hdr->ex2 );*/        /* construct a 'user-data' MPEG packet */        lastXDS[ 0x00 ] = 0x00;        lastXDS[ 0x01 ] = 0x00;        lastXDS[ 0x02 ] = 0x01;        lastXDS[ 0x03 ] = 0xb2;        lastXDS[ 0x04 ] = 'T';    /* vcdimager code says this byte should be 0x11 */        lastXDS[ 0x05 ] = 'Y';    /* (no other notes there) */        lastXDS[ 0x06 ] = 0x02;        lastXDS[ 0x07 ] = rec_hdr->ex1;        lastXDS[ 0x08 ] = rec_hdr->ex2;        /* not sure what to send, because VLC doesn't support this?? */        /*p_block_in = block_NewEmpty(); ????        es_out_Send( p_demux->out, p_sys->p_audio, p_block_in );*/    }    /* ================================================================ */    /* Tivo data services (e.g. "thumbs-up to record!")  useless for us */    /* ================================================================ */    else if ( rec_type == 0x03 )    {    }    /* ================================================================ */    /* Unknown, but seen regularly */    /* ================================================================ */    else if ( rec_type == 0x05 )    {    }    else    {        msg_Dbg(p_demux, "Invalid record type 0x%02x", rec_type );        if (p_block_in) block_Release(p_block_in);            invalidType++;    }    p_sys->i_cur_rec++;    return 1;}/* seek to a position within the stream, if possible */static int ty_stream_seek(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;    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 chunk we want & go there */    p_sys->i_chunk_count = seek_pos / CHUNK_SIZE;    if ( stream_Seek( p_demux->s, p_sys->i_chunk_count * CHUNK_SIZE))    {        /* can't seek stream */        return VLC_EGENERIC;    }    /* load the chunk */    get_chunk_header(p_demux);      /* seek within the chunk to get roughly to where we want */    p_sys->i_cur_rec = (int)      ((double) ((seek_pos % CHUNK_SIZE) / (double) (CHUNK_SIZE)) * p_sys->i_num_recs);    msg_Dbg(p_demux, "Seeked to file pos " I64Fd, seek_pos);    msg_Dbg(p_demux, " (chunk %d, record %d)",             p_sys->i_chunk_count - 1, p_sys->i_cur_rec);    /* seek to the start of this record's data.     * to do that, we have to skip past all prior records */    l_skip_amt = 0;    for (i=0; i<p_sys->i_cur_rec; i++)        l_skip_amt += p_sys->rec_hdrs[i].l_rec_size;    stream_Seek(p_demux->s, ((p_sys->i_chunk_count-1) * CHUNK_SIZE) +                 (p_sys->i_num_recs * 16) + l_skip_amt + 4);    /* to hell with syncing any audio or video, just start reading records... :) */    /*p_sys->lastAudioPTS = p_sys->lastVideoPTS = 0;*/    es_out_Control( p_demux->out, ES_OUT_RESET_PCR );    return VLC_SUCCESS;}static int Control(demux_t *p_demux, int i_query, va_list args){    demux_sys_t *p_sys = p_demux->p_sys;    double f, *pf;    int64_t i64, *p_i64;      /*msg_Info(p_demux, "control cmd %d", i_query);*/    switch( i_query )    {    case DEMUX_GET_POSITION:        /* arg is 0.0 - 1.0 percent of overall file position */        if( ( i64 = p_sys->i_stream_size ) > 0 )        {            pf = (double*) va_arg( args, double* );            *pf = (double)stream_Tell( p_demux->s ) / (double) i64;            return VLC_SUCCESS;        }        return VLC_EGENERIC;    case DEMUX_SET_POSITION:        /* arg is 0.0 - 1.0 percent of overall file position */        f = (double) va_arg( args, double );        //msg_Dbg(p_demux, "Control - set position to %2.3f", f);        if ((i64 = p_sys->i_stream_size) > 0)            return ty_stream_seek(p_demux, f);        return VLC_EGENERIC;    case DEMUX_GET_TIME:        /* return latest PTS - start PTS */        p_i64 = (int64_t *) va_arg(args, int64_t *);        *p_i64 = p_sys->lastAudioPTS - p_sys->firstAudioPTS;        return VLC_SUCCESS;    case DEMUX_SET_TIME:      /* arg is time in microsecs */    case DEMUX_GET_LENGTH:    /* length of program in microseconds, 0 if unk */    case DEMUX_GET_FPS:    default:        return VLC_EGENERIC;    }}/* =========================================================================== */static void TyClose( vlc_object_t *p_this ){    demux_sys_t *p_sys = ((demux_t *) p_this)->p_sys;    free(p_sys->rec_hdrs);    free(p_sys);}/* =========================================================================== */static int get_chunk_header(demux_t *p_demux){    int i_readSize, i_num_recs, i;    uint8_t packet_header[4];    uint8_t record_header[16];    ty_rec_hdr_t *p_rec_hdr;    demux_sys_t *p_sys = p_demux->p_sys;    int i_payload_size = 0;         /* sum of all records */    msg_Dbg(p_demux, "parsing ty chunk #%d", p_sys->i_chunk_count );    /* if we have left-over filler space from the last chunk, get that */    if (p_sys->i_stuff_cnt > 0)        stream_Read( p_demux->s, NULL, p_sys->i_stuff_cnt);    /* read the TY packet header */    i_readSize = stream_Read( p_demux->s, packet_header, 4 );    p_sys->i_chunk_count++;      if ( i_readSize < 4 )    {        /* EOF */        p_sys->eof = 1;        return 0;    }      /* if it's a PART Header, then try again. */    if( U32_AT( &packet_header[ 0 ] ) == TIVO_PES_FILEID )    {        msg_Dbg( p_demux, "skipping TY PART Header" );        /* TODO: if stream is seekable, should we seek() instead of read() ?? */        stream_Read( p_demux->s, NULL, CHUNK_SIZE - 4 );        return get_chunk_header(p_demux);    }    /* number of records in chunk (8- or 16-bit number) */    if (packet_header[3] & 0x80)    {        /* 16 bit rec cnt */        p_sys->i_num_recs = i_num_recs = (packet_header[1] << 8) + packet_header[0];        p_sys->i_seq_rec = (packet_header[3] << 8) + packet_header[2];        if (p_sys->i_seq_rec != 0xffff)        {            p_sys->i_seq_rec &= ~0x8000;        }    }    else    {        /* 8 bit reclen - tivo 1.3 format */        p_sys->i_num_recs = i_num_recs = packet_header[0];        p_sys->i_seq_rec = packet_header[1];    }    p_sys->i_cur_rec = 0;    p_sys->b_first_chunk = VLC_FALSE;      /*msg_Dbg( p_demux, "chunk has %d records", i_num_recs );*/    /* parse headers into array */    if (p_sys->rec_hdrs)        free(p_sys->rec_hdrs);    p_sys->rec_hdrs = malloc(i_num_recs * sizeof(ty_rec_hdr_t));    for (i = 0; i < i_num_recs; i++)    {        i_readSize = stream_Read( p_demux->s, record_header, 16 );        if (i_readSize < 16)        {            /* EOF */            p_sys->eof = VLC_TRUE;            return 0;        }        p_rec_hdr = &p_sys->rec_hdrs[i];     /* for brevity */        p_rec_hdr->rec_type = record_header[3];        p_rec_hdr->subrec_type = record_header[2] & 0x0f;        if ((record_header[ 0 ] & 0x80) == 0x80)        {            unsigned char b1, b2;            /* marker bit 2 set, so read extended data */            b1 = ( ( ( record_header[ 0 ] & 0x0f ) << 4 ) |                    ( ( record_header[ 1 ] & 0xf0 ) >> 4 ) );            b1 &= 0x7f;            b2 = ( ( ( record_header[ 1 ] & 0x0f ) << 4 ) |                    ( ( record_header[ 2 ] & 0xf0 ) >> 4 ) );            b2 &= 0x7f;            p_rec_hdr->ex1 = b1;            p_rec_hdr->ex2 = b2;            p_rec_hdr->l_rec_size = 0;            p_rec_hdr->b_ext = VLC_TRUE;        }        else        {            p_rec_hdr->l_rec_size = ( record_header[ 0 ] << 8 |                record_header[ 1 ] ) << 4 | ( record_header[ 2 ] >> 4 );            i_payload_size += p_rec_hdr->l_rec_size;            p_rec_hdr->b_ext = VLC_FALSE;        }    } /* end of record-header loop */    p_sys->i_stuff_cnt = CHUNK_SIZE - 4 -        (p_sys->i_num_recs * 16) - i_payload_size;    if (p_sys->i_stuff_cnt > 0)        msg_Dbg( p_demux, "chunk has %d stuff bytes at end",                 p_sys->i_stuff_cnt );    return 1;}

⌨️ 快捷键说明

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