📄 demux_ty.c
字号:
/* * tivo@wingert.org, February 2003 * * Copyright (C) 2003 Christopher R. Wingert * * The license covers the portions of this file regarding TiVo additions. * * Olaf Beck and Tridge (indirectly) were essential at providing * information regarding the format of the TiVo streams. * * However, no code in the following subsection is directly copied from * either author. * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <time.h>#include <stdarg.h>#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "stream.h"#include "demuxer.h"#include "parse_es.h"#include "stheader.h"//#include "mp3_hdr.h"//#include "../subreader.h"//#include "../sub_cc.h"//#include "../libvo/sub.h"//#include "dvdauth.h"extern void resync_audio_stream( sh_audio_t *sh_audio );extern void skip_audio_frame( sh_audio_t *sh_audio );extern int sub_justify;// 2/c0: audio data// 3/c0: audio packet header (PES header)// 4/c0: audio data (S/A only?)// 9/c0: audio packet header, AC-3 audio// 2/e0: video data// 6/e0: video packet header (PES header)// 7/e0: video sequence header start// 8/e0: video I-frame header start// a/e0: video P-frame header start// b/e0: video B-frame header start// c/e0: video GOP header start// e/01: closed-caption data// e/02: Extended data services data #define TIVO_PES_FILEID ( 0xf5467abd )#define TIVO_PART_LENGTH ( 0x20000000 )#define CHUNKSIZE ( 128 * 1024 )#define MAX_AUDIO_BUFFER ( 16 * 1024 )#define PTS_MHZ ( 90 )#define PTS_KHZ ( PTS_MHZ * 1000 )#define TY_V ( 1 )#define TY_A ( 1 )typedef struct sTivoInfo{ unsigned char lastAudio[ MAX_AUDIO_BUFFER ]; int lastAudioEnd; int tivoType; // 1 = SA, 2 = DTiVo float firstAudioPTS; float firstVideoPTS; float lastAudioPTS; float lastVideoPTS; int headerOk; unsigned int pesFileId; // Should be 0xf5467abd int streamType; // Should be 0x02 int chunkSize; // Should always be 128k off_t size; int readHeader;} TiVoInfo;off_t vstream_streamsize( );void ty_ClearOSD( int start );// DTiVo MPEG 336, 480, 576, 768// SA TiVo 864// DTiVo AC-3 1550//#define SERIES1_PTS_LENGTH ( 11 )#define SERIES1_PTS_OFFSET ( 6 )#define SERIES2_PTS_LENGTH ( 16 )#define SERIES2_PTS_OFFSET ( 9 )#define AC3_PTS_LENGTH ( 16 )#define AC3_PTS_OFFSET ( 9 )#define NUMBER_DIFFERENT_AUDIO_SIZES ( 6 )static int Series1AudioWithPTS[ NUMBER_DIFFERENT_AUDIO_SIZES ] = { 336 + SERIES1_PTS_LENGTH, 480 + SERIES1_PTS_LENGTH, 576 + SERIES1_PTS_LENGTH, 768 + SERIES1_PTS_LENGTH, 864 + SERIES1_PTS_LENGTH };static int Series2AudioWithPTS[ NUMBER_DIFFERENT_AUDIO_SIZES ] = { 336 + SERIES2_PTS_LENGTH, 480 + SERIES2_PTS_LENGTH, 576 + SERIES2_PTS_LENGTH, 768 + SERIES2_PTS_LENGTH, 864 + SERIES2_PTS_LENGTH };static int IsValidAudioPacket( int size, int *ptsOffset, int *ptsLen ){ int count; *ptsOffset = 0; *ptsLen = 0; // AC-3 if ( ( size == 1550 ) || ( size == 1552 ) ) { *ptsOffset = AC3_PTS_OFFSET; *ptsLen = AC3_PTS_LENGTH; return( 1 ); } // MPEG for( count = 0 ; count < NUMBER_DIFFERENT_AUDIO_SIZES ; count++ ) { if ( size == Series1AudioWithPTS[ count ] ) { *ptsOffset = SERIES1_PTS_OFFSET; *ptsLen = SERIES1_PTS_LENGTH; break; } } if ( *ptsOffset == 0 ) { for( count = 0 ; count < NUMBER_DIFFERENT_AUDIO_SIZES ; count++ ) { if ( size == Series2AudioWithPTS[ count ] ) { *ptsOffset = SERIES2_PTS_OFFSET; *ptsLen = SERIES2_PTS_LENGTH; break; } } } if ( *ptsOffset == 0 ) { mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Tossing Audio Packet Size %d\n", size ); return( 0 ); } else { return( 1 ); }}static float get_ty_pts( unsigned char *buf ){ float result = 0; unsigned char temp; temp = ( buf[ 0 ] & 0xE ) >> 1; result = ( (float) temp ) * ( (float) ( 1L << 30 ) ) / ( (float)PTS_KHZ ); temp = buf[ 1 ]; result += ( (float) temp ) * ( (float) ( 1L << 22 ) ) / ( (float)PTS_KHZ ); temp = ( buf[ 2 ] & 0xFE ) >> 1; result += ( (float) temp ) * ( (float) ( 1L << 15 ) ) / ( (float)PTS_KHZ ); temp = buf[ 3 ]; result += ( (float) temp ) * ( (float) ( 1L << 7 ) ) / ( (float)PTS_KHZ ); temp = ( buf[ 4 ] & 0xFE ) >> 1; result += ( (float) temp ) / ( (float)PTS_MHZ ); return result;}static void demux_ty_AddToAudioBuffer( TiVoInfo *tivo, unsigned char *buffer, int size ){ if ( ( tivo->lastAudioEnd + size ) < MAX_AUDIO_BUFFER ) { memcpy( &( tivo->lastAudio[ tivo->lastAudioEnd ] ), buffer, size ); tivo->lastAudioEnd += size; } else { mp_msg( MSGT_DEMUX, MSGL_ERR, "ty:WARNING - Would have blown my audio buffer\n" ); }}static void demux_ty_CopyToDemuxPacket( int type, TiVoInfo *tivo, demux_stream_t *ds, unsigned char *buffer, int size, off_t pos, float pts ){ demux_packet_t *dp; // mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Calling ds_add_packet() %7.1f\n", pts ); // printf( "%x %x %x %x\n", // buffer[ 0 ], buffer[ 1 ], buffer[ 2 ], buffer[ 3 ] ); dp = new_demux_packet( size ); memcpy( dp->buffer, buffer, size ); dp->pts = pts; dp->pos = pos; dp->flags = 0; ds_add_packet( ds, dp ); ds->pts = pts; if ( type == TY_V ) { if ( tivo->firstVideoPTS == -1 ) { tivo->firstVideoPTS = pts; } } if ( type == TY_A ) { if ( tivo->firstAudioPTS == -1 ) { tivo->firstAudioPTS = pts; } }}static int demux_ty_FindESHeader( unsigned char *header, int headerSize, unsigned char *buffer, int bufferSize, int *esOffset1 ){ int count; *esOffset1 = -1; for( count = 0 ; count < bufferSize ; count++ ) { if ( ( buffer[ count + 0 ] == header[ 0 ] ) && ( buffer[ count + 1 ] == header[ 1 ] ) && ( buffer[ count + 2 ] == header[ 2 ] ) && ( buffer[ count + 3 ] == header[ 3 ] ) ) { *esOffset1 = count; return( 1 ); } } return( -1 );}static void demux_ty_FindESPacket( unsigned char *header, int headerSize, unsigned char *buffer, int bufferSize, int *esOffset1, int *esOffset2 ){ int count; *esOffset1 = -1; *esOffset2 = -1; for( count = 0 ; count < bufferSize ; count++ ) { if ( ( buffer[ count + 0 ] == header[ 0 ] ) && ( buffer[ count + 1 ] == header[ 1 ] ) && ( buffer[ count + 2 ] == header[ 2 ] ) && ( buffer[ count + 3 ] == header[ 3 ] ) ) { *esOffset1 = count; break; } } if ( *esOffset1 != -1 ) { for( count = *esOffset1 + 1 ; count < bufferSize ; count++ ) { if ( ( buffer[ count + 0 ] == header[ 0 ] ) && ( buffer[ count + 1 ] == header[ 1 ] ) && ( buffer[ count + 2 ] == header[ 2 ] ) && ( buffer[ count + 3 ] == header[ 3 ] ) ) { *esOffset2 = count; break; } } }}static int tivobuffer2hostlong( unsigned char *buffer ){ return ( buffer[ 0 ] << 24 | buffer[ 1 ] << 16 | buffer[ 2 ] << 8 | buffer[ 3 ] );}static unsigned char tivo_reversebyte( unsigned char val ){ int count; unsigned char ret; ret = 0; for ( count = 0 ; count < 8 ; count++ ) { ret = ret << 1; ret |= ( ( val >> count ) & 0x01 ); } return( ret );}static unsigned char ty_VideoPacket[] = { 0x00, 0x00, 0x01, 0xe0 };static unsigned char ty_MPEGAudioPacket[] = { 0x00, 0x00, 0x01, 0xc0 };static unsigned char ty_AC3AudioPacket[] = { 0x00, 0x00, 0x01, 0xbd };int demux_ty_fill_buffer( demuxer_t *demux ){ int invalidType = 0; int errorHeader = 0; int recordsDecoded = 0; off_t filePos = 0; unsigned char chunk[ CHUNKSIZE ]; int whichChunk; int readSize; unsigned int pesFileId = 0; int numberRecs; unsigned char *recPtr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -