📄 demux_ty.c
字号:
packetSize ); tivo->lastAudioPTS = get_ty_pts( &tivo->lastAudio[ esOffset1 + ptsOffset ] ); mp_msg( MSGT_DEMUX, MSGL_DBG3, "MPEG Audio PTS %7.1f\n", tivo->lastAudioPTS ); demux_ty_CopyToDemuxPacket ( TY_A, tivo, demux->audio, &( tivo->lastAudio[ esOffset1 + headerSize ] ), ( packetSize - headerSize ), ( demux->filepos + offset ), tivo->lastAudioPTS ); } // Collapse the Audio Buffer memmove( &(tivo->lastAudio[ 0 ] ), &( tivo->lastAudio[ esOffset2 ] ), ( tivo->lastAudioEnd - esOffset2 ) ); tivo->lastAudioEnd -= esOffset2; } } } // SA Audio with no PES Header // ================================================ if ( nybbleType == 0x04 ) { mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Adding Audio Packet Size %d\n", size ); demux_ty_CopyToDemuxPacket( TY_A, tivo, demux->audio, &chunk[ offset ], size, ( demux->filepos + offset ), tivo->lastAudioPTS ); } // DTiVo AC3 Audio Data with PES Header // ================================================ if ( nybbleType == 0x09 ) { tivo->tivoType = 2; demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size ); demux_ty_FindESPacket( ty_AC3AudioPacket, 4, tivo->lastAudio, tivo->lastAudioEnd, &esOffset1, &esOffset2 ); if ( ( esOffset1 != -1 ) && ( esOffset2 != -1 ) ) { int packetSize = esOffset2 - esOffset1; int headerSize; int ptsOffset; if ( IsValidAudioPacket( packetSize, &ptsOffset, &headerSize ) ) { mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Adding DTiVo Audio Packet Size %d\n", packetSize ); tivo->lastAudioPTS = get_ty_pts( &tivo->lastAudio[ esOffset1 + ptsOffset ] ); mp_msg( MSGT_DEMUX, MSGL_DBG3, "AC3 Audio PTS %7.1f\n", tivo->lastAudioPTS ); // AC3 Decoder WANTS the PTS demux_ty_CopyToDemuxPacket ( TY_A, tivo, demux->audio, &( tivo->lastAudio[ esOffset1 ] ), ( packetSize ), ( demux->filepos + offset ), tivo->lastAudioPTS ); } // Collapse the Audio Buffer memmove( &(tivo->lastAudio[ 0 ] ), &( tivo->lastAudio[ esOffset2 ] ), ( tivo->lastAudioEnd - esOffset2 ) ); tivo->lastAudioEnd -= esOffset2; } } offset += size; } else { errorHeader++; } } // ================================================================ // Closed Caption // ================================================================ else if ( type == 0x01 ) { unsigned char b1; unsigned char b2; unsigned char buffer[ 16 ]; b1 = ( ( ( recPtr[ 0 ] & 0x0f ) << 4 ) | ( ( recPtr[ 1 ] & 0xf0 ) >> 4 ) ); b1 &= 0x7f; b2 = ( ( ( recPtr[ 1 ] & 0x0f ) << 4 ) | ( ( recPtr[ 2 ] & 0xf0 ) >> 4 ) ); b2 &= 0x7f; mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:CC %x %x\n", b1, b2 ); buffer[ 0x00 ] = 0x00; buffer[ 0x01 ] = 0x00; buffer[ 0x02 ] = 0x01; buffer[ 0x03 ] = 0xb2; buffer[ 0x04 ] = 'T'; buffer[ 0x05 ] = 'Y'; buffer[ 0x06 ] = 0x01; buffer[ 0x07 ] = b1; buffer[ 0x08 ] = b2; demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, buffer, 0x09, ( demux->filepos + offset ), tivo->lastVideoPTS ); } // ================================================================ // Extended Data Services // ================================================================ else if ( type == 0x02 ) { unsigned char b1; unsigned char b2; unsigned char buffer[ 16 ]; b1 = ( ( ( recPtr[ 0 ] & 0x0f ) << 4 ) | ( ( recPtr[ 1 ] & 0xf0 ) >> 4 ) ); b1 &= 0x7f; b2 = ( ( ( recPtr[ 1 ] & 0x0f ) << 4 ) | ( ( recPtr[ 2 ] & 0xf0 ) >> 4 ) ); b2 &= 0x7f; mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:XDS %x %x\n", b1, b2 ); buffer[ 0x00 ] = 0x00; buffer[ 0x01 ] = 0x00; buffer[ 0x02 ] = 0x01; buffer[ 0x03 ] = 0xb2; buffer[ 0x04 ] = 'T'; buffer[ 0x05 ] = 'Y'; buffer[ 0x06 ] = 0x02; buffer[ 0x07 ] = b1; buffer[ 0x08 ] = b2; demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, buffer, 0x09, ( demux->filepos + offset ), tivo->lastVideoPTS ); } // ================================================================ // Found a 0x03 on Droid's TiVo, I have no idea what it is // ================================================================ else if ( type == 0x03 ) { if ( ( size > 0 ) && ( ( size + offset ) <= CHUNKSIZE ) ) { offset += size; } } // ================================================================ // Unknown // ================================================================ else if ( type == 0x05 ) { if ( ( size > 0 ) && ( ( size + offset ) <= CHUNKSIZE ) ) { offset += size; } } else { if ( ( size > 0 ) && ( ( size + offset ) <= CHUNKSIZE ) ) { offset += size; } mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Invalid Type %x\n", type ); invalidType++; } recPtr += 16; } if ( errorHeader > 0 ) { mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Error Check - Records %d, Parsed %d, Errors %d\n", numberRecs, recordsDecoded, errorHeader ); // Invalid MPEG ES Size Check if ( errorHeader > ( numberRecs / 2 ) ) { return( 0 ); } // Invalid MPEG Stream Type Check if ( invalidType > ( numberRecs / 2 ) ) { return( 0 ); } } demux->filepos = stream_tell( demux->stream ); return( 1 );}void demux_seek_ty( demuxer_t *demuxer, float rel_seek_secs, int flags ){ demux_stream_t *d_audio = demuxer->audio; demux_stream_t *d_video = demuxer->video; sh_audio_t *sh_audio = d_audio->sh; sh_video_t *sh_video = d_video->sh; off_t newpos; off_t res; TiVoInfo *tivo = 0; mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Seeking to %7.1f\n", rel_seek_secs ); if ( ( demuxer->a_streams[ MAX_A_STREAMS - 1 ] ) != 0 ) { tivo = demuxer->a_streams[ MAX_A_STREAMS - 1 ]; tivo->lastAudioEnd = 0; tivo->lastAudioPTS = 0; tivo->lastVideoPTS = 0; } // //================= seek in MPEG ========================== demuxer->filepos = stream_tell( demuxer->stream ); newpos = ( flags & 1 ) ? demuxer->movi_start : demuxer->filepos; if( flags & 2 ) { // float seek 0..1 newpos += ( demuxer->movi_end - demuxer->movi_start ) * rel_seek_secs; } else { // time seek (secs) if( ! sh_video->i_bps ) // unspecified or VBR { newpos += 2324 * 75 * rel_seek_secs; // 174.3 kbyte/sec } else { newpos += sh_video->i_bps * rel_seek_secs; } } if ( newpos < demuxer->movi_start ) { if( demuxer->stream->type != STREAMTYPE_VCD ) demuxer->movi_start = 0; if( newpos < demuxer->movi_start ) newpos = demuxer->movi_start; } res = newpos / CHUNKSIZE; if ( rel_seek_secs >= 0 ) { newpos = ( res + 1 ) * CHUNKSIZE; } else { newpos = res * CHUNKSIZE; } if ( newpos < 0 ) { newpos = 0; } stream_seek( demuxer->stream, newpos ); // re-sync video: videobuf_code_len = 0; // reset ES stream buffer ds_fill_buffer( d_video ); if( sh_audio ) { ds_fill_buffer( d_audio ); resync_audio_stream( sh_audio ); } while( 1 ) { int i; if( sh_audio && !d_audio->eof && d_video->pts && d_audio->pts ) { float a_pts = d_audio->pts; a_pts += ( ds_tell_pts( d_audio ) - sh_audio->a_in_buffer_len ) / (float)sh_audio->i_bps; if( d_video->pts > a_pts ) { skip_audio_frame( sh_audio ); // sync audio continue; } } i = sync_video_packet( d_video ); if( i == 0x1B3 || i == 0x1B8 ) break; // found it! if( !i || !skip_video_packet( d_video ) ) break; // EOF? } if ( subcc_enabled ) { ty_ClearOSD( 0 ); }}int demux_ty_control( demuxer_t *demuxer,int cmd, void *arg ){ demux_stream_t *d_video = demuxer->video; sh_video_t *sh_video = d_video->sh; switch(cmd) { case DEMUXER_CTRL_GET_TIME_LENGTH: if(!sh_video->i_bps) // unspecified or VBR return DEMUXER_CTRL_DONTKNOW; *((unsigned long *)arg)= (demuxer->movi_end-demuxer->movi_start)/sh_video->i_bps; return DEMUXER_CTRL_GUESS; case DEMUXER_CTRL_GET_PERCENT_POS: return DEMUXER_CTRL_DONTKNOW; default: return DEMUXER_CTRL_NOTIMPL; }}int demux_close_ty( demuxer_t *demux ){ TiVoInfo *tivo = 0; if ( ( demux->a_streams[ MAX_A_STREAMS - 1 ] ) != 0 ) { tivo = demux->a_streams[ MAX_A_STREAMS - 1 ]; free( tivo ); demux->a_streams[ MAX_A_STREAMS - 1 ] = 0; sub_justify = 0; } return( 0 );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -