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

📄 a52dec.cpp

📁 完整的RTP RTSP代码库
💻 CPP
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is MPEG4IP. *  * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2004.  All Rights Reserved. *  * Contributor(s):  *              Bill May        wmay@cisco.com */#include "a52dec.h"#include <mp4v2/mp4.h>#include <mp4av/mp4av.h>#include <mpeg2ps/mpeg2_ps.h>#define LOGIT a52dec->m_vft->log_msg// We now support float data passed to the audio driver// if there is a problem, define FLOAT_TO_16, and we'll do the// float conversion here.//#define FLOAT_TO_16 1#ifndef FLOAT_TO_16#define FLOAT float#define CONVERT(a) (a)#define FLOAT_0 (0.0)#define FLOAT_FORMAT AUDIO_FMT_FLOAT#else#define FLOAT int16_t#define CONVERT(a) convert(*(int32_t *)&(a))#define FLOAT_0  (0)#define FLOAT_FORMAT AUDIO_FMT_S16#endif#if defined(FLOAT_TO_16) /* * lifted from a52dec output routines - license for this function is * GPL */static inline int16_t convert (int32_t i){    if (i > 0x43c07fff)	return 32767;    else if (i < 0x43bf8000)	return -32768;    else	return i - 0x43c00000;}#endif/* * Create ac3 audio structure */static codec_data_t *a52dec_codec_create (const char *stream_type,					  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){  a52dec_codec_t *a52dec;  a52dec = (a52dec_codec_t *)malloc(sizeof(a52dec_codec_t));  memset(a52dec, 0, sizeof(a52dec_codec_t));  a52dec->m_vft = vft;  a52dec->m_ifptr = ifptr;  a52dec->m_initialized = 0;  a52dec->m_state = a52_init(0);#ifdef OUTPUT_TO_FILE  a52dec->m_outfile = fopen("raw.ac3", FOPEN_WRITE_BINARY);#endif  return (codec_data_t *)a52dec;}static void a52dec_close (codec_data_t *ptr){  a52dec_codec_t *a52dec = (a52dec_codec_t *)ptr;  a52_free(a52dec->m_state);#ifdef OUTPUT_TO_FILE  fclose(a52dec->m_outfile);#endif  free(a52dec);}/* * Handle pause - basically re-init the codec */static void a52dec_do_pause (codec_data_t *ifptr){}/* * These routines convert to the interleaved format that we want * to use */static inline FLOAT *a52_mono (FLOAT *o, sample_t *s, bool have_lfe){  sample_t *first;  int ix;  if (have_lfe) first = &s[256];  else first = s;  for (ix = 0; ix < 256; ix++) {    FLOAT value = CONVERT(first[ix]);    if (have_lfe) {      *o++ = value;      *o++ = value;      *o++ = value;      *o++ = value;    }    *o++ = value;    if (have_lfe) {      *o++ = CONVERT(s[ix]);    }  }  return o;}static inline FLOAT *a52_stereo (FLOAT *o, sample_t *sample, bool have_lfe){  sample_t *first;  int ix;  if (have_lfe) first = &sample[256];  else first = sample;  for (ix = 0; ix < 256; ix++) {    FLOAT l = CONVERT(first[ix]);    FLOAT r = CONVERT(first[ix + 256]);        *o++ = l;    *o++ = r;    if (have_lfe) {      *o++ = l;      *o++ = r;      *o++ = (l + r) / 2;      *o++ = CONVERT(sample[ix]);    }  }  return o;}static inline FLOAT *a52_3f (FLOAT *outptr, sample_t *sample, bool have_lfe){  int ix;  sample_t *first;  if (have_lfe) {    first = &sample[256];  } else {    first = sample;  }  for (ix = 0; ix < 256; ix++) {    FLOAT l = CONVERT(first[ix]);    FLOAT r = CONVERT(first[ix + 512]);    *outptr++ = l;    *outptr++ = r;    *outptr++ = l;    *outptr++ = r;    *outptr++ = CONVERT(first[ix+256]);    if (have_lfe) *outptr++ = CONVERT(sample[ix]);  }  return outptr;}static inline FLOAT *a52_2f2r (FLOAT *o, sample_t *sample, bool have_lfe){  int ix;  sample_t *first;  if (have_lfe) first = &sample[256];  else first = sample;  for (ix = 0; ix < 256; ix++) {    *o++ = CONVERT(first[ix]);    *o++ = CONVERT(first[ix + 256]);    *o++ = CONVERT(first[ix + 512]);    *o++ = CONVERT(first[ix + 768]);    if (have_lfe) {      *o++ = FLOAT_0;      *o++ = CONVERT(sample[ix]);    }  }  return o;}static inline FLOAT *a52_3f2r (FLOAT *o, sample_t *sample, bool have_lfe){  int ix;  sample_t *first;  if (have_lfe) first = &sample[256];  else first = sample;  for (ix = 0; ix < 256; ix++) {    *o++ = CONVERT(first[ix]);    if (have_lfe == false) {      *o++ = CONVERT(first[ix + 256]);    }    *o++ = CONVERT(first[ix + 512]);    *o++ = CONVERT(first[ix + 768]);    *o++ = CONVERT(first[ix + 1024]);    if (have_lfe) {      *o++ = CONVERT(first[ix + 256]);      *o++ = CONVERT(sample[ix]);    }  }  return o;}/* * Decode task call for ac3 */static int a52dec_decode (codec_data_t *ptr,			  frame_timestamp_t *pts,			  int from_rtp,			  int *sync_frame,			  uint8_t *buffer,			  uint32_t buflen,			  void *ud){  a52dec_codec_t *a52dec = (a52dec_codec_t *)ptr;  sample_t level, bias;  int flags;  uint32_t len;  int sample_rate;  int bit_rate;  uint64_t ts;  uint32_t freq_ts;  // we probably don't need this each time; it won't hurt to  // check everything out  len = a52_syncinfo(buffer, &flags, &sample_rate, &bit_rate);  if (len > buflen || len == 0) {    LOGIT(LOG_ERR, "a52dec", "buffer len too small %d", len);    return buflen;  }#ifdef OUTPUT_TO_FILE  fwrite(buffer, buflen, 1, a52dec->m_outfile);#endif    // these variables are needed - I'm not sure why  level = 1;  bias = 384;  flags |= A52_ADJUST_LEVEL;  // This reads the header and gets ready for the decode  if (a52_frame(a52dec->m_state, 		buffer, 		&flags, 		&level, 		bias)) {    LOGIT(LOG_DEBUG, "a52dec", "a52 frame did not return 0");    return buflen;  }  ts = pts->msec_timestamp;  freq_ts = pts->audio_freq_timestamp;  if (pts->audio_freq != (uint32_t)sample_rate) {    freq_ts = convert_timescale(freq_ts, pts->audio_freq, sample_rate);  }  if (a52dec->m_initialized == 0) {    if (flags & A52_LFE) {      a52dec->m_chans = 6;      LOGIT(LOG_DEBUG, "a52dec", "has lfe - 6 channel");    } else {      switch (flags & A52_CHANNEL_MASK) {      case A52_MONO:	a52dec->m_chans = 1;	break;      case A52_CHANNEL:      case A52_STEREO:      case A52_DOLBY:	a52dec->m_chans = 2;	break;      case A52_2F2R:	a52dec->m_chans = 4;	break;      default:	a52dec->m_chans = 5;	break;      }      LOGIT(LOG_DEBUG, "a52dec", "channels are %u", a52dec->m_chans);    }    a52dec->m_freq = sample_rate;    // we could probably deal with more channels here    a52dec->m_vft->audio_configure(a52dec->m_ifptr,				   sample_rate, 				   a52dec->m_chans, 				   FLOAT_FORMAT,				   256 * 6);    a52dec->m_initialized = 1;    a52dec->m_last_ts = ts;  } else {    // make sure that we're not repeating timestamps here    if (ts == a52dec->m_last_ts) {      a52dec->m_frames_at_ts++;      // there are 256 * 6 samples in each ac3 decode.      ts += a52dec->m_frames_at_ts * 256 * 6 * 1000 / sample_rate;      freq_ts += a52dec->m_frames_at_ts * 256 * 6;    } else {      a52dec->m_frames_at_ts = 0;      a52dec->m_last_ts = ts;    }  }  uint8_t *outbuf;  // get an output buffer  outbuf = a52dec->m_vft->audio_get_buffer(a52dec->m_ifptr,					   freq_ts,					   ts);  if (outbuf == NULL) {    return len;  }  FLOAT *outptr;  outptr = (FLOAT *)outbuf;  // Main guts of program - decode the 6 blocks.  Each block will decode  // 256 samples.  for (int i = 0; i < 6; i++) {    if (a52_block(a52dec->m_state)) {      return len;    }    // get the sample pointer, and convert it from float to int16_t    sample_t *sample = a52_samples(a52dec->m_state);    if (sample == NULL) {      LOGIT(LOG_CRIT, "a52dec", "nullpointer from samples");      return len;    }    /*     * write the sample data to the audio ring buffer in interleaved     * format     */    switch (flags & (A52_CHANNEL_MASK | A52_LFE)) {    case A52_MONO:      outptr = a52_mono(outptr, sample, false);      break;    case A52_MONO | A52_LFE:      outptr = a52_mono(outptr, sample, true);      break;    case A52_STEREO:    case A52_CHANNEL:    case A52_DOLBY:      outptr = a52_stereo(outptr, sample, false);      break;    case A52_STEREO | A52_LFE:    case A52_CHANNEL | A52_LFE:    case A52_DOLBY | A52_LFE:      outptr = a52_stereo(outptr, sample, true);      break;    case A52_3F:      outptr = a52_3f(outptr, sample, false);      break;    case A52_3F | A52_LFE:      outptr = a52_3f(outptr, sample, true);      break;    case A52_2F2R:      outptr = a52_2f2r(outptr, sample, false);      break;    case A52_2F2R | A52_LFE:      outptr = a52_2f2r(outptr, sample, true);      break;    case A52_3F2R:      outptr = a52_3f2r(outptr, sample, false);      break;    case A52_3F2R | A52_LFE:      outptr = a52_3f2r(outptr, sample, true);      break;    }  }    //  LOGIT(LOG_DEBUG, "a52dec", "wrote into frame "U64" %x", ts, flags);  a52dec->m_vft->audio_filled_buffer(a52dec->m_ifptr);  return (len);}static int a52dec_codec_check (lib_message_func_t message,			       const char *stream_type,			       const char *compressor,			       int type,			       int profile,			       format_list_t *fptr, 			       const uint8_t *userdata,			       uint32_t userdata_size,			       CConfigSet *pConfig){  if (strcasecmp(stream_type, STREAM_TYPE_MP4_FILE) == 0 &&      type != -1) {    // we don't handle this yet...    return -1;   }  if ((strcasecmp(stream_type, STREAM_TYPE_MPEG_FILE) == 0) &&      (type == MPEG_AUDIO_AC3)) { // AUDIO_AC3 from mpeg file    return 1;  }  if ((strcasecmp(stream_type, STREAM_TYPE_MPEG2_TRANSPORT_STREAM) == 0) &&	(type == 129)) {    return 1;  }						      return -1;}AUDIO_CODEC_WITH_RAW_FILE_PLUGIN("a52dec",				 a52dec_codec_create,				 a52dec_do_pause,				 a52dec_decode,				 NULL,				 a52dec_close,				 a52dec_codec_check,				 ac3_file_check,				 ac3_file_next_frame,				 ac3_file_used_for_frame,				 ac3_raw_file_seek_to,				 ac3_file_eof,				 NULL, 				 0);/* end file a52dec.cpp */

⌨️ 快捷键说明

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