You need to sign in or sign up before continuing.
Commit 145f0b62 authored by Warren Dukes's avatar Warren Dukes

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
parent 4c1eb922
......@@ -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 <normalperson@yhbt.net>
*
* 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;
}
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;
}
printf("aac_decode!\n");
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);
/*seekTable = malloc(sizeof(float)*numSamples);*/
for(sampleId=0; sampleId<numSamples && !eof; sampleId++) {
if(dc->seek && seekTableEnd>1 &&
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(dc->seek) continue;*/
if(mp4ff_read_sample(mp4fh,track,sampleId,&mp4Buffer,
&mp4BufferSize) == 0)
{
eof = 1;
continue;
if(dc->seek) {
/*chunkLen = 0;
cb->wrap = 0;
cb->end = 0;*/
dc->seekError = 1;
dc->seek = 0;
}
sampleBuffer = faacDecDecode(decoder,&frameInfo,mp4Buffer,
mp4BufferSize);
if(mp4Buffer) free(mp4Buffer);
sampleBuffer = faacDecDecode(decoder,&frameInfo,b.buffer,
b.bytesIntoBuffer);
advanceAacBuffer(&b,frameInfo.bytesconsumed);
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;
}
......
......@@ -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 <normalperson@yhbt.net>
*
* 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
......
......@@ -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);
......
......@@ -40,6 +40,7 @@
#endif
#ifdef HAVE_FAAD
#include "mp4_decode.h"
#include "aac_decode.h"
#endif
#include <signal.h>
......@@ -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;
......
......@@ -21,6 +21,8 @@
#include "../config.h"
#include "mpd_types.h"
#include <stdio.h>
#include <sys/param.h>
......@@ -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;
......
......@@ -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))
......
......@@ -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(i<data->highestFrame && dc->seekWhere >
((float)mad_timer_count(data->times[i],
......
......@@ -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 <normalperson@yhbt.net>
*
* 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;
}
......
......@@ -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 <normalperson@yhbt.net>
*
* 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
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment