ADM_AudiocodecAC3::ADM_AudiocodecAC3( uint32_t fourcc, WAVHeader *info,uint32_t extraLength,uint8_t *extraData) : ADM_Audiocodec(fourcc) { int flags=0; ADM_assert(fourcc==WAV_AC3); ac3_handle=NULL; ac3_sample=NULL; #ifdef ADM_CPU_X86 #define CHK(x,y) if(CpuCaps::has##x()) flags|=MM_ACCEL_X86_##y; CHK(MMX,MMX); CHK(3DNOW,3DNOW); CHK(MMXEXT,MMXEXT); #endif ac3_handle=(void *)a52_init(flags); if(!ac3_handle) { printf("Cannot init a52\n"); ADM_assert(0); } ac3_sample=(sample_t *)a52_samples(AC3_HANDLE); if(!ac3_sample) { printf("Cannot init a52 sample\n"); ADM_assert(0); } _downmix=0; _wavHeader = info; ADM_assert(_wavHeader); }
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) { sample_t level=a52_level, bias=384; int flags=a52_flags|A52_ADJUST_LEVEL; int i,len=-1; if (sh_audio->sample_format == AF_FORMAT_FLOAT_NE) bias = 0; if(!sh_audio->a_in_buffer_len) if(a52_fillbuff(sh_audio)<0) return len; /* EOF */ sh_audio->a_in_buffer_len=0; if (a52_frame (a52_state, sh_audio->a_in_buffer, &flags, &level, bias)){ mp_msg(MSGT_DECAUDIO,MSGL_WARN,"a52: error decoding frame\n"); return len; } /* handle dynrng */ if (a52_drc_action != DRC_NO_ACTION) { if (a52_drc_action == DRC_NO_COMPRESSION) a52_dynrng(a52_state, NULL, NULL); else a52_dynrng(a52_state, dynrng_call, NULL); } len=0; for (i = 0; i < 6; i++) { if (a52_block (a52_state)){ mp_msg(MSGT_DECAUDIO,MSGL_WARN,"a52: error at resampling\n"); break; } len+=2*a52_resample(a52_samples(a52_state),(int16_t *)&buf[len]); } assert(len <= maxlen); return len; }
static GF_Err AC3_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) { A52CTX(); if (ctx->ES_ID && ctx->ES_ID!=esd->ESID) return GF_NOT_SUPPORTED; GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[A52] Attaching stream %d\n", esd->ESID)); if (ctx->codec) a52_free(ctx->codec); ctx->codec = a52_init(MM_ACCEL_DJBFFT); if (!ctx->codec) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[A52] Error initializing decoder\n")); return GF_IO_ERR; } ctx->samples = a52_samples(ctx->codec); if (!ctx->samples) { a52_free(ctx->codec); GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[A52] Error initializing decoder\n")); return GF_IO_ERR; } ctx->num_channels = 0; ctx->sample_rate = 0; ctx->out_size = 0; ctx->num_samples = 1536; ctx->ES_ID = esd->ESID; return GF_OK; }
static int a52_decode_frame(unsigned char *buf, int maxlen, struct frame_fmt *fmt) { sample_t level = 1, bias = 384; int flags; int i, len = -1; if (!a52_buffer.a_in_buffer_len) if (a52_fillbuff(&a52_buffer) < 0) return len; a52_buffer.a_in_buffer_len = 0; flags = a52_flags | A52_ADJUST_LEVEL; level *= gain; if (a52_frame(a52_state, a52_buffer.a_in_buffer, &flags, &level, bias)) { printf("a52_decode_frame a52: error decoding frame\n"); return len; } len = 0; for (i = 0; i < 6; i++) { if (a52_block(a52_state)) { printf("a52: error at resampling\n"); break; } len += 2 * a52_resample(a52_samples(a52_state), (int16_t *) & buf[len]); } assert(len <= maxlen); return len; }
static GstStateChangeReturn gst_a52dec_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstA52Dec *a52dec = GST_A52DEC (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY:{ GstA52DecClass *klass; klass = GST_A52DEC_CLASS (G_OBJECT_GET_CLASS (a52dec)); a52dec->state = a52_init (klass->a52_cpuflags); break; } case GST_STATE_CHANGE_READY_TO_PAUSED: a52dec->samples = a52_samples (a52dec->state); a52dec->bit_rate = -1; a52dec->sample_rate = -1; a52dec->stream_channels = A52_CHANNEL; a52dec->using_channels = A52_CHANNEL; a52dec->level = 1; a52dec->bias = 0; a52dec->time = 0; a52dec->sent_segment = FALSE; a52dec->flag_update = TRUE; gst_segment_init (&a52dec->segment, GST_FORMAT_UNDEFINED); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: a52dec->samples = NULL; if (a52dec->cache) { gst_buffer_unref (a52dec->cache); a52dec->cache = NULL; } clear_queued (a52dec); break; case GST_STATE_CHANGE_READY_TO_NULL: a52_free (a52dec->state); a52dec->state = NULL; break; default: break; } return ret; }
mpeg3_ac3_t* mpeg3_new_ac3() { mpeg3_ac3_t *result = calloc(1, sizeof(mpeg3_ac3_t)); result->stream = mpeg3bits_new_stream(0, 0); #ifdef A52_INIT_NEEDS_ARG result->state = a52_init(0); #else result->state = a52_init(); #endif result->output = a52_samples(result->state); return result; }
static gboolean gst_a52dec_start (GstAudioDecoder * dec) { GstA52Dec *a52dec = GST_A52DEC (dec); GstA52DecClass *klass; GST_DEBUG_OBJECT (dec, "start"); klass = GST_A52DEC_CLASS (G_OBJECT_GET_CLASS (a52dec)); #if defined(A52_ACCEL_DETECT) a52dec->state = a52_init (); /* This line is just to avoid being accused of not using klass */ a52_accel (klass->a52_cpuflags & A52_ACCEL_DETECT); #else a52dec->state = a52_init (klass->a52_cpuflags); #endif if (!a52dec->state) { GST_ELEMENT_ERROR (GST_ELEMENT (a52dec), LIBRARY, INIT, (NULL), ("failed to initialize a52 state")); return FALSE; } a52dec->samples = a52_samples (a52dec->state); a52dec->bit_rate = -1; a52dec->sample_rate = -1; a52dec->stream_channels = A52_CHANNEL; a52dec->using_channels = A52_CHANNEL; a52dec->level = 1; a52dec->bias = 0; a52dec->flag_update = TRUE; /* call upon legacy upstream byte support (e.g. seeking) */ gst_audio_decoder_set_estimate_rate (dec, TRUE); return TRUE; }
/***************************************************************************** * DoWork: decode an ATSC A/52 frame. *****************************************************************************/ static void DoWork( filter_t * p_filter, aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ) { filter_sys_t *p_sys = p_filter->p_sys; #ifdef LIBA52_FIXED sample_t i_sample_level = (1 << 24); #else sample_t i_sample_level = 1; #endif int i_flags = p_sys->i_flags; int i_bytes_per_block = 256 * p_sys->i_nb_channels * sizeof(sample_t); int i; /* Do the actual decoding now. */ a52_frame( p_sys->p_liba52, p_in_buf->p_buffer, &i_flags, &i_sample_level, 0 ); if ( (i_flags & A52_CHANNEL_MASK) != (p_sys->i_flags & A52_CHANNEL_MASK) && !p_sys->b_dontwarn ) { msg_Warn( p_filter, "liba52 couldn't do the requested downmix 0x%x->0x%x", p_sys->i_flags & A52_CHANNEL_MASK, i_flags & A52_CHANNEL_MASK ); p_sys->b_dontwarn = 1; } if( !p_sys->b_dynrng ) { a52_dynrng( p_sys->p_liba52, NULL, NULL ); } for ( i = 0; i < 6; i++ ) { sample_t * p_samples; if( a52_block( p_sys->p_liba52 ) ) { msg_Warn( p_filter, "a52_block failed for block %d", i ); } p_samples = a52_samples( p_sys->p_liba52 ); if ( ((p_sys->i_flags & A52_CHANNEL_MASK) == A52_CHANNEL1 || (p_sys->i_flags & A52_CHANNEL_MASK) == A52_CHANNEL2 || (p_sys->i_flags & A52_CHANNEL_MASK) == A52_MONO) && (p_filter->fmt_out.audio.i_physical_channels & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) ) { Duplicate( (sample_t *)(p_out_buf->p_buffer + i * i_bytes_per_block), p_samples ); } else if ( p_filter->fmt_out.audio.i_original_channels & AOUT_CHAN_REVERSESTEREO ) { Exchange( (sample_t *)(p_out_buf->p_buffer + i * i_bytes_per_block), p_samples ); } else { /* Interleave the *$£%ù samples. */ Interleave( (sample_t *)(p_out_buf->p_buffer + i * i_bytes_per_block), p_samples, p_sys->i_nb_channels, p_sys->pi_chan_table); } } p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; p_out_buf->i_buffer = i_bytes_per_block * 6; }
static void a52_decode_data(uint8_t *start, uint8_t *end) { static uint8_t *bufptr = buf; static uint8_t *bufpos = buf + 7; /* * sample_rate and flags are static because this routine could * exit between the a52_syncinfo() and the ao_setup(), and we want * to have the same values when we get back ! */ static int sample_rate; static int flags; int bit_rate; int len; while (1) { len = end - start; if (!len) break; if (len > bufpos - bufptr) len = bufpos - bufptr; memcpy(bufptr, start, len); bufptr += len; start += len; if (bufptr == bufpos) { if (bufpos == buf + 7) { int length; length = a52_syncinfo(buf, &flags, &sample_rate, &bit_rate); if (!length) { //DEBUGF("skip\n"); for (bufptr = buf; bufptr < buf + 6; bufptr++) bufptr[0] = bufptr[1]; continue; } bufpos = buf + length; } else { /* Unity gain is 1 << 26, and we want to end up on 28 bits of precision instead of the default 30. */ level_t level = 1 << 24; sample_t bias = 0; int i; /* This is the configuration for the downmixing: */ flags = A52_STEREO | A52_ADJUST_LEVEL; if (a52_frame(state, buf, &flags, &level, bias)) goto error; a52_dynrng(state, NULL, NULL); frequency = sample_rate; /* An A52 frame consists of 6 blocks of 256 samples So we decode and output them one block at a time */ for (i = 0; i < 6; i++) { if (a52_block(state)) goto error; output_audio(a52_samples(state)); samplesdone += 256; } ci->set_elapsed(samplesdone/(frequency/1000)); bufptr = buf; bufpos = buf + 7; continue; error: //logf("Error decoding A52 stream\n"); bufptr = buf; bufpos = buf + 7; } } } }
HRESULT TaudioCodecLiba52::decode(TbyteBuffer &src) { unsigned char *p=src.size() ? &src[0] : NULL; unsigned char *base=p; unsigned char *end=p+src.size(); while (end-p>7) { int size=0,flags,sample_rate,bit_rate; if ((size=a52_syncinfo(p,&flags,&sample_rate,&bit_rate))>0) { bool enoughData=p+size<=end; if (enoughData) { if (codecId==CODEC_ID_SPDIF_AC3) { bpssum+=(lastbps=bit_rate/1000); numframes++; HRESULT hr=deciA->deliverSampleSPDIF(p,size,bit_rate,sample_rate,true); if (hr!=S_OK) { return hr; } } else { flags|=A52_ADJUST_LEVEL; liba52::sample_t level=1,bias=0; if (a52_frame(state,p,&flags,&level,bias)==0) { bpssum+=(lastbps=bit_rate/1000); numframes++; // Dynamic range compression if (deci->getParam2(IDFF_audio_decoder_DRC)) { liba52::sample_t drcLevel = ((liba52::sample_t)deci->getParam2(IDFF_audio_decoder_DRC_Level) / 100); a52_dynrngsetlevel(state, drcLevel); } else { a52_dynrngsetlevel(state, 0.0); } int scmapidx=std::min(flags&A52_CHANNEL_MASK,int(countof(scmaps)/2)); const Tscmap &scmap=scmaps[scmapidx+((flags&A52_LFE)?(countof(scmaps)/2):0)]; float *dst0,*dst; dst0=dst=(float*)getDst(6*256*scmap.nchannels*sizeof(float)); int i=0; for(; i<6 && a52_block(state)==0; i++) { liba52::sample_t* samples=a52_samples(state); for (int j=0; j<256; j++,samples++) for (int ch=0; ch<scmap.nchannels; ch++) { *dst++=float(*(samples+256*scmap.ch[ch])/level); } } if (i==6) { fmt.sf=TsampleFormat::SF_FLOAT32; fmt.freq=sample_rate; fmt.setChannels(scmap.nchannels,scmap.channelMask); HRESULT hr=sinkA->deliverDecodedSample(dst0,6*256,fmt); if (hr!=S_OK) { return hr; } } } } p+=size; } memmove(base,p,end-p); end=base+(end-p); p=base; if (!enoughData) { break; } } else { p++; } } src.resize(end-p); return S_OK; }