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 "avformat.h"
00024 #include "mpegts.h"
00025
00026
00027
00028
00029
00030 #define MAX_SCAN_PACKETS 32000
00031
00032
00033
00034 #define MAX_RESYNC_SIZE 4096
00035 #define REGISTRATION_DESCRIPTOR 5
00036
00037 typedef struct PESContext PESContext;
00038
00039 static PESContext* add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type);
00040 static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code);
00041 extern void av_set_program_name(AVProgram *program, char *provider_name, char *name);
00042 extern void av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx);
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);
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 typedef struct {
00084 unsigned int id;
00085 unsigned int nb_pids;
00086 unsigned int pids[MAX_PIDS_PER_PROGRAM];
00087 } Program_t;
00088
00089 struct MpegTSContext {
00090
00091 AVFormatContext *stream;
00092
00093 int raw_packet_size;
00094
00095 int pos47;
00096
00097
00098 int auto_guess;
00099
00100
00101 int mpeg2ts_compute_pcr;
00102
00103 int64_t cur_pcr;
00104 int pcr_incr;
00105
00106
00107
00108 int stop_parse;
00109
00110 AVPacket *pkt;
00111
00112
00113
00114
00115
00116 unsigned int nb_prg;
00117 Program_t *prg;
00118
00119
00120
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 uint8_t header[MAX_PES_HEADER_SIZE];
00151 };
00152
00153 extern AVInputFormat mpegts_demuxer;
00154
00155 static void clear_program(MpegTSContext *ts, unsigned int programid)
00156 {
00157 int i;
00158
00159 for(i=0; i<ts->nb_prg; i++)
00160 if(ts->prg[i].id == programid)
00161 ts->prg[i].nb_pids = 0;
00162 }
00163
00164 static void clear_programs(MpegTSContext *ts)
00165 {
00166 av_freep(&ts->prg);
00167 ts->nb_prg=0;
00168 }
00169
00170 static void add_pat_entry(MpegTSContext *ts, unsigned int programid)
00171 {
00172 Program_t *p;
00173 void *tmp = av_realloc(ts->prg, (ts->nb_prg+1)*sizeof(Program_t));
00174 if(!tmp)
00175 return;
00176 ts->prg = tmp;
00177 p = &ts->prg[ts->nb_prg];
00178 p->id = programid;
00179 p->nb_pids = 0;
00180 ts->nb_prg++;
00181 }
00182
00183 static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, unsigned int pid)
00184 {
00185 int i;
00186 Program_t *p = NULL;
00187 for(i=0; i<ts->nb_prg; i++) {
00188 if(ts->prg[i].id == programid) {
00189 p = &ts->prg[i];
00190 break;
00191 }
00192 }
00193 if(!p)
00194 return;
00195
00196 if(p->nb_pids >= MAX_PIDS_PER_PROGRAM)
00197 return;
00198 p->pids[p->nb_pids++] = pid;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 static int discard_pid(MpegTSContext *ts, unsigned int pid)
00210 {
00211 int i, j, k;
00212 int used = 0, discarded = 0;
00213 Program_t *p;
00214 for(i=0; i<ts->nb_prg; i++) {
00215 p = &ts->prg[i];
00216 for(j=0; j<p->nb_pids; j++) {
00217 if(p->pids[j] != pid)
00218 continue;
00219
00220 for(k=0; k<ts->stream->nb_programs; k++) {
00221 if(ts->stream->programs[k]->id == p->id) {
00222 if(ts->stream->programs[k]->discard == AVDISCARD_ALL)
00223 discarded++;
00224 else
00225 used++;
00226 }
00227 }
00228 }
00229 }
00230
00231 return !used && discarded;
00232 }
00233
00234
00235
00236
00237
00238 static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
00239 const uint8_t *buf, int buf_size, int is_start)
00240 {
00241 MpegTSSectionFilter *tss = &tss1->u.section_filter;
00242 int len;
00243
00244 if (is_start) {
00245 memcpy(tss->section_buf, buf, buf_size);
00246 tss->section_index = buf_size;
00247 tss->section_h_size = -1;
00248 tss->end_of_section_reached = 0;
00249 } else {
00250 if (tss->end_of_section_reached)
00251 return;
00252 len = 4096 - tss->section_index;
00253 if (buf_size < len)
00254 len = buf_size;
00255 memcpy(tss->section_buf + tss->section_index, buf, len);
00256 tss->section_index += len;
00257 }
00258
00259
00260 if (tss->section_h_size == -1 && tss->section_index >= 3) {
00261 len = (AV_RB16(tss->section_buf + 1) & 0xfff) + 3;
00262 if (len > 4096)
00263 return;
00264 tss->section_h_size = len;
00265 }
00266
00267 if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) {
00268 tss->end_of_section_reached = 1;
00269 if (!tss->check_crc ||
00270 av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1,
00271 tss->section_buf, tss->section_h_size) == 0)
00272 tss->section_cb(tss1, tss->section_buf, tss->section_h_size);
00273 }
00274 }
00275
00276 static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int pid,
00277 SectionCallback *section_cb, void *opaque,
00278 int check_crc)
00279
00280 {
00281 MpegTSFilter *filter;
00282 MpegTSSectionFilter *sec;
00283
00284 #ifdef DEBUG_SI
00285 av_log(ts->stream, AV_LOG_DEBUG, "Filter: pid=0x%x\n", pid);
00286 #endif
00287 if (pid >= NB_PID_MAX || ts->pids[pid])
00288 return NULL;
00289 filter = av_mallocz(sizeof(MpegTSFilter));
00290 if (!filter)
00291 return NULL;
00292 ts->pids[pid] = filter;
00293 filter->type = MPEGTS_SECTION;
00294 filter->pid = pid;
00295 filter->last_cc = -1;
00296 sec = &filter->u.section_filter;
00297 sec->section_cb = section_cb;
00298 sec->opaque = opaque;
00299 sec->section_buf = av_malloc(MAX_SECTION_SIZE);
00300 sec->check_crc = check_crc;
00301 if (!sec->section_buf) {
00302 av_free(filter);
00303 return NULL;
00304 }
00305 return filter;
00306 }
00307
00308 static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid,
00309 PESCallback *pes_cb,
00310 void *opaque)
00311 {
00312 MpegTSFilter *filter;
00313 MpegTSPESFilter *pes;
00314
00315 if (pid >= NB_PID_MAX || ts->pids[pid])
00316 return NULL;
00317 filter = av_mallocz(sizeof(MpegTSFilter));
00318 if (!filter)
00319 return NULL;
00320 ts->pids[pid] = filter;
00321 filter->type = MPEGTS_PES;
00322 filter->pid = pid;
00323 filter->last_cc = -1;
00324 pes = &filter->u.pes_filter;
00325 pes->pes_cb = pes_cb;
00326 pes->opaque = opaque;
00327 return filter;
00328 }
00329
00330 static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
00331 {
00332 int pid;
00333
00334 pid = filter->pid;
00335 if (filter->type == MPEGTS_SECTION)
00336 av_freep(&filter->u.section_filter.section_buf);
00337
00338 av_free(filter);
00339 ts->pids[pid] = NULL;
00340 }
00341
00342 static int analyze(const uint8_t *buf, int size, int packet_size, int *index){
00343 int stat[packet_size];
00344 int i;
00345 int x=0;
00346 int best_score=0;
00347
00348 memset(stat, 0, packet_size*sizeof(int));
00349
00350 for(x=i=0; i<size-3; i++){
00351 if(buf[i] == 0x47 && !(buf[i+1] & 0x80) && (buf[i+3] & 0x30)){
00352 stat[x]++;
00353 if(stat[x] > best_score){
00354 best_score= stat[x];
00355 if(index) *index= x;
00356 }
00357 }
00358
00359 x++;
00360 if(x == packet_size) x= 0;
00361 }
00362
00363 return best_score;
00364 }
00365
00366
00367 static int get_packet_size(const uint8_t *buf, int size)
00368 {
00369 int score, fec_score, dvhs_score;
00370
00371 if (size < (TS_FEC_PACKET_SIZE * 5 + 1))
00372 return -1;
00373
00374 score = analyze(buf, size, TS_PACKET_SIZE, NULL);
00375 dvhs_score = analyze(buf, size, TS_DVHS_PACKET_SIZE, NULL);
00376 fec_score= analyze(buf, size, TS_FEC_PACKET_SIZE, NULL);
00377
00378
00379 if (score > fec_score && score > dvhs_score) return TS_PACKET_SIZE;
00380 else if(dvhs_score > score && dvhs_score > fec_score) return TS_DVHS_PACKET_SIZE;
00381 else if(score < fec_score && dvhs_score < fec_score) return TS_FEC_PACKET_SIZE;
00382 else return -1;
00383 }
00384
00385 typedef struct SectionHeader {
00386 uint8_t tid;
00387 uint16_t id;
00388 uint8_t version;
00389 uint8_t sec_num;
00390 uint8_t last_sec_num;
00391 } SectionHeader;
00392
00393 static inline int get8(const uint8_t **pp, const uint8_t *p_end)
00394 {
00395 const uint8_t *p;
00396 int c;
00397
00398 p = *pp;
00399 if (p >= p_end)
00400 return -1;
00401 c = *p++;
00402 *pp = p;
00403 return c;
00404 }
00405
00406 static inline int get16(const uint8_t **pp, const uint8_t *p_end)
00407 {
00408 const uint8_t *p;
00409 int c;
00410
00411 p = *pp;
00412 if ((p + 1) >= p_end)
00413 return -1;
00414 c = AV_RB16(p);
00415 p += 2;
00416 *pp = p;
00417 return c;
00418 }
00419
00420
00421 static char *getstr8(const uint8_t **pp, const uint8_t *p_end)
00422 {
00423 int len;
00424 const uint8_t *p;
00425 char *str;
00426
00427 p = *pp;
00428 len = get8(&p, p_end);
00429 if (len < 0)
00430 return NULL;
00431 if ((p + len) > p_end)
00432 return NULL;
00433 str = av_malloc(len + 1);
00434 if (!str)
00435 return NULL;
00436 memcpy(str, p, len);
00437 str[len] = '\0';
00438 p += len;
00439 *pp = p;
00440 return str;
00441 }
00442
00443 static int parse_section_header(SectionHeader *h,
00444 const uint8_t **pp, const uint8_t *p_end)
00445 {
00446 int val;
00447
00448 val = get8(pp, p_end);
00449 if (val < 0)
00450 return -1;
00451 h->tid = val;
00452 *pp += 2;
00453 val = get16(pp, p_end);
00454 if (val < 0)
00455 return -1;
00456 h->id = val;
00457 val = get8(pp, p_end);
00458 if (val < 0)
00459 return -1;
00460 h->version = (val >> 1) & 0x1f;
00461 val = get8(pp, p_end);
00462 if (val < 0)
00463 return -1;
00464 h->sec_num = val;
00465 val = get8(pp, p_end);
00466 if (val < 0)
00467 return -1;
00468 h->last_sec_num = val;
00469 return 0;
00470 }
00471
00472
00473 static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
00474 {
00475 MpegTSContext *ts = filter->u.section_filter.opaque;
00476 SectionHeader h1, *h = &h1;
00477 PESContext *pes;
00478 AVStream *st;
00479 const uint8_t *p, *p_end, *desc_list_end, *desc_end;
00480 int program_info_length, pcr_pid, pid, stream_type;
00481 int desc_list_len, desc_len, desc_tag;
00482 int comp_page = 0, anc_page = 0;
00483 char language[4] = {0};
00484 int has_hdmv_descr = 0;
00485
00486 #ifdef DEBUG_SI
00487 av_log(ts->stream, AV_LOG_DEBUG, "PMT: len %i\n", section_len);
00488 av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
00489 #endif
00490 p_end = section + section_len - 4;
00491 p = section;
00492 if (parse_section_header(h, &p, p_end) < 0)
00493 return;
00494 #ifdef DEBUG_SI
00495 av_log(ts->stream, AV_LOG_DEBUG, "sid=0x%x sec_num=%d/%d\n",
00496 h->id, h->sec_num, h->last_sec_num);
00497 #endif
00498 if (h->tid != PMT_TID)
00499 return;
00500
00501 clear_program(ts, h->id);
00502 pcr_pid = get16(&p, p_end) & 0x1fff;
00503 if (pcr_pid < 0)
00504 return;
00505 add_pid_to_pmt(ts, h->id, pcr_pid);
00506 #ifdef DEBUG_SI
00507 av_log(ts->stream, AV_LOG_DEBUG, "pcr_pid=0x%x\n", pcr_pid);
00508 #endif
00509 program_info_length = get16(&p, p_end) & 0xfff;
00510 if (program_info_length < 0)
00511 return;
00512 while(program_info_length >= 2) {
00513 uint8_t tag, len;
00514 tag = get8(&p, p_end);
00515 len = get8(&p, p_end);
00516 if(len > program_info_length - 2)
00517
00518 break;
00519 program_info_length -= len + 2;
00520 if(tag == REGISTRATION_DESCRIPTOR && len >= 4) {
00521 uint8_t bytes[4];
00522 bytes[0] = get8(&p, p_end);
00523 bytes[1] = get8(&p, p_end);
00524 bytes[2] = get8(&p, p_end);
00525 bytes[3] = get8(&p, p_end);
00526 len -= 4;
00527 if(bytes[0] == 'H' && bytes[1] == 'D' &&
00528 bytes[2] == 'M' && bytes[3] == 'V')
00529 has_hdmv_descr = 1;
00530 }
00531 p += len;
00532 }
00533 p += program_info_length;
00534 if (p >= p_end)
00535 return;
00536 for(;;) {
00537 language[0] = 0;
00538 st = 0;
00539 stream_type = get8(&p, p_end);
00540 if (stream_type < 0)
00541 break;
00542 pid = get16(&p, p_end) & 0x1fff;
00543 if (pid < 0)
00544 break;
00545 desc_list_len = get16(&p, p_end) & 0xfff;
00546 if (desc_list_len < 0)
00547 break;
00548 desc_list_end = p + desc_list_len;
00549 if (desc_list_end > p_end)
00550 break;
00551 for(;;) {
00552 desc_tag = get8(&p, desc_list_end);
00553 if (desc_tag < 0)
00554 break;
00555 if (stream_type == STREAM_TYPE_PRIVATE_DATA) {
00556 if((desc_tag == 0x6A) || (desc_tag == 0x7A)) {
00557
00558 stream_type = STREAM_TYPE_AUDIO_AC3;
00559 } else if(desc_tag == 0x7B) {
00560
00561 stream_type = STREAM_TYPE_AUDIO_DTS;
00562 }
00563 }
00564 desc_len = get8(&p, desc_list_end);
00565 desc_end = p + desc_len;
00566 if (desc_end > desc_list_end)
00567 break;
00568 #ifdef DEBUG_SI
00569 av_log(ts->stream, AV_LOG_DEBUG, "tag: 0x%02x len=%d\n",
00570 desc_tag, desc_len);
00571 #endif
00572 switch(desc_tag) {
00573 case DVB_SUBT_DESCID:
00574 if (stream_type == STREAM_TYPE_PRIVATE_DATA)
00575 stream_type = STREAM_TYPE_SUBTITLE_DVB;
00576
00577 language[0] = get8(&p, desc_end);
00578 language[1] = get8(&p, desc_end);
00579 language[2] = get8(&p, desc_end);
00580 language[3] = 0;
00581 get8(&p, desc_end);
00582 comp_page = get16(&p, desc_end);
00583 anc_page = get16(&p, desc_end);
00584
00585 break;
00586 case 0x0a:
00587 language[0] = get8(&p, desc_end);
00588 language[1] = get8(&p, desc_end);
00589 language[2] = get8(&p, desc_end);
00590 language[3] = 0;
00591 break;
00592 default:
00593 break;
00594 }
00595 p = desc_end;
00596 }
00597 p = desc_list_end;
00598
00599 #ifdef DEBUG_SI
00600 av_log(ts->stream, AV_LOG_DEBUG, "stream_type=%d pid=0x%x\n",
00601 stream_type, pid);
00602 #endif
00603
00604
00605 switch(stream_type) {
00606 case STREAM_TYPE_AUDIO_MPEG1:
00607 case STREAM_TYPE_AUDIO_MPEG2:
00608 case STREAM_TYPE_VIDEO_MPEG1:
00609 case STREAM_TYPE_VIDEO_MPEG2:
00610 case STREAM_TYPE_VIDEO_MPEG4:
00611 case STREAM_TYPE_VIDEO_H264:
00612 case STREAM_TYPE_VIDEO_VC1:
00613 case STREAM_TYPE_AUDIO_AAC:
00614 case STREAM_TYPE_AUDIO_AC3:
00615 case STREAM_TYPE_AUDIO_DTS:
00616 case STREAM_TYPE_AUDIO_HDMV_DTS:
00617 case STREAM_TYPE_SUBTITLE_DVB:
00618 if(stream_type == STREAM_TYPE_AUDIO_HDMV_DTS && !has_hdmv_descr)
00619 break;
00620 if(ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES){
00621 pes= ts->pids[pid]->u.pes_filter.opaque;
00622 st= pes->st;
00623 }else{
00624 if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]);
00625 pes = add_pes_stream(ts, pid, pcr_pid, stream_type);
00626 if (pes)
00627 st = new_pes_av_stream(pes, 0);
00628 }
00629 add_pid_to_pmt(ts, h->id, pid);
00630 if(st)
00631 av_program_add_stream_index(ts->stream, h->id, st->index);
00632 break;
00633 default:
00634
00635 break;
00636 }
00637
00638 if (st) {
00639 if (language[0] != 0) {
00640 memcpy(st->language, language, 4);
00641 }
00642
00643 if (stream_type == STREAM_TYPE_SUBTITLE_DVB) {
00644 st->codec->sub_id = (anc_page << 16) | comp_page;
00645 }
00646 }
00647 }
00648
00649 ts->stop_parse++;
00650 mpegts_close_filter(ts, filter);
00651 }
00652
00653 static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
00654 {
00655 MpegTSContext *ts = filter->u.section_filter.opaque;
00656 SectionHeader h1, *h = &h1;
00657 const uint8_t *p, *p_end;
00658 int sid, pmt_pid;
00659
00660 #ifdef DEBUG_SI
00661 av_log(ts->stream, AV_LOG_DEBUG, "PAT:\n");
00662 av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
00663 #endif
00664 p_end = section + section_len - 4;
00665 p = section;
00666 if (parse_section_header(h, &p, p_end) < 0)
00667 return;
00668 if (h->tid != PAT_TID)
00669 return;
00670
00671 clear_programs(ts);
00672 for(;;) {
00673 sid = get16(&p, p_end);
00674 if (sid < 0)
00675 break;
00676 pmt_pid = get16(&p, p_end) & 0x1fff;
00677 if (pmt_pid < 0)
00678 break;
00679 #ifdef DEBUG_SI
00680 av_log(ts->stream, AV_LOG_DEBUG, "sid=0x%x pid=0x%x\n", sid, pmt_pid);
00681 #endif
00682 if (sid == 0x0000) {
00683
00684 } else {
00685 av_new_program(ts->stream, sid);
00686 ts->stop_parse--;
00687 mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
00688 add_pat_entry(ts, sid);
00689 add_pid_to_pmt(ts, sid, 0);
00690 add_pid_to_pmt(ts, sid, pmt_pid);
00691 }
00692 }
00693
00694 ts->stop_parse++;
00695
00696 mpegts_close_filter(ts, filter);
00697 }
00698
00699 static void mpegts_set_service(MpegTSContext *ts)
00700 {
00701 mpegts_open_section_filter(ts, PAT_PID,
00702 pat_cb, ts, 1);
00703 }
00704
00705 static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
00706 {
00707 MpegTSContext *ts = filter->u.section_filter.opaque;
00708 SectionHeader h1, *h = &h1;
00709 const uint8_t *p, *p_end, *desc_list_end, *desc_end;
00710 int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
00711 char *name, *provider_name;
00712
00713 #ifdef DEBUG_SI
00714 av_log(ts->stream, AV_LOG_DEBUG, "SDT:\n");
00715 av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
00716 #endif
00717
00718 p_end = section + section_len - 4;
00719 p = section;
00720 if (parse_section_header(h, &p, p_end) < 0)
00721 return;
00722 if (h->tid != SDT_TID)
00723 return;
00724 onid = get16(&p, p_end);
00725 if (onid < 0)
00726 return;
00727 val = get8(&p, p_end);
00728 if (val < 0)
00729 return;
00730 for(;;) {
00731 sid = get16(&p, p_end);
00732 if (sid < 0)
00733 break;
00734 val = get8(&p, p_end);
00735 if (val < 0)
00736 break;
00737 desc_list_len = get16(&p, p_end) & 0xfff;
00738 if (desc_list_len < 0)
00739 break;
00740 desc_list_end = p + desc_list_len;
00741 if (desc_list_end > p_end)
00742 break;
00743 for(;;) {
00744 desc_tag = get8(&p, desc_list_end);
00745 if (desc_tag < 0)
00746 break;
00747 desc_len = get8(&p, desc_list_end);
00748 desc_end = p + desc_len;
00749 if (desc_end > desc_list_end)
00750 break;
00751 #ifdef DEBUG_SI
00752 av_log(ts->stream, AV_LOG_DEBUG, "tag: 0x%02x len=%d\n",
00753 desc_tag, desc_len);
00754 #endif
00755 switch(desc_tag) {
00756 case 0x48:
00757 service_type = get8(&p, p_end);
00758 if (service_type < 0)
00759 break;
00760 provider_name = getstr8(&p, p_end);
00761 if (!provider_name)
00762 break;
00763 name = getstr8(&p, p_end);
00764 if (name) {
00765 AVProgram *program = av_new_program(ts->stream, sid);
00766 if(program)
00767 av_set_program_name(program, provider_name, name);
00768 }
00769 av_free(name);
00770 av_free(provider_name);
00771 break;
00772 default:
00773 break;
00774 }
00775 p = desc_end;
00776 }
00777 p = desc_list_end;
00778 }
00779 }
00780
00781
00782 static void mpegts_scan_sdt(MpegTSContext *ts)
00783 {
00784 mpegts_open_section_filter(ts, SDT_PID,
00785 sdt_cb, ts, 1);
00786 }
00787
00788 static int64_t get_pts(const uint8_t *p)
00789 {
00790 int64_t pts = (int64_t)((p[0] >> 1) & 0x07) << 30;
00791 pts |= (AV_RB16(p + 1) >> 1) << 15;
00792 pts |= AV_RB16(p + 3) >> 1;
00793 return pts;
00794 }
00795
00796
00797 static void mpegts_push_data(MpegTSFilter *filter,
00798 const uint8_t *buf, int buf_size, int is_start)
00799 {
00800 PESContext *pes = filter->u.pes_filter.opaque;
00801 MpegTSContext *ts = pes->ts;
00802 const uint8_t *p;
00803 int len, code;
00804
00805 if(!ts->pkt)
00806 return;
00807
00808 if (is_start) {
00809 pes->state = MPEGTS_HEADER;
00810 pes->data_index = 0;
00811 }
00812 p = buf;
00813 while (buf_size > 0) {
00814 switch(pes->state) {
00815 case MPEGTS_HEADER:
00816 len = PES_START_SIZE - pes->data_index;
00817 if (len > buf_size)
00818 len = buf_size;
00819 memcpy(pes->header + pes->data_index, p, len);
00820 pes->data_index += len;
00821 p += len;
00822 buf_size -= len;
00823 if (pes->data_index == PES_START_SIZE) {
00824
00825
00826 #if 0
00827 av_hex_dump_log(pes->stream, AV_LOG_DEBUG, pes->header, pes->data_index);
00828 #endif
00829 if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
00830 pes->header[2] == 0x01) {
00831
00832 code = pes->header[3] | 0x100;
00833 if (!((code >= 0x1c0 && code <= 0x1df) ||
00834 (code >= 0x1e0 && code <= 0x1ef) ||
00835 (code == 0x1bd) || (code == 0x1fd)))
00836 goto skip;
00837 if (!pes->st) {
00838
00839 new_pes_av_stream(pes, code);
00840 }
00841 pes->state = MPEGTS_PESHEADER_FILL;
00842 pes->total_size = AV_RB16(pes->header + 4);
00843
00844
00845 if (pes->total_size)
00846 pes->total_size += 6;
00847 pes->pes_header_size = pes->header[8] + 9;
00848 } else {
00849
00850
00851 skip:
00852 pes->state = MPEGTS_SKIP;
00853 continue;
00854 }
00855 }
00856 break;
00857
00858
00859 case MPEGTS_PESHEADER_FILL:
00860 len = pes->pes_header_size - pes->data_index;
00861 if (len > buf_size)
00862 len = buf_size;
00863 memcpy(pes->header + pes->data_index, p, len);
00864 pes->data_index += len;
00865 p += len;
00866 buf_size -= len;
00867 if (pes->data_index == pes->pes_header_size) {
00868 const uint8_t *r;
00869 unsigned int flags;
00870
00871 flags = pes->header[7];
00872 r = pes->header + 9;
00873 pes->pts = AV_NOPTS_VALUE;
00874 pes->dts = AV_NOPTS_VALUE;
00875 if ((flags & 0xc0) == 0x80) {
00876 pes->pts = get_pts(r);
00877 r += 5;
00878 } else if ((flags & 0xc0) == 0xc0) {
00879 pes->pts = get_pts(r);
00880 r += 5;
00881 pes->dts = get_pts(r);
00882 r += 5;
00883 }
00884
00885 pes->state = MPEGTS_PAYLOAD;
00886 }
00887 break;
00888 case MPEGTS_PAYLOAD:
00889 if (pes->total_size) {
00890 len = pes->total_size - pes->data_index;
00891 if (len > buf_size)
00892 len = buf_size;
00893 } else {
00894 len = buf_size;
00895 }
00896 if (len > 0) {
00897 AVPacket *pkt = ts->pkt;
00898 if (pes->st && av_new_packet(pkt, len) == 0) {
00899 memcpy(pkt->data, p, len);
00900 pkt->stream_index = pes->st->index;
00901 pkt->pts = pes->pts;
00902 pkt->dts = pes->dts;
00903
00904 pes->pts = AV_NOPTS_VALUE;
00905 pes->dts = AV_NOPTS_VALUE;
00906 ts->stop_parse = 1;
00907 return;
00908 }
00909 }
00910 buf_size = 0;
00911 break;
00912 case MPEGTS_SKIP:
00913 buf_size = 0;
00914 break;
00915 }
00916 }
00917 }
00918
00919 static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code)
00920 {
00921 AVStream *st;
00922 int codec_type, codec_id;
00923
00924 switch(pes->stream_type){
00925 case STREAM_TYPE_AUDIO_MPEG1:
00926 case STREAM_TYPE_AUDIO_MPEG2:
00927 codec_type = CODEC_TYPE_AUDIO;
00928 codec_id = CODEC_ID_MP3;
00929 break;
00930 case STREAM_TYPE_VIDEO_MPEG1:
00931 case STREAM_TYPE_VIDEO_MPEG2:
00932 codec_type = CODEC_TYPE_VIDEO;
00933 codec_id = CODEC_ID_MPEG2VIDEO;
00934 break;
00935 case STREAM_TYPE_VIDEO_MPEG4:
00936 codec_type = CODEC_TYPE_VIDEO;
00937 codec_id = CODEC_ID_MPEG4;
00938 break;
00939 case STREAM_TYPE_VIDEO_H264:
00940 codec_type = CODEC_TYPE_VIDEO;
00941 codec_id = CODEC_ID_H264;
00942 break;
00943 case STREAM_TYPE_VIDEO_VC1:
00944 codec_type = CODEC_TYPE_VIDEO;
00945 codec_id = CODEC_ID_VC1;
00946 break;
00947 case STREAM_TYPE_AUDIO_AAC:
00948 codec_type = CODEC_TYPE_AUDIO;
00949 codec_id = CODEC_ID_AAC;
00950 break;
00951 case STREAM_TYPE_AUDIO_AC3:
00952 codec_type =