00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avcodec.h"
00028 #include <a52dec/a52.h>
00029
00030 #ifdef CONFIG_LIBA52BIN
00031 #include <dlfcn.h>
00032 static const char* liba52name = "liba52.so.0";
00033 #endif
00034
00039 typedef struct AC3DecodeState {
00040 uint8_t inbuf[4096];
00041 uint8_t *inbuf_ptr;
00042 int frame_size;
00043 int flags;
00044 int channels;
00045 a52_state_t* state;
00046 sample_t* samples;
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 void* handle;
00060 a52_state_t* (*a52_init)(uint32_t mm_accel);
00061 sample_t* (*a52_samples)(a52_state_t * state);
00062 int (*a52_syncinfo)(uint8_t * buf, int * flags,
00063 int * sample_rate, int * bit_rate);
00064 int (*a52_frame)(a52_state_t * state, uint8_t * buf, int * flags,
00065 sample_t * level, sample_t bias);
00066 void (*a52_dynrng)(a52_state_t * state,
00067 sample_t (* call) (sample_t, void *), void * data);
00068 int (*a52_block)(a52_state_t * state);
00069 void (*a52_free)(a52_state_t * state);
00070
00071 } AC3DecodeState;
00072
00073 #ifdef CONFIG_LIBA52BIN
00074 static void* dlsymm(void* handle, const char* symbol)
00075 {
00076 void* f = dlsym(handle, symbol);
00077 if (!f)
00078 av_log( NULL, AV_LOG_ERROR, "A52 Decoder - function '%s' can't be resolved\n", symbol);
00079 return f;
00080 }
00081 #endif
00082
00083 static int a52_decode_init(AVCodecContext *avctx)
00084 {
00085 AC3DecodeState *s = avctx->priv_data;
00086
00087 #ifdef CONFIG_LIBA52BIN
00088 s->handle = dlopen(liba52name, RTLD_LAZY);
00089 if (!s->handle)
00090 {
00091 av_log( avctx, AV_LOG_ERROR, "A52 library %s could not be opened! \n%s\n", liba52name, dlerror());
00092 return -1;
00093 }
00094 s->a52_init = (a52_state_t* (*)(uint32_t)) dlsymm(s->handle, "a52_init");
00095 s->a52_samples = (sample_t* (*)(a52_state_t*)) dlsymm(s->handle, "a52_samples");
00096 s->a52_syncinfo = (int (*)(uint8_t*, int*, int*, int*)) dlsymm(s->handle, "a52_syncinfo");
00097 s->a52_frame = (int (*)(a52_state_t*, uint8_t*, int*, sample_t*, sample_t)) dlsymm(s->handle, "a52_frame");
00098 s->a52_block = (int (*)(a52_state_t*)) dlsymm(s->handle, "a52_block");
00099 s->a52_free = (void (*)(a52_state_t*)) dlsymm(s->handle, "a52_free");
00100 if (!s->a52_init || !s->a52_samples || !s->a52_syncinfo
00101 || !s->a52_frame || !s->a52_block || !s->a52_free)
00102 {
00103 dlclose(s->handle);
00104 return -1;
00105 }
00106 #else
00107 s->handle = 0;
00108 s->a52_init = a52_init;
00109 s->a52_samples = a52_samples;
00110 s->a52_syncinfo = a52_syncinfo;
00111 s->a52_frame = a52_frame;
00112 s->a52_block = a52_block;
00113 s->a52_free = a52_free;
00114 #endif
00115 s->state = s->a52_init(0);
00116 s->samples = s->a52_samples(s->state);
00117 s->inbuf_ptr = s->inbuf;
00118 s->frame_size = 0;
00119
00120
00121 if (avctx->channels > 0 && avctx->request_channels > 0 &&
00122 avctx->request_channels < avctx->channels &&
00123 avctx->request_channels <= 2) {
00124 avctx->channels = avctx->request_channels;
00125 }
00126
00127 return 0;
00128 }
00129
00130
00131 static inline void float_to_int (float * _f, int16_t * s16, int nchannels)
00132 {
00133 int i, j, c;
00134 int32_t * f = (int32_t *) _f;
00135
00136 j = 0;
00137 nchannels *= 256;
00138 for (i = 0; i < 256; i++) {
00139 for (c = 0; c < nchannels; c += 256)
00140 s16[j++] = av_clip_int16(f[i + c] - 0x43c00000);
00141 }
00142 }
00143
00144
00145
00146 #define HEADER_SIZE 7
00147
00148 static int a52_decode_frame(AVCodecContext *avctx,
00149 void *data, int *data_size,
00150 uint8_t *buf, int buf_size)
00151 {
00152 AC3DecodeState *s = avctx->priv_data;
00153 uint8_t *buf_ptr;
00154 int flags, i, len;
00155 int sample_rate, bit_rate;
00156 short *out_samples = data;
00157 float level;
00158 static const int ac3_channels[8] = {
00159 2, 1, 2, 3, 3, 4, 4, 5
00160 };
00161
00162 *data_size= 0;
00163
00164 buf_ptr = buf;
00165 while (buf_size > 0) {
00166 len = s->inbuf_ptr - s->inbuf;
00167 if (s->frame_size == 0) {
00168
00169 len = HEADER_SIZE - len;
00170 if (len > buf_size)
00171 len = buf_size;
00172 memcpy(s->inbuf_ptr, buf_ptr, len);
00173 buf_ptr += len;
00174 s->inbuf_ptr += len;
00175 buf_size -= len;
00176 if ((s->inbuf_ptr - s->inbuf) == HEADER_SIZE) {
00177 len = s->a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate);
00178 if (len == 0) {
00179
00180 memcpy(s->inbuf, s->inbuf + 1, HEADER_SIZE - 1);
00181 s->inbuf_ptr--;
00182 } else {
00183 s->frame_size = len;
00184
00185 avctx->sample_rate = sample_rate;
00186 s->channels = ac3_channels[s->flags & 7];
00187 if (s->flags & A52_LFE)
00188 s->channels++;
00189 if (avctx->request_channels > 0 &&
00190 avctx->request_channels <= 2 &&
00191 avctx->request_channels < s->channels) {
00192 avctx->channels = avctx->request_channels;
00193 } else {
00194 avctx->channels = s->channels;
00195 }
00196 avctx->bit_rate = bit_rate;
00197 }
00198 }
00199 } else if (len < s->frame_size) {
00200 len = s->frame_size - len;
00201 if (len > buf_size)
00202 len = buf_size;
00203
00204 memcpy(s->inbuf_ptr, buf_ptr, len);
00205 buf_ptr += len;
00206 s->inbuf_ptr += len;
00207 buf_size -= len;
00208 } else {
00209 flags = s->flags;
00210 if (avctx->channels == 1)
00211 flags = A52_MONO;
00212 else if (avctx->channels == 2)
00213 flags = A52_STEREO;
00214 else
00215 flags |= A52_ADJUST_LEVEL;
00216 level = 1;
00217 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) {
00218 fail:
00219 av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
00220 s->inbuf_ptr = s->inbuf;
00221 s->frame_size = 0;
00222 continue;
00223 }
00224 for (i = 0; i < 6; i++) {
00225 if (s->a52_block(s->state))
00226 goto fail;
00227 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);
00228 }
00229 s->inbuf_ptr = s->inbuf;
00230 s->frame_size = 0;
00231 *data_size = 6 * avctx->channels * 256 * sizeof(int16_t);
00232 break;
00233 }
00234 }
00235 return buf_ptr - buf;
00236 }
00237
00238 static int a52_decode_end(AVCodecContext *avctx)
00239 {
00240 AC3DecodeState *s = avctx->priv_data;
00241 s->a52_free(s->state);
00242 #ifdef CONFIG_LIBA52BIN
00243 dlclose(s->handle);
00244 #endif
00245 return 0;
00246 }
00247
00248 AVCodec liba52_decoder = {
00249 "liba52",
00250 CODEC_TYPE_AUDIO,
00251 CODEC_ID_AC3,
00252 sizeof(AC3DecodeState),
00253 a52_decode_init,
00254 NULL,
00255 a52_decode_end,
00256 a52_decode_frame,
00257 };