X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmlvdec.c;h=f08aabf4e0dccd5ebd3734d510045e20abf2fda6;hb=e0c8e517b6a0d82d8837f78425b62132443ecf15;hp=ded8196af23776c628295d03024a2ca0e00d538a;hpb=fb4a12cda4033f2f3d3d1039739f6e0e6f9afb82;p=ffmpeg diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c index ded8196af23..f08aabf4e0d 100644 --- a/libavformat/mlvdec.c +++ b/libavformat/mlvdec.c @@ -52,7 +52,9 @@ typedef struct { uint64_t pts; } MlvContext; -static int probe(AVProbeData *p) +static int read_close(AVFormatContext *s); + +static int probe(const AVProbeData *p) { if (AV_RL32(p->buf) == MKTAG('M','L','V','I') && AV_RL32(p->buf + 4) >= 52 && @@ -130,23 +132,25 @@ static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int f break; size -= 16; if (vst && type == MKTAG('R','A','W','I') && size >= 164) { - vst->codecpar->width = avio_rl16(pb); - vst->codecpar->height = avio_rl16(pb); - ret = av_image_check_size(vst->codecpar->width, vst->codecpar->height, 0, avctx); + unsigned width = avio_rl16(pb); + unsigned height = avio_rl16(pb); + unsigned bits_per_coded_sample; + ret = av_image_check_size(width, height, 0, avctx); if (ret < 0) return ret; if (avio_rl32(pb) != 1) avpriv_request_sample(avctx, "raw api version"); avio_skip(pb, 20); // pointer, width, height, pitch, frame_size - vst->codecpar->bits_per_coded_sample = avio_rl32(pb); - if (vst->codecpar->bits_per_coded_sample < 0 || - vst->codecpar->bits_per_coded_sample > (INT_MAX - 7) / (vst->codecpar->width * vst->codecpar->height)) { + bits_per_coded_sample = avio_rl32(pb); + if (bits_per_coded_sample > (INT_MAX - 7) / (width * height)) { av_log(avctx, AV_LOG_ERROR, - "invalid bits_per_coded_sample %d (size: %dx%d)\n", - vst->codecpar->bits_per_coded_sample, - vst->codecpar->width, vst->codecpar->height); + "invalid bits_per_coded_sample %u (size: %ux%u)\n", + bits_per_coded_sample, width, height); return AVERROR_INVALIDDATA; } + vst->codecpar->width = width; + vst->codecpar->height = height; + vst->codecpar->bits_per_coded_sample = bits_per_coded_sample; avio_skip(pb, 8 + 16 + 24); // black_level, white_level, xywh, active_area, exposure_bias if (avio_rl32(pb) != 0x2010100) /* RGGB */ avpriv_request_sample(avctx, "cfa_pattern"); @@ -376,6 +380,7 @@ static int read_header(AVFormatContext *avctx) if ((vst && !vst->nb_index_entries) || (ast && !ast->nb_index_entries)) { av_log(avctx, AV_LOG_ERROR, "no index entries found\n"); + read_close(avctx); return AVERROR_INVALIDDATA; } @@ -393,10 +398,14 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt) { MlvContext *mlv = avctx->priv_data; AVIOContext *pb; - AVStream *st = avctx->streams[mlv->stream_index]; + AVStream *st; int index, ret; unsigned int size, space; + if (!avctx->nb_streams) + return AVERROR_EOF; + + st = avctx->streams[mlv->stream_index]; if (mlv->pts >= st->duration) return AVERROR_EOF; @@ -407,6 +416,10 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt) } pb = mlv->pb[st->index_entries[index].size]; + if (!pb) { + ret = FFERROR_REDO; + goto next_packet; + } avio_seek(pb, st->index_entries[index].pos, SEEK_SET); avio_skip(pb, 4); // blockType @@ -435,12 +448,14 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt) pkt->stream_index = mlv->stream_index; pkt->pts = mlv->pts; + ret = 0; +next_packet: mlv->stream_index++; if (mlv->stream_index == avctx->nb_streams) { mlv->stream_index = 0; mlv->pts++; } - return 0; + return ret; } static int read_seek(AVFormatContext *avctx, int stream_index, int64_t timestamp, int flags) @@ -462,8 +477,7 @@ static int read_close(AVFormatContext *s) MlvContext *mlv = s->priv_data; int i; for (i = 0; i < 100; i++) - if (mlv->pb[i]) - ff_format_io_close(s, &mlv->pb[i]); + ff_format_io_close(s, &mlv->pb[i]); return 0; }