00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <celt/celt.h>
00023 #include <celt/celt_header.h>
00024 #include "avcodec.h"
00025 #include "libavutil/intreadwrite.h"
00026
00027 struct libcelt_context {
00028 CELTMode *mode;
00029 CELTDecoder *dec;
00030 int frame_bytes;
00031 int discard;
00032 };
00033
00034 static int ff_celt_error_to_averror(int err)
00035 {
00036 switch(err) {
00037 case CELT_BAD_ARG: return AVERROR(EINVAL);
00038 #ifdef CELT_BUFFER_TOO_SMALL
00039 case CELT_BUFFER_TOO_SMALL: return AVERROR(ENOBUFS);
00040 #endif
00041 case CELT_INTERNAL_ERROR: return AVERROR(EFAULT);
00042 case CELT_CORRUPTED_DATA: return AVERROR_INVALIDDATA;
00043 case CELT_UNIMPLEMENTED: return AVERROR(ENOTSUP);
00044 #ifdef ENOTRECOVERABLE
00045 case CELT_INVALID_STATE: return AVERROR(ENOTRECOVERABLE);
00046 #endif
00047 case CELT_ALLOC_FAIL: return AVERROR(ENOMEM);
00048 default: return AVERROR(EINVAL);
00049 }
00050 }
00051
00052 static int ff_celt_bitstream_version_hack(CELTMode *mode)
00053 {
00054 CELTHeader header = { .version_id = 0 };
00055 celt_header_init(&header, mode, 960, 2);
00056 return header.version_id;
00057 }
00058
00059 static av_cold int libcelt_dec_init(AVCodecContext *c)
00060 {
00061 struct libcelt_context *celt = c->priv_data;
00062 int err;
00063
00064 if (!c->channels || !c->frame_size ||
00065 c->frame_size > INT_MAX / sizeof(int16_t) / c->channels)
00066 return AVERROR(EINVAL);
00067 celt->frame_bytes = c->frame_size * c->channels * sizeof(int16_t);
00068 celt->mode = celt_mode_create(c->sample_rate, c->frame_size, &err);
00069 if (!celt->mode)
00070 return ff_celt_error_to_averror(err);
00071 celt->dec = celt_decoder_create_custom(celt->mode, c->channels, &err);
00072 if (!celt->dec) {
00073 celt_mode_destroy(celt->mode);
00074 return ff_celt_error_to_averror(err);
00075 }
00076 if (c->extradata_size >= 4) {
00077 celt->discard = AV_RL32(c->extradata);
00078 if (celt->discard < 0 || celt->discard >= c->frame_size) {
00079 av_log(c, AV_LOG_WARNING,
00080 "Invalid overlap (%d), ignored.\n", celt->discard);
00081 celt->discard = 0;
00082 }
00083 celt->discard *= c->channels * sizeof(int16_t);
00084 }
00085 if(c->extradata_size >= 8) {
00086 unsigned version = AV_RL32(c->extradata + 4);
00087 unsigned lib_version = ff_celt_bitstream_version_hack(celt->mode);
00088 if (version != lib_version)
00089 av_log(c, AV_LOG_WARNING,
00090 "CELT bitstream version 0x%x may be "
00091 "improperly decoded by libcelt for version 0x%x.\n",
00092 version, lib_version);
00093 }
00094 return 0;
00095 }
00096
00097 static av_cold int libcelt_dec_close(AVCodecContext *c)
00098 {
00099 struct libcelt_context *celt = c->priv_data;
00100
00101 celt_decoder_destroy(celt->dec);
00102 celt_mode_destroy(celt->mode);
00103 return 0;
00104 }
00105
00106 static int libcelt_dec_decode(AVCodecContext *c, void *pcm, int *pcm_size,
00107 AVPacket *pkt)
00108 {
00109 struct libcelt_context *celt = c->priv_data;
00110 int err;
00111
00112 if (*pcm_size < celt->frame_bytes)
00113 return AVERROR(ENOBUFS);
00114 err = celt_decode(celt->dec, pkt->data, pkt->size, pcm, c->frame_size);
00115 if (err < 0)
00116 return ff_celt_error_to_averror(err);
00117 *pcm_size = celt->frame_bytes;
00118 if (celt->discard) {
00119 *pcm_size = celt->frame_bytes - celt->discard;
00120 memmove(pcm, (char *)pcm + celt->discard, *pcm_size);
00121 celt->discard = 0;
00122 }
00123 return pkt->size;
00124 }
00125
00126 AVCodec ff_libcelt_decoder = {
00127 .name = "libcelt",
00128 .type = AVMEDIA_TYPE_AUDIO,
00129 .id = CODEC_ID_CELT,
00130 .priv_data_size = sizeof(struct libcelt_context),
00131 .init = libcelt_dec_init,
00132 .close = libcelt_dec_close,
00133 .decode = libcelt_dec_decode,
00134 .capabilities = 0,
00135 .long_name = NULL_IF_CONFIG_SMALL("Xiph CELT/Opus decoder using libcelt"),
00136 };