Ejemplo n.º 1
0
/*
 * 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;
}
Ejemplo n.º 2
0
/*
 * Create CAACodec class
 */
static codec_data_t *aac_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)

{
  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_faad_inited = 0;
  aac->m_audio_inited = 0;
  aac->m_temp_buff = (uint8_t *)malloc(4096);

  // 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;
    }
  } else {
    if (audio != NULL) {
      aac->m_freq = audio->freq;
    } else {
      aac->m_freq = 44100;
    }
  }
  aac->m_chans = 2; // this may be wrong - the isma spec, Appendix A.1.1 of
  // Appendix H says the default is 1 channel...
  aac->m_output_frame_size = 1024;
  aac->m_object_type = AACMAIN;
  if (userdata != NULL || fmtp != NULL) {
    mpeg4_audio_config_t audio_config;
    decode_mpeg4_audio_config(userdata, userdata_size, &audio_config);
    aac->m_object_type = audio_config.audio_object_type;
    aac->m_freq = audio_config.frequency;
    aac->m_chans = audio_config.channels;
    if (audio_config.codec.aac.frame_len_1024 == 0) {
      aac->m_output_frame_size = 960;
    }
  }

  aa_message(LOG_INFO, aaclib,"AAC object type is %d", aac->m_object_type);
  aac->m_info = faacDecOpen();
  faacDecConfiguration config;
  config.defObjectType = aac->m_object_type;
  config.defSampleRate = aac->m_freq;
  faacDecSetConfiguration(aac->m_info, &config);
  aac->m_msec_per_frame = aac->m_output_frame_size;
  aac->m_msec_per_frame *= TO_U64(1000);
  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;
}
Ejemplo n.º 3
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_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);
}
Ejemplo n.º 4
0
/*
 * Decode task call for FAAC
 */
static int aac_decode (codec_data_t *ptr,
		       frame_timestamp_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;
  uint32_t freq_timestamp;

  freq_timestamp = ts->audio_freq_timestamp;
  if (ts->audio_freq != aac->m_freq) {
    freq_timestamp = convert_timescale(freq_timestamp,
				       ts->audio_freq,
				       aac->m_freq);
  }
  if (aac->m_record_sync_time) {
    aac->m_current_frame = 0;
    aac->m_record_sync_time = 0;
    aac->m_current_time = ts->msec_timestamp;
    aac->m_last_rtp_ts = ts->msec_timestamp;
  } else {
    if (aac->m_last_rtp_ts == ts->msec_timestamp) {
      aac->m_current_frame++;
      aac->m_current_time = aac->m_last_rtp_ts;
      aac->m_current_time += 
	aac->m_output_frame_size * aac->m_current_frame * 
	TO_U64(1000) / aac->m_freq;
      freq_timestamp += aac->m_output_frame_size * aac->m_current_frame;
    } else {
      aac->m_last_rtp_ts = ts->msec_timestamp;
      aac->m_current_time = ts->msec_timestamp;
      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.  
     */
      unsigned long freq, chans;

      faacDecInit(aac->m_info,
		  (unsigned char *)buffer,
		  &freq,
		  &chans);
      aac->m_freq = freq;
      aac->m_chans = chans;
      aac->m_faad_inited = 1;
    }

    uint8_t *buff;

    /* 
     * Get an audio buffer
     */
    if (aac->m_audio_inited == 0) {
      buff = aac->m_temp_buff;
    } else {
      buff = aac->m_vft->audio_get_buffer(aac->m_ifptr,
					  freq_timestamp,
					  aac->m_current_time);
    }
    if (buff == NULL) {
      //player_debug_message("Can't get buffer in aa");
      return (0);
    }

    unsigned long samples;
    bytes_consummed = buflen;
    //aa_message(LOG_DEBUG, aaclib, "decoding %d bits", buflen * 8);
    bits = faacDecDecode(aac->m_info,
			 (unsigned char *)buffer, 
			 &bytes_consummed,
			 (short *)buff, 
			 &samples);
    switch (bits) {
    case FAAD_OK_CHUPDATE:
      if (aac->m_audio_inited != 0) {
	int tempchans = faacDecGetProgConfig(aac->m_info, NULL);
	if (tempchans != aac->m_chans) {
	  aa_message(LOG_NOTICE, aaclib, "chupdate - chans from data is %d", 
			       tempchans);
	}
      }
      // fall through...
    case FAAD_OK:
      if (aac->m_audio_inited == 0) {
	int tempchans = faacDecGetProgConfig(aac->m_info, NULL);
	if (tempchans == 0) {
	  aac->m_resync_with_header = 1;
	  aac->m_record_sync_time = 1;
	  return bytes_consummed;
	}
	if (tempchans != aac->m_chans) {
	  aa_message(LOG_NOTICE, aaclib, "chans from data is %d conf %d", 
		     tempchans, aac->m_chans);
	  aac->m_chans = tempchans;
	}
	aac->m_vft->audio_configure(aac->m_ifptr,
				     aac->m_freq, 
				     aac->m_chans, 
				     AUDIO_FMT_S16, 
				     aac->m_output_frame_size);
	uint8_t *now = aac->m_vft->audio_get_buffer(aac->m_ifptr,
						    freq_timestamp,
						    aac->m_current_time);

	if (now != NULL) {
	  memcpy(now, buff, tempchans * aac->m_output_frame_size * sizeof(int16_t));
	}
	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
      aac->m_vft->audio_filled_buffer(aac->m_ifptr);
      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 "U64, aac->m_current_time);
#endif
      }
      break;
    default:
      aa_message(LOG_ERR, aaclib, "Bits return is %d", bits);
      aac->m_resync_with_header = 1;
#ifdef DEBUG_SYNC
      aa_message(LOG_ERR, aaclib, "Audio decode problem - at "U64, 
		 aac->m_current_time);
#endif
      break;
    }
  return (bytes_consummed);
}