📄 media_export.c
字号:
if (is_ogg) return gf_dump_to_ogg(dumper, szName, track); if (is_vobsub) return gf_dump_to_vobsub(dumper, szName, track, dsi, dsi_size); if (qcp_type>1) { if (dumper->flags & GF_EXPORT_USE_QCP) { strcat(szName, ".qcp"); gf_export_message(dumper, GF_OK, "Extracting %s audio (QCP file)", (qcp_type==2) ? "SMV" : "EVRC"); } else if (qcp_type==2) { strcat(szName, ".smv"); gf_export_message(dumper, GF_OK, "Extracting SMV audio"); } else { strcat(szName, ".evc"); gf_export_message(dumper, GF_OK, "Extracting EVRC audio"); } } if (dumper->out_name && (dumper->flags & GF_EXPORT_MERGE)) { out = gf_f64_open(dumper->out_name, "a+b"); if (out) gf_f64_seek(out, 0, SEEK_END); } else { out = fopen(szName, "wb"); } if (!out) { if (dsi) free(dsi); if (avccfg) gf_odf_avc_cfg_del(avccfg); return gf_export_message(dumper, GF_IO_ERR, "Error opening %s for writing - check disk access & permissions", szName); } bs = gf_bs_from_file(out, GF_BITSTREAM_WRITE); if (is_aac) { gf_m4a_get_config(dsi, dsi_size, &a_cfg); if (is_aac==2) aac_type = a_cfg.base_object_type - 1; free(dsi); dsi = NULL; } if (dsi) { gf_bs_write_data(bs, dsi, dsi_size); free(dsi); } if (avccfg) { count = gf_list_count(avccfg->sequenceParameterSets); for (i=0;i<count;i++) { GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(avccfg->sequenceParameterSets, i); gf_bs_write_u32(bs, 1); gf_bs_write_data(bs, sl->data, sl->size); } count = gf_list_count(avccfg->pictureParameterSets); for (i=0;i<count;i++) { GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(avccfg->pictureParameterSets, i); gf_bs_write_u32(bs, 1); gf_bs_write_data(bs, sl->data, sl->size); } } qcp_rates = NULL; count = gf_isom_get_sample_count(dumper->file, track); rt_cnt = 0; if (m_stype==GF_ISOM_SUBTYPE_3GP_AMR) gf_bs_write_data(bs, "#!AMR\n", 6); else if (m_stype==GF_ISOM_SUBTYPE_3GP_AMR_WB) gf_bs_write_data(bs, "#!AMR-WB\n", 9); else if ((qcp_type>1) && !(dumper->flags & GF_EXPORT_USE_QCP)) { if (qcp_type==2) gf_bs_write_data(bs, "#!SMV\n", 6); else gf_bs_write_data(bs, "#!EVRC\n", 7); qcp_type = 0; } /*QCP formatting*/ if (qcp_type) { GF_ISOSample *samp; Bool needs_rate_octet; u32 tot_size, data_size, sample_size, avg_rate, agg_samp; u32 block_size = 160; u32 sample_rate = 8000; GF_3GPConfig *gpc = gf_isom_3gp_config_get(dumper->file, track, 1); sample_size = gf_isom_get_constant_sample_size(dumper->file, track); agg_samp = 1; if (gpc) { agg_samp = gpc->frames_per_sample; free(gpc); } if (qcp_type==1) { qcp_rates = (u32 *)GF_QCELP_RATE_TO_SIZE; rt_cnt = GF_QCELP_RATE_TO_SIZE_NB; } else { qcp_rates = (u32 *)GF_SMV_EVRC_RATE_TO_SIZE; rt_cnt = GF_SMV_EVRC_RATE_TO_SIZE_NB; } /*if cst size and no aggregation, skip table*/ if (sample_size && !agg_samp) { data_size = sample_size*count; } else { /*dumps full table...*/ for (i=0; i<rt_cnt; i++) { rtable[i].rate_idx = qcp_rates[2*i]; rtable[i].pck_size = qcp_rates[2*i+1]; } data_size = (u32) gf_isom_get_media_data_size(dumper->file, track); } /*check sample format - packetvideo doesn't include rate octet...*/ needs_rate_octet = 1; samp = gf_isom_get_sample_info(dumper->file, track, 1, NULL, NULL); for (i=0; i<rt_cnt; i++) { if (qcp_rates[2*i+1]==samp->dataLength) { needs_rate_octet = 0; break; } } gf_isom_sample_del(&samp); if (needs_rate_octet) data_size += count; has_qcp_pad = (data_size % 2) ? 1 : 0; avg_rate = 8*data_size*sample_rate/count/block_size; /*QLCM + fmt + vrat + data*/ tot_size = 4+ 8+150 + 8+8 + 8 + data_size; /*pad is included in riff size*/ if (has_qcp_pad) tot_size++; gf_bs_write_data(bs, "RIFF", 4); gf_bs_write_u32_le(bs, tot_size); gf_bs_write_data(bs, "QLCM", 4); gf_bs_write_data(bs, "fmt ", 4); gf_bs_write_u32_le(bs, 150);/*fmt chunk size*/ gf_bs_write_u8(bs, 1); gf_bs_write_u8(bs, 0); gf_bs_write_data(bs, GUID, 16); gf_bs_write_u16_le(bs, 1); memset(szName, 0, 80); strcpy(szName, (qcp_type==1) ? "QCELP-GPACExport" : ((qcp_type==2) ? "SMV-GPACExport" : "EVRC-GPACExport")); gf_bs_write_data(bs, szName, 80); gf_bs_write_u16_le(bs, avg_rate); gf_bs_write_u16_le(bs, sample_size); gf_bs_write_u16_le(bs, block_size); gf_bs_write_u16_le(bs, sample_rate); gf_bs_write_u16_le(bs, 16); gf_bs_write_u32_le(bs, rt_cnt); for (i=0; i<8; i++) { if (i<rt_cnt) { /*frame size MINUS rate octet*/ gf_bs_write_u8(bs, rtable[i].pck_size - 1); gf_bs_write_u8(bs, rtable[i].rate_idx); } else { gf_bs_write_u16(bs, 0); } } memset(szName, 0, 80); gf_bs_write_data(bs, szName, 20);/*reserved*/ gf_bs_write_data(bs, "vrat", 4); gf_bs_write_u32_le(bs, 8);/*vrat chunk size*/ gf_bs_write_u32_le(bs, rt_cnt); gf_bs_write_u32_le(bs, count); gf_bs_write_data(bs, "data", 4); gf_bs_write_u32_le(bs, data_size);/*data chunk size*/ qcp_type = needs_rate_octet ? 1 : 0; } for (i=0; i<count; i++) { GF_ISOSample *samp = gf_isom_get_sample(dumper->file, track, i+1, &di); if (!samp) break; /*AVC sample to NALU*/ if (avccfg) { u32 j, nal_size, remain; char *ptr = samp->data; remain = samp->dataLength; while (remain) { nal_size = 0; for (j=0; j<avccfg->nal_unit_size; j++) { nal_size |= ((u8) *ptr); if (j+1<avccfg->nal_unit_size) nal_size<<=8; remain--; ptr++; } gf_bs_write_u32(bs, 1); gf_bs_write_data(bs, ptr, nal_size); ptr += nal_size; remain -= nal_size; } } /*adts frame header*/ else if (is_aac) { gf_bs_write_int(bs, 0xFFF, 12);/*sync*/ gf_bs_write_int(bs, (is_aac==1) ? 1 : 0, 1);/*mpeg2 aac*/ gf_bs_write_int(bs, 0, 2); /*layer*/ gf_bs_write_int(bs, 1, 1); /* protection_absent*/ gf_bs_write_int(bs, aac_type, 2); gf_bs_write_int(bs, a_cfg.base_sr_index, 4); gf_bs_write_int(bs, 0, 1); gf_bs_write_int(bs, a_cfg.nb_chan, 3); gf_bs_write_int(bs, 0, 4); gf_bs_write_int(bs, 7+samp->dataLength, 13); gf_bs_write_int(bs, 0x7FF, 11); gf_bs_write_int(bs, 0, 2); } /*fix rate octet for QCP*/ else if (qcp_type) { u32 j; for (j=0; j<rt_cnt; j++) { if (qcp_rates[2*j+1]==1+samp->dataLength) { gf_bs_write_u8(bs, qcp_rates[2*j]); break; } } } if (!avccfg) gf_bs_write_data(bs, samp->data, samp->dataLength); gf_isom_sample_del(&samp); gf_set_progress("Media Export", i+1, count); if (dumper->flags & GF_EXPORT_DO_ABORT) break; } if (has_qcp_pad) gf_bs_write_u8(bs, 0); if (avccfg) gf_odf_avc_cfg_del(avccfg); gf_bs_del(bs); fclose(out); return GF_OK;}GF_Err gf_media_export_avi_track(GF_MediaExporter *dumper){ GF_Err e; u32 max_size, tot_size, num_samples, i; s32 size; char *comp, *frame; char szOutFile[1024]; avi_t *in; FILE *fout; in = AVI_open_input_file(dumper->in_name, 1); if (!in) return gf_export_message(dumper, GF_URL_ERROR, "Unsupported avi file"); fout = NULL; e = GF_OK; if (dumper->trackID==1) { Bool key; comp = AVI_video_compressor(in); if (!stricmp(comp, "DIVX") || !stricmp(comp, "DX50") /*DivX*/ || !stricmp(comp, "XVID") /*XviD*/ || !stricmp(comp, "3iv2") /*3ivX*/ || !stricmp(comp, "fvfw") /*ffmpeg*/ || !stricmp(comp, "NDIG") /*nero*/ || !stricmp(comp, "MP4V") /*!! not tested*/ || !stricmp(comp, "M4CC") /*Divio - not tested*/ || !stricmp(comp, "PVMM") /*PacketVideo - not tested*/ || !stricmp(comp, "SEDG") /*Samsung - not tested*/ || !stricmp(comp, "RMP4") /*Sigma - not tested*/ ) { sprintf(szOutFile, "%s.cmp", dumper->out_name); } else if (!stricmp(comp, "VSSH") || strstr(comp, "264")) { sprintf(szOutFile, "%s.h264", dumper->out_name); } else { sprintf(szOutFile, "%s.%s", dumper->out_name, comp); } gf_export_message(dumper, GF_OK, "Extracting AVI video (format %s) to %s", comp, szOutFile); fout = fopen(szOutFile, "wb"); max_size = 0; frame = NULL; num_samples = AVI_video_frames(in); for (i=0; i<num_samples; i++) { size = AVI_frame_size(in, i); if (!size) { AVI_read_frame(in, NULL, (int*)&key); continue; } if ((u32) size > max_size) { frame = (char*)realloc(frame, sizeof(char) * size); max_size = size; } AVI_read_frame(in, frame, (int*)&key); if ((u32) size>4) fwrite(frame, 1, size, fout); gf_set_progress("AVI Extract", i+1, num_samples); } free(frame); fclose(fout); fout = NULL; goto exit; } i = 0; tot_size = max_size = 0; while ((size = AVI_audio_size(in, i) )>0) { if (max_size<(u32) 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); switch (in->track[in->aptr].a_fmt) { case WAVE_FORMAT_PCM: comp = "pcm"; break; case WAVE_FORMAT_ADPCM: comp = "adpcm"; break; case WAVE_FORMAT_IBM_CVSD: comp = "cvsd"; break; case WAVE_FORMAT_ALAW: comp = "alaw"; break; case WAVE_FORMAT_MULAW: comp = "mulaw"; break; case WAVE_FORMAT_OKI_ADPCM: comp = "oki_adpcm"; break; case WAVE_FORMAT_DVI_ADPCM: comp = "dvi_adpcm"; break; case WAVE_FORMAT_DIGISTD: comp = "digistd"; break; case WAVE_FORMAT_YAMAHA_ADPCM: comp = "yam_adpcm"; break; case WAVE_FORMAT_DSP_TRUESPEECH: comp = "truespeech"; break; case WAVE_FORMAT_GSM610: comp = "gsm610"; break; case IBM_FORMAT_MULAW: comp = "ibm_mulaw"; break; case IBM_FORMAT_ALAW: comp = "ibm_alaw"; break; case IBM_FORMAT_ADPCM: comp = "ibm_adpcm"; break; case 0x55: comp = "mp3"; break; default: comp = "raw"; break; } sprintf(szOutFile, "%s.%s", dumper->out_name, comp); gf_export_message(dumper, GF_OK, "Extracting AVI %s audio", comp); fout = fopen(szOutFile, "wb"); num_samples = 0; while (1) { Bool continuous; size = AVI_read_audio(in, frame, max_size, (int*)&continuous); if (!size) break; num_samples += size; fwrite(frame, 1, size, fout); gf_set_progress("AVI Extract", num_samples, tot_size); }exit: if (fout) fclose(fout); AVI_close(in); return e;}GF_Err gf_media_export_nhnt(GF_MediaExporter *dumper){ GF_ESD *esd; char szName[1000]; FILE *out_med, *out_inf, *out_nhnt; GF_BitStream *bs; Bool has_b_frames; u32 track, i, di, count, pos; track = gf_isom_get_track_by_id(dumper->file, dumper->trackID); esd = gf_isom_get_esd(dumper->file, track, 1); if (!esd) return gf_export_message(dumper, GF_NON_COMPLIANT_BITSTREAM, "Invalid MPEG-4 stream in track ID %d", dumper->trackID); if (dumper->flags & GF_EXPORT_PROBE_ONLY) { gf_odf_desc_del((GF_Descriptor *) esd); return GF_OK; } sprintf(szName, "%s.media", dumper->out_name); out_med = gf_f64_open(szName, "wb"); if (!out_med) { gf_odf_desc_del((GF_Descriptor *) esd); return gf_export_message(dumper, GF_IO_ERR, "Error opening %s for writing - check disk access & permissions", szName); } sprintf(szName, "%s.nhnt", dumper->out_name); out_nhnt = fopen(szName, "wb"); if (!out_nhnt) { fclose(out_med); gf_odf_desc_del((GF_Descriptor *) esd); return gf_export_message(dumper, GF_IO_ERR, "Error opening %s for writing - check disk access & permissions", szName); } bs = gf_bs_from_file(out_nhnt, GF_BITSTREAM_WRITE); if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { sprintf(szName, "%s.info", dumper->out_name); out_inf = fopen(szName, "wb"); if (out_inf) fwrite(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, 1, out_inf); fclose(out_inf); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -