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