extern "C" void decode_mpeg4_audio_config (const uint8_t *buffer, 
					   uint32_t buf_len,
					   mpeg4_audio_config_t *mptr)
{
  CBitstream bit;
  uint32_t ret;

  bit.init(buffer, buf_len * 8);

  if (bit.getbits(5, &ret) < 0)
    return;

  mptr->audio_object_type = ret;

  if (bit.getbits(4, &ret) < 0)
    return;

  if (ret == 0xf) {
    if (bit.getbits(24, &ret) < 0) 
      return;
    mptr->frequency = ret;
  } else {
    mptr->frequency = freq_index_to_freq[ret];
  }

  if (bit.getbits(4, &ret) < 0)
    return;

  mptr->channels = ret;

  // rptr points to remaining bits - starting with 0x04, moving
  // down buffer_len.
  if (audio_object_type_is_aac(mptr)) {
    if (bit.getbits(1, &ret) < 0)
      return;

    if (ret == 0) {
      mptr->codec.aac.frame_len_1024 = 1;
    } else {
      mptr->codec.aac.frame_len_1024 = 0;
    }
  } else if (audio_object_type_is_celp(mptr)){
    try {
      mptr->codec.celp.isBaseLayer = bit.GetBits(1);
      if (mptr->codec.celp.isBaseLayer == 0) {
	mptr->codec.celp.isBWSLayer = bit.GetBits(1);
	if (mptr->codec.celp.isBWSLayer == 0) {
	  mptr->codec.celp.CELP_BRS_id = bit.GetBits(2);
	}
      }

      mptr->codec.celp.NumOfBitsInBuffer=bit.bits_remain();
      mptr->codec.celp.excitation_mode = bit.GetBits(1);
      mptr->codec.celp.sample_rate_mode = bit.GetBits(1);
      mptr->codec.celp.fine_rate_control = bit.GetBits(1);
      if (mptr->codec.celp.excitation_mode == CELP_EXCITATION_MODE_RPE) {
	mptr->codec.celp.rpe_config = bit.GetBits(3);
	// 16000 is 10 msec, all others are 15 msec
	if (mptr->codec.celp.rpe_config == 1) // 16000 bitrate
	  mptr->codec.celp.samples_per_frame = (16000 * 10) / 1000;
	else
	  mptr->codec.celp.samples_per_frame = (16000 * 15) / 1000;
      } else {
	mptr->codec.celp.mpe_config = bit.GetBits(5);
	mptr->codec.celp.num_enh_layers = bit.GetBits(2);
	if (mptr->codec.celp.sample_rate_mode == 1) {
	  // 16kHz sample rate
	  if (mptr->codec.celp.mpe_config < 16) {
	    mptr->codec.celp.samples_per_frame = (16000 * 20) / 1000;
	  } else {
	    mptr->codec.celp.samples_per_frame = (16000 * 10) / 1000;
	  }
	} else {
	  if (bit.bits_remain() > 0) {
	    mptr->codec.celp.bwsm = bit.GetBits(1);
	  } else {
	    mptr->codec.celp.bwsm = 0;
	  }
	  if (mptr->codec.celp.mpe_config < 3) {
	    //40
	    mptr->codec.celp.samples_per_frame = (8000 * 40) / 1000;
	  } else if (mptr->codec.celp.mpe_config < 6) {
	    // 30
	    mptr->codec.celp.samples_per_frame = (8000 * 30) / 1000;
	  } else if (mptr->codec.celp.mpe_config < 22) {
	    // 20
	    mptr->codec.celp.samples_per_frame = (8000 * 20) / 1000;
	  } else if (mptr->codec.celp.mpe_config < 27) {
	    // 10
	    mptr->codec.celp.samples_per_frame = (8000 * 10) / 1000;
	  } else {
	    // 30
	    mptr->codec.celp.samples_per_frame = (8000 * 30) / 1000;
	  }
	  if (mptr->codec.celp.bwsm != 0) {
	    mptr->codec.celp.samples_per_frame *= 2;
	  }
	}      
      }
    } catch (...) {}
  }
}
Exemplo n.º 2
0
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;
}
/*
 * Isma rtp bytestream has a potential set of headers at the beginning
 * of each rtp frame.  This can interleave frames in different packets
 */
