Ejemplo n.º 1
0
int play_memmap(char *fn)
{
    int tagsize = 0;

    infile = open_filestream(fn);
    
	if (infile == NULL)
        return 1;

    fileread = filelength_filestream(infile);

    memmap_buffer = (char*)LocalAlloc(LPTR, fileread);
    read_buffer_filestream(infile, memmap_buffer, fileread);

    /* skip id3v2 tag */
    memmap_index = id3v2_tag(memmap_buffer);

    hDecoder = faacDecOpen();

	/* Copy the configuration dialog setting and use it as the default */
	/* initialize the decoder, and get samplerate and channel info */

    if ((buffercount = faacDecInit(hDecoder, memmap_buffer + memmap_index,
        fileread - memmap_index - 1, &samplerate, &channels)) < 0)
    {
		MessageBox(mod.hMainWindow, "Error opening input file\n", "FAAD Error", MB_OK);
		return 1;
    }

    memmap_index += buffercount;

    PlayThread_memmap();

    return 0;
}
Ejemplo n.º 2
0
int AacPcm::getInfos(MediaInfo *infos)
{
DWORD	tmp;

    infos->setTitle(Std::filename(infos->getFilename()));

	if(hDecoder)
	    infos->setInfo(StringPrintf("%ihz %ibps %ich", dwSamprate, 16, dwChannels));
	else
	{
	svc_fileReader *reader = infos->getReader();
		if (!reader)
			ERROR_getInfos("File doesn\'t exists")

	    buffer=new BYTE[AAC_BUF_SIZE];
		if(!buffer)
			ERROR_getInfos("Error: buffer=NULL")

		lSize=reader->getLength();
		if(lSize>AAC_BUF_SIZE)
			tmp=AAC_BUF_SIZE;
		else
			tmp=lSize;

		bytes_into_buffer=bytes_read=reader->read((char *)buffer, tmp);
		if(bytes_read!=tmp)
			ERROR_getInfos("Read failed!")

	    hDecoder = faacDecOpen();

	faacDecConfigurationPtr config;
		config = faacDecGetCurrentConfiguration(hDecoder);
		config->defSampleRate = 44100;
		faacDecSetConfiguration(hDecoder, config);

		if((bytes_consumed=faacDecInit(hDecoder, buffer, &dwSamprate, &dwChannels))<0)
			ERROR_getInfos("faacDecInit failed!")
		else
		    infos->setInfo(StringPrintf("%ihz %ibps %ich", dwSamprate, 16, dwChannels));

		bytes_into_buffer-=bytes_consumed;

		bufout=new short[1024*dwChannels];
		if(!bufout)
			ERROR_getInfos("Error: bufout=NULL")

//		fil=fopen("c:\\prova.wav","wb");
	}

    return 0;
}
Ejemplo n.º 3
0
bool faad_decoder::initialize(unsigned int const frequency)
{
    close();

    long ret;

    faad_handle = faacDecOpen();

    faacDecConfigurationPtr conf = faacDecGetCurrentConfiguration(*faad_handle);
    conf->defSampleRate = frequency;
    conf->outputFormat = FAAD_FMT_16BIT;
    faacDecSetConfiguration(*faad_handle, conf);

    unsigned long sample_rate;
    unsigned char channels;

    source_->reset();
    in_buffer.resize(32768);
    long num_read_bytes = source_->read(&in_buffer[0], 32768);
    if (num_read_bytes <= 0)
        return false;
    in_buffer.resize(num_read_bytes);

    ret = faacDecInit(*faad_handle, &in_buffer[0], in_buffer.size(), &sample_rate, &channels);
    if (ret < 0)
    {
        std::cerr << "faacDecInit failed" << std::endl;
        close();
        return false;
    }
    else
    {
        decoder_sample_rate = sample_rate;
        if (ret > 0)
        {
            std::memmove(&in_buffer[0], &in_buffer[ret], in_buffer.size() - ret);
            in_buffer.resize(in_buffer.size() - ret);
        }
        return true;
    }
}
Ejemplo n.º 4
0
/// ±àÂë
int32_t CAacDecoder::Decodec(const char* pSrcBuffer, uint32_t nSrcBuffSize,
                             char* pDestBuffer, uint32_t nDestBufferSize)
{
    int32_t nResult = 0;

    if(NULL != m_hHandleDecoder)
    {
        if(!m_bIsInitDec)
        {
            unsigned long nSamplesRate = 0;
            unsigned char nChannel = 0;

            faacDecInit(m_hHandleDecoder, (unsigned char*)pSrcBuffer, nSrcBuffSize,
                        &nSamplesRate, &nChannel);

            m_bIsInitDec = TRUE;
        }

        if(m_bIsInitDec)
        {
            char* pSampleBuffer = (char*)NeAACDecDecode2(m_hHandleDecoder, &m_aacFrameInfo,
                                  (unsigned char*)pSrcBuffer, nSrcBuffSize, (void**)&pDestBuffer, nDestBufferSize);

            if(NULL != pSampleBuffer
                    && m_aacFrameInfo.error == 0
                    && m_aacFrameInfo.samples > 0)
            {
                nResult = m_aacFrameInfo.samples * m_aacFrameInfo.channels;
                if(nResult > nDestBufferSize)
                {
                    nResult = 0;
                }
            }
        }
    }

    return nResult;
}
Ejemplo n.º 5
0
Archivo: faad.c Proyecto: cmjonze/faad
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;
}
Ejemplo n.º 6
0
int AacPcm::getInfos(MediaInfo *infos)
{
	if(!infos)
		return 1;

	if(hDecoder)
	{
		SHOW_INFO()
	    return 0;
	}

	IsAAC=strcmpi(infos->getFilename()+lstrlen(infos->getFilename())-4,".aac")==0;

	if(!IsAAC) // MP4 file ---------------------------------------------------------------------
	{
	MP4Duration			length;
	unsigned __int32	buffer_size;
    mp4AudioSpecificConfig mp4ASC;

		if(!(mp4File=MP4Read(infos->getFilename(), 0)))
			ERROR_getInfos("Error opening file");

		if((track=GetAACTrack(mp4File))<0)
			ERROR_getInfos(0); //"Unable to find correct AAC sound track");

		if(!(hDecoder=faacDecOpen()))
			ERROR_getInfos("Error initializing decoder library");

		MP4GetTrackESConfiguration(mp4File, track, (unsigned __int8 **)&buffer, &buffer_size);
		if(!buffer)
			ERROR_getInfos("MP4GetTrackESConfiguration");
		AudioSpecificConfig(buffer, buffer_size, &mp4ASC);
        Channels=mp4ASC.channelsConfiguration;

		if(faacDecInit2(hDecoder, buffer, buffer_size, &Samplerate, &Channels) < 0)
			ERROR_getInfos("Error initializing decoder library");
		FREE_ARRAY(buffer);

		length=MP4GetTrackDuration(mp4File, track);
		len_ms=(DWORD)MP4ConvertFromTrackDuration(mp4File, track, length, MP4_MSECS_TIME_SCALE);
		file_info.bitrate=MP4GetTrackBitRate(mp4File, track);
		file_info.version=MP4GetTrackAudioType(mp4File, track)==MP4_MPEG4_AUDIO_TYPE ? 4 : 2;
		numSamples=MP4GetTrackNumberOfSamples(mp4File, track);
		sampleId=1;
	}
	else // AAC file ------------------------------------------------------------------------------
	{   
	DWORD			read,
					tmp;
	BYTE			Channels4Raw=0;

		if(!(aacFile=fopen(infos->getFilename(),"rb")))
			ERROR_getInfos("Error opening file"); 

		// use bufferized stream
		setvbuf(aacFile,NULL,_IOFBF,32767);

		// get size of file
		fseek(aacFile, 0, SEEK_END);
		src_size=ftell(aacFile);
		fseek(aacFile, 0, SEEK_SET);

		if(!(buffer=(BYTE *)malloc(FAAD_STREAMSIZE)))
			ERROR_getInfos("Memory allocation error: buffer")

		tmp=src_size<FAAD_STREAMSIZE ? src_size : FAAD_STREAMSIZE;
		read=fread(buffer, 1, tmp, aacFile);
		if(read==tmp)
		{
			bytes_read=read;
			bytes_into_buffer=read;
		}
		else
			ERROR_getInfos("Read failed!")

		if(tagsize=id3v2_tag(buffer))
		{
			if(tagsize>(long)src_size)
				ERROR_getInfos("Corrupt stream!");
			if(tagsize<bytes_into_buffer)
			{
				bytes_into_buffer-=tagsize;
				memcpy(buffer,buffer+tagsize,bytes_into_buffer);
			}
			else
			{
				bytes_read=tagsize;
				bytes_into_buffer=0;
				if(tagsize>bytes_into_buffer)
					fseek(aacFile, tagsize, SEEK_SET);
			}
			if(src_size<bytes_read+FAAD_STREAMSIZE-bytes_into_buffer)
				tmp=src_size-bytes_read;
			else
				tmp=FAAD_STREAMSIZE-bytes_into_buffer;
			read=fread(buffer+bytes_into_buffer, 1, tmp, aacFile);
			if(read==tmp)
			{
				bytes_read+=read;
				bytes_into_buffer+=read;
			}
			else
				ERROR_getInfos("Read failed!");
		}

		if(get_AAC_format((char *)infos->getFilename(), &file_info, &seek_table, &seek_table_length, 0))
			ERROR_getInfos("get_AAC_format");
		IsSeekable=file_info.headertype==ADTS && seek_table && seek_table_length>0;
		BlockSeeking=!IsSeekable;

		if(!(hDecoder=faacDecOpen()))
			ERROR_getInfos("Can't open library");

		if(file_info.headertype==RAW)
		{
		faacDecConfiguration	config;

			config.defSampleRate=atoi(cfg_samplerate);
			switch(cfg_profile[1])
			{
			case 'a':
				config.defObjectType=MAIN;
				break;
			case 'o':
				config.defObjectType=LOW;
				break;
			case 'S':
				config.defObjectType=SSR;
				break;
			case 'T':
				config.defObjectType=LTP;
				break;
			}
			switch(cfg_bps[0])
			{
			case '1':
				config.outputFormat=FAAD_FMT_16BIT;
				break;
			case '2':
				config.outputFormat=FAAD_FMT_24BIT;
				break;
			case '3':
				config.outputFormat=FAAD_FMT_32BIT;
				break;
			case 'F':
				config.outputFormat=FAAD_FMT_24BIT;
				break;
			}
			faacDecSetConfiguration(hDecoder, &config);

			if(!FindBitrate)
			{
			AacPcm *NewInst;
				if(!(NewInst=new AacPcm()))
					ERROR_getInfos("Memory allocation error: NewInst");

				NewInst->FindBitrate=TRUE;
				if(NewInst->getInfos(infos))
					ERROR_getInfos(0);
				Channels4Raw=NewInst->frameInfo.channels;
				file_info.bitrate=NewInst->file_info.bitrate*Channels4Raw;
				delete NewInst;
			}
			else
			{
			DWORD	Samples,
					BytesConsumed;

				if((bytes_consumed=faacDecInit(hDecoder,buffer,bytes_into_buffer,&Samplerate,&Channels))<0)
					ERROR_getInfos("Can't init library");
				bytes_into_buffer-=bytes_consumed;
				if(!processData(infos,0,0))
					ERROR_getInfos(0);
				Samples=frameInfo.samples/sizeof(short);
				BytesConsumed=frameInfo.bytesconsumed;
				processData(infos,0,0);
				if(BytesConsumed<frameInfo.bytesconsumed)
					BytesConsumed=frameInfo.bytesconsumed;
				file_info.bitrate=(BytesConsumed*8*Samplerate)/Samples;
				if(!file_info.bitrate)
					file_info.bitrate=1000; // try to continue decoding
				return 0;
			}
		}

		if((bytes_consumed=faacDecInit(hDecoder, buffer, bytes_into_buffer, &Samplerate, &Channels))<0)
			ERROR_getInfos("faacDecInit failed!")
		bytes_into_buffer-=bytes_consumed;

		if(Channels4Raw)
			Channels=Channels4Raw;

		len_ms=(DWORD)((1000*((float)src_size*8))/file_info.bitrate);
	}

	SHOW_INFO();
    return 0;
}
Ejemplo n.º 7
0
Archivo: faad.c Proyecto: abhi1302/vlc
/*****************************************************************************
 * 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;
}
Ejemplo n.º 8
0
/*
 * Decode task call for FAAC
 */
