diff --git a/libavformat/mov.c b/libavformat/mov.c index 0c3f988ae43fc352ee17dc7ab1680e88845f3ace..4100f33b87e748883a6eeb648e239e809f10fb37 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1206,6 +1206,92 @@ static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, } } +static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, + AVStream *st, MOVStreamContext *sc) +{ + int bits_per_sample, flags; + uint16_t version = avio_rb16(pb); + + avio_rb16(pb); /* revision level */ + avio_rb32(pb); /* vendor */ + + st->codec->channels = avio_rb16(pb); /* channel count */ + st->codec->bits_per_coded_sample = avio_rb16(pb); /* sample size */ + av_dlog(c->fc, "audio channels %d\n", st->codec->channels); + + sc->audio_cid = avio_rb16(pb); + avio_rb16(pb); /* packet size = 0 */ + + st->codec->sample_rate = ((avio_rb32(pb) >> 16)); + + // Read QT version 1 fields. In version 0 these do not exist. + av_dlog(c->fc, "version =%d, isom =%d\n", version, c->isom); + if (!c->isom) { + if (version == 1) { + sc->samples_per_frame = avio_rb32(pb); + avio_rb32(pb); /* bytes per packet */ + sc->bytes_per_frame = avio_rb32(pb); + avio_rb32(pb); /* bytes per sample */ + } else if (version == 2) { + avio_rb32(pb); /* sizeof struct only */ + st->codec->sample_rate = av_int2double(avio_rb64(pb)); + st->codec->channels = avio_rb32(pb); + avio_rb32(pb); /* always 0x7F000000 */ + st->codec->bits_per_coded_sample = avio_rb32(pb); + + flags = avio_rb32(pb); /* lpcm format specific flag */ + sc->bytes_per_frame = avio_rb32(pb); + sc->samples_per_frame = avio_rb32(pb); + if (st->codec->codec_tag == MKTAG('l','p','c','m')) + st->codec->codec_id = + ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, + flags); + } + } + + switch (st->codec->codec_id) { + case AV_CODEC_ID_PCM_S8: + case AV_CODEC_ID_PCM_U8: + if (st->codec->bits_per_coded_sample == 16) + st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; + break; + case AV_CODEC_ID_PCM_S16LE: + case AV_CODEC_ID_PCM_S16BE: + if (st->codec->bits_per_coded_sample == 8) + st->codec->codec_id = AV_CODEC_ID_PCM_S8; + else if (st->codec->bits_per_coded_sample == 24) + st->codec->codec_id = + st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ? + AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE; + break; + /* set values for old format before stsd version 1 appeared */ + case AV_CODEC_ID_MACE3: + sc->samples_per_frame = 6; + sc->bytes_per_frame = 2 * st->codec->channels; + break; + case AV_CODEC_ID_MACE6: + sc->samples_per_frame = 6; + sc->bytes_per_frame = 1 * st->codec->channels; + break; + case AV_CODEC_ID_ADPCM_IMA_QT: + sc->samples_per_frame = 64; + sc->bytes_per_frame = 34 * st->codec->channels; + break; + case AV_CODEC_ID_GSM: + sc->samples_per_frame = 160; + sc->bytes_per_frame = 33; + break; + default: + break; + } + + bits_per_sample = av_get_bits_per_sample(st->codec->codec_id); + if (bits_per_sample) { + st->codec->bits_per_coded_sample = bits_per_sample; + sc->sample_size = (bits_per_sample >> 3) * st->codec->channels; + } +} + int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) { AVStream *st; @@ -1266,85 +1352,8 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) st->codec->codec_id = id; mov_parse_stsd_video(c, pb, st, sc); } else if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO) { - int bits_per_sample, flags; - uint16_t version = avio_rb16(pb); - st->codec->codec_id = id; - avio_rb16(pb); /* revision level */ - avio_rb32(pb); /* vendor */ - - st->codec->channels = avio_rb16(pb); /* channel count */ - av_dlog(c->fc, "audio channels %d\n", st->codec->channels); - st->codec->bits_per_coded_sample = avio_rb16(pb); /* sample size */ - - sc->audio_cid = avio_rb16(pb); - avio_rb16(pb); /* packet size = 0 */ - - st->codec->sample_rate = ((avio_rb32(pb) >> 16)); - - //Read QT version 1 fields. In version 0 these do not exist. - av_dlog(c->fc, "version =%d, isom =%d\n",version,c->isom); - if (!c->isom) { - if (version==1) { - sc->samples_per_frame = avio_rb32(pb); - avio_rb32(pb); /* bytes per packet */ - sc->bytes_per_frame = avio_rb32(pb); - avio_rb32(pb); /* bytes per sample */ - } else if (version==2) { - avio_rb32(pb); /* sizeof struct only */ - st->codec->sample_rate = av_int2double(avio_rb64(pb)); /* float 64 */ - st->codec->channels = avio_rb32(pb); - avio_rb32(pb); /* always 0x7F000000 */ - st->codec->bits_per_coded_sample = avio_rb32(pb); /* bits per channel if sound is uncompressed */ - flags = avio_rb32(pb); /* lpcm format specific flag */ - sc->bytes_per_frame = avio_rb32(pb); /* bytes per audio packet if constant */ - sc->samples_per_frame = avio_rb32(pb); /* lpcm frames per audio packet if constant */ - if (format == MKTAG('l','p','c','m')) - st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, flags); - } - } - - switch (st->codec->codec_id) { - case AV_CODEC_ID_PCM_S8: - case AV_CODEC_ID_PCM_U8: - if (st->codec->bits_per_coded_sample == 16) - st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; - break; - case AV_CODEC_ID_PCM_S16LE: - case AV_CODEC_ID_PCM_S16BE: - if (st->codec->bits_per_coded_sample == 8) - st->codec->codec_id = AV_CODEC_ID_PCM_S8; - else if (st->codec->bits_per_coded_sample == 24) - st->codec->codec_id = - st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ? - AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE; - break; - /* set values for old format before stsd version 1 appeared */ - case AV_CODEC_ID_MACE3: - sc->samples_per_frame = 6; - sc->bytes_per_frame = 2*st->codec->channels; - break; - case AV_CODEC_ID_MACE6: - sc->samples_per_frame = 6; - sc->bytes_per_frame = 1*st->codec->channels; - break; - case AV_CODEC_ID_ADPCM_IMA_QT: - sc->samples_per_frame = 64; - sc->bytes_per_frame = 34*st->codec->channels; - break; - case AV_CODEC_ID_GSM: - sc->samples_per_frame = 160; - sc->bytes_per_frame = 33; - break; - default: - break; - } - - bits_per_sample = av_get_bits_per_sample(st->codec->codec_id); - if (bits_per_sample) { - st->codec->bits_per_coded_sample = bits_per_sample; - sc->sample_size = (bits_per_sample >> 3) * st->codec->channels; - } + mov_parse_stsd_audio(c, pb, st, sc); } else if (st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){ // ttxt stsd contains display flags, justification, background // color, fonts, and default styles, so fake an atom to read it