ADM_faad::~ADM_faad()
{
	if(_instance)
		faacDecClose(_instance);
	_instance=NULL;
	printf("Faad decoder closed\n");
}
Пример #2
0
void DeleteFAADDec(GF_BaseDecoder *ifcg)
{
	FAADCTX();
	if (ctx->codec) faacDecClose(ctx->codec);
	gf_free(ctx);
	gf_free(ifcg);
}
Пример #3
0
void stop()
{
    killPlayThread=1;

    if (play_thread_handle != INVALID_HANDLE_VALUE)
    {
        if (WaitForSingleObject(play_thread_handle, INFINITE) == WAIT_TIMEOUT)
            TerminateThread(play_thread_handle,0);
        CloseHandle(play_thread_handle);
        play_thread_handle = INVALID_HANDLE_VALUE;
    }

    faacDecClose(hDecoder);
    close_filestream(infile);
    mod.outMod->Close();
    mod.SAVSADeInit();

    if (memmap_buffer) LocalFree(memmap_buffer);
	if(seek_table)
	{
		free(seek_table);
		seek_table = NULL;
		seek_table_length = 0;
	}
}
Пример #4
0
/// Ïú»Ù±àÂëÆ÷
void CAacDecoder::Destroy(void)
{
    if(NULL != m_hHandleDecoder)
    {
        faacDecClose(m_hHandleDecoder);
        m_hHandleDecoder = NULL;
    }
}
Пример #5
0
void faad_decoder::close()
{
    if (faad_handle)
    {
        faacDecClose(*faad_handle);
        faad_handle = boost::none;
    }
}
Пример #6
0
/*****************************************************************************
 * Close:
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t *)p_this;
    decoder_sys_t *p_sys = p_dec->p_sys;

    faacDecClose( p_sys->hfaad );
    free( p_sys->p_buffer );
    free( p_sys );
}
Пример #7
0
HRESULT CCoreAACDecoder::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)
{
	HRESULT hr = CTransformFilter::CompleteConnect(direction, pReceivePin);
	
	if(direction == PINDIR_INPUT)
	{
		if(m_decHandle)
		{
			faacDecClose(m_decHandle);
			m_decHandle = NULL;
		}
		m_decHandle = faacDecOpen();

        faacDecConfigurationPtr config;		
        config = faacDecGetCurrentConfiguration(m_decHandle);
		config->downMatrix = m_DownMatrix;
        faacDecSetConfiguration(m_decHandle, config);

		// Initialize the decoder
		unsigned long SamplesPerSec = 0;
		unsigned char Channels = 0;
		if(faacDecInit2(m_decHandle, m_decoderSpecific, m_decoderSpecificLen,
			&SamplesPerSec, &Channels) < 0)
		{
			return E_FAIL;
		}
		
		if(m_DownMatrix)
		{
			Channels = 2; // TODO : check with mono
		}

		mp4AudioSpecificConfig info;
		AudioSpecificConfig(m_decoderSpecific,m_decoderSpecificLen,&info);
		
		wsprintf(m_ProfileName,"%s%s",
			ObjectTypesNameTable[info.objectTypeIndex],
#if 0
			info.sbr_present_flag ?
#else
			false ?
#endif
			"+SBR" :
			""
			);

		m_Channels = Channels;
		m_SamplesPerSec = SamplesPerSec;
		m_BitsPerSample = 16; // we always decode to the default 16 bits (we could add 24,32,float)
		
		m_brCalcFrames = 0;
		m_brBytesConsumed = 0;
		m_DecodedFrames = 0;
	}

	return hr;
}
Пример #8
0
AacPcm::~AacPcm()
{
	if(hDecoder)
		faacDecClose(hDecoder);
	if(buffer)
		delete buffer;
	if(bufout)
		delete bufout;
//	fclose(fil);
}
Пример #9
0
AacPcm::~AacPcm()
{
	if(mp4File)
		MP4Close(mp4File);
	if(aacFile)
		fclose(aacFile);
	if(hDecoder)
		faacDecClose(hDecoder);
	FREE_ARRAY(buffer);
	FREE_ARRAY(seek_table);
}
Пример #10
0
static GF_Err FAAD_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID)
{
	FAADCTX();
	if (ES_ID != ctx->ES_ID) return GF_BAD_PARAM;
	if (ctx->codec) faacDecClose(ctx->codec);
	ctx->codec = NULL;
	ctx->ES_ID = 0;
	ctx->sample_rate = ctx->out_size = ctx->num_samples = 0;
	ctx->num_channels = 0;
	return GF_OK;
}
Пример #11
0
static void
xmms_faad_destroy (xmms_xform_t *xform)
{
	xmms_faad_data_t *data;

	g_return_if_fail (xform);

	data = xmms_xform_private_data_get (xform);
	g_return_if_fail (data);

	faacDecClose (data->decoder);
	g_string_free (data->outbuf, TRUE);
	g_free (data);
}
Пример #12
0
void aac_close (codec_data_t *ptr)
{
  if (ptr == NULL) {
    return;
  }
  aac_codec_t *aac = (aac_codec_t *)ptr;
  faacDecClose(aac->m_info);
  aac->m_info = NULL;

#if DUMP_OUTPUT_TO_FILE
  fclose(aac->m_outfile);
#endif
  free(aac);
}
Пример #13
0
CCoreAACDecoder::~CCoreAACDecoder()
{
	NOTE("CCoreAACDecoder::~CCoreAACDecoder");

	SaveInt("DownMatrix",m_DownMatrix);

	if(m_decHandle)
	{
		faacDecClose(m_decHandle);
		m_decHandle = NULL;
	}
	if(m_decoderSpecific)
	{
		delete m_decoderSpecific;
		m_decoderSpecific = NULL;
	}
}
Пример #14
0
void aac_close (codec_data_t *ptr)
{
  if (ptr == NULL) {
    return;
  }
  aac_codec_t *aac = (aac_codec_t *)ptr;
  faacDecClose(aac->m_info);
  aac->m_info = NULL;

  CHECK_AND_FREE(aac->m_temp_buff);
  CHECK_AND_FREE(aac->m_buffer);
  if (aac->m_ifile != NULL) {
    fclose(aac->m_ifile);
    aac->m_ifile = NULL;
  }
#if DUMP_OUTPUT_TO_FILE
  fclose(aac->m_outfile);
#endif
  free(aac);
}
Пример #15
0
/// ´´½¨±àÂëÆ÷
BOOL CAacDecoder::Create(void)
{
    if(NULL != m_hHandleDecoder)
        return FALSE;

    m_hHandleDecoder = faacDecOpen();

    faacDecConfigurationPtr pConfig = NULL;
    pConfig = faacDecGetCurrentConfiguration(m_hHandleDecoder);
    if(NULL != pConfig)
    {
        int nOutputFormat = FAAD_FMT_16BIT;
        switch(m_enSample)
        {
        case ENUM_SAMPLE_8BIT:
            nOutputFormat = 0;
            break;
        case ENUM_SAMPLE_16BIT:
            nOutputFormat = FAAD_FMT_16BIT;
            break;
        default:
            nOutputFormat = FAAD_FMT_16BIT;
            break;
        }

        pConfig->defObjectType = LOW;
        pConfig->defSampleRate = m_enFrequency;
        pConfig->outputFormat = nOutputFormat;
        pConfig->dontUpSampleImplicitSBR = 1;

        if(0 == faacDecSetConfiguration(m_hHandleDecoder, pConfig))
        {
            faacDecClose(m_hHandleDecoder);
            m_hHandleDecoder = NULL;
        }
    }
    //faacDecInitDRM(&m_hHandleDecoder, 44100, 2);

    return (NULL != m_hHandleDecoder);
}
Пример #16
0
static GF_Err FAAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd)
{
#ifndef GPAC_DISABLE_AV_PARSERS
	GF_Err e;
	GF_M4ADecSpecInfo a_cfg;
#endif
	FAADCTX();

	if (ctx->ES_ID && ctx->ES_ID!=esd->ESID) return GF_NOT_SUPPORTED;
	if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->dataLength) return GF_NON_COMPLIANT_BITSTREAM;

	if (!ctx->esd) {
		ctx->esd = esd;
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] Attaching stream %d\n", esd->ESID));
	}

	if (ctx->codec) faacDecClose(ctx->codec);
	ctx->codec = faacDecOpen();
	if (!ctx->codec) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error initializing decoder\n"));
		return GF_IO_ERR;
	}

#ifndef GPAC_DISABLE_AV_PARSERS
	e = gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg);
	if (e) return e;
#endif
	if (faacDecInit2(ctx->codec, (unsigned char *)esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, (unsigned long*)&ctx->sample_rate, (u8*)&ctx->num_channels) < 0)
	{
#ifndef GPAC_DISABLE_AV_PARSERS
		s8 res;
		char *dsi, *s_base_object_type;
		u32 dsi_len;
		switch (a_cfg.base_object_type) {
		case GF_M4A_AAC_MAIN:
			s_base_object_type = gf_stringizer(GF_M4A_AAC_MAIN);
			goto base_object_type_error;
		case GF_M4A_AAC_LC:
			s_base_object_type = gf_stringizer(GF_M4A_AAC_LC);
			goto base_object_type_error;
		case GF_M4A_AAC_SSR:
			s_base_object_type = gf_stringizer(GF_M4A_AAC_SSR);
			goto base_object_type_error;
		case GF_M4A_AAC_LTP:
			s_base_object_type = gf_stringizer(GF_M4A_AAC_LTP);
			goto base_object_type_error;
		case GF_M4A_AAC_SBR:
			s_base_object_type = gf_stringizer(GF_M4A_AAC_SBR);
			goto base_object_type_error;
		case GF_M4A_AAC_PS:
			s_base_object_type = gf_stringizer(GF_M4A_AAC_PS);
base_object_type_error: /*error case*/
			GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[FAAD] Error: unsupported %s format for stream %d - defaulting to AAC LC\n", s_base_object_type, esd->ESID));
		default:
			break;
		}
		a_cfg.base_object_type = GF_M4A_AAC_LC;
		a_cfg.has_sbr = GF_FALSE;
		a_cfg.nb_chan = a_cfg.nb_chan > 2 ? 1 : a_cfg.nb_chan;

		gf_m4a_write_config(&a_cfg, &dsi, &dsi_len);
		res = faacDecInit2(ctx->codec, (unsigned char *) dsi, dsi_len, (unsigned long *) &ctx->sample_rate, (u8 *) &ctx->num_channels);
		gf_free(dsi);
		if (res < 0)
#endif
		{
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error when initializing AAC decoder for stream %d\n", esd->ESID));
			return GF_NOT_SUPPORTED;
		}
	}

#ifndef GPAC_DISABLE_AV_PARSERS
	ctx->is_sbr = a_cfg.has_sbr;
#endif
	ctx->num_samples = 1024;
	ctx->out_size = 2 * ctx->num_samples * ctx->num_channels;
	ctx->ES_ID = esd->ESID;
	ctx->signal_mc = ctx->num_channels>2 ? GF_TRUE : GF_FALSE;
	return GF_OK;
}
Пример #17
0
static void *mp4Decode(void *args)
{
  MP4FileHandle mp4file;

  pthread_mutex_lock(&mutex);
  seekPosition = -1;
  bPlaying = TRUE;
  if(!(mp4file = MP4Read(args, 0))){
    mp4cfg.file_type = FILE_AAC;
    MP4Close(mp4file);
  }else{
    mp4cfg.file_type = FILE_MP4;
  }

  if(mp4cfg.file_type == FILE_MP4){
    // We are reading a MP4 file
    gint		mp4track;

    if((mp4track = getAACTrack(mp4file)) < 0){
      //TODO: check here for others Audio format.....
      g_print("Unsupported Audio track type\n");
      g_free(args);
      MP4Close(mp4file);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }else{
      faacDecHandle	decoder;
      unsigned char	*buffer	= NULL;
      guint		bufferSize = 0;
      gulong		samplerate;
      guchar		channels;
      guint		avgBitrate;
      MP4Duration	duration;
      gulong		msDuration;
      MP4SampleId	numSamples;
      MP4SampleId	sampleID = 1;

      decoder = faacDecOpen();
      MP4GetTrackESConfiguration(mp4file, mp4track, &buffer, &bufferSize);
      if(!buffer){
	g_free(args);
	faacDecClose(decoder);
	MP4Close(mp4file);
	bPlaying = FALSE;
	pthread_mutex_unlock(&mutex);
	pthread_exit(NULL);
      }
      if(faacDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0){
	g_free(args);
	faacDecClose(decoder);
	MP4Close(mp4file);
	bPlaying = FALSE;
	pthread_mutex_unlock(&mutex);
	pthread_exit(NULL);
      }
      g_free(buffer);
      if(channels == 0){
	g_print("Number of Channels not supported\n");
	g_free(args);
	faacDecClose(decoder);
	MP4Close(mp4file);
	bPlaying = FALSE;
	pthread_mutex_unlock(&mutex);
	pthread_exit(NULL);
      }
      duration = MP4GetTrackDuration(mp4file, mp4track);
      msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track, duration,
					       MP4_MSECS_TIME_SCALE);
      numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track);
      mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels);
      mp4_ip.output->flush(0);
      mp4_ip.set_info(args, msDuration, -1, samplerate/1000, channels);
      g_print("MP4 - %d channels @ %d Hz\n", channels, samplerate);

      while(bPlaying){
	void*			sampleBuffer;
	faacDecFrameInfo	frameInfo;    
	gint			rc;

	if(seekPosition!=-1){
	  duration = MP4ConvertToTrackDuration(mp4file,
					       mp4track,
					       seekPosition*1000,
					       MP4_MSECS_TIME_SCALE);
	  sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0);
	  mp4_ip.output->flush(seekPosition*1000);
	  seekPosition = -1;
	}
	buffer=NULL;
	bufferSize=0;
	if(sampleID > numSamples){
	  mp4_ip.output->close_audio();
	  g_free(args);
	  faacDecClose(decoder);
	  MP4Close(mp4file);
	  bPlaying = FALSE;
	  pthread_mutex_unlock(&mutex);
	  pthread_exit(NULL);
	}
	rc = MP4ReadSample(mp4file, mp4track, sampleID++, &buffer, &bufferSize,
			   NULL, NULL, NULL, NULL);
	//g_print("%d/%d\n", sampleID-1, numSamples);
	if((rc==0) || (buffer== NULL)){
	  g_print("MP4: read error\n");
	  sampleBuffer = NULL;
	  sampleID=0;
	  mp4_ip.output->buffer_free();
	  mp4_ip.output->close_audio();
	  g_free(args);
	  faacDecClose(decoder);
	  MP4Close(mp4file);
	  bPlaying = FALSE;
	  pthread_mutex_unlock(&mutex);
	  pthread_exit(NULL);
	}else{
	  sampleBuffer = faacDecDecode(decoder, &frameInfo, buffer, bufferSize);
	  if(frameInfo.error > 0){
	    g_print("MP4: %s\n",
		    faacDecGetErrorMessage(frameInfo.error));
	    mp4_ip.output->close_audio();
	    g_free(args);
	    faacDecClose(decoder);
	    MP4Close(mp4file);
	    bPlaying = FALSE;
	    pthread_mutex_unlock(&mutex);
	    pthread_exit(NULL);
	  }
	  if(buffer){
	    g_free(buffer); buffer=NULL; bufferSize=0;
	  }
	  while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1)
	    xmms_usleep(30000);
	}
	mp4_ip.add_vis_pcm(mp4_ip.output->written_time(),
			   FMT_S16_NE,
			   channels,
			   frameInfo.samples<<1,
			   sampleBuffer);
	mp4_ip.output->write_audio(sampleBuffer, frameInfo.samples<<1);
      }
      while(bPlaying && mp4_ip.output->buffer_free()){
	xmms_usleep(10000);
      }
      mp4_ip.output->close_audio();
      g_free(args);
      faacDecClose(decoder);
      MP4Close(mp4file);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
  } else{
    // WE ARE READING AN AAC FILE
    FILE		*file = NULL;
    faacDecHandle	decoder = 0;
    guchar		*buffer = 0;
    gulong		bufferconsumed = 0;
    gulong		samplerate = 0;
    guchar		channels;
    gulong		buffervalid = 0;
    TitleInput*		input;
    gchar		*temp = g_strdup(args);
    gchar		*ext  = strrchr(temp, '.');
    gchar		*xmmstitle = NULL;
    faacDecConfigurationPtr config;

    if((file = fopen(args, "rb")) == 0){
      g_print("AAC: can't find file %s\n", args);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    if((decoder = faacDecOpen()) == NULL){
      g_print("AAC: Open Decoder Error\n");
      fclose(file);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    config = faacDecGetCurrentConfiguration(decoder);
    config->useOldADTSFormat = 0;
    faacDecSetConfiguration(decoder, config);
    if((buffer = g_malloc(BUFFER_SIZE)) == NULL){
      g_print("AAC: error g_malloc\n");
      fclose(file);
      bPlaying = FALSE;
      faacDecClose(decoder);
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){
      g_print("AAC: Error reading file\n");
      g_free(buffer);
      fclose(file);
      bPlaying = FALSE;
      faacDecClose(decoder);
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    XMMS_NEW_TITLEINPUT(input);
    input->file_name = g_basename(temp);
    input->file_ext = ext ? ext+1 : NULL;
    input->file_path = temp;
    if(!strncmp(buffer, "ID3", 3)){
      gint size = 0;

      fseek(file, 0, SEEK_SET);
      size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9];
      size+=10;
      fread(buffer, 1, size, file);
      buffervalid = fread(buffer, 1, BUFFER_SIZE, file);
    }
    xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input);
    if(xmmstitle == NULL)
      xmmstitle = g_strdup(input->file_name);
    if(temp) g_free(temp);
    if(input->performer) g_free(input->performer);
    if(input->album_name) g_free(input->album_name);
    if(input->track_name) g_free(input->track_name);
    if(input->genre) g_free(input->genre);
    g_free(input);
    bufferconsumed = faacDecInit(decoder,
				 buffer,
				 buffervalid,
				 &samplerate,
				 &channels);
    if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){
      g_print("AAC: Output Error\n");
      g_free(buffer); buffer=0;
      faacDecClose(decoder);
      fclose(file);
      mp4_ip.output->close_audio();
      /*
      if(positionTable){
	g_free(positionTable); positionTable=0;
      }
      */
      g_free(xmmstitle);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    //if(bSeek){
    //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels);
      //}else{
    mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels);
      //}
    mp4_ip.output->flush(0);

    while(bPlaying && buffervalid > 0){
      faacDecFrameInfo	finfo;
      unsigned long	samplesdecoded;
      char*		sample_buffer = NULL;
      /*
	if(bSeek && seekPosition!=-1){
	fseek(file, positionTable[seekPosition], SEEK_SET);
	bufferconsumed=0;
	buffervalid = fread(buffer, 1, BUFFER_SIZE, file);
	aac_ip.output->flush(seekPosition*1000);
	seekPosition=-1;
	}
      */
      if(bufferconsumed > 0){
	memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed);
	buffervalid -= bufferconsumed;
	buffervalid += fread(&buffer[buffervalid], 1,
			     BUFFER_SIZE-buffervalid, file);
	bufferconsumed = 0;
      }
      sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid);
      if(finfo.error){
	config = faacDecGetCurrentConfiguration(decoder);
	if(config->useOldADTSFormat != 1){
	  faacDecClose(decoder);
	  decoder = faacDecOpen();
	  config = faacDecGetCurrentConfiguration(decoder);
	  config->useOldADTSFormat = 1;
	  faacDecSetConfiguration(decoder, config);
	  finfo.bytesconsumed=0;
	  finfo.samples = 0;
	  faacDecInit(decoder,
		      buffer,
		      buffervalid,
		      &samplerate,
		      &channels);
	}else{
	  g_print("FAAD2 Warning %s\n", faacDecGetErrorMessage(finfo.error));
	  buffervalid = 0;
	}
      }
      bufferconsumed += finfo.bytesconsumed;
      samplesdecoded = finfo.samples;
      if((samplesdecoded<=0) && !sample_buffer){
	g_print("AAC: error sample decoding\n");
	continue;
      }
      while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){
	xmms_usleep(10000);
      }
      mp4_ip.add_vis_pcm(mp4_ip.output->written_time(),
			 FMT_S16_LE, channels,
			 samplesdecoded<<1, sample_buffer);
      mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1);
    }
    while(bPlaying && mp4_ip.output->buffer_playing()){
      xmms_usleep(10000);
    }
    mp4_ip.output->buffer_free();
    mp4_ip.output->close_audio();
    bPlaying = FALSE;
    g_free(buffer);
    faacDecClose(decoder);
    g_free(xmmstitle);
    fclose(file);
    seekPosition = -1;
    /*
    if(positionTable){
      g_free(positionTable); positionTable=0;
    }
    */
    bPlaying = FALSE;
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
    
  }
}
Пример #18
0
int main(int argc, char *argv[])
{
    int k;
    short sample_buffer[1024*MAX_CHANNELS];
    int writeToStdio = 0, out_dir_set = 0;
    int def_sr_set = 0, use_ltp = 0;
    int def_srate;
    int showHelp = 0;
    char *fnp;
    int result;
    int first_time = 1;
    char out_dir[255];
    char aacFileName[255];
    char audioFileName[255];

    FILE *sndfile;
    FILE *infile;
    faacDecHandle hDecoder;
    faacDecConfigurationPtr config;

    char percent[200];

    long buffercount;
    unsigned long bytesconsumed, samples, fileread, bytecount;
    unsigned char *buffer;

    unsigned long samplerate, channels, tagsize;

/* System dependant types */
#ifdef _WIN32
    long begin, end;
#else
    clock_t begin;
#endif

    fprintf(stderr, "FAAD (Freeware AAC Decoder) Compiled on: " __DATE__ "\n");
    fprintf(stderr, "FAAD homepage: %s\n", "http://www.audiocoding.com");

    /* begin process command line */
    progName = argv[0];
    while (1) {
        int c = -1;
        int option_index = 0;
        static struct option long_options[] = {
            { "outputdir",  0, 0, 'o' },
            { "samplerate", 0, 0, 's' },
            { "ltp",        0, 0, 'l' },
            { "stdio",      0, 0, 'w' },
            { "help",       0, 0, 'h' }
        };

        c = getopt_long(argc, argv, "o:s:whl",
            long_options, &option_index);

        if (c == -1)
            break;

        switch (c) {
        case 'o': {
            if (optarg) {
                char dr[255];
                if (sscanf(optarg, "%s", dr) < 1) {
                    out_dir_set = 0;
                } else {
                    out_dir_set = 1;
                    strcpy(out_dir, dr);
                }
            } else {
                out_dir_set = 0;
            }
            break;
        }
        case 's': {
            if (optarg) {
                char dr[255];
                if (sscanf(optarg, "%s", dr) < 1) {
                    def_sr_set = 0;
                } else {
                    def_sr_set = 1;
                    def_srate = atoi(dr);
                }
            } else {
                out_dir_set = 0;
            }
            break;
        }
        case 'w': {
            writeToStdio = 1;
            break;
        }
        case 'l': {
            use_ltp = 1;
            break;
        }
        case 'h': {
            showHelp = 1;
            break;
        }
        default:
            break;
        }
    }

    /* check that we have at least two non-option arguments */
    /* Print help if requested */
    if (((argc - optind) < 1) || showHelp)
    {
        usage();
        return 1;
    }

    /* point to the specified file name */
    strcpy(aacFileName, argv[optind]);

#ifdef _WIN32
    begin = GetTickCount();
#else
    begin = clock();
#endif

    buffer = (unsigned char*)malloc(768*MAX_CHANNELS);
    memset(buffer, 0, 768*MAX_CHANNELS);

    infile = fopen(aacFileName, "rb");
    if (infile == NULL)
    {
        /* unable to open file */
        fprintf(stderr, "Error opening file: %s\n", aacFileName);
        return 1;
    }
    fseek(infile, 0, SEEK_END);
    fileread = ftell(infile);
    fseek(infile, 0, SEEK_SET);

    buffercount = bytecount = 0;
    fread(buffer, 1, 768*MAX_CHANNELS, infile);

    tagsize = id3v2_tag(buffer);
    if (tagsize) {
        fseek(infile, tagsize, SEEK_SET);

        bytecount = tagsize;
        buffercount = 0;
        fread(buffer, 1, 768*MAX_CHANNELS, infile);
    }

    hDecoder = faacDecOpen();

    /* Set the default object type and samplerate */
    /* This is useful for RAW AAC files */
    config = faacDecGetCurrentConfiguration(hDecoder);
    if (def_sr_set)
        config->defSampleRate = def_srate;
    if (use_ltp)
        config->defObjectType = LTP;

    faacDecSetConfiguration(hDecoder, config);


    if((buffercount = faacDecInit(hDecoder, buffer, &samplerate, &channels)) < 0)
    {
        /* If some error initializing occured, skip the file */
        fprintf(stderr, "Error initializing decoder library.\n");
        return 1;
    }

    if (buffercount > 0) {
        bytecount += buffercount;

        for (k = 0; k < (768*MAX_CHANNELS - buffercount); k++)
            buffer[k] = buffer[k + buffercount];

        fread(buffer + (768*MAX_CHANNELS) - buffercount, 1, buffercount, infile);
        buffercount = 0;
    }

    fprintf(stderr, "Busy decoding %s", aacFileName);
    if (tagsize)
        fprintf(stderr, " (has ID3v2)\n");
    else
        fprintf(stderr, "\n");

    /* Only calculate the path and open the file for writing if we are not writing to stdout. */
    if(!writeToStdio)
    {
        if (out_dir_set)
            combine_path(audioFileName, out_dir, aacFileName);
        else
            strcpy(audioFileName, aacFileName);

        fnp = (char *)strrchr(audioFileName,'.');

        if (fnp)
            fnp[0] = '\0';

        strcat(audioFileName, ".wav");
    }

    first_time = 1;

    do
    {
        if (buffercount > 0) {
            for (k = 0; k < (768*MAX_CHANNELS - buffercount); k++)
                buffer[k] = buffer[k + buffercount];

            fread(buffer + (768*MAX_CHANNELS) - buffercount, 1, buffercount, infile);
            buffercount = 0;
        }

        result = faacDecDecode(hDecoder, buffer, &bytesconsumed, sample_buffer, &samples);
        if (result == FAAD_FATAL_ERROR)
            fprintf(stderr, "Fatal error decoding file\n");
        if (result == FAAD_ERROR)
            fprintf(stderr, "Error decoding frame\n");

        buffercount += bytesconsumed;

        bytecount += bytesconsumed;
        if (bytecount >= fileread)
            result = 9999; /* to make sure it stops now */

        sprintf(percent, "%.2f decoding %s.",
            min((double)(bytecount*100)/fileread,100), aacFileName);
        fprintf(stderr, "%s\r", percent);
#ifdef _WIN32
        SetConsoleTitle(percent);
#endif

        if ((result == FAAD_OK) && (samples > 0))
        {
            if(first_time)
            {
                first_time = 0;

                if(!writeToStdio)
                {
                    sndfile = fopen(audioFileName, "w+b");

                    if (sndfile==NULL)
                    {
                        fprintf(stderr, "Unable to create the file << %s >>.\n", audioFileName);
                        continue;
                    }

                    CreateWavHeader(sndfile, channels, samplerate, 16);
                }
                else
                {
                    sndfile = stdout;
                }
            }

            fwrite(sample_buffer, sizeof(short), 1024*channels, sndfile);
        }

    } while (result <= FAAD_OK_CHUPDATE);

    faacDecClose(hDecoder);

    fclose(infile);

    if(!writeToStdio)
        UpdateWavHeader(sndfile);

    /* Only close if we are not writing to stdout */
    if(!writeToStdio)
        if(sndfile)
            fclose(sndfile);

#ifdef _WIN32
    end = GetTickCount();
    fprintf(stderr, "Decoding %s took: %d sec.\n", aacFileName, (end-begin)/1000);
    SetConsoleTitle("FAAD");
#else
    /* clock() grabs time since the start of the app but when we decode multiple files,
       each file has its own starttime (begin). */
    fprintf(stderr, "Decoding %s took: %5.2f sec.\n", aacFileName,
        (float)(clock() - begin)/(float)CLOCKS_PER_SEC);
#endif

    if (buffer) free(buffer);

    return 0;
}
static int init(sh_audio_t *sh)
{
  unsigned long faac_samplerate;
  unsigned char faac_channels;
  int faac_init, pos = 0;
  faac_hdec = faacDecOpen();

  // If we don't get the ES descriptor, try manual config
  if(!sh->codecdata_len && sh->wf) {
    sh->codecdata_len = sh->wf->cbSize;
    sh->codecdata = malloc(sh->codecdata_len);
    memcpy(sh->codecdata, sh->wf+1, sh->codecdata_len);
    mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: codecdata extracted from WAVEFORMATEX\n");
  }
  if(!sh->codecdata_len) {
    faacDecConfigurationPtr faac_conf;
    /* Set the default object type and samplerate */
    /* This is useful for RAW AAC files */
    faac_conf = faacDecGetCurrentConfiguration(faac_hdec);
    if(sh->samplerate)
      faac_conf->defSampleRate = sh->samplerate;
    /* XXX: FAAD support FLOAT output, how do we handle
      * that (FAAD_FMT_FLOAT)? ::atmos
      */
    if (audio_output_channels <= 2) faac_conf->downMatrix = 1;
      switch(sh->samplesize){
	case 1: // 8Bit
	  mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: 8Bit samplesize not supported by FAAD, assuming 16Bit!\n");
	default:
	  sh->samplesize=2;
	case 2: // 16Bit
	  faac_conf->outputFormat = FAAD_FMT_16BIT;
	  break;
	case 3: // 24Bit
	  faac_conf->outputFormat = FAAD_FMT_24BIT;
	  break;
	case 4: // 32Bit
	  faac_conf->outputFormat = FAAD_FMT_32BIT;
	  break;
      }
    //faac_conf->defObjectType = LTP; // => MAIN, LC, SSR, LTP available.

    faacDecSetConfiguration(faac_hdec, faac_conf);

    sh->a_in_buffer_len = demux_read_data(sh->ds, sh->a_in_buffer, sh->a_in_buffer_size);
#if CONFIG_FAAD_INTERNAL
    /* init the codec, look for LATM */
    faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
                            sh->a_in_buffer_len, &faac_samplerate, &faac_channels,1);
    if (faac_init < 0 && sh->a_in_buffer_len >= 3 && sh->format == mmioFOURCC('M', 'P', '4', 'L')) {
        // working LATM not found at first try, look further on in stream
        int i;

        for (i = 0; i < 5; i++) {
            pos = sh->a_in_buffer_len-3;
            memmove(sh->a_in_buffer, &(sh->a_in_buffer[pos]), 3);
            sh->a_in_buffer_len  = 3;
            sh->a_in_buffer_len += demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len],
                                                   sh->a_in_buffer_size - sh->a_in_buffer_len);
            faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
                                    sh->a_in_buffer_len, &faac_samplerate, &faac_channels,1);
            if (faac_init >= 0) break;
        }
    }
