Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/mov.c')
-rw-r--r--libavformat/mov.c86
1 files changed, 51 insertions, 35 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index c16add7713..302ab18857 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -23,11 +23,11 @@
#include <limits.h>
//#define DEBUG
-//#define DEBUG_METADATA
//#define MOV_EXPORT_ALL_METADATA
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "avio_internal.h"
#include "riff.h"
@@ -79,15 +79,15 @@ typedef struct MOVParseTableEntry {
static const MOVParseTableEntry mov_default_parse_table[];
-static int mov_metadata_trkn(MOVContext *c, AVIOContext *pb, unsigned len)
+static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *type)
{
char buf[16];
avio_rb16(pb); // unknown
snprintf(buf, sizeof(buf), "%d", avio_rb16(pb));
- av_metadata_set2(&c->fc->metadata, "track", buf, 0);
+ av_dict_set(&c->fc->metadata, type, buf, 0);
- avio_rb16(pb); // total tracks
+ avio_rb16(pb); // total tracks/discs
return 0;
}
@@ -138,7 +138,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
const char *key = NULL;
uint16_t str_size, langcode = 0;
uint32_t data_type = 0;
- int (*parse)(MOVContext*, AVIOContext*, unsigned) = NULL;
+ int (*parse)(MOVContext*, AVIOContext*, unsigned, const char *) = NULL;
switch (atom.type) {
case MKTAG(0xa9,'n','a','m'): key = "title"; break;
@@ -164,7 +164,9 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
case MKTAG( 't','v','e','n'): key = "episode_id";break;
case MKTAG( 't','v','n','n'): key = "network"; break;
case MKTAG( 't','r','k','n'): key = "track";
- parse = mov_metadata_trkn; break;
+ parse = mov_metadata_track_or_disc_number; break;
+ case MKTAG( 'd','i','s','k'): key = "disc";
+ parse = mov_metadata_track_or_disc_number; break;
}
if (c->itunes_metadata && atom.size > 8) {
@@ -199,7 +201,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
str_size = FFMIN3(sizeof(str)-1, str_size, atom.size);
if (parse)
- parse(c, pb, str_size);
+ parse(c, pb, str_size, key);
else {
if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Encoded
mov_read_mac_string(c, pb, str_size, str, sizeof(str));
@@ -207,17 +209,15 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_read(pb, str, str_size);
str[str_size] = 0;
}
- av_metadata_set2(&c->fc->metadata, key, str, 0);
+ av_dict_set(&c->fc->metadata, key, str, 0);
if (*language && strcmp(language, "und")) {
snprintf(key2, sizeof(key2), "%s-%s", key, language);
- av_metadata_set2(&c->fc->metadata, key2, str, 0);
+ av_dict_set(&c->fc->metadata, key2, str, 0);
}
}
-#ifdef DEBUG_METADATA
- av_log(c->fc, AV_LOG_DEBUG, "lang \"%3s\" ", language);
- av_log(c->fc, AV_LOG_DEBUG, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %lld\n",
- key, str, (char*)&atom.type, str_size, atom.size);
-#endif
+ av_dlog(c->fc, "lang \"%3s\" ", language);
+ av_dlog(c->fc, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %"PRId64"\n",
+ key, str, (char*)&atom.type, str_size, atom.size);
return 0;
}
@@ -431,7 +431,7 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
uint32_t type;
- uint32_t ctype;
+ uint32_t av_unused ctype;
if (c->fc->nb_streams < 1) // meta before first trak
return 0;
@@ -467,21 +467,21 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
- int tag, len;
+ int tag;
if (fc->nb_streams < 1)
return 0;
st = fc->streams[fc->nb_streams-1];
avio_rb32(pb); /* version + flags */
- len = ff_mp4_read_descr(fc, pb, &tag);
+ ff_mp4_read_descr(fc, pb, &tag);
if (tag == MP4ESDescrTag) {
avio_rb16(pb); /* ID */
avio_r8(pb); /* priority */
} else
avio_rb16(pb); /* ID */
- len = ff_mp4_read_descr(fc, pb, &tag);
+ ff_mp4_read_descr(fc, pb, &tag);
if (tag == MP4DecConfigDescrTag)
ff_mp4_read_dec_config_descr(fc, st, pb);
return 0;
@@ -513,6 +513,19 @@ static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ AVStream *st;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams-1];
+
+ ff_get_wav_header(pb, st->codec, atom.size);
+
+ return 0;
+}
+
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
const int num = avio_rb32(pb);
@@ -558,10 +571,10 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (strcmp(type, "qt "))
c->isom = 1;
av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
- av_metadata_set2(&c->fc->metadata, "major_brand", type, 0);
+ av_dict_set(&c->fc->metadata, "major_brand", type, 0);
minor_ver = avio_rb32(pb); /* minor version */
snprintf(minor_ver_str, sizeof(minor_ver_str), "%d", minor_ver);
- av_metadata_set2(&c->fc->metadata, "minor_version", minor_ver_str, 0);
+ av_dict_set(&c->fc->metadata, "minor_version", minor_ver_str, 0);
comp_brand_size = atom.size - 8;
if (comp_brand_size < 0)
@@ -571,7 +584,7 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return AVERROR(ENOMEM);
avio_read(pb, comp_brands_str, comp_brand_size);
comp_brands_str[comp_brand_size] = 0;
- av_metadata_set2(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
+ av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
av_freep(&comp_brands_str);
return 0;
@@ -595,7 +608,7 @@ static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return mov_read_default(c, pb, atom);
}
-static void mov_metadata_creation_time(AVMetadata **metadata, time_t time)
+static void mov_metadata_creation_time(AVDictionary **metadata, time_t time)
{
char buffer[32];
if (time) {
@@ -604,7 +617,7 @@ static void mov_metadata_creation_time(AVMetadata **metadata, time_t time)
ptm = gmtime(&time);
if (!ptm) return;
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm);
- av_metadata_set2(metadata, "creation_time", buffer, 0);
+ av_dict_set(metadata, "creation_time", buffer, 0);
}
}
@@ -641,7 +654,7 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
lang = avio_rb16(pb); /* language */
if (ff_mov_lang_to_iso639(lang, language))
- av_metadata_set2(&st->metadata, "language", language, 0);
+ av_dict_set(&st->metadata, "language", language, 0);
avio_rb16(pb); /* quality */
return 0;
@@ -718,7 +731,7 @@ static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- little_endian = avio_rb16(pb);
+ little_endian = avio_rb16(pb) & 0xFF;
av_dlog(c->fc, "enda %d\n", little_endian);
if (little_endian == 1) {
switch (st->codec->codec_id) {
@@ -1525,10 +1538,11 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
/* adjust first dts according to edit list */
if (sc->time_offset && mov->time_scale > 0) {
- int rescaled = sc->time_offset < 0 ? av_rescale(sc->time_offset, sc->time_scale, mov->time_scale) : sc->time_offset;
- current_dts = -rescaled;
+ if (sc->time_offset < 0)
+ sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale);
+ current_dts = -sc->time_offset;
if (sc->ctts_data && sc->stts_data &&
- sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) {
+ sc->ctts_data[0].duration / FFMAX(sc->stts_data[0].duration, 1) > 16) {
/* more than 16 frames delay, dts are likely wrong
this happens with files created by iMovie */
sc->wrong_dts = 1;
@@ -1690,13 +1704,13 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
}
-static int mov_open_dref(AVIOContext **pb, char *src, MOVDref *ref)
+static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref)
{
/* try relative path, we do not try the absolute because it can leak information about our
system to an attacker */
if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
char filename[1024];
- char *src_path;
+ const char *src_path;
int i, l;
/* find a source dir */
@@ -1914,6 +1928,10 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->width = width >> 16;
sc->height = height >> 16;
+ if (display_matrix[0][0] == -65536 && display_matrix[1][1] == -65536) {
+ av_dict_set(&st->metadata, "rotate", "180", 0);
+ }
+
// 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
@@ -2056,7 +2074,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (flags & 0x001) data_offset = avio_rb32(pb);
if (flags & 0x004) first_sample_flags = avio_rb32(pb);
- dts = st->duration;
+ dts = st->duration - sc->time_offset;
offset = frag->base_data_offset + data_offset;
distance = 0;
av_dlog(c->fc, "first sample flags 0x%x\n", first_sample_flags);
@@ -2085,7 +2103,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
offset += sample_size;
}
frag->moof_offset = offset;
- st->duration = dts;
+ st->duration = dts + sc->time_offset;
return 0;
}
@@ -2149,9 +2167,6 @@ static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
goto free_and_return;
atom.type = MKTAG('m','o','o','v');
atom.size = moov_len;
-#ifdef DEBUG
-// { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
-#endif
ret = mov_read_default(c, &ctx, atom);
free_and_return:
av_free(moov_data);
@@ -2265,6 +2280,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('e','s','d','s'), mov_read_esds },
{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
+{ MKTAG('w','f','e','x'), mov_read_wfex },
{ MKTAG('c','m','o','v'), mov_read_cmov },
{ MKTAG('c','h','a','n'), mov_read_chan },
{ 0, NULL }