X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmace.c;h=792d71d072eea3d45b8832c5c9d3611d2a5e1bb1;hb=55b9ef18e4a139fc24a3b695cb3c176f3ced09b8;hp=6e7a12812b9be502698f70174e792e1260bfe0b2;hpb=d636f0cc397fed8eb27daed896abab8972041baf;p=ffmpeg diff --git a/libavcodec/mace.c b/libavcodec/mace.c index 6e7a12812b9..792d71d072e 100644 --- a/libavcodec/mace.c +++ b/libavcodec/mace.c @@ -2,39 +2,39 @@ * MACE decoder * Copyright (c) 2002 Laszlo Torok * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file mace.c + * @file * MACE decoder. */ #include "avcodec.h" /* - * Adapted to ffmpeg by Francois Revol + * Adapted to libavcodec by Francois Revol * (removed 68k REG stuff, changed types, added some statics and consts, * libavcodec api, context stuff, interlaced stereo out). */ -static const uint16_t MACEtab1[] = { 0xfff3, 0x0008, 0x004c, 0x00de, 0x00de, 0x004c, 0x0008, 0xfff3 }; +static const int16_t MACEtab1[] = {-13, 8, 76, 222, 222, 76, 8, -13}; -static const uint16_t MACEtab3[] = { 0xffee, 0x008c, 0x008c, 0xffee }; +static const int16_t MACEtab3[] = {-18, 140, 140, -18}; static const int16_t MACEtab2[][4] = { { 37, 116, 206, 330}, { 39, 121, 216, 346}, @@ -138,13 +138,22 @@ static const int16_t MACEtab4[][2] = { { 14576, 32767}, { 15226, 32767}, { 15906, 32767}, { 16615, 32767} }; +static const struct { + const int16_t *tab1; const int16_t *tab2; int stride; +} tabs[] = { + {MACEtab1, &MACEtab2[0][0], 4}, + {MACEtab3, &MACEtab4[0][0], 2}, + {MACEtab1, &MACEtab2[0][0], 4} +}; + #define QT_8S_2_16S(x) (((x) & 0xFF00) | (((x) >> 8) & 0xFF)) typedef struct ChannelData { - int16_t index, lev, factor, prev2, previous, level; + int16_t index, factor, prev2, previous, level; } ChannelData; typedef struct MACEContext { + AVFrame frame; ChannelData chd[2]; } MACEContext; @@ -162,37 +171,39 @@ static inline int16_t mace_broken_clip_int16(int n) return n; } -static void chomp3(ChannelData *chd, int16_t *output, uint8_t val, - const uint16_t tab1[], - const int16_t *tab2, int tab2_stride, - uint32_t numChannels) +static int16_t read_table(ChannelData *chd, uint8_t val, int tab_idx) { int16_t current; - if (val < tab2_stride) - current = tab2[((chd->index & 0x7f0) >> 4)*tab2_stride + val]; + if (val < tabs[tab_idx].stride) + current = tabs[tab_idx].tab2[((chd->index & 0x7f0) >> 4) * tabs[tab_idx].stride + val]; else - current = - 1 - tab2[((chd->index & 0x7f0) >> 4)*tab2_stride + 2*tab2_stride-val-1]; + current = - 1 - tabs[tab_idx].tab2[((chd->index & 0x7f0) >> 4)*tabs[tab_idx].stride + 2*tabs[tab_idx].stride-val-1]; - current = mace_broken_clip_int16(current + chd->lev); + if (( chd->index += tabs[tab_idx].tab1[val]-(chd->index >> 5) ) < 0) + chd->index = 0; - chd->lev = current - (current >> 3); + return current; +} + +static void chomp3(ChannelData *chd, int16_t *output, uint8_t val, + int tab_idx, + uint32_t numChannels) +{ + + int16_t current = read_table(chd, val, tab_idx); + + current = mace_broken_clip_int16(current + chd->level); + + chd->level = current - (current >> 3); *output = QT_8S_2_16S(current); - if (( chd->index += tab1[val]-(chd->index >> 5) ) < 0) - chd->index = 0; } static void chomp6(ChannelData *chd, int16_t *output, uint8_t val, - const uint16_t tab1[], - const int16_t *tab2, int tab2_stride, + int tab_idx, uint32_t numChannels) { - int16_t current; - - if (val < tab2_stride) - current = tab2[((chd->index & 0x7f0) >> 4)*tab2_stride + val]; - else - current = - 1 - tab2[((chd->index & 0x7f0) >> 4)*tab2_stride + 2*tab2_stride-val-1]; + int16_t current = read_table(chd, val, tab_idx); if ((chd->previous ^ current) >= 0) { chd->factor = FFMIN(chd->factor + 506, 32767); @@ -205,7 +216,7 @@ static void chomp6(ChannelData *chd, int16_t *output, uint8_t val, current = mace_broken_clip_int16(current + chd->level); - chd->level = ((current*chd->factor) >> 15); + chd->level = (current*chd->factor) >> 15; current >>= 1; output[0] = QT_8S_2_16S(chd->previous + chd->prev2 - @@ -214,102 +225,89 @@ static void chomp6(ChannelData *chd, int16_t *output, uint8_t val, ((chd->prev2-current) >> 2)); chd->prev2 = chd->previous; chd->previous = current; - - if ((chd->index += tab1[val] - (chd->index >> 5)) < 0) - chd->index = 0; } static av_cold int mace_decode_init(AVCodecContext * avctx) { + MACEContext *ctx = avctx->priv_data; + if (avctx->channels > 2) return -1; - avctx->sample_fmt = SAMPLE_FMT_S16; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + avcodec_get_frame_defaults(&ctx->frame); + avctx->coded_frame = &ctx->frame; + return 0; } -static int mace3_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - const uint8_t *buf, int buf_size) +static int mace_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) { - int16_t *samples = data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + int16_t *samples; MACEContext *ctx = avctx->priv_data; - int i, j, k; + int i, j, k, l, ret; + int is_mace3 = (avctx->codec_id == CODEC_ID_MACE3); + + /* get output buffer */ + ctx->frame.nb_samples = 3 * (buf_size << (1 - is_mace3)) / avctx->channels; + if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + samples = (int16_t *)ctx->frame.data[0]; for(i = 0; i < avctx->channels; i++) { int16_t *output = samples + i; - for (j=0; j < buf_size / 2 / avctx->channels; j++) - for (k=0; k < 2; k++) { - uint8_t pkt = buf[i*2 + j*2*avctx->channels + k]; - chomp3(&ctx->chd[i], output, pkt &7, MACEtab1, MACEtab2, - 4, avctx->channels); - output += avctx->channels; - chomp3(&ctx->chd[i], output,(pkt >> 3) &3, MACEtab3, MACEtab4, - 2, avctx->channels); - output += avctx->channels; - chomp3(&ctx->chd[i], output, pkt >> 5 , MACEtab1, MACEtab2, - 4, avctx->channels); - output += avctx->channels; - } - } - - *data_size = 2 * 3 * buf_size; + for (j=0; j < buf_size / (avctx->channels << is_mace3); j++) + for (k=0; k < (1 << is_mace3); k++) { + uint8_t pkt = buf[(i << is_mace3) + + (j*avctx->channels << is_mace3) + k]; - return buf_size; -} - -static int mace6_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - const uint8_t *buf, int buf_size) -{ - int16_t *samples = data; - MACEContext *ctx = avctx->priv_data; - int i, j; + uint8_t val[2][3] = {{pkt >> 5, (pkt >> 3) & 3, pkt & 7 }, + {pkt & 7 , (pkt >> 3) & 3, pkt >> 5}}; - for(i = 0; i < avctx->channels; i++) { - int16_t *output = samples + i; + for (l=0; l < 3; l++) { + if (is_mace3) + chomp3(&ctx->chd[i], output, val[1][l], l, + avctx->channels); + else + chomp6(&ctx->chd[i], output, val[0][l], l, + avctx->channels); - for (j = 0; j < buf_size / avctx->channels; j++) { - uint8_t pkt = buf[i + j*avctx->channels]; - - chomp6(&ctx->chd[i], output, pkt >> 5 , MACEtab1, MACEtab2, - 4, avctx->channels); - output += avctx->channels << 1; - chomp6(&ctx->chd[i], output,(pkt >> 3) & 3, MACEtab3, MACEtab4, - 2, avctx->channels); - output += avctx->channels << 1; - chomp6(&ctx->chd[i], output, pkt & 7, MACEtab1, MACEtab2, - 4, avctx->channels); - output += avctx->channels << 1; - } + output += avctx->channels << (1-is_mace3); + } + } } - *data_size = 2 * 6 * buf_size; + *got_frame_ptr = 1; + *(AVFrame *)data = ctx->frame; return buf_size; } -AVCodec mace3_decoder = { - "mace3", - CODEC_TYPE_AUDIO, - CODEC_ID_MACE3, - sizeof(MACEContext), - mace_decode_init, - NULL, - NULL, - mace3_decode_frame, +AVCodec ff_mace3_decoder = { + .name = "mace3", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_MACE3, + .priv_data_size = sizeof(MACEContext), + .init = mace_decode_init, + .decode = mace_decode_frame, + .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 3:1"), }; -AVCodec mace6_decoder = { - "mace6", - CODEC_TYPE_AUDIO, - CODEC_ID_MACE6, - sizeof(MACEContext), - mace_decode_init, - NULL, - NULL, - mace6_decode_frame, +AVCodec ff_mace6_decoder = { + .name = "mace6", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_MACE6, + .priv_data_size = sizeof(MACEContext), + .init = mace_decode_init, + .decode = mace_decode_frame, + .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 6:1"), };