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
This commit is contained in:
Warren Dukes 2004-03-22 02:44:22 +00:00
parent 4c1eb9225d
commit 145f0b62d2
10 changed files with 72 additions and 120 deletions

View File

@ -2,8 +2,6 @@
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org * This project's homepage is: http://www.musicpd.org
* *
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * 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 && 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; return 0;
} }
@ -215,59 +217,29 @@ int getAacTotalTime(char * file) {
int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
/*FILE * fh;
mp4ff_t * mp4fh;
mp4ff_callback_t * mp4cb;
int32_t track;
float time; float time;
int32_t scale; float totalTime;
faacDecHandle decoder; faacDecHandle decoder;
faacDecFrameInfo frameInfo; faacDecFrameInfo frameInfo;
faacDecConfigurationPtr config; faacDecConfigurationPtr config;
unsigned char * mp4Buffer; size_t bread;
int mp4BufferSize;
unsigned long sampleRate; unsigned long sampleRate;
unsigned char channels; unsigned char channels;
long sampleId;
long numSamples;
int eof = 0; int eof = 0;
long dur;
unsigned int sampleCount; unsigned int sampleCount;
char * sampleBuffer; char * sampleBuffer;
size_t sampleBufferLen; size_t sampleBufferLen;
unsigned int initial = 1;
int chunkLen = 0; int chunkLen = 0;
float * seekTable; /*float * seekTable;
long seekTableEnd = -1; long seekTableEnd = -1;
int seekPositionFound = 0; int seekPositionFound = 0;*/
long offset;
mpd_uint16 bitRate = 0; mpd_uint16 bitRate = 0;
AacBuffer b;
fh = fopen(dc->file,"r"); printf("aac_decode!\n");
if(!fh) {
ERROR("failed to open %s\n",dc->file);
return -1;
}
mp4cb = malloc(sizeof(mp4ff_callback_t)); if(initAacBuffer(dc->file,&b,&totalTime) < 0) {
mp4cb->read = mp4_readCallback; ERROR("Not AAC file no ADTS or ADIF headers found.\n");
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);
return -1; return -1;
} }
@ -285,48 +257,33 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
af->bits = 16; af->bits = 16;
mp4Buffer = NULL; fillAacBuffer(&b);
mp4BufferSize = 0; if((bread = faacDecInit(decoder,b.buffer,b.bytesIntoBuffer,
mp4ff_get_decoder_config(mp4fh,track,&mp4Buffer,&mp4BufferSize); &sampleRate,&channels)) < 0)
if(faacDecInit2(decoder,mp4Buffer,mp4BufferSize,&sampleRate,&channels)
< 0)
{ {
ERROR("Error initializing AAC decoder library.\n"); ERROR("Error not a AAC stream.\n");
faacDecClose(decoder); faacDecClose(decoder);
mp4ff_close(mp4fh); fclose(b.infile);
free(mp4cb); if(b.buffer) free(b.buffer);
fclose(fh);
return -1; return -1;
} }
af->sampleRate = sampleRate; af->sampleRate = sampleRate;
af->channels = channels; af->channels = channels;
time = mp4ff_get_track_duration_use_offsets(mp4fh,track);
scale = mp4ff_time_scale(mp4fh,track);
if(mp4Buffer) free(mp4Buffer); cb->totalTime = totalTime+0.5;
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);
dc->state = DECODE_STATE_DECODE; dc->state = DECODE_STATE_DECODE;
dc->start = 0; dc->start = 0;
time = 0.0; time = 0.0;
seekTable = malloc(sizeof(float)*numSamples); advanceAacBuffer(&b,bread);
fillAacBuffer(&b);
for(sampleId=0; sampleId<numSamples && !eof; sampleId++) { /*seekTable = malloc(sizeof(float)*numSamples);*/
if(dc->seek && seekTableEnd>1 &&
do {
/*if(dc->seek && seekTableEnd>1 &&
seekTable[seekTableEnd]>=dc->seekWhere) seekTable[seekTableEnd]>=dc->seekWhere)
{ {
int i = 2; int i = 2;
@ -335,9 +292,6 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
time = seekTable[sampleId]; time = seekTable[sampleId];
} }
dur = mp4ff_get_sample_duration(mp4fh,track,sampleId);
offset = mp4ff_get_sample_offset(mp4fh,track,sampleId);
if(sampleId>seekTableEnd) { if(sampleId>seekTableEnd) {
seekTable[sampleId] = time; seekTable[sampleId] = time;
seekTableEnd = sampleId; seekTableEnd = sampleId;
@ -358,42 +312,36 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
dc->seek = 0; dc->seek = 0;
} }
if(dc->seek) continue; if(dc->seek) continue;*/
if(mp4ff_read_sample(mp4fh,track,sampleId,&mp4Buffer, if(dc->seek) {
&mp4BufferSize) == 0) /*chunkLen = 0;
{ cb->wrap = 0;
eof = 1; cb->end = 0;*/
continue; 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) { if(frameInfo.error > 0) {
eof = 1; eof = 1;
break; break;
} }
if(channels*(dur+offset) > frameInfo.samples) { sampleCount = (unsigned long)(frameInfo.samples);
dur = frameInfo.samples;
offset = 0;
}
sampleCount = (unsigned long)(dur*channels);
if(sampleCount>0) { if(sampleCount>0) {
initial =0;
bitRate = frameInfo.bytesconsumed*8.0* bitRate = frameInfo.bytesconsumed*8.0*
frameInfo.channels*scale/ frameInfo.channels*sampleRate/
frameInfo.samples/1024+0.5; frameInfo.samples/1024+0.5;
time+= (float)(frameInfo.samples)/channels/sampleRate;
} }
sampleBufferLen = sampleCount*2; sampleBufferLen = sampleCount*2;
sampleBuffer+=offset*channels*2;
while(sampleBufferLen>0 && !dc->seek) { while(sampleBufferLen>0 && !dc->seek) {
size_t size = sampleBufferLen>CHUNK_SIZE-chunkLen ? size_t size = sampleBufferLen>CHUNK_SIZE-chunkLen ?
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) { if(!dc->stop && !dc->seek && chunkLen>0) {
cb->chunkSize[cb->end] = chunkLen; cb->chunkSize[cb->end] = chunkLen;
@ -440,11 +392,10 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
chunkLen = 0; chunkLen = 0;
} }
free(seekTable); /*free(seekTable);*/
faacDecClose(decoder); faacDecClose(decoder);
mp4ff_close(mp4fh); fclose(b.infile);
fclose(fh); if(b.buffer) free(b.buffer);
free(mp4cb);
if(dc->seek) dc->seek = 0; 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->state = DECODE_STATE_STOP;
dc->stop = 0; dc->stop = 0;
} }
else dc->state = DECODE_STATE_STOP;*/ else dc->state = DECODE_STATE_STOP;
return 0; return 0;
} }

