]> git.sesse.net Git - ffmpeg/blob - libavformat/ty.c
Merge commit '91760a934055ab06812885ab5ec1a97a8db6d217'
[ffmpeg] / libavformat / ty.c
1 /*
2  * TiVo ty stream demuxer
3  * Copyright (c) 2005 VLC authors and VideoLAN
4  * Copyright (c) 2005 by Neal Symms (tivo@freakinzoo.com) - February 2005
5  * based on code by Christopher Wingert for tivo-mplayer
6  * tivo(at)wingert.org, February 2003
7  * Copyright (c) 2017 Paul B Mahol
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25
26 #include "libavutil/intreadwrite.h"
27 #include "avformat.h"
28 #include "internal.h"
29 #include "mpeg.h"
30
31 #define SERIES1_PES_LENGTH  11    /* length of audio PES hdr on S1 */
32 #define SERIES2_PES_LENGTH  16    /* length of audio PES hdr on S2 */
33 #define AC3_PES_LENGTH      14    /* length of audio PES hdr for AC3 */
34 #define VIDEO_PES_LENGTH    16    /* length of video PES header */
35 #define DTIVO_PTS_OFFSET    6     /* offs into PES for MPEG PTS on DTivo */
36 #define SA_PTS_OFFSET       9     /* offset into PES for MPEG PTS on SA */
37 #define AC3_PTS_OFFSET      9     /* offset into PES for AC3 PTS on DTivo */
38 #define VIDEO_PTS_OFFSET    9     /* offset into PES for video PTS on all */
39 #define AC3_PKT_LENGTH      1536  /* size of TiVo AC3 pkts (w/o PES hdr) */
40
41 static const uint8_t ty_VideoPacket[]     = { 0x00, 0x00, 0x01, 0xe0 };
42 static const uint8_t ty_MPEGAudioPacket[] = { 0x00, 0x00, 0x01, 0xc0 };
43 static const uint8_t ty_AC3AudioPacket[]  = { 0x00, 0x00, 0x01, 0xbd };
44
45 #define TIVO_PES_FILEID   0xf5467abd
46 #define CHUNK_SIZE        (128 * 1024)
47 #define CHUNK_PEEK_COUNT  3      /* number of chunks to probe */
48
49 typedef struct TyRecHdr {
50     int64_t   rec_size;
51     uint8_t   ex[2];
52     uint8_t   rec_type;
53     uint8_t   subrec_type;
54     uint64_t  ty_pts;            /* TY PTS in the record header */
55 } TyRecHdr;
56
57 typedef enum {
58     TIVO_TYPE_UNKNOWN,
59     TIVO_TYPE_SA,
60     TIVO_TYPE_DTIVO
61 } TiVo_type;
62
63 typedef enum {
64     TIVO_SERIES_UNKNOWN,
65     TIVO_SERIES1,
66     TIVO_SERIES2
67 } TiVo_series;
68
69 typedef enum {
70     TIVO_AUDIO_UNKNOWN,
71     TIVO_AUDIO_AC3,
72     TIVO_AUDIO_MPEG
73 } TiVo_audio;
74
75 typedef struct TySeqTable {
76     uint64_t    timestamp;
77     uint8_t     chunk_bitmask[8];
78 } TySeqTable;
79
80 typedef struct TYDemuxContext {
81     unsigned        cur_chunk;
82     unsigned        cur_chunk_pos;
83     int64_t         cur_pos;
84     TiVo_type       tivo_type;        /* TiVo type (SA / DTiVo) */
85     TiVo_series     tivo_series;      /* Series1 or Series2 */
86     TiVo_audio      audio_type;       /* AC3 or MPEG */
87     int             pes_length;       /* Length of Audio PES header */
88     int             pts_offset;       /* offset into audio PES of PTS */
89     uint8_t         pes_buffer[20];   /* holds incomplete pes headers */
90     int             pes_buf_cnt;      /* how many bytes in our buffer */
91     size_t          ac3_pkt_size;     /* length of ac3 pkt we've seen so far */
92     uint64_t        last_ty_pts;      /* last TY timestamp we've seen */
93     unsigned        seq_table_size;   /* number of entries in SEQ table */
94
95     int64_t         first_audio_pts;
96     int64_t         last_audio_pts;
97     int64_t         last_video_pts;
98
99     TyRecHdr       *rec_hdrs;         /* record headers array */
100     int             cur_rec;          /* current record in this chunk */
101     int             num_recs;         /* number of recs in this chunk */
102     int             seq_rec;          /* record number where seq start is */
103     TySeqTable     *seq_table;        /* table of SEQ entries from mstr chk */
104     int             first_chunk;
105
106     uint8_t         chunk[CHUNK_SIZE];
107 } TYDemuxContext;
108
109 static int ty_probe(AVProbeData *p)
110 {
111     int i;
112
113     for (i = 0; i + 12 < p->buf_size; i += CHUNK_SIZE) {
114         if (AV_RB32(p->buf + i) == TIVO_PES_FILEID &&
115             AV_RB32(p->buf + i + 4) == 0x02 &&
116             AV_RB32(p->buf + i + 8) == CHUNK_SIZE) {
117             return AVPROBE_SCORE_MAX;
118         }
119     }
120
121     return 0;
122 }
123
124 static TyRecHdr *parse_chunk_headers(const uint8_t *buf,
125                                      int num_recs)
126 {
127     TyRecHdr *hdrs, *rec_hdr;
128     int i;
129
130     hdrs = av_calloc(num_recs, sizeof(TyRecHdr));
131     if (!hdrs)
132         return NULL;
133
134     for (i = 0; i < num_recs; i++) {
135         const uint8_t *record_header = buf + (i * 16);
136
137         rec_hdr = &hdrs[i];     /* for brevity */
138         rec_hdr->rec_type = record_header[3];
139         rec_hdr->subrec_type = record_header[2] & 0x0f;
140         if ((record_header[0] & 0x80) == 0x80) {
141             uint8_t b1, b2;
142
143             /* marker bit 2 set, so read extended data */
144             b1 = (((record_header[0] & 0x0f) << 4) |
145                   ((record_header[1] & 0xf0) >> 4));
146             b2 = (((record_header[1] & 0x0f) << 4) |
147                   ((record_header[2] & 0xf0) >> 4));
148
149             rec_hdr->ex[0] = b1;
150             rec_hdr->ex[1] = b2;
151             rec_hdr->rec_size = 0;
152             rec_hdr->ty_pts = 0;
153         } else {
154             rec_hdr->rec_size = (record_header[0] << 8 |
155                                  record_header[1]) << 4 |
156                                 (record_header[2] >> 4);
157             rec_hdr->ty_pts = AV_RB64(&record_header[8]);
158         }
159     }
160     return hdrs;
161 }
162
163 static int find_es_header(const uint8_t *header,
164                           const uint8_t *buffer, int search_len)
165 {
166     int count;
167
168     for (count = 0; count < search_len; count++) {
169         if (!memcmp(&buffer[count], header, 4))
170             return count;
171     }
172     return -1;
173 }
174
175 static int analyze_chunk(AVFormatContext *s, const uint8_t *chunk)
176 {
177     TYDemuxContext *ty = s->priv_data;
178     int num_recs, i;
179     TyRecHdr *hdrs;
180     int num_6e0, num_be0, num_9c0, num_3c0;
181
182     /* skip if it's a Part header */
183     if (AV_RB32(&chunk[0]) == TIVO_PES_FILEID)
184         return 0;
185
186     /* number of records in chunk (we ignore high order byte;
187      * rarely are there > 256 chunks & we don't need that many anyway) */
188     num_recs = chunk[0];
189     if (num_recs < 5) {
190         /* try again with the next chunk.  Sometimes there are dead ones */
191         return 0;
192     }
193
194     chunk += 4;       /* skip past rec count & SEQ bytes */
195     ff_dlog(s, "probe: chunk has %d recs\n", num_recs);
196     hdrs = parse_chunk_headers(chunk, num_recs);
197     if (!hdrs)
198         return AVERROR(ENOMEM);
199
200     /* scan headers.
201      * 1. check video packets.  Presence of 0x6e0 means S1.
202      *    No 6e0 but have be0 means S2.
203      * 2. probe for audio 0x9c0 vs 0x3c0 (AC3 vs Mpeg)
204      *    If AC-3, then we have DTivo.
205      *    If MPEG, search for PTS offset.  This will determine SA vs. DTivo.
206      */
207     num_6e0 = num_be0 = num_9c0 = num_3c0 = 0;
208     for (i = 0; i < num_recs; i++) {
209         switch (hdrs[i].subrec_type << 8 | hdrs[i].rec_type) {
210         case 0x6e0:
211             num_6e0++;
212             break;
213         case 0xbe0:
214             num_be0++;
215             break;
216         case 0x3c0:
217             num_3c0++;
218             break;
219         case 0x9c0:
220             num_9c0++;
221             break;
222         }
223     }
224     ff_dlog(s, "probe: chunk has %d 0x6e0 recs, %d 0xbe0 recs.\n",
225             num_6e0, num_be0);
226
227     /* set up our variables */
228     if (num_6e0 > 0) {
229         ff_dlog(s, "detected Series 1 Tivo\n");
230         ty->tivo_series = TIVO_SERIES1;
231         ty->pes_length = SERIES1_PES_LENGTH;
232     } else if (num_be0 > 0) {
233         ff_dlog(s, "detected Series 2 Tivo\n");
234         ty->tivo_series = TIVO_SERIES2;
235         ty->pes_length = SERIES2_PES_LENGTH;
236     }
237     if (num_9c0 > 0) {
238         ff_dlog(s, "detected AC-3 Audio (DTivo)\n");
239         ty->audio_type = TIVO_AUDIO_AC3;
240         ty->tivo_type = TIVO_TYPE_DTIVO;
241         ty->pts_offset = AC3_PTS_OFFSET;
242         ty->pes_length = AC3_PES_LENGTH;
243     } else if (num_3c0 > 0) {
244         ty->audio_type = TIVO_AUDIO_MPEG;
245         ff_dlog(s, "detected MPEG Audio\n");
246     }
247
248     /* if tivo_type still unknown, we can check PTS location
249      * in MPEG packets to determine tivo_type */
250     if (ty->tivo_type == TIVO_TYPE_UNKNOWN) {
251         uint32_t data_offset = 16 * num_recs;
252
253         for (i = 0; i < num_recs; i++) {
254             if (data_offset + hdrs[i].rec_size > CHUNK_SIZE)
255                 break;
256
257             if ((hdrs[i].subrec_type << 0x08 | hdrs[i].rec_type) == 0x3c0 && hdrs[i].rec_size > 15) {
258                 /* first make sure we're aligned */
259                 int pes_offset = find_es_header(ty_MPEGAudioPacket,
260                         &chunk[data_offset], 5);
261                 if (pes_offset >= 0) {
262                     /* pes found. on SA, PES has hdr data at offset 6, not PTS. */
263                     if ((chunk[data_offset + 6 + pes_offset] & 0x80) == 0x80) {
264                         /* S1SA or S2(any) Mpeg Audio (PES hdr, not a PTS start) */
265                         if (ty->tivo_series == TIVO_SERIES1)
266                             ff_dlog(s, "detected Stand-Alone Tivo\n");
267                         ty->tivo_type = TIVO_TYPE_SA;
268                         ty->pts_offset = SA_PTS_OFFSET;
269                     } else {
270                         if (ty->tivo_series == TIVO_SERIES1)
271                             ff_dlog(s, "detected DirecTV Tivo\n");
272                         ty->tivo_type = TIVO_TYPE_DTIVO;
273                         ty->pts_offset = DTIVO_PTS_OFFSET;
274                     }
275                     break;
276                 }
277             }
278             data_offset += hdrs[i].rec_size;
279         }
280     }
281     av_free(hdrs);
282
283     return 0;
284 }
285
286 static int ty_read_header(AVFormatContext *s)
287 {
288     TYDemuxContext *ty = s->priv_data;
289     AVIOContext *pb = s->pb;
290     AVStream *st, *ast;
291     int i, ret = 0;
292
293     ty->first_audio_pts = AV_NOPTS_VALUE;
294     ty->last_audio_pts = AV_NOPTS_VALUE;
295     ty->last_video_pts = AV_NOPTS_VALUE;
296
297     for (i = 0; i < CHUNK_PEEK_COUNT; i++) {
298         avio_read(pb, ty->chunk, CHUNK_SIZE);
299
300         ret = analyze_chunk(s, ty->chunk);
301         if (ret < 0)
302             return ret;
303         if (ty->tivo_series != TIVO_SERIES_UNKNOWN &&
304             ty->audio_type  != TIVO_AUDIO_UNKNOWN &&
305             ty->tivo_type   != TIVO_TYPE_UNKNOWN)
306             break;
307     }
308
309     if (ty->tivo_series == TIVO_SERIES_UNKNOWN ||
310         ty->audio_type == TIVO_AUDIO_UNKNOWN ||
311         ty->tivo_type == TIVO_TYPE_UNKNOWN)
312         return AVERROR(EIO);
313
314     st = avformat_new_stream(s, NULL);
315     if (!st)
316         return AVERROR(ENOMEM);
317     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
318     st->codecpar->codec_id   = AV_CODEC_ID_MPEG2VIDEO;
319     st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
320     avpriv_set_pts_info(st, 64, 1, 90000);
321
322     ast = avformat_new_stream(s, NULL);
323     if (!ast)
324         return AVERROR(ENOMEM);
325     ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
326
327     if (ty->audio_type == TIVO_AUDIO_MPEG) {
328         ast->codecpar->codec_id = AV_CODEC_ID_MP2;
329         ast->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
330     } else {
331         ast->codecpar->codec_id = AV_CODEC_ID_AC3;
332     }
333     avpriv_set_pts_info(ast, 64, 1, 90000);
334
335     ty->first_chunk = 1;
336
337     avio_seek(pb, 0, SEEK_SET);
338
339     return 0;
340 }
341
342 /* parse a master chunk, filling the SEQ table and other variables.
343  * We assume the stream is currently pointing to it.
344  */
345 static void parse_master(AVFormatContext *s)
346 {
347     TYDemuxContext *ty = s->priv_data;
348     unsigned map_size;  /* size of bitmask, in bytes */
349     unsigned i, j;
350
351     /* Note that the entries in the SEQ table in the stream may have
352        different sizes depending on the bits per entry.  We store them
353        all in the same size structure, so we have to parse them out one
354        by one.  If we had a dynamic structure, we could simply read the
355        entire table directly from the stream into memory in place. */
356
357     /* clear the SEQ table */
358     av_freep(&ty->seq_table);
359
360     /* parse header info */
361
362     map_size = AV_RB32(ty->chunk + 20);  /* size of bitmask, in bytes */
363     i = AV_RB32(ty->chunk + 28);   /* size of SEQ table, in bytes */
364
365     ty->seq_table_size = i / (8LL + map_size);
366
367     if (ty->seq_table_size == 0) {
368         ty->seq_table = NULL;
369         return;
370     }
371
372     /* parse all the entries */
373     ty->seq_table = av_calloc(ty->seq_table_size, sizeof(TySeqTable));
374     if (ty->seq_table == NULL) {
375         ty->seq_table_size = 0;
376         return;
377     }
378
379     ty->cur_chunk_pos = 32;
380     for (j = 0; j < ty->seq_table_size; j++) {
381         ty->seq_table[j].timestamp = AV_RB64(ty->chunk + ty->cur_chunk_pos);
382         ty->cur_chunk_pos += 8;
383         if (map_size > 8) {
384             av_log(s, AV_LOG_ERROR, "Unsupported SEQ bitmap size in master chunk.\n");
385             ty->cur_chunk_pos += map_size;
386         } else {
387             memcpy(ty->seq_table[j].chunk_bitmask, ty->chunk + ty->cur_chunk_pos, map_size);
388         }
389     }
390 }
391
392 static int get_chunk(AVFormatContext *s)
393 {
394     TYDemuxContext *ty = s->priv_data;
395     AVIOContext *pb = s->pb;
396     int read_size, num_recs;
397
398     ff_dlog(s, "parsing ty chunk #%d\n", ty->cur_chunk);
399
400     /* if we have left-over filler space from the last chunk, get that */
401     if (avio_feof(pb))
402         return AVERROR_EOF;
403
404     /* read the TY packet header */
405     read_size = avio_read(pb, ty->chunk, CHUNK_SIZE);
406     ty->cur_chunk++;
407
408     if ((read_size < 4) || (AV_RB32(ty->chunk) == 0)) {
409         return AVERROR_EOF;
410     }
411
412     /* check if it's a PART Header */
413     if (AV_RB32(ty->chunk) == TIVO_PES_FILEID) {
414         parse_master(s); /* parse master chunk */
415         return get_chunk(s);
416     }
417
418     /* number of records in chunk (8- or 16-bit number) */
419     if (ty->chunk[3] & 0x80) {
420         /* 16 bit rec cnt */
421         ty->num_recs = num_recs = (ty->chunk[1] << 8) + ty->chunk[0];
422         ty->seq_rec = (ty->chunk[3] << 8) + ty->chunk[2];
423         if (ty->seq_rec != 0xffff) {
424             ty->seq_rec &= ~0x8000;
425         }
426     } else {
427         /* 8 bit reclen - TiVo 1.3 format */
428         ty->num_recs = num_recs = ty->chunk[0];
429         ty->seq_rec = ty->chunk[1];
430     }
431     ty->cur_rec = 0;
432     ty->first_chunk = 0;
433
434     ff_dlog(s, "chunk has %d records\n", num_recs);
435     ty->cur_chunk_pos = 4;
436
437     av_freep(&ty->rec_hdrs);
438
439     if (num_recs * 16 >= CHUNK_SIZE - 4)
440         return AVERROR_INVALIDDATA;
441
442     ty->rec_hdrs = parse_chunk_headers(ty->chunk + 4, num_recs);
443     ty->cur_chunk_pos += 16 * num_recs;
444
445     return 0;
446 }
447
448 static int demux_video(AVFormatContext *s, TyRecHdr *rec_hdr, AVPacket *pkt)
449 {
450     TYDemuxContext *ty = s->priv_data;
451     const int subrec_type = rec_hdr->subrec_type;
452     const int64_t rec_size = rec_hdr->rec_size;
453     int es_offset1;
454     int got_packet = 0;
455
456     if (subrec_type != 0x02 && subrec_type != 0x0c &&
457         subrec_type != 0x08 && rec_size > 4) {
458         /* get the PTS from this packet if it has one.
459          * on S1, only 0x06 has PES.  On S2, however, most all do.
460          * Do NOT Pass the PES Header to the MPEG2 codec */
461         es_offset1 = find_es_header(ty_VideoPacket, ty->chunk + ty->cur_chunk_pos, 5);
462         if (es_offset1 != -1) {
463             ty->last_video_pts = ff_parse_pes_pts(
464                     ty->chunk + ty->cur_chunk_pos + es_offset1 + VIDEO_PTS_OFFSET);
465             if (subrec_type != 0x06) {
466                 /* if we found a PES, and it's not type 6, then we're S2 */
467                 /* The packet will have video data (& other headers) so we
468                  * chop out the PES header and send the rest */
469                 if (rec_size >= VIDEO_PES_LENGTH + es_offset1) {
470                     int size = rec_hdr->rec_size - VIDEO_PES_LENGTH - es_offset1;
471
472                     ty->cur_chunk_pos += VIDEO_PES_LENGTH + es_offset1;
473                     if (av_new_packet(pkt, size) < 0)
474                         return AVERROR(ENOMEM);
475                     memcpy(pkt->data, ty->chunk + ty->cur_chunk_pos, size);
476                     ty->cur_chunk_pos += size;
477                     pkt->stream_index = 0;
478                     got_packet = 1;
479                 } else {
480                     ff_dlog(s, "video rec type 0x%02x has short PES"
481                         " (%"PRId64" bytes)\n", subrec_type, rec_size);
482                     /* nuke this block; it's too short, but has PES marker */
483                     ty->cur_chunk_pos += rec_size;
484                     return 0;
485                 }
486             }
487         }
488     }
489
490     if (subrec_type == 0x06) {
491         /* type 6 (S1 DTivo) has no data, so we're done */
492         ty->cur_chunk_pos += rec_size;
493         return 0;
494     }
495
496     if (!got_packet) {
497         if (av_new_packet(pkt, rec_size) < 0)
498             return AVERROR(ENOMEM);
499         memcpy(pkt->data, ty->chunk + ty->cur_chunk_pos, rec_size);
500         ty->cur_chunk_pos += rec_size;
501         pkt->stream_index = 0;
502         got_packet = 1;
503     }
504
505     /* if it's not a continue blk, then set PTS */
506     if (subrec_type != 0x02) {
507         if (subrec_type == 0x0c && pkt->size >= 6)
508             pkt->data[5] |= 0x08;
509         if (subrec_type == 0x07) {
510             ty->last_ty_pts = rec_hdr->ty_pts;
511         } else {
512             /* yes I know this is a cheap hack.  It's the timestamp
513                used for display and skipping fwd/back, so it
514                doesn't have to be accurate to the millisecond.
515                I adjust it here by roughly one 1/30 sec.  Yes it
516                will be slightly off for UK streams, but it's OK.
517              */
518             ty->last_ty_pts += 35000000;
519             //ty->last_ty_pts += 33366667;
520         }
521         /* set PTS for this block before we send */
522         if (ty->last_video_pts > AV_NOPTS_VALUE) {
523             pkt->pts = ty->last_video_pts;
524             /* PTS gets used ONCE.
525              * Any subsequent frames we get BEFORE next PES
526              * header will have their PTS computed in the codec */
527             ty->last_video_pts = AV_NOPTS_VALUE;
528         }
529     }
530
531     return got_packet;
532 }
533
534 static int check_sync_pes(AVFormatContext *s, AVPacket *pkt,
535                           int32_t offset, int32_t rec_len)
536 {
537     TYDemuxContext *ty = s->priv_data;
538
539     if (offset < 0 || offset + ty->pes_length > rec_len) {
540         /* entire PES header not present */
541         ff_dlog(s, "PES header at %"PRId32" not complete in record. storing.\n", offset);
542         /* save the partial pes header */
543         if (offset < 0) {
544             /* no header found, fake some 00's (this works, believe me) */
545             memset(ty->pes_buffer, 0, 4);
546             ty->pes_buf_cnt = 4;
547             if (rec_len > 4)
548                 ff_dlog(s, "PES header not found in record of %"PRId32" bytes!\n", rec_len);
549             return -1;
550         }
551         /* copy the partial pes header we found */
552         memcpy(ty->pes_buffer, pkt->data + offset, rec_len - offset);
553         ty->pes_buf_cnt = rec_len - offset;
554
555         if (offset > 0) {
556             /* PES Header was found, but not complete, so trim the end of this record */
557             pkt->size -= rec_len - offset;
558             return 1;
559         }
560         return -1;    /* partial PES, no audio data */
561     }
562     /* full PES header present, extract PTS */
563     ty->last_audio_pts = ff_parse_pes_pts(&pkt->data[ offset + ty->pts_offset]);
564     if (ty->first_audio_pts == AV_NOPTS_VALUE)
565         ty->first_audio_pts = ty->last_audio_pts;
566     pkt->pts = ty->last_audio_pts;
567     memmove(pkt->data + offset, pkt->data + offset + ty->pes_length, rec_len - ty->pes_length);
568     pkt->size -= ty->pes_length;
569     return 0;
570 }
571
572 static int demux_audio(AVFormatContext *s, TyRecHdr *rec_hdr, AVPacket *pkt)
573 {
574     TYDemuxContext *ty = s->priv_data;
575     const int subrec_type = rec_hdr->subrec_type;
576     const int64_t rec_size = rec_hdr->rec_size;
577     int es_offset1;
578
579     if (subrec_type == 2) {
580         int need = 0;
581         /* SA or DTiVo Audio Data, no PES (continued block)
582          * ================================================
583          */
584
585         /* continue PES if previous was incomplete */
586         if (ty->pes_buf_cnt > 0) {
587             need = ty->pes_length - ty->pes_buf_cnt;
588
589             ff_dlog(s, "continuing PES header\n");
590             /* do we have enough data to complete? */
591             if (need >= rec_size) {
592                 /* don't have complete PES hdr; save what we have and return */
593                 memcpy(ty->pes_buffer + ty->pes_buf_cnt, ty->chunk + ty->cur_chunk_pos, rec_size);
594                 ty->cur_chunk_pos += rec_size;
595                 ty->pes_buf_cnt += rec_size;
596                 return 0;
597             }
598
599             /* we have enough; reconstruct this frame with the new hdr */
600             memcpy(ty->pes_buffer + ty->pes_buf_cnt, ty->chunk + ty->cur_chunk_pos, need);
601             ty->cur_chunk_pos += need;
602             /* get the PTS out of this PES header (MPEG or AC3) */
603             if (ty->audio_type == TIVO_AUDIO_MPEG) {
604                 es_offset1 = find_es_header(ty_MPEGAudioPacket,
605                         ty->pes_buffer, 5);
606             } else {
607                 es_offset1 = find_es_header(ty_AC3AudioPacket,
608                         ty->pes_buffer, 5);
609             }
610             if (es_offset1 < 0) {
611                 ff_dlog(s, "Can't find audio PES header in packet.\n");
612             } else {
613                 ty->last_audio_pts = ff_parse_pes_pts(
614                     &ty->pes_buffer[es_offset1 + ty->pts_offset]);
615                 pkt->pts = ty->last_audio_pts;
616             }
617             ty->pes_buf_cnt = 0;
618
619         }
620         if (av_new_packet(pkt, rec_size - need) < 0)
621             return AVERROR(ENOMEM);
622         memcpy(pkt->data, ty->chunk + ty->cur_chunk_pos, rec_size - need);
623         ty->cur_chunk_pos += rec_size - need;
624         pkt->stream_index = 1;
625
626         /* S2 DTivo has AC3 packets with 2 padding bytes at end.  This is
627          * not allowed in the AC3 spec and will cause problems.  So here
628          * we try to trim things. */
629         /* Also, S1 DTivo has alternating short / long AC3 packets.  That
630          * is, one packet is short (incomplete) and the next packet has
631          * the first one's missing data, plus all of its own.  Strange. */
632         if (ty->audio_type == TIVO_AUDIO_AC3 &&
633                 ty->tivo_series == TIVO_SERIES2) {
634             if (ty->ac3_pkt_size + pkt->size > AC3_PKT_LENGTH) {
635                 pkt->size -= 2;
636                 ty->ac3_pkt_size = 0;
637             } else {
638                 ty->ac3_pkt_size += pkt->size;
639             }
640         }
641     } else if (subrec_type == 0x03) {
642         if (av_new_packet(pkt, rec_size) < 0)
643             return AVERROR(ENOMEM);
644         memcpy(pkt->data, ty->chunk + ty->cur_chunk_pos, rec_size);
645         ty->cur_chunk_pos += rec_size;
646         pkt->stream_index = 1;
647         /* MPEG Audio with PES Header, either SA or DTiVo   */
648         /* ================================================ */
649         es_offset1 = find_es_header(ty_MPEGAudioPacket, pkt->data, 5);
650
651         /* SA PES Header, No Audio Data                     */
652         /* ================================================ */
653         if ((es_offset1 == 0) && (rec_size == 16)) {
654             ty->last_audio_pts = ff_parse_pes_pts(&pkt->data[SA_PTS_OFFSET]);
655             if (ty->first_audio_pts == AV_NOPTS_VALUE)
656                 ty->first_audio_pts = ty->last_audio_pts;
657             av_packet_unref(pkt);
658             return 0;
659         }
660         /* DTiVo Audio with PES Header                      */
661         /* ================================================ */
662
663         /* Check for complete PES */
664         if (check_sync_pes(s, pkt, es_offset1, rec_size) == -1) {
665             /* partial PES header found, nothing else.
666              * we're done. */
667             av_packet_unref(pkt);
668             return 0;
669         }
670     } else if (subrec_type == 0x04) {
671         /* SA Audio with no PES Header                      */
672         /* ================================================ */
673         if (av_new_packet(pkt, rec_size) < 0)
674             return AVERROR(ENOMEM);
675         memcpy(pkt->data, ty->chunk + ty->cur_chunk_pos, rec_size);
676         ty->cur_chunk_pos += rec_size;
677         pkt->stream_index = 1;
678         pkt->pts = ty->last_audio_pts;
679     } else if (subrec_type == 0x09) {
680         if (av_new_packet(pkt, rec_size) < 0)
681             return AVERROR(ENOMEM);
682         memcpy(pkt->data, ty->chunk + ty->cur_chunk_pos, rec_size);
683         ty->cur_chunk_pos += rec_size ;
684         pkt->stream_index = 1;
685
686         /* DTiVo AC3 Audio Data with PES Header             */
687         /* ================================================ */
688         es_offset1 = find_es_header(ty_AC3AudioPacket, pkt->data, 5);
689
690         /* Check for complete PES */
691         if (check_sync_pes(s, pkt, es_offset1, rec_size) == -1) {
692             /* partial PES header found, nothing else.  we're done. */
693             av_packet_unref(pkt);
694             return 0;
695         }
696         /* S2 DTivo has invalid long AC3 packets */
697         if (ty->tivo_series == TIVO_SERIES2) {
698             if (pkt->size > AC3_PKT_LENGTH) {
699                 pkt->size -= 2;
700                 ty->ac3_pkt_size = 0;
701             } else {
702                 ty->ac3_pkt_size = pkt->size;
703             }
704         }
705     } else {
706         /* Unsupported/Unknown */
707         ty->cur_chunk_pos += rec_size;
708         return 0;
709     }
710
711     return 1;
712 }
713
714 static int ty_read_packet(AVFormatContext *s, AVPacket *pkt)
715 {
716     TYDemuxContext *ty = s->priv_data;
717     AVIOContext *pb = s->pb;
718     TyRecHdr *rec;
719     int64_t rec_size = 0;
720     int ret = 0;
721
722     if (avio_feof(pb))
723         return AVERROR_EOF;
724
725     while (ret <= 0) {
726         if (ty->first_chunk || ty->cur_rec >= ty->num_recs) {
727             if (get_chunk(s) < 0 || ty->num_recs == 0)
728                 return AVERROR_EOF;
729         }
730
731         rec = &ty->rec_hdrs[ty->cur_rec];
732         rec_size = rec->rec_size;
733         ty->cur_rec++;
734
735         if (rec_size <= 0)
736             continue;
737
738         if (ty->cur_chunk_pos + rec->rec_size > CHUNK_SIZE)
739             return AVERROR_INVALIDDATA;
740
741         if (avio_feof(pb))
742             return AVERROR_EOF;
743
744         switch (rec->rec_type) {
745         case VIDEO_ID:
746             ret = demux_video(s, rec, pkt);
747             break;
748         case AUDIO_ID:
749             ret = demux_audio(s, rec, pkt);
750             break;
751         default:
752             ff_dlog(s, "Invalid record type 0x%02x\n", rec->rec_type);
753         case 0x01:
754         case 0x02:
755         case 0x03: /* TiVo data services */
756         case 0x05: /* unknown, but seen regularly */
757             ty->cur_chunk_pos += rec->rec_size;
758             break;
759         }
760     }
761
762     return 0;
763 }
764
765 AVInputFormat ff_ty_demuxer = {
766     .name           = "ty",
767     .long_name      = NULL_IF_CONFIG_SMALL("TiVo TY Stream"),
768     .priv_data_size = sizeof(TYDemuxContext),
769     .read_probe     = ty_probe,
770     .read_header    = ty_read_header,
771     .read_packet    = ty_read_packet,
772     .extensions     = "ty,ty+",
773     .flags          = AVFMT_TS_DISCONT,
774 };