Mercurial > mplayer.hg
comparison libmpdemux/demux_ty.c @ 24487:f364db0d1067
Remove tabs and trailing whitespace
author | reimar |
---|---|
date | Fri, 14 Sep 2007 20:59:05 +0000 |
parents | 20a8ee3f041a |
children | d6c49e8a8046 |
comparison
equal
deleted
inserted
replaced
24486:20a8ee3f041a | 24487:f364db0d1067 |
---|---|
3 * | 3 * |
4 * Copyright (C) 2003 Christopher R. Wingert | 4 * Copyright (C) 2003 Christopher R. Wingert |
5 * | 5 * |
6 * The license covers the portions of this file regarding TiVo additions. | 6 * The license covers the portions of this file regarding TiVo additions. |
7 * | 7 * |
8 * Olaf Beck and Tridge (indirectly) were essential at providing | 8 * Olaf Beck and Tridge (indirectly) were essential at providing |
9 * information regarding the format of the TiVo streams. | 9 * information regarding the format of the TiVo streams. |
10 * | 10 * |
11 * However, no code in the following subsection is directly copied from | 11 * However, no code in the following subsection is directly copied from |
12 * either author. | 12 * either author. |
13 * | 13 * |
14 * | 14 * |
15 * This program is free software; you can redistribute it and/or | 15 * This program is free software; you can redistribute it and/or |
16 * modify it under the terms of the GNU General Public License | 16 * modify it under the terms of the GNU General Public License |
60 // 8/e0: video I-frame header start | 60 // 8/e0: video I-frame header start |
61 // a/e0: video P-frame header start | 61 // a/e0: video P-frame header start |
62 // b/e0: video B-frame header start | 62 // b/e0: video B-frame header start |
63 // c/e0: video GOP header start | 63 // c/e0: video GOP header start |
64 // e/01: closed-caption data | 64 // e/01: closed-caption data |
65 // e/02: Extended data services data | 65 // e/02: Extended data services data |
66 | 66 |
67 | 67 |
68 #define TIVO_PES_FILEID 0xf5467abd | 68 #define TIVO_PES_FILEID 0xf5467abd |
69 #define TIVO_PART_LENGTH 0x20000000 | 69 #define TIVO_PART_LENGTH 0x20000000 |
70 | 70 |
100 int64_t lastVideoPTS; | 100 int64_t lastVideoPTS; |
101 | 101 |
102 int headerOk; | 102 int headerOk; |
103 off_t size; | 103 off_t size; |
104 int readHeader; | 104 int readHeader; |
105 | 105 |
106 int tmf; | 106 int tmf; |
107 tmf_fileParts tmfparts[ MAX_TMF_PARTS ]; | 107 tmf_fileParts tmfparts[ MAX_TMF_PARTS ]; |
108 int tmf_totalparts; | 108 int tmf_totalparts; |
109 } TiVoInfo; | 109 } TiVoInfo; |
110 | 110 |
142 | 142 |
143 mp_msg( MSGT_DEMUX, MSGL_DBG3, "Dumping tar contents\n" ); | 143 mp_msg( MSGT_DEMUX, MSGL_DBG3, "Dumping tar contents\n" ); |
144 while (1) | 144 while (1) |
145 { | 145 { |
146 if (!stream_seek(demux->stream, offset)) | 146 if (!stream_seek(demux->stream, offset)) |
147 { | 147 { |
148 mp_msg( MSGT_DEMUX, MSGL_DBG3, "Seek bad %"PRId64"\n", (int64_t)offset ); | 148 mp_msg( MSGT_DEMUX, MSGL_DBG3, "Seek bad %"PRId64"\n", (int64_t)offset ); |
149 break; | 149 break; |
150 } | 150 } |
151 if (stream_read(demux->stream, header, 512) < 512) | 151 if (stream_read(demux->stream, header, 512) < 512) |
152 { | 152 { |
153 mp_msg( MSGT_DEMUX, MSGL_DBG3, "Read bad\n" ); | 153 mp_msg( MSGT_DEMUX, MSGL_DBG3, "Read bad\n" ); |
154 break; | 154 break; |
155 } | 155 } |
156 name = header; | 156 name = header; |
157 name[99] = 0; | 157 name[99] = 0; |
165 if ( offset + skip > totalsize ) | 165 if ( offset + skip > totalsize ) |
166 size = totalsize - offset; | 166 size = totalsize - offset; |
167 | 167 |
168 isty = ty_extensionis( name, ".ty" ); | 168 isty = ty_extensionis( name, ".ty" ); |
169 | 169 |
170 mp_msg( MSGT_DEMUX, MSGL_DBG3, "name %-20.20s size %-12.12s %d %d\n", | 170 mp_msg( MSGT_DEMUX, MSGL_DBG3, "name %-20.20s size %-12.12s %d %d\n", |
171 name, sizestr, size, isty ); | 171 name, sizestr, size, isty ); |
172 | 172 |
173 if ( isty ) | 173 if ( isty ) |
174 { | 174 { |
175 if ( parts >= MAX_TMF_PARTS ) { | 175 if ( parts >= MAX_TMF_PARTS ) { |
179 tivo->tmfparts[ parts ].fileNo = parts; | 179 tivo->tmfparts[ parts ].fileNo = parts; |
180 tivo->tmfparts[ parts ].fileSize = size; | 180 tivo->tmfparts[ parts ].fileSize = size; |
181 tivo->tmfparts[ parts ].startOffset = offset + 512; | 181 tivo->tmfparts[ parts ].startOffset = offset + 512; |
182 tivo->tmfparts[ parts ].chunks = size / CHUNKSIZE; | 182 tivo->tmfparts[ parts ].chunks = size / CHUNKSIZE; |
183 mp_msg | 183 mp_msg |
184 ( | 184 ( |
185 MSGT_DEMUX, MSGL_DBG3, | 185 MSGT_DEMUX, MSGL_DBG3, |
186 "tmf_filetoparts(): index %d, file %d, chunks %d\n", | 186 "tmf_filetoparts(): index %d, file %d, chunks %d\n", |
187 parts, | 187 parts, |
188 tivo->tmfparts[ parts ].fileNo, | 188 tivo->tmfparts[ parts ].fileNo, |
189 tivo->tmfparts[ parts ].chunks | 189 tivo->tmfparts[ parts ].chunks |
190 ); | 190 ); |
191 mp_msg | 191 mp_msg |
192 ( | 192 ( |
193 MSGT_DEMUX, MSGL_DBG3, | 193 MSGT_DEMUX, MSGL_DBG3, |
194 "tmf_filetoparts(): size %"PRId64"\n", | 194 "tmf_filetoparts(): size %"PRId64"\n", |
195 tivo->tmfparts[ parts ].fileSize | 195 tivo->tmfparts[ parts ].fileSize |
196 ); | 196 ); |
197 mp_msg | 197 mp_msg |
198 ( | 198 ( |
199 MSGT_DEMUX, MSGL_DBG3, | 199 MSGT_DEMUX, MSGL_DBG3, |
200 "tmf_filetoparts(): startOffset %"PRId64"\n", | 200 "tmf_filetoparts(): startOffset %"PRId64"\n", |
201 tivo->tmfparts[ parts ].startOffset | 201 tivo->tmfparts[ parts ].startOffset |
202 ); | 202 ); |
203 parts++; | 203 parts++; |
227 return -1; | 227 return -1; |
228 } | 228 } |
229 | 229 |
230 | 230 |
231 // =========================================================================== | 231 // =========================================================================== |
232 static int tmf_load_chunk( demuxer_t *demux, TiVoInfo *tivo, | 232 static int tmf_load_chunk( demuxer_t *demux, TiVoInfo *tivo, |
233 unsigned char *buff, int size, int readChunk ) | 233 unsigned char *buff, int size, int readChunk ) |
234 { | 234 { |
235 off_t fileoffset; | 235 off_t fileoffset; |
236 int count; | 236 int count; |
237 | 237 |
238 mp_msg( MSGT_DEMUX, MSGL_DBG3, "\ntmf_load_chunk() begin %d\n", | 238 mp_msg( MSGT_DEMUX, MSGL_DBG3, "\ntmf_load_chunk() begin %d\n", |
239 readChunk ); | 239 readChunk ); |
240 | 240 |
241 fileoffset = tmf_filetooffset(tivo, readChunk); | 241 fileoffset = tmf_filetooffset(tivo, readChunk); |
242 | 242 |
243 if (fileoffset == -1) { | 243 if (fileoffset == -1) { |
249 { | 249 { |
250 mp_msg( MSGT_DEMUX, MSGL_ERR, "Read past EOF()\n" ); | 250 mp_msg( MSGT_DEMUX, MSGL_ERR, "Read past EOF()\n" ); |
251 return 0; | 251 return 0; |
252 } | 252 } |
253 count = stream_read( demux->stream, buff, size ); | 253 count = stream_read( demux->stream, buff, size ); |
254 demux->filepos = stream_tell( demux->stream ); | 254 demux->filepos = stream_tell( demux->stream ); |
255 | 255 |
256 mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() count %x\n", | 256 mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() count %x\n", |
257 count ); | 257 count ); |
258 | 258 |
259 mp_msg( MSGT_DEMUX, MSGL_DBG3, | 259 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
260 "tmf_load_chunk() bytes %x %x %x %x %x %x %x %x\n", | 260 "tmf_load_chunk() bytes %x %x %x %x %x %x %x %x\n", |
261 buff[ 0 ], buff[ 1 ], buff[ 2 ], buff[ 3 ], | 261 buff[ 0 ], buff[ 1 ], buff[ 2 ], buff[ 3 ], |
262 buff[ 4 ], buff[ 5 ], buff[ 6 ], buff[ 7 ] ); | 262 buff[ 4 ], buff[ 5 ], buff[ 6 ], buff[ 7 ] ); |
263 | 263 |
264 mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() end\n" ); | 264 mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() end\n" ); |
265 | 265 |
266 return count; | 266 return count; |
267 } | 267 } |
268 | 268 |
269 // =========================================================================== | 269 // =========================================================================== |
270 | 270 |
303 { | 303 { |
304 *ptsOffset = SERIES2_PTS_OFFSET; | 304 *ptsOffset = SERIES2_PTS_OFFSET; |
305 *ptsLen = SERIES2_PTS_LENGTH; | 305 *ptsLen = SERIES2_PTS_LENGTH; |
306 return 1; | 306 return 1; |
307 } | 307 } |
308 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Tossing Audio Packet Size %d\n", | 308 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Tossing Audio Packet Size %d\n", |
309 size ); | 309 size ); |
310 return 0; | 310 return 0; |
311 } | 311 } |
312 | 312 |
313 | 313 |
321 return MP_NOPTS_VALUE; | 321 return MP_NOPTS_VALUE; |
322 a >>= 1; b >>= 1; c >>= 1; | 322 a >>= 1; b >>= 1; c >>= 1; |
323 return (((uint64_t)a) << 30) | (b << 15) | c; | 323 return (((uint64_t)a) << 30) | (b << 15) | c; |
324 } | 324 } |
325 | 325 |
326 static void demux_ty_AddToAudioBuffer( TiVoInfo *tivo, unsigned char *buffer, | 326 static void demux_ty_AddToAudioBuffer( TiVoInfo *tivo, unsigned char *buffer, |
327 int size ) | 327 int size ) |
328 { | 328 { |
329 if ( tivo->lastAudioEnd + size < MAX_AUDIO_BUFFER ) | 329 if ( tivo->lastAudioEnd + size < MAX_AUDIO_BUFFER ) |
330 { | 330 { |
331 memcpy( &tivo->lastAudio[ tivo->lastAudioEnd ], | 331 memcpy( &tivo->lastAudio[ tivo->lastAudioEnd ], |
332 buffer, size ); | 332 buffer, size ); |
333 tivo->lastAudioEnd += size; | 333 tivo->lastAudioEnd += size; |
334 } | 334 } |
335 else | 335 else |
336 mp_msg( MSGT_DEMUX, MSGL_ERR, | 336 mp_msg( MSGT_DEMUX, MSGL_ERR, |
337 "ty:WARNING - Would have blown my audio buffer\n" ); | 337 "ty:WARNING - Would have blown my audio buffer\n" ); |
338 } | 338 } |
339 | 339 |
340 static void demux_ty_CopyToDemuxPacket( int type, TiVoInfo *tivo, demux_stream_t *ds, | 340 static void demux_ty_CopyToDemuxPacket( int type, TiVoInfo *tivo, demux_stream_t *ds, |
341 unsigned char *buffer, int size, off_t pos, float pts ) | 341 unsigned char *buffer, int size, off_t pos, float pts ) |
342 { | 342 { |
343 demux_packet_t *dp = new_demux_packet( size ); | 343 demux_packet_t *dp = new_demux_packet( size ); |
344 memcpy( dp->buffer, buffer, size ); | 344 memcpy( dp->buffer, buffer, size ); |
345 if (pts != MP_NOPTS_VALUE) | 345 if (pts != MP_NOPTS_VALUE) |
346 dp->pts = pts / 90000.0; | 346 dp->pts = pts / 90000.0; |
347 dp->pos = pos; | 347 dp->pos = pos; |
348 dp->flags = 0; | 348 dp->flags = 0; |
349 ds_add_packet( ds, dp ); | 349 ds_add_packet( ds, dp ); |
350 if ( type == TY_V && tivo->firstVideoPTS == MP_NOPTS_VALUE ) | 350 if ( type == TY_V && tivo->firstVideoPTS == MP_NOPTS_VALUE ) |
351 tivo->firstVideoPTS = pts; | 351 tivo->firstVideoPTS = pts; |
352 if ( type == TY_A && tivo->firstAudioPTS == MP_NOPTS_VALUE ) | 352 if ( type == TY_A && tivo->firstAudioPTS == MP_NOPTS_VALUE ) |
353 tivo->firstAudioPTS = pts; | 353 tivo->firstAudioPTS = pts; |
354 } | 354 } |
355 | 355 |
356 static int demux_ty_FindESHeader( uint8_t nal, | 356 static int demux_ty_FindESHeader( uint8_t nal, |
357 unsigned char *buffer, int bufferSize ) | 357 unsigned char *buffer, int bufferSize ) |
358 { | 358 { |
367 return p - buffer - 4; | 367 return p - buffer - 4; |
368 } | 368 } |
369 return -1; | 369 return -1; |
370 } | 370 } |
371 | 371 |
372 static void demux_ty_FindESPacket( uint8_t nal, | 372 static void demux_ty_FindESPacket( uint8_t nal, |
373 unsigned char *buffer, int bufferSize, int *esOffset1, int *esOffset2 ) | 373 unsigned char *buffer, int bufferSize, int *esOffset1, int *esOffset2 ) |
374 { | 374 { |
375 *esOffset1 = demux_ty_FindESHeader(nal, buffer, bufferSize); | 375 *esOffset1 = demux_ty_FindESHeader(nal, buffer, bufferSize); |
376 if (*esOffset1 == -1) { | 376 if (*esOffset1 == -1) { |
377 *esOffset2 = -1; | 377 *esOffset2 = -1; |
402 int offset; | 402 int offset; |
403 | 403 |
404 int counter; | 404 int counter; |
405 | 405 |
406 int aid; | 406 int aid; |
407 | 407 |
408 TiVoInfo *tivo = demux->priv; | 408 TiVoInfo *tivo = demux->priv; |
409 | 409 |
410 if ( demux->stream->type == STREAMTYPE_DVD ) | 410 if ( demux->stream->type == STREAMTYPE_DVD ) |
411 return 0; | 411 return 0; |
412 | 412 |
413 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty processing\n" ); | 413 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty processing\n" ); |
414 | 414 |
415 if( demux->stream->eof ) return 0; | 415 if( demux->stream->eof ) return 0; |
416 | 416 |
417 // ====================================================================== | 417 // ====================================================================== |
418 // If we haven't figured out the size of the stream, let's do so | 418 // If we haven't figured out the size of the stream, let's do so |
419 // ====================================================================== | 419 // ====================================================================== |
420 #ifdef STREAMTYPE_STREAM_TY | 420 #ifdef STREAMTYPE_STREAM_TY |
421 if ( demux->stream->type == STREAMTYPE_STREAM_TY ) | 421 if ( demux->stream->type == STREAMTYPE_STREAM_TY ) |
454 if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID ) | 454 if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID ) |
455 { | 455 { |
456 off_t numberParts; | 456 off_t numberParts; |
457 | 457 |
458 readSize = 0; | 458 readSize = 0; |
459 | 459 |
460 if ( tivo->tmf != 1 ) | 460 if ( tivo->tmf != 1 ) |
461 { | 461 { |
462 off_t offset; | 462 off_t offset; |
463 | 463 |
464 numberParts = demux->stream->end_pos / TIVO_PART_LENGTH; | 464 numberParts = demux->stream->end_pos / TIVO_PART_LENGTH; |
475 } | 475 } |
476 else | 476 else |
477 { | 477 { |
478 numberParts = tivo->tmf_totalparts; | 478 numberParts = tivo->tmf_totalparts; |
479 offset = numberParts * TIVO_PART_LENGTH; | 479 offset = numberParts * TIVO_PART_LENGTH; |
480 readSize = tmf_load_chunk( demux, tivo, chunk, CHUNKSIZE, | 480 readSize = tmf_load_chunk( demux, tivo, chunk, CHUNKSIZE, |
481 numberParts * ( TIVO_PART_LENGTH - CHUNKSIZE ) / | 481 numberParts * ( TIVO_PART_LENGTH - CHUNKSIZE ) / |
482 CHUNKSIZE ); | 482 CHUNKSIZE ); |
483 } | 483 } |
484 | 484 |
485 if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID ) | 485 if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID ) |
486 { | 486 { |
487 int size = AV_RB24(chunk + 12); | 487 int size = AV_RB24(chunk + 12); |
488 size -= 4; | 488 size -= 4; |
489 size *= CHUNKSIZE; | 489 size *= CHUNKSIZE; |
490 tivo->size = numberParts * TIVO_PART_LENGTH; | 490 tivo->size = numberParts * TIVO_PART_LENGTH; |
491 tivo->size += size; | 491 tivo->size += size; |
492 mp_msg( MSGT_DEMUX, MSGL_DBG3, | 492 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
493 "ty:Header Calc Stream Size %"PRId64"\n", tivo->size ); | 493 "ty:Header Calc Stream Size %"PRId64"\n", tivo->size ); |
494 } | 494 } |
495 } | 495 } |
496 if ( tivo->size > demux->stream->end_pos ) | 496 if ( tivo->size > demux->stream->end_pos ) |
497 tivo->size = demux->stream->end_pos; | 497 tivo->size = demux->stream->end_pos; |
498 | 498 |
499 if ( demux->stream->start_pos > 0 ) | 499 if ( demux->stream->start_pos > 0 ) |
500 filePos = demux->stream->start_pos; | 500 filePos = demux->stream->start_pos; |
501 stream_seek( demux->stream, filePos ); | 501 stream_seek( demux->stream, filePos ); |
502 demux->filepos = stream_tell( demux->stream ); | 502 demux->filepos = stream_tell( demux->stream ); |
503 tivo->whichChunk = filePos / CHUNKSIZE; | 503 tivo->whichChunk = filePos / CHUNKSIZE; |
504 } | 504 } |
505 demux->movi_start = 0; | 505 demux->movi_start = 0; |
506 demux->movi_end = tivo->size; | 506 demux->movi_end = tivo->size; |
507 } | 507 } |
541 if ( readSize != CHUNKSIZE ) | 541 if ( readSize != CHUNKSIZE ) |
542 return 0; | 542 return 0; |
543 } | 543 } |
544 else | 544 else |
545 { | 545 { |
546 readSize = tmf_load_chunk( demux, tivo, chunk, CHUNKSIZE, | 546 readSize = tmf_load_chunk( demux, tivo, chunk, CHUNKSIZE, |
547 tivo->whichChunk ); | 547 tivo->whichChunk ); |
548 if ( readSize != CHUNKSIZE ) | 548 if ( readSize != CHUNKSIZE ) |
549 return 0; | 549 return 0; |
550 tivo->whichChunk++; | 550 tivo->whichChunk++; |
551 } | 551 } |
559 demux->filepos = stream_tell( demux->stream ); | 559 demux->filepos = stream_tell( demux->stream ); |
560 readSize = stream_read( demux->stream, chunk, CHUNKSIZE ); | 560 readSize = stream_read( demux->stream, chunk, CHUNKSIZE ); |
561 } | 561 } |
562 else | 562 else |
563 { | 563 { |
564 readSize = tmf_load_chunk( demux, tivo, chunk, CHUNKSIZE, | 564 readSize = tmf_load_chunk( demux, tivo, chunk, CHUNKSIZE, |
565 tivo->whichChunk ); | 565 tivo->whichChunk ); |
566 tivo->whichChunk++; | 566 tivo->whichChunk++; |
567 } | 567 } |
568 | 568 |
569 if ( readSize != CHUNKSIZE ) | 569 if ( readSize != CHUNKSIZE ) |
570 return 0; | 570 return 0; |
571 } | 571 } |
572 mp_msg( MSGT_DEMUX, MSGL_DBG3, | 572 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
573 "\nty:actual current offset %"PRIx64"\n", stream_tell( demux->stream ) - | 573 "\nty:actual current offset %"PRIx64"\n", stream_tell( demux->stream ) - |
574 CHUNKSIZE ); | 574 CHUNKSIZE ); |
575 | 575 |
576 | 576 |
577 // Let's make a Video Demux Stream for MPlayer | 577 // Let's make a Video Demux Stream for MPlayer |
578 aid = 0x0; | 578 aid = 0x0; |
579 if( !demux->v_streams[ aid ] ) new_sh_video( demux, aid ); | 579 if( !demux->v_streams[ aid ] ) new_sh_video( demux, aid ); |
606 // ================================================================ | 606 // ================================================================ |
607 if ( type == 0xe0 ) | 607 if ( type == 0xe0 ) |
608 { | 608 { |
609 if ( size > 0 && size + offset <= CHUNKSIZE ) | 609 if ( size > 0 && size + offset <= CHUNKSIZE ) |
610 { | 610 { |
611 int esOffset1 = demux_ty_FindESHeader( VIDEO_NAL, &chunk[ offset ], | 611 int esOffset1 = demux_ty_FindESHeader( VIDEO_NAL, &chunk[ offset ], |
612 size); | 612 size); |
613 if ( esOffset1 != -1 ) | 613 if ( esOffset1 != -1 ) |
614 tivo->lastVideoPTS = get_ty_pts( | 614 tivo->lastVideoPTS = get_ty_pts( |
615 &chunk[ offset + esOffset1 + 9 ] ); | 615 &chunk[ offset + esOffset1 + 9 ] ); |
616 | 616 |
617 // Do NOT Pass the PES Header onto the MPEG2 Decode | 617 // Do NOT Pass the PES Header onto the MPEG2 Decode |
618 if( nybbleType != 0x06 ) | 618 if( nybbleType != 0x06 ) |
619 demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, | 619 demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, |
620 &chunk[ offset ], size, demux->filepos + offset, | 620 &chunk[ offset ], size, demux->filepos + offset, |
621 tivo->lastVideoPTS ); | 621 tivo->lastVideoPTS ); |
622 offset += size; | 622 offset += size; |
623 } | 623 } |
624 else | 624 else |
625 errorHeader++; | 625 errorHeader++; |
626 } | 626 } |
627 // ================================================================ | 627 // ================================================================ |
628 // Audio Parsing | 628 // Audio Parsing |
629 // ================================================================ | 629 // ================================================================ |
630 else if ( type == 0xc0 ) | 630 else if ( type == 0xc0 ) |
631 { | 631 { |
632 if ( size > 0 && size + offset <= CHUNKSIZE ) | 632 if ( size > 0 && size + offset <= CHUNKSIZE ) |
633 { | 633 { |
634 if( demux->audio->id == -1 ) | 634 if( demux->audio->id == -1 ) |
635 { | 635 { |
677 else | 677 else |
678 { | 678 { |
679 | 679 |
680 mp_msg( MSGT_DEMUX, MSGL_DBG3, | 680 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
681 "ty:Adding Audio Packet Size %d\n", size ); | 681 "ty:Adding Audio Packet Size %d\n", size ); |
682 demux_ty_CopyToDemuxPacket( TY_A, tivo, demux->audio, | 682 demux_ty_CopyToDemuxPacket( TY_A, tivo, demux->audio, |
683 &chunk[ offset ], size, ( demux->filepos + offset ), | 683 &chunk[ offset ], size, ( demux->filepos + offset ), |
684 tivo->lastAudioPTS ); | 684 tivo->lastAudioPTS ); |
685 } | 685 } |
686 } | 686 } |
687 | 687 |
688 // 3 - MPEG Audio with PES Header, either SA or DTiVo | 688 // 3 - MPEG Audio with PES Header, either SA or DTiVo |
689 // 9 - DTiVo AC3 Audio Data with PES Header | 689 // 9 - DTiVo AC3 Audio Data with PES Header |
690 // ================================================ | 690 // ================================================ |
691 if ( nybbleType == 0x03 || nybbleType == 0x09 ) | 691 if ( nybbleType == 0x03 || nybbleType == 0x09 ) |
692 { | 692 { |
693 int esOffset1, esOffset2; | 693 int esOffset1, esOffset2; |
694 if ( nybbleType == 0x03 ) | 694 if ( nybbleType == 0x03 ) |
695 esOffset1 = demux_ty_FindESHeader( AUDIO_NAL, &chunk[ offset ], | 695 esOffset1 = demux_ty_FindESHeader( AUDIO_NAL, &chunk[ offset ], |
696 size); | 696 size); |
697 | 697 |
698 // SA PES Header, No Audio Data | 698 // SA PES Header, No Audio Data |
699 // ================================================ | 699 // ================================================ |
700 if ( nybbleType == 0x03 && esOffset1 == 0 && size == 16 ) | 700 if ( nybbleType == 0x03 && esOffset1 == 0 && size == 16 ) |
701 { | 701 { |
702 tivo->tivoType = 1; | 702 tivo->tivoType = 1; |
703 tivo->lastAudioPTS = get_ty_pts( &chunk[ offset + | 703 tivo->lastAudioPTS = get_ty_pts( &chunk[ offset + |
704 SERIES2_PTS_OFFSET ] ); | 704 SERIES2_PTS_OFFSET ] ); |
705 } | 705 } |
706 else | 706 else |
707 // DTiVo Audio with PES Header | 707 // DTiVo Audio with PES Header |
708 // ================================================ | 708 // ================================================ |
718 { | 718 { |
719 int packetSize = esOffset2 - esOffset1; | 719 int packetSize = esOffset2 - esOffset1; |
720 int headerSize; | 720 int headerSize; |
721 int ptsOffset; | 721 int ptsOffset; |
722 | 722 |
723 if ( IsValidAudioPacket( packetSize, &ptsOffset, | 723 if ( IsValidAudioPacket( packetSize, &ptsOffset, |
724 &headerSize ) ) | 724 &headerSize ) ) |
725 { | 725 { |
726 mp_msg( MSGT_DEMUX, MSGL_DBG3, | 726 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
727 "ty:Adding DTiVo Audio Packet Size %d\n", | 727 "ty:Adding DTiVo Audio Packet Size %d\n", |
728 packetSize ); | 728 packetSize ); |
729 | 729 |
730 tivo->lastAudioPTS = get_ty_pts( | 730 tivo->lastAudioPTS = get_ty_pts( |
731 &tivo->lastAudio[ esOffset1 + ptsOffset ] ); | 731 &tivo->lastAudio[ esOffset1 + ptsOffset ] ); |
732 | 732 |
733 if (nybbleType == 9) headerSize = 0; | 733 if (nybbleType == 9) headerSize = 0; |
734 demux_ty_CopyToDemuxPacket | 734 demux_ty_CopyToDemuxPacket |
735 ( | 735 ( |
736 TY_A, | 736 TY_A, |
737 tivo, | 737 tivo, |
738 demux->audio, | 738 demux->audio, |
739 &tivo->lastAudio[ esOffset1 + headerSize ], | 739 &tivo->lastAudio[ esOffset1 + headerSize ], |
740 packetSize - headerSize, | 740 packetSize - headerSize, |
741 demux->filepos + offset, | 741 demux->filepos + offset, |
742 tivo->lastAudioPTS | 742 tivo->lastAudioPTS |
743 ); | 743 ); |
744 | 744 |
745 } | 745 } |
746 | 746 |
747 // Collapse the Audio Buffer | 747 // Collapse the Audio Buffer |
748 tivo->lastAudioEnd -= esOffset2; | 748 tivo->lastAudioEnd -= esOffset2; |
749 memmove( &tivo->lastAudio[ 0 ], | 749 memmove( &tivo->lastAudio[ 0 ], |
750 &tivo->lastAudio[ esOffset2 ], | 750 &tivo->lastAudio[ esOffset2 ], |
751 tivo->lastAudioEnd ); | 751 tivo->lastAudioEnd ); |
752 } | 752 } |
753 } | 753 } |
754 } | 754 } |
755 | 755 |
756 offset += size; | 756 offset += size; |
757 } | 757 } |
758 else | 758 else |
759 errorHeader++; | 759 errorHeader++; |
760 } | 760 } |
761 // ================================================================ | 761 // ================================================================ |
762 // 1 = Closed Caption | 762 // 1 = Closed Caption |
763 // 2 = Extended Data Services | 763 // 2 = Extended Data Services |
764 // ================================================================ | 764 // ================================================================ |
765 else if ( type == 0x01 || type == 0x02 ) | 765 else if ( type == 0x01 || type == 0x02 ) |
766 { | 766 { |
767 unsigned char lastXDS[ 16 ]; | 767 unsigned char lastXDS[ 16 ]; |
768 int b = AV_RB24(recPtr) >> 4; | 768 int b = AV_RB24(recPtr) >> 4; |
769 b &= 0x7f7f; | 769 b &= 0x7f7f; |
770 | 770 |
771 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:%s %04x\n", type == 1 ? "CC" : "XDS", b); | 771 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:%s %04x\n", type == 1 ? "CC" : "XDS", b); |
772 | 772 |
773 lastXDS[ 0x00 ] = 0x00; | 773 lastXDS[ 0x00 ] = 0x00; |
774 lastXDS[ 0x01 ] = 0x00; | 774 lastXDS[ 0x01 ] = 0x00; |
775 lastXDS[ 0x02 ] = 0x01; | 775 lastXDS[ 0x02 ] = 0x01; |
776 lastXDS[ 0x03 ] = 0xb2; | 776 lastXDS[ 0x03 ] = 0xb2; |
777 lastXDS[ 0x04 ] = 'T'; | 777 lastXDS[ 0x04 ] = 'T'; |
778 lastXDS[ 0x05 ] = 'Y'; | 778 lastXDS[ 0x05 ] = 'Y'; |
779 lastXDS[ 0x06 ] = type; | 779 lastXDS[ 0x06 ] = type; |
780 lastXDS[ 0x07 ] = b >> 8; | 780 lastXDS[ 0x07 ] = b >> 8; |
781 lastXDS[ 0x08 ] = b; | 781 lastXDS[ 0x08 ] = b; |
782 if ( subcc_enabled ) | 782 if ( subcc_enabled ) |
783 demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, lastXDS, 0x09, | 783 demux_ty_CopyToDemuxPacket( TY_V, tivo, demux->video, lastXDS, 0x09, |
784 demux->filepos + offset, tivo->lastVideoPTS ); | 784 demux->filepos + offset, tivo->lastVideoPTS ); |
785 } | 785 } |
786 // ================================================================ | 786 // ================================================================ |
787 // Unknown | 787 // Unknown |
788 // ================================================================ | 788 // ================================================================ |
789 else | 789 else |
790 { | 790 { |
791 if ( size > 0 && size + offset <= CHUNKSIZE ) | 791 if ( size > 0 && size + offset <= CHUNKSIZE ) |
792 offset += size; | 792 offset += size; |
793 if (type != 3 && type != 5) { | 793 if (type != 3 && type != 5) { |
794 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Invalid Type %x\n", type ); | 794 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Invalid Type %x\n", type ); |
795 invalidType++; | 795 invalidType++; |
796 } | 796 } |
797 } | 797 } |
798 recPtr += 16; | 798 recPtr += 16; |
799 } | 799 } |
800 | 800 |
801 if ( errorHeader > 0 || invalidType > 0 ) | 801 if ( errorHeader > 0 || invalidType > 0 ) |
802 { | 802 { |
803 mp_msg( MSGT_DEMUX, MSGL_DBG3, | 803 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
804 "ty:Error Check - Records %d, Parsed %d, Errors %d + %d\n", | 804 "ty:Error Check - Records %d, Parsed %d, Errors %d + %d\n", |
805 numberRecs, recordsDecoded, errorHeader, invalidType ); | 805 numberRecs, recordsDecoded, errorHeader, invalidType ); |
806 | 806 |
807 // Invalid MPEG ES Size Check | 807 // Invalid MPEG ES Size Check |
808 if ( errorHeader > numberRecs / 2 ) | 808 if ( errorHeader > numberRecs / 2 ) |
836 // | 836 // |
837 //================= seek in MPEG ========================== | 837 //================= seek in MPEG ========================== |
838 demuxer->filepos = stream_tell( demuxer->stream ); | 838 demuxer->filepos = stream_tell( demuxer->stream ); |
839 | 839 |
840 newpos = ( flags & 1 ) ? demuxer->movi_start : demuxer->filepos; | 840 newpos = ( flags & 1 ) ? demuxer->movi_start : demuxer->filepos; |
841 | 841 |
842 if( flags & 2 ) | 842 if( flags & 2 ) |
843 // float seek 0..1 | 843 // float seek 0..1 |
844 newpos += ( demuxer->movi_end - demuxer->movi_start ) * rel_seek_secs; | 844 newpos += ( demuxer->movi_end - demuxer->movi_start ) * rel_seek_secs; |
845 else | 845 else |
846 { | 846 { |
847 // time seek (secs) | 847 // time seek (secs) |
848 if( ! sh_video->i_bps ) // unspecified or VBR | 848 if( ! sh_video->i_bps ) // unspecified or VBR |
849 newpos += 2324 * 75 * rel_seek_secs; // 174.3 kbyte/sec | 849 newpos += 2324 * 75 * rel_seek_secs; // 174.3 kbyte/sec |
850 else | 850 else |
851 newpos += sh_video->i_bps * rel_seek_secs; | 851 newpos += sh_video->i_bps * rel_seek_secs; |
852 } | 852 } |
853 | 853 |
854 if ( newpos < demuxer->movi_start ) | 854 if ( newpos < demuxer->movi_start ) |
855 { | 855 { |
856 if( demuxer->stream->type != STREAMTYPE_VCD ) demuxer->movi_start = 0; | 856 if( demuxer->stream->type != STREAMTYPE_VCD ) demuxer->movi_start = 0; |
857 if( newpos < demuxer->movi_start ) newpos = demuxer->movi_start; | 857 if( newpos < demuxer->movi_start ) newpos = demuxer->movi_start; |
858 } | 858 } |
859 | 859 |
860 res = newpos / CHUNKSIZE; | 860 res = newpos / CHUNKSIZE; |
861 if ( rel_seek_secs >= 0 ) | 861 if ( rel_seek_secs >= 0 ) |
862 newpos = ( res + 1 ) * CHUNKSIZE; | 862 newpos = ( res + 1 ) * CHUNKSIZE; |
863 else | 863 else |
871 stream_seek( demuxer->stream, newpos ); | 871 stream_seek( demuxer->stream, newpos ); |
872 | 872 |
873 // re-sync video: | 873 // re-sync video: |
874 videobuf_code_len = 0; // reset ES stream buffer | 874 videobuf_code_len = 0; // reset ES stream buffer |
875 | 875 |
876 ds_fill_buffer( d_video ); | 876 ds_fill_buffer( d_video ); |
877 if( sh_audio ) | 877 if( sh_audio ) |
878 ds_fill_buffer( d_audio ); | 878 ds_fill_buffer( d_audio ); |
879 | 879 |
880 while( 1 ) | 880 while( 1 ) |
881 { | 881 { |
882 int i; | 882 int i; |
883 if( sh_audio && !d_audio->eof && d_video->pts && d_audio->pts ) | 883 if( sh_audio && !d_audio->eof && d_video->pts && d_audio->pts ) |
884 { | 884 { |
885 float a_pts = d_audio->pts; | 885 float a_pts = d_audio->pts; |
886 a_pts += ( ds_tell_pts( d_audio ) - sh_audio->a_in_buffer_len ) / | 886 a_pts += ( ds_tell_pts( d_audio ) - sh_audio->a_in_buffer_len ) / |
887 (float)sh_audio->i_bps; | 887 (float)sh_audio->i_bps; |
888 if( d_video->pts > a_pts ) | 888 if( d_video->pts > a_pts ) |
889 { | 889 { |
890 skip_audio_frame( sh_audio ); // sync audio | 890 skip_audio_frame( sh_audio ); // sync audio |
891 continue; | 891 continue; |
892 } | 892 } |
893 } | 893 } |
894 i = sync_video_packet( d_video ); | 894 i = sync_video_packet( d_video ); |
895 if( i == 0x1B3 || i == 0x1B8 ) break; // found it! | 895 if( i == 0x1B3 || i == 0x1B8 ) break; // found it! |
896 if( !i || !skip_video_packet( d_video ) ) break; // EOF? | 896 if( !i || !skip_video_packet( d_video ) ) break; // EOF? |
897 } | 897 } |
898 if ( subcc_enabled ) | 898 if ( subcc_enabled ) |
899 ty_ClearOSD( 0 ); | 899 ty_ClearOSD( 0 ); |
900 } | 900 } |
901 | 901 |
902 static int demux_ty_control( demuxer_t *demuxer,int cmd, void *arg ) | 902 static int demux_ty_control( demuxer_t *demuxer,int cmd, void *arg ) |
903 { | 903 { |
904 demux_stream_t *d_video = demuxer->video; | 904 demux_stream_t *d_video = demuxer->video; |
905 sh_video_t *sh_video = d_video->sh; | 905 sh_video_t *sh_video = d_video->sh; |
906 | 906 |
907 switch(cmd) | 907 switch(cmd) |
908 { | 908 { |
909 case DEMUXER_CTRL_GET_TIME_LENGTH: | 909 case DEMUXER_CTRL_GET_TIME_LENGTH: |
910 if(!sh_video->i_bps) // unspecified or VBR | 910 if(!sh_video->i_bps) // unspecified or VBR |
911 return DEMUXER_CTRL_DONTKNOW; | 911 return DEMUXER_CTRL_DONTKNOW; |
912 *(double *)arg= | 912 *(double *)arg= |
913 (double)demuxer->movi_end-demuxer->movi_start/sh_video->i_bps; | 913 (double)demuxer->movi_end-demuxer->movi_start/sh_video->i_bps; |
914 return DEMUXER_CTRL_GUESS; | 914 return DEMUXER_CTRL_GUESS; |
915 | 915 |
916 case DEMUXER_CTRL_GET_PERCENT_POS: | 916 case DEMUXER_CTRL_GET_PERCENT_POS: |
917 return DEMUXER_CTRL_DONTKNOW; | 917 return DEMUXER_CTRL_DONTKNOW; |
918 default: | 918 default: |
919 return DEMUXER_CTRL_NOTIMPL; | 919 return DEMUXER_CTRL_NOTIMPL; |
920 } | 920 } |
921 } | 921 } |
922 | 922 |
923 | 923 |
924 static void demux_close_ty( demuxer_t *demux ) | 924 static void demux_close_ty( demuxer_t *demux ) |
925 { | 925 { |
926 TiVoInfo *tivo = demux->priv; | 926 TiVoInfo *tivo = demux->priv; |
927 | 927 |
928 free( tivo ); | 928 free( tivo ); |
929 sub_justify = 0; | 929 sub_justify = 0; |
930 } | 930 } |
931 | 931 |
932 | 932 |
933 static int ty_check_file(demuxer_t* demuxer) | 933 static int ty_check_file(demuxer_t* demuxer) |
934 { | 934 { |