summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Carlsson <joca@rixmail.se>2003-06-06 11:46:25 +0000
committerZdenek Kabelac <kabi@informatics.muni.cz>2003-06-06 11:46:25 +0000
commit14342fd53794471da963c6a41f2712bb09191945 (patch)
treea3017ce980de2acdf30732ac3c374755a3bef5ed
parent8f8c0800f82f7ba958183b288a7253c97463b5e5 (diff)
* missing part of the 3gp patch by Johannes Carlsson
Originally committed as revision 1933 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/mov.c120
1 files changed, 100 insertions, 20 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index f24a22b052..72f03d4fd4 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -59,6 +59,10 @@
/* in case you can't read a file, try commenting */
#define MOV_SPLIT_CHUNKS
+/* Special handling for movies created with Minolta Dimaxe Xi*/
+/* this fix should not interfere with other .mov files, but just in case*/
+#define MOV_MINOLTA_FIX
+
/* some streams in QT (and in MP4 mostly) aren't either video nor audio */
/* so we first list them as this, then clean up the list of streams we give back, */
/* getting rid of these */
@@ -768,9 +772,10 @@ static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
st->codec.bits_per_sample = get_be16(pb); /* depth */
st->codec.color_table_id = get_be16(pb); /* colortable id */
+/* These are set in mov_read_stts and might already be set!
st->codec.frame_rate = 25;
st->codec.frame_rate_base = 1;
-
+*/
size -= (16+8*4+2+32+2*2);
#if 0
while (size >= 8) {
@@ -878,7 +883,7 @@ static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
get_byte(pb); //frames_per_sample
#ifdef DEBUG
- printf("Audio: damr_type=%c%c%c%c damr_size=%Ld damr_vendor=%c%c%c%c\n",
+ printf("Audio: damr_type=%c%c%c%c damr_size=%d damr_vendor=%c%c%c%c\n",
(damr_type >> 24) & 0xff,
(damr_type >> 16) & 0xff,
(damr_type >> 8) & 0xff,
@@ -890,7 +895,7 @@ static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
(damr_vendor >> 0) & 0xff
);
#endif
-
+
st->time_length=0;//Not possible to get from this info, must count number of AMR frames
st->codec.sample_rate=8000;
st->codec.channels=1;
@@ -898,9 +903,20 @@ static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
st->codec.bit_rate=0; /*It is not possible to tell this before we have
an audio frame and even then every frame can be different*/
}
- else
- {
- get_be16(pb); /* version */
+ else if( st->codec.codec_tag == MKTAG( 'm', 'p', '4', 's' ))
+ {
+ //This is some stuff for the hint track, lets ignore it!
+ //Do some mp4 auto detect.
+ c->mp4=1;
+ size-=(16);
+ url_fskip(pb, size); /* The mp4s atom also contians a esds atom that we can skip*/
+ }
+ else if(size>=(16+20))
+ {//16 bytes read, reading atleast 20 more
+#ifdef DEBUG
+ printf("audio size=0x%X\n",size);
+#endif
+ uint16_t version = get_be16(pb); /* version */
get_be16(pb); /* revision level */
get_be32(pb); /* vendor */
@@ -925,14 +941,51 @@ static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
default:
;
}
- get_be32(pb); /* samples per packet */
- get_be32(pb); /* bytes per packet */
- get_be32(pb); /* bytes per frame */
- get_be32(pb); /* bytes per sample */
- {
- MOV_atom_t a = { format, url_ftell(pb), size - (16 + 20 + 16 + 8) };
- mov_read_default(c, pb, a);
- }
+
+ //Read QT version 1 fields. In version 0 theese dont exist
+#ifdef DEBUG
+ printf("version =%d mp4=%d\n",version,c->mp4);
+ printf("size-(16+20+16)=%d\n",size-(16+20+16));
+#endif
+ if((version==1) && size>=(16+20+16))
+ {
+ get_be32(pb); /* samples per packet */
+ get_be32(pb); /* bytes per packet */
+ get_be32(pb); /* bytes per frame */
+ get_be32(pb); /* bytes per sample */
+ if(size>(16+20+16))
+ {
+ //Optional, additional atom-based fields
+#ifdef DEBUG
+ printf("offest=0x%X, sizeleft=%d=0x%x,format=%c%c%c%c\n",(int)url_ftell(pb),size - (16 + 20 + 16 ),size - (16 + 20 + 16 ),
+ (format >> 0) & 0xff,
+ (format >> 8) & 0xff,
+ (format >> 16) & 0xff,
+ (format >> 24) & 0xff);
+#endif
+ MOV_atom_t a = { format, url_ftell(pb), size - (16 + 20 + 16 + 8) };
+ mov_read_default(c, pb, a);
+ }
+ }
+ else
+ {
+ //We should be down to 0 bytes here, but lets make sure.
+ size-=(16+20);
+#ifdef DEBUG
+ if(size>0)
+ printf("skipping 0x%X bytes\n",size-(16+20));
+#endif
+ url_fskip(pb, size);
+ }
+ }
+ else
+ {
+ size-=16;
+ //Unknown size, but lets do our best and skip the rest.
+#ifdef DEBUG
+ printf("Strange size, skipping 0x%X bytes\n",size);
+#endif
+ url_fskip(pb, size);
}
}
}
@@ -1043,16 +1096,43 @@ printf("track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
#endif
}
- if(st->codec.codec_type==CODEC_TYPE_VIDEO)
+#define MAX(a,b) a>b?a:b
+#define MIN(a,b) a>b?b:a
+ /*The stsd atom which contain codec type sometimes comes after the stts so we cannot check for codec_type*/
+ if(duration>0)
{
+ //Find greatest common divisor to avoid overflow using the Euclidean Algorithm...
+ uint32_t max=MAX(duration,total_sample_count);
+ uint32_t min=MIN(duration,total_sample_count);
+ uint32_t spare=max%min;
+
+ while(spare!=0)
+ {
+ max=min;
+ min=spare;
+ spare=max%min;
+ }
+
+ duration/=min;
+ total_sample_count/=min;
+
//Only support constant frame rate. But lets calculate the average. Needed by .mp4-files created with nec e606 3g phone.
- //Hmm, lets set base to 1
- st->codec.frame_rate_base=1;
- st->codec.frame_rate = st->codec.frame_rate_base * c->streams[c->total_streams]->time_scale * total_sample_count / duration;
+ //To get better precision, we use the duration as frame_rate_base
+
+ st->codec.frame_rate_base=duration;
+ st->codec.frame_rate = c->streams[c->total_streams]->time_scale * total_sample_count;
+
#ifdef DEBUG
- printf("VIDEO FRAME RATE average= %i (tot sample count= %i ,tot dur= %i)\n", st->codec.frame_rate,total_sample_count,duration);
+ printf("FRAME RATE average (video or audio)= %f (tot sample count= %i ,tot dur= %i timescale=%d)\n", (float)st->codec.frame_rate/st->codec.frame_rate_base,total_sample_count,duration,c->streams[c->total_streams]->time_scale);
#endif
}
+ else
+ {
+ st->codec.frame_rate_base = 1;
+ st->codec.frame_rate = c->streams[c->total_streams]->time_scale;
+ }
+#undef MAX
+#undef MIN
return 0;
}
@@ -1334,7 +1414,7 @@ static int mov_probe(AVProbeData *p)
return AVPROBE_SCORE_MAX;
case MKTAG( 'f', 't', 'y', 'p' ):
case MKTAG( 's', 'k', 'i', 'p' ):
- offset = to_be32(p->buf) + offset;
+ offset = to_be32(p->buf+offset) + offset;
break;
default:
/* unrecognized tag */