static int aac_decode (codec_data_t *ptr,
               uint64_t ts,
               int from_rtp,
               int *sync_frame,
               uint8_t *buffer,
               uint32_t buflen,
               void *userdata)
{
  aac_codec_t *aac = (aac_codec_t *)ptr;
  unsigned long bytes_consummed;
  int bits = -1;
  //  struct timezone tz;

  if (aac->m_record_sync_time) {
    aac->m_current_frame = 0;
    aac->m_record_sync_time = 0;
    aac->m_current_time = ts;
    aac->m_last_rtp_ts = ts;
  } else {
    if (aac->m_last_rtp_ts == ts) {
      aac->m_current_time += aac->m_msec_per_frame;
      aac->m_current_frame++;
    } else {
      aac->m_last_rtp_ts = ts;
      aac->m_current_time = ts;
      aac->m_current_frame = 0;
    }

    // Note - here m_current_time should pretty much always be >= rtpts.
    // If we're not, we most likely want to stop and resync.  We don't
    // need to keep decoding - just decode this frame and indicate we
    // need a resync... That should handle fast forwards...  We need
    // someway to handle reverses - perhaps if we're more than .5 seconds
    // later...
  }

  if (aac->m_faad_inited == 0) {
    /*
     * If not initialized, do so.
     */
    abort();
    unsigned long freq;
    unsigned char chans;

    faacDecInit(aac->m_info,
        (unsigned char *)buffer,
        buflen,
        &freq,
        &chans);
    aac->m_freq = freq;
    aac->m_chans = chans;
    aac->m_faad_inited = 1;
  }

  uint8_t *buff;
  unsigned long samples;
  bytes_consummed = buflen;
  //aa_message(LOG_DEBUG, aaclib, "decoding %d bits", buflen * 8);
  faacDecFrameInfo frame_info;
  buff = (uint8_t *)faacDecDecode(aac->m_info,
                  &frame_info,
                  buffer,
                  buflen);
  if (buff != NULL) {
    bytes_consummed = frame_info.bytesconsumed;
#if 0
    aa_message(LOG_DEBUG, aaclib, LLU" bytes %d samples %d",
           ts, bytes_consummed, frame_info.samples);
#endif
    if (aac->m_audio_inited != 0) {
      int tempchans = frame_info.channels;
      if (tempchans != aac->m_chans) {
    aa_message(LOG_NOTICE, aaclib, "chupdate - chans from data is %d",
           tempchans);
      }
    } else {
      int tempchans = frame_info.channels;

      if (tempchans == 0) {
    aa_message(LOG_ERR, aaclib, "initializing aac, returned channels are 0");
    aac->m_resync_with_header = 1;
    aac->m_record_sync_time = 1;
    return bytes_consummed;
      }
      aac->m_chans = tempchans;
      aac->m_freq = frame_info.samplerate;

      aac->m_vft->audio_configure(aac->m_ifptr,
                  aac->m_freq,
                  aac->m_chans,
                  AUDIO_S16SYS,
                  aac->m_output_frame_size);
      uint8_t *now = aac->m_vft->audio_get_buffer(aac->m_ifptr);
      aac->m_audio_inited = 1;
    }
    /*
     * good result - give it to audio sync class
     */
#if DUMP_OUTPUT_TO_FILE
    fwrite(buff, aac->m_output_frame_size * 4, 1, aac->m_outfile);
#endif
    if (frame_info.samples != 0) {
      aac->m_vft->audio_load_buffer(aac->m_ifptr,
                    buff,
                    frame_info.samples * 2,
                    aac->m_last_ts,
                    aac->m_resync_with_header);
      if (aac->m_resync_with_header == 1) {
    aac->m_resync_with_header = 0;
#ifdef DEBUG_SYNC
    aa_message(LOG_DEBUG, aaclib, "Back to good at "LLU, aac->m_current_time);
#endif
      }
    }
  } else {
    aa_message(LOG_ERR, aaclib, "error return is %d", frame_info.error);
    aac->m_resync_with_header = 1;
#ifdef DEBUG_SYNC
    aa_message(LOG_ERR, aaclib, "Audio decode problem - at "LLU,
           aac->m_current_time);
#endif
  }
  aac->m_last_ts = aac->m_current_time;
  return (bytes_consummed);
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
static gboolean
xmms_faad_init (xmms_xform_t *xform)
{
	xmms_faad_data_t *data;
	xmms_error_t error;

	faacDecConfigurationPtr config;
	gint bytes_read;
	guint32 samplerate;
	guchar channels;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_faad_data_t, 1);
	data->outbuf = g_string_new (NULL);
	data->buffer_size = FAAD_BUFFER_SIZE;

	xmms_xform_private_data_set (xform, data);

	data->decoder = faacDecOpen ();
	config = faacDecGetCurrentConfiguration (data->decoder);
	config->defObjectType = LC;
	config->defSampleRate = 44100;
	config->outputFormat = FAAD_FMT_16BIT;
	config->downMatrix = 0;
	config->dontUpSampleImplicitSBR = 0;
	faacDecSetConfiguration (data->decoder, config);

	switch (config->outputFormat) {
	case FAAD_FMT_16BIT:
		data->sampleformat = XMMS_SAMPLE_FORMAT_S16;
		break;
	case FAAD_FMT_24BIT:
		/* we don't have 24-bit format to use in xmms2 */
		data->sampleformat = XMMS_SAMPLE_FORMAT_S32;
		break;
	case FAAD_FMT_32BIT:
		data->sampleformat = XMMS_SAMPLE_FORMAT_S32;
		break;
	case FAAD_FMT_FLOAT:
		data->sampleformat = XMMS_SAMPLE_FORMAT_FLOAT;
		break;
	case FAAD_FMT_DOUBLE:
		data->sampleformat = XMMS_SAMPLE_FORMAT_DOUBLE;
		break;
	}

	while (data->buffer_length < 8) {
		xmms_error_reset (&error);
		bytes_read = xmms_xform_read (xform,
		                              (gchar *) data->buffer + data->buffer_length,
		                              data->buffer_size - data->buffer_length,
		                              &error);
		data->buffer_length += bytes_read;

		if (bytes_read < 0) {
			xmms_log_error ("Error while trying to read data on init");
			goto err;
		} else if (bytes_read == 0) {
			XMMS_DBG ("Not enough bytes to check the AAC header");
			goto err;
		}
	}

	/* which type of file are we dealing with? */
	data->filetype = FAAD_TYPE_UNKNOWN;
	if (xmms_xform_auxdata_has_val (xform, "decoder_config")) {
		data->filetype = FAAD_TYPE_MP4;
	} else if (!strncmp ((char *) data->buffer, "ADIF", 4)) {
		data->filetype = FAAD_TYPE_ADIF;
	} else {
		int i;

		/* ADTS mpeg file can be a stream and start in the middle of a
		 * frame so we need to have extra loop check here */
		for (i=0; i<data->buffer_length-1; i++) {
			if (data->buffer[i] == 0xff && (data->buffer[i+1]&0xf6) == 0xf0) {
				data->filetype = FAAD_TYPE_ADTS;
				g_memmove (data->buffer, data->buffer+i, data->buffer_length-i);
				data->buffer_length -= i;
				break;
			}
		}
	}

	if (data->filetype == FAAD_TYPE_ADTS || data->filetype == FAAD_TYPE_ADIF) {
		bytes_read = faacDecInit (data->decoder, data->buffer,
		                          data->buffer_length, &samplerate,
		                          &channels);
	} else if (data->filetype == FAAD_TYPE_MP4) {
		const guchar *tmpbuf;
		gssize tmpbuflen;
		guchar *copy;

		if (!xmms_xform_auxdata_get_bin (xform, "decoder_config", &tmpbuf,
		                                 &tmpbuflen)) {
			XMMS_DBG ("AAC decoder config data found but it's wrong type! (something broken?)");
			goto err;
		}

		copy = g_memdup (tmpbuf, tmpbuflen);
		bytes_read = faacDecInit2 (data->decoder, copy, tmpbuflen,
		                           &samplerate, &channels);
		g_free (copy);
	}

	if (bytes_read < 0) {
		XMMS_DBG ("Error initializing decoder library.");
		goto err;
	}

	/* Get mediainfo and skip the possible header */
	xmms_faad_get_mediainfo (xform);
	g_memmove (data->buffer, data->buffer + bytes_read,
	           data->buffer_length - bytes_read);
	data->buffer_length -= bytes_read;

	data->samplerate = samplerate;
	data->channels = channels;

	/* Because for HE AAC files some versions of libfaad return the wrong
	 * samplerate in init, we have to do one read and let it decide the
	 * real parameters. After changing sample parameters and format is
	 * supported, this hack should be removed and handled in read instead. */
	{
		gchar tmpbuf[1024];

		xmms_error_reset (&error);
		bytes_read = xmms_faad_read (xform, tmpbuf, 1024, &error);
		if (bytes_read <= 0) {
			XMMS_DBG ("First read from faad decoder failed!");
			return FALSE;
		}
		g_string_prepend_len (data->outbuf, tmpbuf, bytes_read);
	}

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             data->sampleformat,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             data->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             data->samplerate,
	                             XMMS_STREAM_TYPE_END);

	XMMS_DBG ("AAC decoder inited successfully!");

	return TRUE;

