📄 demux_ty.c
字号:
int offset; int size; int type; int nybbleType; int counter; int aid; demux_stream_t *ds = NULL; int esOffset1; int esOffset2; TiVoInfo *tivo = 0; if ( demux->stream->type == STREAMTYPE_DVD ) { return( 0 ); } mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Parsing a chunk\n" ); if ( ( demux->a_streams[ MAX_A_STREAMS - 1 ] ) == 0 ) { demux->a_streams[ MAX_A_STREAMS - 1 ] = malloc( sizeof( TiVoInfo ) ); tivo = demux->a_streams[ MAX_A_STREAMS - 1 ]; memset( tivo, 0, sizeof( TiVoInfo ) ); tivo->firstAudioPTS = -1; tivo->firstVideoPTS = -1; } else { tivo = demux->a_streams[ MAX_A_STREAMS - 1 ]; } if( demux->stream->eof ) return 0; // ====================================================================== // If we haven't figured out the size of the stream, let's do so // ======================================================================#ifdef STREAMTYPE_STREAM_TY if ( demux->stream->type == STREAMTYPE_STREAM_TY ) { // The vstream code figures out the exact size of the stream demux->movi_start = 0; demux->movi_end = vstream_streamsize(); tivo->size = vstream_streamsize(); } else#endif { // If its a local file, try to find the Part Headers, so we can // calculate the ACTUAL stream size // If we can't find it, go off with the file size and hope the // extract program did the "right thing" if ( tivo->readHeader == 0 ) { tivo->readHeader = 1; filePos = demux->filepos; stream_seek( demux->stream, 0 ); // mp_msg( MSGT_DEMUX, MSGL_DBG3, // "ty:Reading a chunk %d\n", __LINE__ ); readSize = stream_read( demux->stream, chunk, CHUNKSIZE ); if ( readSize == CHUNKSIZE ) { tivo->pesFileId = tivobuffer2hostlong( &chunk[ 0x00 ] ); tivo->streamType = tivobuffer2hostlong( &chunk[ 0x04 ] ); tivo->chunkSize = tivobuffer2hostlong( &chunk[ 0x08 ] ); tivo->size = tivobuffer2hostlong( &chunk[ 0x0c ] ); if ( tivo->pesFileId == TIVO_PES_FILEID ) { off_t numberParts; off_t size; if ( demux->stream->end_pos > TIVO_PART_LENGTH ) { numberParts = demux->stream->end_pos / TIVO_PART_LENGTH; mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Number Parts %d\n", numberParts ); stream_seek( demux->stream, numberParts * TIVO_PART_LENGTH ); // mp_msg( MSGT_DEMUX, MSGL_DBG3, // "ty:Reading a chunk %d\n", __LINE__ ); readSize = stream_read( demux->stream, chunk, CHUNKSIZE ); pesFileId = tivobuffer2hostlong( &chunk[ 0x00 ] ); if ( pesFileId == TIVO_PES_FILEID ) { size = tivobuffer2hostlong( &chunk[ 0x0c ] ); size /= 256; size -= 4; size *= CHUNKSIZE; tivo->size = numberParts * TIVO_PART_LENGTH; tivo->size += size; mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Header Calc Stream Size %lld\n", tivo->size ); } else { tivo->size = demux->stream->end_pos; } } else { tivo->size = demux->stream->end_pos; } } else { tivo->size = demux->stream->end_pos; } } if ( tivo->size > demux->stream->end_pos ) { tivo->size = demux->stream->end_pos; } if ( demux->stream->start_pos > 0 ) { filePos = demux->stream->start_pos; } stream_seek( demux->stream, filePos ); demux->filepos = stream_tell( demux->stream ); } demux->movi_start = 0; demux->movi_end = tivo->size; } // ====================================================================== // Give a clue as to where we are in the stream // ====================================================================== mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty header size %llx\n", tivo->size ); mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:file end_pos %llx\n", demux->stream->end_pos );// mp_msg( MSGT_DEMUX, MSGL_DBG3,// "ty:vstream size %llx\n", vstream_streamsize() ); mp_msg( MSGT_DEMUX, MSGL_DBG3, "\nty:wanted current offset %llx\n", stream_tell( demux->stream ) ); if ( tivo->size > 0 ) { if ( stream_tell( demux->stream ) > tivo->size ) { demux->stream->eof = 1; return( 0 ); } } // Make sure we are on a 128k boundary if ( ( demux->filepos % CHUNKSIZE ) != 0 ) { whichChunk = demux->filepos / CHUNKSIZE; if ( ( demux->filepos % CHUNKSIZE ) > ( CHUNKSIZE / 2 ) ) { whichChunk++; } stream_seek( demux->stream, ( whichChunk * CHUNKSIZE ) ); } demux->filepos = stream_tell( demux->stream ); readSize = stream_read( demux->stream, chunk, CHUNKSIZE ); if ( readSize != CHUNKSIZE ) { return( 0 ); } // We found a part header, skip it pesFileId = tivobuffer2hostlong( &chunk[ 0x00 ] ); if( pesFileId == TIVO_PES_FILEID ) { demux->filepos = stream_tell( demux->stream ); mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Skipping PART Header\n" ); readSize = stream_read( demux->stream, chunk, CHUNKSIZE ); if ( readSize != CHUNKSIZE ) { return( 0 ); } } mp_msg( MSGT_DEMUX, MSGL_DBG3, "\nty:actual current offset %llx\n", ( stream_tell( demux->stream ) - 0x20000 ) ); // Let's make a Video Demux Stream for MPlayer aid = 0x0; if( !demux->v_streams[ aid ] ) new_sh_video( demux, aid ); if( demux->video->id == -1 ) demux->video->id = aid; if( demux->video->id == aid ) { ds = demux->video; if( !ds->sh ) ds->sh = demux->v_streams[ aid ]; } // ====================================================================== // Finally, we get to actually parse the chunk // ====================================================================== numberRecs = chunk[ 0 ]; recPtr = &chunk[ 4 ]; offset = ( numberRecs * 16 ) + 4; for ( counter = 0 ; counter < numberRecs ; counter++ ) { size = ( recPtr[ 0 ] << 8 | recPtr[ 1 ] ) << 4 | ( recPtr[ 2 ] >> 4 ); type = recPtr[ 3 ]; nybbleType = recPtr[ 2 ] & 0x0f; recordsDecoded++; mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Record Type %x/%x %d\n", nybbleType, type, size ); // ================================================================ // Video Parsing // ================================================================ if ( type == 0xe0 ) { if ( ( size > 0 ) && ( ( size + offset ) <= CHUNKSIZE ) ) {#if 0 printf( "Video Chunk Header " ); for( count = 0 ; count < 24 ; count++ ) { printf( "%2.2x ", chunk[ offset + count ] ); } printf( "\n" );#endif demux_ty_FindESHeader( ty_VideoPacket, 4, &chunk[ offset ], size, &esOffset1 ); if ( esOffset1 != -1 ) { tivo->lastVideoPTS = get_ty_pts( &chunk[ offset + esOffset1 + 9 ] ); mp_msg( MSGT_DEMUX, MSGL_DBG3, "Video PTS %7.1f\n", tivo->lastVideoPTS ); } // Do NOT Pass the PES Header onto the MPEG2 Decode if( nybbleType != 0x06 ) { demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, &chunk[ offset ], size, ( demux->filepos + offset ), tivo->lastVideoPTS ); } offset += size; } else { errorHeader++; } } // ================================================================ // Audio Parsing // ================================================================ else if ( type == 0xc0 ) { if ( ( size > 0 ) && ( ( size + offset ) <= CHUNKSIZE ) ) {#if 0 printf( "Audio Chunk Header " ); for( count = 0 ; count < 24 ; count++ ) { printf( "%2.2x ", chunk[ offset + count ] ); } printf( "\n" );#endif if( demux->audio->id == -1 ) { if ( nybbleType == 0x02 ) { continue; // DTiVo inconclusive, wait for more } else if ( nybbleType == 0x09 ) { mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Setting AC-3 Audio\n" ); aid = 0x80; // AC-3 } else { mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Setting MPEG Audio\n" ); aid = 0x0; // MPEG Audio } demux->audio->id = aid; if( !demux->a_streams[ aid ] ) new_sh_audio( demux, aid ); if( demux->audio->id == aid ) { ds = demux->audio; if( !ds->sh ) ds->sh = demux->a_streams[ aid ]; } } aid = demux->audio->id; // SA DTiVo Audio Data, no PES // ================================================ if ( nybbleType == 0x02 ) { if ( tivo->tivoType == 2 ) { demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size ); } else { 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 ); } } // MPEG Audio with PES Header, either SA or DTiVo // ================================================ if ( nybbleType == 0x03 ) { demux_ty_FindESHeader( ty_MPEGAudioPacket, 4, &chunk[ offset ], size, &esOffset1 ); // SA PES Header, No Audio Data // ================================================ if ( ( esOffset1 == 0 ) && ( size == 16 ) ) { tivo->tivoType = 1; tivo->lastAudioPTS = get_ty_pts( &chunk[ offset + SERIES2_PTS_OFFSET ] ); mp_msg( MSGT_DEMUX, MSGL_DBG3, "SA Audio PTS %7.1f\n", tivo->lastAudioPTS ); } else // DTiVo Audio with PES Header // ================================================ { tivo->tivoType = 2; demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size ); demux_ty_FindESPacket( ty_MPEGAudioPacket, 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",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -