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

📄 faad2.cpp

📁 the mpeg2/4 aac decoder
💻 CPP
字号:
/*** MPEG4IP plugin for FAAD2** Copyright (C) 2003 Bill May wmay@cisco.com**** 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** (at your option) any later version.**** This program 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 General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.**** $Id: faad2.cpp,v 1.3 2004/08/20 08:30:53 menno Exp $**/#include "faad2.h"#include <mpeg4_audio_config.h>#include <mpeg4_sdp.h>#include <mp4.h>#include <SDL/SDL.h>#define DEBUG_SYNC 2#ifndef M_LLU#define M_LLU M_64#define LLU U64#endifconst char *aaclib="faad2";/* * Create CAACodec class */static codec_data_t *aac_codec_create (const char *compressor,                       int type,                       int profile,                       format_list_t *media_fmt,                       audio_info_t *audio,                       const uint8_t *userdata,                       uint32_t userdata_size,                       audio_vft_t *vft,                       void *ifptr){  aac_codec_t *aac;  aac = (aac_codec_t *)malloc(sizeof(aac_codec_t));  memset(aac, 0, sizeof(aac_codec_t));  aac->m_vft = vft;  aac->m_ifptr = ifptr;  fmtp_parse_t *fmtp = NULL;  // Start setting up FAAC stuff...  aac->m_resync_with_header = 1;  aac->m_record_sync_time = 1;  aac->m_audio_inited = 0;  // Use media_fmt to indicate that we're streaming.  if (media_fmt != NULL) {    // haven't checked for null buffer    // This is not necessarilly right - it is, for the most part, but    // we should be reading the fmtp statement, and looking at the config.    // (like we do below in the userdata section...    aac->m_freq = media_fmt->rtpmap->clock_rate;    fmtp = parse_fmtp_for_mpeg4(media_fmt->fmt_param, vft->log_msg);    if (fmtp != NULL) {      userdata = fmtp->config_binary;      userdata_size = fmtp->config_binary_len;    }  }  aac->m_info = faacDecOpen();  unsigned long srate;  unsigned char chan;  if ((userdata == NULL && fmtp == NULL) ||      (faacDecInit2(aac->m_info,             (uint8_t *)userdata,             userdata_size,            &srate,             &chan) < 0)) {      if (fmtp != NULL) free_fmtp_parse(fmtp);      return NULL;  }  mp4AudioSpecificConfig mp4ASC;  aac->m_output_frame_size = 1024;  if (AudioSpecificConfig((unsigned char *)userdata,              userdata_size,              &mp4ASC)) {    if (mp4ASC.frameLengthFlag) {      aac->m_output_frame_size = 960;    }  }  aac->m_freq = srate;  aac->m_chans = chan;  aac->m_faad_inited = 1;  aac->m_msec_per_frame = aac->m_output_frame_size;  aac->m_msec_per_frame *= M_LLU;  aac->m_msec_per_frame /= aac->m_freq;  //  faad_init_bytestream(&m_info->ld, c_read_byte, c_bookmark, m_bytestream);  aa_message(LOG_INFO, aaclib, "Setting freq to %d", aac->m_freq);#if DUMP_OUTPUT_TO_FILE  aac->m_outfile = fopen("temp.raw", "w");#endif  if (fmtp != NULL) {    free_fmtp_parse(fmtp);  }  return (codec_data_t *)aac;}void aac_close (codec_data_t *ptr){  if (ptr == NULL) {    return;  }  aac_codec_t *aac = (aac_codec_t *)ptr;  faacDecClose(aac->m_info);  aac->m_info = NULL;#if DUMP_OUTPUT_TO_FILE  fclose(aac->m_outfile);#endif  free(aac);}/* * Handle pause - basically re-init the codec */static void aac_do_pause (codec_data_t *ifptr){  aac_codec_t *aac = (aac_codec_t *)ifptr;  aac->m_resync_with_header = 1;  aac->m_record_sync_time = 1;  aac->m_audio_inited = 0;  aac->m_ignore_first_sample = 0;  faacDecPostSeekReset(aac->m_info, 0);}/* * Decode task call for FAAC */static int aac_decode (codec_data_t *ptr,               uint64_t ts,               int from_rtp,               int *sync_frame,               uint8_t *buffer,               uint32_t buflen,               void *userdata){  aac_codec_t *aac = (aac_codec_t *)ptr;  unsigned long bytes_consummed;  int bits = -1;  //  struct timezone tz;  if (aac->m_record_sync_time) {    aac->m_current_frame = 0;    aac->m_record_sync_time = 0;    aac->m_current_time = ts;    aac->m_last_rtp_ts = ts;  } else {    if (aac->m_last_rtp_ts == ts) {      aac->m_current_time += aac->m_msec_per_frame;      aac->m_current_frame++;    } else {      aac->m_last_rtp_ts = ts;      aac->m_current_time = ts;      aac->m_current_frame = 0;    }    // Note - here m_current_time should pretty much always be >= rtpts.    // If we're not, we most likely want to stop and resync.  We don't    // need to keep decoding - just decode this frame and indicate we    // need a resync... That should handle fast forwards...  We need    // someway to handle reverses - perhaps if we're more than .5 seconds    // later...  }  if (aac->m_faad_inited == 0) {    /*     * If not initialized, do so.     */    abort();    unsigned long freq;    unsigned char chans;    faacDecInit(aac->m_info,        (unsigned char *)buffer,        buflen,        &freq,        &chans);    aac->m_freq = freq;    aac->m_chans = chans;    aac->m_faad_inited = 1;  }  uint8_t *buff;  unsigned long samples;  bytes_consummed = buflen;  //aa_message(LOG_DEBUG, aaclib, "decoding %d bits", buflen * 8);  faacDecFrameInfo frame_info;  buff = (uint8_t *)faacDecDecode(aac->m_info,                  &frame_info,                  buffer,                  buflen);  if (buff != NULL) {    bytes_consummed = frame_info.bytesconsumed;#if 0    aa_message(LOG_DEBUG, aaclib, LLU" bytes %d samples %d",           ts, bytes_consummed, frame_info.samples);#endif    if (aac->m_audio_inited != 0) {      int tempchans = frame_info.channels;      if (tempchans != aac->m_chans) {    aa_message(LOG_NOTICE, aaclib, "chupdate - chans from data is %d",           tempchans);      }    } else {      int tempchans = frame_info.channels;      if (tempchans == 0) {    aa_message(LOG_ERR, aaclib, "initializing aac, returned channels are 0");    aac->m_resync_with_header = 1;    aac->m_record_sync_time = 1;    return bytes_consummed;      }      aac->m_chans = tempchans;      aac->m_freq = frame_info.samplerate;      aac->m_vft->audio_configure(aac->m_ifptr,                  aac->m_freq,                  aac->m_chans,                  (audio_format_t)AUDIO_S16SYS,                  aac->m_output_frame_size);      uint8_t *now = aac->m_vft->audio_get_buffer(aac->m_ifptr);      aac->m_audio_inited = 1;    }    /*     * good result - give it to audio sync class     */#if DUMP_OUTPUT_TO_FILE    fwrite(buff, aac->m_output_frame_size * 4, 1, aac->m_outfile);#endif    if (frame_info.samples != 0) {      aac->m_vft->audio_load_buffer(aac->m_ifptr,                    buff,                    frame_info.samples * 2,                    aac->m_last_ts,                    aac->m_resync_with_header);      if (aac->m_resync_with_header == 1) {    aac->m_resync_with_header = 0;#ifdef DEBUG_SYNC    aa_message(LOG_DEBUG, aaclib, "Back to good at "LLU, aac->m_current_time);#endif      }    }  } else {    aa_message(LOG_ERR, aaclib, "error return is %d", frame_info.error);    aac->m_resync_with_header = 1;#ifdef DEBUG_SYNC    aa_message(LOG_ERR, aaclib, "Audio decode problem - at "LLU,           aac->m_current_time);#endif  }  aac->m_last_ts = aac->m_current_time;  return (bytes_consummed);}static const char *aac_compressors[] = {  "aac ",  "mp4a",  "enca",  NULL};static int aac_codec_check (lib_message_func_t message,                const char *compressor,                int type,                int profile,                format_list_t *fptr,                const uint8_t *userdata,                uint32_t userdata_size#ifdef HAVE_PLUGIN_VERSION_0_8              ,CConfigSet *pConfig#endif              ){  fmtp_parse_t *fmtp = NULL;  if (compressor != NULL &&      strcasecmp(compressor, "MP4 FILE") == 0 &&      type != -1) {    switch (type) {    case MP4_MPEG2_AAC_MAIN_AUDIO_TYPE:    case MP4_MPEG2_AAC_LC_AUDIO_TYPE:    case MP4_MPEG2_AAC_SSR_AUDIO_TYPE:    case MP4_MPEG4_AUDIO_TYPE:      break;    default:      return -1;    }  }  if (fptr != NULL &&      fptr->rtpmap != NULL &&      fptr->rtpmap->encode_name != NULL) {    if (strcasecmp(fptr->rtpmap->encode_name, "mpeg4-generic") != 0) {      return -1;    }    if (userdata == NULL) {      fmtp = parse_fmtp_for_mpeg4(fptr->fmt_param, message);      if (fmtp != NULL) {    userdata = fmtp->config_binary;    userdata_size = fmtp->config_binary_len;      }    }  }  if (userdata != NULL) {    mpeg4_audio_config_t audio_config;    decode_mpeg4_audio_config(userdata, userdata_size, &audio_config);    message(LOG_DEBUG, "aac", "audio type is %d", audio_config.audio_object_type);    if (fmtp != NULL) free_fmtp_parse(fmtp);    if (audio_object_type_is_aac(&audio_config) == 0) {      return -1;    }#if 0    if (audio_config.audio_object_type == 17) {      message(LOG_INFO, "aac", "audio type is legal ISMA, but not supported");      return -1;    }#endif    return 2;  }#if 0  // I'm not sure I want to be here if we don't have an audio config  if (compressor != NULL) {    const char **lptr = aac_compressors;    while (*lptr != NULL) {      if (strcasecmp(*lptr, compressor) == 0) {    return 2;      }      lptr++;    }  }#endif  return -1;}#ifndef HAVE_PLUGIN_VERSION_0_8AUDIO_CODEC_WITH_RAW_FILE_PLUGIN("faad2",                 aac_codec_create,                 aac_do_pause,                 aac_decode,                 NULL,                 aac_close,                 aac_codec_check,                 aac_file_check,                 aac_file_next_frame,                 aac_file_used_for_frame,                 aac_raw_file_seek_to,               aac_file_eof               );#elseAUDIO_CODEC_WITH_RAW_FILE_PLUGIN("faad2",               aac_codec_create,               aac_do_pause,               aac_decode,               NULL,               aac_close,               aac_codec_check,               aac_file_check,               aac_file_next_frame,               aac_file_used_for_frame,               aac_raw_file_seek_to,               aac_file_eof,               NULL,               0               );#endif/* end file aa.cpp */

⌨️ 快捷键说明

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