Commit bfb5ba84 authored by Michael Niedermayer's avatar Michael Niedermayer

Merge remote-tracking branch 'qatar/master'

* qatar/master:
  ape: fix seeking
  apedec: 8bit and 24bit support
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 7e850f1c 86b57e4e
...@@ -131,6 +131,7 @@ typedef struct APEContext { ...@@ -131,6 +131,7 @@ typedef struct APEContext {
DSPContext dsp; DSPContext dsp;
int channels; int channels;
int samples; ///< samples left to decode in current frame int samples; ///< samples left to decode in current frame
int bps;
int fileversion; ///< codec version, very important in decoding process int fileversion; ///< codec version, very important in decoding process
int compression_level; ///< compression levels int compression_level; ///< compression levels
...@@ -184,14 +185,26 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) ...@@ -184,14 +185,26 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
av_log(avctx, AV_LOG_ERROR, "Incorrect extradata\n"); av_log(avctx, AV_LOG_ERROR, "Incorrect extradata\n");
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
if (avctx->bits_per_coded_sample != 16) {
av_log(avctx, AV_LOG_ERROR, "Only 16-bit samples are supported\n");
return AVERROR(EINVAL);
}
if (avctx->channels > 2) { if (avctx->channels > 2) {
av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n"); av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n");
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
s->bps = avctx->bits_per_coded_sample;
switch (s->bps) {
case 8:
avctx->sample_fmt = AV_SAMPLE_FMT_U8;
break;
case 16:
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
break;
case 24:
avctx->sample_fmt = AV_SAMPLE_FMT_S32;
break;
default:
av_log_ask_for_sample(avctx, "Unsupported bits per coded sample %d\n",
s->bps);
return AVERROR_PATCHWELCOME;
}
s->avctx = avctx; s->avctx = avctx;
s->channels = avctx->channels; s->channels = avctx->channels;
s->fileversion = AV_RL16(avctx->extradata); s->fileversion = AV_RL16(avctx->extradata);
...@@ -215,7 +228,6 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) ...@@ -215,7 +228,6 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
} }
dsputil_init(&s->dsp, avctx); dsputil_init(&s->dsp, avctx);
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
avcodec_get_frame_defaults(&s->frame); avcodec_get_frame_defaults(&s->frame);
...@@ -816,7 +828,9 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, ...@@ -816,7 +828,9 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
{ {
const uint8_t *buf = avpkt->data; const uint8_t *buf = avpkt->data;
APEContext *s = avctx->priv_data; APEContext *s = avctx->priv_data;
int16_t *samples; uint8_t *sample8;
int16_t *sample16;
int32_t *sample24;
int i, ret; int i, ret;
int blockstodecode; int blockstodecode;
int bytes_used = 0; int bytes_used = 0;
...@@ -894,7 +908,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, ...@@ -894,7 +908,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret; return ret;
} }
samples = (int16_t *)s->frame.data[0];
s->error=0; s->error=0;
...@@ -910,10 +923,31 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, ...@@ -910,10 +923,31 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
switch (s->bps) {
case 8:
sample8 = (uint8_t *)s->frame.data[0];
for (i = 0; i < blockstodecode; i++) { for (i = 0; i < blockstodecode; i++) {
*samples++ = s->decoded0[i]; *sample8++ = (s->decoded0[i] + 0x80) & 0xff;
if(s->channels == 2) if (s->channels == 2)
*samples++ = s->decoded1[i]; *sample8++ = (s->decoded1[i] + 0x80) & 0xff;
}
break;
case 16:
sample16 = (int16_t *)s->frame.data[0];
for (i = 0; i < blockstodecode; i++) {
*sample16++ = s->decoded0[i];
if (s->channels == 2)
*sample16++ = s->decoded1[i];
}
break;
case 24:
sample24 = (int32_t *)s->frame.data[0];
for (i = 0; i < blockstodecode; i++) {
*sample24++ = s->decoded0[i] << 8;
if (s->channels == 2)
*sample24++ = s->decoded1[i] << 8;
}
break;
} }
s->samples -= blockstodecode; s->samples -= blockstodecode;
......
...@@ -406,6 +406,8 @@ static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp ...@@ -406,6 +406,8 @@ static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
if (index < 0) if (index < 0)
return -1; return -1;
if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0)
return -1;
ape->currentframe = index; ape->currentframe = index;
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment