mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-17 21:14:47 +00:00
Merge remote-tracking branch 'qatar/master'
* qatar/master: ape: fix seeking apedec: 8bit and 24bit support Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
bfb5ba8495
@ -131,6 +131,7 @@ typedef struct APEContext {
|
||||
DSPContext dsp;
|
||||
int channels;
|
||||
int samples; ///< samples left to decode in current frame
|
||||
int bps;
|
||||
|
||||
int fileversion; ///< codec version, very important in decoding process
|
||||
int compression_level; ///< compression levels
|
||||
@ -184,14 +185,26 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
|
||||
av_log(avctx, AV_LOG_ERROR, "Incorrect extradata\n");
|
||||
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) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n");
|
||||
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->channels = avctx->channels;
|
||||
s->fileversion = AV_RL16(avctx->extradata);
|
||||
@ -215,7 +228,6 @@ static av_cold int ape_decode_init(AVCodecContext *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;
|
||||
|
||||
avcodec_get_frame_defaults(&s->frame);
|
||||
@ -816,7 +828,9 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
APEContext *s = avctx->priv_data;
|
||||
int16_t *samples;
|
||||
uint8_t *sample8;
|
||||
int16_t *sample16;
|
||||
int32_t *sample24;
|
||||
int i, ret;
|
||||
int blockstodecode;
|
||||
int bytes_used = 0;
|
||||
@ -894,7 +908,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
|
||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||
return ret;
|
||||
}
|
||||
samples = (int16_t *)s->frame.data[0];
|
||||
|
||||
s->error=0;
|
||||
|
||||
@ -910,10 +923,31 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
for (i = 0; i < blockstodecode; i++) {
|
||||
*samples++ = s->decoded0[i];
|
||||
if(s->channels == 2)
|
||||
*samples++ = s->decoded1[i];
|
||||
switch (s->bps) {
|
||||
case 8:
|
||||
sample8 = (uint8_t *)s->frame.data[0];
|
||||
for (i = 0; i < blockstodecode; i++) {
|
||||
*sample8++ = (s->decoded0[i] + 0x80) & 0xff;
|
||||
if (s->channels == 2)
|
||||
*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;
|
||||
|
@ -406,6 +406,8 @@ static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
|
||||
if (index < 0)
|
||||
return -1;
|
||||
|
||||
if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0)
|
||||
return -1;
|
||||
ape->currentframe = index;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user