#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
-#include "libavutil/bswap.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
#include "libavutil/internal.h"
AVFormatContext *sub_ctx;
AVPacket sub_pkt;
- uint8_t *sub_buffer;
+ AVBufferRef *sub_buffer;
int64_t seek_pos;
} AVIStream;
{ 0 },
};
+static int avi_read_close(AVFormatContext *s);
static int avi_load_index(AVFormatContext *s);
static int guess_ni_flag(AVFormatContext *s);
-#define print_tag(str, tag, size) \
- av_log(NULL, AV_LOG_TRACE, "pos:%"PRIX64" %s: tag=%s size=0x%x\n", \
+#define print_tag(s, str, tag, size) \
+ av_log(s, AV_LOG_TRACE, "pos:%"PRIX64" %s: tag=%s size=0x%x\n", \
avio_tell(pb), str, av_fourcc2str(tag), size) \
static inline int get_duration(AVIStream *ast, int len)
value = av_malloc(size + 1);
if (!value)
return AVERROR(ENOMEM);
- if (avio_read(pb, value, size) != size)
+ if (avio_read(pb, value, size) != size) {
+ av_freep(&value);
return AVERROR_INVALIDDATA;
+ }
value[size] = 0;
AV_WL32(key, tag);
maxpos = FFMAX(maxpos, st->index_entries[j-1].pos);
lensum += len;
}
- if (maxpos < avi->io_fsize*9/10) // index does not cover the whole file
+ if (maxpos < av_rescale(avi->io_fsize, 9, 10)) // index does not cover the whole file
return 0;
if (lensum*9/10 > maxpos || lensum < maxpos*9/10) // frame sum and filesize mismatch
return 0;
continue;
duration = st->index_entries[j-1].timestamp - st->index_entries[0].timestamp;
bitrate = av_rescale(8*len, st->time_base.den, duration * st->time_base.num);
- if (bitrate <= INT_MAX && bitrate > 0) {
+ if (bitrate > 0) {
st->codecpar->bit_rate = bitrate;
}
}
return 1;
}
+#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0)
static int avi_read_header(AVFormatContext *s)
{
AVIContext *avi = s->priv_data;
frame_period = 0;
for (;;) {
if (avio_feof(pb))
- goto fail;
+ RETURN_ERROR(AVERROR_INVALIDDATA);
tag = avio_rl32(pb);
size = avio_rl32(pb);
- print_tag("tag", tag, size);
+ print_tag(s, "tag", tag, size);
switch (tag) {
case MKTAG('L', 'I', 'S', 'T'):
/* Ignored, except at start of video packets. */
tag1 = avio_rl32(pb);
- print_tag("list", tag1, 0);
+ print_tag(s, "list", tag1, 0);
if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
avi->movi_list = avio_tell(pb) - 4;
avi->movi_end = avi->movi_list + size + (size & 1);
else
avi->movi_end = avi->fsize;
- av_log(NULL, AV_LOG_TRACE, "movi end=%"PRIx64"\n", avi->movi_end);
+ av_log(s, AV_LOG_TRACE, "movi end=%"PRIx64"\n", avi->movi_end);
goto end_of_header;
} else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
ff_read_riff_info(s, size - 4);
stream_index++;
st = avformat_new_stream(s, NULL);
if (!st)
- goto fail;
+ RETURN_ERROR(AVERROR(ENOMEM));
st->id = stream_index;
ast = av_mallocz(sizeof(AVIStream));
if (!ast)
- goto fail;
+ RETURN_ERROR(AVERROR(ENOMEM));
st->priv_data = ast;
}
if (amv_file_format)
tag1 = stream_index ? MKTAG('a', 'u', 'd', 's')
: MKTAG('v', 'i', 'd', 's');
- print_tag("strh", tag1, -1);
+ print_tag(s, "strh", tag1, -1);
if (tag1 == MKTAG('i', 'a', 'v', 's') ||
tag1 == MKTAG('i', 'v', 'a', 's')) {
/* After some consideration -- I don't think we
* have to support anything but DV in type1 AVIs. */
if (s->nb_streams != 1)
- goto fail;
+ RETURN_ERROR(AVERROR_INVALIDDATA);
if (handler != MKTAG('d', 'v', 's', 'd') &&
handler != MKTAG('d', 'v', 'h', 'd') &&
handler != MKTAG('d', 'v', 's', 'l'))
- goto fail;
+ return AVERROR_INVALIDDATA;
+
+ if (!CONFIG_DV_DEMUXER)
+ return AVERROR_DEMUXER_NOT_FOUND;
ast = s->streams[0]->priv_data;
- av_freep(&s->streams[0]->codecpar->extradata);
- av_freep(&s->streams[0]->codecpar);
-#if FF_API_LAVF_AVCTX
-FF_DISABLE_DEPRECATION_WARNINGS
- av_freep(&s->streams[0]->codec);
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- if (s->streams[0]->info)
- av_freep(&s->streams[0]->info->duration_error);
- av_freep(&s->streams[0]->info);
- if (s->streams[0]->internal)
- av_freep(&s->streams[0]->internal->avctx);
- av_freep(&s->streams[0]->internal);
- av_freep(&s->streams[0]);
- s->nb_streams = 0;
- if (CONFIG_DV_DEMUXER) {
- avi->dv_demux = avpriv_dv_init_demux(s);
- if (!avi->dv_demux)
- goto fail;
- } else
- goto fail;
+ st->priv_data = NULL;
+ ff_free_stream(s, st);
+
+ avi->dv_demux = avpriv_dv_init_demux(s);
+ if (!avi->dv_demux) {
+ av_free(ast);
+ return AVERROR(ENOMEM);
+ }
+
s->streams[0]->priv_data = ast;
avio_skip(pb, 3 * 4);
ast->scale = avio_rl32(pb);
"Invalid sample_size %d at stream %d\n",
ast->sample_size,
stream_index);
- goto fail;
+ RETURN_ERROR(AVERROR_INVALIDDATA);
}
av_log(s, AV_LOG_WARNING,
"Invalid sample_size %d at stream %d "
st->codecpar->extradata_size = size - 10 * 4;
if (st->codecpar->extradata) {
av_log(s, AV_LOG_WARNING, "New extradata in strf chunk, freeing previous one.\n");
- av_freep(&st->codecpar->extradata);
}
- if (ff_get_extradata(s, st->codecpar, pb, st->codecpar->extradata_size) < 0)
- return AVERROR(ENOMEM);
+ ret = ff_get_extradata(s, st->codecpar, pb,
+ st->codecpar->extradata_size);
+ if (ret < 0)
+ return ret;
}
// FIXME: check if the encoder really did this correctly
ast->has_pal = 1;
}
- print_tag("video", tag1, 0);
+ print_tag(s, "video", tag1, 0);
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
st->codecpar->codec_tag = tag1;
"mov tag found in avi (fourcc %s)\n",
av_fourcc2str(tag1));
}
+ if (!st->codecpar->codec_id)
+ st->codecpar->codec_id = ff_codec_get_id(ff_codec_bmp_tags_unofficial, tag1);
+
/* This is needed to get the pict type which is necessary
* for generating correct pts. */
st->need_parsing = AVSTREAM_PARSE_HEADERS;
st->need_parsing = AVSTREAM_PARSE_FULL;
if (st->codecpar->codec_id == AV_CODEC_ID_RV40)
st->need_parsing = AVSTREAM_PARSE_NONE;
+ if (st->codecpar->codec_id == AV_CODEC_ID_HEVC &&
+ st->codecpar->codec_tag == MKTAG('H', '2', '6', '5'))
+ st->need_parsing = AVSTREAM_PARSE_FULL;
if (st->codecpar->codec_tag == 0 && st->codecpar->height > 0 &&
st->codecpar->extradata_size < 1U << 30) {
break;
case AVMEDIA_TYPE_SUBTITLE:
st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
- st->request_probe= 1;
+ st->internal->request_probe= 1;
avio_skip(pb, size);
break;
default:
if (size<(1<<30)) {
if (st->codecpar->extradata) {
av_log(s, AV_LOG_WARNING, "New extradata in strd chunk, freeing previous one.\n");
- av_freep(&st->codecpar->extradata);
}
- if (ff_get_extradata(s, st->codecpar, pb, size) < 0)
- return AVERROR(ENOMEM);
+ if ((ret = ff_get_extradata(s, st->codecpar, pb, size)) < 0)
+ goto fail;
}
if (st->codecpar->extradata_size & 1) //FIXME check if the encoder really did this correctly
avi->use_odml &&
read_odml_index(s, 0) < 0 &&
(s->error_recognition & AV_EF_EXPLODE))
- goto fail;
+ RETURN_ERROR(AVERROR_INVALIDDATA);
avio_seek(pb, pos + size, SEEK_SET);
break;
case MKTAG('v', 'p', 'r', 'p'):
if (s->nb_streams) {
ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size);
if (ret < 0)
- return ret;
+ goto fail;
break;
}
default:
"I will ignore it and try to continue anyway.\n",
av_fourcc2str(tag), size);
if (s->error_recognition & AV_EF_EXPLODE)
- goto fail;
+ RETURN_ERROR(AVERROR_INVALIDDATA);
avi->movi_list = avio_tell(pb) - 4;
avi->movi_end = avi->fsize;
goto end_of_header;
end_of_header:
/* check stream number */
if (stream_index != s->nb_streams - 1) {
-
-fail:
- return AVERROR_INVALIDDATA;
+ RETURN_ERROR(AVERROR_INVALIDDATA);
}
if (!avi->index_loaded && (pb->seekable & AVIO_SEEKABLE_NORMAL))
avi->index_loaded |= 1;
if ((ret = guess_ni_flag(s)) < 0)
- return ret;
+ goto fail;
avi->non_interleaved |= ret | (s->flags & AVFMT_FLAG_SORT_DTS);
ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
return 0;
+fail:
+ avi_read_close(s);
+ return ret;
}
static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
uint8_t desc[256];
int score = AVPROBE_SCORE_EXTENSION, ret;
AVIStream *ast = st->priv_data;
- AVInputFormat *sub_demuxer;
+ ff_const59 AVInputFormat *sub_demuxer;
AVRational time_base;
int size;
+ AVProbeData pd;
+ unsigned int desc_len;
AVIOContext *pb = avio_alloc_context(pkt->data + 7,
pkt->size - 7,
0, NULL, NULL, NULL, NULL);
- AVProbeData pd;
- unsigned int desc_len = avio_rl32(pb);
+ if (!pb)
+ goto error;
+
+ desc_len = avio_rl32(pb);
if (desc_len > pb->buf_end - pb->buf_ptr)
goto error;
time_base = ast->sub_ctx->streams[0]->time_base;
avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
}
- ast->sub_buffer = pkt->data;
- memset(pkt, 0, sizeof(*pkt));
+ ast->sub_buffer = pkt->buf;
+ pkt->buf = NULL;
+ av_packet_unref(pkt);
return 1;
error:
if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) {
int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
- if (avi->dts_max - dts > 2*AV_TIME_BASE) {
+ if (avi->dts_max < dts) {
+ avi->dts_max = dts;
+ } else if (avi->dts_max - (uint64_t)dts > 2*AV_TIME_BASE) {
avi->non_interleaved= 1;
av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
- }else if (avi->dts_max < dts)
- avi->dts_max = dts;
+ }
}
return 0;
av_freep(&ast->sub_ctx->pb);
avformat_close_input(&ast->sub_ctx);
}
- av_freep(&ast->sub_buffer);
+ av_buffer_unref(&ast->sub_buffer);
av_packet_unref(&ast->sub_pkt);
}
}
return 0;
}
-static int avi_probe(AVProbeData *p)
+static int avi_probe(const AVProbeData *p)
{
int i;