#include "libavutil/attributes.h"
#include "libavutil/channel_layout.h"
-#include "libavutil/display.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/mathematics.h"
#include "libavutil/time_internal.h"
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
+#include "libavutil/display.h"
#include "libavutil/opt.h"
#include "libavutil/timecode.h"
#include "libavcodec/ac3tab.h"
if (!key)
return 0;
- if (atom.size < 0)
+ if (atom.size < 0 || str_size >= INT_MAX/2)
return AVERROR_INVALIDDATA;
// worst-case requirement for output string in case of utf8 coded input
str_size_alloc = (raw ? str_size : str_size * 2) + 1;
- str = av_malloc(str_size_alloc);
+ str = av_mallocz(str_size_alloc);
if (!str)
return AVERROR(ENOMEM);
return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
}
+static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
+}
+
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
st->codec->codec_id == AV_CODEC_ID_QDMC ||
st->codec->codec_id == AV_CODEC_ID_SPEEX) {
// pass all frma atom to codec, needed at least for QDMC and QDM2
- av_free(st->codec->extradata);
+ av_freep(&st->codec->extradata);
if (ff_get_extradata(st->codec, pb, atom.size) < 0)
return AVERROR(ENOMEM);
} else if (atom.size > 8) { /* to read frma, esds atoms */
av_log(c, AV_LOG_WARNING, "ignoring multiple glbl\n");
return 0;
}
- av_free(st->codec->extradata);
+ av_freep(&st->codec->extradata);
if (ff_get_extradata(st->codec, pb, atom.size) < 0)
return AVERROR(ENOMEM);
return 0;
avio_seek(pb, 6, SEEK_CUR);
- av_free(st->codec->extradata);
+ av_freep(&st->codec->extradata);
if ((ret = ff_get_extradata(st->codec, pb, atom.size - 7)) < 0)
return ret;
return AVERROR_INVALIDDATA;
avio_skip(pb, 40);
- av_free(st->codec->extradata);
+ av_freep(&st->codec->extradata);
if (ff_get_extradata(st->codec, pb, atom.size - 40) < 0)
return AVERROR(ENOMEM);
return 0;
st->codec->flags2 |= CODEC_FLAG2_DROP_FRAME_TIMECODE;
st->codec->time_base.den = st->codec->extradata[16]; /* number of frame */
st->codec->time_base.num = 1;
+ /* adjust for per frame dur in counter mode */
+ if (tmcd_ctx->tmcd_flags & 0x0008) {
+ int timescale = AV_RB32(st->codec->extradata + 8);
+ int framedur = AV_RB32(st->codec->extradata + 12);
+ st->codec->time_base.den *= timescale;
+ st->codec->time_base.num *= framedur;
+ }
if (size > 30) {
uint32_t len = AV_RB32(st->codec->extradata + 18); /* name atom length */
uint32_t format = AV_RB32(st->codec->extradata + 22);
int i;
int width;
int height;
- int64_t disp_transform[2];
int display_matrix[3][3];
AVStream *st;
MOVStreamContext *sc;
}
// transform the display width/height according to the matrix
- // skip this if the display matrix is the default identity matrix
- // or if it is rotating the picture, ex iPhone 3GS
// to keep the same scale, use [width height 1<<16]
- if (width && height &&
- ((display_matrix[0][0] != 65536 ||
- display_matrix[1][1] != 65536) &&
- !display_matrix[0][1] &&
- !display_matrix[1][0] &&
- !display_matrix[2][0] && !display_matrix[2][1])) {
+ if (width && height && sc->display_matrix) {
+ double disp_transform[2];
+
+#define SQR(a) ((a)*(double)(a))
for (i = 0; i < 2; i++)
- disp_transform[i] =
- (int64_t) width * display_matrix[0][i] +
- (int64_t) height * display_matrix[1][i] +
- ((int64_t) display_matrix[2][i] << 16);
-
- //sample aspect ratio is new width/height divided by old width/height
- st->sample_aspect_ratio = av_d2q(
- ((double) disp_transform[0] * height) /
- ((double) disp_transform[1] * width), INT_MAX);
+ disp_transform[i] = sqrt(SQR(display_matrix[i][0]) + SQR(display_matrix[i][1]));
+
+ if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
+ disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
+ fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
+ st->sample_aspect_ratio = av_d2q(
+ disp_transform[0] / disp_transform[1],
+ INT_MAX);
}
return 0;
}
{ MKTAG('c','o','l','r'), mov_read_colr },
{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
{ MKTAG('d','i','n','f'), mov_read_default },
+{ MKTAG('D','p','x','E'), mov_read_dpxe },
{ MKTAG('d','r','e','f'), mov_read_dref },
{ MKTAG('e','d','t','s'), mov_read_default },
{ MKTAG('e','l','s','t'), mov_read_elst },
}
}
total_size += 8;
- if (a.size == 1) { /* 64 bit extended size */
+ if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
a.size = avio_rb64(pb) - 8;
total_size += 8;
}
sc->drefs_count = 0;
if (!sc->pb_is_copied)
- avio_close(sc->pb);
+ avio_closep(&sc->pb);
sc->pb = NULL;
av_freep(&sc->chunk_offsets);
static int read_tfra(MOVContext *mov, AVIOContext *f)
{
MOVFragmentIndex* index = NULL;
- int version, fieldlength, i, j, err;
+ int version, fieldlength, i, j;
int64_t pos = avio_tell(f);
uint32_t size = avio_rb32(f);
+ void *tmp;
+
if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
- return -1;
+ return 1;
}
av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
index = av_mallocz(sizeof(MOVFragmentIndex));
if (!index) {
return AVERROR(ENOMEM);
}
- mov->fragment_index_count++;
- if ((err = av_reallocp(&mov->fragment_index_data,
- mov->fragment_index_count *
- sizeof(MOVFragmentIndex*))) < 0) {
+
+ tmp = av_realloc_array(mov->fragment_index_data,
+ mov->fragment_index_count + 1,
+ sizeof(MOVFragmentIndex*));
+ if (!tmp) {
av_freep(&index);
- return err;
+ return AVERROR(ENOMEM);
}
- mov->fragment_index_data[mov->fragment_index_count - 1] =
- index;
+ mov->fragment_index_data = tmp;
+ mov->fragment_index_data[mov->fragment_index_count++] = index;
version = avio_r8(f);
avio_rb24(f);
index->track_id = avio_rb32(f);
fieldlength = avio_rb32(f);
index->item_count = avio_rb32(f);
- index->items = av_mallocz(
- index->item_count * sizeof(MOVFragmentIndexItem));
+ index->items = av_mallocz_array(
+ index->item_count, sizeof(MOVFragmentIndexItem));
if (!index->items) {
+ index->item_count = 0;
return AVERROR(ENOMEM);
}
for (i = 0; i < index->item_count; i++) {
av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
goto fail;
}
- ret = 0;
av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
- while (!read_tfra(c, f)) {
- /* Empty */
- }
+ do {
+ ret = read_tfra(c, f);
+ if (ret < 0)
+ goto fail;
+ } while (!ret);
+ ret = 0;
fail:
seek_ret = avio_seek(f, original_pos, SEEK_SET);
if (seek_ret < 0) {
#if CONFIG_DV_DEMUXER
if (mov->dv_demux && sc->dv_audio_container) {
avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
- av_free(pkt->data);
+ av_freep(&pkt->data);
pkt->size = 0;
ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
if (ret < 0)