int dc_gpac_audio_moov_create(AudioOutputFile *audio_output_file, char *filename) { GF_Err ret; u32 di, track; u8 bpsample; GF_ESD *esd; #ifndef GPAC_DISABLE_AV_PARSERS GF_M4ADecSpecInfo acfg; #endif AVCodecContext *audio_codec_ctx = audio_output_file->codec_ctx; audio_output_file->isof = gf_isom_open(filename, GF_ISOM_OPEN_WRITE, NULL); if (!audio_output_file->isof) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open iso file %s\n", filename)); return -1; } esd = gf_odf_desc_esd_new(2); if (!esd) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create GF_ESD\n")); return -1; } esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); esd->decoderConfig->streamType = GF_STREAM_AUDIO; if (!strcmp(audio_output_file->codec_ctx->codec->name, "aac")) { //TODO: find an automatic table esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; esd->decoderConfig->bufferSizeDB = 20; esd->slConfig->timestampResolution = audio_codec_ctx->sample_rate; esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); esd->ESID = 1; #ifndef GPAC_DISABLE_AV_PARSERS memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); acfg.base_object_type = GF_M4A_AAC_LC; acfg.base_sr = audio_codec_ctx->sample_rate; acfg.nb_chan = audio_codec_ctx->channels; acfg.sbr_object_type = 0; acfg.audioPL = gf_m4a_get_profile(&acfg); ret = gf_m4a_write_config(&acfg, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); assert(ret == GF_OK); #endif } else { if (strcmp(audio_output_file->codec_ctx->codec->name, "mp2")) { GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("Unlisted codec, setting GPAC_OTI_AUDIO_MPEG1 descriptor.\n")); } esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG1; esd->decoderConfig->bufferSizeDB = 20; esd->slConfig->timestampResolution = audio_codec_ctx->sample_rate; esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); esd->ESID = 1; #ifndef GPAC_DISABLE_AV_PARSERS memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); acfg.base_object_type = GF_M4A_LAYER2; acfg.base_sr = audio_codec_ctx->sample_rate; acfg.nb_chan = audio_codec_ctx->channels; acfg.sbr_object_type = 0; acfg.audioPL = gf_m4a_get_profile(&acfg); ret = gf_m4a_write_config(&acfg, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); assert(ret == GF_OK); #endif } //gf_isom_store_movie_config(video_output_file->isof, 0); track = gf_isom_new_track(audio_output_file->isof, esd->ESID, GF_ISOM_MEDIA_AUDIO, audio_codec_ctx->sample_rate); GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("TimeScale: %d \n", audio_codec_ctx->time_base.den)); if (!track) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create new track\n")); return -1; } ret = gf_isom_set_track_enabled(audio_output_file->isof, track, 1); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_track_enabled\n", gf_error_to_string(ret))); return -1; } // if (!esd->ESID) esd->ESID = gf_isom_get_track_id(audio_output_file->isof, track); ret = gf_isom_new_mpeg4_description(audio_output_file->isof, track, esd, NULL, NULL, &di); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_new_mpeg4_description\n", gf_error_to_string(ret))); return -1; } gf_odf_desc_del((GF_Descriptor *) esd); esd = NULL; bpsample = av_get_bytes_per_sample(audio_output_file->codec_ctx->sample_fmt) * 8; ret = gf_isom_set_audio_info(audio_output_file->isof, track, di, audio_codec_ctx->sample_rate, audio_output_file->codec_ctx->channels, bpsample); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_audio_info\n", gf_error_to_string(ret))); return -1; } #ifndef GPAC_DISABLE_AV_PARSERS ret = gf_isom_set_pl_indication(audio_output_file->isof, GF_ISOM_PL_AUDIO, acfg.audioPL); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_pl_indication\n", gf_error_to_string(ret))); return -1; } #endif GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("time scale: %d sample dur: %d \n", audio_codec_ctx->time_base.den, audio_output_file->codec_ctx->frame_size)); ret = gf_isom_setup_track_fragment(audio_output_file->isof, track, 1, audio_output_file->codec_ctx->frame_size, 0, 0, 0, 0); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_setup_track_fragment\n", gf_error_to_string(ret))); return -1; } //gf_isom_add_track_to_root_od(video_output_file->isof,1); ret = gf_isom_finalize_for_fragment(audio_output_file->isof, 1); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret))); return -1; } ret = gf_media_get_rfc_6381_codec_name(audio_output_file->isof, track, audio_output_file->audio_data_conf->codec6381, GF_FALSE, GF_FALSE); if (ret != GF_OK) return -1; return 0; }
static GF_Err FAAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) { #ifndef GPAC_DISABLE_AV_PARSERS GF_Err e; GF_M4ADecSpecInfo a_cfg; #endif FAADCTX(); if (ctx->ES_ID && ctx->ES_ID!=esd->ESID) return GF_NOT_SUPPORTED; if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->dataLength) return GF_NON_COMPLIANT_BITSTREAM; if (!ctx->esd) { ctx->esd = esd; GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] Attaching stream %d\n", esd->ESID)); } if (ctx->codec) faacDecClose(ctx->codec); ctx->codec = faacDecOpen(); if (!ctx->codec) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error initializing decoder\n")); return GF_IO_ERR; } #ifndef GPAC_DISABLE_AV_PARSERS e = gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg); if (e) return e; #endif if (faacDecInit2(ctx->codec, (unsigned char *)esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, (unsigned long*)&ctx->sample_rate, (u8*)&ctx->num_channels) < 0) { #ifndef GPAC_DISABLE_AV_PARSERS s8 res; char *dsi, *s_base_object_type; u32 dsi_len; switch (a_cfg.base_object_type) { case GF_M4A_AAC_MAIN: s_base_object_type = gf_stringizer(GF_M4A_AAC_MAIN); goto base_object_type_error; case GF_M4A_AAC_LC: s_base_object_type = gf_stringizer(GF_M4A_AAC_LC); goto base_object_type_error; case GF_M4A_AAC_SSR: s_base_object_type = gf_stringizer(GF_M4A_AAC_SSR); goto base_object_type_error; case GF_M4A_AAC_LTP: s_base_object_type = gf_stringizer(GF_M4A_AAC_LTP); goto base_object_type_error; case GF_M4A_AAC_SBR: s_base_object_type = gf_stringizer(GF_M4A_AAC_SBR); goto base_object_type_error; case GF_M4A_AAC_PS: s_base_object_type = gf_stringizer(GF_M4A_AAC_PS); base_object_type_error: /*error case*/ GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[FAAD] Error: unsupported %s format for stream %d - defaulting to AAC LC\n", s_base_object_type, esd->ESID)); default: break; } a_cfg.base_object_type = GF_M4A_AAC_LC; a_cfg.has_sbr = GF_FALSE; a_cfg.nb_chan = a_cfg.nb_chan > 2 ? 1 : a_cfg.nb_chan; gf_m4a_write_config(&a_cfg, &dsi, &dsi_len); res = faacDecInit2(ctx->codec, (unsigned char *) dsi, dsi_len, (unsigned long *) &ctx->sample_rate, (u8 *) &ctx->num_channels); gf_free(dsi); if (res < 0) #endif { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error when initializing AAC decoder for stream %d\n", esd->ESID)); return GF_NOT_SUPPORTED; } } #ifndef GPAC_DISABLE_AV_PARSERS ctx->is_sbr = a_cfg.has_sbr; #endif ctx->num_samples = 1024; ctx->out_size = 2 * ctx->num_samples * ctx->num_channels; ctx->ES_ID = esd->ESID; ctx->signal_mc = ctx->num_channels>2 ? GF_TRUE : GF_FALSE; return GF_OK; }
int dc_gpac_audio_moov_create(AudioOutputFile * p_aoutf, char * psz_name) { GF_Err ret; AVCodecContext * p_audio_codec_ctx = p_aoutf->p_codec_ctx; u32 di; u32 track; GF_M4ADecSpecInfo acfg; p_aoutf->p_isof = gf_isom_open(psz_name, GF_ISOM_OPEN_WRITE, NULL); if (!p_aoutf->p_isof) { fprintf(stderr, "Cannot open iso file %s\n", psz_name); return -1; } memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); acfg.base_object_type = GF_M4A_AAC_LC; acfg.base_sr = p_audio_codec_ctx->sample_rate; acfg.nb_chan = p_audio_codec_ctx->channels; acfg.sbr_object_type = 0; acfg.audioPL = gf_m4a_get_profile(&acfg); GF_ESD * p_esd = gf_odf_desc_esd_new(2); if (!p_esd) { fprintf(stderr, "Cannot create GF_ESD\n"); return -1; } p_esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); p_esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); p_esd->decoderConfig->streamType = GF_STREAM_AUDIO; p_esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; p_esd->decoderConfig->bufferSizeDB = 20; p_esd->slConfig->timestampResolution = p_audio_codec_ctx->sample_rate; p_esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); p_esd->ESID = 1; ret = gf_m4a_write_config(&acfg, &p_esd->decoderConfig->decoderSpecificInfo->data, &p_esd->decoderConfig->decoderSpecificInfo->dataLength); //gf_isom_store_movie_config(p_voutf->p_isof, 0); track = gf_isom_new_track(p_aoutf->p_isof, p_esd->ESID, GF_ISOM_MEDIA_AUDIO, p_audio_codec_ctx->sample_rate); //printf("TimeScale: %d \n", p_video_codec_ctx->time_base.den); if (!track) { fprintf(stderr, "Cannot create new track\n"); return -1; } ret = gf_isom_set_track_enabled(p_aoutf->p_isof, track, 1); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_set_track_enabled\n", gf_error_to_string(ret)); return -1; } // if (!p_esd->ESID) p_esd->ESID = gf_isom_get_track_id(p_aoutf->p_isof, track); ret = gf_isom_new_mpeg4_description(p_aoutf->p_isof, track, p_esd, NULL, NULL, &di); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_new_mpeg4_description\n", gf_error_to_string(ret)); return -1; } gf_odf_desc_del((GF_Descriptor *) p_esd); p_esd = NULL; u8 bpsample = av_get_bytes_per_sample(p_aoutf->p_codec_ctx->sample_fmt) * 8; ret = gf_isom_set_audio_info(p_aoutf->p_isof, track, di, p_audio_codec_ctx->sample_rate, p_aoutf->p_codec_ctx->channels, bpsample); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_set_audio_info\n", gf_error_to_string(ret)); return -1; } ret = gf_isom_set_pl_indication(p_aoutf->p_isof, GF_ISOM_PL_AUDIO, acfg.audioPL); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_set_pl_indication\n", gf_error_to_string(ret)); return -1; } //printf("time scale: %d sample dur: %d \n", // p_video_codec_ctx->time_base.den, p_aoutf->p_codec_ctx->frame_size); ret = gf_isom_setup_track_fragment(p_aoutf->p_isof, track, 1, p_aoutf->p_codec_ctx->frame_size, 0, 0, 0, 0); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_setup_track_fragment\n", gf_error_to_string(ret)); return -1; } //gf_isom_add_track_to_root_od(p_voutf->p_isof,1); ret = gf_isom_finalize_for_fragment(p_aoutf->p_isof, 1); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret)); return -1; } return 0; }