View File

@ -2,8 +2,6 @@
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org * This project's homepage is: http://www.musicpd.org
* *
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or

View File

@ -86,7 +86,7 @@ int audiofile_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc)
while(!eof) { while(!eof) {
if(dc->seek) { if(dc->seek) {
cb->end = 0; cb->end = cb->begin;
cb->wrap = 0; cb->wrap = 0;
current = dc->seekWhere * af->sampleRate; current = dc->seekWhere * af->sampleRate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK,current); afSeekFrame(af_fp, AF_DEFAULT_TRACK,current);

View File

@ -40,6 +40,7 @@
#endif #endif
#ifdef HAVE_FAAD #ifdef HAVE_FAAD
#include "mp4_decode.h" #include "mp4_decode.h"
#include "aac_decode.h"
#endif #endif
#include <signal.h> #include <signal.h>
@ -159,11 +160,11 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
pc->totalTime-0.1 : pc->totalTime-0.1 :
pc->seekWhere; pc->seekWhere;
dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere; dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere;
cb->begin = 0; dc->seekError = 0;
dc->seek = 1; dc->seek = 1;
pc->elapsedTime = dc->seekWhere;
pc->bitRate = 0; pc->bitRate = 0;
while(*decode_pid>0 && dc->seek) usleep(1000); while(*decode_pid>0 && dc->seek) usleep(1000);
if(dc->seekError) pc->elapsedTime = dc->seekWhere;
} }
} }
pc->seek = 0; pc->seek = 0;
@ -229,6 +230,9 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af,
break; break;
#endif #endif
#ifdef HAVE_FAAD #ifdef HAVE_FAAD
case DECODE_TYPE_AAC:
dc->error = aac_decode(cb,af,dc);
break;
case DECODE_TYPE_MP4: case DECODE_TYPE_MP4:
dc->error = mp4_decode(cb,af,dc); dc->error = mp4_decode(cb,af,dc);
break; break;

View File

@ -21,6 +21,8 @@
#include "../config.h" #include "../config.h"
#include "mpd_types.h"
#include <stdio.h> #include <stdio.h>
#include <sys/param.h> #include <sys/param.h>
@ -38,11 +40,12 @@
#define DECODE_ERROR_UNKTYPE 1 #define DECODE_ERROR_UNKTYPE 1
typedef struct _DecoderControl { typedef struct _DecoderControl {
int state; mpd_sint8 state;
int stop; mpd_sint8 stop;
int start; mpd_sint8 start;
int error; mpd_uint16 error;
int seek; mpd_sint8 seek;
mpd_sint8 seekError;
double seekWhere; double seekWhere;
char file[MAXPATHLEN+1]; char file[MAXPATHLEN+1];
} DecoderControl; } DecoderControl;

View File

@ -104,7 +104,7 @@ void flacPlayFile(char *file, Buffer * cb, AudioFormat * af,
if(dc->seek) { if(dc->seek) {
FLAC__uint64 sampleToSeek = dc->seekWhere* FLAC__uint64 sampleToSeek = dc->seekWhere*
af->sampleRate+0.5; af->sampleRate+0.5;
cb->end = 0; cb->end = cb->begin;
cb->wrap = 0; cb->wrap = 0;
if(FLAC__file_decoder_seek_absolute(flacDec, if(FLAC__file_decoder_seek_absolute(flacDec,
sampleToSeek)) sampleToSeek))

View File

@ -487,7 +487,7 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) {
if(dc->seek) { if(dc->seek) {
long i = 0; long i = 0;
cb->wrap = 0; cb->wrap = 0;
cb->end = 0; cb->end = cb->begin;
data->muteFrame = 1; data->muteFrame = 1;
while(i<data->highestFrame && dc->seekWhere > while(i<data->highestFrame && dc->seekWhere >
((float)mad_timer_count(data->times[i], ((float)mad_timer_count(data->times[i],

View File

@ -2,8 +2,6 @@
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org * This project's homepage is: http://www.musicpd.org
* *
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * 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) if(faacDecInit2(decoder,mp4Buffer,mp4BufferSize,&sampleRate,&channels)
< 0) < 0)
{ {
ERROR("Error initializing AAC decoder library.\n"); ERROR("Error not a AAC stream.\n");
faacDecClose(decoder); faacDecClose(decoder);
mp4ff_close(mp4fh); mp4ff_close(mp4fh);
free(mp4cb); free(mp4cb);
@ -210,7 +208,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
if(dc->seek && seekPositionFound) { if(dc->seek && seekPositionFound) {
seekPositionFound = 0; seekPositionFound = 0;
chunkLen = 0; chunkLen = 0;
cb->end = 0; cb->end = cb->begin;
cb->wrap = 0; cb->wrap = 0;
dc->seek = 0; dc->seek = 0;
} }
@ -233,7 +231,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
} }
if(channels*(dur+offset) > frameInfo.samples) { if(channels*(dur+offset) > frameInfo.samples) {
dur = frameInfo.samples; dur = frameInfo.samples/channels;
offset = 0; offset = 0;
} }

View File

@ -2,8 +2,6 @@
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org * This project's homepage is: http://www.musicpd.org
* *
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or

View File

@ -95,7 +95,7 @@ int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc)
while(!eof) { while(!eof) {
if(dc->seek) { if(dc->seek) {
cb->end = 0; cb->end = cb->begin;
cb->wrap = 0; cb->wrap = 0;
chunkpos = 0; chunkpos = 0;
ov_time_seek_page(&vf,dc->seekWhere); ov_time_seek_page(&vf,dc->seekWhere);