mirror of https://git.ffmpeg.org/ffmpeg.git
avformat/rsd: add WADP support
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
3919089beb
commit
3a63890154
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
static const AVCodecTag rsd_tags[] = {
|
static const AVCodecTag rsd_tags[] = {
|
||||||
{ AV_CODEC_ID_ADPCM_THP, MKTAG('G','A','D','P') },
|
{ AV_CODEC_ID_ADPCM_THP, MKTAG('G','A','D','P') },
|
||||||
|
{ AV_CODEC_ID_ADPCM_THP, MKTAG('W','A','D','P') },
|
||||||
{ AV_CODEC_ID_ADPCM_IMA_RAD, MKTAG('R','A','D','P') },
|
{ AV_CODEC_ID_ADPCM_IMA_RAD, MKTAG('R','A','D','P') },
|
||||||
{ AV_CODEC_ID_ADPCM_IMA_WAV, MKTAG('X','A','D','P') },
|
{ AV_CODEC_ID_ADPCM_IMA_WAV, MKTAG('X','A','D','P') },
|
||||||
{ AV_CODEC_ID_PCM_S16BE, MKTAG('P','C','M','B') },
|
{ AV_CODEC_ID_PCM_S16BE, MKTAG('P','C','M','B') },
|
||||||
|
@ -37,7 +38,6 @@ static const AVCodecTag rsd_tags[] = {
|
||||||
static const uint32_t rsd_unsupported_tags[] = {
|
static const uint32_t rsd_unsupported_tags[] = {
|
||||||
MKTAG('O','G','G',' '),
|
MKTAG('O','G','G',' '),
|
||||||
MKTAG('V','A','G',' '),
|
MKTAG('V','A','G',' '),
|
||||||
MKTAG('W','A','D','P'),
|
|
||||||
MKTAG('X','M','A',' '),
|
MKTAG('X','M','A',' '),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -110,19 +110,32 @@ static int rsd_read_header(AVFormatContext *s)
|
||||||
st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start);
|
st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start);
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_ADPCM_THP:
|
case AV_CODEC_ID_ADPCM_THP:
|
||||||
/* RSD3GADP is mono, so only alloc enough memory
|
if (st->codec->codec_tag == MKTAG('G','A','D','P')) {
|
||||||
to store the coeff table for a single channel. */
|
/* RSD3GADP is mono, so only alloc enough memory
|
||||||
|
to store the coeff table for a single channel. */
|
||||||
|
|
||||||
start = avio_rl32(pb);
|
start = avio_rl32(pb);
|
||||||
|
|
||||||
if (ff_get_extradata(codec, s->pb, 32) < 0)
|
if (ff_get_extradata(codec, s->pb, 32) < 0)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
AV_WB16(codec->extradata + i * 2, AV_RL16(codec->extradata + i * 2));
|
AV_WB16(codec->extradata + i * 2, AV_RL16(codec->extradata + i * 2));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
codec->block_align = 8 * codec->channels;
|
||||||
|
avio_skip(s->pb, 0x1A4 - avio_tell(s->pb));
|
||||||
|
|
||||||
|
if (ff_alloc_extradata(st->codec, 32 * st->codec->channels) < 0)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
for (i = 0; i < st->codec->channels; i++) {
|
||||||
|
avio_read(s->pb, st->codec->extradata + 32 * i, 32);
|
||||||
|
avio_skip(s->pb, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (pb->seekable)
|
if (pb->seekable)
|
||||||
st->duration = (avio_size(pb) - start) / 8 * 14;
|
st->duration = (avio_size(pb) - start) / (8 * st->codec->channels) * 14;
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_PCM_S16LE:
|
case AV_CODEC_ID_PCM_S16LE:
|
||||||
case AV_CODEC_ID_PCM_S16BE:
|
case AV_CODEC_ID_PCM_S16BE:
|
||||||
|
@ -150,18 +163,24 @@ static int rsd_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||||
return AVERROR_EOF;
|
return AVERROR_EOF;
|
||||||
|
|
||||||
if (codec->codec_id == AV_CODEC_ID_ADPCM_IMA_RAD ||
|
if (codec->codec_id == AV_CODEC_ID_ADPCM_IMA_RAD ||
|
||||||
codec->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV)
|
codec->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
|
||||||
ret = av_get_packet(s->pb, pkt, codec->block_align);
|
ret = av_get_packet(s->pb, pkt, codec->block_align);
|
||||||
else
|
} else if (codec->codec_tag == MKTAG('W','A','D','P') &&
|
||||||
ret = av_get_packet(s->pb, pkt, size);
|
codec->channels > 1) {
|
||||||
|
int i, ch;
|
||||||
|
|
||||||
if (ret != size) {
|
av_new_packet(pkt, codec->block_align);
|
||||||
if (ret < 0) {
|
for (i = 0; i < 4; i++) {
|
||||||
av_free_packet(pkt);
|
for (ch = 0; ch < codec->channels; ch++) {
|
||||||
return ret;
|
pkt->data[ch * 8 + i * 2 + 0] = avio_r8(s->pb);
|
||||||
|
pkt->data[ch * 8 + i * 2 + 1] = avio_r8(s->pb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
av_shrink_packet(pkt, ret);
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
ret = av_get_packet(s->pb, pkt, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pkt->stream_index = 0;
|
pkt->stream_index = 0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue