📄 media_import.c
字号:
/*assume this is packed bitstream n-vop and discard it.*/ } else {proceed: if (e==GF_EOS) size = 0; else is_packed = 1; nb_f++; samp->IsRAP = 0; if (ftype==2) { b_frames ++; nbB++; /*adjust CTS*/ if (!has_cts_offset) { u32 i; for (i=0; i<gf_isom_get_sample_count(import->dest, track); i++) { gf_isom_modify_cts_offset(import->dest, track, i+1, dts_inc); } has_cts_offset = 1; } } else { if (!ftype) { samp->IsRAP = 1; nbI++; } else { nbP++; } /*even if no out-of-order frames we MUST adjust CTS if cts_offset is present is */ if (ref_frame && has_cts_offset) gf_isom_modify_cts_offset(import->dest, track, ref_frame, (1+b_frames)*dts_inc); ref_frame = cur_samp+1; if (max_b<b_frames) max_b = b_frames; b_frames = 0; } /*frame_start indicates start of VOP (eg we always remove VOL from each I)*/ samp->data = frame + samp_offset + frame_start; samp->dataLength = framesize; if (import->flags & GF_IMPORT_USE_DATAREF) { samp->data = NULL; e = gf_isom_add_sample_reference(import->dest, track, di, samp, file_offset + samp_offset + frame_start); } else { e = gf_isom_add_sample(import->dest, track, di, samp); } cur_samp++; samp->DTS += dts_inc; if (e) gf_import_message(import, GF_OK, "Error importing AVI frame %d", i+1); } if (!size || (size == framesize + frame_start)) break; } gf_m4v_parser_del(vparse); if (nb_f>2) gf_import_message(import, GF_OK, "Warning: more than 2 frames packed together"); } samp_offset = 0; gf_set_progress("Importing AVI Video", i, num_samples); if (duration && (samp->DTS > duration)) break; if (import->flags & GF_IMPORT_DO_ABORT) break; } /*final flush*/ if (ref_frame && has_cts_offset) gf_isom_modify_cts_offset(import->dest, track, ref_frame, (1+b_frames)*dts_inc); gf_set_progress("Importing AVI Video", num_samples, num_samples); num_samples = gf_isom_get_sample_count(import->dest, track); if (has_cts_offset) { gf_import_message(import, GF_OK, "Has B-Frames (%d max consecutive B-VOPs%s)", max_b, is_packed ? " - packed bitstream" : ""); /*repack CTS tables and adjust offsets for B-frames*/ gf_isom_set_cts_packing(import->dest, track, 0); /*this is plain ugly but since some encoders (divx) don't use the video PL correctly we force the system video_pl to ASP@L5 since we have I, P, B in base layer*/ if (PL<=3) { PL = 0xF5; erase_pl = 1; gf_import_message(import, GF_OK, "WARNING: indicated profile doesn't include B-VOPs - forcing %s", gf_m4v_get_profile_name((u8) PL)); } gf_import_message(import, GF_OK, "Import results: %d VOPs (%d Is - %d Ps - %d Bs)", num_samples, nbI, nbP, nbB); } else { /*no B-frames, remove CTS offsets*/ gf_isom_remove_cts_info(import->dest, track); gf_import_message(import, GF_OK, "Import results: %d VOPs (%d Is - %d Ps)", num_samples, nbI, nbP); } samp->data = NULL; gf_isom_sample_del(&samp); if (erase_pl) { gf_m4v_rewrite_pl(&import->esd->decoderConfig->decoderSpecificInfo->data, &import->esd->decoderConfig->decoderSpecificInfo->dataLength, (u8) PL); gf_isom_change_mpeg4_description(import->dest, track, 1, import->esd); } MP4T_RecomputeBitRate(import->dest, track); if (is_vfr) { if (nbB) { if (is_packed) gf_import_message(import, GF_OK, "Warning: Mix of non-coded frames: packed bitstream and encoder skiped - unpredictable timing"); } else { if (import->flags & GF_IMPORT_NO_FRAME_DROP) { if (nbNotCoded) gf_import_message(import, GF_OK, "Stream has %d N-VOPs", nbNotCoded); } else { gf_import_message(import, GF_OK, "import using Variable Frame Rate - Removed %d N-VOPs", nbNotCoded); } nbNotCoded = 0; } } if (nbDummy || nbNotCoded) gf_import_message(import, GF_OK, "Removed Frames: %d VFW delay frames - %d N-VOPs", nbDummy, nbNotCoded); gf_isom_set_pl_indication(import->dest, GF_ISOM_PL_VISUAL, (u8) PL);exit: if (destroy_esd) { gf_odf_desc_del((GF_Descriptor *) import->esd); import->esd = NULL; } if (frame) free(frame); AVI_close(in); return e;}/*credits to CISCO MPEG4/IP for MP3 parsing*/GF_Err gf_import_avi_audio(GF_MediaImporter *import){ GF_Err e; FILE *test; u32 hdr, di, track, i, tot_size, duration; s64 offset; s32 size, max_size, done; u16 sampleRate; Double dur; Bool is_cbr; u8 oti; GF_ISOSample *samp; char *frame; Bool destroy_esd; s32 continuous; unsigned char temp[4]; avi_t *in; if (import->flags & GF_IMPORT_PROBE_ONLY) return GF_OK; /*video only, ignore*/ if (import->trackID==1) return GF_OK; test = fopen(import->in_name, "rb"); if (!test) return gf_import_message(import, GF_URL_ERROR, "Opening file %s failed", import->in_name); fclose(test); in = AVI_open_input_file(import->in_name, 1); if (!in) return gf_import_message(import, GF_NOT_SUPPORTED, "Unsupported avi file"); AVI_seek_start(in); e = GF_OK; if (import->trackID) AVI_set_audio_track(in, import->trackID-2); if (AVI_read_audio(in, (char *) temp, 4, &continuous) != 4) { AVI_close(in); return gf_import_message(import, GF_OK, "No audio track found"); } hdr = GF_4CC(temp[0], temp[1], temp[2], temp[3]); if ((hdr &0xFFE00000) != 0xFFE00000) { AVI_close(in); return gf_import_message(import, GF_NOT_SUPPORTED, "Unsupported AVI audio format"); } sampleRate = gf_mp3_sampling_rate(hdr); oti = gf_mp3_object_type_indication(hdr); if (!oti || !sampleRate) { AVI_close(in); return gf_import_message(import, GF_NOT_SUPPORTED, "Error: invalid MPEG Audio track"); } frame = NULL; destroy_esd = 0; if (!import->esd) { destroy_esd = 1; import->esd = gf_odf_desc_esd_new(0); } track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_AUDIO, sampleRate); if (!track) 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; 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->slConfig->timestampResolution = sampleRate; if (import->esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) import->esd->decoderConfig->decoderSpecificInfo); import->esd->decoderConfig->decoderSpecificInfo = NULL; import->esd->decoderConfig->streamType = GF_STREAM_AUDIO; import->esd->decoderConfig->objectTypeIndication = oti; e = gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di); if (e) goto exit; gf_import_message(import, GF_OK, "AVI Audio import - sample rate %d - %s audio - %d channel%s", sampleRate, (oti==0x6B) ? "MPEG-1" : "MPEG-2", gf_mp3_num_channels(hdr), (gf_mp3_num_channels(hdr)>1) ? "s" : ""); AVI_seek_start(in); AVI_set_audio_position(in, 0); i = 0; tot_size = max_size = 0; while ((size = AVI_audio_size(in, i) )>0) { if (max_size<size) max_size=size; tot_size += size; i++; } frame = (char*)malloc(sizeof(char) * max_size); AVI_seek_start(in); AVI_set_audio_position(in, 0); dur = import->duration; dur *= sampleRate; dur /= 1000; duration = (u32) dur; samp = gf_isom_sample_new(); done=max_size=0; is_cbr = 1; while (1) { if (AVI_read_audio(in, frame, 4, (int*)&continuous) != 4) break; offset = gf_f64_tell(in->fdes) - 4; hdr = GF_4CC((u8) frame[0], (u8) frame[1], (u8) frame[2], (u8) frame[3]); size = gf_mp3_frame_size(hdr); if (size>max_size) { frame = (char*)realloc(frame, sizeof(char) * size); if (max_size) is_cbr = 0; max_size = size; } size = 4 + AVI_read_audio(in, &frame[4], size - 4, &continuous); if ((import->flags & GF_IMPORT_USE_DATAREF) && !continuous) { gf_import_message(import, GF_IO_ERR, "Cannot use media references, splited input audio frame found"); e = GF_IO_ERR; goto exit; } samp->IsRAP = 1; samp->data = frame; samp->dataLength = size; if (import->flags & GF_IMPORT_USE_DATAREF) { e = gf_isom_add_sample_reference(import->dest, track, di, samp, offset); } else { e = gf_isom_add_sample(import->dest, track, di, samp); } samp->DTS += gf_mp3_window_size(hdr); gf_set_progress("Importing AVI Audio", done, tot_size); done += size; if (duration && (samp->DTS > duration) ) break; if (import->flags & GF_IMPORT_DO_ABORT) break; } gf_set_progress("Importing AVI Audio", tot_size, tot_size); gf_import_message(import, GF_OK, "Import done - %s bit rate MP3 detected", is_cbr ? "constant" : "variable"); samp->data = NULL; gf_isom_sample_del(&samp); MP4T_RecomputeBitRate(import->dest, track); gf_isom_set_pl_indication(import->dest, GF_ISOM_PL_AUDIO, 0xFE); exit: if (import->esd && destroy_esd) { gf_odf_desc_del((GF_Descriptor *) import->esd); import->esd = NULL; } if (frame) free(frame); AVI_close(in); return e;}GF_Err gf_import_isomedia(GF_MediaImporter *import){ GF_Err e; u64 offset, sampDTS; u32 track, di, trackID, track_in, i, num_samples, mtype, stype, w, h, duration, sr, sbr_sr, ch, mstype; s32 trans_x, trans_y; s16 layer; u8 bps; char lang[4]; const char *url, *urn; Bool sbr, is_clone; GF_ISOSample *samp; GF_ESD *origin_esd; GF_InitialObjectDescriptor *iod; if (import->flags & GF_IMPORT_PROBE_ONLY) { for (i=0; i<gf_isom_get_track_count(import->orig); i++) { import->tk_info[i].track_num = gf_isom_get_track_id(import->orig, i+1); import->tk_info[i].type = gf_isom_get_media_type(import->orig, i+1); import->tk_info[i].flags = GF_IMPORT_USE_DATAREF; if (import->tk_info[i].type == GF_ISOM_MEDIA_VISUAL) { gf_isom_get_visual_info(import->orig, i+1, 1, &import->tk_info[i].video_info.width, &import->tk_info[i].video_info.height); } else if (import->tk_info[i].type == GF_ISOM_MEDIA_AUDIO) { gf_isom_get_audio_info(import->orig, i+1, 1, &import->tk_info[i].audio_info.sample_rate, &import->tk_info[i].audio_info.nb_channels, NULL); } lang[3] = 0; gf_isom_get_media_language(import->orig, i+1, lang); import->tk_info[i].lang = GF_4CC(' ', lang[0], lang[1], lang[2]); import->nb_tracks ++; } return GF_OK; } trackID = import->trackID; if (!trackID) { if (gf_isom_get_track_count(import->orig) != 1) return gf_import_message(import, GF_BAD_PARAM, "Several tracks in MP4 - please indicate track to import"); trackID = gf_isom_get_track_id(import->orig, 1); } track_in = gf_isom_get_track_by_id(import->orig, trackID); if (!track_in) return gf_import_message(import, GF_URL_ERROR, "Cannot find track ID %d in file", trackID); origin_esd = gf_isom_get_esd(import->orig, track_in, 1); e = GF_OK; if (import->esd && origin_esd) { origin_esd->OCRESID = import->esd->OCRESID; /*there may be other things to import...*/ } sbr = 0; sbr_sr = 0; iod = (GF_InitialObjectDescriptor *) gf_isom_get_root_od(import->orig); if (iod && (iod->tag != GF_ODF_IOD_TAG)) { gf_odf_desc_del((GF_Descriptor *) iod); iod = NULL; } mtype = gf_isom_get_media_type(import->orig, track_in); if (mtype==GF_ISOM_MEDIA_VISUAL) { u8 PL = iod ? iod->visual_profileAndLevel : 0xFE; w = h = 0; gf_isom_get_visual_info(import->orig, track_in, 1, &w, &h); /*for MPEG-4 visual, always check size (don't trust input file)*/ if (origin_esd && (origin_esd->decoderConfig->objectTypeIndication==0x20)) { GF_M4VDecSpecInfo dsi; gf_m4v_get_config(origin_esd->decoderConfig->decoderSpecificInfo->data, origin_esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); w = dsi.width; h = dsi.height; PL = dsi.VideoPL; } gf_isom_set_pl_indication(import->dest, GF_ISOM_PL_VISUAL, PL); } else if (mtype==GF_ISOM_MEDIA_AUDIO) { u8 PL = iod ? iod->audio_profileAndLevel : 0xFE; bps = 16; sr = ch = sbr_sr = 0; sbr = 0; gf_isom_get_audio_info(import->orig, track_in, 1, &sr, &ch, &bps); if (origin_esd && (origin_esd->decoderConfig->objectTypeIndication==0x40)) { GF_M4ADecSpecInfo dsi; gf_m4a_get_config(origin_esd->decoderConfig->decoderSpecificInfo->data, origin_esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); sr = dsi.base_sr; if (dsi.has_sbr) sbr_sr = dsi.sbr_sr; ch = dsi.nb_chan; PL = dsi.audioPL; sbr = dsi.has_sbr ? ((dsi.base_object_type==GF_M4A_AAC_SBR) ? 2 : 1) : 0; } gf_isom_set_pl_indication(import->dest, GF_ISOM_PL_AUDIO, PL); } else if (mtype==GF_ISOM_MEDIA_SUBPIC) { w = h = 0; trans_x = trans_y = 0; layer = 0; if (origin_esd && origin_esd->decoderConfig->objectTypeIndication == 0xe0) { gf_isom_get_track_layout_info(import->orig, track_in, &w, &h, &trans_x, &trans_y, &layer); } } gf_odf_desc_del((GF_Descriptor *) iod); /*check if MPEG-4 or not*/ is_clone = 0; stype = gf_isom_get_media_subtype(import->orig, track_in, 1); if ((stype==GF_ISOM_SUBTYPE_MPEG4) || (stype==GF_ISOM_SUBTYPE_MPEG4_CRYP)) { track = gf_isom_new_track(import->dest, import->esd ? import->esd->ESID : 0, gf_isom_get_media_type(import->orig, track_in), gf_isom_get_media_timescale(import->orig, track_in));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -