From 145f0b62d26974c5e15ad65c902045fe671a9d05 Mon Sep 17 00:00:00 2001 From: Warren Dukes Date: Mon, 22 Mar 2004 02:44:22 +0000 Subject: [PATCH] aac decoding! need to work on seeking for AAC also, don't reset cb->begin on seek to 0, instead just set cb->end=cb->begin, works much better for disabling seeking (like ADIF AAC's) git-svn-id: https://svn.musicpd.org/mpd/trunk@356 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- src/aac_decode.c | 151 ++++++++++++++--------------------------- src/aac_decode.h | 2 - src/audiofile_decode.c | 2 +- src/decode.c | 8 ++- src/decode.h | 13 ++-- src/flac_decode.c | 2 +- src/mp3_decode.c | 2 +- src/mp4_decode.c | 8 +-- src/mp4_decode.h | 2 - src/ogg_decode.c | 2 +- 10 files changed, 72 insertions(+), 120 deletions(-) diff --git a/src/aac_decode.c b/src/aac_decode.c index 26e430d06..40e1217e4 100644 --- a/src/aac_decode.c +++ b/src/aac_decode.c @@ -2,8 +2,6 @@ * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * This project's homepage is: http://www.musicpd.org * - * libaudiofile (wave) support added by Eric Wong - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -196,7 +194,11 @@ int initAacBuffer(char * file, AacBuffer * b, float * length) { if(*length!=0 && bitRate!=0) *length = *length*8.0/bitRate; } - if(*length<0) return -1; + if(*length<0) { + fclose(b->infile); + if(b->buffer) free(b->buffer); + return -1; + } return 0; } @@ -215,59 +217,29 @@ int getAacTotalTime(char * file) { int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { - /*FILE * fh; - mp4ff_t * mp4fh; - mp4ff_callback_t * mp4cb; - int32_t track; float time; - int32_t scale; + float totalTime; faacDecHandle decoder; faacDecFrameInfo frameInfo; faacDecConfigurationPtr config; - unsigned char * mp4Buffer; - int mp4BufferSize; + size_t bread; unsigned long sampleRate; unsigned char channels; - long sampleId; - long numSamples; int eof = 0; - long dur; unsigned int sampleCount; char * sampleBuffer; size_t sampleBufferLen; - unsigned int initial = 1; int chunkLen = 0; - float * seekTable; + /*float * seekTable; long seekTableEnd = -1; - int seekPositionFound = 0; - long offset; + int seekPositionFound = 0;*/ mpd_uint16 bitRate = 0; + AacBuffer b; - fh = fopen(dc->file,"r"); - if(!fh) { - ERROR("failed to open %s\n",dc->file); - return -1; - } + printf("aac_decode!\n"); - mp4cb = malloc(sizeof(mp4ff_callback_t)); - mp4cb->read = mp4_readCallback; - mp4cb->seek = mp4_seekCallback; - mp4cb->user_data = fh; - - mp4fh = mp4ff_open_read(mp4cb); - if(!mp4fh) { - ERROR("Input does not appear to be a mp4 stream.\n"); - free(mp4cb); - fclose(fh); - return -1; - } - - track = mp4_getAACTrack(mp4fh); - if(track < 0) { - ERROR("No AAC track found in mp4 stream.\n"); - mp4ff_close(mp4fh); - fclose(fh); - free(mp4cb); + if(initAacBuffer(dc->file,&b,&totalTime) < 0) { + ERROR("Not AAC file no ADTS or ADIF headers found.\n"); return -1; } @@ -285,48 +257,33 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { af->bits = 16; - mp4Buffer = NULL; - mp4BufferSize = 0; - mp4ff_get_decoder_config(mp4fh,track,&mp4Buffer,&mp4BufferSize); - - if(faacDecInit2(decoder,mp4Buffer,mp4BufferSize,&sampleRate,&channels) - < 0) + fillAacBuffer(&b); + if((bread = faacDecInit(decoder,b.buffer,b.bytesIntoBuffer, + &sampleRate,&channels)) < 0) { - ERROR("Error initializing AAC decoder library.\n"); + ERROR("Error not a AAC stream.\n"); faacDecClose(decoder); - mp4ff_close(mp4fh); - free(mp4cb); - fclose(fh); + fclose(b.infile); + if(b.buffer) free(b.buffer); return -1; } af->sampleRate = sampleRate; af->channels = channels; - time = mp4ff_get_track_duration_use_offsets(mp4fh,track); - scale = mp4ff_time_scale(mp4fh,track); - if(mp4Buffer) free(mp4Buffer); - - if(scale < 0) { - ERROR("Error getting audio format of mp4 AAC track.\n"); - faacDecClose(decoder); - mp4ff_close(mp4fh); - fclose(fh); - free(mp4cb); - return -1; - } - cb->totalTime = ((float)time)/scale; - - numSamples = mp4ff_num_samples(mp4fh,track); + cb->totalTime = totalTime+0.5; dc->state = DECODE_STATE_DECODE; dc->start = 0; time = 0.0; - seekTable = malloc(sizeof(float)*numSamples); + advanceAacBuffer(&b,bread); + fillAacBuffer(&b); - for(sampleId=0; sampleIdseek && seekTableEnd>1 && + /*seekTable = malloc(sizeof(float)*numSamples);*/ + + do { + /*if(dc->seek && seekTableEnd>1 && seekTable[seekTableEnd]>=dc->seekWhere) { int i = 2; @@ -335,9 +292,6 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { time = seekTable[sampleId]; } - dur = mp4ff_get_sample_duration(mp4fh,track,sampleId); - offset = mp4ff_get_sample_offset(mp4fh,track,sampleId); - if(sampleId>seekTableEnd) { seekTable[sampleId] = time; seekTableEnd = sampleId; @@ -358,42 +312,36 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { dc->seek = 0; } - if(dc->seek) continue; - - if(mp4ff_read_sample(mp4fh,track,sampleId,&mp4Buffer, - &mp4BufferSize) == 0) - { - eof = 1; - continue; - } + if(dc->seek) continue;*/ + + if(dc->seek) { + /*chunkLen = 0; + cb->wrap = 0; + cb->end = 0;*/ + dc->seekError = 1; + dc->seek = 0; + } + + sampleBuffer = faacDecDecode(decoder,&frameInfo,b.buffer, + b.bytesIntoBuffer); + advanceAacBuffer(&b,frameInfo.bytesconsumed); - sampleBuffer = faacDecDecode(decoder,&frameInfo,mp4Buffer, - mp4BufferSize); - if(mp4Buffer) free(mp4Buffer); if(frameInfo.error > 0) { eof = 1; break; } - if(channels*(dur+offset) > frameInfo.samples) { - dur = frameInfo.samples; - offset = 0; - } - - sampleCount = (unsigned long)(dur*channels); + sampleCount = (unsigned long)(frameInfo.samples); if(sampleCount>0) { - initial =0; bitRate = frameInfo.bytesconsumed*8.0* - frameInfo.channels*scale/ + frameInfo.channels*sampleRate/ frameInfo.samples/1024+0.5; + time+= (float)(frameInfo.samples)/channels/sampleRate; } - sampleBufferLen = sampleCount*2; - sampleBuffer+=offset*channels*2; - while(sampleBufferLen>0 && !dc->seek) { size_t size = sampleBufferLen>CHUNK_SIZE-chunkLen ? CHUNK_SIZE-chunkLen: @@ -427,7 +375,11 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { } } } - } + + fillAacBuffer(&b); + + if(b.bytesIntoBuffer==0) eof = 1; + } while (!eof); if(!dc->stop && !dc->seek && chunkLen>0) { cb->chunkSize[cb->end] = chunkLen; @@ -440,11 +392,10 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { chunkLen = 0; } - free(seekTable); + /*free(seekTable);*/ faacDecClose(decoder); - mp4ff_close(mp4fh); - fclose(fh); - free(mp4cb); + fclose(b.infile); + if(b.buffer) free(b.buffer); if(dc->seek) dc->seek = 0; @@ -452,7 +403,7 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { dc->state = DECODE_STATE_STOP; dc->stop = 0; } - else dc->state = DECODE_STATE_STOP;*/ + else dc->state = DECODE_STATE_STOP; return 0; } diff --git a/src/aac_decode.h b/src/aac_decode.h index ad0d75d75..7ce9781f4 100644 --- a/src/aac_decode.h +++ b/src/aac_decode.h @@ -2,8 +2,6 @@ * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * This project's homepage is: http://www.musicpd.org * - * libaudiofile (wave) support added by Eric Wong - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or diff --git a/src/audiofile_decode.c b/src/audiofile_decode.c index 0c2824dc6..9889fbf2f 100644 --- a/src/audiofile_decode.c +++ b/src/audiofile_decode.c @@ -86,7 +86,7 @@ int audiofile_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) while(!eof) { if(dc->seek) { - cb->end = 0; + cb->end = cb->begin; cb->wrap = 0; current = dc->seekWhere * af->sampleRate; afSeekFrame(af_fp, AF_DEFAULT_TRACK,current); diff --git a/src/decode.c b/src/decode.c index b80166af4..334812d8b 100644 --- a/src/decode.c +++ b/src/decode.c @@ -40,6 +40,7 @@ #endif #ifdef HAVE_FAAD #include "mp4_decode.h" +#include "aac_decode.h" #endif #include @@ -159,11 +160,11 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, pc->totalTime-0.1 : pc->seekWhere; dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere; - cb->begin = 0; + dc->seekError = 0; dc->seek = 1; - pc->elapsedTime = dc->seekWhere; pc->bitRate = 0; while(*decode_pid>0 && dc->seek) usleep(1000); + if(dc->seekError) pc->elapsedTime = dc->seekWhere; } } pc->seek = 0; @@ -229,6 +230,9 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af, break; #endif #ifdef HAVE_FAAD + case DECODE_TYPE_AAC: + dc->error = aac_decode(cb,af,dc); + break; case DECODE_TYPE_MP4: dc->error = mp4_decode(cb,af,dc); break; diff --git a/src/decode.h b/src/decode.h index 9f6e2f0e5..faf18f344 100644 --- a/src/decode.h +++ b/src/decode.h @@ -21,6 +21,8 @@ #include "../config.h" +#include "mpd_types.h" + #include #include @@ -38,11 +40,12 @@ #define DECODE_ERROR_UNKTYPE 1 typedef struct _DecoderControl { - int state; - int stop; - int start; - int error; - int seek; + mpd_sint8 state; + mpd_sint8 stop; + mpd_sint8 start; + mpd_uint16 error; + mpd_sint8 seek; + mpd_sint8 seekError; double seekWhere; char file[MAXPATHLEN+1]; } DecoderControl; diff --git a/src/flac_decode.c b/src/flac_decode.c index a684e5091..29f7dbdaa 100644 --- a/src/flac_decode.c +++ b/src/flac_decode.c @@ -104,7 +104,7 @@ void flacPlayFile(char *file, Buffer * cb, AudioFormat * af, if(dc->seek) { FLAC__uint64 sampleToSeek = dc->seekWhere* af->sampleRate+0.5; - cb->end = 0; + cb->end = cb->begin; cb->wrap = 0; if(FLAC__file_decoder_seek_absolute(flacDec, sampleToSeek)) diff --git a/src/mp3_decode.c b/src/mp3_decode.c index a07485a32..6fa931fe7 100644 --- a/src/mp3_decode.c +++ b/src/mp3_decode.c @@ -487,7 +487,7 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { if(dc->seek) { long i = 0; cb->wrap = 0; - cb->end = 0; + cb->end = cb->begin; data->muteFrame = 1; while(ihighestFrame && dc->seekWhere > ((float)mad_timer_count(data->times[i], diff --git a/src/mp4_decode.c b/src/mp4_decode.c index a2cfc2ee0..d3c16b73e 100644 --- a/src/mp4_decode.c +++ b/src/mp4_decode.c @@ -2,8 +2,6 @@ * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * This project's homepage is: http://www.musicpd.org * - * libaudiofile (wave) support added by Eric Wong - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -149,7 +147,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { if(faacDecInit2(decoder,mp4Buffer,mp4BufferSize,&sampleRate,&channels) < 0) { - ERROR("Error initializing AAC decoder library.\n"); + ERROR("Error not a AAC stream.\n"); faacDecClose(decoder); mp4ff_close(mp4fh); free(mp4cb); @@ -210,7 +208,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { if(dc->seek && seekPositionFound) { seekPositionFound = 0; chunkLen = 0; - cb->end = 0; + cb->end = cb->begin; cb->wrap = 0; dc->seek = 0; } @@ -233,7 +231,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { } if(channels*(dur+offset) > frameInfo.samples) { - dur = frameInfo.samples; + dur = frameInfo.samples/channels; offset = 0; } diff --git a/src/mp4_decode.h b/src/mp4_decode.h index 58d40aeff..a981e1e0a 100644 --- a/src/mp4_decode.h +++ b/src/mp4_decode.h @@ -2,8 +2,6 @@ * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * This project's homepage is: http://www.musicpd.org * - * libaudiofile (wave) support added by Eric Wong - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or diff --git a/src/ogg_decode.c b/src/ogg_decode.c index 7fe3dfeb6..ff8d2024c 100644 --- a/src/ogg_decode.c +++ b/src/ogg_decode.c @@ -95,7 +95,7 @@ int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) while(!eof) { if(dc->seek) { - cb->end = 0; + cb->end = cb->begin; cb->wrap = 0; chunkpos = 0; ov_time_seek_page(&vf,dc->seekWhere);