demux_ty.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 911 行 · 第 1/2 页

C
911
字号
   // ======================================================================   mp_msg( MSGT_DEMUX, MSGL_DBG3,      "ty:ty header size %"PRIx64"\n", (int64_t)tivo->size );   mp_msg( MSGT_DEMUX, MSGL_DBG3,      "ty:ty which Chunk %d\n", tivo->whichChunk );   mp_msg( MSGT_DEMUX, MSGL_DBG3,      "ty:file end_pos   %"PRIx64"\n", (int64_t)demux->stream->end_pos );   mp_msg( MSGT_DEMUX, MSGL_DBG3,      "\nty:wanted current offset %"PRIx64"\n", (int64_t)stream_tell( demux->stream ) );   if ( tivo->size > 0 && stream_tell( demux->stream ) > tivo->size )   {         demux->stream->eof = 1;         goto errexit;   }   do {   if ( tivo->tmf != 1 )   {      // Make sure we are on a 128k boundary      if ( demux->filepos % CHUNKSIZE != 0 )      {         int whichChunk = demux->filepos / CHUNKSIZE;         if ( demux->filepos % CHUNKSIZE > CHUNKSIZE / 2 )            whichChunk++;         stream_seek( demux->stream, whichChunk * CHUNKSIZE );      }      demux->filepos = stream_tell( demux->stream );      tivo->whichChunk = demux->filepos / CHUNKSIZE;      readSize = stream_read( demux->stream, chunk, CHUNKSIZE );      if ( readSize != CHUNKSIZE )         goto errexit;   }   else   {      readSize = tmf_load_chunk( demux, tivo, chunk, tivo->whichChunk );      if ( readSize != CHUNKSIZE )         goto errexit;      tivo->whichChunk++;   }   if (AV_RB32(chunk) == TIVO_PES_FILEID)      mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Skipping PART Header\n" );   } while (AV_RB32(chunk) == TIVO_PES_FILEID);   mp_msg( MSGT_DEMUX, MSGL_DBG3,      "\nty:actual current offset %"PRIx64"\n", stream_tell( demux->stream ) -      CHUNKSIZE );   // 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 )   {      demux_stream_t *ds = demux->video;      if( !ds->sh ) ds->sh = demux->v_streams[ aid ];   }   // ======================================================================   // Finally, we get to actually parse the chunk   // ======================================================================   mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty parsing a chunk\n" );   numberRecs = chunk[ 0 ];   recPtr = &chunk[ 4 ];   offset = numberRecs * 16 + 4;   for ( counter = 0 ; counter < numberRecs ; counter++ )   {      int size = AV_RB24(recPtr) >> 4;      int type = recPtr[ 3 ];      int 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 )         {            int esOffset1 = demux_ty_FindESHeader( VIDEO_NAL, &chunk[ offset ],               size);            if ( esOffset1 != -1 )               tivo->lastVideoPTS = get_ty_pts(                  &chunk[ offset + esOffset1 + 9 ] );            // Do NOT Pass the PES Header onto the MPEG2 Decode            if( nybbleType != 0x06 )               demux_ty_CopyToDemuxPacket( 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( 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 )               {                  demux_stream_t *ds = demux->audio;                  if( !ds->sh ) {                    sh_audio_t* sh_a;                    ds->sh = demux->a_streams[ aid ];                    sh_a = (sh_audio_t*)ds->sh;                    switch(aid & 0xE0){  // 1110 0000 b  (high 3 bit: type  low 5: id)                      case 0x00: sh_a->format=0x50;break; // mpeg                      case 0xA0: sh_a->format=0x10001;break;  // dvd pcm                      case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts                                  else sh_a->format=0x2000;break; // ac3                    }                 }               }            }            aid = demux->audio->id;            // SA DTiVo Audio Data, no PES            // ================================================            if ( nybbleType == 0x02 || nybbleType == 0x04 )            {               if ( nybbleType == 0x02 && 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( demux->audio,                     &chunk[ offset ], size, ( demux->filepos + offset ),                     tivo->lastAudioPTS );               }            }            // 3 - MPEG Audio with PES Header, either SA or DTiVo            // 9 - DTiVo AC3 Audio Data with PES Header            // ================================================            if ( nybbleType == 0x03 || nybbleType == 0x09 )            {               int esOffset1, esOffset2;               if ( nybbleType == 0x03 )               esOffset1 = demux_ty_FindESHeader( AUDIO_NAL, &chunk[ offset ],                  size);               // SA PES Header, No Audio Data               // ================================================               if ( nybbleType == 0x03 && esOffset1 == 0 && size == 16 )               {                  tivo->tivoType = 1;                  tivo->lastAudioPTS = get_ty_pts( &chunk[ offset +                     SERIES2_PTS_OFFSET ] );               }               else               // DTiVo Audio with PES Header               // ================================================               {                  tivo->tivoType = 2;                  demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size );                  demux_ty_FindESPacket( nybbleType == 9 ? AC3_NAL : AUDIO_NAL,                     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 ] );                        if (nybbleType == 9) headerSize = 0;                        demux_ty_CopyToDemuxPacket                        (                           demux->audio,                           &tivo->lastAudio[ esOffset1 + headerSize ],                           packetSize - headerSize,                           demux->filepos + offset,                           tivo->lastAudioPTS                        );                     }                     // Collapse the Audio Buffer                     tivo->lastAudioEnd -= esOffset2;                     memmove( &tivo->lastAudio[ 0 ],                        &tivo->lastAudio[ esOffset2 ],                        tivo->lastAudioEnd );                  }               }            }            offset += size;         }         else            errorHeader++;      }      // ================================================================      // 1 = Closed Caption      // 2 = Extended Data Services      // ================================================================      else if ( type == 0x01 || type == 0x02 )      {                        unsigned char lastXDS[ 16 ];         int b = AV_RB24(recPtr) >> 4;         b &= 0x7f7f;         mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:%s %04x\n", type == 1 ? "CC" : "XDS", b);         lastXDS[ 0x00 ] = 0x00;         lastXDS[ 0x01 ] = 0x00;         lastXDS[ 0x02 ] = 0x01;         lastXDS[ 0x03 ] = 0xb2;         lastXDS[ 0x04 ] = 'T';         lastXDS[ 0x05 ] = 'Y';         lastXDS[ 0x06 ] = type;         lastXDS[ 0x07 ] = b >> 8;         lastXDS[ 0x08 ] = b;         #if 0 //by dsqiu         if ( subcc_enabled )            demux_ty_CopyToDemuxPacket( demux->video, lastXDS, 0x09,               demux->filepos + offset, tivo->lastVideoPTS );         #endif      }      // ================================================================      // Unknown      // ================================================================      else      {         if ( size > 0 && size + offset <= CHUNKSIZE )            offset += size;         if (type != 3 && type != 5 && (type != 0 || size > 0)) {         mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Invalid Type %x\n", type );         invalidType++;         }      }     recPtr += 16;   }   if ( errorHeader > 0 || invalidType > 0 )   {      mp_msg( MSGT_DEMUX, MSGL_DBG3,         "ty:Error Check - Records %d, Parsed %d, Errors %d + %d\n",         numberRecs, recordsDecoded, errorHeader, invalidType );      // Invalid MPEG ES Size Check      if ( errorHeader > numberRecs / 2 )         goto errexit;      // Invalid MPEG Stream Type Check      if ( invalidType > numberRecs / 2 )         goto errexit;   }   demux->filepos = stream_tell( demux->stream );	 free(chunk);   return 1;errexit:	 free(chunk);	 return 0;}static void demux_seek_ty( demuxer_t *demuxer, float rel_seek_secs, float audio_delay, 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 = demuxer->priv;   mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Seeking to %7.1f\n", rel_seek_secs );      tivo->lastAudioEnd = 0;      tivo->lastAudioPTS = MP_NOPTS_VALUE;      tivo->lastVideoPTS = MP_NOPTS_VALUE;   //   //================= 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;   tivo->whichChunk = newpos / CHUNKSIZE;   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 );   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 0 //by dsqiu   if ( subcc_enabled )      ty_ClearOSD( 0 );#endif}static 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;         *(double *)arg=            (double)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;    }}static void demux_close_ty( demuxer_t *demux ){   TiVoInfo         *tivo = demux->priv;      free( tivo );      sub_justify = 0;}static int ty_check_file(demuxer_t* demuxer){  TiVoInfo *tivo = calloc(1, sizeof(TiVoInfo));  demuxer->priv = tivo;  return ds_fill_buffer(demuxer->video) ? DEMUXER_TYPE_MPEG_TY : 0;}static demuxer_t* demux_open_ty(demuxer_t* demuxer){    sh_audio_t *sh_audio=NULL;    sh_video_t *sh_video=NULL;    sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;    if(demuxer->audio->id!=-2) {        if(!ds_fill_buffer(demuxer->audio)){            mp_msg(MSGT_DEMUXER,MSGL_INFO,"MPEG: " MSGTR_MissingAudioStream);            demuxer->audio->sh=NULL;        } else {            sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;        }    }    return demuxer;}demuxer_desc_t demuxer_desc_mpeg_ty = {  "TiVo demuxer",  "tivo",  "TiVo",  "Christopher R. Wingert",  "Demux streams from TiVo",  DEMUXER_TYPE_MPEG_TY,  0, // unsafe autodetect  ty_check_file,  demux_ty_fill_buffer,  demux_open_ty,  demux_close_ty,  demux_seek_ty,  demux_ty_control};

⌨️ 快捷键说明

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