X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmpegts.c;h=abdb000445101b3c02fb7fa3a9de255a9eaeeaa5;hb=895678f8239213db1d074a39653fcd78bdf87c25;hp=8467e85a04c0946bb710f6a982f5f68b92792cfe;hpb=665132e6204766b1d43ce413d6b1cc2a1d34ea29;p=ffmpeg diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 8467e85a04c..abdb0004451 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -2,20 +2,20 @@ * MPEG2 transport stream (aka DVB) demuxer * Copyright (c) 2002-2003 Fabrice Bellard * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,13 +29,11 @@ #include "avformat.h" #include "mpegts.h" #include "internal.h" +#include "avio_internal.h" #include "seek.h" #include "mpeg.h" #include "isom.h" -/* 1.0 second at 24Mbit/s */ -#define MAX_SCAN_PACKETS 32000 - /* maximum size in which we look for synchronisation if synchronisation is lost */ #define MAX_RESYNC_SIZE 65536 @@ -854,32 +852,32 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, int *es_id, uint8_t **dec_config_descr, int *dec_config_descr_size) { - ByteIOContext pb; + AVIOContext pb; int tag; unsigned len; - init_put_byte(&pb, buf, size, 0, NULL, NULL, NULL, NULL); + ffio_init_context(&pb, buf, size, 0, NULL, NULL, NULL, NULL); len = ff_mp4_read_descr(s, &pb, &tag); if (tag == MP4IODescrTag) { - get_be16(&pb); // ID - get_byte(&pb); - get_byte(&pb); - get_byte(&pb); - get_byte(&pb); - get_byte(&pb); + avio_rb16(&pb); // ID + avio_r8(&pb); + avio_r8(&pb); + avio_r8(&pb); + avio_r8(&pb); + avio_r8(&pb); len = ff_mp4_read_descr(s, &pb, &tag); if (tag == MP4ESDescrTag) { - *es_id = get_be16(&pb); /* ES_ID */ + *es_id = avio_rb16(&pb); /* ES_ID */ av_dlog(s, "ES_ID %#x\n", *es_id); - get_byte(&pb); /* priority */ + avio_r8(&pb); /* priority */ len = ff_mp4_read_descr(s, &pb, &tag); if (tag == MP4DecConfigDescrTag) { *dec_config_descr = av_malloc(len); if (!*dec_config_descr) return AVERROR(ENOMEM); *dec_config_descr_size = len; - get_buffer(&pb, *dec_config_descr, len); + avio_read(&pb, *dec_config_descr, len); } } } @@ -893,7 +891,8 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type { const uint8_t *desc_end; int desc_len, desc_tag; - char language[4]; + char language[252]; + int i; desc_tag = get8(pp, desc_list_end); if (desc_tag < 0) @@ -916,8 +915,8 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type get16(pp, desc_end); if (st->codec->codec_id == CODEC_ID_AAC_LATM && mp4_dec_config_descr_len && mp4_es_id == pid) { - ByteIOContext pb; - init_put_byte(&pb, mp4_dec_config_descr, + AVIOContext pb; + ffio_init_context(&pb, mp4_dec_config_descr, mp4_dec_config_descr_len, 0, NULL, NULL, NULL, NULL); ff_mp4_read_dec_config_descr(fc, st, &pb); if (st->codec->codec_id == CODEC_ID_AAC && @@ -937,7 +936,17 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type language[1] = get8(pp, desc_end); language[2] = get8(pp, desc_end); language[3] = 0; - get8(pp, desc_end); + /* hearing impaired subtitles detection */ + switch(get8(pp, desc_end)) { + case 0x20: /* DVB subtitles (for the hard of hearing) with no monitor aspect ratio criticality */ + case 0x21: /* DVB subtitles (for the hard of hearing) for display on 4:3 aspect ratio monitor */ + case 0x22: /* DVB subtitles (for the hard of hearing) for display on 16:9 aspect ratio monitor */ + case 0x23: /* DVB subtitles (for the hard of hearing) for display on 2.21:1 aspect ratio monitor */ + case 0x24: /* DVB subtitles (for the hard of hearing) for display on a high definition monitor */ + case 0x25: /* DVB subtitles (for the hard of hearing) with plano-stereoscopic disparity for display on a high definition monitor */ + st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED; + break; + } if (st->codec->extradata) { if (st->codec->extradata_size == 4 && memcmp(st->codec->extradata, *pp, 4)) av_log_ask_for_sample(fc, "DVB sub with multiple IDs\n"); @@ -952,11 +961,21 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type av_metadata_set2(&st->metadata, "language", language, 0); break; case 0x0a: /* ISO 639 language descriptor */ - language[0] = get8(pp, desc_end); - language[1] = get8(pp, desc_end); - language[2] = get8(pp, desc_end); - language[3] = 0; - av_metadata_set2(&st->metadata, "language", language, 0); + for (i = 0; i + 4 <= desc_len; i += 4) { + language[i + 0] = get8(pp, desc_end); + language[i + 1] = get8(pp, desc_end); + language[i + 2] = get8(pp, desc_end); + language[i + 3] = ','; + switch (get8(pp, desc_end)) { + case 0x01: st->disposition |= AV_DISPOSITION_CLEAN_EFFECTS; break; + case 0x02: st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED; break; + case 0x03: st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED; break; + } + } + if (i) { + language[i - 1] = 0; + av_metadata_set2(&st->metadata, "language", language, 0); + } break; case 0x05: /* registration descriptor */ st->codec->codec_tag = bytestream_get_le32(pp); @@ -1262,7 +1281,7 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) if (p >= p_end) return 0; - pos = url_ftell(ts->stream->pb); + pos = avio_tell(ts->stream->pb); ts->pos47= pos % ts->raw_packet_size; if (tss->type == MPEGTS_SECTION) { @@ -1305,15 +1324,15 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) get_packet_size() ?) */ static int mpegts_resync(AVFormatContext *s) { - ByteIOContext *pb = s->pb; + AVIOContext *pb = s->pb; int c, i; for(i = 0;i < MAX_RESYNC_SIZE; i++) { - c = url_fgetc(pb); - if (c < 0) + c = avio_r8(pb); + if (pb->eof_reached) return -1; if (c == 0x47) { - url_fseek(pb, -1, SEEK_CUR); + avio_seek(pb, -1, SEEK_CUR); return 0; } } @@ -1325,17 +1344,17 @@ static int mpegts_resync(AVFormatContext *s) /* return -1 if error or EOF. Return 0 if OK. */ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size) { - ByteIOContext *pb = s->pb; + AVIOContext *pb = s->pb; int skip, len; for(;;) { - len = get_buffer(pb, buf, TS_PACKET_SIZE); + len = avio_read(pb, buf, TS_PACKET_SIZE); if (len != TS_PACKET_SIZE) return AVERROR(EIO); /* check paquet sync byte */ if (buf[0] != 0x47) { /* find a new packet start */ - url_fseek(pb, -TS_PACKET_SIZE, SEEK_CUR); + avio_seek(pb, -TS_PACKET_SIZE, SEEK_CUR); if (mpegts_resync(s) < 0) return AVERROR(EAGAIN); else @@ -1343,7 +1362,7 @@ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size) } else { skip = raw_packet_size - TS_PACKET_SIZE; if (skip > 0) - url_fskip(pb, skip); + avio_skip(pb, skip); break; } } @@ -1437,7 +1456,7 @@ static int mpegts_read_header(AVFormatContext *s, AVFormatParameters *ap) { MpegTSContext *ts = s->priv_data; - ByteIOContext *pb = s->pb; + AVIOContext *pb = s->pb; uint8_t buf[5*1024]; int len; int64_t pos; @@ -1451,8 +1470,8 @@ static int mpegts_read_header(AVFormatContext *s, } /* read the first 1024 bytes to get packet size */ - pos = url_ftell(pb); - len = get_buffer(pb, buf, sizeof(buf)); + pos = avio_tell(pb); + len = avio_read(pb, buf, sizeof(buf)); if (len != sizeof(buf)) goto fail; ts->raw_packet_size = get_packet_size(buf, sizeof(buf)); @@ -1465,7 +1484,7 @@ static int mpegts_read_header(AVFormatContext *s, /* normal demux */ /* first do a scaning to get all the services */ - if (url_fseek(pb, pos, SEEK_SET) < 0) + if (avio_seek(pb, pos, SEEK_SET) < 0) av_log(s, AV_LOG_ERROR, "Unable to seek back to the start\n"); mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); @@ -1530,7 +1549,7 @@ static int mpegts_read_header(AVFormatContext *s, #endif } - url_fseek(pb, pos, SEEK_SET); + avio_seek(pb, pos, SEEK_SET); return 0; fail: return -1; @@ -1549,7 +1568,7 @@ static int mpegts_raw_read_packet(AVFormatContext *s, if (av_new_packet(pkt, TS_PACKET_SIZE) < 0) return AVERROR(ENOMEM); - pkt->pos= url_ftell(s->pb); + pkt->pos= avio_tell(s->pb); ret = read_packet(s, pkt->data, ts->raw_packet_size); if (ret < 0) { av_free_packet(pkt); @@ -1559,10 +1578,10 @@ static int mpegts_raw_read_packet(AVFormatContext *s, /* compute exact PCR for each packet */ if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) { /* we read the next PCR (XXX: optimize it by using a bigger buffer */ - pos = url_ftell(s->pb); + pos = avio_tell(s->pb); for(i = 0; i < MAX_PACKET_READAHEAD; i++) { - url_fseek(s->pb, pos + i * ts->raw_packet_size, SEEK_SET); - get_buffer(s->pb, pcr_buf, 12); + avio_seek(s->pb, pos + i * ts->raw_packet_size, SEEK_SET); + avio_read(s->pb, pcr_buf, 12); if (parse_pcr(&next_pcr_h, &next_pcr_l, pcr_buf) == 0) { /* XXX: not precise enough */ ts->pcr_incr = ((next_pcr_h - pcr_h) * 300 + (next_pcr_l - pcr_l)) / @@ -1570,7 +1589,7 @@ static int mpegts_raw_read_packet(AVFormatContext *s, break; } } - url_fseek(s->pb, pos, SEEK_SET); + avio_seek(s->pb, pos, SEEK_SET); /* no next PCR found: we use previous increment */ ts->cur_pcr = pcr_h * 300 + pcr_l; } @@ -1588,7 +1607,7 @@ static int mpegts_read_packet(AVFormatContext *s, MpegTSContext *ts = s->priv_data; int ret, i; - if (url_ftell(s->pb) != ts->last_pos) { + if (avio_tell(s->pb) != ts->last_pos) { /* seek detected, flush pes buffer */ for (i = 0; i < NB_PID_MAX; i++) { if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) { @@ -1617,7 +1636,7 @@ static int mpegts_read_packet(AVFormatContext *s, } } - ts->last_pos = url_ftell(s->pb); + ts->last_pos = avio_tell(s->pb); return ret; } @@ -1646,8 +1665,8 @@ static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index, pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47; if (find_next) { for(;;) { - url_fseek(s->pb, pos, SEEK_SET); - if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) + avio_seek(s->pb, pos, SEEK_SET); + if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) return AV_NOPTS_VALUE; if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) && parse_pcr(×tamp, &pcr_l, buf) == 0) { @@ -1660,8 +1679,8 @@ static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index, pos -= ts->raw_packet_size; if (pos < 0) return AV_NOPTS_VALUE; - url_fseek(s->pb, pos, SEEK_SET); - if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) + avio_seek(s->pb, pos, SEEK_SET); + if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) return AV_NOPTS_VALUE; if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) && parse_pcr(×tamp, &pcr_l, buf) == 0) { @@ -1768,17 +1787,17 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, in if(av_seek_frame_binary(s, stream_index, target_ts, flags) < 0) return -1; - pos= url_ftell(s->pb); + pos= avio_tell(s->pb); for(;;) { - url_fseek(s->pb, pos, SEEK_SET); - if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) + avio_seek(s->pb, pos, SEEK_SET); + if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) return -1; // pid = AV_RB16(buf + 1) & 0x1fff; if(buf[1] & 0x40) break; pos += ts->raw_packet_size; } - url_fseek(s->pb, pos, SEEK_SET); + avio_seek(s->pb, pos, SEEK_SET); return 0; }