📄 demux_ts.c
字号:
priv->pat.version_number = (ptr[5] >> 1) & 0x1F; priv->pat.section_length = ((ptr[1] & 0x03) << 8 ) | ptr[2]; priv->pat.section_number = ptr[6]; priv->pat.last_section_number = ptr[7]; //check_crc32(0xFFFFFFFFL, ptr, priv->pat.buffer_len - 4, &ptr[priv->pat.buffer_len - 4]); mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_PAT: section_len: %d, section %d/%d\n", priv->pat.section_length, priv->pat.section_number, priv->pat.last_section_number); entries = (int) (priv->pat.section_length - 9) / 4; //entries per section for(i=0; i < entries; i++) { int32_t idx; base = &ptr[8 + i*4]; progid = (base[0] << 8) | base[1]; if((idx = prog_idx_in_pat(priv, progid)) == -1) { int sz = sizeof(struct pat_progs_t) * (priv->pat.progs_cnt+1); tmp = realloc_struct(priv->pat.progs, priv->pat.progs_cnt+1, sizeof(struct pat_progs_t)); if(tmp == NULL) { mp_msg(MSGT_DEMUX, MSGL_ERR, "PARSE_PAT: COULDN'T REALLOC %d bytes, NEXT\n", sz); break; } priv->pat.progs = tmp; idx = priv->pat.progs_cnt; priv->pat.progs_cnt++; } priv->pat.progs[idx].id = progid; priv->pat.progs[idx].pmt_pid = ((base[2] & 0x1F) << 8) | base[3]; mp_msg(MSGT_DEMUX, MSGL_V, "PROG: %d (%d-th of %d), PMT: %d\n", priv->pat.progs[idx].id, i+1, entries, priv->pat.progs[idx].pmt_pid); } return 1;}static inline int32_t es_pid_in_pmt(pmt_t * pmt, uint16_t pid){ uint16_t i; if(pmt == NULL) return -1; if(pmt->es == NULL) return -1; for(i = 0; i < pmt->es_cnt; i++) { if(pmt->es[i].pid == pid) return (int32_t) i; } return -1;}static uint16_t get_mp4_desc_len(uint8_t *buf, int *len){ //uint16_t i = 0, size = 0; int i = 0, j, size = 0; mp_msg(MSGT_DEMUX, MSGL_DBG2, "PARSE_MP4_DESC_LEN(%d), bytes: ", *len); j = FFMIN(*len, 4); while(i < j) { mp_msg(MSGT_DEMUX, MSGL_DBG2, " %x ", buf[i]); size |= (buf[i] & 0x7f); if(!(buf[i] & 0x80)) break; size <<= 7; i++; } mp_msg(MSGT_DEMUX, MSGL_DBG2, ", SIZE=%d\n", size); *len = i+1; return size;}static uint16_t parse_mp4_slconfig_descriptor(uint8_t *buf, int len, void *elem){ int i = 0; mp4_es_descr_t *es; mp4_sl_config_t *sl; mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_SLCONFIG_DESCRIPTOR(%d)\n", len); es = (mp4_es_descr_t *) elem; if(!es) { mp_msg(MSGT_DEMUX, MSGL_V, "argh! NULL elem passed, skip\n"); return len; } sl = &(es->sl); sl->ts_len = sl->ocr_len = sl->au_len = sl->instant_bitrate_len = sl->degr_len = sl->au_seqnum_len = sl->packet_seqnum_len = 0; sl->ocr = sl->dts = sl->cts = 0; if(buf[0] == 0) { i++; sl->flags = buf[i]; i++; sl->ts_resolution = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3]; i += 4; sl->ocr_resolution = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3]; i += 4; sl->ts_len = buf[i]; i++; sl->ocr_len = buf[i]; i++; sl->au_len = buf[i]; i++; sl->instant_bitrate_len = buf[i]; i++; sl->degr_len = (buf[i] >> 4) & 0x0f; sl->au_seqnum_len = ((buf[i] & 0x0f) << 1) | ((buf[i+1] >> 7) & 0x01); i++; sl->packet_seqnum_len = ((buf[i] >> 2) & 0x1f); i++; } else if(buf[0] == 1) { sl->flags = 0; sl->ts_resolution = 1000; sl->ts_len = 32; i++; } else if(buf[0] == 2) { sl->flags = 4; i++; } else { sl->flags = 0; i++; } sl->au_start = (sl->flags >> 7) & 0x1; sl->au_end = (sl->flags >> 6) & 0x1; sl->random_accesspoint = (sl->flags >> 5) & 0x1; sl->random_accesspoint_only = (sl->flags >> 4) & 0x1; sl->padding = (sl->flags >> 3) & 0x1; sl->use_ts = (sl->flags >> 2) & 0x1; sl->idle = (sl->flags >> 1) & 0x1; sl->duration = sl->flags & 0x1; if(sl->duration) { sl->timescale = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3]; i += 4; sl->au_duration = (buf[i] << 8) | buf[i+1]; i += 2; sl->cts_duration = (buf[i] << 8) | buf[i+1]; i += 2; } else //no support for fixed durations atm sl->timescale = sl->au_duration = sl->cts_duration = 0; mp_msg(MSGT_DEMUX, MSGL_V, "MP4SLCONFIG(len=0x%x), predef: %d, flags: %x, use_ts: %d, tslen: %d, timescale: %d, dts: %"PRIu64", cts: %"PRIu64"\n", len, buf[0], sl->flags, sl->use_ts, sl->ts_len, sl->timescale, (uint64_t) sl->dts, (uint64_t) sl->cts); return len;}static int parse_mp4_descriptors(pmt_t *pmt, uint8_t *buf, int len, void *elem);static uint16_t parse_mp4_decoder_config_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem){ int i = 0, j; mp4_es_descr_t *es; mp4_decoder_config_t *dec; mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_DECODER_CONFIG_DESCRIPTOR(%d)\n", len); es = (mp4_es_descr_t *) elem; if(!es) { mp_msg(MSGT_DEMUX, MSGL_V, "argh! NULL elem passed, skip\n"); return len; } dec = (mp4_decoder_config_t*) &(es->decoder); dec->object_type = buf[i]; dec->stream_type = (buf[i+1]>>2) & 0x3f; if(dec->object_type == 1 && dec->stream_type == 1) { dec->object_type = MP4_OD; dec->stream_type = MP4_OD; } else if(dec->stream_type == 4) { if(dec->object_type == 0x6a) dec->object_type = VIDEO_MPEG1; if(dec->object_type >= 0x60 && dec->object_type <= 0x65) dec->object_type = VIDEO_MPEG2; else if(dec->object_type == 0x20) dec->object_type = VIDEO_MPEG4; else if(dec->object_type == 0x21) dec->object_type = VIDEO_AVC; /*else if(dec->object_type == 0x22) fprintf(stderr, "TYPE 0x22\n");*/ else dec->object_type = UNKNOWN; } else if(dec->stream_type == 5) { if(dec->object_type == 0x40) dec->object_type = AUDIO_AAC; else if(dec->object_type == 0x6b) dec->object_type = AUDIO_MP2; else if(dec->object_type >= 0x66 && dec->object_type <= 0x69) dec->object_type = AUDIO_MP2; else dec->object_type = UNKNOWN; } else dec->object_type = dec->stream_type = UNKNOWN; if(dec->object_type != UNKNOWN) { //update the type of the current stream for(j = 0; j < pmt->es_cnt; j++) { if(pmt->es[j].mp4_es_id == es->id) { pmt->es[j].type = SL_PES_STREAM; } } } if(len > 13) parse_mp4_descriptors(pmt, &buf[13], len-13, dec); mp_msg(MSGT_DEMUX, MSGL_V, "MP4DECODER(0x%x), object_type: 0x%x, stream_type: 0x%x\n", len, dec->object_type, dec->stream_type); return len;}static uint16_t parse_mp4_decoder_specific_descriptor(uint8_t *buf, int len, void *elem){ int i; mp4_decoder_config_t *dec; mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_DECODER_SPECIFIC_DESCRIPTOR(%d)\n", len); dec = (mp4_decoder_config_t *) elem; if(!dec) { mp_msg(MSGT_DEMUX, MSGL_V, "argh! NULL elem passed, skip\n"); return len; } mp_msg(MSGT_DEMUX, MSGL_DBG2, "MP4 SPECIFIC INFO BYTES: \n"); for(i=0; i<len; i++) mp_msg(MSGT_DEMUX, MSGL_DBG2, "%02x ", buf[i]); mp_msg(MSGT_DEMUX, MSGL_DBG2, "\n"); if(len > MAX_EXTRADATA_SIZE) { mp_msg(MSGT_DEMUX, MSGL_ERR, "DEMUX_TS, EXTRADATA SUSPICIOUSLY BIG: %d, REFUSED\r\n", len); return len; } memcpy(dec->buf, buf, len); dec->buf_size = len; return len;}static uint16_t parse_mp4_es_descriptor(pmt_t *pmt, uint8_t *buf, int len){ int i = 0, j = 0, k, found; uint8_t flag; mp4_es_descr_t es, *target_es = NULL, *tmp; mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4ES: len=%d\n", len); memset(&es, 0, sizeof(mp4_es_descr_t)); while(i < len) { es.id = (buf[i] << 8) | buf[i+1]; mp_msg(MSGT_DEMUX, MSGL_V, "MP4ES_ID: %d\n", es.id); i += 2; flag = buf[i]; i++; if(flag & 0x80) i += 2; if(flag & 0x40) i += buf[i]+1; if(flag & 0x20) //OCR, maybe we need it i += 2; j = parse_mp4_descriptors(pmt, &buf[i], len-i, &es); mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4ES, types after parse_mp4_descriptors: 0x%x, 0x%x\n", es.decoder.object_type, es.decoder.stream_type); if(es.decoder.object_type != UNKNOWN && es.decoder.stream_type != UNKNOWN) { found = 0; //search this ES_ID if we already have it for(k=0; k < pmt->mp4es_cnt; k++) { if(pmt->mp4es[k].id == es.id) { target_es = &(pmt->mp4es[k]); found = 1; } } if(! found) { tmp = realloc_struct(pmt->mp4es, pmt->mp4es_cnt+1, sizeof(mp4_es_descr_t)); if(tmp == NULL) { fprintf(stderr, "CAN'T REALLOC MP4_ES_DESCR\n"); continue; } pmt->mp4es = tmp; target_es = &(pmt->mp4es[pmt->mp4es_cnt]); pmt->mp4es_cnt++; } memcpy(target_es, &es, sizeof(mp4_es_descr_t)); mp_msg(MSGT_DEMUX, MSGL_V, "MP4ES_CNT: %d, ID=%d\n", pmt->mp4es_cnt, target_es->id); } i += j; } return len;}static void parse_mp4_object_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem){ int i, j = 0, id; i=0; id = (buf[0] << 2) | ((buf[1] & 0xc0) >> 6); mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_OBJECT_DESCRIPTOR: len=%d, OD_ID=%d\n", len, id); if(buf[1] & 0x20) { i += buf[2] + 1; //url mp_msg(MSGT_DEMUX, MSGL_V, "URL\n"); } else { i = 2; while(i < len) { j = parse_mp4_descriptors(pmt, &(buf[i]), len-i, elem); mp_msg(MSGT_DEMUX, MSGL_V, "OBJD, NOW i = %d, j=%d, LEN=%d\n", i, j, len); i += j; } }}static void parse_mp4_iod(pmt_t *pmt, uint8_t *buf, int len, void *elem){ int i, j = 0; mp4_od_t *iod = &(pmt->iod); iod->id = (buf[0] << 2) | ((buf[1] & 0xc0) >> 6); mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_IOD: len=%d, IOD_ID=%d\n", len, iod->id); i = 2; if(buf[1] & 0x20) { i += buf[2] + 1; //url mp_msg(MSGT_DEMUX, MSGL_V, "URL\n"); } else { i = 7; while(i < len) { j = parse_mp4_descriptors(pmt, &(buf[i]), len-i, elem); mp_msg(MSGT_DEMUX, MSGL_V, "IOD, NOW i = %d, j=%d, LEN=%d\n", i, j, len); i += j; } }}static int parse_mp4_descriptors(pmt_t *pmt, uint8_t *buf, int len, void *elem){ int tag, descr_len, i = 0, j = 0; mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_DESCRIPTORS, len=%d\n", len); if(! len) return len; while(i < len) { tag = buf[i]; j = len - i -1; descr_len = get_mp4_desc_len(&(buf[i+1]), &j); mp_msg(MSGT_DEMUX, MSGL_V, "TAG=%d (0x%x), DESCR_len=%d, len=%d, j=%d\n", tag, tag, descr_len, len, j); if(descr_len > len - j+1) { mp_msg(MSGT_DEMUX, MSGL_V, "descriptor is too long, exit\n"); return len; } i += j+1; switch(tag) { case 0x1: parse_mp4_object_descriptor(pmt, &(buf[i]), descr_len, elem); break; case 0x2: parse_mp4_iod(pmt, &(buf[i]), descr_len, elem); break; case 0x3: parse_mp4_es_descriptor(pmt, &(buf[i]), descr_len); break; case 0x4: parse_mp4_decoder_config_descriptor(pmt, &buf[i], descr_len, elem); break; case 0x05: parse_mp4_decoder_specific_descriptor(&buf[i], descr_len, elem); break; case 0x6: parse_mp4_slconfig_descriptor(&buf[i], descr_len, elem); break; default: mp_msg(MSGT_DEMUX, MSGL_V, "Unsupported mp4 descriptor 0x%x\n", tag); } i += descr_len; } return len;}static ES_stream_t *new_pid(ts_priv_t *priv, int pid){ ES_stream_t *tss; tss = malloc(sizeof(ES_stream_t)); if(! tss) return NULL; memset(tss, 0, sizeof(ES_stream_t)); tss->pid = pid; tss->last_cc = -1; tss->type = UNKNOWN; tss->subtype = UNKNOWN; tss->is_synced = 0; tss->extradata = NULL; tss->extradata_alloc = tss->extradata_len = 0; priv->ts.pids[pid] = tss; return tss;}static int parse_program_descriptors(pmt_t *pmt, uint8_t *buf, uint16_t len){ uint16_t i = 0, k, olen = len; while(len > 0) { mp_msg(MSGT_DEMUX, MSGL_V, "PROG DESCR, TAG=%x, LEN=%d(%x)\n", buf[i], buf[i+1], buf[i+1]); if(buf[i+1] > len-2) { mp_msg(MSGT_DEMUX, MSGL_V, "ERROR, descriptor len is too long, skipping\n"); return olen; } if(buf[i] == 0x1d) { if(buf[i+3] == 2) //buggy versions of vlc muxer make this non-standard mess (missing iod_scope) k = 3; else k = 4; //this is standard compliant parse_mp4_descriptors(pmt, &buf[i+k], (int) buf[i+1]-(k-2), NULL); } len -= 2 + buf[i+1]; } return olen;}static int parse_descriptors(struct pmt_es_t *es, uint8_t *ptr){ int j, descr_len, len; j = 0; len = es->descr_length; while(len > 2) { descr_len = ptr[j+1]; mp_msg(MSGT_DEMUX, MSGL_V, "...descr id: 0x%x, len=%d\n", ptr[j], descr_len); if(descr_len > len) { mp_msg(MSGT_DEMUX, MSGL_ERR, "INVALID DESCR LEN for tag %02x: %d vs %d max, EXIT LOOP\n", ptr[j], descr_len, len); return -1; } if(ptr[j] == 0x6a || ptr[j] == 0x7a) //A52 Descriptor { if(es->type == 0x6) { es->type = AUDIO_A52; mp_msg(MSGT_DEMUX, MSGL_DBG2, "DVB A52 Descriptor\n"); } } else if(ptr[j] == 0x7b) //DVB DTS Descriptor { if(es->type == 0x6) { es->type = AUDIO_DTS; mp_msg(MSGT_DEMUX, MSGL_DBG2, "DVB DTS Descriptor\n"); } } else if(ptr[j] == 0x59) //Subtitling Descriptor { uint8_t subtype; mp_msg(MSGT_DEMUX, MSGL_DBG2, "Subtitling Descriptor\n"); if(descr_len < 8) { mp_msg(MSGT_DEMUX, MSGL_DBG2, "Descriptor length too short for DVB Subtitle Descriptor: %d, SKIPPING\n", descr_len); } else { memcpy(es->lang, &ptr[j+2], 3); es->lang[3] = 0; subtype = ptr[j+5]; if( (subtype >= 0x10 && subtype <= 0x13) || (subtype >= 0x20 && subtype <= 0x23) ) { es->type = SPU_DVB; //page parameters: compo page 2 bytes, ancillary page 2 bytes } else es->type = UNKNOWN; } } else if(ptr[j] == 0x50) //Component Descriptor { mp_msg(MSGT_DEMUX, MSGL_DBG2, "Component Descriptor\n"); memcpy(es->lang, &ptr[j+5], 3); es->lang[3] = 0; } else if(ptr[j] == 0xa) //Language Descriptor { memcpy(es->lang, &ptr[j+2], 3);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -