diff --git a/libavformat/mov.c b/libavformat/mov.c index 4370b48bc5..6c1985d3ff 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1227,6 +1227,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, ByteIOContext *pb, int entries) case CODEC_ID_GSM: case CODEC_ID_ADPCM_MS: case CODEC_ID_ADPCM_IMA_WAV: + st->codec->frame_size = sc->samples_per_frame; st->codec->block_align = sc->bytes_per_frame; break; case CODEC_ID_ALAC: diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 5230938872..6fe5da7f99 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -314,6 +314,16 @@ static int mov_pcm_le_gt16(enum CodecID codec_id) codec_id == CODEC_ID_PCM_F64LE; } +static int mov_write_ms_tag(ByteIOContext *pb, MOVTrack *track) +{ + int64_t pos = url_ftell(pb); + put_be32(pb, 0); + put_le32(pb, track->tag); + track->enc->codec_tag = track->tag >> 16; + ff_put_wav_header(pb, track->enc); + return updateSize(pb, pos); +} + static int mov_write_wave_tag(ByteIOContext *pb, MOVTrack *track) { int64_t pos = url_ftell(pb); @@ -339,6 +349,9 @@ static int mov_write_wave_tag(ByteIOContext *pb, MOVTrack *track) mov_write_ac3_tag(pb, track); } else if (track->enc->codec_id == CODEC_ID_ALAC) { mov_write_extradata_tag(pb, track); + } else if (track->enc->codec_id == CODEC_ID_ADPCM_MS || + track->enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) { + mov_write_ms_tag(pb, track); } put_be32(pb, 8); /* size */ @@ -395,7 +408,9 @@ static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack *track) if (mov_get_lpcm_flags(track->enc->codec_id)) tag = AV_RL32("lpcm"); version = 2; - } else if (track->audio_vbr || mov_pcm_le_gt16(track->enc->codec_id)) { + } else if (track->audio_vbr || mov_pcm_le_gt16(track->enc->codec_id) || + track->enc->codec_id == CODEC_ID_ADPCM_MS || + track->enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) { version = 1; } } @@ -457,6 +472,8 @@ static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack *track) track->enc->codec_id == CODEC_ID_AC3 || track->enc->codec_id == CODEC_ID_AMR_NB || track->enc->codec_id == CODEC_ID_ALAC || + track->enc->codec_id == CODEC_ID_ADPCM_MS || + track->enc->codec_id == CODEC_ID_ADPCM_IMA_WAV || mov_pcm_le_gt16(track->enc->codec_id))) mov_write_wave_tag(pb, track); else if(track->tag == MKTAG('m','p','4','a')) @@ -1909,6 +1926,9 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n"); return -1; } + } else if (enc->codec_id == CODEC_ID_ADPCM_MS || + enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) { + samplesInChunk = enc->frame_size; } else if (trk->sampleSize) samplesInChunk = size/trk->sampleSize; else @@ -2108,6 +2128,13 @@ static int mov_write_header(AVFormatContext *s) if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) { av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i); goto error; + }else if(st->codec->codec_id == CODEC_ID_ADPCM_MS || + st->codec->codec_id == CODEC_ID_ADPCM_IMA_WAV){ + if (!st->codec->block_align) { + av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i); + goto error; + } + track->sampleSize = st->codec->block_align; }else if(st->codec->frame_size > 1){ /* assume compressed audio */ track->audio_vbr = 1; }else{