Пример #1
0
int PlayThread_file()
{
    int k;

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

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

    sample_buffer = (char*)faacDecDecode(hDecoder, &frameInfo, buffer, 768*2);
    if (frameInfo.error)
    {
        MessageBox(NULL, faacDecGetErrorMessage(frameInfo.error), "FAAD Error", MB_OK);
        last_frame = 1;
    }

    buffercount += frameInfo.bytesconsumed;

    bytecount += frameInfo.bytesconsumed;
    if (bytecount >= fileread)
        last_frame = 1;

    return frameInfo.bytesconsumed;
}
Пример #2
0
void* NEAACDECAPI mtv_faacDecDecode(NeAACDecFrameInfo *hInfo,
                                 uint8_t *buffer, uint32_t buffer_size)
{
    unsigned char *pcm_o;
    pcm_o = faacDecDecode(faac_hdec, &faac_finfo, buffer, buffer_size);            //decode a audio packet
    *hInfo = faac_finfo;
    return (void *)pcm_o;
}
Пример #3
0
int AacPcm::processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch)
{
DWORD			BytesDecoded=0;
char			*bufout=0;
ChunkInfosI		*ci=0;
svc_fileReader	*reader=0;

	if(!FindBitrate && !chunk_list)
		ERROR_processData("chunk_list==NULL"); // is this case possible?

	if(!(reader=infos->getReader()))
		ERROR_processData("File doesn\'t exists");

	if(chunk_list)
	{
		if(!(ci=new ChunkInfosI()))
			ERROR_processData("Memory allocation error: ci");

		ci->addInfo("srate", Samplerate);
		ci->addInfo("bps", bps);
		ci->addInfo("nch", Channels);
	}

	if(!IsAAC) // MP4 file --------------------------------------------------------------------------
	{   
	unsigned __int32 buffer_size=0;
    int rc;

		if(newpos_ms>-1)
		{
		MP4Duration duration=MP4ConvertToTrackDuration(mp4File,track,newpos_ms,MP4_MSECS_TIME_SCALE);
            sampleId=MP4GetSampleIdFromTime(mp4File,track,duration,0);
			bytes_read=(DWORD)(((float)newpos_ms*file_info.bitrate)/(8*1000));
			reader->seek(bytes_read);  // updates slider
			newpos_ms=-1;
		}
		do
		{
			buffer=NULL;
			if(sampleId>=numSamples)
				ERROR_processData(0);

			rc=MP4ReadSample(mp4File, track, sampleId++, (unsigned __int8 **)&buffer, &buffer_size, NULL, NULL, NULL, NULL);
			if(rc==0 || buffer==NULL)
			{
				FREE_ARRAY(buffer);
				ERROR_processData("MP4ReadSample")
			}

			bufout=(char *)faacDecDecode(hDecoder,&frameInfo,buffer,buffer_size);
			BytesDecoded=frameInfo.samples*sizeof(short);
			FREE_ARRAY(buffer);
			// to update the slider
			bytes_read+=buffer_size;
			reader->seek(bytes_read);
		}while(!BytesDecoded && !frameInfo.error);
Пример #4
0
unsigned int faad_decoder::update(void *dest, unsigned int const num_samples_to_write)
{
    if (!is_initialized())
        return 0;

    unsigned int multiplier = playback_properties_.num_channels * get_sample_size(playback_properties_.sample_type_);

    faacDecFrameInfo info;
    while (out_buffer.size() < (num_samples_to_write * multiplier))
    {
        size_t actual_in_size = in_buffer.size();

        if (actual_in_size < 32768)
        {
            size_t old_in_size = actual_in_size;
            in_buffer.resize(old_in_size + 32768);
            long num_read_bytes = source_->read(&in_buffer[old_in_size], 32768);
            if (num_read_bytes <= 0)
                break;
            actual_in_size = old_in_size + num_read_bytes;
        }

        void *output_samples = faacDecDecode(*faad_handle, &info, reinterpret_cast < unsigned char* > (&in_buffer[0]), actual_in_size);
        unsigned int num_remaining_bytes = actual_in_size;

        num_remaining_bytes -= info.bytesconsumed;
        std::memmove(&in_buffer[0], &in_buffer[info.bytesconsumed], num_remaining_bytes);
        in_buffer.resize(num_remaining_bytes);

        if ((output_samples == 0) || (info.error != 0) || (info.channels == 0))
        {
            initialized = false;
            break;
        }

        if (info.samples > 0)
        {
            size_t old_out_size = out_buffer.size();
            out_buffer.resize(old_out_size + info.samples * playback_properties_.num_channels);
            std::memcpy(&out_buffer[old_out_size], output_samples, info.samples * playback_properties_.num_channels);
        }
    }

    size_t num_bytes_to_copy = std::min(size_t(num_samples_to_write * multiplier), out_buffer.size());
    std::memcpy(dest, &out_buffer[0], num_bytes_to_copy);
    if (out_buffer.size() > num_bytes_to_copy)
        std::memmove(&out_buffer[0], &out_buffer[num_bytes_to_copy], out_buffer.size() - num_bytes_to_copy);
    out_buffer.resize(out_buffer.size() - num_bytes_to_copy);

    current_position += num_bytes_to_copy / multiplier;
    return num_bytes_to_copy / multiplier;
}
Пример #5
0
bool CCoreAACDecoder::Decode(BYTE *pSrc, DWORD SrcLength, BYTE *pDst, DWORD DstLength, DWORD *ActualDstLength)
{
	faacDecFrameInfo frameInfo;
	short *outsamples = (short *)faacDecDecode(m_decHandle, &frameInfo, pSrc, DstLength);

	if (frameInfo.error)
	{
		NOTE2("CCoreAACDecoder::Decode Error %d [%s]\n", 
			frameInfo.error, faacDecGetErrorMessage(frameInfo.error));
		return false;
	}

	m_brCalcFrames++;
	m_DecodedFrames++;
	m_brBytesConsumed += SrcLength;

	if(m_brCalcFrames == 43)
	{
		m_Bitrate = (int)((m_brBytesConsumed * 8) / (m_DecodedFrames / 43.07));
		m_brCalcFrames = 0;
	}

	if (!frameInfo.error && outsamples)
	{
		int channelidx = frameInfo.channels-1;
		if(chmap[channelidx][0])
		{
			// dshow remapping
			short *dstBuffer = (short*)pDst;
			for(unsigned int i = 0;
			    i < frameInfo.samples;
				i += frameInfo.channels, outsamples += frameInfo.channels)
			{
				for(unsigned int j=1; j <= frameInfo.channels; j++)
				{
					*dstBuffer++ = outsamples[chmap[channelidx][j]];
				}				
			}
		}
		else
		{
			memcpy(pDst, outsamples, frameInfo.samples * sizeof(short));
		}
	}
	else
		return false;

	*ActualDstLength = frameInfo.samples * sizeof(short);
	return true;
}
Пример #6
0
int PlayThread_memmap()
{
    sample_buffer = (char*)faacDecDecode(hDecoder, &frameInfo,
        memmap_buffer + memmap_index, fileread - memmap_index - 1);
    if (frameInfo.error)
    {
        MessageBox(NULL, faacDecGetErrorMessage(frameInfo.error), "FAAD Error", MB_OK);
        last_frame = 1;
    }

    memmap_index += frameInfo.bytesconsumed;
    if (memmap_index >= fileread)
        last_frame = 1;

    return frameInfo.bytesconsumed;
}
Пример #7
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;
}
Пример #8
0
static GF_Err FAAD_ProcessData(GF_MediaDecoder *ifcg,
                               char *inBuffer, u32 inBufferLength,
                               u16 ES_ID, u32 *CTS,
                               char *outBuffer, u32 *outBufferLength,
                               u8 PaddingBits, u32 mmlevel)
{
	void *buffer;
	unsigned short *conv_in, *conv_out;
	u32 i, j;
	FAADCTX();

	/*check not using scalabilty*/
	if (ctx->ES_ID != ES_ID) return GF_BAD_PARAM;

	/*if late or seeking don't decode*/
	switch (mmlevel) {
	case GF_CODEC_LEVEL_SEEK:
//	case GF_CODEC_LEVEL_DROP:
		*outBufferLength = 0;
		return GF_OK;
	default:
		break;
	}

	if (ctx->out_size > *outBufferLength) {
		*outBufferLength = ctx->out_size;
		return GF_BUFFER_TOO_SMALL;
	}

	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] Decoding AU\n"));
	buffer = faacDecDecode(ctx->codec, &ctx->info, (unsigned char *) inBuffer, inBufferLength);
	if (ctx->info.error>0) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[FAAD] Error decoding AU %s\n", faacDecGetErrorMessage(ctx->info.error) ));
		*outBufferLength = 0;
		//reinit if error
		FAAD_AttachStream((GF_BaseDecoder *)ifcg, ctx->esd);
		return GF_NON_COMPLIANT_BITSTREAM;
	}
	if (!ctx->info.samples || !buffer || !ctx->info.bytesconsumed) {
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] empty/non complete AU\n"));
		*outBufferLength = 0;
		return GF_OK;
	}
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] AU decoded\n"));

	/*FAAD froces us to decode a frame to get channel cfg*/
	if (ctx->signal_mc) {
		s32 ch, idx;
		ctx->signal_mc = GF_FALSE;
		idx = 0;
		/*NOW WATCH OUT!! FAAD may very well decide to output more channels than indicated!!!*/
		ctx->num_channels = ctx->info.channels;

		/*get cfg*/
		ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_FRONT_LEFT);
		if (ch>=0) {
			ctx->ch_reorder[idx] = ch;
			idx++;
		}
		ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_FRONT_RIGHT);
		if (ch>=0) {
			ctx->ch_reorder[idx] = ch;
			idx++;
		}
		ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_FRONT_CENTER);
		if (ch>=0) {
			ctx->ch_reorder[idx] = ch;
			idx++;
		}
		ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_LFE);
		if (ch>=0) {
			ctx->ch_reorder[idx] = ch;
			idx++;
		}
		ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_BACK_LEFT);
		if (ch>=0) {
			ctx->ch_reorder[idx] = ch;
			idx++;
		}
		ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_BACK_RIGHT);
		if (ch>=0) {
			ctx->ch_reorder[idx] = ch;
			idx++;
		}
		ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_BACK_CENTER);
		if (ch>=0) {
			ctx->ch_reorder[idx] = ch;
			idx++;
		}
		ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_SIDE_LEFT);
		if (ch>=0) {
			ctx->ch_reorder[idx] = ch;
			idx++;
		}
		ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_SIDE_RIGHT);
		if (ch>=0) {
			ctx->ch_reorder[idx] = ch;
			idx++;
		}

		*outBufferLength = ctx->out_size;
		if (sizeof(short) * ctx->info.samples > *outBufferLength) {
			*outBufferLength = ctx->out_size = (u32) (sizeof(short)*ctx->info.samples);
		}
		return GF_BUFFER_TOO_SMALL;
	}
	if (sizeof(short) * ctx->info.samples > *outBufferLength) {
		*outBufferLength = (u32) (sizeof(short)*ctx->info.samples);
		return GF_BUFFER_TOO_SMALL;
	}

	/*we assume left/right order*/
	if (ctx->num_channels<=2) {
		memcpy(outBuffer, buffer, sizeof(short)* ctx->info.samples);
		*outBufferLength = (u32) (sizeof(short)*ctx->info.samples);
		return GF_OK;
	}
	conv_in = (unsigned short *) buffer;
	conv_out = (unsigned short *) outBuffer;
	for (i=0; i<ctx->info.samples; i+=ctx->info.channels) {
		for (j=0; j<ctx->info.channels; j++) {
			conv_out[i + j] = conv_in[i + ctx->ch_reorder[j]];
		}
	}
	*outBufferLength = (u32) (sizeof(short)*ctx->info.samples);
	return GF_OK;
}
Пример #9
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;
}
Пример #10
0
static gint
xmms_faad_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *err)
{
	xmms_faad_data_t *data;
	xmms_error_t error;

	faacDecFrameInfo frameInfo;
	gpointer sample_buffer;
	guint size, bytes_read = 0;

	data = xmms_xform_private_data_get (xform);
	g_return_val_if_fail (data, -1);

	size = MIN (data->outbuf->len, len);
	while (size == 0) {
		gboolean need_read;

		/* MP4 demuxer always gives full packets so we need different handling */
		if (data->filetype == FAAD_TYPE_MP4)
			need_read = (data->buffer_length == 0);
		else
			need_read = (data->buffer_length < data->buffer_size);

		if (need_read) {
			bytes_read = xmms_xform_read (xform,
			                              (gchar *) data->buffer + data->buffer_length,
			                              data->buffer_size - data->buffer_length,
			                              &error);

			if (bytes_read <= 0 && data->buffer_length == 0) {
				XMMS_DBG ("EOF");
				return 0;
			}

			data->buffer_length += bytes_read;
		}

		sample_buffer = faacDecDecode (data->decoder, &frameInfo, data->buffer,
		                               data->buffer_length);

		g_memmove (data->buffer, data->buffer + frameInfo.bytesconsumed,
		           data->buffer_length - frameInfo.bytesconsumed);
		data->buffer_length -= frameInfo.bytesconsumed;
		bytes_read = frameInfo.samples * xmms_sample_size_get (data->sampleformat);

		if (bytes_read > 0 && frameInfo.error == 0) {
			gint32 temp, toskip = 0;

			if (data->samplerate != frameInfo.samplerate ||
			    data->channels != frameInfo.channels) {
				/* We should inform output to change parameters somehow */
				XMMS_DBG ("Output format changed in the middle of a read!");
				data->samplerate = frameInfo.samplerate;
				data->channels = frameInfo.channels;
			}

			if (xmms_xform_auxdata_get_int (xform, "frame_offset", &temp)) {
				toskip = (temp * frameInfo.channels *
				          xmms_sample_size_get (data->sampleformat));
			}

			if (xmms_xform_auxdata_get_int (xform, "frame_duration", &temp)) {
				bytes_read = (temp * frameInfo.channels *
				              xmms_sample_size_get (data->sampleformat));
			}

			g_string_append_len (data->outbuf, sample_buffer + toskip,
			                     bytes_read - toskip);
		} else if (frameInfo.error > 0) {
			XMMS_DBG ("ERROR %d in faad decoding: %s", frameInfo.error,
			          faacDecGetErrorMessage (frameInfo.error));
			return -1;
		}

		size = MIN (data->outbuf->len, len);
	}

	memcpy (buf, data->outbuf->str, size);
	g_string_erase (data->outbuf, 0, size);
	return size;
}
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;
}
Пример #12
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;
}
Пример #13
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);
}
Пример #14
0
Файл: faad.c Проект: 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;
}
Пример #15
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;
}
Пример #16
0
int AacPcm::processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch)
{
DWORD		read,
			tmp,
			shorts_decoded=0;
long		result=0;
ChunkInfosI *ci = new ChunkInfosI();

	ci->addInfo("srate", dwSamprate); 
    ci->addInfo("bps", 16); 
	ci->addInfo("nch", dwChannels); 

	if(bytes_into_buffer<0)
		ERROR_processData(0);

svc_fileReader *reader = infos->getReader();
	if(!reader)
		ERROR_processData("File doesn\'t exists");

	do
	{
		if(bytes_consumed>0 && bytes_into_buffer>=0)
		{
			if(bytes_into_buffer)
				memcpy(buffer,buffer+bytes_consumed,bytes_into_buffer);

			if(bytes_read<lSize)
			{
				if(bytes_read+bytes_consumed<lSize)
					tmp=bytes_consumed;
				else
					tmp=lSize-bytes_read;
				read=reader->read((char *)buffer+bytes_into_buffer, tmp);
				if(read==tmp)
				{
					bytes_read+=read;
					bytes_into_buffer+=read;
				}
				else
					infos->status("Read failed!"); // continue until bytes_into_buffer<1
			}
			else
				if(bytes_into_buffer)
					memset(buffer+bytes_into_buffer, 0, bytes_consumed);
		}

		if(bytes_into_buffer<1)
			if(bytes_read<lSize)
				ERROR_processData("Buffer empty!")
			else
				return 0;

		result=faacDecDecode(hDecoder, buffer, &bytes_consumed, (short*)bufout, &shorts_decoded);
		bytes_into_buffer-=bytes_consumed;
	}while(!shorts_decoded || result==FAAD_OK_CHUPDATE);


	if(result==FAAD_FATAL_ERROR || result==FAAD_ERROR)
		ERROR_processData("FAAD_FATAL_ERROR or FAAD_ERROR");

	shorts_decoded*=sizeof(short);

    chunk_list->setChunk("PCM", bufout, shorts_decoded, ci);
//	fwrite(bufout,1,bytesDec,fil);

    if(!shorts_decoded)
		ERROR_processData(0);

    return 1;
}
Пример #17
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);
}
Пример #18
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);
    
  }
}
Пример #19
0
static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen)
{
  int j = 0, len = 0, last_dec_len = 1, errors = 0;	      
  void *faac_sample_buffer;

  while(len < minlen && last_dec_len > 0 && errors < MAX_FAAD_ERRORS) {

    /* update buffer for raw aac streams: */
  if(!sh->codecdata_len)
    if(sh->a_in_buffer_len < sh->a_in_buffer_size){
      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);
    }
	  
#ifdef DUMP_AAC_COMPRESSED
    {int i;
    for (i = 0; i < 16; i++)
      printf ("%02X ", sh->a_in_buffer[i]);
    printf ("\n");}
#endif

  if(!sh->codecdata_len){
   // raw aac stream:
   do {
    faac_sample_buffer = faacDecDecode(faac_hdec, &faac_finfo, sh->a_in_buffer, sh->a_in_buffer_len);
	
    /* update buffer index after faacDecDecode */
    if(faac_finfo.bytesconsumed >= sh->a_in_buffer_len) {
      sh->a_in_buffer_len=0;
    } else {
      sh->a_in_buffer_len-=faac_finfo.bytesconsumed;
      memmove(sh->a_in_buffer,&sh->a_in_buffer[faac_finfo.bytesconsumed],sh->a_in_buffer_len);
    }

    if(faac_finfo.error > 0) {
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: error: %s, trying to resync!\n",
              faacDecGetErrorMessage(faac_finfo.error));
      if (sh->a_in_buffer_len <= 0) {
        errors = MAX_FAAD_ERRORS;
        break;
      }
      sh->a_in_buffer_len--;
      memmove(sh->a_in_buffer,&sh->a_in_buffer[1],sh->a_in_buffer_len);
      aac_sync(sh);
      errors++;
    } else
      break;
   } while(errors < MAX_FAAD_ERRORS);	  
  } else {
   // packetized (.mp4) aac stream:
    unsigned char* bufptr=NULL;
    double pts;
    int buflen=ds_get_packet_pts(sh->ds, &bufptr, &pts);
    if(buflen<=0) break;
    if (pts != MP_NOPTS_VALUE) {
	sh->pts = pts;
	sh->pts_bytes = 0;
    }
    faac_sample_buffer = faacDecDecode(faac_hdec, &faac_finfo, bufptr, buflen);
  }
  //for (j=0;j<faac_finfo.channels;j++) printf("%d:%d\n", j, faac_finfo.channel_position[j]);
  
    if(faac_finfo.error > 0) {
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to decode frame: %s \n",
      faacDecGetErrorMessage(faac_finfo.error));
    } else if (faac_finfo.samples == 0) {
      mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Decoded zero samples!\n");
    } else {
      /* XXX: samples already multiplied by channels! */
      mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Successfully decoded frame (%ld Bytes)!\n",
      sh->samplesize*faac_finfo.samples);
      memcpy(buf+len,faac_sample_buffer, sh->samplesize*faac_finfo.samples);
      last_dec_len = sh->samplesize*faac_finfo.samples;
      len += last_dec_len;
      sh->pts_bytes += last_dec_len;
    //printf("FAAD: buffer: %d bytes  consumed: %d \n", k, faac_finfo.bytesconsumed);
    }
  }
  return len;
}
Пример #20
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;
}
Пример #21
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;
}
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;
}