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; 
}
Beispiel #2
0
/*****************************************************************************
 * 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;
}
Beispiel #3
0
static GstFlowReturn
gst_dtsdec_handle_frame (GstDtsDec * dts, guint8 * data,
    guint length, gint flags, gint sample_rate, gint bit_rate)
{
  gboolean need_renegotiation = FALSE;
  gint channels, num_blocks;
  GstBuffer *out;
  gint i, s, c, num_c;
  sample_t *samples;
  GstFlowReturn result = GST_FLOW_OK;

  /* go over stream properties, update caps/streaminfo if needed */
  if (dts->sample_rate != sample_rate) {
    need_renegotiation = TRUE;
    dts->sample_rate = sample_rate;
  }

  dts->stream_channels = flags;

  if (bit_rate != dts->bit_rate) {
    dts->bit_rate = bit_rate;
    gst_dtsdec_update_streaminfo (dts);
  }

  if (dts->request_channels == DTS_CHANNEL) {
    GstCaps *caps;

    caps = gst_pad_get_allowed_caps (dts->srcpad);
    if (caps && gst_caps_get_size (caps) > 0) {
      GstCaps *copy = gst_caps_copy_nth (caps, 0);
      GstStructure *structure = gst_caps_get_structure (copy, 0);
      gint channels;
      const int dts_channels[6] = {
        DTS_MONO,
        DTS_STEREO,
        DTS_STEREO | DTS_LFE,
        DTS_2F2R,
        DTS_2F2R | DTS_LFE,
        DTS_3F2R | DTS_LFE,
      };

      /* Prefer the original number of channels, but fixate to something 
       * preferred (first in the caps) downstream if possible.
       */
      gst_structure_fixate_field_nearest_int (structure, "channels",
          flags ? gst_dtsdec_channels (flags, NULL) : 6);
      gst_structure_get_int (structure, "channels", &channels);
      if (channels <= 6)
        dts->request_channels = dts_channels[channels - 1];
      else
        dts->request_channels = dts_channels[5];

      gst_caps_unref (copy);
    } else if (flags) {
      dts->request_channels = dts->stream_channels;
    } else {
      dts->request_channels = DTS_3F2R | DTS_LFE;
    }

    if (caps)
      gst_caps_unref (caps);
  }

  /* process */
  flags = dts->request_channels | DTS_ADJUST_LEVEL;
  dts->level = 1;

  if (dts_frame (dts->state, data, &flags, &dts->level, dts->bias)) {
    GST_WARNING ("dts_frame error");
    return GST_FLOW_OK;
  }

  channels = flags & (DTS_CHANNEL_MASK | DTS_LFE);

  if (dts->using_channels != channels) {
    need_renegotiation = TRUE;
    dts->using_channels = channels;
  }

  if (need_renegotiation == TRUE) {
    GST_DEBUG ("dtsdec: sample_rate:%d stream_chans:0x%x using_chans:0x%x",
        dts->sample_rate, dts->stream_channels, dts->using_channels);
    if (!gst_dtsdec_renegotiate (dts)) {
      GST_ELEMENT_ERROR (dts, CORE, NEGOTIATION, (NULL), (NULL));
      return GST_FLOW_ERROR;
    }
  }

  if (dts->dynamic_range_compression == FALSE) {
    dts_dynrng (dts->state, NULL, NULL);
  }

  /* handle decoded data, one block is 256 samples */
  num_blocks = dts_blocks_num (dts->state);
  for (i = 0; i < num_blocks; i++) {
    if (dts_block (dts->state)) {
      GST_WARNING ("dts_block error %d", i);
      continue;
    }

    samples = dts_samples (dts->state);
    num_c = gst_dtsdec_channels (dts->using_channels, NULL);

    result = gst_pad_alloc_buffer_and_set_caps (dts->srcpad, 0,
        (SAMPLE_WIDTH / 8) * 256 * num_c, GST_PAD_CAPS (dts->srcpad), &out);

    if (result != GST_FLOW_OK)
      break;

    GST_BUFFER_TIMESTAMP (out) = dts->current_ts;
    GST_BUFFER_DURATION (out) = GST_SECOND * 256 / dts->sample_rate;
    dts->current_ts += GST_BUFFER_DURATION (out);

    /* libdts returns buffers in 256-sample-blocks per channel,
     * we want interleaved. And we need to copy anyway... */
    data = GST_BUFFER_DATA (out);
    for (s = 0; s < 256; s++) {
      for (c = 0; c < num_c; c++) {
        *(sample_t *) data = samples[s + c * 256];
        data += (SAMPLE_WIDTH / 8);
      }
    }

    /* push on */
    result = gst_pad_push (dts->srcpad, out);

    if (result != GST_FLOW_OK)
      break;
  }

  return result;
}