ffmpeg / libavformat / mpegts.c @ ed68efad
History | View | Annotate | Download (45.4 KB)
1 |
/*
|
---|---|
2 |
* MPEG2 transport stream (aka DVB) demuxer
|
3 |
* Copyright (c) 2002-2003 Fabrice Bellard
|
4 |
*
|
5 |
* This file is part of FFmpeg.
|
6 |
*
|
7 |
* FFmpeg is free software; you can redistribute it and/or
|
8 |
* modify it under the terms of the GNU Lesser General Public
|
9 |
* License as published by the Free Software Foundation; either
|
10 |
* version 2.1 of the License, or (at your option) any later version.
|
11 |
*
|
12 |
* FFmpeg is distributed in the hope that it will be useful,
|
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 |
* Lesser General Public License for more details.
|
16 |
*
|
17 |
* You should have received a copy of the GNU Lesser General Public
|
18 |
* License along with FFmpeg; if not, write to the Free Software
|
19 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 |
*/
|
21 |
|
22 |
//#define DEBUG
|
23 |
//#define DEBUG_SEEK
|
24 |
|
25 |
#include "libavutil/crc.h" |
26 |
#include "libavutil/intreadwrite.h" |
27 |
#include "libavcodec/bytestream.h" |
28 |
#include "avformat.h" |
29 |
#include "mpegts.h" |
30 |
#include "internal.h" |
31 |
|
32 |
/* 1.0 second at 24Mbit/s */
|
33 |
#define MAX_SCAN_PACKETS 32000 |
34 |
|
35 |
/* maximum size in which we look for synchronisation if
|
36 |
synchronisation is lost */
|
37 |
#define MAX_RESYNC_SIZE 4096 |
38 |
|
39 |
#define MAX_PES_PAYLOAD 200*1024 |
40 |
|
41 |
typedef struct PESContext PESContext; |
42 |
|
43 |
static PESContext* add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type); |
44 |
|
45 |
enum MpegTSFilterType {
|
46 |
MPEGTS_PES, |
47 |
MPEGTS_SECTION, |
48 |
}; |
49 |
|
50 |
typedef struct MpegTSFilter MpegTSFilter; |
51 |
|
52 |
typedef int PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos); |
53 |
|
54 |
typedef struct MpegTSPESFilter { |
55 |
PESCallback *pes_cb; |
56 |
void *opaque;
|
57 |
} MpegTSPESFilter; |
58 |
|
59 |
typedef void SectionCallback(MpegTSFilter *f, const uint8_t *buf, int len); |
60 |
|
61 |
typedef void SetServiceCallback(void *opaque, int ret); |
62 |
|
63 |
typedef struct MpegTSSectionFilter { |
64 |
int section_index;
|
65 |
int section_h_size;
|
66 |
uint8_t *section_buf; |
67 |
unsigned int check_crc:1; |
68 |
unsigned int end_of_section_reached:1; |
69 |
SectionCallback *section_cb; |
70 |
void *opaque;
|
71 |
} MpegTSSectionFilter; |
72 |
|
73 |
struct MpegTSFilter {
|
74 |
int pid;
|
75 |
int last_cc; /* last cc code (-1 if first packet) */ |
76 |
enum MpegTSFilterType type;
|
77 |
union {
|
78 |
MpegTSPESFilter pes_filter; |
79 |
MpegTSSectionFilter section_filter; |
80 |
} u; |
81 |
}; |
82 |
|
83 |
#define MAX_PIDS_PER_PROGRAM 64 |
84 |
struct Program {
|
85 |
unsigned int id; //program id/service id |
86 |
unsigned int nb_pids; |
87 |
unsigned int pids[MAX_PIDS_PER_PROGRAM]; |
88 |
}; |
89 |
|
90 |
struct MpegTSContext {
|
91 |
/* user data */
|
92 |
AVFormatContext *stream; |
93 |
/** raw packet size, including FEC if present */
|
94 |
int raw_packet_size;
|
95 |
|
96 |
int pos47;
|
97 |
|
98 |
/** if true, all pids are analyzed to find streams */
|
99 |
int auto_guess;
|
100 |
|
101 |
/** compute exact PCR for each transport stream packet */
|
102 |
int mpeg2ts_compute_pcr;
|
103 |
|
104 |
int64_t cur_pcr; /**< used to estimate the exact PCR */
|
105 |
int pcr_incr; /**< used to estimate the exact PCR */ |
106 |
|
107 |
/* data needed to handle file based ts */
|
108 |
/** stop parsing loop */
|
109 |
int stop_parse;
|
110 |
/** packet containing Audio/Video data */
|
111 |
AVPacket *pkt; |
112 |
/** to detect seek */
|
113 |
int64_t last_pos; |
114 |
|
115 |
/******************************************/
|
116 |
/* private mpegts data */
|
117 |
/* scan context */
|
118 |
/** structure to keep track of Program->pids mapping */
|
119 |
unsigned int nb_prg; |
120 |
struct Program *prg;
|
121 |
|
122 |
|
123 |
/** filters for various streams specified by PMT + for the PAT and PMT */
|
124 |
MpegTSFilter *pids[NB_PID_MAX]; |
125 |
}; |
126 |
|
127 |
/* TS stream handling */
|
128 |
|
129 |
enum MpegTSState {
|
130 |
MPEGTS_HEADER = 0,
|
131 |
MPEGTS_PESHEADER_FILL, |
132 |
MPEGTS_PAYLOAD, |
133 |
MPEGTS_SKIP, |
134 |
}; |
135 |
|
136 |
/* enough for PES header + length */
|
137 |
#define PES_START_SIZE 9 |
138 |
#define MAX_PES_HEADER_SIZE (9 + 255) |
139 |
|
140 |
struct PESContext {
|
141 |
int pid;
|
142 |
int pcr_pid; /**< if -1 then all packets containing PCR are considered */ |
143 |
int stream_type;
|
144 |
MpegTSContext *ts; |
145 |
AVFormatContext *stream; |
146 |
AVStream *st; |
147 |
enum MpegTSState state;
|
148 |
/* used to get the format */
|
149 |
int data_index;
|
150 |
int total_size;
|
151 |
int pes_header_size;
|
152 |
int64_t pts, dts; |
153 |
int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */
|
154 |
uint8_t header[MAX_PES_HEADER_SIZE]; |
155 |
uint8_t *buffer; |
156 |
}; |
157 |
|
158 |
extern AVInputFormat mpegts_demuxer;
|
159 |
|
160 |
static void clear_program(MpegTSContext *ts, unsigned int programid) |
161 |
{ |
162 |
int i;
|
163 |
|
164 |
for(i=0; i<ts->nb_prg; i++) |
165 |
if(ts->prg[i].id == programid)
|
166 |
ts->prg[i].nb_pids = 0;
|
167 |
} |
168 |
|
169 |
static void clear_programs(MpegTSContext *ts) |
170 |
{ |
171 |
av_freep(&ts->prg); |
172 |
ts->nb_prg=0;
|
173 |
} |
174 |
|
175 |
static void add_pat_entry(MpegTSContext *ts, unsigned int programid) |
176 |
{ |
177 |
struct Program *p;
|
178 |
void *tmp = av_realloc(ts->prg, (ts->nb_prg+1)*sizeof(struct Program)); |
179 |
if(!tmp)
|
180 |
return;
|
181 |
ts->prg = tmp; |
182 |
p = &ts->prg[ts->nb_prg]; |
183 |
p->id = programid; |
184 |
p->nb_pids = 0;
|
185 |
ts->nb_prg++; |
186 |
} |
187 |
|
188 |
static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, unsigned int pid) |
189 |
{ |
190 |
int i;
|
191 |
struct Program *p = NULL; |
192 |
for(i=0; i<ts->nb_prg; i++) { |
193 |
if(ts->prg[i].id == programid) {
|
194 |
p = &ts->prg[i]; |
195 |
break;
|
196 |
} |
197 |
} |
198 |
if(!p)
|
199 |
return;
|
200 |
|
201 |
if(p->nb_pids >= MAX_PIDS_PER_PROGRAM)
|
202 |
return;
|
203 |
p->pids[p->nb_pids++] = pid; |
204 |
} |
205 |
|
206 |
/**
|
207 |
* \brief discard_pid() decides if the pid is to be discarded according
|
208 |
* to caller's programs selection
|
209 |
* \param ts : - TS context
|
210 |
* \param pid : - pid
|
211 |
* \return 1 if the pid is only comprised in programs that have .discard=AVDISCARD_ALL
|
212 |
* 0 otherwise
|
213 |
*/
|
214 |
static int discard_pid(MpegTSContext *ts, unsigned int pid) |
215 |
{ |
216 |
int i, j, k;
|
217 |
int used = 0, discarded = 0; |
218 |
struct Program *p;
|
219 |
for(i=0; i<ts->nb_prg; i++) { |
220 |
p = &ts->prg[i]; |
221 |
for(j=0; j<p->nb_pids; j++) { |
222 |
if(p->pids[j] != pid)
|
223 |
continue;
|
224 |
//is program with id p->id set to be discarded?
|
225 |
for(k=0; k<ts->stream->nb_programs; k++) { |
226 |
if(ts->stream->programs[k]->id == p->id) {
|
227 |
if(ts->stream->programs[k]->discard == AVDISCARD_ALL)
|
228 |
discarded++; |
229 |
else
|
230 |
used++; |
231 |
} |
232 |
} |
233 |
} |
234 |
} |
235 |
|
236 |
return !used && discarded;
|
237 |
} |
238 |
|
239 |
/**
|
240 |
* Assembles PES packets out of TS packets, and then calls the "section_cb"
|
241 |
* function when they are complete.
|
242 |
*/
|
243 |
static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1, |
244 |
const uint8_t *buf, int buf_size, int is_start) |
245 |
{ |
246 |
MpegTSSectionFilter *tss = &tss1->u.section_filter; |
247 |
int len;
|
248 |
|
249 |
if (is_start) {
|
250 |
memcpy(tss->section_buf, buf, buf_size); |
251 |
tss->section_index = buf_size; |
252 |
tss->section_h_size = -1;
|
253 |
tss->end_of_section_reached = 0;
|
254 |
} else {
|
255 |
if (tss->end_of_section_reached)
|
256 |
return;
|
257 |
len = 4096 - tss->section_index;
|
258 |
if (buf_size < len)
|
259 |
len = buf_size; |
260 |
memcpy(tss->section_buf + tss->section_index, buf, len); |
261 |
tss->section_index += len; |
262 |
} |
263 |
|
264 |
/* compute section length if possible */
|
265 |
if (tss->section_h_size == -1 && tss->section_index >= 3) { |
266 |
len = (AV_RB16(tss->section_buf + 1) & 0xfff) + 3; |
267 |
if (len > 4096) |
268 |
return;
|
269 |
tss->section_h_size = len; |
270 |
} |
271 |
|
272 |
if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) { |
273 |
tss->end_of_section_reached = 1;
|
274 |
if (!tss->check_crc ||
|
275 |
av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1,
|
276 |
tss->section_buf, tss->section_h_size) == 0)
|
277 |
tss->section_cb(tss1, tss->section_buf, tss->section_h_size); |
278 |
} |
279 |
} |
280 |
|
281 |
static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int pid, |
282 |
SectionCallback *section_cb, void *opaque,
|
283 |
int check_crc)
|
284 |
|
285 |
{ |
286 |
MpegTSFilter *filter; |
287 |
MpegTSSectionFilter *sec; |
288 |
|
289 |
dprintf(ts->stream, "Filter: pid=0x%x\n", pid);
|
290 |
|
291 |
if (pid >= NB_PID_MAX || ts->pids[pid])
|
292 |
return NULL; |
293 |
filter = av_mallocz(sizeof(MpegTSFilter));
|
294 |
if (!filter)
|
295 |
return NULL; |
296 |
ts->pids[pid] = filter; |
297 |
filter->type = MPEGTS_SECTION; |
298 |
filter->pid = pid; |
299 |
filter->last_cc = -1;
|
300 |
sec = &filter->u.section_filter; |
301 |
sec->section_cb = section_cb; |
302 |
sec->opaque = opaque; |
303 |
sec->section_buf = av_malloc(MAX_SECTION_SIZE); |
304 |
sec->check_crc = check_crc; |
305 |
if (!sec->section_buf) {
|
306 |
av_free(filter); |
307 |
return NULL; |
308 |
} |
309 |
return filter;
|
310 |
} |
311 |
|
312 |
static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid, |
313 |
PESCallback *pes_cb, |
314 |
void *opaque)
|
315 |
{ |
316 |
MpegTSFilter *filter; |
317 |
MpegTSPESFilter *pes; |
318 |
|
319 |
if (pid >= NB_PID_MAX || ts->pids[pid])
|
320 |
return NULL; |
321 |
filter = av_mallocz(sizeof(MpegTSFilter));
|
322 |
if (!filter)
|
323 |
return NULL; |
324 |
ts->pids[pid] = filter; |
325 |
filter->type = MPEGTS_PES; |
326 |
filter->pid = pid; |
327 |
filter->last_cc = -1;
|
328 |
pes = &filter->u.pes_filter; |
329 |
pes->pes_cb = pes_cb; |
330 |
pes->opaque = opaque; |
331 |
return filter;
|
332 |
} |
333 |
|
334 |
static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) |
335 |
{ |
336 |
int pid;
|
337 |
|
338 |
pid = filter->pid; |
339 |
if (filter->type == MPEGTS_SECTION)
|
340 |
av_freep(&filter->u.section_filter.section_buf); |
341 |
else if (filter->type == MPEGTS_PES) { |
342 |
PESContext *pes = filter->u.pes_filter.opaque; |
343 |
av_freep(&pes->buffer); |
344 |
/* referenced private data will be freed later in
|
345 |
* av_close_input_stream */
|
346 |
if (!((PESContext *)filter->u.pes_filter.opaque)->st) {
|
347 |
av_freep(&filter->u.pes_filter.opaque); |
348 |
} |
349 |
} |
350 |
|
351 |
av_free(filter); |
352 |
ts->pids[pid] = NULL;
|
353 |
} |
354 |
|
355 |
static int analyze(const uint8_t *buf, int size, int packet_size, int *index){ |
356 |
int stat[packet_size];
|
357 |
int i;
|
358 |
int x=0; |
359 |
int best_score=0; |
360 |
|
361 |
memset(stat, 0, packet_size*sizeof(int)); |
362 |
|
363 |
for(x=i=0; i<size-3; i++){ |
364 |
if(buf[i] == 0x47 && !(buf[i+1] & 0x80) && (buf[i+3] & 0x30)){ |
365 |
stat[x]++; |
366 |
if(stat[x] > best_score){
|
367 |
best_score= stat[x]; |
368 |
if(index) *index= x;
|
369 |
} |
370 |
} |
371 |
|
372 |
x++; |
373 |
if(x == packet_size) x= 0; |
374 |
} |
375 |
|
376 |
return best_score;
|
377 |
} |
378 |
|
379 |
/* autodetect fec presence. Must have at least 1024 bytes */
|
380 |
static int get_packet_size(const uint8_t *buf, int size) |
381 |
{ |
382 |
int score, fec_score, dvhs_score;
|
383 |
|
384 |
if (size < (TS_FEC_PACKET_SIZE * 5 + 1)) |
385 |
return -1; |
386 |
|
387 |
score = analyze(buf, size, TS_PACKET_SIZE, NULL);
|
388 |
dvhs_score = analyze(buf, size, TS_DVHS_PACKET_SIZE, NULL);
|
389 |
fec_score= analyze(buf, size, TS_FEC_PACKET_SIZE, NULL);
|
390 |
// av_log(NULL, AV_LOG_DEBUG, "score: %d, dvhs_score: %d, fec_score: %d \n", score, dvhs_score, fec_score);
|
391 |
|
392 |
if (score > fec_score && score > dvhs_score) return TS_PACKET_SIZE; |
393 |
else if(dvhs_score > score && dvhs_score > fec_score) return TS_DVHS_PACKET_SIZE; |
394 |
else if(score < fec_score && dvhs_score < fec_score) return TS_FEC_PACKET_SIZE; |
395 |
else return -1; |
396 |
} |
397 |
|
398 |
typedef struct SectionHeader { |
399 |
uint8_t tid; |
400 |
uint16_t id; |
401 |
uint8_t version; |
402 |
uint8_t sec_num; |
403 |
uint8_t last_sec_num; |
404 |
} SectionHeader; |
405 |
|
406 |
static inline int get8(const uint8_t **pp, const uint8_t *p_end) |
407 |
{ |
408 |
const uint8_t *p;
|
409 |
int c;
|
410 |
|
411 |
p = *pp; |
412 |
if (p >= p_end)
|
413 |
return -1; |
414 |
c = *p++; |
415 |
*pp = p; |
416 |
return c;
|
417 |
} |
418 |
|
419 |
static inline int get16(const uint8_t **pp, const uint8_t *p_end) |
420 |
{ |
421 |
const uint8_t *p;
|
422 |
int c;
|
423 |
|
424 |
p = *pp; |
425 |
if ((p + 1) >= p_end) |
426 |
return -1; |
427 |
c = AV_RB16(p); |
428 |
p += 2;
|
429 |
*pp = p; |
430 |
return c;
|
431 |
} |
432 |
|
433 |
/* read and allocate a DVB string preceeded by its length */
|
434 |
static char *getstr8(const uint8_t **pp, const uint8_t *p_end) |
435 |
{ |
436 |
int len;
|
437 |
const uint8_t *p;
|
438 |
char *str;
|
439 |
|
440 |
p = *pp; |
441 |
len = get8(&p, p_end); |
442 |
if (len < 0) |
443 |
return NULL; |
444 |
if ((p + len) > p_end)
|
445 |
return NULL; |
446 |
str = av_malloc(len + 1);
|
447 |
if (!str)
|
448 |
return NULL; |
449 |
memcpy(str, p, len); |
450 |
str[len] = '\0';
|
451 |
p += len; |
452 |
*pp = p; |
453 |
return str;
|
454 |
} |
455 |
|
456 |
static int parse_section_header(SectionHeader *h, |
457 |
const uint8_t **pp, const uint8_t *p_end) |
458 |
{ |
459 |
int val;
|
460 |
|
461 |
val = get8(pp, p_end); |
462 |
if (val < 0) |
463 |
return -1; |
464 |
h->tid = val; |
465 |
*pp += 2;
|
466 |
val = get16(pp, p_end); |
467 |
if (val < 0) |
468 |
return -1; |
469 |
h->id = val; |
470 |
val = get8(pp, p_end); |
471 |
if (val < 0) |
472 |
return -1; |
473 |
h->version = (val >> 1) & 0x1f; |
474 |
val = get8(pp, p_end); |
475 |
if (val < 0) |
476 |
return -1; |
477 |
h->sec_num = val; |
478 |
val = get8(pp, p_end); |
479 |
if (val < 0) |
480 |
return -1; |
481 |
h->last_sec_num = val; |
482 |
return 0; |
483 |
} |
484 |
|
485 |
typedef struct { |
486 |
uint32_t stream_type; |
487 |
enum CodecType codec_type;
|
488 |
enum CodecID codec_id;
|
489 |
} StreamType; |
490 |
|
491 |
static const StreamType ISO_types[] = { |
492 |
{ 0x01, CODEC_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO },
|
493 |
{ 0x02, CODEC_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO },
|
494 |
{ 0x03, CODEC_TYPE_AUDIO, CODEC_ID_MP3 },
|
495 |
{ 0x04, CODEC_TYPE_AUDIO, CODEC_ID_MP3 },
|
496 |
{ 0x0f, CODEC_TYPE_AUDIO, CODEC_ID_AAC },
|
497 |
{ 0x10, CODEC_TYPE_VIDEO, CODEC_ID_MPEG4 },
|
498 |
{ 0x1b, CODEC_TYPE_VIDEO, CODEC_ID_H264 },
|
499 |
{ 0xd1, CODEC_TYPE_VIDEO, CODEC_ID_DIRAC },
|
500 |
{ 0xea, CODEC_TYPE_VIDEO, CODEC_ID_VC1 },
|
501 |
{ 0 },
|
502 |
}; |
503 |
|
504 |
static const StreamType HDMV_types[] = { |
505 |
{ 0x81, CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
|
506 |
{ 0x82, CODEC_TYPE_AUDIO, CODEC_ID_DTS },
|
507 |
{ 0 },
|
508 |
}; |
509 |
|
510 |
/* ATSC ? */
|
511 |
static const StreamType MISC_types[] = { |
512 |
{ 0x81, CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
|
513 |
{ 0x8a, CODEC_TYPE_AUDIO, CODEC_ID_DTS },
|
514 |
{0x100, CODEC_TYPE_SUBTITLE, CODEC_ID_DVB_SUBTITLE }, // demuxer internal |
515 |
{ 0 },
|
516 |
}; |
517 |
|
518 |
static const StreamType REGD_types[] = { |
519 |
{ MKTAG('d','r','a','c'), CODEC_TYPE_VIDEO, CODEC_ID_DIRAC }, |
520 |
{ MKTAG('A','C','-','3'), CODEC_TYPE_AUDIO, CODEC_ID_AC3 }, |
521 |
{ 0 },
|
522 |
}; |
523 |
|
524 |
/* descriptor present */
|
525 |
static const StreamType DESC_types[] = { |
526 |
{ 0x6a, CODEC_TYPE_AUDIO, CODEC_ID_AC3 }, /* AC-3 descriptor */ |
527 |
{ 0x7a, CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
|
528 |
{ 0x7b, CODEC_TYPE_AUDIO, CODEC_ID_DTS },
|
529 |
{ 0x59, CODEC_TYPE_SUBTITLE, CODEC_ID_DVB_SUBTITLE }, /* subtitling descriptor */ |
530 |
}; |
531 |
|
532 |
static void mpegts_find_stream_type(AVStream *st, |
533 |
uint32_t stream_type, const StreamType *types)
|
534 |
{ |
535 |
for (; types->stream_type; types++) {
|
536 |
if (stream_type == types->stream_type) {
|
537 |
st->codec->codec_type = types->codec_type; |
538 |
st->codec->codec_id = types->codec_id; |
539 |
return;
|
540 |
} |
541 |
} |
542 |
} |
543 |
|
544 |
static AVStream *new_pes_av_stream(PESContext *pes, uint32_t prog_reg_desc)
|
545 |
{ |
546 |
AVStream *st = av_new_stream(pes->stream, pes->pid); |
547 |
|
548 |
if (!st)
|
549 |
return NULL; |
550 |
|
551 |
av_set_pts_info(st, 33, 1, 90000); |
552 |
st->priv_data = pes; |
553 |
st->codec->codec_type = CODEC_TYPE_DATA; |
554 |
st->codec->codec_id = CODEC_ID_PROBE; |
555 |
st->need_parsing = AVSTREAM_PARSE_FULL; |
556 |
pes->st = st; |
557 |
|
558 |
dprintf(pes->stream, "stream_type=%x pid=%x prog_reg_desc=%.4s\n",
|
559 |
pes->stream_type, pes->pid, (char*)&prog_reg_desc);
|
560 |
|
561 |
mpegts_find_stream_type(st, pes->stream_type, ISO_types); |
562 |
if (prog_reg_desc == AV_RL32("HDMV") && |
563 |
st->codec->codec_id == CODEC_ID_PROBE) |
564 |
mpegts_find_stream_type(st, pes->stream_type, HDMV_types); |
565 |
if (st->codec->codec_id == CODEC_ID_PROBE)
|
566 |
mpegts_find_stream_type(st, pes->stream_type, MISC_types); |
567 |
|
568 |
return st;
|
569 |
} |
570 |
|
571 |
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) |
572 |
{ |
573 |
MpegTSContext *ts = filter->u.section_filter.opaque; |
574 |
SectionHeader h1, *h = &h1; |
575 |
PESContext *pes; |
576 |
AVStream *st; |
577 |
const uint8_t *p, *p_end, *desc_list_end, *desc_end;
|
578 |
int program_info_length, pcr_pid, pid, stream_type;
|
579 |
int desc_list_len, desc_len, desc_tag;
|
580 |
int comp_page, anc_page;
|
581 |
char language[4]; |
582 |
uint32_t prog_reg_desc = 0; /* registration descriptor */ |
583 |
uint32_t reg_desc; /* registration descriptor */
|
584 |
|
585 |
#ifdef DEBUG
|
586 |
dprintf(ts->stream, "PMT: len %i\n", section_len);
|
587 |
av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); |
588 |
#endif
|
589 |
|
590 |
p_end = section + section_len - 4;
|
591 |
p = section; |
592 |
if (parse_section_header(h, &p, p_end) < 0) |
593 |
return;
|
594 |
|
595 |
dprintf(ts->stream, "sid=0x%x sec_num=%d/%d\n",
|
596 |
h->id, h->sec_num, h->last_sec_num); |
597 |
|
598 |
if (h->tid != PMT_TID)
|
599 |
return;
|
600 |
|
601 |
clear_program(ts, h->id); |
602 |
pcr_pid = get16(&p, p_end) & 0x1fff;
|
603 |
if (pcr_pid < 0) |
604 |
return;
|
605 |
add_pid_to_pmt(ts, h->id, pcr_pid); |
606 |
|
607 |
dprintf(ts->stream, "pcr_pid=0x%x\n", pcr_pid);
|
608 |
|
609 |
program_info_length = get16(&p, p_end) & 0xfff;
|
610 |
if (program_info_length < 0) |
611 |
return;
|
612 |
while(program_info_length >= 2) { |
613 |
uint8_t tag, len; |
614 |
tag = get8(&p, p_end); |
615 |
len = get8(&p, p_end); |
616 |
if(len > program_info_length - 2) |
617 |
//something else is broken, exit the program_descriptors_loop
|
618 |
break;
|
619 |
program_info_length -= len + 2;
|
620 |
if(tag == 0x05 && len >= 4) { // registration descriptor |
621 |
prog_reg_desc = bytestream_get_le32(&p); |
622 |
len -= 4;
|
623 |
} |
624 |
p += len; |
625 |
} |
626 |
p += program_info_length; |
627 |
if (p >= p_end)
|
628 |
return;
|
629 |
for(;;) {
|
630 |
st = 0;
|
631 |
stream_type = get8(&p, p_end); |
632 |
if (stream_type < 0) |
633 |
break;
|
634 |
pid = get16(&p, p_end) & 0x1fff;
|
635 |
if (pid < 0) |
636 |
break;
|
637 |
|
638 |
/* now create ffmpeg stream */
|
639 |
if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) {
|
640 |
pes = ts->pids[pid]->u.pes_filter.opaque; |
641 |
st = pes->st; |
642 |
} else {
|
643 |
if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably |
644 |
pes = add_pes_stream(ts, pid, pcr_pid, stream_type); |
645 |
if (pes)
|
646 |
st = new_pes_av_stream(pes, prog_reg_desc); |
647 |
} |
648 |
|
649 |
if (!st)
|
650 |
return;
|
651 |
|
652 |
add_pid_to_pmt(ts, h->id, pid); |
653 |
|
654 |
av_program_add_stream_index(ts->stream, h->id, st->index); |
655 |
|
656 |
desc_list_len = get16(&p, p_end) & 0xfff;
|
657 |
if (desc_list_len < 0) |
658 |
break;
|
659 |
desc_list_end = p + desc_list_len; |
660 |
if (desc_list_end > p_end)
|
661 |
break;
|
662 |
for(;;) {
|
663 |
desc_tag = get8(&p, desc_list_end); |
664 |
if (desc_tag < 0) |
665 |
break;
|
666 |
desc_len = get8(&p, desc_list_end); |
667 |
if (desc_len < 0) |
668 |
break;
|
669 |
desc_end = p + desc_len; |
670 |
if (desc_end > desc_list_end)
|
671 |
break;
|
672 |
|
673 |
dprintf(ts->stream, "tag: 0x%02x len=%d\n",
|
674 |
desc_tag, desc_len); |
675 |
|
676 |
if (st->codec->codec_id == CODEC_ID_PROBE &&
|
677 |
stream_type == STREAM_TYPE_PRIVATE_DATA) |
678 |
mpegts_find_stream_type(st, desc_tag, DESC_types); |
679 |
|
680 |
switch(desc_tag) {
|
681 |
case 0x59: /* subtitling descriptor */ |
682 |
language[0] = get8(&p, desc_end);
|
683 |
language[1] = get8(&p, desc_end);
|
684 |
language[2] = get8(&p, desc_end);
|
685 |
language[3] = 0; |
686 |
get8(&p, desc_end); |
687 |
comp_page = get16(&p, desc_end); |
688 |
anc_page = get16(&p, desc_end); |
689 |
st->codec->sub_id = (anc_page << 16) | comp_page;
|
690 |
av_metadata_set(&st->metadata, "language", language);
|
691 |
break;
|
692 |
case 0x0a: /* ISO 639 language descriptor */ |
693 |
language[0] = get8(&p, desc_end);
|
694 |
language[1] = get8(&p, desc_end);
|
695 |
language[2] = get8(&p, desc_end);
|
696 |
language[3] = 0; |
697 |
av_metadata_set(&st->metadata, "language", language);
|
698 |
break;
|
699 |
case 0x05: /* registration descriptor */ |
700 |
reg_desc = bytestream_get_le32(&p); |
701 |
if (st->codec->codec_id == CODEC_ID_PROBE &&
|
702 |
stream_type == STREAM_TYPE_PRIVATE_DATA) |
703 |
mpegts_find_stream_type(st, reg_desc, REGD_types); |
704 |
break;
|
705 |
default:
|
706 |
break;
|
707 |
} |
708 |
p = desc_end; |
709 |
} |
710 |
p = desc_list_end; |
711 |
} |
712 |
/* all parameters are there */
|
713 |
ts->stop_parse++; |
714 |
mpegts_close_filter(ts, filter); |
715 |
} |
716 |
|
717 |
static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) |
718 |
{ |
719 |
MpegTSContext *ts = filter->u.section_filter.opaque; |
720 |
SectionHeader h1, *h = &h1; |
721 |
const uint8_t *p, *p_end;
|
722 |
int sid, pmt_pid;
|
723 |
|
724 |
#ifdef DEBUG
|
725 |
dprintf(ts->stream, "PAT:\n");
|
726 |
av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); |
727 |
#endif
|
728 |
p_end = section + section_len - 4;
|
729 |
p = section; |
730 |
if (parse_section_header(h, &p, p_end) < 0) |
731 |
return;
|
732 |
if (h->tid != PAT_TID)
|
733 |
return;
|
734 |
|
735 |
clear_programs(ts); |
736 |
for(;;) {
|
737 |
sid = get16(&p, p_end); |
738 |
if (sid < 0) |
739 |
break;
|
740 |
pmt_pid = get16(&p, p_end) & 0x1fff;
|
741 |
if (pmt_pid < 0) |
742 |
break;
|
743 |
|
744 |
dprintf(ts->stream, "sid=0x%x pid=0x%x\n", sid, pmt_pid);
|
745 |
|
746 |
if (sid == 0x0000) { |
747 |
/* NIT info */
|
748 |
} else {
|
749 |
av_new_program(ts->stream, sid); |
750 |
ts->stop_parse--; |
751 |
mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
|
752 |
add_pat_entry(ts, sid); |
753 |
add_pid_to_pmt(ts, sid, 0); //add pat pid to program |
754 |
add_pid_to_pmt(ts, sid, pmt_pid); |
755 |
} |
756 |
} |
757 |
/* not found */
|
758 |
ts->stop_parse++; |
759 |
|
760 |
mpegts_close_filter(ts, filter); |
761 |
} |
762 |
|
763 |
static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) |
764 |
{ |
765 |
MpegTSContext *ts = filter->u.section_filter.opaque; |
766 |
SectionHeader h1, *h = &h1; |
767 |
const uint8_t *p, *p_end, *desc_list_end, *desc_end;
|
768 |
int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
|
769 |
char *name, *provider_name;
|
770 |
|
771 |
#ifdef DEBUG
|
772 |
dprintf(ts->stream, "SDT:\n");
|
773 |
av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); |
774 |
#endif
|
775 |
|
776 |
p_end = section + section_len - 4;
|
777 |
p = section; |
778 |
if (parse_section_header(h, &p, p_end) < 0) |
779 |
return;
|
780 |
if (h->tid != SDT_TID)
|
781 |
return;
|
782 |
onid = get16(&p, p_end); |
783 |
if (onid < 0) |
784 |
return;
|
785 |
val = get8(&p, p_end); |
786 |
if (val < 0) |
787 |
return;
|
788 |
for(;;) {
|
789 |
sid = get16(&p, p_end); |
790 |
if (sid < 0) |
791 |
break;
|
792 |
val = get8(&p, p_end); |
793 |
if (val < 0) |
794 |
break;
|
795 |
desc_list_len = get16(&p, p_end) & 0xfff;
|
796 |
if (desc_list_len < 0) |
797 |
break;
|
798 |
desc_list_end = p + desc_list_len; |
799 |
if (desc_list_end > p_end)
|
800 |
break;
|
801 |
for(;;) {
|
802 |
desc_tag = get8(&p, desc_list_end); |
803 |
if (desc_tag < 0) |
804 |
break;
|
805 |
desc_len = get8(&p, desc_list_end); |
806 |
desc_end = p + desc_len; |
807 |
if (desc_end > desc_list_end)
|
808 |
break;
|
809 |
|
810 |
dprintf(ts->stream, "tag: 0x%02x len=%d\n",
|
811 |
desc_tag, desc_len); |
812 |
|
813 |
switch(desc_tag) {
|
814 |
case 0x48: |
815 |
service_type = get8(&p, p_end); |
816 |
if (service_type < 0) |
817 |
break;
|
818 |
provider_name = getstr8(&p, p_end); |
819 |
if (!provider_name)
|
820 |
break;
|
821 |
name = getstr8(&p, p_end); |
822 |
if (name) {
|
823 |
AVProgram *program = av_new_program(ts->stream, sid); |
824 |
if(program) {
|
825 |
av_metadata_set(&program->metadata, "name", name);
|
826 |
av_metadata_set(&program->metadata, "provider_name", provider_name);
|
827 |
} |
828 |
} |
829 |
av_free(name); |
830 |
av_free(provider_name); |
831 |
break;
|
832 |
default:
|
833 |
break;
|
834 |
} |
835 |
p = desc_end; |
836 |
} |
837 |
p = desc_list_end; |
838 |
} |
839 |
} |
840 |
|
841 |
static int64_t get_pts(const uint8_t *p) |
842 |
{ |
843 |
int64_t pts = (int64_t)((p[0] >> 1) & 0x07) << 30; |
844 |
pts |= (AV_RB16(p + 1) >> 1) << 15; |
845 |
pts |= AV_RB16(p + 3) >> 1; |
846 |
return pts;
|
847 |
} |
848 |
|
849 |
static void new_pes_packet(PESContext *pes, AVPacket *pkt) |
850 |
{ |
851 |
av_init_packet(pkt); |
852 |
|
853 |
pkt->destruct = av_destruct_packet; |
854 |
pkt->data = pes->buffer; |
855 |
pkt->size = pes->data_index; |
856 |
memset(pkt->data+pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
857 |
|
858 |
pkt->stream_index = pes->st->index; |
859 |
pkt->pts = pes->pts; |
860 |
pkt->dts = pes->dts; |
861 |
/* store position of first TS packet of this PES packet */
|
862 |
pkt->pos = pes->ts_packet_pos; |
863 |
|
864 |
/* reset pts values */
|
865 |
pes->pts = AV_NOPTS_VALUE; |
866 |
pes->dts = AV_NOPTS_VALUE; |
867 |
pes->buffer = NULL;
|
868 |
pes->data_index = 0;
|
869 |
} |
870 |
|
871 |
/* return non zero if a packet could be constructed */
|
872 |
static int mpegts_push_data(MpegTSFilter *filter, |
873 |
const uint8_t *buf, int buf_size, int is_start, |
874 |
int64_t pos) |
875 |
{ |
876 |
PESContext *pes = filter->u.pes_filter.opaque; |
877 |
MpegTSContext *ts = pes->ts; |
878 |
const uint8_t *p;
|
879 |
int len, code;
|
880 |
|
881 |
if(!ts->pkt)
|
882 |
return 0; |
883 |
|
884 |
if (is_start) {
|
885 |
if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) { |
886 |
new_pes_packet(pes, ts->pkt); |
887 |
ts->stop_parse = 1;
|
888 |
} |
889 |
pes->state = MPEGTS_HEADER; |
890 |
pes->data_index = 0;
|
891 |
pes->ts_packet_pos = pos; |
892 |
} |
893 |
p = buf; |
894 |
while (buf_size > 0) { |
895 |
switch(pes->state) {
|
896 |
case MPEGTS_HEADER:
|
897 |
len = PES_START_SIZE - pes->data_index; |
898 |
if (len > buf_size)
|
899 |
len = buf_size; |
900 |
memcpy(pes->header + pes->data_index, p, len); |
901 |
pes->data_index += len; |
902 |
p += len; |
903 |
buf_size -= len; |
904 |
if (pes->data_index == PES_START_SIZE) {
|
905 |
/* we got all the PES or section header. We can now
|
906 |
decide */
|
907 |
#if 0
|
908 |
av_hex_dump_log(pes->stream, AV_LOG_DEBUG, pes->header, pes->data_index);
|
909 |
#endif
|
910 |
if (pes->header[0] == 0x00 && pes->header[1] == 0x00 && |
911 |
pes->header[2] == 0x01) { |
912 |
/* it must be an mpeg2 PES stream */
|
913 |
code = pes->header[3] | 0x100; |
914 |
if (!pes->st || pes->st->discard == AVDISCARD_ALL ||
|
915 |
!((code >= 0x1c0 && code <= 0x1df) || |
916 |
(code >= 0x1e0 && code <= 0x1ef) || |
917 |
(code == 0x1bd) || (code == 0x1fd))) |
918 |
goto skip;
|
919 |
pes->state = MPEGTS_PESHEADER_FILL; |
920 |
pes->total_size = AV_RB16(pes->header + 4);
|
921 |
/* NOTE: a zero total size means the PES size is
|
922 |
unbounded */
|
923 |
pes->pes_header_size = pes->header[8] + 9; |
924 |
} else {
|
925 |
/* otherwise, it should be a table */
|
926 |
/* skip packet */
|
927 |
skip:
|
928 |
pes->state = MPEGTS_SKIP; |
929 |
continue;
|
930 |
} |
931 |
} |
932 |
break;
|
933 |
/**********************************************/
|
934 |
/* PES packing parsing */
|
935 |
case MPEGTS_PESHEADER_FILL:
|
936 |
len = pes->pes_header_size - pes->data_index; |
937 |
if (len < 0) |
938 |
return -1; |
939 |
if (len > buf_size)
|
940 |
len = buf_size; |
941 |
memcpy(pes->header + pes->data_index, p, len); |
942 |
pes->data_index += len; |
943 |
p += len; |
944 |
buf_size -= len; |
945 |
if (pes->data_index == pes->pes_header_size) {
|
946 |
const uint8_t *r;
|
947 |
unsigned int flags; |
948 |
|
949 |
flags = pes->header[7];
|
950 |
r = pes->header + 9;
|
951 |
pes->pts = AV_NOPTS_VALUE; |
952 |
pes->dts = AV_NOPTS_VALUE; |
953 |
if ((flags & 0xc0) == 0x80) { |
954 |
pes->dts = pes->pts = get_pts(r); |
955 |
r += 5;
|
956 |
} else if ((flags & 0xc0) == 0xc0) { |
957 |
pes->pts = get_pts(r); |
958 |
r += 5;
|
959 |
pes->dts = get_pts(r); |
960 |
r += 5;
|
961 |
} |
962 |
|
963 |
if (pes->total_size > pes->data_index - 6) |
964 |
pes->total_size -= pes->data_index - 6;
|
965 |
else
|
966 |
pes->total_size = MAX_PES_PAYLOAD; |
967 |
/* allocate pes buffer */
|
968 |
pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE); |
969 |
if (!pes->buffer)
|
970 |
return AVERROR(ENOMEM);
|
971 |
|
972 |
/* we got the full header. We parse it and get the payload */
|
973 |
pes->state = MPEGTS_PAYLOAD; |
974 |
pes->data_index = 0;
|
975 |
} |
976 |
break;
|
977 |
case MPEGTS_PAYLOAD:
|
978 |
if (buf_size > 0) { |
979 |
if (pes->data_index+buf_size > pes->total_size) {
|
980 |
new_pes_packet(pes, ts->pkt); |
981 |
pes->total_size = MAX_PES_PAYLOAD; |
982 |
pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE); |
983 |
if (!pes->buffer)
|
984 |
return AVERROR(ENOMEM);
|
985 |
ts->stop_parse = 1;
|
986 |
} |
987 |
memcpy(pes->buffer+pes->data_index, p, buf_size); |
988 |
pes->data_index += buf_size; |
989 |
} |
990 |
buf_size = 0;
|
991 |
break;
|
992 |
case MPEGTS_SKIP:
|
993 |
buf_size = 0;
|
994 |
break;
|
995 |
} |
996 |
} |
997 |
|
998 |
return 0; |
999 |
} |
1000 |
|
1001 |
static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type) |
1002 |
{ |
1003 |
MpegTSFilter *tss; |
1004 |
PESContext *pes; |
1005 |
|
1006 |
/* if no pid found, then add a pid context */
|
1007 |
pes = av_mallocz(sizeof(PESContext));
|
1008 |
if (!pes)
|
1009 |
return 0; |
1010 |
pes->ts = ts; |
1011 |
pes->stream = ts->stream; |
1012 |
pes->pid = pid; |
1013 |
pes->pcr_pid = pcr_pid; |
1014 |
pes->stream_type = stream_type; |
1015 |
tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes); |
1016 |
if (!tss) {
|
1017 |
av_free(pes); |
1018 |
return 0; |
1019 |
} |
1020 |
return pes;
|
1021 |
} |
1022 |
|
1023 |
/* handle one TS packet */
|
1024 |
static int handle_packet(MpegTSContext *ts, const uint8_t *packet) |
1025 |
{ |
1026 |
AVFormatContext *s = ts->stream; |
1027 |
MpegTSFilter *tss; |
1028 |
int len, pid, cc, cc_ok, afc, is_start;
|
1029 |
const uint8_t *p, *p_end;
|
1030 |
int64_t pos; |
1031 |
|
1032 |
pid = AV_RB16(packet + 1) & 0x1fff; |
1033 |
if(pid && discard_pid(ts, pid))
|
1034 |
return 0; |
1035 |
is_start = packet[1] & 0x40; |
1036 |
tss = ts->pids[pid]; |
1037 |
if (ts->auto_guess && tss == NULL && is_start) { |
1038 |
add_pes_stream(ts, pid, -1, 0); |
1039 |
tss = ts->pids[pid]; |
1040 |
} |
1041 |
if (!tss)
|
1042 |
return 0; |
1043 |
|
1044 |
/* continuity check (currently not used) */
|
1045 |
cc = (packet[3] & 0xf); |
1046 |
cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc)); |
1047 |
tss->last_cc = cc; |
1048 |
|
1049 |
/* skip adaptation field */
|
1050 |
afc = (packet[3] >> 4) & 3; |
1051 |
p = packet + 4;
|
1052 |
if (afc == 0) /* reserved value */ |
1053 |
return 0; |
1054 |
if (afc == 2) /* adaptation field only */ |
1055 |
return 0; |
1056 |
if (afc == 3) { |
1057 |
/* skip adapation field */
|
1058 |
p += p[0] + 1; |
1059 |
} |
1060 |
/* if past the end of packet, ignore */
|
1061 |
p_end = packet + TS_PACKET_SIZE; |
1062 |
if (p >= p_end)
|
1063 |
return 0; |
1064 |
|
1065 |
pos = url_ftell(ts->stream->pb); |
1066 |
ts->pos47= pos % ts->raw_packet_size; |
1067 |
|
1068 |
if (tss->type == MPEGTS_SECTION) {
|
1069 |
if (is_start) {
|
1070 |
/* pointer field present */
|
1071 |
len = *p++; |
1072 |
if (p + len > p_end)
|
1073 |
return 0; |
1074 |
if (len && cc_ok) {
|
1075 |
/* write remaining section bytes */
|
1076 |
write_section_data(s, tss, |
1077 |
p, len, 0);
|
1078 |
/* check whether filter has been closed */
|
1079 |
if (!ts->pids[pid])
|
1080 |
return 0; |
1081 |
} |
1082 |
p += len; |
1083 |
if (p < p_end) {
|
1084 |
write_section_data(s, tss, |
1085 |
p, p_end - p, 1);
|
1086 |
} |
1087 |
} else {
|
1088 |
if (cc_ok) {
|
1089 |
write_section_data(s, tss, |
1090 |
p, p_end - p, 0);
|
1091 |
} |
1092 |
} |
1093 |
} else {
|
1094 |
int ret;
|
1095 |
// Note: The position here points actually behind the current packet.
|
1096 |
if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start,
|
1097 |
pos - ts->raw_packet_size)) < 0)
|
1098 |
return ret;
|
1099 |
} |
1100 |
|
1101 |
return 0; |
1102 |
} |
1103 |
|
1104 |
/* XXX: try to find a better synchro over several packets (use
|
1105 |
get_packet_size() ?) */
|
1106 |
static int mpegts_resync(ByteIOContext *pb) |
1107 |
{ |
1108 |
int c, i;
|
1109 |
|
1110 |
for(i = 0;i < MAX_RESYNC_SIZE; i++) { |
1111 |
c = url_fgetc(pb); |
1112 |
if (c < 0) |
1113 |
return -1; |
1114 |
if (c == 0x47) { |
1115 |
url_fseek(pb, -1, SEEK_CUR);
|
1116 |
return 0; |
1117 |
} |
1118 |
} |
1119 |
/* no sync found */
|
1120 |
return -1; |
1121 |
} |
1122 |
|
1123 |
/* return -1 if error or EOF. Return 0 if OK. */
|
1124 |
static int read_packet(ByteIOContext *pb, uint8_t *buf, int raw_packet_size) |
1125 |
{ |
1126 |
int skip, len;
|
1127 |
|
1128 |
for(;;) {
|
1129 |
len = get_buffer(pb, buf, TS_PACKET_SIZE); |
1130 |
if (len != TS_PACKET_SIZE)
|
1131 |
return AVERROR(EIO);
|
1132 |
/* check paquet sync byte */
|
1133 |
if (buf[0] != 0x47) { |
1134 |
/* find a new packet start */
|
1135 |
url_fseek(pb, -TS_PACKET_SIZE, SEEK_CUR); |
1136 |
if (mpegts_resync(pb) < 0) |
1137 |
return AVERROR_INVALIDDATA;
|
1138 |
else
|
1139 |
continue;
|
1140 |
} else {
|
1141 |
skip = raw_packet_size - TS_PACKET_SIZE; |
1142 |
if (skip > 0) |
1143 |
url_fskip(pb, skip); |
1144 |
break;
|
1145 |
} |
1146 |
} |
1147 |
return 0; |
1148 |
} |
1149 |
|
1150 |
static int handle_packets(MpegTSContext *ts, int nb_packets) |
1151 |
{ |
1152 |
AVFormatContext *s = ts->stream; |
1153 |
ByteIOContext *pb = s->pb; |
1154 |
uint8_t packet[TS_PACKET_SIZE]; |
1155 |
int packet_num, ret;
|
1156 |
|
1157 |
ts->stop_parse = 0;
|
1158 |
packet_num = 0;
|
1159 |
for(;;) {
|
1160 |
if (ts->stop_parse>0) |
1161 |
break;
|
1162 |
packet_num++; |
1163 |
if (nb_packets != 0 && packet_num >= nb_packets) |
1164 |
break;
|
1165 |
ret = read_packet(pb, packet, ts->raw_packet_size); |
1166 |
if (ret != 0) |
1167 |
return ret;
|
1168 |
ret = handle_packet(ts, packet); |
1169 |
if (ret != 0) |
1170 |
return ret;
|
1171 |
} |
1172 |
return 0; |
1173 |
} |
1174 |
|
1175 |
static int mpegts_probe(AVProbeData *p) |
1176 |
{ |
1177 |
#if 1 |
1178 |
const int size= p->buf_size; |
1179 |
int score, fec_score, dvhs_score;
|
1180 |
int check_count= size / TS_FEC_PACKET_SIZE;
|
1181 |
#define CHECK_COUNT 10 |
1182 |
|
1183 |
if (check_count < CHECK_COUNT)
|
1184 |
return -1; |
1185 |
|
1186 |
score = analyze(p->buf, TS_PACKET_SIZE *check_count, TS_PACKET_SIZE , NULL)*CHECK_COUNT/check_count;
|
1187 |
dvhs_score= analyze(p->buf, TS_DVHS_PACKET_SIZE*check_count, TS_DVHS_PACKET_SIZE, NULL)*CHECK_COUNT/check_count;
|
1188 |
fec_score = analyze(p->buf, TS_FEC_PACKET_SIZE *check_count, TS_FEC_PACKET_SIZE , NULL)*CHECK_COUNT/check_count;
|
1189 |
// av_log(NULL, AV_LOG_DEBUG, "score: %d, dvhs_score: %d, fec_score: %d \n", score, dvhs_score, fec_score);
|
1190 |
|
1191 |
// we need a clear definition for the returned score otherwise things will become messy sooner or later
|
1192 |
if (score > fec_score && score > dvhs_score && score > 6) return AVPROBE_SCORE_MAX + score - CHECK_COUNT; |
1193 |
else if(dvhs_score > score && dvhs_score > fec_score && dvhs_score > 6) return AVPROBE_SCORE_MAX + dvhs_score - CHECK_COUNT; |
1194 |
else if( fec_score > 6) return AVPROBE_SCORE_MAX + fec_score - CHECK_COUNT; |
1195 |
else return -1; |
1196 |
#else
|
1197 |
/* only use the extension for safer guess */
|
1198 |
if (match_ext(p->filename, "ts")) |
1199 |
return AVPROBE_SCORE_MAX;
|
1200 |
else
|
1201 |
return 0; |
1202 |
#endif
|
1203 |
} |
1204 |
|
1205 |
/* return the 90kHz PCR and the extension for the 27MHz PCR. return
|
1206 |
(-1) if not available */
|
1207 |
static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, |
1208 |
const uint8_t *packet)
|
1209 |
{ |
1210 |
int afc, len, flags;
|
1211 |
const uint8_t *p;
|
1212 |
unsigned int v; |
1213 |
|
1214 |
afc = (packet[3] >> 4) & 3; |
1215 |
if (afc <= 1) |
1216 |
return -1; |
1217 |
p = packet + 4;
|
1218 |
len = p[0];
|
1219 |
p++; |
1220 |
if (len == 0) |
1221 |
return -1; |
1222 |
flags = *p++; |
1223 |
len--; |
1224 |
if (!(flags & 0x10)) |
1225 |
return -1; |
1226 |
if (len < 6) |
1227 |
return -1; |
1228 |
v = AV_RB32(p); |
1229 |
*ppcr_high = ((int64_t)v << 1) | (p[4] >> 7); |
1230 |
*ppcr_low = ((p[4] & 1) << 8) | p[5]; |
1231 |
return 0; |
1232 |
} |
1233 |
|
1234 |
static int mpegts_read_header(AVFormatContext *s, |
1235 |
AVFormatParameters *ap) |
1236 |
{ |
1237 |
MpegTSContext *ts = s->priv_data; |
1238 |
ByteIOContext *pb = s->pb; |
1239 |
uint8_t buf[5*1024]; |
1240 |
int len;
|
1241 |
int64_t pos; |
1242 |
|
1243 |
if (ap) {
|
1244 |
ts->mpeg2ts_compute_pcr = ap->mpeg2ts_compute_pcr; |
1245 |
if(ap->mpeg2ts_raw){
|
1246 |
av_log(s, AV_LOG_ERROR, "use mpegtsraw_demuxer!\n");
|
1247 |
return -1; |
1248 |
} |
1249 |
} |
1250 |
|
1251 |
/* read the first 1024 bytes to get packet size */
|
1252 |
pos = url_ftell(pb); |
1253 |
len = get_buffer(pb, buf, sizeof(buf));
|
1254 |
if (len != sizeof(buf)) |
1255 |
goto fail;
|
1256 |
ts->raw_packet_size = get_packet_size(buf, sizeof(buf));
|
1257 |
if (ts->raw_packet_size <= 0) |
1258 |
goto fail;
|
1259 |
ts->stream = s; |
1260 |
ts->auto_guess = 0;
|
1261 |
|
1262 |
if (s->iformat == &mpegts_demuxer) {
|
1263 |
/* normal demux */
|
1264 |
|
1265 |
/* first do a scaning to get all the services */
|
1266 |
url_fseek(pb, pos, SEEK_SET); |
1267 |
|
1268 |
mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
|
1269 |
|
1270 |
mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1);
|
1271 |
|
1272 |
handle_packets(ts, s->probesize); |
1273 |
/* if could not find service, enable auto_guess */
|
1274 |
|
1275 |
ts->auto_guess = 1;
|
1276 |
|
1277 |
dprintf(ts->stream, "tuning done\n");
|
1278 |
|
1279 |
s->ctx_flags |= AVFMTCTX_NOHEADER; |
1280 |
} else {
|
1281 |
AVStream *st; |
1282 |
int pcr_pid, pid, nb_packets, nb_pcrs, ret, pcr_l;
|
1283 |
int64_t pcrs[2], pcr_h;
|
1284 |
int packet_count[2]; |
1285 |
uint8_t packet[TS_PACKET_SIZE]; |
1286 |
|
1287 |
/* only read packets */
|
1288 |
|
1289 |
st = av_new_stream(s, 0);
|
1290 |
if (!st)
|
1291 |
goto fail;
|
1292 |
av_set_pts_info(st, 60, 1, 27000000); |
1293 |
st->codec->codec_type = CODEC_TYPE_DATA; |
1294 |
st->codec->codec_id = CODEC_ID_MPEG2TS; |
1295 |
|
1296 |
/* we iterate until we find two PCRs to estimate the bitrate */
|
1297 |
pcr_pid = -1;
|
1298 |
nb_pcrs = 0;
|
1299 |
nb_packets = 0;
|
1300 |
for(;;) {
|
1301 |
ret = read_packet(s->pb, packet, ts->raw_packet_size); |
1302 |
if (ret < 0) |
1303 |
return -1; |
1304 |
pid = AV_RB16(packet + 1) & 0x1fff; |
1305 |
if ((pcr_pid == -1 || pcr_pid == pid) && |
1306 |
parse_pcr(&pcr_h, &pcr_l, packet) == 0) {
|
1307 |
pcr_pid = pid; |
1308 |
packet_count[nb_pcrs] = nb_packets; |
1309 |
pcrs[nb_pcrs] = pcr_h * 300 + pcr_l;
|
1310 |
nb_pcrs++; |
1311 |
if (nb_pcrs >= 2) |
1312 |
break;
|
1313 |
} |
1314 |
nb_packets++; |
1315 |
} |
1316 |
|
1317 |
/* NOTE1: the bitrate is computed without the FEC */
|
1318 |
/* NOTE2: it is only the bitrate of the start of the stream */
|
1319 |
ts->pcr_incr = (pcrs[1] - pcrs[0]) / (packet_count[1] - packet_count[0]); |
1320 |
ts->cur_pcr = pcrs[0] - ts->pcr_incr * packet_count[0]; |
1321 |
s->bit_rate = (TS_PACKET_SIZE * 8) * 27e6 / ts->pcr_incr; |
1322 |
st->codec->bit_rate = s->bit_rate; |
1323 |
st->start_time = ts->cur_pcr; |
1324 |
#if 0
|
1325 |
av_log(ts->stream, AV_LOG_DEBUG, "start=%0.3f pcr=%0.3f incr=%d\n",
|
1326 |
st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);
|
1327 |
#endif
|
1328 |
} |
1329 |
|
1330 |
url_fseek(pb, pos, SEEK_SET); |
1331 |
return 0; |
1332 |
fail:
|
1333 |
return -1; |
1334 |
} |
1335 |
|
1336 |
#define MAX_PACKET_READAHEAD ((128 * 1024) / 188) |
1337 |
|
1338 |
static int mpegts_raw_read_packet(AVFormatContext *s, |
1339 |
AVPacket *pkt) |
1340 |
{ |
1341 |
MpegTSContext *ts = s->priv_data; |
1342 |
int ret, i;
|
1343 |
int64_t pcr_h, next_pcr_h, pos; |
1344 |
int pcr_l, next_pcr_l;
|
1345 |
uint8_t pcr_buf[12];
|
1346 |
|
1347 |
if (av_new_packet(pkt, TS_PACKET_SIZE) < 0) |
1348 |
return AVERROR(ENOMEM);
|
1349 |
pkt->pos= url_ftell(s->pb); |
1350 |
ret = read_packet(s->pb, pkt->data, ts->raw_packet_size); |
1351 |
if (ret < 0) { |
1352 |
av_free_packet(pkt); |
1353 |
return ret;
|
1354 |
} |
1355 |
if (ts->mpeg2ts_compute_pcr) {
|
1356 |
/* compute exact PCR for each packet */
|
1357 |
if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) { |
1358 |
/* we read the next PCR (XXX: optimize it by using a bigger buffer */
|
1359 |
pos = url_ftell(s->pb); |
1360 |
for(i = 0; i < MAX_PACKET_READAHEAD; i++) { |
1361 |
url_fseek(s->pb, pos + i * ts->raw_packet_size, SEEK_SET); |
1362 |
get_buffer(s->pb, pcr_buf, 12);
|
1363 |
if (parse_pcr(&next_pcr_h, &next_pcr_l, pcr_buf) == 0) { |
1364 |
/* XXX: not precise enough */
|
1365 |
ts->pcr_incr = ((next_pcr_h - pcr_h) * 300 + (next_pcr_l - pcr_l)) /
|
1366 |
(i + 1);
|
1367 |
break;
|
1368 |
} |
1369 |
} |
1370 |
url_fseek(s->pb, pos, SEEK_SET); |
1371 |
/* no next PCR found: we use previous increment */
|
1372 |
ts->cur_pcr = pcr_h * 300 + pcr_l;
|
1373 |
} |
1374 |
pkt->pts = ts->cur_pcr; |
1375 |
pkt->duration = ts->pcr_incr; |
1376 |
ts->cur_pcr += ts->pcr_incr; |
1377 |
} |
1378 |
pkt->stream_index = 0;
|
1379 |
return 0; |
1380 |
} |
1381 |
|
1382 |
static int mpegts_read_packet(AVFormatContext *s, |
1383 |
AVPacket *pkt) |
1384 |
{ |
1385 |
MpegTSContext *ts = s->priv_data; |
1386 |
int ret, i;
|
1387 |
|
1388 |
if (url_ftell(s->pb) != ts->last_pos) {
|
1389 |
/* seek detected, flush pes buffer */
|
1390 |
for (i = 0; i < NB_PID_MAX; i++) { |
1391 |
if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {
|
1392 |
PESContext *pes = ts->pids[i]->u.pes_filter.opaque; |
1393 |
av_freep(&pes->buffer); |
1394 |
pes->data_index = 0;
|
1395 |
pes->state = MPEGTS_SKIP; /* skip until pes header */
|
1396 |
} |
1397 |
} |
1398 |
} |
1399 |
|
1400 |
ts->pkt = pkt; |
1401 |
ret = handle_packets(ts, 0);
|
1402 |
if (ret < 0) { |
1403 |
/* flush pes data left */
|
1404 |
for (i = 0; i < NB_PID_MAX; i++) { |
1405 |
if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {
|
1406 |
PESContext *pes = ts->pids[i]->u.pes_filter.opaque; |
1407 |
if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) { |
1408 |
new_pes_packet(pes, pkt); |
1409 |
ret = 0;
|
1410 |
break;
|
1411 |
} |
1412 |
} |
1413 |
} |
1414 |
} |
1415 |
|
1416 |
ts->last_pos = url_ftell(s->pb); |
1417 |
|
1418 |
return ret;
|
1419 |
} |
1420 |
|
1421 |
static int mpegts_read_close(AVFormatContext *s) |
1422 |
{ |
1423 |
MpegTSContext *ts = s->priv_data; |
1424 |
int i;
|
1425 |
|
1426 |
clear_programs(ts); |
1427 |
|
1428 |
for(i=0;i<NB_PID_MAX;i++) |
1429 |
if (ts->pids[i]) mpegts_close_filter(ts, ts->pids[i]);
|
1430 |
|
1431 |
return 0; |
1432 |
} |
1433 |
|
1434 |
static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index, |
1435 |
int64_t *ppos, int64_t pos_limit) |
1436 |
{ |
1437 |
MpegTSContext *ts = s->priv_data; |
1438 |
int64_t pos, timestamp; |
1439 |
uint8_t buf[TS_PACKET_SIZE]; |
1440 |
int pcr_l, pcr_pid = ((PESContext*)s->streams[stream_index]->priv_data)->pcr_pid;
|
1441 |
const int find_next= 1; |
1442 |
pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47;
|
1443 |
if (find_next) {
|
1444 |
for(;;) {
|
1445 |
url_fseek(s->pb, pos, SEEK_SET); |
1446 |
if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
|
1447 |
return AV_NOPTS_VALUE;
|
1448 |
if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) && |
1449 |
parse_pcr(×tamp, &pcr_l, buf) == 0) {
|
1450 |
break;
|
1451 |
} |
1452 |
pos += ts->raw_packet_size; |
1453 |
} |
1454 |
} else {
|
1455 |
for(;;) {
|
1456 |
pos -= ts->raw_packet_size; |
1457 |
if (pos < 0) |
1458 |
return AV_NOPTS_VALUE;
|
1459 |
url_fseek(s->pb, pos, SEEK_SET); |
1460 |
if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
|
1461 |
return AV_NOPTS_VALUE;
|
1462 |
if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) && |
1463 |
parse_pcr(×tamp, &pcr_l, buf) == 0) {
|
1464 |
break;
|
1465 |
} |
1466 |
} |
1467 |
} |
1468 |
*ppos = pos; |
1469 |
|
1470 |
return timestamp;
|
1471 |
} |
1472 |
|
1473 |
static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){ |
1474 |
MpegTSContext *ts = s->priv_data; |
1475 |
uint8_t buf[TS_PACKET_SIZE]; |
1476 |
int64_t pos; |
1477 |
|
1478 |
if(av_seek_frame_binary(s, stream_index, target_ts, flags) < 0) |
1479 |
return -1; |
1480 |
|
1481 |
pos= url_ftell(s->pb); |
1482 |
|
1483 |
for(;;) {
|
1484 |
url_fseek(s->pb, pos, SEEK_SET); |
1485 |
if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
|
1486 |
return -1; |
1487 |
// pid = AV_RB16(buf + 1) & 0x1fff;
|
1488 |
if(buf[1] & 0x40) break; |
1489 |
pos += ts->raw_packet_size; |
1490 |
} |
1491 |
url_fseek(s->pb, pos, SEEK_SET); |
1492 |
|
1493 |
return 0; |
1494 |
} |
1495 |
|
1496 |
/**************************************************************/
|
1497 |
/* parsing functions - called from other demuxers such as RTP */
|
1498 |
|
1499 |
MpegTSContext *mpegts_parse_open(AVFormatContext *s) |
1500 |
{ |
1501 |
MpegTSContext *ts; |
1502 |
|
1503 |
ts = av_mallocz(sizeof(MpegTSContext));
|
1504 |
if (!ts)
|
1505 |
return NULL; |
1506 |
/* no stream case, currently used by RTP */
|
1507 |
ts->raw_packet_size = TS_PACKET_SIZE; |
1508 |
ts->stream = s; |
1509 |
ts->auto_guess = 1;
|
1510 |
return ts;
|
1511 |
} |
1512 |
|
1513 |
/* return the consumed length if a packet was output, or -1 if no
|
1514 |
packet is output */
|
1515 |
int mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
|
1516 |
const uint8_t *buf, int len) |
1517 |
{ |
1518 |
int len1;
|
1519 |
|
1520 |
len1 = len; |
1521 |
ts->pkt = pkt; |
1522 |
ts->stop_parse = 0;
|
1523 |
for(;;) {
|
1524 |
if (ts->stop_parse>0) |
1525 |
break;
|
1526 |
if (len < TS_PACKET_SIZE)
|
1527 |
return -1; |
1528 |
if (buf[0] != 0x47) { |
1529 |
buf++; |
1530 |
len--; |
1531 |
} else {
|
1532 |
handle_packet(ts, buf); |
1533 |
buf += TS_PACKET_SIZE; |
1534 |
len -= TS_PACKET_SIZE; |
1535 |
} |
1536 |
} |
1537 |
return len1 - len;
|
1538 |
} |
1539 |
|
1540 |
void mpegts_parse_close(MpegTSContext *ts)
|
1541 |
{ |
1542 |
int i;
|
1543 |
|
1544 |
for(i=0;i<NB_PID_MAX;i++) |
1545 |
av_free(ts->pids[i]); |
1546 |
av_free(ts); |
1547 |
} |
1548 |
|
1549 |
AVInputFormat mpegts_demuxer = { |
1550 |
"mpegts",
|
1551 |
NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
|
1552 |
sizeof(MpegTSContext),
|
1553 |
mpegts_probe, |
1554 |
mpegts_read_header, |
1555 |
mpegts_read_packet, |
1556 |
mpegts_read_close, |
1557 |
read_seek, |
1558 |
mpegts_get_pcr, |
1559 |
.flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT, |
1560 |
}; |
1561 |
|
1562 |
AVInputFormat mpegtsraw_demuxer = { |
1563 |
"mpegtsraw",
|
1564 |
NULL_IF_CONFIG_SMALL("MPEG-2 raw transport stream format"),
|
1565 |
sizeof(MpegTSContext),
|
1566 |
NULL,
|
1567 |
mpegts_read_header, |
1568 |
mpegts_raw_read_packet, |
1569 |
mpegts_read_close, |
1570 |
read_seek, |
1571 |
mpegts_get_pcr, |
1572 |
.flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT, |
1573 |
}; |