static int parse_dca(bgav_audio_parser_t * parser) { int i; int frame_bytes; int frame_length; int flags; int sample_rate; int bit_rate; dca_t * priv = parser->priv; for(i = 0; i < parser->buf.size - DCA_HEADER_BYTES; i++) { frame_bytes = dts_syncinfo(priv->state, parser->buf.buffer + i, &flags, &sample_rate, &bit_rate, &frame_length); if(frame_bytes) { // fprintf(stderr, "Got frame bytes: %d, length: %d\n", // frame_bytes, frame_length); if(!parser->have_format) { parser->s->data.audio.format.samplerate = sample_rate; bgav_dca_flags_2_channel_setup(flags, &parser->s->data.audio.format); parser->have_format = 1; return PARSER_HAVE_FORMAT; } bgav_audio_parser_set_frame(parser, i, frame_bytes, frame_length); return PARSER_HAVE_FRAME; } } return PARSER_NEED_DATA; }
static GstFlowReturn gst_dtsdec_chain_raw (GstPad * pad, GstBuffer * buf) { GstDtsDec *dts; guint8 *data; gint size; gint length, flags, sample_rate, bit_rate, frame_length; GstFlowReturn result = GST_FLOW_OK; dts = GST_DTSDEC (GST_PAD_PARENT (pad)); if (dts->cache) { buf = gst_buffer_join (dts->cache, buf); dts->cache = NULL; } data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); length = 0; while (size >= 7) { length = dts_syncinfo (dts->state, data, &flags, &sample_rate, &bit_rate, &frame_length); if (length == 0) { /* shift window to re-find sync */ data++; size--; } else if (length <= size) { GST_DEBUG ("Sync: frame size %d", length); result = gst_dtsdec_handle_frame (dts, data, length, flags, sample_rate, bit_rate); if (result != GST_FLOW_OK) { size = 0; break; } size -= length; data += length; } else { GST_LOG ("Not enough data available (needed %d had %d)", length, size); break; } } /* keep cache */ if (length == 0) { GST_LOG ("No sync found"); } if (size > 0) { dts->cache = gst_buffer_create_sub (buf, GST_BUFFER_SIZE (buf) - size, size); } gst_buffer_unref (buf); return result; }
static int parse_frame_dca(bgav_audio_parser_t * parser, bgav_packet_t * p) { int flags, sample_rate, bit_rate, frame_length, frame_bytes; dca_t * priv = parser->priv; if(p->data_size < DCA_HEADER_BYTES) return 0; frame_bytes = dts_syncinfo(priv->state, p->data, &flags, &sample_rate, &bit_rate, &frame_length); if(frame_bytes <= 0) return 0; p->duration = frame_length; if(parser->s->codec_bitrate <= 0) parser->s->codec_bitrate = bit_rate; if(parser->s->data.audio.format.channel_locations[0] == GAVL_CHID_NONE) bgav_dca_flags_2_channel_setup(flags, &parser->s->data.audio.format); // fprintf(stderr, "Parse frame: %d %d\n", p->data_size, frame_bytes); return 1; }
/***************************************************************************** * DoWork: decode a DTS frame. *****************************************************************************/ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ) { filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys; sample_t i_sample_level = 1; int i_flags = p_sys->i_flags; int i_bytes_per_block = 256 * p_sys->i_nb_channels * sizeof(float); int i; /* * Do the actual decoding now. */ /* Needs to be called so the decoder knows which type of bitstream it is * dealing with. */ int i_sample_rate, i_bit_rate, i_frame_length; if( !dts_syncinfo( p_sys->p_libdts, p_in_buf->p_buffer, &i_flags, &i_sample_rate, &i_bit_rate, &i_frame_length ) ) { msg_Warn( p_filter, "libdts couldn't sync on frame" ); p_out_buf->i_nb_samples = p_out_buf->i_nb_bytes = 0; return; } i_flags = p_sys->i_flags; dts_frame( p_sys->p_libdts, p_in_buf->p_buffer, &i_flags, &i_sample_level, 0 ); if ( (i_flags & DTS_CHANNEL_MASK) != (p_sys->i_flags & DTS_CHANNEL_MASK) && !p_sys->b_dontwarn ) { msg_Warn( p_filter, "libdts couldn't do the requested downmix 0x%x->0x%x", p_sys->i_flags & DTS_CHANNEL_MASK, i_flags & DTS_CHANNEL_MASK ); p_sys->b_dontwarn = 1; } if( 0)//!p_sys->b_dynrng ) { dts_dynrng( p_sys->p_libdts, NULL, NULL ); } for ( i = 0; i < dts_blocks_num(p_sys->p_libdts); i++ ) { sample_t * p_samples; if( dts_block( p_sys->p_libdts ) ) { msg_Warn( p_filter, "dts_block failed for block %d", i ); break; } p_samples = dts_samples( p_sys->p_libdts ); if ( (p_sys->i_flags & DTS_CHANNEL_MASK) == DTS_MONO && (p_filter->output.i_physical_channels & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) ) { Duplicate( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block), p_samples ); } else if ( p_filter->output.i_original_channels & AOUT_CHAN_REVERSESTEREO ) { Exchange( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block), p_samples ); } else { /* Interleave the *$£%ù samples. */ Interleave( (float *)(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_nb_bytes = i_bytes_per_block * i; }
uint8_t ADM_AudiocodecDCA::run(uint8_t *inptr, uint32_t nbIn, float *outptr, uint32_t *nbOut) { uint32_t avail; uint32_t length,syncoff; int flags = 0, samprate = 0, bitrate = 0, frame_length; uint8_t chan = _wavHeader->channels; *nbOut=0; // Ready to decode while(nbIn) { if(nbIn<DTS_HEADER_SIZE) { if(nbIn) printf("[DTS]: no data to decode avail %u\n",nbIn); break; } //length = ADM_DCAGetInfo(ptr,nbIn, &samprate, &bitrate, &chan,&syncoff,&flags); length = dts_syncinfo (DTS_HANDLE, inptr, &flags, &samprate,&bitrate, &frame_length); if(!length) { printf("[DTS] dts_syncinfo failed\n"); ADM_assert(0); } if(length>nbIn) { // not enough data break; } if (ch_route.mode < 1) { CHANNEL_TYPE *p_ch_type = ch_route.input_type; switch (flags & DTS_CHANNEL_MASK) { case DTS_MONO: *(p_ch_type++) = CH_MONO; break; case DTS_STEREO: *(p_ch_type++) = CH_FRONT_LEFT; *(p_ch_type++) = CH_FRONT_RIGHT; break; case DTS_3F2R: *(p_ch_type++) = CH_FRONT_CENTER; *(p_ch_type++) = CH_FRONT_LEFT; *(p_ch_type++) = CH_FRONT_RIGHT; *(p_ch_type++) = CH_REAR_LEFT; *(p_ch_type++) = CH_REAR_RIGHT; break; default: ADM_assert(0); } if (flags & DTS_LFE) { *(p_ch_type++) = CH_LFE; } } sample_t level = 1, bias = 0; flags &=DTS_CHANNEL_MASK; flags |= DTS_ADJUST_LEVEL; if (dts_frame(DTS_HANDLE, inptr, &flags, &level, bias)) { printf("\n DTS_frame failed!"); inptr+=length; nbIn-=length; outptr+=256*chan; *nbOut+=256*chan; break; }; inptr+=length; nbIn-=length; // Each block is 256 samples *nbOut += 256 * chan * dts_blocks_num(DTS_HANDLE); float *cur; for (int i = 0; i < dts_blocks_num(DTS_HANDLE); i++) { if (dts_block (DTS_HANDLE)) { printf("\n[DTS] dts_block failed on block %d/%d\n",i,dts_blocks_num (DTS_HANDLE)); // in that case we silent out the chunk memset(outptr, 0, 256 * chan * sizeof(float)); } else { float *cur; for (int k = 0; k < chan; k++) { sample_t *sample=(sample_t *)dts_samples(DTS_HANDLE); sample += 256 * k; cur = outptr + k; for (int j = 0; j < 256; j++) { *cur = *sample++; cur+=chan; } } } outptr += chan * 256; } } return 1; }