⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 faad2.c

📁 这个库实现了录象功能
💻 C
字号:
/******************************************************************************* faad2.c libquicktime - A library for reading and writing quicktime/avi/mp4 files. http://libquicktime.sourceforge.net Copyright (C) 2002 Heroine Virtual Ltd. Copyright (C) 2002-2007 Members of the libquicktime project. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************/ #include "lqt_private.h"#define LQT_LIBQUICKTIME#include <quicktime/lqt_codecapi.h>#include "faad2.h"#include <string.h>#include <stdlib.h>#ifdef HAVE_NEAACDEC_H#include <neaacdec.h>/* *  Backwards compatibility names (currently in neaacdec.h, *  but might be removed in future versions) */#ifndef faacDecHandle/* structs */#define faacDecHandle                  NeAACDecHandle#define faacDecConfiguration           NeAACDecConfiguration#define faacDecConfigurationPtr        NeAACDecConfigurationPtr#define faacDecFrameInfo               NeAACDecFrameInfo/* functions */#define faacDecGetErrorMessage         NeAACDecGetErrorMessage#define faacDecSetConfiguration        NeAACDecSetConfiguration#define faacDecGetCurrentConfiguration NeAACDecGetCurrentConfiguration#define faacDecInit                    NeAACDecInit#define faacDecInit2                   NeAACDecInit2#define faacDecInitDRM                 NeAACDecInitDRM#define faacDecPostSeekReset           NeAACDecPostSeekReset#define faacDecOpen                    NeAACDecOpen#define faacDecClose                   NeAACDecClose#define faacDecDecode                  NeAACDecDecode#define AudioSpecificConfig            NeAACDecAudioSpecificConfig#endif#else#include <faad.h>#endif#define LOG_DOMAIN "faad2"typedef struct  {  faacDecHandle dec;  /* Start and end positions of the sample buffer */    int64_t sample_buffer_start;  int64_t sample_buffer_end;      uint8_t * data;  int data_alloc;    float * sample_buffer;  int sample_buffer_alloc;  int upsample;    } quicktime_faad2_codec_t;static int delete_codec(quicktime_audio_map_t *atrack)  {  quicktime_faad2_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;  if(codec->dec)    faacDecClose(codec->dec);  if(codec->sample_buffer)    free(codec->sample_buffer);  if(codec->data)    free(codec->data);          free(codec);  return 0;  }/* Channel IDs */static struct  {  int faad_ch;  lqt_channel_t lqt_ch;  }channels[] =   {    { FRONT_CHANNEL_CENTER, LQT_CHANNEL_FRONT_CENTER },    { FRONT_CHANNEL_LEFT,   LQT_CHANNEL_FRONT_LEFT },    { FRONT_CHANNEL_RIGHT,  LQT_CHANNEL_FRONT_RIGHT },    { SIDE_CHANNEL_LEFT,    LQT_CHANNEL_SIDE_LEFT },    { SIDE_CHANNEL_RIGHT,   LQT_CHANNEL_SIDE_RIGHT },    { BACK_CHANNEL_LEFT,    LQT_CHANNEL_BACK_LEFT },    { BACK_CHANNEL_RIGHT,   LQT_CHANNEL_BACK_RIGHT },    { BACK_CHANNEL_CENTER,  LQT_CHANNEL_BACK_CENTER },    { LFE_CHANNEL,          LQT_CHANNEL_LFE },    { UNKNOWN_CHANNEL,      LQT_CHANNEL_UNKNOWN }  };  static lqt_channel_t get_channel(int channel)  {  int i;  for(i = 0; i < sizeof(channels)/sizeof(channels[0]); i++)    {    if(channels[i].faad_ch == channel)      return channels[i].lqt_ch;    }  return LQT_CHANNEL_UNKNOWN;  }  static int decode_chunk(quicktime_t *file, int track)  {  int i, j, num_packets, num_samples, packet_size;  float * samples;  faacDecFrameInfo frame_info;  quicktime_audio_map_t *track_map = &(file->atracks[track]);    quicktime_faad2_codec_t *codec =    ((quicktime_codec_t*)file->atracks[track].codec)->priv;    num_packets = lqt_audio_num_vbr_packets(file, track, track_map->current_chunk, &num_samples);  if(!num_packets)    return 0;  if(codec->upsample)    num_samples *= 2;      if(codec->sample_buffer_alloc < codec->sample_buffer_end - codec->sample_buffer_start + num_samples)    {    codec->sample_buffer_alloc = codec->sample_buffer_end - codec->sample_buffer_start + num_samples + 1024;    codec->sample_buffer = realloc(codec->sample_buffer,                                   codec->sample_buffer_alloc * track_map->channels * sizeof(float));    }    for(i = 0; i < num_packets; i++)    {    packet_size = lqt_audio_read_vbr_packet(file, track, track_map->current_chunk, i,                                            &(codec->data),                                            &(codec->data_alloc), &num_samples);    if(codec->upsample)      num_samples *= 2;    samples = faacDecDecode(codec->dec, &frame_info,                            codec->data, packet_size);    if(!samples)      {      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "faacDecDecode failed %s",              faacDecGetErrorMessage(frame_info.error));            return 0;      }    /* Set up channel map */    if(!track_map->channel_setup)      {      track_map->channel_setup = calloc(track_map->channels,                                        sizeof(*(track_map->channel_setup)));      for(i = 0; i < track_map->channels; i++)        {        track_map->channel_setup[i] = get_channel(frame_info.channel_position[i]);        }      }                      if((track_map->channels == 1) && (frame_info.channels == 2))      {                  for(j = 0; j < frame_info.samples/2; j++)        samples[j] = samples[2*j];      frame_info.samples/=2;      }        memcpy(&(codec->sample_buffer[(codec->sample_buffer_end -                                   codec->sample_buffer_start)*track_map->channels]),           samples, frame_info.samples * sizeof(float));    codec->sample_buffer_end += frame_info.samples / track_map->channels;    }    track_map->current_chunk++;  return 1;  }static int decode(quicktime_t *file,                   void * output,                  long samples,                   int track)   {  int64_t chunk_sample;  int samples_copied = 0;  int samples_to_skip;  int samples_to_move;  int samples_decoded;    quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_faad2_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  /* TODO Check whether seeking happened */  if(!output)    {    /* Set channel setup */    decode_chunk(file, track);    return 0;    }    if(track_map->last_position != track_map->current_position)    {    /* Get the next chunk */        if(codec->upsample)      {      lqt_chunk_of_sample_vbr(&chunk_sample,                              &(track_map->current_chunk),                              track_map->track,                              track_map->current_position / 2);      chunk_sample *= 2;      }    else      lqt_chunk_of_sample_vbr(&chunk_sample,                              &(track_map->current_chunk),                              track_map->track,                              track_map->current_position);        if(track_map->current_chunk >= track_map->track->mdia.minf.stbl.stco.total_entries)      {      return 0;      }        codec->sample_buffer_start = chunk_sample;    codec->sample_buffer_end   = chunk_sample;    /* Decode frames until we have enough */    while(codec->sample_buffer_end < track_map->current_position + samples)      {      if(!decode_chunk(file, track))        break;      }    }    /* Flush unneeded samples */    if(track_map->current_position > codec->sample_buffer_start)    {    samples_to_skip = track_map->current_position - codec->sample_buffer_start;    samples_to_move = codec->sample_buffer_end - track_map->current_position;    if(samples_to_move > 0)      {      memmove(codec->sample_buffer, codec->sample_buffer + samples_to_skip * track_map->channels,              samples_to_move * track_map->channels * sizeof(float));      }    codec->sample_buffer_start = track_map->current_position;    if(samples_to_move > 0)      codec->sample_buffer_end = codec->sample_buffer_start + samples_to_move;    else      codec->sample_buffer_end = codec->sample_buffer_start;    }  /* Decode new chunks until we have enough samples */  while(codec->sample_buffer_end < codec->sample_buffer_start + samples)    {    if(!decode_chunk(file, track))      break;    }  samples_decoded = codec->sample_buffer_end - codec->sample_buffer_start;  samples_copied = (samples_decoded > samples) ? samples : samples_decoded;    memcpy(output, codec->sample_buffer, samples_copied * track_map->channels * sizeof(float));  track_map->last_position = track_map->current_position + samples_copied;    return samples_copied;  }static int set_parameter(quicktime_t *file, 		int track, 		const char *key, 		const void *value)  {  return 0;  }void quicktime_init_codec_faad2(quicktime_audio_map_t *atrack)  {  uint8_t * extradata = (uint8_t *)0;  int extradata_size = 0;  quicktime_stsd_t * stsd;  unsigned long samplerate = 0;  unsigned char channels;  faacDecConfigurationPtr cfg;    quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;  quicktime_faad2_codec_t *codec;  /* Init public items */  codec_base->priv = calloc(1, sizeof(quicktime_faad2_codec_t));  codec_base->delete_acodec = delete_codec;  codec_base->decode_audio = decode;  codec_base->set_parameter = set_parameter;    codec = codec_base->priv;  atrack->sample_format = LQT_SAMPLE_FLOAT;  /* Ok, usually, we initialize decoders during the first     decode() call, but in this case, we might need to     set the correct samplerate, which should be known before */  codec->dec = faacDecOpen();  stsd = &(atrack->track->mdia.minf.stbl.stsd);    if(stsd->table[0].has_esds)    {    extradata = stsd->table[0].esds.decoderConfig;    extradata_size =      stsd->table[0].esds.decoderConfigLen;    }  else if(stsd->table[0].has_wave &&          stsd->table[0].wave.has_esds)    {    extradata = stsd->table[0].wave.esds.decoderConfig;    extradata_size = stsd->table[0].wave.esds.decoderConfigLen;    }  else    {    lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN,            "No extradata found, decoding is doomed to failure");    }  cfg = faacDecGetCurrentConfiguration(codec->dec);  cfg->outputFormat = FAAD_FMT_FLOAT;    faacDecSetConfiguration(codec->dec, cfg);    faacDecInit2(codec->dec, extradata, extradata_size,               &samplerate, &channels);  if(atrack->samplerate != samplerate)    {    atrack->samplerate = samplerate;    codec->upsample = 1;    atrack->total_samples *= 2;    }  stsd->table[0].channels = channels;  atrack->channels = channels;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -