00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/crc.h"
00023 #include "libavutil/intreadwrite.h"
00024 #include "avformat.h"
00025 #include "mpegts.h"
00026 #include "internal.h"
00027
00028
00029
00030
00031
00032 #define MAX_SCAN_PACKETS 32000
00033
00034
00035
00036 #define MAX_RESYNC_SIZE 4096
00037 #define REGISTRATION_DESCRIPTOR 5
00038
00039 typedef struct PESContext PESContext;
00040
00041 static PESContext* add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type);
00042 static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code);
00043
00044 enum MpegTSFilterType {
00045 MPEGTS_PES,
00046 MPEGTS_SECTION,
00047 };
00048
00049 typedef struct MpegTSFilter MpegTSFilter;
00050
00051 typedef void PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos);
00052
00053 typedef struct MpegTSPESFilter {
00054 PESCallback *pes_cb;
00055 void *opaque;
00056 } MpegTSPESFilter;
00057
00058 typedef void SectionCallback(MpegTSFilter *f, const uint8_t *buf, int len);
00059
00060 typedef void SetServiceCallback(void *opaque, int ret);
00061
00062 typedef struct MpegTSSectionFilter {
00063 int section_index;
00064 int section_h_size;
00065 uint8_t *section_buf;
00066 unsigned int check_crc:1;
00067 unsigned int end_of_section_reached:1;
00068 SectionCallback *section_cb;
00069 void *opaque;
00070 } MpegTSSectionFilter;
00071
00072 struct MpegTSFilter {
00073 int pid;
00074 int last_cc;
00075 enum MpegTSFilterType type;
00076 union {
00077 MpegTSPESFilter pes_filter;
00078 MpegTSSectionFilter section_filter;
00079 } u;
00080 };
00081
00082 #define MAX_PIDS_PER_PROGRAM 64
00083 struct Program {
00084 unsigned int id;
00085 unsigned int nb_pids;
00086 unsigned int pids[MAX_PIDS_PER_PROGRAM];
00087 };
00088
00089 struct MpegTSContext {
00090
00091 AVFormatContext *stream;
00093 int raw_packet_size;
00094
00095 int pos47;
00096
00098 int auto_guess;
00099
00101 int mpeg2ts_compute_pcr;
00102
00103 int64_t cur_pcr;
00104 int pcr_incr;
00106
00108 int stop_parse;
00110 AVPacket *pkt;
00111
00112
00113
00114
00116 unsigned int nb_prg;
00117 struct Program *prg;
00118
00119
00121 MpegTSFilter *pids[NB_PID_MAX];
00122 };
00123
00124
00125
00126 enum MpegTSState {
00127 MPEGTS_HEADER = 0,
00128 MPEGTS_PESHEADER_FILL,
00129 MPEGTS_PAYLOAD,
00130 MPEGTS_SKIP,
00131 };
00132
00133
00134 #define PES_START_SIZE 9
00135 #define MAX_PES_HEADER_SIZE (9 + 255)
00136
00137 struct PESContext {
00138 int pid;
00139 int pcr_pid;
00140 int stream_type;
00141 MpegTSContext *ts;
00142 AVFormatContext *stream;
00143 AVStream *st;
00144 enum MpegTSState state;
00145
00146 int data_index;
00147 int total_size;
00148 int pes_header_size;
00149 int64_t pts, dts;
00150 int64_t ts_packet_pos;
00151 uint8_t header[MAX_PES_HEADER_SIZE];
00152 };
00153
00154 extern AVInputFormat mpegts_demuxer;
00155
00156 static void clear_program(MpegTSContext *ts, unsigned int programid)
00157 {
00158 int i;
00159
00160 for(i=0; i<ts->nb_prg; i++)
00161 if(ts->prg[i].id == programid)
00162 ts->prg[i].nb_pids = 0;
00163 }
00164
00165 static void clear_programs(MpegTSContext *ts)
00166 {
00167 av_freep(&ts->prg);
00168 ts->nb_prg=0;
00169 }
00170
00171 static void add_pat_entry(MpegTSContext *ts, unsigned int programid)
00172 {
00173 struct Program *p;
00174 void *tmp = av_realloc(ts->prg, (ts->nb_prg+1)*sizeof(struct Program));
00175 if(!tmp)
00176 return;
00177 ts->prg = tmp;
00178 p = &ts->prg[ts->nb_prg];
00179 p->id = programid;
00180 p->nb_pids = 0;
00181 ts->nb_prg++;
00182 }
00183
00184 static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, unsigned int pid)
00185 {
00186 int i;
00187 struct Program *p = NULL;
00188 for(i=0; i<ts->nb_prg; i++) {
00189 if(ts->prg[i].id == programid) {
00190 p = &ts->prg[i];
00191 break;
00192 }
00193 }
00194 if(!p)
00195 return;
00196
00197 if(p->nb_pids >= MAX_PIDS_PER_PROGRAM)
00198 return;
00199 p->pids[p->nb_pids++] = pid;
00200 }
00201
00210 static int discard_pid(MpegTSContext *ts, unsigned int pid)
00211 {
00212 int i, j, k;
00213 int used = 0, discarded = 0;
00214 struct Program *p;
00215 for(i=0; i<ts->nb_prg; i++) {
00216 p = &ts->prg[i];
00217 for(j=0; j<p->nb_pids; j++) {
00218 if(p->pids[j] != pid)
00219 continue;
00220
00221 for(k=0; k<ts->stream->nb_programs; k++) {
00222 if(ts->stream->programs[k]->id == p->id) {
00223 if(ts->stream->programs[k]->discard == AVDISCARD_ALL)
00224 discarded++;
00225 else
00226 used++;
00227 }
00228 }
00229 }
00230 }
00231
00232 return !used && discarded;
00233 }
00234
00239 static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
00240 const uint8_t *buf, int buf_size, int is_start)
00241 {
00242 MpegTSSectionFilter *tss = &tss1->u.section_filter;
00243 int len;
00244
00245 if (is_start) {
00246 memcpy(tss->section_buf, buf, buf_size);
00247 tss->section_index = buf_size;
00248 tss->section_h_size = -1;
00249 tss->end_of_section_reached = 0;
00250 } else {
00251 if (tss->end_of_section_reached)
00252 return;
00253 len = 4096 - tss->section_index;
00254 if (buf_size < len)
00255 len = buf_size;
00256 memcpy(tss->section_buf + tss->section_index, buf, len);
00257 tss->section_index += len;
00258 }
00259
00260
00261 if (tss->section_h_size == -1 && tss->section_index >= 3) {
00262 len = (AV_RB16(tss->section_buf + 1) & 0xfff) + 3;
00263 if (len > 4096)
00264 return;
00265 tss->section_h_size = len;
00266 }
00267
00268 if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) {
00269 tss->end_of_section_reached = 1;
00270 if (!tss->check_crc ||
00271 av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1,
00272 tss->section_buf, tss->section_h_size) == 0)
00273 tss->section_cb(tss1, tss->section_buf, tss->section_h_size);
00274 }
00275 }
00276
00277 static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int pid,
00278 SectionCallback *section_cb, void *opaque,
00279 int check_crc)
00280
00281 {
00282 MpegTSFilter *filter;
00283 MpegTSSectionFilter *sec;
00284
00285 #ifdef DEBUG_SI
00286 av_log(ts->stream, AV_LOG_DEBUG, "Filter: pid=0x%x\n", pid);
00287 #endif
00288 if (pid >= NB_PID_MAX || ts->pids[pid])
00289 return NULL;
00290 filter = av_mallocz(sizeof(MpegTSFilter));
00291 if (!filter)
00292 return NULL;
00293 ts->pids[pid] = filter;
00294 filter->type = MPEGTS_SECTION;
00295 filter->pid = pid;
00296 filter->last_cc = -1;
00297 sec = &filter->u.section_filter;
00298 sec->section_cb = section_cb;
00299 sec->opaque = opaque;
00300 sec->section_buf = av_malloc(MAX_SECTION_SIZE);
00301 sec->check_crc = check_crc;
00302 if (!sec->section_buf) {
00303 av_free(filter);
00304 return NULL;
00305 }
00306 return filter;
00307 }
00308
00309 static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid,
00310 PESCallback *pes_cb,
00311 void *opaque)
00312 {
00313 MpegTSFilter *filter;
00314 MpegTSPESFilter *pes;
00315
00316 if (pid >= NB_PID_MAX || ts->pids[pid])
00317 return NULL;
00318 filter = av_mallocz(sizeof(MpegTSFilter));
00319 if (!filter)
00320 return NULL;
00321 ts->pids[pid] = filter;
00322 filter->type = MPEGTS_PES;
00323 filter->pid = pid;
00324 filter->last_cc = -1;
00325 pes = &filter->u.pes_filter;
00326 pes->pes_cb = pes_cb;
00327 pes->opaque = opaque;
00328 return filter;
00329 }
00330
00331 static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
00332 {
00333 int pid;
00334
00335 pid = filter->pid;
00336 if (filter->type == MPEGTS_SECTION)
00337 av_freep(&filter->u.section_filter.section_buf);
00338 else if (filter->type == MPEGTS_PES) {
00339
00340
00341 if (!((PESContext *)filter->u.pes_filter.opaque)->st) {
00342 av_freep(&filter->u.pes_filter.opaque);
00343 }
00344 }
00345
00346 av_free(filter);
00347 ts->pids[pid] = NULL;
00348 }
00349
00350 static int analyze(const uint8_t *buf, int size, int packet_size, int *index){
00351 int stat[packet_size];
00352 int i;
00353 int x=0;
00354 int best_score=0;
00355
00356 memset(stat, 0, packet_size*sizeof(int));
00357
00358 for(x=i=0; i<size-3; i++){
00359 if(buf[i] == 0x47 && !(buf[i+1] & 0x80) && (buf[i+3] & 0x30)){
00360 stat[x]++;
00361 if(stat[x] > best_score){
00362 best_score= stat[x];
00363 if(index) *index= x;
00364 }
00365 }
00366
00367 x++;
00368 if(x == packet_size) x= 0;
00369 }
00370
00371 return best_score;
00372 }
00373
00374
00375 static int get_packet_size(const uint8_t *buf, int size)
00376 {
00377 int score, fec_score, dvhs_score;
00378
00379 if (size < (TS_FEC_PACKET_SIZE * 5 + 1))
00380 return -1;
00381
00382 score = analyze(buf, size, TS_PACKET_SIZE, NULL);
00383 dvhs_score = analyze(buf, size, TS_DVHS_PACKET_SIZE, NULL);
00384 fec_score= analyze(buf, size, TS_FEC_PACKET_SIZE, NULL);
00385
00386
00387 if (score > fec_score && score > dvhs_score) return TS_PACKET_SIZE;
00388 else if(dvhs_score > score && dvhs_score > fec_score) return TS_DVHS_PACKET_SIZE;
00389 else if(score < fec_score && dvhs_score < fec_score) return TS_FEC_PACKET_SIZE;
00390 else return -1;
00391 }
00392
00393 typedef struct SectionHeader {
00394 uint8_t tid;
00395 uint16_t id;
00396 uint8_t version;
00397 uint8_t sec_num;
00398 uint8_t last_sec_num;
00399 } SectionHeader;
00400
00401 static inline int get8(const uint8_t **pp, const uint8_t *p_end)
00402 {
00403 const uint8_t *p;
00404 int c;
00405
00406 p = *pp;
00407 if (p >= p_end)
00408 return -1;
00409 c = *p++;
00410 *pp = p;
00411 return c;
00412 }
00413
00414 static inline int get16(const uint8_t **pp, const uint8_t *p_end)
00415 {
00416 const uint8_t *p;
00417 int c;
00418
00419 p = *pp;
00420 if ((p + 1) >= p_end)
00421 return -1;
00422 c = AV_RB16(p);
00423 p += 2;
00424 *pp = p;
00425 return c;
00426 }
00427
00428
00429 static char *getstr8(const uint8_t **pp, const uint8_t *p_end)
00430 {
00431 int len;
00432 const uint8_t *p;
00433 char *str;
00434
00435 p = *pp;
00436 len = get8(&p, p_end);
00437 if (len < 0)
00438 return NULL;
00439 if ((p + len) > p_end)
00440 return NULL;
00441 str = av_malloc(len + 1);
00442 if (!str)
00443 return NULL;
00444 memcpy(str, p, len);
00445 str[len] = '\0';
00446 p += len;
00447 *pp = p;
00448 return str;
00449 }
00450
00451 static int parse_section_header(SectionHeader *h,
00452 const uint8_t **pp, const uint8_t *p_end)
00453 {
00454 int val;
00455
00456 val = get8(pp, p_end);
00457 if (val < 0)
00458 return -1;
00459 h->tid = val;
00460 *pp += 2;
00461 val = get16(pp, p_end);
00462 if (val < 0)
00463 return -1;
00464 h->id = val;
00465 val = get8(pp, p_end);
00466 if (val < 0)
00467 return -1;
00468 h->version = (val >> 1) & 0x1f;
00469 val = get8(pp, p_end);
00470 if (val < 0)
00471 return -1;
00472 h->sec_num = val;
00473 val = get8(pp, p_end);
00474 if (val < 0)
00475 return -1;
00476 h->last_sec_num = val;
00477 return 0;
00478 }
00479
00480
00481 static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
00482 {
00483 MpegTSContext *ts = filter->u.section_filter.opaque;
00484 SectionHeader h1, *h = &h1;
00485 PESContext *pes;
00486 AVStream *st;
00487 const uint8_t *p, *p_end, *desc_list_end, *desc_end;
00488 int program_info_length, pcr_pid, pid, stream_type;
00489 int desc_list_len, desc_len, desc_tag;
00490 int comp_page = 0, anc_page = 0;
00491 char language[4] = {0};
00492 int has_hdmv_descr = 0;
00493 int has_dirac_descr = 0;
00494
00495 #ifdef DEBUG_SI
00496 av_log(ts->stream, AV_LOG_DEBUG, "PMT: len %i\n", section_len);
00497 av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
00498 #endif
00499 p_end = section + section_len - 4;
00500 p = section;
00501 if (parse_section_header(h, &p, p_end) < 0)
00502 return;
00503 #ifdef DEBUG_SI
00504 av_log(ts->stream, AV_LOG_DEBUG, "sid=0x%x sec_num=%d/%d\n",
00505 h->id, h->sec_num, h->last_sec_num);
00506 #endif
00507 if (h->tid != PMT_TID)
00508 return;
00509
00510 clear_program(ts, h->id);
00511 pcr_pid = get16(&p, p_end) & 0x1fff;
00512 if (pcr_pid < 0)
00513 return;
00514 add_pid_to_pmt(ts, h->id, pcr_pid);
00515 #ifdef DEBUG_SI
00516 av_log(ts->stream, AV_LOG_DEBUG, "pcr_pid=0x%x\n", pcr_pid);
00517 #endif
00518 program_info_length = get16(&p, p_end) & 0xfff;
00519 if (program_info_length < 0)
00520 return;
00521 while(program_info_length >= 2) {
00522 uint8_t tag, len;
00523 tag = get8(&p, p_end);
00524 len = get8(&p, p_end);
00525 if(len > program_info_length - 2)
00526
00527 break;
00528 program_info_length -= len + 2;
00529 if(tag == REGISTRATION_DESCRIPTOR && len >= 4) {
00530 uint8_t bytes[4];
00531 bytes[0] = get8(&p, p_end);
00532 bytes[1] = get8(&p, p_end);
00533 bytes[2] = get8(&p, p_end);
00534 bytes[3] = get8(&p, p_end);
00535 len -= 4;
00536 if(bytes[0] == 'H' && bytes[1] == 'D' &&
00537 bytes[2] == 'M' && bytes[3] == 'V')
00538 has_hdmv_descr = 1;
00539 }
00540 p += len;
00541 }
00542 p += program_info_length;
00543 if (p >= p_end)
00544 return;
00545 for(;;) {
00546 language[0] = 0;
00547 st = 0;
00548 stream_type = get8(&p, p_end);
00549 if (stream_type < 0)
00550 break;
00551 pid = get16(&p, p_end) & 0x1fff;
00552 if (pid < 0)
00553 break;
00554 desc_list_len = get16(&p, p_end) & 0xfff;
00555 if (desc_list_len < 0)
00556 break;
00557 desc_list_end = p + desc_list_len;
00558 if (desc_list_end > p_end)
00559 break;
00560 for(;;) {
00561 desc_tag = get8(&p, desc_list_end);
00562 if (desc_tag < 0)
00563 break;
00564 if (stream_type == STREAM_TYPE_PRIVATE_DATA) {
00565 if((desc_tag == 0x6A) || (desc_tag == 0x7A)) {
00566
00567 stream_type = STREAM_TYPE_AUDIO_AC3;
00568 } else if(desc_tag == 0x7B) {
00569
00570 stream_type = STREAM_TYPE_AUDIO_DTS;
00571 }
00572 }
00573 desc_len = get8(&p, desc_list_end);
00574 desc_end = p + desc_len;
00575 if (desc_end > desc_list_end)
00576 break;
00577 #ifdef DEBUG_SI
00578 av_log(ts->stream, AV_LOG_DEBUG, "tag: 0x%02x len=%d\n",
00579 desc_tag, desc_len);
00580 #endif
00581 switch(desc_tag) {
00582 case DVB_SUBT_DESCID:
00583 if (stream_type == STREAM_TYPE_PRIVATE_DATA)
00584 stream_type = STREAM_TYPE_SUBTITLE_DVB;
00585
00586 language[0] = get8(&p, desc_end);
00587 language[1] = get8(&p, desc_end);
00588 language[2] = get8(&p, desc_end);
00589 language[3] = 0;
00590 get8(&p, desc_end);
00591 comp_page = get16(&p, desc_end);
00592 anc_page = get16(&p, desc_end);
00593
00594 break;
00595 case 0x0a:
00596 language[0] = get8(&p, desc_end);
00597 language[1] = get8(&p, desc_end);
00598 language[2] = get8(&p, desc_end);
00599 language[3] = 0;
00600 break;
00601 case REGISTRATION_DESCRIPTOR:
00602 {
00603 uint8_t bytes[4];
00604 bytes[0] = get8(&p, desc_end);
00605 bytes[1] = get8(&p, desc_end);
00606 bytes[2] = get8(&p, desc_end);
00607 bytes[3] = get8(&p, desc_end);
00608 if(bytes[0] == 'd' && bytes[1] == 'r' &&
00609 bytes[2] == 'a' && bytes[3] == 'c')
00610 has_dirac_descr = 1;
00611 break;
00612 }
00613 default:
00614 break;
00615 }
00616 p = desc_end;
00617 }
00618 p = desc_list_end;
00619
00620 #ifdef DEBUG_SI
00621 av_log(ts->stream, AV_LOG_DEBUG, "stream_type=%d pid=0x%x\n",
00622 stream_type, pid);
00623 #endif
00624
00625
00626 switch(stream_type) {
00627 case STREAM_TYPE_AUDIO_MPEG1:
00628 case STREAM_TYPE_AUDIO_MPEG2:
00629 case STREAM_TYPE_VIDEO_MPEG1:
00630 case STREAM_TYPE_VIDEO_MPEG2:
00631 case STREAM_TYPE_VIDEO_MPEG4:
00632 case STREAM_TYPE_VIDEO_H264:
00633 case STREAM_TYPE_VIDEO_VC1:
00634 case STREAM_TYPE_VIDEO_DIRAC:
00635 case STREAM_TYPE_AUDIO_AAC:
00636 case STREAM_TYPE_AUDIO_AC3:
00637 case STREAM_TYPE_AUDIO_DTS:
00638 case STREAM_TYPE_AUDIO_HDMV_DTS:
00639 case STREAM_TYPE_SUBTITLE_DVB:
00640 if((stream_type == STREAM_TYPE_AUDIO_HDMV_DTS && !has_hdmv_descr)
00641 || (stream_type == STREAM_TYPE_VIDEO_DIRAC && !has_dirac_descr))
00642 break;
00643 if(ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES){
00644 pes= ts->pids[pid]->u.pes_filter.opaque;
00645 st= pes->st;
00646 }else{
00647 if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]);
00648 pes = add_pes_stream(ts, pid, pcr_pid, stream_type);
00649 if (pes)
00650 st = new_pes_av_stream(pes, 0);
00651 }
00652 add_pid_to_pmt(ts, h->id, pid);
00653 if(st)
00654 av_program_add_stream_index(ts->stream, h->id, st->index);
00655 break;
00656 default:
00657
00658 break;
00659 }
00660
00661 if (st) {
00662 if (language[0] != 0) {
00663 av_metadata_set(&st->metadata, "language", language);
00664 }
00665
00666 if (stream_type == STREAM_TYPE_SUBTITLE_DVB) {
00667 st->codec->sub_id = (anc_page << 16) | comp_page;
00668 }
00669 }
00670 }
00671
00672 ts->stop_parse++;
00673 mpegts_close_filter(ts, filter);
00674 }
00675
00676 static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
00677 {
00678 MpegTSContext *ts = filter->u.section_filter.opaque;
00679 SectionHeader h1, *h = &h1;
00680 const uint8_t *p, *p_end;
00681 int sid, pmt_pid;
00682
00683 #ifdef DEBUG_SI
00684 av_log(ts->stream, AV_LOG_DEBUG, "PAT:\n");
00685 av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
00686 #endif
00687 p_end = section + section_len - 4;
00688 p = section;
00689 if (parse_section_header(h, &p, p_end) < 0)
00690 return;
00691 if (h->tid != PAT_TID)
00692 return;
00693
00694 clear_programs(ts);
00695 for(;;) {
00696 sid = get16(&p, p_end);
00697 if (sid < 0)
00698 break;
00699 pmt_pid = get16(&p, p_end) & 0x1fff;
00700 if (pmt_pid < 0)
00701 break;
00702 #ifdef DEBUG_SI
00703 av_log(ts->stream, AV_LOG_DEBUG, "sid=0x%x pid=0x%x\n", sid, pmt_pid);
00704 #endif
00705 if (sid == 0x0000) {
00706
00707 } else {
00708 av_new_program(ts->stream, sid);
00709 ts->stop_parse--;
00710 mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
00711 add_pat_entry(ts, sid);
00712 add_pid_to_pmt(ts, sid, 0);
00713 add_pid_to_pmt(ts, sid, pmt_pid);
00714 }
00715 }
00716
00717 ts->stop_parse++;
00718
00719 mpegts_close_filter(ts, filter);
00720 }
00721
00722 static void mpegts_set_service(MpegTSContext *ts)
00723 {
00724 mpegts_open_section_filter(ts, PAT_PID,
00725 pat_cb, ts, 1);
00726 }
00727
00728 static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
00729 {
00730 MpegTSContext *ts = filter->u.section_filter.opaque;
00731 SectionHeader h1, *h = &h1;
00732 const uint8_t *p, *p_end, *desc_list_end, *desc_end;
00733 int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
00734 char *name, *provider_name;
00735
00736 #ifdef DEBUG_SI
00737 av_log(ts->stream, AV_LOG_DEBUG, "SDT:\n");
00738 av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
00739 #endif
00740
00741 p_end = section + section_len - 4;
00742 p = section;
00743 if (parse_section_header(h, &p, p_end) < 0)
00744 return;
00745 if (h->tid != SDT_TID)
00746 return;
00747 onid = get16(&p, p_end);
00748 if (onid < 0)
00749 return;
00750 val = get8(&p, p_end);
00751 if (val < 0)
00752 return;
00753 for(;;) {
00754 sid = get16(&p, p_end);
00755 if (sid < 0)
00756 break;
00757 val = get8(&p, p_end);
00758 if (val < 0)
00759 break;
00760 desc_list_len = get16(&p, p_end) & 0xfff;
00761 if (desc_list_len < 0)
00762 break;
00763 desc_list_end = p + desc_list_len;
00764 if (desc_list_end > p_end)
00765 break;
00766 for(;;) {
00767 desc_tag = get8(&p, desc_list_end);
00768 if (desc_tag < 0)
00769 break;
00770 desc_len = get8(&p, desc_list_end);
00771 desc_end = p + desc_len;
00772 if (desc_end > desc_list_end)
00773 break;
00774 #ifdef DEBUG_SI
00775 av_log(ts->stream, AV_LOG_DEBUG, "tag: 0x%02x len=%d\n",
00776 desc_tag, desc_len);
00777 #endif
00778 switch(desc_tag) {
00779 case 0x48:
00780 service_type = get8(&p, p_end);
00781 if (service_type < 0)
00782 break;
00783 provider_name = getstr8(&p, p_end);
00784 if (!provider_name)
00785 break;
00786 name = getstr8(&p, p_end);
00787 if (name) {
00788 AVProgram *program = av_new_program(ts->stream, sid);
00789 if(program) {
00790 av_metadata_set(&program->metadata, "name", name);
00791 av_metadata_set(&program->metadata, "provider_name", provider_name);
00792 }
00793 }
00794 av_free(name);
00795 av_free(provider_name);
00796 break;
00797 default:
00798 break;
00799 }
00800 p = desc_end;
00801 }
00802 p = desc_list_end;
00803 }
00804 }
00805
00806
00807 static void mpegts_scan_sdt(MpegTSContext *ts)
00808 {
00809 mpegts_open_section_filter(ts, SDT_PID,
00810 sdt_cb, ts, 1);
00811 }
00812
00813 static int64_t get_pts(const uint8_t *p)
00814 {
00815 int64_t pts = (int64_t)((p[0] >> 1) & 0x07) << 30;
00816 pts |= (AV_RB16(p + 1) >> 1) << 15;
00817 pts |= AV_RB16(p + 3) >> 1;
00818 return pts;
00819 }
00820
00821
00822 static void mpegts_push_data(MpegTSFilter *filter,
00823 const uint8_t *buf, int buf_size, int is_start,
00824 int64_t pos)
00825 {
00826 PESContext *pes = filter->u.pes_filter.opaque;
00827 MpegTSContext *ts = pes->ts;
00828 const uint8_t *p;
00829 int len, code;
00830
00831 if(!ts->pkt)
00832 return;
00833
00834 if (is_start) {
00835 pes->state = MPEGTS_HEADER;
00836 pes->data_index = 0;
00837 pes->ts_packet_pos = pos;
00838 }
00839 p = buf;
00840 while (buf_size > 0) {
00841 switch(pes->state) {
00842 case MPEGTS_HEADER:
00843 len = PES_START_SIZE - pes->data_index;
00844 if (len > buf_size)
00845 len = buf_size;
00846 memcpy(pes->header + pes->data_index, p, len);
00847 pes->data_index += len;
00848 p += len;
00849 buf_size -= len;
00850 if (pes->data_index == PES_START_SIZE) {
00851
00852
00853 #if 0
00854 av_hex_dump_log(pes->stream, AV_LOG_DEBUG, pes->header, pes->data_index);
00855 #endif
00856 if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
00857 pes->header[2] == 0x01) {
00858
00859 code = pes->header[3] | 0x100;
00860 if (!((code >= 0x1c0 && code <= 0x1df) ||
00861 (code >= 0x1e0 && code <= 0x1ef) ||
00862 (code == 0x1bd) || (code == 0x1fd)))
00863 goto skip;
00864 if (!pes->st) {
00865
00866 new_pes_av_stream(pes, code);
00867 }
00868 pes->state = MPEGTS_PESHEADER_FILL;
00869 pes->total_size = AV_RB16(pes->header + 4);
00870
00871
00872 if (pes->total_size)
00873 pes->total_size += 6;
00874 pes->pes_header_size = pes->header[8] + 9;
00875 } else {
00876
00877
00878 skip:
00879 pes->state = MPEGTS_SKIP;
00880 continue;
00881 }
00882 }
00883 break;
00884
00885
00886 case MPEGTS_PESHEADER_FILL:
00887 len = pes->pes_header_size - pes->data_index;
00888 if (len > buf_size)
00889 len = buf_size;
00890 memcpy(pes->header + pes->data_index, p, len);
00891 pes->data_index += len;
00892 p += len;
00893 buf_size -= len;
00894 if (pes->data_index == pes->pes_header_size) {
00895 const uint8_t *r;
00896 unsigned int flags;
00897
00898 flags = pes->header[7];
00899 r = pes->header + 9;
00900 pes->pts = AV_NOPTS_VALUE;
00901 pes->dts = AV_NOPTS_VALUE;
00902 if ((flags & 0xc0) == 0x80) {
00903 pes->dts = pes->pts = get_pts(r);
00904 r += 5;
00905 } else if ((flags & 0xc0) == 0xc0) {
00906 pes->pts = get_pts(r);
00907 r += 5;
00908 pes->dts = get_pts(r);
00909 r += 5;
00910 }
00911
00912 pes->state = MPEGTS_PAYLOAD;
00913 }
00914 break;
00915 case MPEGTS_PAYLOAD:
00916 if (pes->total_size) {
00917 len = pes->total_size - pes->data_index;
00918 if (len > buf_size)
00919 len = buf_size;
00920 } else {
00921 len = buf_size;
00922 }
00923 if (len > 0) {
00924 AVPacket *pkt = ts->pkt;
00925 if (pes->st && av_new_packet(pkt, len) == 0) {
00926 memcpy(pkt->data, p, len);
00927 pkt->stream_index = pes->st->index;
00928 pkt->pts = pes->pts;
00929 pkt->dts = pes->dts;
00930
00931 pkt->pos = pes->ts_packet_pos;
00932
00933 pes->pts = AV_NOPTS_VALUE;
00934 pes->dts = AV_NOPTS_VALUE;
00935 ts->stop_parse = 1;
00936 return;
00937 }
00938 }
00939 buf_size = 0;
00940 break;
00941 case MPEGTS_SKIP:
00942 buf_size = 0;
00943 break;
00944 }
00945 }
00946 }
00947
00948 static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code)
00949 {
00950 AVStream *st;
00951 enum CodecID codec_id;
00952 enum CodecType codec_type;
00953
00954 switch(pes->stream_type){
00955 case STREAM_TYPE_AUDIO_MPEG1:
00956 case STREAM_TYPE_AUDIO_MPEG2:
00957 codec_type = CODEC_TYPE_AUDIO;
00958 codec_id = CODEC_ID_MP3;
00959 break;
00960 case STREAM_TYPE_VIDEO_MPEG1:
00961 case STREAM_TYPE_VIDEO_MPEG2:
00962 codec_type = CODEC_TYPE_VIDEO;
00963 codec_id = CODEC_ID_MPEG2VIDEO;
00964 break;
00965 case STREAM_TYPE_VIDEO_MPEG4:
00966 codec_type = CODEC_TYPE_VIDEO;
00967 codec_id = CODEC_ID_MPEG4;
00968 break;
00969 case STREAM_TYPE_VIDEO_H264:
00970 codec_type = CODEC_TYPE_VIDEO;
00971 codec_id = CODEC_ID_H264;
00972 break;
00973 case STREAM_TYPE_VIDEO_VC1:
00974 codec_type = CODEC_TYPE_VIDEO;
00975 codec_id = CODEC_ID_VC1;
00976 break;
00977 case STREAM_TYPE_VIDEO_DIRAC:
00978 codec_type = CODEC_TYPE_VIDEO;
00979 codec_id = CODEC_ID_DIRAC;
00980 break;
00981 case STREAM_TYPE_AUDIO_AAC:
00982 codec_type = CODEC_TYPE_AUDIO;
00983 codec_id = CODEC_ID_AAC;
00984 break;
00985 case STREAM_TYPE_AUDIO_AC3:
00986 codec_type = CODEC_TYPE_AUDIO;
00987 codec_id = CODEC_ID_AC3;
00988 break;
00989 case STREAM_TYPE_AUDIO_DTS:
00990 case STREAM_TYPE_AUDIO_HDMV_DTS:
00991 codec_type = CODEC_TYPE_AUDIO;
00992 codec_id = CODEC_ID_DTS;
00993 break;
00994 case STREAM_TYPE_SUBTITLE_DVB:
00995 codec_type = CODEC_TYPE_SUBTITLE;
00996 codec_id = CODEC_ID_DVB_SUBTITLE;
00997 break;
00998 default:
00999 if (code >= 0x1c0 && code <= 0x1df) {
01000 codec_type = CODEC_TYPE_AUDIO;
01001 codec_id = CODEC_ID_MP2;
01002 } else if (code == 0x1bd) {
01003 codec_type = CODEC_TYPE_AUDIO;
01004 codec_id = CODEC_ID_AC3;
01005 } else {
01006 codec_type = CODEC_TYPE_VIDEO;
01007 codec_id = CODEC_ID_PROBE;
01008 }
01009 break;
01010 }
01011 st = av_new_stream(pes->stream, pes->pid);
01012 if (st) {
01013 av_set_pts_info(st, 33, 1, 90000);
01014 st->priv_data = pes;
01015 st->codec->codec_type = codec_type;
01016 st->codec->codec_id = codec_id;
01017 st->need_parsing = AVSTREAM_PARSE_FULL;
01018 pes->st = st;
01019 }
01020 return st;
01021 }
01022
01023
01024 static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type)
01025 {
01026 MpegTSFilter *tss;
01027 PESContext *pes;
01028
01029
01030 pes = av_mallocz(sizeof(PESContext));
01031 if (!pes)
01032 return 0;
01033 pes->ts = ts;
01034 pes->stream = ts->stream;
01035 pes->pid = pid;
01036 pes->pcr_pid = pcr_pid;
01037 pes->stream_type = stream_type;
01038 tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
01039 if (!tss) {
01040 av_free(pes);
01041 return 0;
01042 }
01043 return pes;
01044 }
01045
01046
01047 static void handle_packet(MpegTSContext *ts, const uint8_t *packet)
01048 {
01049 AVFormatContext *s = ts->stream;
01050 MpegTSFilter *tss;
01051 int len, pid, cc, cc_ok, afc, is_start;
01052 const uint8_t *p, *p_end;
01053 int64_t pos;
01054
01055 pid = AV_RB16(packet + 1) & 0x1fff;
01056 if(pid && discard_pid(ts, pid))
01057 return;
01058 is_start = packet[1] & 0x40;
01059 tss = ts->pids[pid];
01060 if (ts->auto_guess && tss == NULL && is_start) {
01061 add_pes_stream(ts, pid, -1, 0);
01062 tss = ts->pids[pid];
01063 }
01064 if (!tss)
01065 return;
01066
01067
01068 cc = (packet[3] & 0xf);
01069 cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));
01070 tss->last_cc = cc;
01071
01072
01073 afc = (packet[3] >> 4) & 3;
01074 p = packet + 4;
01075 if (afc == 0)
01076 return;
01077 if (afc == 2)
01078 return;
01079 if (afc == 3) {
01080
01081 p += p[0] + 1;
01082 }
01083
01084 p_end = packet + TS_PACKET_SIZE;
01085 if (p >= p_end)
01086 return;
01087
01088 pos = url_ftell(ts->stream->pb);
01089 ts->pos47= pos % ts->raw_packet_size;
01090
01091 if (tss->type == MPEGTS_SECTION) {
01092 if (is_start) {
01093
01094 len = *p++;
01095 if (p + len > p_end)
01096 return;
01097 if (len && cc_ok) {
01098
01099 write_section_data(s, tss,
01100 p, len, 0);
01101
01102 if (!ts->pids[pid])
01103 return;
01104 }
01105 p += len;
01106 if (p < p_end) {
01107 write_section_data(s, tss,
01108 p, p_end - p, 1);
01109 }
01110 } else {
01111 if (cc_ok) {
01112 write_section_data(s, tss,
01113 p, p_end - p, 0);
01114 }
01115 }
01116 } else {
01117
01118 tss->u.pes_filter.pes_cb(tss,
01119 p, p_end - p, is_start, pos - ts->raw_packet_size);
01120 }
01121 }
01122
01123
01124
01125 static int mpegts_resync(ByteIOContext *pb)
01126 {
01127 int c, i;
01128
01129 for(i = 0;i < MAX_RESYNC_SIZE; i++) {
01130 c = url_fgetc(pb);
01131 if (c < 0)
01132 return -1;
01133 if (c == 0x47) {
01134 url_fseek(pb, -1, SEEK_CUR);
01135 return 0;
01136 }
01137 }
01138
01139 return -1;
01140 }
01141
01142
01143 static int read_packet(ByteIOContext *pb, uint8_t *buf, int raw_packet_size)
01144 {
01145 int skip, len;
01146
01147 for(;;) {
01148 len = get_buffer(pb, buf, TS_PACKET_SIZE);
01149 if (len != TS_PACKET_SIZE)
01150 return AVERROR(EIO);
01151
01152 if (buf[0] != 0x47) {
01153
01154 url_fseek(pb, -TS_PACKET_SIZE, SEEK_CUR);
01155 if (mpegts_resync(pb) < 0)
01156 return AVERROR_INVALIDDATA;
01157 else
01158 continue;
01159 } else {
01160 skip = raw_packet_size - TS_PACKET_SIZE;
01161 if (skip > 0)
01162 url_fskip(pb, skip);
01163 break;
01164 }
01165 }
01166 return 0;
01167 }
01168
01169 static int handle_packets(MpegTSContext *ts, int nb_packets)
01170 {
01171 AVFormatContext *s = ts->stream;
01172 ByteIOContext *pb = s->pb;
01173 uint8_t packet[TS_PACKET_SIZE];
01174 int packet_num, ret;
01175
01176 ts->stop_parse = 0;
01177 packet_num = 0;
01178 for(;;) {
01179 if (ts->stop_parse>0)
01180 break;
01181 packet_num++;
01182 if (nb_packets != 0 && packet_num >= nb_packets)
01183 break;
01184 ret = read_packet(pb, packet, ts->raw_packet_size);
01185 if (ret != 0)
01186 return ret;
01187 handle_packet(ts, packet);
01188 }
01189 return 0;
01190 }
01191
01192 static int mpegts_probe(AVProbeData *p)
01193 {
01194 #if 1
01195 const int size= p->buf_size;
01196 int score, fec_score, dvhs_score;
01197 int check_count= size / TS_FEC_PACKET_SIZE;
01198 #define CHECK_COUNT 10
01199
01200 if (check_count < CHECK_COUNT)
01201 return -1;
01202
01203 score = analyze(p->buf, TS_PACKET_SIZE *check_count, TS_PACKET_SIZE , NULL)*CHECK_COUNT/check_count;
01204 dvhs_score= analyze(p->buf, TS_DVHS_PACKET_SIZE*check_count, TS_DVHS_PACKET_SIZE, NULL)*CHECK_COUNT/check_count;
01205 fec_score = analyze(p->buf, TS_FEC_PACKET_SIZE *check_count, TS_FEC_PACKET_SIZE , NULL)*CHECK_COUNT/check_count;
01206
01207
01208
01209 if (score > fec_score && score > dvhs_score && score > 6) return AVPROBE_SCORE_MAX + score - CHECK_COUNT;
01210 else if(dvhs_score > score && dvhs_score > fec_score && dvhs_score > 6) return AVPROBE_SCORE_MAX + dvhs_score - CHECK_COUNT;
01211 else if( fec_score > 6) return AVPROBE_SCORE_MAX + fec_score - CHECK_COUNT;
01212 else return -1;
01213 #else
01214
01215 if (match_ext(p->filename, "ts"))
01216 return AVPROBE_SCORE_MAX;
01217 else
01218 return 0;
01219 #endif
01220 }
01221
01222
01223
01224 static int parse_pcr(int64_t *ppcr_high, int *ppcr_low,
01225 const uint8_t *packet)
01226 {
01227 int afc, len, flags;
01228 const uint8_t *p;
01229 unsigned int v;
01230
01231 afc = (packet[3] >> 4) & 3;
01232 if (afc <= 1)
01233 return -1;
01234 p = packet + 4;
01235 len = p[0];
01236 p++;
01237 if (len == 0)
01238 return -1;
01239 flags = *p++;
01240 len--;
01241 if (!(flags & 0x10))
01242 return -1;
01243 if (len < 6)
01244 return -1;
01245 v = AV_RB32(p);
01246 *ppcr_high = ((int64_t)v << 1) | (p[4] >> 7);
01247 *ppcr_low = ((p[4] & 1) << 8) | p[5];
01248 return 0;
01249 }
01250
01251 static int mpegts_read_header(AVFormatContext *s,
01252 AVFormatParameters *ap)
01253 {
01254 MpegTSContext *ts = s->priv_data;
01255 ByteIOContext *pb = s->pb;
01256 uint8_t buf[5*1024];
01257 int len;
01258 int64_t pos;
01259
01260 if (ap) {
01261 ts->mpeg2ts_compute_pcr = ap->mpeg2ts_compute_pcr;
01262 if(ap->mpeg2ts_raw){
01263 av_log(s, AV_LOG_ERROR, "use mpegtsraw_demuxer!\n");
01264 return -1;
01265 }
01266 }
01267
01268
01269 pos = url_ftell(pb);
01270 len = get_buffer(pb, buf, sizeof(buf));
01271 if (len != sizeof(buf))
01272 goto fail;
01273 ts->raw_packet_size = get_packet_size(buf, sizeof(buf));
01274 if (ts->raw_packet_size <= 0)
01275 goto fail;
01276 ts->stream = s;
01277 ts->auto_guess = 0;
01278
01279 if (s->iformat == &mpegts_demuxer) {
01280
01281
01282
01283 url_fseek(pb, pos, SEEK_SET);
01284 mpegts_scan_sdt(ts);
01285
01286 mpegts_set_service(ts);
01287
01288 handle_packets(ts, s->probesize);
01289
01290
01291 ts->auto_guess = 1;
01292
01293 #ifdef DEBUG_SI
01294 av_log(ts->stream, AV_LOG_DEBUG, "tuning done\n");
01295 #endif
01296 s->ctx_flags |= AVFMTCTX_NOHEADER;
01297 } else {
01298 AVStream *st;
01299 int pcr_pid, pid, nb_packets, nb_pcrs, ret, pcr_l;
01300 int64_t pcrs[2], pcr_h;
01301 int packet_count[2];
01302 uint8_t packet[TS_PACKET_SIZE];
01303
01304
01305
01306 st = av_new_stream(s, 0);
01307 if (!st)
01308 goto fail;
01309 av_set_pts_info(st, 60, 1, 27000000);
01310 st->codec->codec_type = CODEC_TYPE_DATA;
01311 st->codec->codec_id = CODEC_ID_MPEG2TS;
01312
01313
01314 pcr_pid = -1;
01315 nb_pcrs = 0;
01316 nb_packets = 0;
01317 for(;;) {
01318 ret = read_packet(s->pb, packet, ts->raw_packet_size);
01319 if (ret < 0)
01320 return -1;
01321 pid = AV_RB16(packet + 1) & 0x1fff;
01322 if ((pcr_pid == -1 || pcr_pid == pid) &&
01323 parse_pcr(&pcr_h, &pcr_l, packet) == 0) {
01324 pcr_pid = pid;
01325 packet_count[nb_pcrs] = nb_packets;
01326 pcrs[nb_pcrs] = pcr_h * 300 + pcr_l;
01327 nb_pcrs++;
01328 if (nb_pcrs >= 2)
01329 break;
01330 }
01331 nb_packets++;
01332 }
01333
01334
01335
01336 ts->pcr_incr = (pcrs[1] - pcrs[0]) / (packet_count[1] - packet_count[0]);
01337 ts->cur_pcr = pcrs[0] - ts->pcr_incr * packet_count[0];
01338 s->bit_rate = (TS_PACKET_SIZE * 8) * 27e6 / ts->pcr_incr;
01339 st->codec->bit_rate = s->bit_rate;
01340 st->start_time = ts->cur_pcr;
01341 #if 0
01342 av_log(ts->stream, AV_LOG_DEBUG, "start=%0.3f pcr=%0.3f incr=%d\n",
01343 st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);
01344 #endif
01345 }
01346
01347 url_fseek(pb, pos, SEEK_SET);
01348 return 0;
01349 fail:
01350 return -1;
01351 }
01352
01353 #define MAX_PACKET_READAHEAD ((128 * 1024) / 188)
01354
01355 static int mpegts_raw_read_packet(AVFormatContext *s,
01356 AVPacket *pkt)
01357 {
01358 MpegTSContext *ts = s->priv_data;
01359 int ret, i;
01360 int64_t pcr_h, next_pcr_h, pos;
01361 int pcr_l, next_pcr_l;
01362 uint8_t pcr_buf[12];
01363
01364 if (av_new_packet(pkt, TS_PACKET_SIZE) < 0)
01365 return AVERROR(ENOMEM);
01366 pkt->pos= url_ftell(s->pb);
01367 ret = read_packet(s->pb, pkt->data, ts->raw_packet_size);
01368 if (ret < 0) {
01369 av_free_packet(pkt);
01370 return ret;
01371 }
01372 if (ts->mpeg2ts_compute_pcr) {
01373
01374 if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) {
01375
01376 pos = url_ftell(s->pb);
01377 for(i = 0; i < MAX_PACKET_READAHEAD; i++) {
01378 url_fseek(s->pb, pos + i * ts->raw_packet_size, SEEK_SET);
01379 get_buffer(s->pb, pcr_buf, 12);
01380 if (parse_pcr(&next_pcr_h, &next_pcr_l, pcr_buf) == 0) {
01381
01382 ts->pcr_incr = ((next_pcr_h - pcr_h) * 300 + (next_pcr_l - pcr_l)) /
01383 (i + 1);
01384 break;
01385 }
01386 }
01387 url_fseek(s->pb, pos, SEEK_SET);
01388
01389 ts->cur_pcr = pcr_h * 300 + pcr_l;
01390 }
01391 pkt->pts = ts->cur_pcr;
01392 pkt->duration = ts->pcr_incr;
01393 ts->cur_pcr += ts->pcr_incr;
01394 }
01395 pkt->stream_index = 0;
01396 return 0;
01397 }
01398
01399 static int mpegts_read_packet(AVFormatContext *s,
01400 AVPacket *pkt)
01401 {
01402 MpegTSContext *ts = s->priv_data;
01403
01404 ts->pkt = pkt;
01405 return handle_packets(ts, 0);
01406 }
01407
01408 static int mpegts_read_close(AVFormatContext *s)
01409 {
01410 MpegTSContext *ts = s->priv_data;
01411 int i;
01412
01413 clear_programs(ts);
01414
01415 for(i=0;i<NB_PID_MAX;i++)
01416 if (ts->pids[i]) mpegts_close_filter(ts, ts->pids[i]);
01417
01418 return 0;
01419 }
01420
01421 static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
01422 int64_t *ppos, int64_t pos_limit)
01423 {
01424 MpegTSContext *ts = s->priv_data;
01425 int64_t pos, timestamp;
01426 uint8_t buf[TS_PACKET_SIZE];
01427 int pcr_l, pcr_pid = ((PESContext*)s->streams[stream_index]->priv_data)->pcr_pid;
01428 const int find_next= 1;
01429 pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47;
01430 if (find_next) {
01431 for(;;) {
01432 url_fseek(s->pb, pos, SEEK_SET);
01433 if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
01434 return AV_NOPTS_VALUE;
01435 if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
01436 parse_pcr(×tamp, &pcr_l, buf) == 0) {
01437 break;
01438 }
01439 pos += ts->raw_packet_size;
01440 }
01441 } else {
01442 for(;;) {
01443 pos -= ts->raw_packet_size;
01444 if (pos < 0)
01445 return AV_NOPTS_VALUE;
01446 url_fseek(s->pb, pos, SEEK_SET);
01447 if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
01448 return AV_NOPTS_VALUE;
01449 if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
01450 parse_pcr(×tamp, &pcr_l, buf) == 0) {
01451 break;
01452 }
01453 }
01454 }
01455 *ppos = pos;
01456
01457 return timestamp;
01458 }
01459
01460 static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
01461 MpegTSContext *ts = s->priv_data;
01462 uint8_t buf[TS_PACKET_SIZE];
01463 int64_t pos;
01464
01465 if(av_seek_frame_binary(s, stream_index, target_ts, flags) < 0)
01466 return -1;
01467
01468 pos= url_ftell(s->pb);
01469
01470 for(;;) {
01471 url_fseek(s->pb, pos, SEEK_SET);
01472 if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
01473 return -1;
01474
01475 if(buf[1] & 0x40) break;
01476 pos += ts->raw_packet_size;
01477 }
01478 url_fseek(s->pb, pos, SEEK_SET);
01479
01480 return 0;
01481 }
01482
01483
01484
01485
01486 MpegTSContext *mpegts_parse_open(AVFormatContext *s)
01487 {
01488 MpegTSContext *ts;
01489
01490 ts = av_mallocz(sizeof(MpegTSContext));
01491 if (!ts)
01492 return NULL;
01493
01494 ts->raw_packet_size = TS_PACKET_SIZE;
01495 ts->stream = s;
01496 ts->auto_guess = 1;
01497 return ts;
01498 }
01499
01500
01501
01502 int mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
01503 const uint8_t *buf, int len)
01504 {
01505 int len1;
01506
01507 len1 = len;
01508 ts->pkt = pkt;
01509 ts->stop_parse = 0;
01510 for(;;) {
01511 if (ts->stop_parse>0)
01512 break;
01513 if (len < TS_PACKET_SIZE)
01514 return -1;
01515 if (buf[0] != 0x47) {
01516 buf++;
01517 len--;
01518 } else {
01519 handle_packet(ts, buf);
01520 buf += TS_PACKET_SIZE;
01521 len -= TS_PACKET_SIZE;
01522 }
01523 }
01524 return len1 - len;
01525 }
01526
01527 void mpegts_parse_close(MpegTSContext *ts)
01528 {
01529 int i;
01530
01531 for(i=0;i<NB_PID_MAX;i++)
01532 av_free(ts->pids[i]);
01533 av_free(ts);
01534 }
01535
01536 AVInputFormat mpegts_demuxer = {
01537 "mpegts",
01538 NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
01539 sizeof(MpegTSContext),
01540 mpegts_probe,
01541 mpegts_read_header,
01542 mpegts_read_packet,
01543 mpegts_read_close,
01544 read_seek,
01545 mpegts_get_pcr,
01546 .flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
01547 };
01548
01549 AVInputFormat mpegtsraw_demuxer = {
01550 "mpegtsraw",
01551 NULL_IF_CONFIG_SMALL("MPEG-2 raw transport stream format"),
01552 sizeof(MpegTSContext),
01553 NULL,
01554 mpegts_read_header,
01555 mpegts_raw_read_packet,
01556 mpegts_read_close,
01557 read_seek,
01558 mpegts_get_pcr,
01559 .flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
01560 };