mirror of
https://github.com/mpv-player/mpv
synced 2025-01-20 21:07:29 +01:00
Port dec_audio.c faad aac decoder to libmpcodecs, cleaned up code, improved buffering scheme.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@5357 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
9ef25a9736
commit
96b58cfa58
@ -3,7 +3,7 @@ include ../config.mak
|
||||
|
||||
LIBNAME = libmpcodecs.a
|
||||
|
||||
AUDIO_SRCS=dec_audio.c ad.c ad_a52.c ad_acm.c ad_alaw.c ad_dk3adpcm.c ad_dk4adpcm.c ad_dshow.c ad_dvdpcm.c ad_ffmpeg.c ad_hwac3.c ad_imaadpcm.c ad_mp3.c ad_msadpcm.c ad_pcm.c ad_roqaudio.c ad_msgsm.c
|
||||
AUDIO_SRCS=dec_audio.c ad.c ad_a52.c ad_acm.c ad_alaw.c ad_dk3adpcm.c ad_dk4adpcm.c ad_dshow.c ad_dvdpcm.c ad_ffmpeg.c ad_hwac3.c ad_imaadpcm.c ad_mp3.c ad_msadpcm.c ad_pcm.c ad_roqaudio.c ad_msgsm.c ad_faad.c
|
||||
VIDEO_SRCS=dec_video.c vd.c vd_null.c vd_cinepak.c vd_qtrpza.c vd_ffmpeg.c vd_dshow.c vd_vfw.c vd_odivx.c vd_divx4.c vd_raw.c vd_xanim.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_nuv.c vd_libmpeg2.c vd_msrle.c vd_huffyuv.c vd_zlib.c
|
||||
|
||||
ifeq ($(PNG),yes)
|
||||
|
@ -31,6 +31,7 @@ extern ad_functions_t mpcodecs_ad_roqaudio;
|
||||
extern ad_functions_t mpcodecs_ad_dshow;
|
||||
extern ad_functions_t mpcodecs_ad_acm;
|
||||
extern ad_functions_t mpcodecs_ad_msgsm;
|
||||
extern ad_functions_t mpcodecs_ad_faad;
|
||||
|
||||
ad_functions_t* mpcodecs_ad_drivers[] =
|
||||
{
|
||||
@ -55,6 +56,9 @@ ad_functions_t* mpcodecs_ad_drivers[] =
|
||||
&mpcodecs_ad_dshow,
|
||||
#endif
|
||||
&mpcodecs_ad_acm,
|
||||
#endif
|
||||
#ifdef HAVE_FAAD
|
||||
&mpcodecs_ad_faad,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
204
libmpcodecs/ad_faad.c
Normal file
204
libmpcodecs/ad_faad.c
Normal file
@ -0,0 +1,204 @@
|
||||
/* ad_faad.c - MPlayer AAC decoder using libfaad2
|
||||
* This file is part of MPlayer, see http://mplayerhq.hu/ for info.
|
||||
* (c)2002 by Felix Buenemann <atmosfear at users.sourceforge.net>
|
||||
* File licensed under the GPL, see http://www.fsf.org/ for more info.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ad_internal.h"
|
||||
|
||||
#ifdef HAVE_FAAD
|
||||
|
||||
static ad_info_t info =
|
||||
{
|
||||
"AAC (MPEG2/4 Advanced Audio Coding)",
|
||||
"libfaad2",
|
||||
AFM_AAC,
|
||||
"Felix Buenemann",
|
||||
"faad2",
|
||||
"Under development!"
|
||||
};
|
||||
|
||||
LIBAD_EXTERN(faad)
|
||||
|
||||
#include <faad.h>
|
||||
|
||||
/* configure maximum supported channels, *
|
||||
* this is theoretically max. 64 chans */
|
||||
#define FAAD_MAX_CHANNELS 6
|
||||
#define FAAD_BUFFLEN (FAAD_MIN_STREAMSIZE*FAAD_MAX_CHANNELS)
|
||||
|
||||
//#define AAC_DUMP_COMPRESSED
|
||||
|
||||
static faacDecHandle faac_hdec;
|
||||
static faacDecFrameInfo faac_finfo;
|
||||
|
||||
static int preinit(sh_audio_t *sh)
|
||||
{
|
||||
sh->audio_in_minsize=FAAD_BUFFLEN;
|
||||
sh->audio_out_minsize=2048*FAAD_MAX_CHANNELS;
|
||||
|
||||
// XXX: why is this duplicated in sh struct? ::atmos
|
||||
sh->a_in_buffer_size=sh->audio_in_minsize;
|
||||
sh->a_in_buffer=malloc(sh->a_in_buffer_size);
|
||||
sh->a_in_buffer_len=0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int init(sh_audio_t *sh)
|
||||
{
|
||||
unsigned long faac_samplerate, faac_channels;
|
||||
int faac_init;
|
||||
faac_hdec = faacDecOpen();
|
||||
|
||||
sh->a_in_buffer_len = demux_read_data(sh->ds, sh->a_in_buffer, sh->a_in_buffer_size);
|
||||
|
||||
// If we don't get the ES descriptor, try manual config
|
||||
if(!sh->codecdata_len) {
|
||||
#if 1
|
||||
faacDecConfigurationPtr faac_conf;
|
||||
/* Set the default object type and samplerate */
|
||||
/* This is useful for RAW AAC files */
|
||||
faac_conf = faacDecGetCurrentConfiguration(faac_hdec);
|
||||
if(sh->samplerate)
|
||||
faac_conf->defSampleRate = sh->samplerate;
|
||||
/* XXX: FAAD support FLOAT output, how do we handle
|
||||
* that (FAAD_FMT_FLOAT)? ::atmos
|
||||
*/
|
||||
if(sh->samplesize)
|
||||
switch(sh->samplesize){
|
||||
case 1: // 8Bit
|
||||
mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: 8Bit samplesize not supported by FAAD, assuming 16Bit!\n");
|
||||
default:
|
||||
case 2: // 16Bit
|
||||
faac_conf->outputFormat = FAAD_FMT_16BIT;
|
||||
break;
|
||||
case 3: // 24Bit
|
||||
faac_conf->outputFormat = FAAD_FMT_24BIT;
|
||||
break;
|
||||
case 4: // 32Bit
|
||||
faac_conf->outputFormat = FAAD_FMT_32BIT;
|
||||
break;
|
||||
}
|
||||
//faac_conf->defObjectType = LTP; // => MAIN, LC, SSR, LTP available.
|
||||
|
||||
faacDecSetConfiguration(faac_hdec, faac_conf);
|
||||
#endif
|
||||
|
||||
/* init the codec */
|
||||
faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
|
||||
&faac_samplerate, &faac_channels);
|
||||
sh->a_in_buffer_len -= (faac_init > 0)?faac_init:0; // how many bytes init consumed
|
||||
|
||||
} else { // We have ES DS in codecdata
|
||||
/*int i;
|
||||
for(i = 0; i < sh_audio->codecdata_len; i++)
|
||||
printf("codecdata_dump %d: 0x%02X\n", i, sh_audio->codecdata[i]);*/
|
||||
|
||||
faac_init = faacDecInit2(faac_hdec, sh->codecdata,
|
||||
sh->codecdata_len, &faac_samplerate, &faac_channels);
|
||||
}
|
||||
if(faac_init < 0) {
|
||||
mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to initialize the decoder!\n"); // XXX: deal with cleanup!
|
||||
faacDecClose(faac_hdec);
|
||||
// XXX: free a_in_buffer here or in uninit?
|
||||
return 0;
|
||||
} else {
|
||||
mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug!
|
||||
mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %dHz channels: %d\n", faac_samplerate, faac_channels);
|
||||
sh->channels = faac_channels;
|
||||
sh->samplerate = faac_samplerate;
|
||||
//sh->o_bps = sh->samplesize*faac_channels*faac_samplerate;
|
||||
if(!sh->i_bps) {
|
||||
mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: compressed input bitrate missing, assuming 128kbit/s!\n");
|
||||
sh->i_bps = 128*1000/8; // XXX: HACK!!! ::atmos
|
||||
} else
|
||||
mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: got %dkbit/s bitrate from MP4 header!\n",sh->i_bps*8/1000);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void uninit(sh_audio_t *sh)
|
||||
{
|
||||
mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Closing decoder!\n");
|
||||
faacDecClose(faac_hdec);
|
||||
if(sh->a_in_buffer_size) {
|
||||
free(sh->a_in_buffer);
|
||||
sh->a_in_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int control(sh_audio_t *sh,int cmd,void* arg, ...)
|
||||
{
|
||||
switch(cmd)
|
||||
{
|
||||
#if 0
|
||||
case ADCTRL_RESYNC_STREAM:
|
||||
return CONTROL_TRUE;
|
||||
case ADCTRL_SKIP_FRAME:
|
||||
return CONTROL_TRUE;
|
||||
#endif
|
||||
}
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
|
||||
static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen)
|
||||
{
|
||||
int j = 0, len = 0;
|
||||
void *faac_sample_buffer;
|
||||
//memset(sh->a_buffer,0,sh->a_buffer_size); // XXX: check if needed.
|
||||
|
||||
while(len < minlen) {
|
||||
/* update buffer */
|
||||
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
|
||||
do {
|
||||
faac_sample_buffer = faacDecDecode(faac_hdec, &faac_finfo, sh->a_in_buffer+j);
|
||||
/* 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;
|
||||
memcpy(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: Trying to resync!\n");
|
||||
j++;
|
||||
} else
|
||||
break;
|
||||
} while(j < FAAD_BUFFLEN);
|
||||
|
||||
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 (%d Bytes)!\n",
|
||||
sh->samplesize*faac_finfo.samples);
|
||||
memcpy(buf+len,faac_sample_buffer, sh->samplesize*faac_finfo.samples);
|
||||
len += sh->samplesize*faac_finfo.samples;
|
||||
//printf("FAAD: buffer: %d bytes consumed: %d \n", k, faac_finfo.bytesconsumed);
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_FAAD */
|
||||
|
Loading…
Reference in New Issue
Block a user