err:
	g_string_free (data->outbuf, TRUE);
	g_free (data);

	return FALSE;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
/*
 * Decode task call for FAAC
 */
static int aac_decode (codec_data_t *ptr,
		       frame_timestamp_t *ts,
		       int from_rtp,
		       int *sync_frame,
		       uint8_t *buffer,
		       uint32_t buflen, 
		       void *userdata)
{
  aac_codec_t *aac = (aac_codec_t *)ptr;
  unsigned long bytes_consummed;
  int bits = -1;
  //  struct timezone tz;
  uint32_t freq_timestamp;

  freq_timestamp = ts->audio_freq_timestamp;
  if (ts->audio_freq != aac->m_freq) {
    freq_timestamp = convert_timescale(freq_timestamp,
				       ts->audio_freq,
				       aac->m_freq);
  }
  if (aac->m_record_sync_time) {
    aac->m_current_frame = 0;
    aac->m_record_sync_time = 0;
    aac->m_current_time = ts->msec_timestamp;
    aac->m_last_rtp_ts = ts->msec_timestamp;
  } else {
    if (aac->m_last_rtp_ts == ts->msec_timestamp) {
      aac->m_current_frame++;
      aac->m_current_time = aac->m_last_rtp_ts;
      aac->m_current_time += 
	aac->m_output_frame_size * aac->m_current_frame * 
	TO_U64(1000) / aac->m_freq;
      freq_timestamp += aac->m_output_frame_size * aac->m_current_frame;
    } else {
      aac->m_last_rtp_ts = ts->msec_timestamp;
      aac->m_current_time = ts->msec_timestamp;
      aac->m_current_frame = 0;
    }

    // Note - here m_current_time should pretty much always be >= rtpts.  
    // If we're not, we most likely want to stop and resync.  We don't
    // need to keep decoding - just decode this frame and indicate we
    // need a resync... That should handle fast forwards...  We need
    // someway to handle reverses - perhaps if we're more than .5 seconds
    // later...
  }

    if (aac->m_faad_inited == 0) {
      /*
       * If not initialized, do so.  
     */
      unsigned long freq, chans;

      faacDecInit(aac->m_info,
		  (unsigned char *)buffer,
		  &freq,
		  &chans);
      aac->m_freq = freq;
      aac->m_chans = chans;
      aac->m_faad_inited = 1;
    }

    uint8_t *buff;

    /* 
     * Get an audio buffer
     */
    if (aac->m_audio_inited == 0) {
      buff = aac->m_temp_buff;
    } else {
      buff = aac->m_vft->audio_get_buffer(aac->m_ifptr,
					  freq_timestamp,
					  aac->m_current_time);
    }
    if (buff == NULL) {
      //player_debug_message("Can't get buffer in aa");
      return (0);
    }

    unsigned long samples;
    bytes_consummed = buflen;
    //aa_message(LOG_DEBUG, aaclib, "decoding %d bits", buflen * 8);
    bits = faacDecDecode(aac->m_info,
			 (unsigned char *)buffer, 
			 &bytes_consummed,
			 (short *)buff, 
			 &samples);
    switch (bits) {
    case FAAD_OK_CHUPDATE:
      if (aac->m_audio_inited != 0) {
	int tempchans = faacDecGetProgConfig(aac->m_info, NULL);
	if (tempchans != aac->m_chans) {
	  aa_message(LOG_NOTICE, aaclib, "chupdate - chans from data is %d", 
			       tempchans);
	}
      }
      // fall through...
    case FAAD_OK:
      if (aac->m_audio_inited == 0) {
	int tempchans = faacDecGetProgConfig(aac->m_info, NULL);
	if (tempchans == 0) {
	  aac->m_resync_with_header = 1;
	  aac->m_record_sync_time = 1;
	  return bytes_consummed;
	}
	if (tempchans != aac->m_chans) {
	  aa_message(LOG_NOTICE, aaclib, "chans from data is %d conf %d", 
		     tempchans, aac->m_chans);
	  aac->m_chans = tempchans;
	}
	aac->m_vft->audio_configure(aac->m_ifptr,
				     aac->m_freq, 
				     aac->m_chans, 
				     AUDIO_FMT_S16, 
				     aac->m_output_frame_size);
	uint8_t *now = aac->m_vft->audio_get_buffer(aac->m_ifptr,
						    freq_timestamp,
						    aac->m_current_time);

	if (now != NULL) {
	  memcpy(now, buff, tempchans * aac->m_output_frame_size * sizeof(int16_t));
	}
	aac->m_audio_inited = 1;
      }
      /*
       * good result - give it to audio sync class
       */
#if DUMP_OUTPUT_TO_FILE
      fwrite(buff, aac->m_output_frame_size * 4, 1, aac->m_outfile);
#endif
      aac->m_vft->audio_filled_buffer(aac->m_ifptr);
      if (aac->m_resync_with_header == 1) {
	aac->m_resync_with_header = 0;
#ifdef DEBUG_SYNC
	aa_message(LOG_DEBUG, aaclib, "Back to good at "U64, aac->m_current_time);
#endif
      }
      break;
    default:
      aa_message(LOG_ERR, aaclib, "Bits return is %d", bits);
      aac->m_resync_with_header = 1;
#ifdef DEBUG_SYNC
      aa_message(LOG_ERR, aaclib, "Audio decode problem - at "U64, 
		 aac->m_current_time);
#endif
      break;
    }
  return (bytes_consummed);
}
Ejemplo n.º 13
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);
    
  }
}
Ejemplo n.º 14
0
uint8_t ADM_faad::run(uint8_t *inptr, uint32_t nbIn, float *outptr, uint32_t *nbOut)
{
uint32_t xin;
long int res;
void *outbuf;
faacDecFrameInfo info;
int max=0;
#ifdef OLD_FAAD_PROTO
unsigned long int srate;
#else
uint32_t srate;
#endif
unsigned char chan=0;
uint8_t first=0;


		ADM_assert(_instance);
		*nbOut=0;
		if(!_inited) // we still have'nt initialized the codec
		{
			// Try
			printf("Trying with %d bytes\n",nbIn);
			res=faacDecInit(_instance,inptr,nbIn,&srate,&chan);
			if(res>=0)
			{
				printf("Faad Inited : rate:%d chan:%d off:%ld\n",srate,chan,res);
				_inited=1;
				first=1;
				_inbuffer=0;
				inptr+=res;
				nbIn-=res;
				
			}
		}
		if(!_inited)
		{
			printf("No dice...\n");
			return 1;	
		}
		// The codec is initialized, feed him
		do
		{
			max=FAAD_BUFFER-_inbuffer;
			if(nbIn<max) max=nbIn;
			memcpy(_buffer+_inbuffer,inptr,max);
			inptr+=max;
			nbIn-=max;
			_inbuffer+=max;
			/*
			if(_inbuffer<FAAD_MIN_STREAMSIZE*2)
			{
				return 1;
			}*/
			memset(&info,0,sizeof(info));
			//printf("%x %x\n",_buffer[0],_buffer[1]);
		 	outbuf = faacDecDecode(_instance, &info, _buffer, _inbuffer);
			if(info.error)
			{
				printf("Faad: Error %d :%s\n",info.error,
					faacDecGetErrorMessage(info.error));
				printf("Bye consumed %u, bytes dropped %u \n",info.bytesconsumed,_inbuffer);

                                _inbuffer=0; // Purge buffer
				return 1;
			}
			if(first)
			{
				printf("Channels : %d\n",info.channels);
				printf("Frequency: %d\n",info.samplerate);
				printf("SBR      : %d\n",info.sbr);
				
			
			}
			xin=info.bytesconsumed ;
			if(xin>_inbuffer) xin=0;
			
			memmove(_buffer,_buffer+xin,_inbuffer-xin);
			_inbuffer-=xin;
			if(info.samples)
			{
				*nbOut+= info.samples;
				int16_t *in = (int16_t *) outbuf;
				for (int i = 0; i < info.samples; i++) {
					*(outptr++) = (float)*in / 32768;
					in++;
				}
			}
		}while(nbIn);
		return 1;
}
Ejemplo n.º 15
0
uint8_t ADM_faad::run( uint8_t * ptr, uint32_t nbIn, 
                       uint8_t * outptr,   uint32_t * nbOut,ADM_ChannelMatrix *matrix)
{
long int res;
void *outbuf;
faacDecFrameInfo info;
int max=0;
#ifdef OLD_FAAD_PROTO
unsigned long int srate;
#else
uint32_t srate;
#endif
unsigned char chan=0;
uint8_t first=0;


		ADM_assert(_instance);
		*nbOut=0;
		if(!_inited) // we still have'nt initialized the codec
		{
			// Try
			printf("Trying with %d bytes\n",nbIn);
			res=faacDecInit(_instance,ptr,nbIn,&srate,&chan);
			if(res>=0)
			{
				printf("Faad Inited : rate:%d chan:%d off:%ld\n",srate,chan,res);
				_inited=1;
				first=1;
				_inbuffer=0;
				ptr+=res;
				nbIn-=res;
				
			}
		}
		if(!_inited)
		{
			printf("No dice...\n");
			return 1;	
		}
		// The codec is initialized, feed him
		do
		{
			max=FAAD_BUFFER-_inbuffer;
			if(nbIn<max) max=nbIn;
			memcpy(_buffer+_inbuffer,ptr,max);
			ptr+=max;
			nbIn-=max;
			_inbuffer+=max;
			/*
			if(_inbuffer<FAAD_MIN_STREAMSIZE*2)
			{
				return 1;
			}*/
			memset(&info,0,sizeof(info));
			//printf("%x %x\n",_buffer[0],_buffer[1]);
		 	outbuf = faacDecDecode(_instance, &info, _buffer, _inbuffer);
			if(info.error)
			{
				printf("Faad: Error %d :%s\n",info.error,
					faacDecGetErrorMessage(info.error));
					/*
				xin=info.bytesconsumed ;
				if(!xin) xin=1;
				memmove(_buffer,_buffer+xin,_inbuffer-xin);
				_inbuffer-=xin;
				return 1;*/
				return 0;
			}
			if(first)
			{
				printf("Channels : %d\n",info.channels);
				printf("Frequency: %d\n",info.samplerate);
				printf("SBR      : %d\n",info.sbr);
				
			
			}
			xin=info.bytesconsumed ;
			if(xin>_inbuffer) xin=0;
			
			xout=info.samples*2;
			
			//printf("in:%d out:%d\n",xin,xout);
			
			memmove(_buffer,_buffer+xin,_inbuffer-xin);
			_inbuffer-=xin;
			if(xout)
			{
				memcpy(outptr,outbuf,xout);
				*nbOut+=xout;
				outptr+=xout;
			}
		}while(nbIn);
		return 1;
}
Ejemplo n.º 16
0
int play_file(char *fn)
{
    int k;
    int tagsize;

    ZeroMemory(buffer, 768*2);

    infile = open_filestream(fn);
    
	if (infile == NULL)
        return 1;

    fileread = filelength_filestream(infile);

    buffercount = bytecount = 0;
    read_buffer_filestream(infile, buffer, 768*2);

    tagsize = id3v2_tag(buffer);

	/* If we find a tag, run right over it */
    if(tagsize)
	{
        if(infile->http)
        {
            int i;
            /* Crude way of doing this, but I believe its fast enough to not make a big difference */
            close_filestream(infile);
            infile = open_filestream(fn);

            for(i=0; i < tagsize; i++)
                read_byte_filestream(infile);
        }
        else
        {
            seek_filestream(infile, tagsize, FILE_BEGIN);
        }

        bytecount = tagsize;
        buffercount = 0;
        read_buffer_filestream(infile, buffer, 768*2);
    }

    hDecoder = faacDecOpen();

	/* Copy the configuration dialog setting and use it as the default */
	/* initialize the decoder, and get samplerate and channel info */

    if((buffercount = faacDecInit(hDecoder, buffer, 768*2, &samplerate, &channels)) < 0)
    {
		MessageBox(mod.hMainWindow, "Error opening input file\n", "FAAD Error", MB_OK);
		return 1;
    }

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

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

		read_buffer_filestream(infile, buffer + (768*2) - buffercount, buffercount);
		buffercount = 0;
	}

    PlayThread_file();

    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;
}
Ejemplo n.º 18
0
Archivo: faad.c Proyecto: Kafay/vlc
/*****************************************************************************
 * DecodeBlock:
 *****************************************************************************/
