#include "isom.h"
#include "libavcodec/mpeg4audio.h"
#include "libavcodec/mpegaudiodata.h"
-#include "libavcodec/bitstream.h"
+#include "libavcodec/get_bits.h"
#if CONFIG_ZLIB
#include <zlib.h>
{ CODEC_ID_MP3ON4, AOT_L1 }, /* layer 1 */
{ CODEC_ID_MP3ON4, AOT_L2 }, /* layer 2 */
{ CODEC_ID_MP3ON4, AOT_L3 }, /* layer 3 */
+ { CODEC_ID_MP4ALS, AOT_ALS }, /* MPEG-4 ALS */
{ CODEC_ID_NONE, AOT_NULL },
};
// color, fonts, and default styles, so fake an atom to read it
MOVAtom fake_atom = { .size = size - (url_ftell(pb) - start_pos) };
if (format != AV_RL32("mp4s")) // mp4s contains a regular esds atom
- mov_read_glbl(c, pb, fake_atom);
+ mov_read_glbl(c, pb, fake_atom);
st->codec->codec_id= id;
st->codec->width = sc->width;
st->codec->height = sc->height;
#endif
/* no ifdef since parameters are always those */
case CODEC_ID_QCELP:
+ // force sample rate for qcelp when not stored in mov
+ if (st->codec->codec_tag != MKTAG('Q','c','l','p'))
+ st->codec->sample_rate = 8000;
st->codec->frame_size= 160;
st->codec->channels= 1; /* really needed */
break;
return 0;
}
+static int mov_read_cslg(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
+{
+ AVStream *st;
+ MOVStreamContext *sc;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams-1];
+ sc = st->priv_data;
+
+ get_be32(pb); // version + flags
+
+ sc->dts_shift = get_be32(pb);
+ dprintf(c->fc, "dts shift %d\n", sc->dts_shift);
+
+ sc->time_rate= av_gcd(sc->time_rate, FFABS(sc->dts_shift));
+
+ get_be32(pb); // least dts to pts delta
+ get_be32(pb); // greatest dts to pts delta
+ get_be32(pb); // pts start
+ get_be32(pb); // pts end
+
+ return 0;
+}
+
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
AVStream *st = c->fc->streams[c->fc->nb_streams-1];
int count =get_be32(pb);
int duration =get_be32(pb);
- if (duration < 0) {
- sc->wrong_dts = 1;
- st->codec->has_b_frames = 1;
- }
sc->ctts_data[i].count = count;
sc->ctts_data[i].duration= duration;
unsigned int distance = 0;
int key_off = sc->keyframes && sc->keyframes[0] == 1;
+ sc->dts_shift /= sc->time_rate;
+ current_dts -= sc->dts_shift;
+
st->nb_frames = sc->sample_count;
for (i = 0; i < sc->chunk_count; i++) {
current_offset = sc->chunk_offsets[i];
static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('a','v','s','s'), mov_read_extradata },
{ MKTAG('c','o','6','4'), mov_read_stco },
+{ MKTAG('c','s','l','g'), mov_read_cslg },
{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
{ MKTAG('d','i','n','f'), mov_read_default },
{ MKTAG('d','r','e','f'), mov_read_dref },
pkt->dts = sample->timestamp;
if (sc->ctts_data) {
assert(sc->ctts_data[sc->ctts_index].duration % sc->time_rate == 0);
- pkt->pts = pkt->dts + sc->ctts_data[sc->ctts_index].duration / sc->time_rate;
+ pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration / sc->time_rate;
/* update ctts context */
sc->ctts_sample++;
if (sc->ctts_index < sc->ctts_count &&