X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmpeg.c;h=fad7c7fd552b10f9719a48a78612d583fff1f0c9;hb=6a7b5226e1c868fe6406b114e7303c70d886900b;hp=80983f8a815ec3950b9070bd504f7bc91e53d444;hpb=3f37880c05714ede6590fb32390ed991552d5115;p=ffmpeg diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index 80983f8a815..fad7c7fd552 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -713,12 +713,23 @@ static int vobsub_probe(const AVProbeData *p) return 0; } +static int vobsub_read_close(AVFormatContext *s) +{ + VobSubDemuxContext *vobsub = s->priv_data; + int i; + + for (i = 0; i < s->nb_streams; i++) + ff_subtitles_queue_clean(&vobsub->q[i]); + if (vobsub->sub_ctx) + avformat_close_input(&vobsub->sub_ctx); + return 0; +} + static int vobsub_read_header(AVFormatContext *s) { int i, ret = 0, header_parsed = 0, langidx = 0; VobSubDemuxContext *vobsub = s->priv_data; size_t fname_len; - char *header_str = NULL; AVBPrint header; int64_t delay = 0; AVStream *st = NULL; @@ -731,8 +742,7 @@ static int vobsub_read_header(AVFormatContext *s) char *ext; vobsub->sub_name = av_strdup(s->url); if (!vobsub->sub_name) { - ret = AVERROR(ENOMEM); - goto end; + return AVERROR(ENOMEM); } fname_len = strlen(vobsub->sub_name); @@ -740,24 +750,23 @@ static int vobsub_read_header(AVFormatContext *s) if (fname_len < 4 || *(ext - 1) != '.') { av_log(s, AV_LOG_ERROR, "The input index filename is too short " "to guess the associated .SUB file\n"); - ret = AVERROR_INVALIDDATA; - goto end; + return AVERROR_INVALIDDATA; } memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3); av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->url, vobsub->sub_name); } if (!(iformat = av_find_input_format("mpeg"))) { - ret = AVERROR_DEMUXER_NOT_FOUND; - goto end; + return AVERROR_DEMUXER_NOT_FOUND; } vobsub->sub_ctx = avformat_alloc_context(); if (!vobsub->sub_ctx) { - ret = AVERROR(ENOMEM); - goto end; + return AVERROR(ENOMEM); } + av_bprint_init(&header, 0, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE); + if ((ret = ff_copy_whiteblacklists(vobsub->sub_ctx, s)) < 0) goto end; @@ -767,7 +776,6 @@ static int vobsub_read_header(AVFormatContext *s) goto end; } - av_bprint_init(&header, 0, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE); while (!avio_feof(s->pb)) { char line[MAX_LINE_SIZE]; int len = ff_get_line(s->pb, line, sizeof(line)); @@ -888,22 +896,21 @@ static int vobsub_read_header(AVFormatContext *s) } if (!av_bprint_is_complete(&header)) { - av_bprint_finalize(&header, NULL); ret = AVERROR(ENOMEM); goto end; } - av_bprint_finalize(&header, &header_str); for (i = 0; i < s->nb_streams; i++) { AVCodecParameters *par = s->streams[i]->codecpar; ret = ff_alloc_extradata(par, header.len); if (ret < 0) { goto end; } - memcpy(par->extradata, header_str, header.len); + memcpy(par->extradata, header.str, header.len); } end: - - av_free(header_str); + if (ret < 0) + vobsub_read_close(s); + av_bprint_finalize(&header, NULL); return ret; } @@ -913,7 +920,6 @@ static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) FFDemuxSubtitlesQueue *q; AVIOContext *pb = vobsub->sub_ctx->pb; int ret, psize, total_read = 0, i; - AVPacket idx_pkt = { 0 }; int64_t min_ts = INT64_MAX; int sid = 0; @@ -928,24 +934,22 @@ static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) } } q = &vobsub->q[sid]; - ret = ff_subtitles_queue_read_packet(q, &idx_pkt); + /* The returned packet will have size zero, + * so that it can be directly used with av_grow_packet. */ + ret = ff_subtitles_queue_read_packet(q, pkt); if (ret < 0) return ret; /* compute maximum packet size using the next packet position. This is * useful when the len in the header is non-sense */ if (q->current_sub_idx < q->nb_subs) { - psize = q->subs[q->current_sub_idx].pos - idx_pkt.pos; + psize = q->subs[q->current_sub_idx].pos - pkt->pos; } else { int64_t fsize = avio_size(pb); - psize = fsize < 0 ? 0xffff : fsize - idx_pkt.pos; + psize = fsize < 0 ? 0xffff : fsize - pkt->pos; } - avio_seek(pb, idx_pkt.pos, SEEK_SET); - - av_init_packet(pkt); - pkt->size = 0; - pkt->data = NULL; + avio_seek(pb, pkt->pos, SEEK_SET); do { int n, to_read, startcode; @@ -969,7 +973,7 @@ static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) total_read += pkt_size; /* the current chunk doesn't match the stream index (unlikely) */ - if ((startcode & 0x1f) != s->streams[idx_pkt.stream_index]->id) + if ((startcode & 0x1f) != s->streams[pkt->stream_index]->id) break; ret = av_grow_packet(pkt, to_read); @@ -981,16 +985,10 @@ static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->size -= to_read - n; } while (total_read < psize); - pkt->pts = pkt->dts = idx_pkt.pts; - pkt->pos = idx_pkt.pos; - pkt->stream_index = idx_pkt.stream_index; - - av_packet_unref(&idx_pkt); return 0; fail: av_packet_unref(pkt); - av_packet_unref(&idx_pkt); return ret; } @@ -1027,18 +1025,6 @@ static int vobsub_read_seek(AVFormatContext *s, int stream_index, min_ts, ts, max_ts, flags); } -static int vobsub_read_close(AVFormatContext *s) -{ - VobSubDemuxContext *vobsub = s->priv_data; - int i; - - for (i = 0; i < s->nb_streams; i++) - ff_subtitles_queue_clean(&vobsub->q[i]); - if (vobsub->sub_ctx) - avformat_close_input(&vobsub->sub_ctx); - return 0; -} - static const AVOption options[] = { { "sub_name", "URI for .sub file", offsetof(VobSubDemuxContext, sub_name), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM }, { NULL }