#else
    /* external faad does not have latm lookup support */
    faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
                            sh->a_in_buffer_len, &faac_samplerate, &faac_channels);
#endif

    if (faac_init < 0) {
    pos = aac_probe(sh->a_in_buffer, sh->a_in_buffer_len);
    if(pos) {
      sh->a_in_buffer_len -= pos;
      memmove(sh->a_in_buffer, &(sh->a_in_buffer[pos]), sh->a_in_buffer_len);
      sh->a_in_buffer_len +=
	demux_read_data(sh->ds,&(sh->a_in_buffer[sh->a_in_buffer_len]),
	sh->a_in_buffer_size - sh->a_in_buffer_len);
      pos = 0;
    }

    /* init the codec */
#if CONFIG_FAAD_INTERNAL
    faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
          sh->a_in_buffer_len, &faac_samplerate, &faac_channels,0);
#else
    faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
          sh->a_in_buffer_len, &faac_samplerate, &faac_channels);
#endif
    }

    sh->a_in_buffer_len -= (faac_init > 0)?faac_init:0; // how many bytes init consumed
    // XXX FIXME: shouldn't we memcpy() here in a_in_buffer ?? --A'rpi

  } else { // We have ES DS in codecdata
    faacDecConfigurationPtr faac_conf = faacDecGetCurrentConfiguration(faac_hdec);
    if (audio_output_channels <= 2) {
        faac_conf->downMatrix = 1;
        faacDecSetConfiguration(faac_hdec, faac_conf);
    }

    /*int i;
    for(i = 0; i < sh_audio->codecdata_len; i++)
      printf("codecdata_dump %d: 0x%02X\n", i, sh_audio->codecdata[i]);*/

    faac_init = faacDecInit2(faac_hdec, sh->codecdata,
       sh->codecdata_len,	&faac_samplerate, &faac_channels);
  }
  if(faac_init < 0) {
    mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to initialize the decoder!\n"); // XXX: deal with cleanup!
    faacDecClose(faac_hdec);
    // XXX: free a_in_buffer here or in uninit?
    return 0;
  } else {
    mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug!
    mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %ldHz  channels: %d\n", faac_samplerate, faac_channels);
    // 8 channels is aac channel order #7.
    sh->channels = faac_channels == 7 ? 8 : faac_channels;
    if (audio_output_channels <= 2) sh->channels = faac_channels > 1 ? 2 : 1;
    sh->samplerate = faac_samplerate;
    sh->samplesize=2;
    //sh->o_bps = sh->samplesize*faac_channels*faac_samplerate;
    if(!sh->i_bps) {
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: compressed input bitrate missing, assuming 128kbit/s!\n");
      sh->i_bps = 128*1000/8; // XXX: HACK!!! ::atmos
    } else
      mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: got %dkbit/s bitrate from MP4 header!\n",sh->i_bps*8/1000);
  }
  return 1;
}
Пример #20
0
static void *mp4Decode(void *args)
{
  FILE*		mp4file;

  pthread_mutex_lock(&mutex);
  seekPosition = -1;
  bPlaying = TRUE;

  if(!(mp4file = fopen(args, "rb"))){
    g_print("MP4!AAC - Can't open file\n");
    g_free(args);
    bPlaying = FALSE;
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);

  }
  mp4_get_file_type(mp4file);
  fseek(mp4file, 0, SEEK_SET);
  if(mp4cfg.file_type == FILE_MP4){// We are reading a MP4 file
    mp4ff_callback_t*	mp4cb;
    mp4ff_t*		infile;
    gint		mp4track;

    mp4cb = getMP4FF_cb(mp4file);
    if(!(infile = mp4ff_open_read(mp4cb))){
      g_print("MP4 - Can't open file\n");
      goto end;
    }

    if((mp4track = getAACTrack(infile)) < 0){
      /*
       * TODO: check here for others Audio format.....
       *
      */
      g_print("Unsupported Audio track type\n");
      g_free(args);
      fclose(mp4file);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }else{
      NeAACDecHandle	decoder;
      unsigned char	*buffer	= NULL;
      guint		bufferSize = 0;
      gulong		samplerate;
      guchar		channels;
      //guint		avgBitrate;
      //MP4Duration	duration;
      int		msDuration;
      int		numSamples;
      int		sampleID = 0;
      unsigned int	framesize;
      mp4AudioSpecificConfig mp4ASC;
      gchar		*xmmstitle;

      decoder = NeAACDecOpen();
      mp4ff_get_decoder_config(infile, mp4track, &buffer, &bufferSize);
      if(NeAACDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0){
          goto end;
      }
      if(buffer){
	framesize = 1024;
	if(NeAACDecAudioSpecificConfig(buffer, bufferSize, &mp4ASC) >= 0){
	  if(mp4ASC.frameLengthFlag == 1) framesize = 960;
	  if(mp4ASC.sbr_present_flag == 1) framesize *= 2;
	}
	g_free(buffer);
      }
      if(channels == 0){
	g_print("Number of Channels not supported\n");
	goto end;
      }

      //duration = MP4GetTrackDuration(mp4file, mp4track);
      //msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track,
      //				       duration,MP4_MSECS_TIME_SCALE);

      //msDuration = mp4ff_get_track_duration(infile, mp4track);
      //printf("%d\n", msDuration);

      //numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track);
      numSamples = mp4ff_num_samples(infile, mp4track);
      {
	float f = 1024.0;
	if(mp4ASC.sbr_present_flag == 1)
	  f = f * 2.0;
	msDuration = ((float)numSamples*(float)(f-1.0)/
		      (float)samplerate)*1000;
      }
      xmmstitle = getMP4title(infile, args);
      mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels);
      mp4_ip.output->flush(0);
      mp4_ip.set_info(xmmstitle, msDuration, -1, samplerate/1000, channels);
      g_print("MP4 - %d channels @ %ld Hz\n", channels, samplerate);

      while(bPlaying){
	void*			sampleBuffer;
	faacDecFrameInfo	frameInfo;
	gint			rc;

	if(seekPosition!=-1){
	  /*
	  duration = MP4ConvertToTrackDuration(mp4file,
					       mp4track,
					       seekPosition*1000,
					       MP4_MSECS_TIME_SCALE);
	  sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0);
          */
          float f = 1024.0;
	  if(mp4ASC.sbr_present_flag == 1)
	    f = f * 2.0;
          sampleID = (float)seekPosition*(float)samplerate/(float)(f-1.0);
	  mp4_ip.output->flush(seekPosition*1000);
	  seekPosition = -1;
	}
	buffer=NULL;
	bufferSize=0;
	rc = mp4ff_read_sample(infile, mp4track, sampleID++,
			       &buffer, &bufferSize);
	//g_print("%d/%d\n", sampleID-1, numSamples);
	if((rc==0) || (buffer== NULL)){
	  g_print("MP4: read error\n");
	  sampleBuffer = NULL;
	  sampleID=0;
	  mp4_ip.output->buffer_free();
            goto end;
	}else{
	  sampleBuffer = NeAACDecDecode(decoder, &frameInfo, buffer, bufferSize);
	  if(frameInfo.error > 0){
	    g_print("MP4: %s\n",
		    faacDecGetErrorMessage(frameInfo.error));
	    goto end;
	  }
	  if(buffer){
	    g_free(buffer); buffer=NULL; bufferSize=0;
	  }
	  while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1)
	    xmms_usleep(30000);
	}
	mp4_ip.add_vis_pcm(mp4_ip.output->written_time(),
			   FMT_S16_NE,
			   channels,
			   frameInfo.samples<<1,
			   sampleBuffer);
	mp4_ip.output->write_audio(sampleBuffer, frameInfo.samples<<1);
	if(sampleID >= numSamples){
          break;
	}
      }
      while(bPlaying && mp4_ip.output->buffer_playing() && mp4_ip.output->buffer_free()){
	xmms_usleep(10000);
      }