static aout_buffer_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 )
            {
                vlc_memcpy( p_block->p_buffer,
                            p_block->p_buffer + i_header_size,
                            p_block->i_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 )
    {
        p_sys->i_buffer_size = p_sys->i_buffer + p_block->i_buffer;
        p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size );
    }

    if( p_block->i_buffer > 0 )
    {
        vlc_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];

            aout_DateInit( &p_sys->date, i_rate );
        }
    }

    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];
        aout_DateInit( &p_sys->date, i_rate );
    }

    if( p_block->i_pts != 0 && p_block->i_pts != aout_DateGet( &p_sys->date ) )
    {
        aout_DateSet( &p_sys->date, p_block->i_pts );
    }
    else if( !aout_DateGet( &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;
        aout_buffer_t *p_out;
        int i, j;

        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 ) );

            /* 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 )
        {
            aout_DateInit( &p_sys->date, frame.samplerate );
            aout_DateSet( &p_sys->date, p_block->i_pts );
        }
        p_block->i_pts = 0;  /* PTS is valid only once */

        p_dec->fmt_out.audio.i_rate = frame.samplerate;
        p_dec->fmt_out.audio.i_channels = frame.channels;
        p_dec->fmt_out.audio.i_physical_channels
            = p_dec->fmt_out.audio.i_original_channels
            = pi_channels_guessed[frame.channels];

        /* Adjust stream info when dealing with SBR/PS */
        if( p_sys->b_sbr != frame.sbr || p_sys->b_ps != frame.ps )
        {
            const char *psz_ext = (frame.sbr && frame.ps) ? "SBR+PS" :
                                    frame.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 = frame.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;
        for( i = 0; i < frame.channels; 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];
        }
        p_dec->fmt_out.audio.i_original_channels =
            p_dec->fmt_out.audio.i_physical_channels;

        p_out = decoder_NewAudioBuffer(p_dec, frame.samples/frame.channels);
        if( p_out == NULL )
        {
            p_sys->i_buffer = 0;
            block_Release( p_block );
            return NULL;
        }

        p_out->start_date = aout_DateGet( &p_sys->date );
        p_out->end_date = aout_DateIncrement( &p_sys->date, frame.samples / frame.channels );

        DoReordering( (uint32_t *)p_out->p_buffer, samples,
                      frame.samples / frame.channels, frame.channels,
                      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;
}
Ejemplo n.º 19
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;
}