Mercurial > mplayer.hg
annotate libmpdemux/demux_ty.c @ 36441:b75ebb89d803
Workaround VDPAU decode errors on aspect change on NVidia.
The NVidia driver seems to expect a decoder reinit on aspect
change, otherwise giving a nonsense VDP_STATUS_INVALID_SIZE
error.
Since decode and display can run out of sync, we do not in fact
know when an aspect change will happen during decode but only when
we want to display that decoded frame, and with threaded decoding
these will differ significantly.
So just catch the error and retry decoding instead, this also has
the advantage of not affecting (and possibly costing performance)
drivers without this issue.
author | reimar |
---|---|
date | Sun, 08 Dec 2013 15:07:00 +0000 |
parents | 9ed8b7b1b94a |
children | 92dd1764392a |
rev | line source |
---|---|
10263 | 1 /* |
2 * tivo@wingert.org, February 2003 | |
3 * | |
4 * Copyright (C) 2003 Christopher R. Wingert | |
5 * | |
6 * The license covers the portions of this file regarding TiVo additions. | |
7 * | |
24487 | 8 * Olaf Beck and Tridge (indirectly) were essential at providing |
9 * information regarding the format of the TiVo streams. | |
10263 | 10 * |
24487 | 11 * However, no code in the following subsection is directly copied from |
10263 | 12 * either author. |
13 * | |
26742
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25883
diff
changeset
|
14 * This file is part of MPlayer. |
10263 | 15 * |
26742
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25883
diff
changeset
|
16 * MPlayer is free software; you can redistribute it and/or modify |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25883
diff
changeset
|
17 * it under the terms of the GNU General Public License as published by |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25883
diff
changeset
|
18 * the Free Software Foundation; either version 2 of the License, or |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25883
diff
changeset
|
19 * (at your option) any later version. |
10263 | 20 * |
26742
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25883
diff
changeset
|
21 * MPlayer is distributed in the hope that it will be useful, |
10263 | 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 * GNU General Public License for more details. | |
25 * | |
26742
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25883
diff
changeset
|
26 * You should have received a copy of the GNU General Public License along |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25883
diff
changeset
|
27 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25883
diff
changeset
|
28 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
10263 | 29 */ |
30 | |
31 | |
32 #include <stdio.h> | |
33 #include <stdlib.h> | |
34 #include <unistd.h> | |
35 #include <time.h> | |
36 #include <stdarg.h> | |
37 | |
38 #include "config.h" | |
39 #include "mp_msg.h" | |
40 #include "help_mp.h" | |
41 | |
32345
e9556f0abee8
Replace forward declarations of skip_audio_frame() by proper #include.
diego
parents:
32012
diff
changeset
|
42 #include "libmpcodecs/dec_audio.h" |
32467 | 43 #include "sub/sub.h" |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
20141
diff
changeset
|
44 #include "stream/stream.h" |
10263 | 45 #include "demuxer.h" |
30577
737b7fd47ef4
Add header for ty_ClearOSD(), ty_processuserdata(); avoids forward declarations.
diego
parents:
29898
diff
changeset
|
46 #include "demux_ty_osd.h" |
10263 | 47 #include "parse_es.h" |
48 #include "stheader.h" | |
32458 | 49 #include "sub/sub_cc.h" |
23703
9fb716ab06a3
Avoid code duplication and ugly config.h hack by using av_strlcat/av_strlcpy
reimar
parents:
23381
diff
changeset
|
50 #include "libavutil/avstring.h" |
24461
921de822048c
Fix completely broken get_ty_pts (it's an ordinary MPEG timestamp)
reimar
parents:
24460
diff
changeset
|
51 #include "libavutil/intreadwrite.h" |
10263 | 52 |
53 // 2/c0: audio data | |
54 // 3/c0: audio packet header (PES header) | |
55 // 4/c0: audio data (S/A only?) | |
56 // 9/c0: audio packet header, AC-3 audio | |
57 // 2/e0: video data | |
58 // 6/e0: video packet header (PES header) | |
59 // 7/e0: video sequence header start | |
60 // 8/e0: video I-frame header start | |
61 // a/e0: video P-frame header start | |
62 // b/e0: video B-frame header start | |
63 // c/e0: video GOP header start | |
64 // e/01: closed-caption data | |
24487 | 65 // e/02: Extended data services data |
10263 | 66 |
67 | |
24446 | 68 #define TIVO_PES_FILEID 0xf5467abd |
69 #define TIVO_PART_LENGTH 0x20000000 | |
10263 | 70 |
71 #define CHUNKSIZE ( 128 * 1024 ) | |
72 #define MAX_AUDIO_BUFFER ( 16 * 1024 ) | |
73 | |
24446 | 74 #define TY_V 1 |
75 #define TY_A 2 | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
76 |
24499 | 77 typedef struct |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
78 { |
24498
7d955b1de13c
Remove another variable and reorder to avoid wasting space due to alignment
reimar
parents:
24497
diff
changeset
|
79 off_t startOffset; |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
80 off_t fileSize; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
81 int chunks; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
82 } tmf_fileParts; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
83 |
24446 | 84 #define MAX_TMF_PARTS 16 |
10263 | 85 |
24499 | 86 typedef struct |
10263 | 87 { |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
88 int whichChunk; |
29898 | 89 unsigned char chunk[ CHUNKSIZE ]; |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
90 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
91 unsigned char lastAudio[ MAX_AUDIO_BUFFER ]; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
92 int lastAudioEnd; |
10263 | 93 |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
94 int tivoType; // 1 = SA, 2 = DTiVo |
10263 | 95 |
24463 | 96 int64_t lastAudioPTS; |
97 int64_t lastVideoPTS; | |
10263 | 98 |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
99 off_t size; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
100 int readHeader; |
24487 | 101 |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
102 int tmf; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
103 tmf_fileParts tmfparts[ MAX_TMF_PARTS ]; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
104 int tmf_totalparts; |
10263 | 105 } TiVoInfo; |
106 | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
107 // =========================================================================== |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
108 #define TMF_SIG "showing.xml" |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
109 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
110 // =========================================================================== |
24443 | 111 static int ty_tmf_filetoparts( demuxer_t *demux, TiVoInfo *tivo ) |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
112 { |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
113 int parts = 0; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
114 |
24501 | 115 stream_seek(demux->stream, 0); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
116 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
117 mp_msg( MSGT_DEMUX, MSGL_DBG3, "Dumping tar contents\n" ); |
24501 | 118 while (!demux->stream->eof) |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
119 { |
24488 | 120 char header[ 512 ]; |
121 char *name; | |
24500 | 122 char *extension; |
24488 | 123 char *sizestr; |
124 int size; | |
125 off_t skip; | |
24457 | 126 if (stream_read(demux->stream, header, 512) < 512) |
24487 | 127 { |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
128 mp_msg( MSGT_DEMUX, MSGL_DBG3, "Read bad\n" ); |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
129 break; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
130 } |
24448
044d3ec97bf7
Avoid strlcpy, tar headers already have space to ensure 0-termination
reimar
parents:
24447
diff
changeset
|
131 name = header; |
044d3ec97bf7
Avoid strlcpy, tar headers already have space to ensure 0-termination
reimar
parents:
24447
diff
changeset
|
132 name[99] = 0; |
044d3ec97bf7
Avoid strlcpy, tar headers already have space to ensure 0-termination
reimar
parents:
24447
diff
changeset
|
133 sizestr = &header[124]; |
24449 | 134 sizestr[11] = 0; |
24442
9fc610537539
Use strtol instead of horribly suboptimal ty_octaltodecimal
reimar
parents:
24423
diff
changeset
|
135 size = strtol(sizestr, NULL, 8); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
136 |
24501 | 137 mp_msg( MSGT_DEMUX, MSGL_DBG3, "name %-20.20s size %-12.12s %d\n", |
138 name, sizestr, size ); | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
139 |
24500 | 140 extension = strrchr(name, '.'); |
24501 | 141 if (extension && strcmp(extension, ".ty") == 0) |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
142 { |
24455 | 143 if ( parts >= MAX_TMF_PARTS ) { |
144 mp_msg( MSGT_DEMUX, MSGL_ERR, "ty:tmf too big\n" ); | |
145 break; | |
146 } | |
24447
c6253f3b5f47
Do not ignore last chunk in .tmf files, it will cause part of the file to be
reimar
parents:
24446
diff
changeset
|
147 tivo->tmfparts[ parts ].fileSize = size; |
24501 | 148 tivo->tmfparts[ parts ].startOffset = stream_tell(demux->stream); |
24450 | 149 tivo->tmfparts[ parts ].chunks = size / CHUNKSIZE; |
24502 | 150 mp_msg(MSGT_DEMUX, MSGL_DBG3, |
151 "tmf_filetoparts(): index %d, chunks %d\n" | |
152 "tmf_filetoparts(): size %"PRId64"\n" | |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16346
diff
changeset
|
153 "tmf_filetoparts(): startOffset %"PRId64"\n", |
24502 | 154 parts, tivo->tmfparts[ parts ].chunks, |
155 tivo->tmfparts[ parts ].fileSize, tivo->tmfparts[ parts ].startOffset | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
156 ); |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
157 parts++; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
158 } |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
159 |
24501 | 160 // size rounded up to blocks |
161 skip = (size + 511) & ~511; | |
162 stream_skip(demux->stream, skip); | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
163 } |
24501 | 164 stream_reset(demux->stream); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
165 tivo->tmf_totalparts = parts; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
166 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
167 "tmf_filetoparts(): No More Part Files %d\n", parts ); |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
168 |
24446 | 169 return 1; |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
170 } |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
171 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
172 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
173 // =========================================================================== |
24451 | 174 static off_t tmf_filetooffset(TiVoInfo *tivo, int chunk) |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
175 { |
24451 | 176 int i; |
177 for (i = 0; i < tivo->tmf_totalparts; i++) { | |
178 if (chunk < tivo->tmfparts[i].chunks) | |
179 return tivo->tmfparts[i].startOffset + chunk * CHUNKSIZE; | |
180 chunk -= tivo->tmfparts[i].chunks; | |
181 } | |
182 return -1; | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
183 } |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
184 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
185 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
186 // =========================================================================== |
24487 | 187 static int tmf_load_chunk( demuxer_t *demux, TiVoInfo *tivo, |
24506
1639f5402540
get rid of pointless size parameter for tmf_load_chunk
reimar
parents:
24505
diff
changeset
|
188 unsigned char *buff, int readChunk ) |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
189 { |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
190 off_t fileoffset; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
191 int count; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
192 |
24487 | 193 mp_msg( MSGT_DEMUX, MSGL_DBG3, "\ntmf_load_chunk() begin %d\n", |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
194 readChunk ); |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
195 |
24452 | 196 fileoffset = tmf_filetooffset(tivo, readChunk); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
197 |
24503 | 198 if (fileoffset == -1 || !stream_seek(demux->stream, fileoffset)) { |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
199 mp_msg( MSGT_DEMUX, MSGL_ERR, "Read past EOF()\n" ); |
24464 | 200 return 0; |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
201 } |
24506
1639f5402540
get rid of pointless size parameter for tmf_load_chunk
reimar
parents:
24505
diff
changeset
|
202 count = stream_read( demux->stream, buff, CHUNKSIZE ); |
24487 | 203 demux->filepos = stream_tell( demux->stream ); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
204 |
24487 | 205 mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() count %x\n", |
206 count ); | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
207 |
24487 | 208 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
209 "tmf_load_chunk() bytes %x %x %x %x %x %x %x %x\n", | |
210 buff[ 0 ], buff[ 1 ], buff[ 2 ], buff[ 3 ], | |
211 buff[ 4 ], buff[ 5 ], buff[ 6 ], buff[ 7 ] ); | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
212 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
213 mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() end\n" ); |
24487 | 214 |
24446 | 215 return count; |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
216 } |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
217 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
218 // =========================================================================== |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
219 |
10263 | 220 // DTiVo MPEG 336, 480, 576, 768 |
221 // SA TiVo 864 | |
222 // DTiVo AC-3 1550 | |
223 // | |
24446 | 224 #define SERIES1_PTS_LENGTH 11 |
225 #define SERIES1_PTS_OFFSET 6 | |
226 #define SERIES2_PTS_LENGTH 16 | |
227 #define SERIES2_PTS_OFFSET 9 | |
228 #define AC3_PTS_LENGTH 16 | |
229 #define AC3_PTS_OFFSET 9 | |
10263 | 230 |
231 static int IsValidAudioPacket( int size, int *ptsOffset, int *ptsLen ) | |
232 { | |
233 // AC-3 | |
24446 | 234 if ( size == 1550 || size == 1552 ) |
10263 | 235 { |
236 *ptsOffset = AC3_PTS_OFFSET; | |
237 *ptsLen = AC3_PTS_LENGTH; | |
24446 | 238 return 1; |
10263 | 239 } |
240 | |
241 // MPEG | |
24471
516c6a2277b1
Greatly simplify IsValidAudioPacket, though this might break something
reimar
parents:
24470
diff
changeset
|
242 if ( (size & 15) == (SERIES1_PTS_LENGTH & 15) ) |
10263 | 243 { |
244 *ptsOffset = SERIES1_PTS_OFFSET; | |
245 *ptsLen = SERIES1_PTS_LENGTH; | |
24470 | 246 return 1; |
10263 | 247 } |
24471
516c6a2277b1
Greatly simplify IsValidAudioPacket, though this might break something
reimar
parents:
24470
diff
changeset
|
248 if ( (size & 15) == (SERIES2_PTS_LENGTH & 15) ) |
10263 | 249 { |
250 *ptsOffset = SERIES2_PTS_OFFSET; | |
251 *ptsLen = SERIES2_PTS_LENGTH; | |
24470 | 252 return 1; |
10263 | 253 } |
24487 | 254 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Tossing Audio Packet Size %d\n", |
10263 | 255 size ); |
24446 | 256 return 0; |
10263 | 257 } |
258 | |
259 | |
24463 | 260 static int64_t get_ty_pts( unsigned char *buf ) |
10263 | 261 { |
24461
921de822048c
Fix completely broken get_ty_pts (it's an ordinary MPEG timestamp)
reimar
parents:
24460
diff
changeset
|
262 int a = buf[0] & 0xe; |
921de822048c
Fix completely broken get_ty_pts (it's an ordinary MPEG timestamp)
reimar
parents:
24460
diff
changeset
|
263 int b = AV_RB16(buf + 1); |
921de822048c
Fix completely broken get_ty_pts (it's an ordinary MPEG timestamp)
reimar
parents:
24460
diff
changeset
|
264 int c = AV_RB16(buf + 3); |
10263 | 265 |
24461
921de822048c
Fix completely broken get_ty_pts (it's an ordinary MPEG timestamp)
reimar
parents:
24460
diff
changeset
|
266 if (!(1 & a & b & c)) // invalid MPEG timestamp |
24463 | 267 return MP_NOPTS_VALUE; |
24461
921de822048c
Fix completely broken get_ty_pts (it's an ordinary MPEG timestamp)
reimar
parents:
24460
diff
changeset
|
268 a >>= 1; b >>= 1; c >>= 1; |
24463 | 269 return (((uint64_t)a) << 30) | (b << 15) | c; |
10263 | 270 } |
271 | |
24487 | 272 static void demux_ty_AddToAudioBuffer( TiVoInfo *tivo, unsigned char *buffer, |
10263 | 273 int size ) |
274 { | |
24446 | 275 if ( tivo->lastAudioEnd + size < MAX_AUDIO_BUFFER ) |
10263 | 276 { |
24487 | 277 memcpy( &tivo->lastAudio[ tivo->lastAudioEnd ], |
10263 | 278 buffer, size ); |
279 tivo->lastAudioEnd += size; | |
280 } | |
281 else | |
282 mp_msg( MSGT_DEMUX, MSGL_ERR, | |
283 "ty:WARNING - Would have blown my audio buffer\n" ); | |
284 } | |
285 | |
24496
42693ad6dd30
Remove now useless parameters from demux_ty_CopyToDemuxPacket
reimar
parents:
24495
diff
changeset
|
286 static void demux_ty_CopyToDemuxPacket( demux_stream_t *ds, |
24497
713ad2d3878d
PTS should be passed as int64_t to demux_ty_CopyToDemuxPacket
reimar
parents:
24496
diff
changeset
|
287 unsigned char *buffer, int size, off_t pos, int64_t pts ) |
10263 | 288 { |
24482 | 289 demux_packet_t *dp = new_demux_packet( size ); |
10263 | 290 memcpy( dp->buffer, buffer, size ); |
24463 | 291 if (pts != MP_NOPTS_VALUE) |
292 dp->pts = pts / 90000.0; | |
10263 | 293 dp->pos = pos; |
294 dp->flags = 0; | |
295 ds_add_packet( ds, dp ); | |
296 } | |
297 | |
24484 | 298 static int demux_ty_FindESHeader( uint8_t nal, |
24478 | 299 unsigned char *buffer, int bufferSize ) |
10263 | 300 { |
24484 | 301 uint32_t search = 0x00000100 | nal; |
24483 | 302 uint32_t found = -1; |
303 uint8_t *p = buffer; | |
304 uint8_t *end = p + bufferSize; | |
305 while (p < end) { | |
306 found <<= 8; | |
307 found |= *p++; | |
308 if (found == search) | |
309 return p - buffer - 4; | |
10263 | 310 } |
24446 | 311 return -1; |
10263 | 312 } |
313 | |
24487 | 314 static void demux_ty_FindESPacket( uint8_t nal, |
10263 | 315 unsigned char *buffer, int bufferSize, int *esOffset1, int *esOffset2 ) |
316 { | |
24484 | 317 *esOffset1 = demux_ty_FindESHeader(nal, buffer, bufferSize); |
24480
a365d70938b3
Simplify demux_ty_FindESPacket by reusing demux_ty_FindESHeader
reimar
parents:
24479
diff
changeset
|
318 if (*esOffset1 == -1) { |
a365d70938b3
Simplify demux_ty_FindESPacket by reusing demux_ty_FindESHeader
reimar
parents:
24479
diff
changeset
|
319 *esOffset2 = -1; |
a365d70938b3
Simplify demux_ty_FindESPacket by reusing demux_ty_FindESHeader
reimar
parents:
24479
diff
changeset
|
320 return; |
a365d70938b3
Simplify demux_ty_FindESPacket by reusing demux_ty_FindESHeader
reimar
parents:
24479
diff
changeset
|
321 } |
a365d70938b3
Simplify demux_ty_FindESPacket by reusing demux_ty_FindESHeader
reimar
parents:
24479
diff
changeset
|
322 buffer += *esOffset1 + 1; |
a365d70938b3
Simplify demux_ty_FindESPacket by reusing demux_ty_FindESHeader
reimar
parents:
24479
diff
changeset
|
323 bufferSize -= *esOffset1 + 1; |
24484 | 324 *esOffset2 = demux_ty_FindESHeader(nal, buffer, bufferSize); |
24480
a365d70938b3
Simplify demux_ty_FindESPacket by reusing demux_ty_FindESHeader
reimar
parents:
24479
diff
changeset
|
325 if (*esOffset2 != -1) |
a365d70938b3
Simplify demux_ty_FindESPacket by reusing demux_ty_FindESHeader
reimar
parents:
24479
diff
changeset
|
326 *esOffset2 += *esOffset1 + 1; |
10263 | 327 } |
328 | |
24484 | 329 #define VIDEO_NAL 0xe0 |
330 #define AUDIO_NAL 0xc0 | |
331 #define AC3_NAL 0xbd | |
10263 | 332 |
16175 | 333 static int demux_ty_fill_buffer( demuxer_t *demux, demux_stream_t *dsds ) |
10263 | 334 { |
335 int invalidType = 0; | |
336 int errorHeader = 0; | |
337 int recordsDecoded = 0; | |
338 | |
339 int readSize; | |
340 | |
341 int numberRecs; | |
342 unsigned char *recPtr; | |
343 int offset; | |
344 | |
345 int counter; | |
346 | |
347 int aid; | |
24487 | 348 |
24469
afbab72dbf2c
Do not misuse a_streams for private info, demuxer->priv is for that!
reimar
parents:
24468
diff
changeset
|
349 TiVoInfo *tivo = demux->priv; |
29898 | 350 unsigned char *chunk = tivo->chunk; |
10263 | 351 |
352 if ( demux->stream->type == STREAMTYPE_DVD ) | |
24487 | 353 return 0; |
10263 | 354 |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
355 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty processing\n" ); |
10263 | 356 |
357 if( demux->stream->eof ) return 0; | |
24487 | 358 |
10263 | 359 // ====================================================================== |
11000 | 360 // If we haven't figured out the size of the stream, let's do so |
10263 | 361 // ====================================================================== |
31357
0b68c2893cac
Cleanup some demux_ty code and at the same time possibly fix vstream support (untested).
reimar
parents:
30577
diff
changeset
|
362 if ( demux->stream->type == STREAMTYPE_VSTREAM ) |
10263 | 363 { |
364 // The vstream code figures out the exact size of the stream | |
365 demux->movi_start = 0; | |
31357
0b68c2893cac
Cleanup some demux_ty code and at the same time possibly fix vstream support (untested).
reimar
parents:
30577
diff
changeset
|
366 demux->movi_end = demux->stream->end_pos; |
0b68c2893cac
Cleanup some demux_ty code and at the same time possibly fix vstream support (untested).
reimar
parents:
30577
diff
changeset
|
367 tivo->size = demux->stream->end_pos; |
10263 | 368 } |
369 else | |
370 { | |
371 // If its a local file, try to find the Part Headers, so we can | |
372 // calculate the ACTUAL stream size | |
373 // If we can't find it, go off with the file size and hope the | |
374 // extract program did the "right thing" | |
375 if ( tivo->readHeader == 0 ) | |
376 { | |
24477
8c9d86adb28e
Move variable declarations into the block where they are used
reimar
parents:
24476
diff
changeset
|
377 off_t filePos; |
10263 | 378 tivo->readHeader = 1; |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
379 |
10263 | 380 filePos = demux->filepos; |
381 stream_seek( demux->stream, 0 ); | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
382 |
10263 | 383 readSize = stream_read( demux->stream, chunk, CHUNKSIZE ); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
384 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
385 if ( memcmp( chunk, TMF_SIG, sizeof( TMF_SIG ) ) == 0 ) |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
386 { |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
387 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Detected a tmf\n" ); |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
388 tivo->tmf = 1; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
389 ty_tmf_filetoparts( demux, tivo ); |
24506
1639f5402540
get rid of pointless size parameter for tmf_load_chunk
reimar
parents:
24505
diff
changeset
|
390 readSize = tmf_load_chunk( demux, tivo, chunk, 0 ); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
391 } |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
392 |
24467 | 393 if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID ) |
10263 | 394 { |
395 off_t numberParts; | |
396 | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
397 readSize = 0; |
24487 | 398 |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
399 if ( tivo->tmf != 1 ) |
10263 | 400 { |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
401 off_t offset; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
402 |
10263 | 403 numberParts = demux->stream->end_pos / TIVO_PART_LENGTH; |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
404 offset = numberParts * TIVO_PART_LENGTH; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
405 |
17366 | 406 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty/ty+Number Parts %"PRId64"\n", |
407 (int64_t)numberParts ); | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
408 |
24446 | 409 if ( offset + CHUNKSIZE < demux->stream->end_pos ) |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
410 { |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
411 stream_seek( demux->stream, offset ); |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
412 readSize = stream_read( demux->stream, chunk, CHUNKSIZE ); |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
413 } |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
414 } |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
415 else |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
416 { |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
417 numberParts = tivo->tmf_totalparts; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
418 offset = numberParts * TIVO_PART_LENGTH; |
24506
1639f5402540
get rid of pointless size parameter for tmf_load_chunk
reimar
parents:
24505
diff
changeset
|
419 readSize = tmf_load_chunk( demux, tivo, chunk, |
24487 | 420 numberParts * ( TIVO_PART_LENGTH - CHUNKSIZE ) / |
24446 | 421 CHUNKSIZE ); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
422 } |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
423 |
24467 | 424 if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID ) |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
425 { |
24477
8c9d86adb28e
Move variable declarations into the block where they are used
reimar
parents:
24476
diff
changeset
|
426 int size = AV_RB24(chunk + 12); |
10263 | 427 size -= 4; |
428 size *= CHUNKSIZE; | |
429 tivo->size = numberParts * TIVO_PART_LENGTH; | |
430 tivo->size += size; | |
24487 | 431 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16346
diff
changeset
|
432 "ty:Header Calc Stream Size %"PRId64"\n", tivo->size ); |
10263 | 433 } |
434 } | |
435 | |
24487 | 436 if ( demux->stream->start_pos > 0 ) |
437 filePos = demux->stream->start_pos; | |
10263 | 438 stream_seek( demux->stream, filePos ); |
24487 | 439 demux->filepos = stream_tell( demux->stream ); |
24446 | 440 tivo->whichChunk = filePos / CHUNKSIZE; |
10263 | 441 } |
442 demux->movi_start = 0; | |
443 demux->movi_end = tivo->size; | |
444 } | |
445 | |
446 // ====================================================================== | |
447 // Give a clue as to where we are in the stream | |
448 // ====================================================================== | |
449 mp_msg( MSGT_DEMUX, MSGL_DBG3, | |
17366 | 450 "ty:ty header size %"PRIx64"\n", (int64_t)tivo->size ); |
10263 | 451 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
17366 | 452 "ty:ty which Chunk %d\n", tivo->whichChunk ); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
453 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
17366 | 454 "ty:file end_pos %"PRIx64"\n", (int64_t)demux->stream->end_pos ); |
10263 | 455 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
17366 | 456 "\nty:wanted current offset %"PRIx64"\n", (int64_t)stream_tell( demux->stream ) ); |
10263 | 457 |
24464 | 458 if ( tivo->size > 0 && stream_tell( demux->stream ) > tivo->size ) |
10263 | 459 { |
460 demux->stream->eof = 1; | |
24464 | 461 return 0; |
10263 | 462 } |
463 | |
24507 | 464 do { |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
465 if ( tivo->tmf != 1 ) |
10263 | 466 { |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
467 // Make sure we are on a 128k boundary |
24446 | 468 if ( demux->filepos % CHUNKSIZE != 0 ) |
10263 | 469 { |
24477
8c9d86adb28e
Move variable declarations into the block where they are used
reimar
parents:
24476
diff
changeset
|
470 int whichChunk = demux->filepos / CHUNKSIZE; |
24446 | 471 if ( demux->filepos % CHUNKSIZE > CHUNKSIZE / 2 ) |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
472 whichChunk++; |
24446 | 473 stream_seek( demux->stream, whichChunk * CHUNKSIZE ); |
10263 | 474 } |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
475 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
476 demux->filepos = stream_tell( demux->stream ); |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
477 tivo->whichChunk = demux->filepos / CHUNKSIZE; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
478 readSize = stream_read( demux->stream, chunk, CHUNKSIZE ); |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
479 if ( readSize != CHUNKSIZE ) |
24464 | 480 return 0; |
10263 | 481 } |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
482 else |
10263 | 483 { |
24506
1639f5402540
get rid of pointless size parameter for tmf_load_chunk
reimar
parents:
24505
diff
changeset
|
484 readSize = tmf_load_chunk( demux, tivo, chunk, tivo->whichChunk ); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
485 if ( readSize != CHUNKSIZE ) |
24446 | 486 return 0; |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
487 tivo->whichChunk++; |
10263 | 488 } |
24507 | 489 if (AV_RB32(chunk) == TIVO_PES_FILEID) |
10263 | 490 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Skipping PART Header\n" ); |
24507 | 491 } while (AV_RB32(chunk) == TIVO_PES_FILEID); |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
492 |
10263 | 493 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
24487 | 494 "\nty:actual current offset %"PRIx64"\n", stream_tell( demux->stream ) - |
495 CHUNKSIZE ); | |
10263 | 496 |
497 | |
12860 | 498 // Let's make a Video Demux Stream for MPlayer |
10263 | 499 aid = 0x0; |
500 if( !demux->v_streams[ aid ] ) new_sh_video( demux, aid ); | |
501 if( demux->video->id == -1 ) demux->video->id = aid; | |
502 if( demux->video->id == aid ) | |
503 { | |
24477
8c9d86adb28e
Move variable declarations into the block where they are used
reimar
parents:
24476
diff
changeset
|
504 demux_stream_t *ds = demux->video; |
10263 | 505 if( !ds->sh ) ds->sh = demux->v_streams[ aid ]; |
506 } | |
507 | |
508 // ====================================================================== | |
509 // Finally, we get to actually parse the chunk | |
510 // ====================================================================== | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
511 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty parsing a chunk\n" ); |
10263 | 512 numberRecs = chunk[ 0 ]; |
513 recPtr = &chunk[ 4 ]; | |
24446 | 514 offset = numberRecs * 16 + 4; |
10263 | 515 for ( counter = 0 ; counter < numberRecs ; counter++ ) |
516 { | |
24477
8c9d86adb28e
Move variable declarations into the block where they are used
reimar
parents:
24476
diff
changeset
|
517 int size = AV_RB24(recPtr) >> 4; |
8c9d86adb28e
Move variable declarations into the block where they are used
reimar
parents:
24476
diff
changeset
|
518 int type = recPtr[ 3 ]; |
8c9d86adb28e
Move variable declarations into the block where they are used
reimar
parents:
24476
diff
changeset
|
519 int nybbleType = recPtr[ 2 ] & 0x0f; |
10263 | 520 recordsDecoded++; |
521 | |
522 mp_msg( MSGT_DEMUX, MSGL_DBG3, | |
523 "ty:Record Type %x/%x %d\n", nybbleType, type, size ); | |
524 | |
525 // ================================================================ | |
526 // Video Parsing | |
527 // ================================================================ | |
528 if ( type == 0xe0 ) | |
529 { | |
24446 | 530 if ( size > 0 && size + offset <= CHUNKSIZE ) |
10263 | 531 { |
24487 | 532 int esOffset1 = demux_ty_FindESHeader( VIDEO_NAL, &chunk[ offset ], |
24478 | 533 size); |
10263 | 534 if ( esOffset1 != -1 ) |
24487 | 535 tivo->lastVideoPTS = get_ty_pts( |
10263 | 536 &chunk[ offset + esOffset1 + 9 ] ); |
537 | |
538 // Do NOT Pass the PES Header onto the MPEG2 Decode | |
539 if( nybbleType != 0x06 ) | |
24496
42693ad6dd30
Remove now useless parameters from demux_ty_CopyToDemuxPacket
reimar
parents:
24495
diff
changeset
|
540 demux_ty_CopyToDemuxPacket( demux->video, |
24487 | 541 &chunk[ offset ], size, demux->filepos + offset, |
542 tivo->lastVideoPTS ); | |
10263 | 543 offset += size; |
544 } | |
24487 | 545 else |
546 errorHeader++; | |
10263 | 547 } |
548 // ================================================================ | |
549 // Audio Parsing | |
550 // ================================================================ | |
24487 | 551 else if ( type == 0xc0 ) |
10263 | 552 { |
24446 | 553 if ( size > 0 && size + offset <= CHUNKSIZE ) |
10263 | 554 { |
555 if( demux->audio->id == -1 ) | |
556 { | |
557 if ( nybbleType == 0x02 ) | |
558 continue; // DTiVo inconclusive, wait for more | |
559 else if ( nybbleType == 0x09 ) | |
560 { | |
561 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Setting AC-3 Audio\n" ); | |
562 aid = 0x80; // AC-3 | |
563 } | |
564 else | |
565 { | |
566 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Setting MPEG Audio\n" ); | |
567 aid = 0x0; // MPEG Audio | |
568 } | |
569 | |
570 demux->audio->id = aid; | |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
31357
diff
changeset
|
571 if( !demux->a_streams[ aid ] ) new_sh_audio( demux, aid, NULL ); |
10263 | 572 if( demux->audio->id == aid ) |
573 { | |
24477
8c9d86adb28e
Move variable declarations into the block where they are used
reimar
parents:
24476
diff
changeset
|
574 demux_stream_t *ds = demux->audio; |
15580 | 575 if( !ds->sh ) { |
576 sh_audio_t* sh_a; | |
577 ds->sh = demux->a_streams[ aid ]; | |
578 sh_a = (sh_audio_t*)ds->sh; | |
579 switch(aid & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id) | |
580 case 0x00: sh_a->format=0x50;break; // mpeg | |
581 case 0xA0: sh_a->format=0x10001;break; // dvd pcm | |
582 case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts | |
583 else sh_a->format=0x2000;break; // ac3 | |
584 } | |
585 } | |
10263 | 586 } |
587 } | |
588 | |
589 aid = demux->audio->id; | |
590 | |
591 | |
592 // SA DTiVo Audio Data, no PES | |
593 // ================================================ | |
24476 | 594 if ( nybbleType == 0x02 || nybbleType == 0x04 ) |
10263 | 595 { |
24476 | 596 if ( nybbleType == 0x02 && tivo->tivoType == 2 ) |
10263 | 597 demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size ); |
598 else | |
599 { | |
600 | |
601 mp_msg( MSGT_DEMUX, MSGL_DBG3, | |
602 "ty:Adding Audio Packet Size %d\n", size ); | |
24496
42693ad6dd30
Remove now useless parameters from demux_ty_CopyToDemuxPacket
reimar
parents:
24495
diff
changeset
|
603 demux_ty_CopyToDemuxPacket( demux->audio, |
24487 | 604 &chunk[ offset ], size, ( demux->filepos + offset ), |
605 tivo->lastAudioPTS ); | |
10263 | 606 } |
607 } | |
608 | |
24475 | 609 // 3 - MPEG Audio with PES Header, either SA or DTiVo |
610 // 9 - DTiVo AC3 Audio Data with PES Header | |
10263 | 611 // ================================================ |
24475 | 612 if ( nybbleType == 0x03 || nybbleType == 0x09 ) |
10263 | 613 { |
24477
8c9d86adb28e
Move variable declarations into the block where they are used
reimar
parents:
24476
diff
changeset
|
614 int esOffset1, esOffset2; |
24475 | 615 if ( nybbleType == 0x03 ) |
24487 | 616 esOffset1 = demux_ty_FindESHeader( AUDIO_NAL, &chunk[ offset ], |
24478 | 617 size); |
10263 | 618 |
619 // SA PES Header, No Audio Data | |
620 // ================================================ | |
24475 | 621 if ( nybbleType == 0x03 && esOffset1 == 0 && size == 16 ) |
10263 | 622 { |
623 tivo->tivoType = 1; | |
24487 | 624 tivo->lastAudioPTS = get_ty_pts( &chunk[ offset + |
10263 | 625 SERIES2_PTS_OFFSET ] ); |
626 } | |
627 else | |
628 // DTiVo Audio with PES Header | |
629 // ================================================ | |
630 { | |
631 tivo->tivoType = 2; | |
632 | |
633 demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size ); | |
24484 | 634 demux_ty_FindESPacket( nybbleType == 9 ? AC3_NAL : AUDIO_NAL, |
10263 | 635 tivo->lastAudio, tivo->lastAudioEnd, &esOffset1, |
636 &esOffset2 ); | |
637 | |
24446 | 638 if ( esOffset1 != -1 && esOffset2 != -1 ) |
10263 | 639 { |
640 int packetSize = esOffset2 - esOffset1; | |
641 int headerSize; | |
642 int ptsOffset; | |
643 | |
24487 | 644 if ( IsValidAudioPacket( packetSize, &ptsOffset, |
10263 | 645 &headerSize ) ) |
646 { | |
647 mp_msg( MSGT_DEMUX, MSGL_DBG3, | |
24487 | 648 "ty:Adding DTiVo Audio Packet Size %d\n", |
10263 | 649 packetSize ); |
650 | |
24487 | 651 tivo->lastAudioPTS = get_ty_pts( |
10263 | 652 &tivo->lastAudio[ esOffset1 + ptsOffset ] ); |
653 | |
24475 | 654 if (nybbleType == 9) headerSize = 0; |
10263 | 655 demux_ty_CopyToDemuxPacket |
24487 | 656 ( |
657 demux->audio, | |
24486 | 658 &tivo->lastAudio[ esOffset1 + headerSize ], |
659 packetSize - headerSize, | |
660 demux->filepos + offset, | |
24487 | 661 tivo->lastAudioPTS |
10263 | 662 ); |
663 | |
664 } | |
665 | |
666 // Collapse the Audio Buffer | |
24485 | 667 tivo->lastAudioEnd -= esOffset2; |
24487 | 668 memmove( &tivo->lastAudio[ 0 ], |
669 &tivo->lastAudio[ esOffset2 ], | |
24485 | 670 tivo->lastAudioEnd ); |
10263 | 671 } |
672 } | |
673 } | |
674 | |
675 offset += size; | |
676 } | |
24487 | 677 else |
678 errorHeader++; | |
679 } | |
10263 | 680 // ================================================================ |
24474 | 681 // 1 = Closed Caption |
682 // 2 = Extended Data Services | |
10263 | 683 // ================================================================ |
24487 | 684 else if ( type == 0x01 || type == 0x02 ) |
685 { | |
24474 | 686 unsigned char lastXDS[ 16 ]; |
24487 | 687 int b = AV_RB24(recPtr) >> 4; |
688 b &= 0x7f7f; | |
10263 | 689 |
24474 | 690 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:%s %04x\n", type == 1 ? "CC" : "XDS", b); |
10263 | 691 |
24487 | 692 lastXDS[ 0x00 ] = 0x00; |
693 lastXDS[ 0x01 ] = 0x00; | |
694 lastXDS[ 0x02 ] = 0x01; | |
695 lastXDS[ 0x03 ] = 0xb2; | |
696 lastXDS[ 0x04 ] = 'T'; | |
697 lastXDS[ 0x05 ] = 'Y'; | |
698 lastXDS[ 0x06 ] = type; | |
699 lastXDS[ 0x07 ] = b >> 8; | |
700 lastXDS[ 0x08 ] = b; | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
701 if ( subcc_enabled ) |
24496
42693ad6dd30
Remove now useless parameters from demux_ty_CopyToDemuxPacket
reimar
parents:
24495
diff
changeset
|
702 demux_ty_CopyToDemuxPacket( demux->video, lastXDS, 0x09, |
24487 | 703 demux->filepos + offset, tivo->lastVideoPTS ); |
704 } | |
10263 | 705 // ================================================================ |
706 // Unknown | |
707 // ================================================================ | |
24487 | 708 else |
709 { | |
24446 | 710 if ( size > 0 && size + offset <= CHUNKSIZE ) |
10263 | 711 offset += size; |
24489
97eba82233f5
live recordings can contain 0-size type 0 chunks, ignore them instead
reimar
parents:
24488
diff
changeset
|
712 if (type != 3 && type != 5 && (type != 0 || size > 0)) { |
10263 | 713 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Invalid Type %x\n", type ); |
24487 | 714 invalidType++; |
24472 | 715 } |
24487 | 716 } |
10263 | 717 recPtr += 16; |
718 } | |
719 | |
20141
bd3afd5a2e48
Fix misdetection of http://samples.mplayerhq.hu/tta/tivo_misdetect.tta as TiVo file
reimar
parents:
19614
diff
changeset
|
720 if ( errorHeader > 0 || invalidType > 0 ) |
10263 | 721 { |
24487 | 722 mp_msg( MSGT_DEMUX, MSGL_DBG3, |
20141
bd3afd5a2e48
Fix misdetection of http://samples.mplayerhq.hu/tta/tivo_misdetect.tta as TiVo file
reimar
parents:
19614
diff
changeset
|
723 "ty:Error Check - Records %d, Parsed %d, Errors %d + %d\n", |
bd3afd5a2e48
Fix misdetection of http://samples.mplayerhq.hu/tta/tivo_misdetect.tta as TiVo file
reimar
parents:
19614
diff
changeset
|
724 numberRecs, recordsDecoded, errorHeader, invalidType ); |
10263 | 725 |
726 // Invalid MPEG ES Size Check | |
24446 | 727 if ( errorHeader > numberRecs / 2 ) |
728 return 0; | |
10263 | 729 |
730 // Invalid MPEG Stream Type Check | |
24446 | 731 if ( invalidType > numberRecs / 2 ) |
732 return 0; | |
10263 | 733 } |
734 | |
735 demux->filepos = stream_tell( demux->stream ); | |
736 | |
24446 | 737 return 1; |
10263 | 738 } |
739 | |
17636 | 740 static void demux_seek_ty( demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags ) |
10263 | 741 { |
742 demux_stream_t *d_audio = demuxer->audio; | |
743 demux_stream_t *d_video = demuxer->video; | |
744 sh_audio_t *sh_audio = d_audio->sh; | |
745 sh_video_t *sh_video = d_video->sh; | |
746 off_t newpos; | |
747 off_t res; | |
24469
afbab72dbf2c
Do not misuse a_streams for private info, demuxer->priv is for that!
reimar
parents:
24468
diff
changeset
|
748 TiVoInfo *tivo = demuxer->priv; |
10263 | 749 |
750 mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Seeking to %7.1f\n", rel_seek_secs ); | |
751 | |
752 tivo->lastAudioEnd = 0; | |
24463 | 753 tivo->lastAudioPTS = MP_NOPTS_VALUE; |
754 tivo->lastVideoPTS = MP_NOPTS_VALUE; | |
10263 | 755 // |
756 //================= seek in MPEG ========================== | |
757 demuxer->filepos = stream_tell( demuxer->stream ); | |
758 | |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
759 newpos = ( flags & SEEK_ABSOLUTE ) ? demuxer->movi_start : demuxer->filepos; |
24487 | 760 |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
761 if( flags & SEEK_FACTOR ) |
24487 | 762 // float seek 0..1 |
763 newpos += ( demuxer->movi_end - demuxer->movi_start ) * rel_seek_secs; | |
764 else | |
10263 | 765 { |
24487 | 766 // time seek (secs) |
10263 | 767 if( ! sh_video->i_bps ) // unspecified or VBR |
768 newpos += 2324 * 75 * rel_seek_secs; // 174.3 kbyte/sec | |
769 else | |
770 newpos += sh_video->i_bps * rel_seek_secs; | |
771 } | |
772 | |
773 if ( newpos < demuxer->movi_start ) | |
774 { | |
24487 | 775 if( demuxer->stream->type != STREAMTYPE_VCD ) demuxer->movi_start = 0; |
776 if( newpos < demuxer->movi_start ) newpos = demuxer->movi_start; | |
777 } | |
10263 | 778 |
779 res = newpos / CHUNKSIZE; | |
780 if ( rel_seek_secs >= 0 ) | |
781 newpos = ( res + 1 ) * CHUNKSIZE; | |
782 else | |
783 newpos = res * CHUNKSIZE; | |
784 | |
785 if ( newpos < 0 ) | |
786 newpos = 0; | |
15581
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
787 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
788 tivo->whichChunk = newpos / CHUNKSIZE; |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
789 |
2e621c99354d
a cleaned-up version of ty demuxer improvements found in tivo-mplayer fork.
joey
parents:
15580
diff
changeset
|
790 stream_seek( demuxer->stream, newpos ); |
10263 | 791 |
792 // re-sync video: | |
793 videobuf_code_len = 0; // reset ES stream buffer | |
794 | |
24487 | 795 ds_fill_buffer( d_video ); |
796 if( sh_audio ) | |
797 ds_fill_buffer( d_audio ); | |
10263 | 798 |
24487 | 799 while( 1 ) |
10263 | 800 { |
24487 | 801 int i; |
10263 | 802 if( sh_audio && !d_audio->eof && d_video->pts && d_audio->pts ) |
803 { | |
24487 | 804 float a_pts = d_audio->pts; |
10263 | 805 a_pts += ( ds_tell_pts( d_audio ) - sh_audio->a_in_buffer_len ) / |
806 (float)sh_audio->i_bps; | |
24487 | 807 if( d_video->pts > a_pts ) |
10263 | 808 { |
24487 | 809 skip_audio_frame( sh_audio ); // sync audio |
810 continue; | |
811 } | |
10263 | 812 } |
813 i = sync_video_packet( d_video ); | |
814 if( i == 0x1B3 || i == 0x1B8 ) break; // found it! | |
815 if( !i || !skip_video_packet( d_video ) ) break; // EOF? | |
816 } | |
24487 | 817 if ( subcc_enabled ) |
818 ty_ClearOSD( 0 ); | |
10263 | 819 } |
820 | |
24443 | 821 static int demux_ty_control( demuxer_t *demuxer,int cmd, void *arg ) |
10263 | 822 { |
823 demux_stream_t *d_video = demuxer->video; | |
824 sh_video_t *sh_video = d_video->sh; | |
825 | |
24487 | 826 switch(cmd) |
10263 | 827 { |
24487 | 828 case DEMUXER_CTRL_GET_TIME_LENGTH: |
829 if(!sh_video->i_bps) // unspecified or VBR | |
830 return DEMUXER_CTRL_DONTKNOW; | |
831 *(double *)arg= | |
24446 | 832 (double)demuxer->movi_end-demuxer->movi_start/sh_video->i_bps; |
24487 | 833 return DEMUXER_CTRL_GUESS; |
10263 | 834 |
24487 | 835 case DEMUXER_CTRL_GET_PERCENT_POS: |
836 return DEMUXER_CTRL_DONTKNOW; | |
837 default: | |
838 return DEMUXER_CTRL_NOTIMPL; | |
10263 | 839 } |
840 } | |
841 | |
842 | |
17174
83a8c738be89
make demuxer seek and close functions return void, patch by Dominik Mierzejewski
wanderer
parents:
17012
diff
changeset
|
843 static void demux_close_ty( demuxer_t *demux ) |
10263 | 844 { |
24469
afbab72dbf2c
Do not misuse a_streams for private info, demuxer->priv is for that!
reimar
parents:
24468
diff
changeset
|
845 TiVoInfo *tivo = demux->priv; |
10263 | 846 |
847 free( tivo ); | |
24487 | 848 sub_justify = 0; |
10263 | 849 } |
850 | |
851 | |
16175 | 852 static int ty_check_file(demuxer_t* demuxer) |
853 { | |
24469
afbab72dbf2c
Do not misuse a_streams for private info, demuxer->priv is for that!
reimar
parents:
24468
diff
changeset
|
854 TiVoInfo *tivo = calloc(1, sizeof(TiVoInfo)); |
afbab72dbf2c
Do not misuse a_streams for private info, demuxer->priv is for that!
reimar
parents:
24468
diff
changeset
|
855 demuxer->priv = tivo; |
33914
9ed8b7b1b94a
Ensure filepos is initialized before following code tries to use it.
reimar
parents:
32467
diff
changeset
|
856 demuxer->filepos = stream_tell( demuxer->stream ); |
16175 | 857 return ds_fill_buffer(demuxer->video) ? DEMUXER_TYPE_MPEG_TY : 0; |
858 } | |
859 | |
860 | |
861 static demuxer_t* demux_open_ty(demuxer_t* demuxer) | |
862 { | |
863 sh_audio_t *sh_audio=NULL; | |
864 sh_video_t *sh_video=NULL; | |
865 | |
866 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video; | |
867 | |
868 if(demuxer->audio->id!=-2) { | |
869 if(!ds_fill_buffer(demuxer->audio)){ | |
870 mp_msg(MSGT_DEMUXER,MSGL_INFO,"MPEG: " MSGTR_MissingAudioStream); | |
871 demuxer->audio->sh=NULL; | |
872 } else { | |
873 sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio; | |
874 } | |
875 } | |
876 | |
877 return demuxer; | |
878 } | |
879 | |
880 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
24507
diff
changeset
|
881 const demuxer_desc_t demuxer_desc_mpeg_ty = { |
16175 | 882 "TiVo demuxer", |
883 "tivo", | |
884 "TiVo", | |
885 "Christopher R. Wingert", | |
886 "Demux streams from TiVo", | |
887 DEMUXER_TYPE_MPEG_TY, | |
888 0, // unsafe autodetect | |
889 ty_check_file, | |
890 demux_ty_fill_buffer, | |
891 demux_open_ty, | |
892 demux_close_ty, | |
893 demux_seek_ty, | |
894 demux_ty_control | |
895 }; |