end:
      mp4_ip.output->close_audio();
      g_free(args);
      NeAACDecClose(decoder);
      if(infile) mp4ff_close(infile);
      if(mp4cb) g_free(mp4cb);
      bPlaying = FALSE;
      fclose(mp4file);
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
  }else{
    // WE ARE READING AN AAC FILE
    FILE		*file = NULL;
    NeAACDecHandle	decoder = 0;
    guchar		*buffer = 0;
    gulong		bufferconsumed = 0;
    gulong		samplerate = 0;
    guchar		channels;
    gulong		buffervalid = 0;
    TitleInput*		input;
    gchar		*temp = g_strdup(args);
    gchar		*ext  = strrchr(temp, '.');
    gchar		*xmmstitle = NULL;
    NeAACDecConfigurationPtr config;

    if((file = fopen(args, "rb")) == 0){
      g_print("AAC: can't find file %s\n", args);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    if((decoder = NeAACDecOpen()) == NULL){
      g_print("AAC: Open Decoder Error\n");
      fclose(file);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    config = NeAACDecGetCurrentConfiguration(decoder);
    config->useOldADTSFormat = 0;
    NeAACDecSetConfiguration(decoder, config);
    if((buffer = g_malloc(BUFFER_SIZE)) == NULL){
      g_print("AAC: error g_malloc\n");
      fclose(file);
      bPlaying = FALSE;
      NeAACDecClose(decoder);
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){
      g_print("AAC: Error reading file\n");
      g_free(buffer);
      fclose(file);
      bPlaying = FALSE;
      NeAACDecClose(decoder);
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    XMMS_NEW_TITLEINPUT(input);
    input->file_name = g_basename(temp);
    input->file_ext = ext ? ext+1 : NULL;
    input->file_path = temp;
    if(!strncmp(buffer, "ID3", 3)){
      gint size = 0;

      fseek(file, 0, SEEK_SET);
      size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9];
      size+=10;
      fread(buffer, 1, size, file);
      buffervalid = fread(buffer, 1, BUFFER_SIZE, file);
    }
    xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input);
    if(xmmstitle == NULL)
      xmmstitle = g_strdup(input->file_name);
    if(temp) g_free(temp);
    if(input->performer) g_free(input->performer);
    if(input->album_name) g_free(input->album_name);
    if(input->track_name) g_free(input->track_name);
    if(input->genre) g_free(input->genre);
    g_free(input);
    bufferconsumed = NeAACDecInit(decoder,
				 buffer,
				 buffervalid,
				 &samplerate,
				 &channels);
    if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){
      g_print("AAC: Output Error\n");
      g_free(buffer); buffer=0;
      faacDecClose(decoder);
      fclose(file);
      mp4_ip.output->close_audio();
      /*
      if(positionTable){
	g_free(positionTable); positionTable=0;
      }
      */
      g_free(xmmstitle);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    //if(bSeek){
    //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels);
      //}else{
    mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels);
      //}
    mp4_ip.output->flush(0);

    while(bPlaying && buffervalid > 0){
      NeAACDecFrameInfo	finfo;
      unsigned long	samplesdecoded;
      char*		sample_buffer = NULL;
      /*
	if(bSeek && seekPosition!=-1){
	fseek(file, positionTable[seekPosition], SEEK_SET);
	bufferconsumed=0;
	buffervalid = fread(buffer, 1, BUFFER_SIZE, file);
	aac_ip.output->flush(seekPosition*1000);
	seekPosition=-1;
	}
      */
      if(bufferconsumed > 0){
	memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed);
	buffervalid -= bufferconsumed;
	buffervalid += fread(&buffer[buffervalid], 1,
			     BUFFER_SIZE-buffervalid, file);
	bufferconsumed = 0;
      }
      sample_buffer = NeAACDecDecode(decoder, &finfo, buffer, buffervalid);
      if(finfo.error){
	config = NeAACDecGetCurrentConfiguration(decoder);
	if(config->useOldADTSFormat != 1){
	  NeAACDecClose(decoder);
	  decoder = NeAACDecOpen();
	  config = NeAACDecGetCurrentConfiguration(decoder);
	  config->useOldADTSFormat = 1;
	  NeAACDecSetConfiguration(decoder, config);
	  finfo.bytesconsumed=0;
	  finfo.samples = 0;
	  NeAACDecInit(decoder,
		      buffer,
		      buffervalid,
		      &samplerate,
		      &channels);
	}else{
	  g_print("FAAD2 Warning %s\n", NeAACDecGetErrorMessage(finfo.error));
	  buffervalid = 0;
	}
      }
      bufferconsumed += finfo.bytesconsumed;
      samplesdecoded = finfo.samples;
      if((samplesdecoded<=0) && !sample_buffer){
	g_print("AAC: error sample decoding\n");
	continue;
      }
      while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){
	xmms_usleep(10000);
      }
      mp4_ip.add_vis_pcm(mp4_ip.output->written_time(),
			 FMT_S16_LE, channels,
			 samplesdecoded<<1, sample_buffer);
      mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1);
    }
    while(bPlaying && mp4_ip.output->buffer_playing()){
      xmms_usleep(10000);
    }
    mp4_ip.output->buffer_free();
    mp4_ip.output->close_audio();
    bPlaying = FALSE;
    g_free(buffer);
    NeAACDecClose(decoder);
    g_free(xmmstitle);
    fclose(file);
    seekPosition = -1;
    /*
    if(positionTable){
      g_free(positionTable); positionTable=0;
    }
    */
    bPlaying = FALSE;
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);

  }
}
Пример #21
0
int decodeAACfile(char *sndfile, int def_srate, aac_dec_opt *opt)
{
    int tagsize;
    unsigned long samplerate;
    unsigned char channels;
    void *sample_buffer;

    FILE *infile;

    audio_file *aufile;

    faacDecHandle hDecoder;
    faacDecFrameInfo frameInfo;
    faacDecConfigurationPtr config;

    int first_time = 1;


    /* declare variables for buffering */
    DEC_BUFF_VARS

    infile = fopen(opt->filename, "rb");
    if (infile == NULL)
    {
        /* unable to open file */
        error_handler("Error opening file: %s\n", opt->filename);
        return 1;
    }
    INIT_BUFF(infile)

    tagsize = id3v2_tag(buffer);
    if (tagsize)
    {
        UPDATE_BUFF_SKIP(tagsize)
    }

    hDecoder = faacDecOpen();

    /* Set the default object type and samplerate */
    /* This is useful for RAW AAC files */
    config = faacDecGetCurrentConfiguration(hDecoder);
    if (def_srate)
        config->defSampleRate = def_srate;
    config->defObjectType = opt->object_type;
    config->outputFormat = opt->output_format;

    faacDecSetConfiguration(hDecoder, config);

    if ((bytesconsumed = faacDecInit(hDecoder, buffer, bytes_in_buffer,
        &samplerate, &channels)) < 0)
    {
        /* If some error initializing occured, skip the file */
        error_handler("Error initializing decoder library.\n");
        END_BUFF
        faacDecClose(hDecoder);
        fclose(infile);
        return 1;
    }
    buffer_index += bytesconsumed;

    do
    {
        /* update buffer */
        UPDATE_BUFF_READ

        sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, bytes_in_buffer);

        /* update buffer indices */
        UPDATE_BUFF_IDX(frameInfo)

        if (frameInfo.error > 0)
        {
            error_handler("Error: %s\n",
            faacDecGetErrorMessage(frameInfo.error));
        }

        opt->progress_update((long)fileread, buffer_index);

        /* open the sound file now that the number of channels are known */
        if (first_time && !frameInfo.error)
        {
            if(opt->decode_mode == 0)
            {
                if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE,
                                frameInfo.channels) < 0)
                {
                    error_handler("\nCan't access %s\n", "WAVE OUT");
                    END_BUFF
                    faacDecClose(hDecoder);
                    fclose(infile);
                    return (0);
                }
            }
            else
            {
                aufile = open_audio_file(sndfile, samplerate, frameInfo.channels,
                    opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo));

                if (aufile == NULL)
                {
                    END_BUFF
                    faacDecClose(hDecoder);
                    fclose(infile);
                    return 0;
                }
            }
            first_time = 0;
        }

        if ((frameInfo.error == 0) && (frameInfo.samples > 0))
        {
            if(opt->decode_mode == 0)
                WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples);
            else
                write_audio_file(aufile, sample_buffer, frameInfo.samples, 0);
        }

        if (buffer_index >= fileread)
            sample_buffer = NULL; /* to make sure it stops now */

        if(stop_decoding)
            break;

    } while (sample_buffer != NULL);

    faacDecClose(hDecoder);

    fclose(infile);

    if(opt->decode_mode == 0)
        WIN_Audio_close();
    else
    {
        if (!first_time)
            close_audio_file(aufile);
    }

    END_BUFF

    return frameInfo.error;
}
Пример #22
0
int fdpl_decode_AAC(int def_srate, const char *file_path, size_t &c, size_t &sr,  size_t &samples, std::vector<float> * ch1, std::vector<float> *ch2)
{
    int tagsize;
    uint32_t samplerate;
    unsigned char channels;
    void *sample_buffer;

    FILE *infile;

    faacDecHandle hDecoder;
    faacDecFrameInfo frameInfo;
    faacDecConfigurationPtr config;

    /* declare variables for buffering */
    DEC_BUFF_VARS

    infile = fopen(file_path, "rb");
    if (infile == NULL)
    {
        /* unable to open file */
       	std::cerr<<"Error opening file"<<std::endl;
        return 1;
    }
    INIT_BUFF(infile)

    tagsize = id3v2_tag(buffer);//avoids ID3 tag (useful for mp3 as well)
    if (tagsize)
    {
        UPDATE_BUFF_SKIP(tagsize)
    }

    hDecoder = faacDecOpen();

    /* Set the default object type and samplerate */
    /* This is useful for RAW AAC files */
    config = faacDecGetCurrentConfiguration(hDecoder);
    if (def_srate)
        config->defSampleRate = def_srate;
    config->defObjectType = LC;//default
    config->outputFormat = FAAD_FMT_FLOAT;
    config -> downMatrix = 0; //set to 1

    faacDecSetConfiguration(hDecoder, config);

    if ((bytesconsumed = faacDecInit(hDecoder, buffer, bytes_in_buffer,
        &samplerate, &channels)) < 0)
    {
        /* If some error initializing occured, skip the file */
        std::cerr<<"Error initializing decoder library."<<std::endl;
        END_BUFF
        faacDecClose(hDecoder);
        fclose(infile);
        return 1;
    }
    buffer_index += bytesconsumed;

    do
    {
        /* update buffer */
        UPDATE_BUFF_READ

        sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, bytes_in_buffer);

        /* update buffer indices */
        UPDATE_BUFF_IDX(frameInfo)

        if (frameInfo.error > 0)
        {
            std::cerr<<"Error: %s\n"<<faacDecGetErrorMessage(frameInfo.error)<<std::endl;
        }

        if ((frameInfo.error == 0) && (frameInfo.samples > 0) && (frameInfo.channels < 3))
        {
		size_t samples_channel = (size_t)frameInfo.samples/(size_t)frameInfo.channels;
       		samples += samples_channel;
		float *pcm;		
		pcm = (float *)sample_buffer;
		for(size_t i=0; i<samples_channel; i++){
		//writing the samples of each channel in separate float vectors
			for(size_t j=0; j<frameInfo.channels; j++){
			          		
				if(j==0){
					ch1 -> push_back(pcm[i*frameInfo.channels+j]);

				}else if(j==1){
					ch2 -> push_back(pcm[i*frameInfo.channels+j]);

				}else{
					std::cerr<<"Unexpected number of channels: "<<j<<std::endl;
					return -1;
				}
			}
		}		
        }
        if (buffer_index >= fileread)
            sample_buffer = NULL; /* to make sure it stops now */

    } while (sample_buffer != NULL);

    c = frameInfo.channels;
    sr = frameInfo.samplerate; 

    faacDecClose(hDecoder);

    fclose(infile);

    END_BUFF

    return frameInfo.error;
}
Пример #23
0
static int init(sh_audio_t *sh)
{
  unsigned long faac_samplerate;
  unsigned char faac_channels;
  int faac_init, pos = 0;
  faac_hdec = faacDecOpen();

  // If we don't get the ES descriptor, try manual config
  if(!sh->codecdata_len && sh->wf) {
    sh->codecdata_len = sh->wf->cbSize;
    sh->codecdata = (char*)(sh->wf+1);
    mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: codecdata extracted from WAVEFORMATEX\n");
  }
  if(!sh->codecdata_len) {
#if 1
    faacDecConfigurationPtr faac_conf;
    /* Set the default object type and samplerate */
    /* This is useful for RAW AAC files */
    faac_conf = faacDecGetCurrentConfiguration(faac_hdec);
    if(sh->samplerate)
      faac_conf->defSampleRate = sh->samplerate;
    /* XXX: FAAD support FLOAT output, how do we handle
      * that (FAAD_FMT_FLOAT)? ::atmos
      */
    if (audio_output_channels <= 2) faac_conf->downMatrix = 1;
      switch(sh->samplesize){
	case 1: // 8Bit
	  mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: 8Bit samplesize not supported by FAAD, assuming 16Bit!\n");
	default:
	  sh->samplesize=2;
	case 2: // 16Bit
	  faac_conf->outputFormat = FAAD_FMT_16BIT;
	  break;
	case 3: // 24Bit
	  faac_conf->outputFormat = FAAD_FMT_24BIT;
	  break;
	case 4: // 32Bit
	  faac_conf->outputFormat = FAAD_FMT_32BIT;
	  break;
      }
    //faac_conf->defObjectType = LTP; // => MAIN, LC, SSR, LTP available.

    faacDecSetConfiguration(faac_hdec, faac_conf);
#endif

    sh->a_in_buffer_len = demux_read_data(sh->ds, sh->a_in_buffer, sh->a_in_buffer_size);
    pos = aac_probe(sh->a_in_buffer, sh->a_in_buffer_len);
    if(pos) {
      sh->a_in_buffer_len -= pos;
      memmove(sh->a_in_buffer, &(sh->a_in_buffer[pos]), sh->a_in_buffer_len);
      sh->a_in_buffer_len +=
	demux_read_data(sh->ds,&(sh->a_in_buffer[sh->a_in_buffer_len]),
	sh->a_in_buffer_size - sh->a_in_buffer_len);
      pos = 0;
    }

    /* init the codec */
    faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
       sh->a_in_buffer_len, &faac_samplerate, &faac_channels);

    sh->a_in_buffer_len -= (faac_init > 0)?faac_init:0; // how many bytes init consumed
    // XXX FIXME: shouldn't we memcpy() here in a_in_buffer ?? --A'rpi

  } else { // We have ES DS in codecdata
    faacDecConfigurationPtr faac_conf = faacDecGetCurrentConfiguration(faac_hdec);
    if (audio_output_channels <= 2) {
        faac_conf->downMatrix = 1;
        faacDecSetConfiguration(faac_hdec, faac_conf);
    }
    
    /*int i;
    for(i = 0; i < sh_audio->codecdata_len; i++)
      printf("codecdata_dump %d: 0x%02X\n", i, sh_audio->codecdata[i]);*/

    faac_init = faacDecInit2(faac_hdec, sh->codecdata,
       sh->codecdata_len,	&faac_samplerate, &faac_channels);
  }
  if(faac_init < 0) {
    mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to initialize the decoder!\n"); // XXX: deal with cleanup!
    faacDecClose(faac_hdec);
    // XXX: free a_in_buffer here or in uninit?
    return 0;
  } else {
    mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug!
    mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %ldHz  channels: %d\n", faac_samplerate, faac_channels);
    sh->channels = faac_channels;
    if (audio_output_channels <= 2) sh->channels = faac_channels > 1 ? 2 : 1;
    
    /* re-map channels */
    switch (sh->channels) {
      default:
      case 1: /* no action needed */
      case 2: /* no action needed */
      case 3: /* no suitable default behavior? */
      case 4: /* no suitable default behavior? */
        break;
      case 5: /* mplayer treats this like 6-channel */
      case 6:
        sh->chan_map = af_set_channel_map(6, "04" "10" "21" "32" "43" "55");
        break;
      case 7: /* not supported by mplayer? */
        break;
    }
    
    sh->samplerate = faac_samplerate;
    sh->samplesize=2;
    //sh->o_bps = sh->samplesize*faac_channels*faac_samplerate;
    if(!sh->i_bps) {
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: compressed input bitrate missing, assuming 128kbit/s!\n");
      sh->i_bps = 128*1000/8; // XXX: HACK!!! ::atmos
    } else 
      mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: got %dkbit/s bitrate from MP4 header!\n",sh->i_bps*8/1000);
  }  
  return 1;
}
Пример #24
0
int decodeMP4file(char *sndfile, aac_dec_opt *opt)
{
    int track;
    unsigned long samplerate;
    unsigned char channels;
    void *sample_buffer;

    MP4FileHandle infile;
    MP4SampleId sampleId, numSamples;

    audio_file *aufile;

    faacDecHandle hDecoder;
    faacDecFrameInfo frameInfo;

    unsigned char *buffer;
    int buffer_size;

    int first_time = 1;

    hDecoder = faacDecOpen();

    infile = MP4Read(opt->filename, 0);
    if (!infile)
    {
        /* unable to open file */
        error_handler("Error opening file: %s\n", opt->filename);
        return 1;
    }

    if ((track = GetAACTrack(infile)) < 0)
    {
        error_handler("Unable to find correct AAC sound track in the MP4 file.\n");
        MP4Close(infile);
        return 1;
    }

    buffer = NULL;
    buffer_size = 0;
    MP4GetTrackESConfiguration(infile, track, &buffer, &buffer_size);

    if(faacDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0)
    {
        /* If some error initializing occured, skip the file */
        error_handler("Error initializing decoder library.\n");
        faacDecClose(hDecoder);
        MP4Close(infile);
        return 1;
    }
    if (buffer)
        free(buffer);

    numSamples = MP4GetTrackNumberOfSamples(infile, track);

    for (sampleId = 1; sampleId <= numSamples; sampleId++)
    {
        int rc;

        /* get access unit from MP4 file */
        buffer = NULL;
        buffer_size = 0;

        rc = MP4ReadSample(infile, track, sampleId, &buffer, &buffer_size, NULL, NULL, NULL, NULL);
        if (rc == 0)
        {
            error_handler("Reading from MP4 file failed.\n");
            faacDecClose(hDecoder);
            MP4Close(infile);
            return 1;
        }

        sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size);

        if (buffer)
            free(buffer);

        opt->progress_update((long)numSamples, sampleId);

        /* open the sound file now that the number of channels are known */
        if (first_time && !frameInfo.error)
        {
            if(opt->decode_mode == 0)
            {
                if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE,
                                frameInfo.channels) < 0)
                {
                    error_handler("\nCan't access %s\n", "WAVE OUT");
                    faacDecClose(hDecoder);
                    MP4Close(infile);
                    return (0);
                }
            }
            else
            {
                aufile = open_audio_file(sndfile, samplerate, frameInfo.channels,
                     opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo));

                if (aufile == NULL)
                {
                    faacDecClose(hDecoder);
                    MP4Close(infile);
                    return 0;
                }
            }
            first_time = 0;
        }

        if ((frameInfo.error == 0) && (frameInfo.samples > 0))
        {
            if(opt->decode_mode == 0)
                WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples);
            else
                write_audio_file(aufile, sample_buffer, frameInfo.samples, 0);
        }

        if (frameInfo.error > 0)
        {
            error_handler("Error: %s\n",
            faacDecGetErrorMessage(frameInfo.error));
            break;
        }
        if(stop_decoding)
            break;
    }


    faacDecClose(hDecoder);


    MP4Close(infile);

    if(opt->decode_mode == 0)
        WIN_Audio_close();
    else
    {
        if (!first_time)
            close_audio_file(aufile);
    }

    return frameInfo.error;
}
Пример #25
0
static void uninit(sh_audio_t *sh)
{
  mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Closing decoder!\n");
  faacDecClose(faac_hdec);
}
Пример #26
0
/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*)p_this;
    decoder_sys_t *p_sys;
    faacDecConfiguration *cfg;

    if( p_dec->fmt_in.i_codec != VLC_CODEC_MP4A )
    {
        return VLC_EGENERIC;
    }

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) ) ) == NULL )
        return VLC_ENOMEM;

    /* Open a faad context */
    if( ( p_sys->hfaad = faacDecOpen() ) == NULL )
    {
        msg_Err( p_dec, "cannot initialize faad" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* Misc init */
    date_Set( &p_sys->date, 0 );
    p_dec->fmt_out.i_cat = AUDIO_ES;

    p_dec->fmt_out.i_codec = HAVE_FPU ? VLC_CODEC_FL32 : VLC_CODEC_S16N;
    p_dec->pf_decode_audio = DecodeBlock;

    p_dec->fmt_out.audio.i_physical_channels =
        p_dec->fmt_out.audio.i_original_channels = 0;

    if( p_dec->fmt_in.i_extra > 0 )
    {
        /* We have a decoder config so init the handle */
        unsigned long i_rate;
        unsigned char i_channels;

        if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
                          p_dec->fmt_in.i_extra,
                          &i_rate, &i_channels ) < 0 )
        {
            msg_Err( p_dec, "Failed to initialize faad using extra data" );
            faacDecClose( p_sys->hfaad );
            free( p_sys );
            return VLC_EGENERIC;
        }

        p_dec->fmt_out.audio.i_rate = i_rate;
        p_dec->fmt_out.audio.i_channels = i_channels;
        p_dec->fmt_out.audio.i_physical_channels
            = p_dec->fmt_out.audio.i_original_channels
            = pi_channels_guessed[i_channels];
        date_Init( &p_sys->date, i_rate, 1 );
    }
    else
    {
        /* Will be initalised from first frame */
        p_dec->fmt_out.audio.i_rate = 0;
        p_dec->fmt_out.audio.i_channels = 0;
    }

    /* Set the faad config */
    cfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
    cfg->outputFormat = HAVE_FPU ? FAAD_FMT_FLOAT : FAAD_FMT_16BIT;
    faacDecSetConfiguration( p_sys->hfaad, cfg );

    /* buffer */
    p_sys->i_buffer = p_sys->i_buffer_size = 0;
    p_sys->p_buffer = NULL;

    /* Faad2 can't deal with truncated data (eg. from MPEG TS) */
    p_dec->b_need_packetized = true;

    p_sys->b_sbr = p_sys->b_ps = false;
    return VLC_SUCCESS;
}
Пример #27
0
/*****************************************************************************
 * DecodeBlock:
 *****************************************************************************/
static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_block;

    if( !pp_block || !*pp_block ) return NULL;

    p_block = *pp_block;

    if( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
    {
        block_Release( p_block );
        return NULL;
    }

    /* Remove ADTS header if we have decoder specific config */
    if( p_dec->fmt_in.i_extra && p_block->i_buffer > 7 )
    {
        if( p_block->p_buffer[0] == 0xff &&
            ( p_block->p_buffer[1] & 0xf0 ) == 0xf0 ) /* syncword */
        {   /* ADTS header present */
            size_t i_header_size; /* 7 bytes (+ 2 bytes for crc) */
            i_header_size = 7 + ( ( p_block->p_buffer[1] & 0x01 ) ? 0 : 2 );
            /* FIXME: multiple blocks per frame */
            if( p_block->i_buffer > i_header_size )
            {
                p_block->p_buffer += i_header_size;
                p_block->i_buffer -= i_header_size;
            }
        }
    }

    /* Append the block to the temporary buffer */
    if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
    {
        size_t  i_buffer_size = p_sys->i_buffer + p_block->i_buffer;
        uint8_t *p_buffer     = realloc( p_sys->p_buffer, i_buffer_size );
        if( p_buffer )
        {
            p_sys->i_buffer_size = i_buffer_size;
            p_sys->p_buffer      = p_buffer;
        }
        else
        {
            p_block->i_buffer = 0;
        }
    }

    if( p_block->i_buffer > 0 )
    {
        memcpy( &p_sys->p_buffer[p_sys->i_buffer],
                     p_block->p_buffer, p_block->i_buffer );
        p_sys->i_buffer += p_block->i_buffer;
        p_block->i_buffer = 0;
    }

    if( p_dec->fmt_out.audio.i_rate == 0 && p_dec->fmt_in.i_extra > 0 )
    {
        /* We have a decoder config so init the handle */
        unsigned long i_rate;
        unsigned char i_channels;

        if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
                          p_dec->fmt_in.i_extra,
                          &i_rate, &i_channels ) >= 0 )
        {
            p_dec->fmt_out.audio.i_rate = i_rate;
            p_dec->fmt_out.audio.i_channels = i_channels;
            p_dec->fmt_out.audio.i_physical_channels
                = p_dec->fmt_out.audio.i_original_channels
                = pi_channels_guessed[i_channels];

            date_Init( &p_sys->date, i_rate, 1 );
        }
    }

    if( p_dec->fmt_out.audio.i_rate == 0 && p_sys->i_buffer )
    {
        unsigned long i_rate;
        unsigned char i_channels;

        /* Init faad with the first frame */
        if( faacDecInit( p_sys->hfaad,
                         p_sys->p_buffer, p_sys->i_buffer,
                         &i_rate, &i_channels ) < 0 )
        {
            block_Release( p_block );
            return NULL;
        }

        p_dec->fmt_out.audio.i_rate = i_rate;
        p_dec->fmt_out.audio.i_channels = i_channels;
        p_dec->fmt_out.audio.i_physical_channels
            = p_dec->fmt_out.audio.i_original_channels
            = pi_channels_guessed[i_channels];
        date_Init( &p_sys->date, i_rate, 1 );
    }

    if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != date_Get( &p_sys->date ) )
    {
        date_Set( &p_sys->date, p_block->i_pts );
    }
    else if( !date_Get( &p_sys->date ) )
    {
        /* We've just started the stream, wait for the first PTS. */
        block_Release( p_block );
        p_sys->i_buffer = 0;
        return NULL;
    }

    /* Decode all data */
    if( p_sys->i_buffer )
    {
        void *samples;
        faacDecFrameInfo frame;
        block_t *p_out;

        samples = faacDecDecode( p_sys->hfaad, &frame,
                                 p_sys->p_buffer, p_sys->i_buffer );

        if( frame.error > 0 )
        {
            msg_Warn( p_dec, "%s", faacDecGetErrorMessage( frame.error ) );

            if( frame.error == 21 || frame.error == 12 )
            {
                /*
                 * Once an "Unexpected channel configuration change"
                 * or a "Invalid number of channels" error
                 * occurs, it will occurs afterwards, and we got no sound.
                 * Reinitialization of the decoder is required.
                 */
                unsigned long i_rate;
                unsigned char i_channels;
                faacDecHandle *hfaad;
                faacDecConfiguration *cfg,*oldcfg;

                oldcfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
                hfaad = faacDecOpen();
                cfg = faacDecGetCurrentConfiguration( hfaad );
                if( oldcfg->defSampleRate )
                    cfg->defSampleRate = oldcfg->defSampleRate;
                cfg->defObjectType = oldcfg->defObjectType;
                cfg->outputFormat = oldcfg->outputFormat;
                faacDecSetConfiguration( hfaad, cfg );

                if( faacDecInit( hfaad, p_sys->p_buffer, p_sys->i_buffer,
                                &i_rate,&i_channels ) < 0 )
                {
                    /* reinitialization failed */
                    faacDecClose( hfaad );
                    faacDecSetConfiguration( p_sys->hfaad, oldcfg );
                }
                else
                {
                    faacDecClose( p_sys->hfaad );
                    p_sys->hfaad = hfaad;
                    p_dec->fmt_out.audio.i_rate = i_rate;
                    p_dec->fmt_out.audio.i_channels = i_channels;
                    p_dec->fmt_out.audio.i_physical_channels
                        = p_dec->fmt_out.audio.i_original_channels
                        = pi_channels_guessed[i_channels];
                    date_Init( &p_sys->date, i_rate, 1 );
                }
            }

            /* Flush the buffer */
            p_sys->i_buffer = 0;
            block_Release( p_block );
            return NULL;
        }

        if( frame.channels <= 0 || frame.channels > 8 || frame.channels == 7 )
        {
            msg_Warn( p_dec, "invalid channels count: %i", frame.channels );

            /* Flush the buffer */
            p_sys->i_buffer -= frame.bytesconsumed;
            if( p_sys->i_buffer > 0 )
            {
                memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed],
                         p_sys->i_buffer );
            }
            block_Release( p_block );
            return NULL;
        }

        if( frame.samples <= 0 )
        {
            msg_Warn( p_dec, "decoded zero sample" );

            /* Flush the buffer */
            p_sys->i_buffer -= frame.bytesconsumed;
            if( p_sys->i_buffer > 0 )
            {
                memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed],
                         p_sys->i_buffer );
            }
            block_Release( p_block );
            return NULL;
        }

        /* We decoded a valid frame */
        if( p_dec->fmt_out.audio.i_rate != frame.samplerate )
        {
            date_Init( &p_sys->date, frame.samplerate, 1 );
            date_Set( &p_sys->date, p_block->i_pts );
        }
        p_block->i_pts = VLC_TS_INVALID;  /* PTS is valid only once */

        p_dec->fmt_out.audio.i_rate = frame.samplerate;
        p_dec->fmt_out.audio.i_channels = frame.channels;

        /* Adjust stream info when dealing with SBR/PS */
        bool b_sbr = (frame.sbr == 1) || (frame.sbr == 2);
        if( p_sys->b_sbr != b_sbr || p_sys->b_ps != frame.ps )
        {
            const char *psz_ext = (b_sbr && frame.ps) ? "SBR+PS" :
                                    b_sbr ? "SBR" : "PS";

            msg_Dbg( p_dec, "AAC %s (channels: %u, samplerate: %lu)",
                    psz_ext, frame.channels, frame.samplerate );

            if( !p_dec->p_description )
                p_dec->p_description = vlc_meta_New();
            if( p_dec->p_description )
                vlc_meta_AddExtra( p_dec->p_description, _("AAC extension"), psz_ext );

            p_sys->b_sbr = b_sbr;
            p_sys->b_ps = frame.ps;
        }

        /* Convert frame.channel_position to our own channel values */
        p_dec->fmt_out.audio.i_physical_channels = 0;
        const uint32_t nbChannels = frame.channels;
        unsigned j;
        for( unsigned i = 0; i < nbChannels; i++ )
        {
            /* Find the channel code */
            for( j = 0; j < MAX_CHANNEL_POSITIONS; j++ )
            {
                if( frame.channel_position[i] == pi_channels_in[j] )
                    break;
            }
            if( j >= MAX_CHANNEL_POSITIONS )
            {
                msg_Warn( p_dec, "unknown channel ordering" );
                /* Invent something */
                j = i;
            }
            /* */
            p_sys->pi_channel_positions[i] = pi_channels_out[j];
            if( p_dec->fmt_out.audio.i_physical_channels & pi_channels_out[j] )
                frame.channels--; /* We loose a duplicated channel */
            else
                p_dec->fmt_out.audio.i_physical_channels |= pi_channels_out[j];
        }
        if ( nbChannels != frame.channels )
        {
            p_dec->fmt_out.audio.i_physical_channels
                = p_dec->fmt_out.audio.i_original_channels
                = pi_channels_guessed[nbChannels];
        }
        else
        {
            p_dec->fmt_out.audio.i_original_channels =
                p_dec->fmt_out.audio.i_physical_channels;
        }
        p_dec->fmt_out.audio.i_channels = nbChannels;
        p_out = decoder_NewAudioBuffer( p_dec, frame.samples / nbChannels );
        if( p_out == NULL )
        {
            p_sys->i_buffer = 0;
            block_Release( p_block );
            return NULL;
        }

        p_out->i_pts = date_Get( &p_sys->date );
        p_out->i_length = date_Increment( &p_sys->date,
                                          frame.samples / nbChannels )
                          - p_out->i_pts;

        DoReordering( (uint32_t *)p_out->p_buffer, samples,
                      frame.samples / nbChannels, nbChannels,
                      p_sys->pi_channel_positions );

        p_sys->i_buffer -= frame.bytesconsumed;
        if( p_sys->i_buffer > 0 )
        {
            memmove( p_sys->p_buffer, &p_sys->p_buffer[frame.bytesconsumed],
                     p_sys->i_buffer );
        }

        return p_out;
    }

    block_Release( p_block );
    return NULL;
}
Пример #28
0
int fdpl_decode_MP4(const char *file_path, size_t &ch, size_t &sr,  size_t &samples, std::vector<float> *ch1, std::vector<float> *ch2)
{
    unsigned int track;
    uint32_t samplerate;//these for init, we prefer to take the ones at frameInfo
    unsigned char channels;
    void *sample_buffer;

    mp4ff_t *infile;
    FILE *mp4File;
    int sampleId, numSamples;

    faacDecHandle hDecoder;
    faacDecFrameInfo frameInfo;

    unsigned char *buffer;
    unsigned int buffer_size;

    /* initialise the callback structure */
    mp4ff_callback_t *mp4cb;
    mp4cb = (mp4ff_callback_t *)malloc(sizeof(mp4ff_callback_t));

    mp4File = fopen(file_path, "rb");
    mp4cb->read = read_callback;
    mp4cb->seek = seek_callback;
    mp4cb->user_data = mp4File;

    infile = mp4ff_open_read(mp4cb);
    if (!infile)
    {
        /* unable to open file */
        std::cerr<<"Error opening file "<< file_path <<std::endl;
        return 1;
    }

    if ((track = GetAACTrack(infile)) < 0)
    {
        std::cerr<<"Unable to find correct AAC sound track in the MP4 file"<<std::endl;
        mp4ff_close(infile);
        free(mp4cb);
        fclose(mp4File);
        return 1;
    }

    buffer = NULL;
    buffer_size = 0;
    mp4ff_get_decoder_config(infile, track, &buffer, &buffer_size);

    hDecoder = faacDecOpen();

    if(faacDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0)
    {
        /* If some error initializing occured, skip the file */
      	std::cerr<<"Error initializing decoder library"<<std::endl;
        faacDecClose(hDecoder);
        mp4ff_close(infile);
        free(mp4cb);
        fclose(mp4File);
        return 1;
    }
    if (buffer)
        free(buffer);

    numSamples = mp4ff_num_samples(infile, track);

    samples = 0;
    //firstTime = 1;

    for (sampleId = 0; sampleId < numSamples; sampleId++)
    {
        int rc;

        /* get access unit from MP4 file */
        buffer = NULL;
        buffer_size = 0;

        rc = mp4ff_read_sample(infile, track, sampleId, &buffer, &buffer_size);
        if (rc == 0)
        {
            std::cerr<<"error while decoding"<<std::endl;
            faacDecClose(hDecoder);
            mp4ff_close(infile);
            free(mp4cb);
            fclose(mp4File);
            return 1;
        }

        sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size);

        if (buffer)
            free(buffer);

        if ((frameInfo.error == 0) && (frameInfo.samples > 0) && (frameInfo.channels < 3))
        {
		size_t samples_channel = (size_t)frameInfo.samples/(size_t)frameInfo.channels;
       		samples += samples_channel;
		float *pcm;		
		pcm = (float *)sample_buffer;
		for(size_t i=0; i<samples_channel; i++){
		//writing the samples of each channel in separate float vectors
			for(size_t j=0; j<frameInfo.channels; j++){
			          		
				if(j==0){
					ch1 -> push_back(pcm[i*frameInfo.channels+j]);

				}else if(j==1){
					ch2 -> push_back(pcm[i*frameInfo.channels+j]);

				}else{
					std::cerr<<"Unexpected number of channels: "<<j<<std::endl;
					return -1;
				}
			}
		}		
        }
		
        if (frameInfo.error > 0)
        {
            std::cerr<<"error: "<<faacDecGetErrorMessage(frameInfo.error)<<std::endl;
            break;
        }
        
    }
    ch = frameInfo.channels;
    sr = frameInfo.samplerate; 
 
    faacDecClose(hDecoder);

    mp4ff_close(infile);
    free(mp4cb);
    fclose(mp4File);

    return frameInfo.error;
}