Libav 0.7.1
libavcodec/shorten.c
Go to the documentation of this file.
00001 /*
00002  * Shorten decoder
00003  * Copyright (c) 2005 Jeff Muizelaar
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * Libav is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00029 #include <limits.h>
00030 #include "avcodec.h"
00031 #include "get_bits.h"
00032 #include "golomb.h"
00033 
00034 #define MAX_CHANNELS 8
00035 #define MAX_BLOCKSIZE 65535
00036 
00037 #define OUT_BUFFER_SIZE 16384
00038 
00039 #define ULONGSIZE 2
00040 
00041 #define WAVE_FORMAT_PCM 0x0001
00042 
00043 #define DEFAULT_BLOCK_SIZE 256
00044 
00045 #define TYPESIZE 4
00046 #define CHANSIZE 0
00047 #define LPCQSIZE 2
00048 #define ENERGYSIZE 3
00049 #define BITSHIFTSIZE 2
00050 
00051 #define TYPE_S16HL 3
00052 #define TYPE_S16LH 5
00053 
00054 #define NWRAP 3
00055 #define NSKIPSIZE 1
00056 
00057 #define LPCQUANT 5
00058 #define V2LPCQOFFSET (1 << LPCQUANT)
00059 
00060 #define FNSIZE 2
00061 #define FN_DIFF0        0
00062 #define FN_DIFF1        1
00063 #define FN_DIFF2        2
00064 #define FN_DIFF3        3
00065 #define FN_QUIT         4
00066 #define FN_BLOCKSIZE    5
00067 #define FN_BITSHIFT     6
00068 #define FN_QLPC         7
00069 #define FN_ZERO         8
00070 #define FN_VERBATIM     9
00071 
00072 #define VERBATIM_CKSIZE_SIZE 5
00073 #define VERBATIM_BYTE_SIZE 8
00074 #define CANONICAL_HEADER_SIZE 44
00075 
00076 typedef struct ShortenContext {
00077     AVCodecContext *avctx;
00078     GetBitContext gb;
00079 
00080     int min_framesize, max_framesize;
00081     int channels;
00082 
00083     int32_t *decoded[MAX_CHANNELS];
00084     int32_t *offset[MAX_CHANNELS];
00085     int *coeffs;
00086     uint8_t *bitstream;
00087     int bitstream_size;
00088     int bitstream_index;
00089     unsigned int allocated_bitstream_size;
00090     int header_size;
00091     uint8_t header[OUT_BUFFER_SIZE];
00092     int version;
00093     int cur_chan;
00094     int bitshift;
00095     int nmean;
00096     int internal_ftype;
00097     int nwrap;
00098     int blocksize;
00099     int bitindex;
00100     int32_t lpcqoffset;
00101 } ShortenContext;
00102 
00103 static av_cold int shorten_decode_init(AVCodecContext * avctx)
00104 {
00105     ShortenContext *s = avctx->priv_data;
00106     s->avctx = avctx;
00107     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00108 
00109     return 0;
00110 }
00111 
00112 static int allocate_buffers(ShortenContext *s)
00113 {
00114     int i, chan;
00115     int *coeffs;
00116 
00117     for (chan=0; chan<s->channels; chan++) {
00118         if(FFMAX(1, s->nmean) >= UINT_MAX/sizeof(int32_t)){
00119             av_log(s->avctx, AV_LOG_ERROR, "nmean too large\n");
00120             return -1;
00121         }
00122         if(s->blocksize + s->nwrap >= UINT_MAX/sizeof(int32_t) || s->blocksize + s->nwrap <= (unsigned)s->nwrap){
00123             av_log(s->avctx, AV_LOG_ERROR, "s->blocksize + s->nwrap too large\n");
00124             return -1;
00125         }
00126 
00127         s->offset[chan] = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean));
00128 
00129         s->decoded[chan] = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap));
00130         for (i=0; i<s->nwrap; i++)
00131             s->decoded[chan][i] = 0;
00132         s->decoded[chan] += s->nwrap;
00133     }
00134 
00135     coeffs = av_realloc(s->coeffs, s->nwrap * sizeof(*s->coeffs));
00136     if (!coeffs)
00137         return AVERROR(ENOMEM);
00138     s->coeffs = coeffs;
00139 
00140     return 0;
00141 }
00142 
00143 
00144 static inline unsigned int get_uint(ShortenContext *s, int k)
00145 {
00146     if (s->version != 0)
00147         k = get_ur_golomb_shorten(&s->gb, ULONGSIZE);
00148     return get_ur_golomb_shorten(&s->gb, k);
00149 }
00150 
00151 
00152 static void fix_bitshift(ShortenContext *s, int32_t *buffer)
00153 {
00154     int i;
00155 
00156     if (s->bitshift != 0)
00157         for (i = 0; i < s->blocksize; i++)
00158             buffer[s->nwrap + i] <<= s->bitshift;
00159 }
00160 
00161 
00162 static void init_offset(ShortenContext *s)
00163 {
00164     int32_t mean = 0;
00165     int  chan, i;
00166     int nblock = FFMAX(1, s->nmean);
00167     /* initialise offset */
00168     switch (s->internal_ftype)
00169     {
00170         case TYPE_S16HL:
00171         case TYPE_S16LH:
00172             mean = 0;
00173             break;
00174         default:
00175             av_log(s->avctx, AV_LOG_ERROR, "unknown audio type");
00176             abort();
00177     }
00178 
00179     for (chan = 0; chan < s->channels; chan++)
00180         for (i = 0; i < nblock; i++)
00181             s->offset[chan][i] = mean;
00182 }
00183 
00184 static inline int get_le32(GetBitContext *gb)
00185 {
00186     return av_bswap32(get_bits_long(gb, 32));
00187 }
00188 
00189 static inline short get_le16(GetBitContext *gb)
00190 {
00191     return av_bswap16(get_bits_long(gb, 16));
00192 }
00193 
00194 static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header_size)
00195 {
00196     GetBitContext hb;
00197     int len;
00198     short wave_format;
00199 
00200     init_get_bits(&hb, header, header_size*8);
00201     if (get_le32(&hb) != MKTAG('R','I','F','F')) {
00202         av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
00203         return -1;
00204     }
00205 
00206     skip_bits_long(&hb, 32);    /* chunk_size */
00207 
00208     if (get_le32(&hb) != MKTAG('W','A','V','E')) {
00209         av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n");
00210         return -1;
00211     }
00212 
00213     while (get_le32(&hb) != MKTAG('f','m','t',' ')) {
00214         len = get_le32(&hb);
00215         skip_bits(&hb, 8*len);
00216     }
00217     len = get_le32(&hb);
00218 
00219     if (len < 16) {
00220         av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n");
00221         return -1;
00222     }
00223 
00224     wave_format = get_le16(&hb);
00225 
00226     switch (wave_format) {
00227         case WAVE_FORMAT_PCM:
00228             break;
00229         default:
00230             av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n");
00231             return -1;
00232     }
00233 
00234     avctx->channels = get_le16(&hb);
00235     avctx->sample_rate = get_le32(&hb);
00236     avctx->bit_rate = get_le32(&hb) * 8;
00237     avctx->block_align = get_le16(&hb);
00238     avctx->bits_per_coded_sample = get_le16(&hb);
00239 
00240     if (avctx->bits_per_coded_sample != 16) {
00241         av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n");
00242         return -1;
00243     }
00244 
00245     len -= 16;
00246     if (len > 0)
00247         av_log(avctx, AV_LOG_INFO, "%d header bytes unparsed\n", len);
00248 
00249     return 0;
00250 }
00251 
00252 static int16_t * interleave_buffer(int16_t *samples, int nchan, int blocksize, int32_t **buffer) {
00253     int i, chan;
00254     for (i=0; i<blocksize; i++)
00255         for (chan=0; chan < nchan; chan++)
00256             *samples++ = FFMIN(buffer[chan][i], 32768);
00257     return samples;
00258 }
00259 
00260 static void decode_subframe_lpc(ShortenContext *s, int channel, int residual_size, int pred_order)
00261 {
00262     int sum, i, j;
00263     int *coeffs = s->coeffs;
00264 
00265     for (i=0; i<pred_order; i++)
00266         coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT);
00267 
00268     for (i=0; i < s->blocksize; i++) {
00269         sum = s->lpcqoffset;
00270         for (j=0; j<pred_order; j++)
00271             sum += coeffs[j] * s->decoded[channel][i-j-1];
00272         s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> LPCQUANT);
00273     }
00274 }
00275 
00276 
00277 static int shorten_decode_frame(AVCodecContext *avctx,
00278         void *data, int *data_size,
00279         AVPacket *avpkt)
00280 {
00281     const uint8_t *buf = avpkt->data;
00282     int buf_size = avpkt->size;
00283     ShortenContext *s = avctx->priv_data;
00284     int i, input_buf_size = 0;
00285     int16_t *samples = data;
00286     if(s->max_framesize == 0){
00287         s->max_framesize= 1024; // should hopefully be enough for the first header
00288         s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize);
00289     }
00290 
00291     if(1 && s->max_framesize){//FIXME truncated
00292         buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size);
00293         input_buf_size= buf_size;
00294 
00295         if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){
00296             //                printf("memmove\n");
00297             memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
00298             s->bitstream_index=0;
00299         }
00300         memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);
00301         buf= &s->bitstream[s->bitstream_index];
00302         buf_size += s->bitstream_size;
00303         s->bitstream_size= buf_size;
00304 
00305         if(buf_size < s->max_framesize){
00306             *data_size = 0;
00307             return input_buf_size;
00308         }
00309     }
00310     init_get_bits(&s->gb, buf, buf_size*8);
00311     skip_bits(&s->gb, s->bitindex);
00312     if (!s->blocksize)
00313     {
00314         int maxnlpc = 0;
00315         /* shorten signature */
00316         if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) {
00317             av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n");
00318             return -1;
00319         }
00320 
00321         s->lpcqoffset = 0;
00322         s->blocksize = DEFAULT_BLOCK_SIZE;
00323         s->channels = 1;
00324         s->nmean = -1;
00325         s->version = get_bits(&s->gb, 8);
00326         s->internal_ftype = get_uint(s, TYPESIZE);
00327 
00328         s->channels = get_uint(s, CHANSIZE);
00329         if (s->channels > MAX_CHANNELS) {
00330             av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
00331             return -1;
00332         }
00333 
00334         /* get blocksize if version > 0 */
00335         if (s->version > 0) {
00336             int skip_bytes;
00337             s->blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE));
00338             maxnlpc = get_uint(s, LPCQSIZE);
00339             s->nmean = get_uint(s, 0);
00340 
00341             skip_bytes = get_uint(s, NSKIPSIZE);
00342             for (i=0; i<skip_bytes; i++) {
00343                 skip_bits(&s->gb, 8);
00344             }
00345         }
00346         s->nwrap = FFMAX(NWRAP, maxnlpc);
00347 
00348         if (allocate_buffers(s))
00349             return -1;
00350 
00351         init_offset(s);
00352 
00353         if (s->version > 1)
00354             s->lpcqoffset = V2LPCQOFFSET;
00355 
00356         if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) {
00357             av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at beginning of stream\n");
00358             return -1;
00359         }
00360 
00361         s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
00362         if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) {
00363             av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", s->header_size);
00364             return -1;
00365         }
00366 
00367         for (i=0; i<s->header_size; i++)
00368             s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
00369 
00370         if (decode_wave_header(avctx, s->header, s->header_size) < 0)
00371             return -1;
00372 
00373         s->cur_chan = 0;
00374         s->bitshift = 0;
00375     }
00376     else
00377     {
00378         int cmd;
00379         int len;
00380         cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);
00381         switch (cmd) {
00382             case FN_ZERO:
00383             case FN_DIFF0:
00384             case FN_DIFF1:
00385             case FN_DIFF2:
00386             case FN_DIFF3:
00387             case FN_QLPC:
00388                 {
00389                     int residual_size = 0;
00390                     int channel = s->cur_chan;
00391                     int32_t coffset;
00392                     if (cmd != FN_ZERO) {
00393                         residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);
00394                         /* this is a hack as version 0 differed in defintion of get_sr_golomb_shorten */
00395                         if (s->version == 0)
00396                             residual_size--;
00397                     }
00398 
00399                     if (s->nmean == 0)
00400                         coffset = s->offset[channel][0];
00401                     else {
00402                         int32_t sum = (s->version < 2) ? 0 : s->nmean / 2;
00403                         for (i=0; i<s->nmean; i++)
00404                             sum += s->offset[channel][i];
00405                         coffset = sum / s->nmean;
00406                         if (s->version >= 2)
00407                             coffset >>= FFMIN(1, s->bitshift);
00408                     }
00409                     switch (cmd) {
00410                         case FN_ZERO:
00411                             for (i=0; i<s->blocksize; i++)
00412                                 s->decoded[channel][i] = 0;
00413                             break;
00414                         case FN_DIFF0:
00415                             for (i=0; i<s->blocksize; i++)
00416                                 s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + coffset;
00417                             break;
00418                         case FN_DIFF1:
00419                             for (i=0; i<s->blocksize; i++)
00420                                 s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + s->decoded[channel][i - 1];
00421                             break;
00422                         case FN_DIFF2:
00423                             for (i=0; i<s->blocksize; i++)
00424                                 s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 2*s->decoded[channel][i-1]
00425                                                                                                       -   s->decoded[channel][i-2];
00426                             break;
00427                         case FN_DIFF3:
00428                             for (i=0; i<s->blocksize; i++)
00429                                 s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 3*s->decoded[channel][i-1]
00430                                                                                                       - 3*s->decoded[channel][i-2]
00431                                                                                                       +   s->decoded[channel][i-3];
00432                             break;
00433                         case FN_QLPC:
00434                             {
00435                                 int pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE);
00436                                 if (pred_order > s->nwrap) {
00437                                     av_log(avctx, AV_LOG_ERROR,
00438                                            "invalid pred_order %d\n",
00439                                            pred_order);
00440                                     return -1;
00441                                 }
00442                                 for (i=0; i<pred_order; i++)
00443                                     s->decoded[channel][i - pred_order] -= coffset;
00444                                 decode_subframe_lpc(s, channel, residual_size, pred_order);
00445                                 if (coffset != 0)
00446                                     for (i=0; i < s->blocksize; i++)
00447                                         s->decoded[channel][i] += coffset;
00448                             }
00449                     }
00450                     if (s->nmean > 0) {
00451                         int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2;
00452                         for (i=0; i<s->blocksize; i++)
00453                             sum += s->decoded[channel][i];
00454 
00455                         for (i=1; i<s->nmean; i++)
00456                             s->offset[channel][i-1] = s->offset[channel][i];
00457 
00458                         if (s->version < 2)
00459                             s->offset[channel][s->nmean - 1] = sum / s->blocksize;
00460                         else
00461                             s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift;
00462                     }
00463                     for (i=-s->nwrap; i<0; i++)
00464                         s->decoded[channel][i] = s->decoded[channel][i + s->blocksize];
00465 
00466                     fix_bitshift(s, s->decoded[channel]);
00467 
00468                     s->cur_chan++;
00469                     if (s->cur_chan == s->channels) {
00470                         samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded);
00471                         s->cur_chan = 0;
00472                         goto frame_done;
00473                     }
00474                     break;
00475                 }
00476                 break;
00477             case FN_VERBATIM:
00478                 len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
00479                 while (len--) {
00480                     get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
00481                 }
00482                 break;
00483             case FN_BITSHIFT:
00484                 s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE);
00485                 break;
00486             case FN_BLOCKSIZE:
00487                 s->blocksize = get_uint(s, av_log2(s->blocksize));
00488                 break;
00489             case FN_QUIT:
00490                 *data_size = 0;
00491                 return buf_size;
00492                 break;
00493             default:
00494                 av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd);
00495                 return -1;
00496                 break;
00497         }
00498     }
00499 frame_done:
00500     *data_size = (int8_t *)samples - (int8_t *)data;
00501 
00502     //    s->last_blocksize = s->blocksize;
00503     s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8);
00504     i= (get_bits_count(&s->gb))/8;
00505     if (i > buf_size) {
00506         av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size);
00507         s->bitstream_size=0;
00508         s->bitstream_index=0;
00509         return -1;
00510     }
00511     if (s->bitstream_size) {
00512         s->bitstream_index += i;
00513         s->bitstream_size  -= i;
00514         return input_buf_size;
00515     } else
00516         return i;
00517 }
00518 
00519 static av_cold int shorten_decode_close(AVCodecContext *avctx)
00520 {
00521     ShortenContext *s = avctx->priv_data;
00522     int i;
00523 
00524     for (i = 0; i < s->channels; i++) {
00525         s->decoded[i] -= s->nwrap;
00526         av_freep(&s->decoded[i]);
00527         av_freep(&s->offset[i]);
00528     }
00529     av_freep(&s->bitstream);
00530     av_freep(&s->coeffs);
00531     return 0;
00532 }
00533 
00534 static void shorten_flush(AVCodecContext *avctx){
00535     ShortenContext *s = avctx->priv_data;
00536 
00537     s->bitstream_size=
00538         s->bitstream_index= 0;
00539 }
00540 
00541 AVCodec ff_shorten_decoder = {
00542     "shorten",
00543     AVMEDIA_TYPE_AUDIO,
00544     CODEC_ID_SHORTEN,
00545     sizeof(ShortenContext),
00546     shorten_decode_init,
00547     NULL,
00548     shorten_decode_close,
00549     shorten_decode_frame,
00550     .flush= shorten_flush,
00551     .long_name= NULL_IF_CONFIG_SMALL("Shorten"),
00552 };