rtp_plugin_data_t *isma_rtp_plugin_create (format_list_t *media_fmt,
        uint8_t rtp_payload_type,
        rtp_vft_t *vft,
        void *ifptr)
{
    isma_enc_rtp_data_t *iptr;
    fmtp_parse_t *fmtp;

    iptr = MALLOC_STRUCTURE(isma_enc_rtp_data_t);
    if ( iptr == NULL )
        return NULL;

    memset(iptr, 0, sizeof(isma_enc_rtp_data_t));

    if (strcasecmp(media_fmt->media->media, "audio") == 0) {
        ismacrypInitSession(&(iptr->myEncSID), KeyTypeAudio);
    }

    iptr->m_vft = vft;
    iptr->m_ifptr = ifptr;

    iptr->m_rtp_packet_mutex = SDL_CreateMutex();
#ifdef ISMA_RTP_DUMP_OUTPUT_TO_FILE
    iptr->m_outfile = fopen("isma.aac", "w");
#endif
    iptr->m_frame_data_head = NULL;
    iptr->m_frame_data_on = NULL;
    iptr->m_frame_data_free = NULL;
    isma_frame_data_t *p;
    for (iptr->m_frame_data_max = 0; iptr->m_frame_data_max < 25; iptr->m_frame_data_max++) {
        p = (isma_frame_data_t *)malloc(sizeof(isma_frame_data_t));
        p->frame_data_next = iptr->m_frame_data_free;
        iptr->m_frame_data_free = p;
    }

    fmtp = parse_fmtp_for_mpeg4(media_fmt->fmt_param, iptr->m_vft->log_msg);

    mpeg4_audio_config_t audio_config;
    decode_mpeg4_audio_config(fmtp->config_binary,
                              fmtp->config_binary_len,
                              &audio_config);
    if (audio_object_type_is_aac(&audio_config)) {
        iptr->m_rtp_ts_add = audio_config.codec.aac.frame_len_1024 != 0 ? 1024 : 960;
    } else {
        iptr->m_rtp_ts_add = audio_config.codec.celp.samples_per_frame;
        isma_message(LOG_DEBUG, ismaencrtp, "celp spf is %d", iptr->m_rtp_ts_add);
    }
    iptr->m_rtp_ts_add = (iptr->m_rtp_ts_add * media_fmt->rtpmap->clock_rate) /
                         audio_config.frequency;
    isma_message(LOG_DEBUG, ismaencrtp,
                 "Rtp ts add is %d (%d %d)", iptr->m_rtp_ts_add,
                 media_fmt->rtpmap->clock_rate,
                 audio_config.frequency);
    iptr->m_fmtp = fmtp;
    iptr->m_min_first_header_bits = iptr->m_fmtp->size_length + iptr->m_fmtp->index_length;
    iptr->m_min_header_bits = iptr->m_fmtp->size_length + iptr->m_fmtp->index_delta_length;
    if (iptr->m_fmtp->CTS_delta_length > 0) {
        iptr->m_min_header_bits++;
        iptr->m_min_first_header_bits++;
    }
    if (iptr->m_fmtp->DTS_delta_length > 0) {
        iptr->m_min_header_bits++;
        iptr->m_min_first_header_bits++;
    }

    isma_message(LOG_DEBUG, ismaencrtp, "min headers are %d %d", iptr->m_min_first_header_bits,
                 iptr->m_min_header_bits);

    iptr->m_min_header_bits += iptr->m_fmtp->auxiliary_data_size_length;
    iptr->m_min_first_header_bits += iptr->m_fmtp->auxiliary_data_size_length;
    iptr->m_frag_reass_buffer = NULL;
    iptr->m_frag_reass_size_max = 0;
    return (&iptr->plug);
}
Exemplo n.º 4
0
static int aac_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)
{
  fmtp_parse_t *fmtp = NULL;
  if (compressor != NULL && 
      strcasecmp(stream_type, "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 (strcasecmp(stream_type, STREAM_TYPE_RTP) == 0 &&
      fptr != NULL && 
      fptr->rtpmap != NULL &&
      fptr->rtpmap->encode_name != NULL) {
    if ((strcasecmp(fptr->rtpmap->encode_name, "mpeg4-generic") != 0) &&
        (strcasecmp(fptr->rtpmap->encode_name, "enc-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 (audio_config.audio_object_type == 17) {
      message(LOG_INFO, "aac", "audio type is legal ISMA, but not supported");
      return -1;
    }
    return 1;
  }
  if (compressor != NULL) {
    const char **lptr = aac_compressors;
    while (*lptr != NULL) {
      if (strcasecmp(*lptr, compressor) == 0) {
	return 1;
      }
      lptr++;
    }
  }
  return -1;
}