📄 mpeg.c.svn-base
字号:
/* stuffing */ for(;;) { if (len < 1) goto error_redo; c = get_byte(s->pb); len--; /* XXX: for mpeg1, should test only bit 7 */ if (c != 0xff) break; } if ((c & 0xc0) == 0x40) { /* buffer scale & size */ get_byte(s->pb); c = get_byte(s->pb); len -= 2; } if ((c & 0xe0) == 0x20) { dts = pts = get_pts(s->pb, c); len -= 4; if (c & 0x10){ dts = get_pts(s->pb, -1); len -= 5; } } else if ((c & 0xc0) == 0x80) { /* mpeg 2 PES */#if 0 /* some streams have this field set for no apparent reason */ if ((c & 0x30) != 0) { /* Encrypted multiplex not handled */ goto redo; }#endif flags = get_byte(s->pb); header_len = get_byte(s->pb); len -= 2; if (header_len > len) goto error_redo; len -= header_len; if (flags & 0x80) { dts = pts = get_pts(s->pb, -1); header_len -= 5; if (flags & 0x40) { dts = get_pts(s->pb, -1); header_len -= 5; } } if (flags & 0x01) { /* PES extension */ pes_ext = get_byte(s->pb); header_len--; if (pes_ext & 0x40) { /* pack header - should be zero in PS */ goto error_redo; } /* Skip PES private data, program packet sequence counter and P-STD buffer */ skip = (pes_ext >> 4) & 0xb; skip += skip & 0x9; url_fskip(s->pb, skip); header_len -= skip; if (pes_ext & 0x01) { /* PES extension 2 */ ext2_len = get_byte(s->pb); header_len--; if ((ext2_len & 0x7f) > 0) { id_ext = get_byte(s->pb); if ((id_ext & 0x80) == 0) startcode = ((startcode & 0xff) << 8) | id_ext; header_len--; } } } if(header_len < 0) goto error_redo; url_fskip(s->pb, header_len); } else if( c!= 0xf ) goto redo; if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) { startcode = get_byte(s->pb); len--; if (startcode >= 0x80 && startcode <= 0xcf) { /* audio: skip header */ get_byte(s->pb); get_byte(s->pb); get_byte(s->pb); len -= 3; if (startcode >= 0xb0 && startcode <= 0xbf) { /* MLP/TrueHD audio has a 4-byte header */ get_byte(s->pb); len--; } } } if(len<0) goto error_redo; if(dts != AV_NOPTS_VALUE && ppos){ int i; for(i=0; i<s->nb_streams; i++){ if(startcode == s->streams[i]->id && !url_is_streamed(s->pb) /* index useless on streams anyway */) { ff_reduce_index(s, i); av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); } } } *pstart_code = startcode; *ppts = pts; *pdts = dts; return len;}static int mpegps_read_packet(AVFormatContext *s, AVPacket *pkt){ MpegDemuxContext *m = s->priv_data; AVStream *st; int len, startcode, i, type, codec_id = 0, es_type; int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work redo: len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts); if (len < 0) return len; /* now find stream */ for(i=0;i<s->nb_streams;i++) { st = s->streams[i]; if (st->id == startcode) goto found; } es_type = m->psm_es_type[startcode & 0xff]; if(es_type > 0){ if(es_type == STREAM_TYPE_VIDEO_MPEG1){ codec_id = CODEC_ID_MPEG2VIDEO; type = CODEC_TYPE_VIDEO; } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){ codec_id = CODEC_ID_MPEG2VIDEO; type = CODEC_TYPE_VIDEO; } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 || es_type == STREAM_TYPE_AUDIO_MPEG2){ codec_id = CODEC_ID_MP3; type = CODEC_TYPE_AUDIO; } else if(es_type == STREAM_TYPE_AUDIO_AAC){ codec_id = CODEC_ID_AAC; type = CODEC_TYPE_AUDIO; } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){ codec_id = CODEC_ID_MPEG4; type = CODEC_TYPE_VIDEO; } else if(es_type == STREAM_TYPE_VIDEO_H264){ codec_id = CODEC_ID_H264; type = CODEC_TYPE_VIDEO; } else if(es_type == STREAM_TYPE_AUDIO_AC3){ codec_id = CODEC_ID_AC3; type = CODEC_TYPE_AUDIO; } else { goto skip; } } else if (startcode >= 0x1e0 && startcode <= 0x1ef) { static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 }; unsigned char buf[8]; get_buffer(s->pb, buf, 8); url_fseek(s->pb, -8, SEEK_CUR); if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1)) codec_id = CODEC_ID_CAVS; else codec_id = CODEC_ID_MPEG2VIDEO; type = CODEC_TYPE_VIDEO; } else if (startcode >= 0x1c0 && startcode <= 0x1df) { type = CODEC_TYPE_AUDIO; codec_id = m->sofdec > 0 ? CODEC_ID_ADPCM_ADX : CODEC_ID_MP2; } else if (startcode >= 0x80 && startcode <= 0x87) { type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_AC3; } else if ((startcode >= 0x88 && startcode <= 0x8f) ||( startcode >= 0x98 && startcode <= 0x9f)) { /* 0x90 - 0x97 is reserved for SDDS in DVD specs */ type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_DTS; } else if (startcode >= 0xa0 && startcode <= 0xaf) { type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_PCM_S16BE; } else if (startcode >= 0xb0 && startcode <= 0xbf) { type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_MLP; } else if (startcode >= 0xc0 && startcode <= 0xcf) { /* Used for both AC-3 and E-AC-3 in EVOB files */ type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_AC3; } else if (startcode >= 0x20 && startcode <= 0x3f) { type = CODEC_TYPE_SUBTITLE; codec_id = CODEC_ID_DVD_SUBTITLE; } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) { type = CODEC_TYPE_VIDEO; codec_id = CODEC_ID_VC1; } else { skip: /* skip packet */ url_fskip(s->pb, len); goto redo; } /* no stream found: add a new stream */ st = av_new_stream(s, startcode); if (!st) goto skip; st->codec->codec_type = type; st->codec->codec_id = codec_id; if (codec_id != CODEC_ID_PCM_S16BE) st->need_parsing = AVSTREAM_PARSE_FULL; found: if(st->discard >= AVDISCARD_ALL) goto skip; if (startcode >= 0xa0 && startcode <= 0xaf) { int b1, freq; /* for LPCM, we just skip the header and consider it is raw audio data */ if (len <= 3) goto skip; get_byte(s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ b1 = get_byte(s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ get_byte(s->pb); /* dynamic range control (0x80 = off) */ len -= 3; freq = (b1 >> 4) & 3; st->codec->sample_rate = lpcm_freq_tab[freq]; st->codec->channels = 1 + (b1 & 7); st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 2; } av_new_packet(pkt, len); get_buffer(s->pb, pkt->data, pkt->size); pkt->pts = pts; pkt->dts = dts; pkt->stream_index = st->index;#if 0 av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n", pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size);#endif return 0;}static int mpegps_read_close(AVFormatContext *s){ return 0;}static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit){ int len, startcode; int64_t pos, pts, dts; pos = *ppos;#ifdef DEBUG_SEEK printf("read_dts: pos=0x%"PRIx64" next=%d -> ", pos, find_next);#endif url_fseek(s->pb, pos, SEEK_SET); for(;;) { len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts); if (len < 0) {#ifdef DEBUG_SEEK printf("none (ret=%d)\n", len);#endif return AV_NOPTS_VALUE; } if (startcode == s->streams[stream_index]->id && dts != AV_NOPTS_VALUE) { break; } url_fskip(s->pb, len); }#ifdef DEBUG_SEEK printf("pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", pos, dts, dts / 90000.0);#endif *ppos = pos; return dts;}AVInputFormat mpegps_demuxer = { "mpeg", "MPEG PS format", sizeof(MpegDemuxContext), mpegps_probe, mpegps_read_header, mpegps_read_packet, mpegps_read_close, NULL, //mpegps_read_seek, mpegps_read_dts, .flags = AVFMT_SHOW_IDS,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -