📄 media_import.c
字号:
gf_set_progress("Importing MP3", done, tot_size); samp->DTS += gf_mp3_window_size(hdr); done += samp->dataLength; if (duration && (samp->DTS > duration)) break; if (import->flags & GF_IMPORT_DO_ABORT) break; } MP4T_RecomputeBitRate(import->dest, track); gf_set_progress("Importing MP3", tot_size, tot_size);exit: if (import->esd && destroy_esd) { gf_odf_desc_del((GF_Descriptor *) import->esd); import->esd = NULL; } if (samp) gf_isom_sample_del(&samp); fclose(in); return e;}typedef struct{ Bool is_mp2, no_crc; u32 profile, sr_idx, nb_ch, frame_size;} ADTSHeader;static Bool ADTS_SyncFrame(GF_BitStream *bs, ADTSHeader *hdr){ u32 val, hdr_size, pos; while (gf_bs_available(bs)) { val = gf_bs_read_u8(bs); if (val!=0xFF) continue; val = gf_bs_read_int(bs, 4); if (val != 0x0F) { gf_bs_read_int(bs, 4); continue; } hdr->is_mp2 = gf_bs_read_int(bs, 1); gf_bs_read_int(bs, 2); hdr->no_crc = gf_bs_read_int(bs, 1); pos = (u32) gf_bs_get_position(bs) - 2; hdr->profile = 1 + gf_bs_read_int(bs, 2); hdr->sr_idx = gf_bs_read_int(bs, 4); gf_bs_read_int(bs, 1); hdr->nb_ch = gf_bs_read_int(bs, 3); gf_bs_read_int(bs, 4); hdr->frame_size = gf_bs_read_int(bs, 13); gf_bs_read_int(bs, 11); gf_bs_read_int(bs, 2); hdr_size = hdr->no_crc ? 7 : 9; if (!hdr->no_crc) gf_bs_read_int(bs, 16); if (hdr->frame_size < hdr_size) { gf_bs_seek(bs, pos+1); continue; } hdr->frame_size -= hdr_size; if (gf_bs_available(bs) == hdr->frame_size) return 1; gf_bs_skip_bytes(bs, hdr->frame_size); val = gf_bs_read_u8(bs); if (val!=0xFF) { gf_bs_seek(bs, pos+1); continue; } val = gf_bs_read_int(bs, 4); if (val!=0x0F) { gf_bs_read_int(bs, 4); gf_bs_seek(bs, pos+2); continue; } gf_bs_seek(bs, pos+hdr_size); return 1; } return 0;}GF_Err gf_import_aac_adts(GF_MediaImporter *import){ u8 oti; Bool destroy_esd; GF_Err e; Bool sync_frame; u16 sr, sbr_sr, sbr_sr_idx, dts_inc; GF_BitStream *bs, *dsi; ADTSHeader hdr; GF_M4ADecSpecInfo acfg; FILE *in; u64 offset; u32 max_size, track, di, tot_size, done, duration, prof, i; GF_ISOSample *samp; in = gf_f64_open(import->in_name, "rb"); if (!in) return gf_import_message(import, GF_URL_ERROR, "Opening file %s failed", import->in_name); bs = gf_bs_from_file(in, GF_BITSTREAM_READ); sync_frame = ADTS_SyncFrame(bs, &hdr); if (!sync_frame) { gf_bs_del(bs); fclose(in); return gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Audio isn't MPEG-2/4 AAC with ADTS"); } /*keep MPEG-2 AAC OTI even for HE-SBR (that's correct according to latest MPEG-4 audio spec)*/ oti = hdr.is_mp2 ? hdr.profile+0x66-1 : 0x40; sr = GF_M4ASampleRates[hdr.sr_idx]; if (import->flags & GF_IMPORT_PROBE_ONLY) { import->tk_info[0].track_num = 1; import->tk_info[0].type = GF_ISOM_MEDIA_AUDIO; import->tk_info[0].flags = GF_IMPORT_USE_DATAREF | GF_IMPORT_SBR_IMPLICIT | GF_IMPORT_SBR_EXPLICIT; import->nb_tracks = 1; import->tk_info[0].audio_info.sample_rate = sr; import->tk_info[0].audio_info.nb_channels = hdr.nb_ch; gf_bs_del(bs); fclose(in); return GF_OK; } dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); sbr_sr = sr; sbr_sr_idx = hdr.sr_idx; for (i=0; i<16; i++) { if (GF_M4ASampleRates[i] == (u32) 2*sr) { sbr_sr_idx = i; sbr_sr = 2*sr; break; } } /*no provision for explicit indication of MPEG-2 AAC through MPEG-4 PLs, so force implicit*/ if (hdr.is_mp2) { if (import->flags & GF_IMPORT_SBR_EXPLICIT) { import->flags &= ~GF_IMPORT_SBR_EXPLICIT; import->flags |= GF_IMPORT_SBR_IMPLICIT; } } dts_inc = 1024; memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); acfg.base_object_type = hdr.profile; acfg.base_sr = sr; acfg.nb_chan = hdr.nb_ch; acfg.sbr_object_type = 0; if (import->flags & GF_IMPORT_SBR_EXPLICIT) { acfg.has_sbr = 1; acfg.base_object_type = 5; acfg.sbr_object_type = hdr.profile; /*for better interop, always store using full SR when using explict signaling*/ dts_inc = 2048; sr = sbr_sr; } else if (import->flags & GF_IMPORT_SBR_IMPLICIT) { acfg.has_sbr = 1; } acfg.audioPL = gf_m4a_get_profile(&acfg); /*explicit SBR signal (non backward-compatible)*/ if (import->flags & GF_IMPORT_SBR_EXPLICIT) { gf_bs_write_int(dsi, 5, 5); gf_bs_write_int(dsi, hdr.sr_idx, 4); gf_bs_write_int(dsi, hdr.nb_ch, 4); gf_bs_write_int(dsi, sbr_sr ? sbr_sr_idx : hdr.sr_idx, 4); gf_bs_write_int(dsi, hdr.profile, 5); } else { /*regular AAC*/ gf_bs_write_int(dsi, hdr.profile, 5); gf_bs_write_int(dsi, hdr.sr_idx, 4); gf_bs_write_int(dsi, hdr.nb_ch, 4); gf_bs_align(dsi); /*implicit AAC SBR signal*/ if (import->flags & GF_IMPORT_SBR_IMPLICIT) { gf_bs_write_int(dsi, 0x2b7, 11); /*sync extension type*/ gf_bs_write_int(dsi, 5, 5); /*SBR objectType*/ gf_bs_write_int(dsi, 1, 1); /*SBR present flag*/ gf_bs_write_int(dsi, sbr_sr_idx, 4); } } /*not MPEG4 tool*/ if (0 && hdr.is_mp2) acfg.audioPL = 0xFE; gf_bs_align(dsi); prof = hdr.profile; e = GF_OK; destroy_esd = 0; if (!import->esd) { import->esd = gf_odf_desc_esd_new(2); destroy_esd = 1; } if (!import->esd->decoderConfig) import->esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); if (!import->esd->slConfig) import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); import->esd->decoderConfig->streamType = GF_STREAM_AUDIO; import->esd->decoderConfig->objectTypeIndication = oti; import->esd->decoderConfig->bufferSizeDB = 20; import->esd->slConfig->timestampResolution = sr; if (!import->esd->decoderConfig->decoderSpecificInfo) import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); if (import->esd->decoderConfig->decoderSpecificInfo->data) free(import->esd->decoderConfig->decoderSpecificInfo->data); gf_bs_get_content(dsi, &import->esd->decoderConfig->decoderSpecificInfo->data, &import->esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(dsi); samp = NULL; gf_import_message(import, GF_OK, "AAC import %s- sample rate %d - %s audio - %d channel%s", (import->flags & GF_IMPORT_SBR_IMPLICIT) ? "SBR (implicit) " : ((import->flags & GF_IMPORT_SBR_EXPLICIT) ? "SBR (explicit) " : ""), sr, (oti==0x40) ? "MPEG-4" : "MPEG-2", hdr.nb_ch, (hdr.nb_ch>1) ? "s" : ""); track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_AUDIO, sr); if (!track) { e = gf_isom_last_error(import->dest); goto exit; } gf_isom_set_track_enabled(import->dest, track, 1); if (!import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track); import->final_trackID = import->esd->ESID; gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di); gf_isom_set_audio_info(import->dest, track, di, sr, (hdr.nb_ch>2) ? 2 : hdr.nb_ch, 16); e = GF_OK; /*add first sample*/ samp = gf_isom_sample_new(); samp->IsRAP = 1; max_size = samp->dataLength = hdr.frame_size; samp->data = (char*)malloc(sizeof(char)*hdr.frame_size); offset = gf_bs_get_position(bs); gf_bs_read_data(bs, samp->data, hdr.frame_size); if (import->flags & GF_IMPORT_USE_DATAREF) { gf_isom_add_sample_reference(import->dest, track, di, samp, offset); } else { gf_isom_add_sample(import->dest, track, di, samp); } samp->DTS+=dts_inc; duration = import->duration*sr; duration /= 1000; tot_size = (u32) gf_bs_get_size(bs); done = 0; while (gf_bs_available(bs) ) { sync_frame = ADTS_SyncFrame(bs, &hdr); if (!sync_frame) break; if (hdr.frame_size>max_size) { samp->data = (char*)realloc(samp->data, sizeof(char) * hdr.frame_size); max_size = hdr.frame_size; } samp->dataLength = hdr.frame_size; offset = gf_bs_get_position(bs); gf_bs_read_data(bs, samp->data, hdr.frame_size); if (import->flags & GF_IMPORT_USE_DATAREF) { gf_isom_add_sample_reference(import->dest, track, di, samp, offset); } else { gf_isom_add_sample(import->dest, track, di, samp); } gf_set_progress("Importing AAC", done, tot_size); samp->DTS += dts_inc; done += samp->dataLength; if (duration && (samp->DTS > duration)) break; if (import->flags & GF_IMPORT_DO_ABORT) break; } MP4T_RecomputeBitRate(import->dest, track); gf_isom_set_pl_indication(import->dest, GF_ISOM_PL_AUDIO, acfg.audioPL); gf_set_progress("Importing AAC", tot_size, tot_size);exit: if (import->esd && destroy_esd) { gf_odf_desc_del((GF_Descriptor *) import->esd); import->esd = NULL; } if (samp) gf_isom_sample_del(&samp); gf_bs_del(bs); fclose(in); return e;}static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12){ GF_Err e; Double FPS; FILE *mdia; GF_ISOSample *samp; u32 nb_samp, i, timescale, max_size, samp_offset, track, di, PL, max_b, nbI, nbP, nbB, nbNotCoded, tot_size, done_size, dts_inc, ref_frame, b_frames; Bool is_vfr, enable_vfr, erase_pl, has_cts_offset, is_packed, destroy_esd, do_vfr, forced_packed; GF_M4VDecSpecInfo dsi; GF_M4VParser *vparse; GF_BitStream *bs; u64 pos; u32 duration; destroy_esd = forced_packed = 0; mdia = gf_f64_open(import->in_name, "rb"); if (!mdia) return gf_import_message(import, GF_URL_ERROR, "Opening %s failed", import->in_name); bs = gf_bs_from_file(mdia, GF_BITSTREAM_READ); samp = NULL; vparse = gf_m4v_parser_bs_new(bs, mpeg12); e = gf_m4v_parse_config(vparse, &dsi); if (e) { gf_import_message(import, e, "Cannot load MPEG-4 decoder config"); goto exit; } tot_size = (u32) gf_bs_get_size(bs); done_size = 0; destroy_esd = 0; FPS = mpeg12 ? dsi.fps : GF_IMPORT_DEFAULT_FPS; if (import->video_fps) FPS = (Double) import->video_fps; get_video_timing(FPS, ×cale, &dts_inc); duration = (u32) (import->duration*FPS); is_packed = 0; nbNotCoded = nbI = nbP = nbB = max_b = 0; enable_vfr = is_vfr = erase_pl = 0; if (import->flags & GF_IMPORT_PROBE_ONLY) { import->tk_info[0].track_num = 1; import->tk_info[0].type = GF_ISOM_MEDIA_VISUAL; import->tk_info[0].media_type = mpeg12 ? ((dsi.VideoPL==0x6A) ? GF_4CC('M','P','G','1') : GF_4CC('M','P','G','2') ) : GF_4CC('M','P','4','V') ; import->tk_info[0].flags = GF_IMPORT_USE_DATAREF | GF_IMPORT_OVERRIDE_FPS; if (!mpeg12) import->tk_info[0].flags |= GF_IMPORT_NO_FRAME_DROP | GF_IMPORT_FORCE_PACKED; import->tk_info[0].video_info.width = dsi.width; import->tk_info[0].video_info.height = dsi.height; import->tk_info[0].video_info.par = (dsi.par_num<<16) | dsi.par_den; import->nb_tracks = 1; goto exit; } samp = gf_isom_sample_new(); max_size = 4096; samp->data = (char*)malloc(sizeof(char)*max_size); /*no auto frame-rate detection*/ if (import->video_fps == 10000.0) import->video_fps = 25.0; PL = dsi.VideoPL; if (!PL) { PL = 0x01; erase_pl = 1; } samp_offset = 0; /*MPEG-4 visual*/ if (!mpeg12) samp_offset = gf_m4v_get_object_start(vparse); if (!import->esd) { import->esd = gf_odf_desc_esd_new(0); destroy_esd = 1; } track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_VISUAL, timescale); if (!track) { e = gf_isom_last_error(import->dest); goto exit; } gf_isom_set_track_enabled(import->dest, track, 1); if (!import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track); import->final_trackID = gf_isom_get_track_id(import->dest, track); if (!import->esd->slConfig) import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); import->esd->slConfig->timestampResolution = timescale; if (!import->esd->decoderConfig) import->esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); if (import->esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) import->esd->decoderConfig->decoderSpecificInfo); import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); import->esd->decoderConfig->streamType = GF_STREAM_VISUAL; if (mpeg12) { import->esd->decoderConfig->objectTypeIndication = dsi.VideoPL; } else { import->esd->decoderConfig->objectTypeIndication = 0x20; } if (samp_offset) { import->esd->decoderConfig->decoderSpecificInfo->data = (char*)malloc(sizeof(char) * samp_offset); import->esd->decoderConfig->decoderSpecificInfo->dataLength = samp_offset; pos = gf_bs_get_position(bs); gf_bs_seek(bs, 0); gf_bs_read_data(bs, import->esd->decoderConfig->decoderSpecificInfo->data, samp_offset); gf_bs_seek(bs, pos); /*remove packed flag if any (VOSH user data)*/ forced_packed = 0; i=0; while (1) { char *frame = import->esd->decoderConfig->decoderSpecificInfo->data; while ((i+3<samp_offset) && ((frame[i]!=0) || (frame[i+1]!=0) || (frame[i+2]!=1))) i++; if (i+4>=samp_offset) break; if (strncmp(frame+i+4, "DivX", 4)) { i += 4; continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -