⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 media_export.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / Media Tools sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/internal/media_dev.h>#include <gpac/mpegts.h>#include <gpac/constants.h>#ifndef GPAC_READ_ONLY#include <gpac/internal/avilib.h>#include <gpac/internal/ogg.h>#include <gpac/internal/vobsub.h>static GF_Err gf_export_message(GF_MediaExporter *dumper, GF_Err e, char *format, ...){	if (dumper->flags & GF_EXPORT_PROBE_ONLY) return e;#ifndef GPAC_DISABLE_LOG	if (gf_log_get_level() && (gf_log_get_tools() & GF_LOG_AUTHOR)) {		va_list args;		char szMsg[1024];		va_start(args, format);		vsprintf(szMsg, format, args);		va_end(args);		GF_LOG((u32) (e ? GF_LOG_ERROR : GF_LOG_WARNING), GF_LOG_AUTHOR, ("%s\n", szMsg) );	}#endif	return e;}/*that's very very crude, we only support vorbis & theora in MP4 - this will need cleanup as soon as possible*/static GF_Err gf_dump_to_ogg(GF_MediaExporter *dumper, char *szName, u32 track){	FILE *out;	ogg_stream_state os;	ogg_packet op;	ogg_page og;	u32 count, i, di, theora_kgs, nb_i, nb_p;	GF_BitStream *bs;	GF_ISOSample *samp;	GF_ESD *esd = gf_isom_get_esd(dumper->file, track, 1);	gf_rand_init(1);	ogg_stream_init(&os, gf_rand());	op.granulepos = 0;	op.packetno = 0;	op.b_o_s = 1;	op.e_o_s = 0;	out = gf_f64_open(szName, "wb");	if (!out) return gf_export_message(dumper, GF_IO_ERR, "Error opening %s for writing - check disk access & permissions", szName);	theora_kgs = 0;	bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ);	while (gf_bs_available(bs)) {		op.bytes = gf_bs_read_u16(bs);		op.packet = (unsigned char*)malloc(sizeof(char) * op.bytes);		gf_bs_read_data(bs, (char*)op.packet, op.bytes);		ogg_stream_packetin(&os, &op);		if (op.b_o_s) {			ogg_stream_pageout(&os, &og);			fwrite(og.header, 1, og.header_len, out);			fwrite(og.body, 1, og.body_len, out);			op.b_o_s = 0;			if (esd->decoderConfig->objectTypeIndication==0xDF) {				u32 kff;				GF_BitStream *vbs = gf_bs_new((char*)op.packet, op.bytes, GF_BITSTREAM_READ);				gf_bs_skip_bytes(vbs, 40);				gf_bs_read_int(vbs, 6); /* quality */				kff = 1 << gf_bs_read_int(vbs, 5);				gf_bs_del(vbs);				theora_kgs = 0;				kff--;				while (kff) {					theora_kgs ++;					kff >>= 1;				}			}		}		free(op.packet);		op.packetno ++;	}	gf_bs_del(bs);	gf_odf_desc_del((GF_Descriptor *)esd);	while (ogg_stream_pageout(&os, &og)>0) {		fwrite(og.header, 1, og.header_len, out);		fwrite(og.body, 1, og.body_len, out);	}		op.granulepos = -1;	count = gf_isom_get_sample_count(dumper->file, track);	nb_i = nb_p = 0;	samp = gf_isom_get_sample(dumper->file, track, 1, &di);	for (i=0; i<count; i++) {		GF_ISOSample *next_samp = gf_isom_get_sample(dumper->file, track, i+2, &di);		if (!samp) break;		op.bytes = samp->dataLength;		op.packet = (unsigned char*)samp->data;		op.packetno ++;		if (theora_kgs) {			if (samp->IsRAP) {				if (i) nb_i+=nb_p+1;				nb_p = 0;			} else {				nb_p++;			}			op.granulepos = nb_i;			op.granulepos <<= theora_kgs;			op.granulepos |= nb_p;		} else {			if (next_samp) op.granulepos = next_samp->DTS;		}		if (!next_samp) op.e_o_s = 1;		ogg_stream_packetin(&os, &op);		gf_isom_sample_del(&samp);		samp = next_samp;		next_samp = NULL;		gf_set_progress("OGG Export", i+1, count);		if (dumper->flags & GF_EXPORT_DO_ABORT) break;		while (ogg_stream_pageout(&os, &og)>0) {			fwrite(og.header, 1, og.header_len, out);			fwrite(og.body, 1, og.body_len, out);		}	}	if (samp) gf_isom_sample_del(&samp);	while (ogg_stream_flush(&os, &og)>0) {		fwrite(og.header, 1, og.header_len, out);		fwrite(og.body, 1, og.body_len, out);	}    ogg_stream_clear(&os);	fclose(out);	return GF_OK;}GF_Err gf_export_hint(GF_MediaExporter *dumper){	GF_Err e;	char szName[1000], szType[5];	char *pck;	FILE *out;	u32 track, i, size, m_stype, sn, count;	track = gf_isom_get_track_by_id(dumper->file, dumper->trackID);	m_stype = gf_isom_get_media_subtype(dumper->file, track, 1);	e = gf_isom_reset_hint_reader(dumper->file, track, dumper->sample_num ? dumper->sample_num : 1, 0, 0, 0);	if (e) return gf_export_message(dumper, e, "Error initializing hint reader");	gf_export_message(dumper, GF_OK, "Extracting hint track samples - type %s", szType);	count = gf_isom_get_sample_count(dumper->file, track);	if (dumper->sample_num) count = 0;	i = 1;	while (1) {		e = gf_isom_next_hint_packet(dumper->file, track, &pck, &size, NULL, NULL, NULL, &sn);		if (e==GF_EOS) break;		if (dumper->sample_num && (dumper->sample_num != sn)) {			free(pck);			break;		}		if (e) return gf_export_message(dumper, e, "Error fetching hint packet %d", i);		sprintf(szName, "%s_pck_%04d.%s", dumper->out_name, i, gf_4cc_to_str(m_stype));		out = fopen(szName, "wb");		fwrite(pck, size, 1, out);		fclose(out);		free(pck);		i++;		if (count) gf_set_progress("Hint Export", sn, count);	}	if (count) gf_set_progress("Hint Export", count, count);	return GF_OK;}static void write_jp2_file(GF_BitStream *bs, char *data, u32 data_size, char *dsi, u32 dsi_size){	gf_bs_write_u32(bs, 12);	gf_bs_write_u32(bs, GF_4CC('j','P',' ',' '));	gf_bs_write_u32(bs, 0x0D0A870A);	gf_bs_write_u32(bs, 20);	gf_bs_write_u32(bs, GF_4CC('f','t','y','p'));	gf_bs_write_u32(bs, GF_4CC('j','p','2',' '));	gf_bs_write_u32(bs, 0);	gf_bs_write_u32(bs, GF_4CC('j','p','2',' '));	gf_bs_write_data(bs, dsi, dsi_size);	gf_bs_write_data(bs, data, data_size);}GF_Err gf_media_export_samples(GF_MediaExporter *dumper){	GF_DecoderConfig *dcfg;	GF_GenericSampleDescription *udesc;	char szName[1000], szEXT[10], szNum[1000], *dsi;	FILE *out;	GF_BitStream *bs;	u32 track, i, di, count, m_type, m_stype, dsi_size, is_mj2k;	track = gf_isom_get_track_by_id(dumper->file, dumper->trackID);	m_type = gf_isom_get_media_type(dumper->file, track);	m_stype = gf_isom_get_media_subtype(dumper->file, track, 1);	dsi_size = 0;	if (dumper->sample_num) sprintf(szNum, " %d", dumper->sample_num);	else strcpy(szNum, "s");	is_mj2k = 0;	dsi = NULL;	udesc = NULL;	dcfg = NULL;	if ((m_stype==GF_ISOM_SUBTYPE_MPEG4) || (m_stype==GF_ISOM_SUBTYPE_MPEG4_CRYP)) 		dcfg = gf_isom_get_decoder_config(dumper->file, track, 1);	strcpy(szName, dumper->out_name ? dumper->out_name : "");	if (dcfg) {		switch (dcfg->streamType) {		case GF_STREAM_VISUAL:			switch (dcfg->objectTypeIndication) {			case 0x20:				strcpy(szEXT, ".cmp");				gf_export_message(dumper, GF_OK, "Dumping MPEG-4 Visual sample%s", szNum);				break;			case 0x21:				strcpy(szEXT, ".h264");				gf_export_message(dumper, GF_OK, "Dumping MPEG-4 AVC-H264 Visual sample%s", szNum);				break;			case 0x6C:				strcpy(szEXT, ".jpg");				gf_export_message(dumper, GF_OK, "Dumping JPEG image%s", szNum);				break;			case 0x6D:				strcpy(szEXT, ".png");				gf_export_message(dumper, GF_OK, "Dumping PNG image%s", szNum);				break;			case 0x6E:				strcpy(szEXT, ".jp2");				gf_export_message(dumper, GF_OK, "Dumping JPEG 2000 image%s", szNum);				break;			case GPAC_OGG_MEDIA_OTI:				strcpy(szEXT, ".theo");				gf_export_message(dumper, GF_OK, "Dumping Theora video sample%s", szNum);				break;			default:				strcpy(szEXT, ".raw");				gf_export_message(dumper, GF_OK, "Dumping Unknown video sample%s (OTI %d)", szNum, dcfg->objectTypeIndication);				break;			}			break;		case GF_STREAM_AUDIO:			switch (dcfg->objectTypeIndication) {			case 0x66:			case 0x67:			case 0x68:			case 0x40:				strcpy(szEXT, ".aac");				gf_export_message(dumper, GF_OK, "Dumping MPEG-%d AAC sample%s", (dcfg->objectTypeIndication==0x40) ? 4 : 2, szNum);				break;			case 0x69:			case 0x6B:				strcpy(szEXT, ".mp3");				gf_export_message(dumper, GF_OK, "Dumping MPEG-1/2 Audio (MP3) sample%s", szNum);				break;			case GPAC_OGG_MEDIA_OTI:				strcpy(szEXT, ".vorb");				gf_export_message(dumper, GF_OK, "Dumping Vorbis audio sample%s", szNum);				break;			default:				strcpy(szEXT, ".raw");				gf_export_message(dumper, GF_OK, "Dumping Unknown audio sample%s (OTI %d)", szNum, dcfg->objectTypeIndication);				break;			}			break;		case GF_STREAM_SCENE:			strcpy(szEXT, ".bifs"); gf_export_message(dumper, GF_OK, "Dumping BIFS sample%s", szNum); 			break;		case GF_STREAM_OD:			strcpy(szEXT, ".od"); gf_export_message(dumper, GF_OK, "Dumping OD sample%s", szNum); 			break;		case GF_STREAM_MPEGJ:			strcpy(szEXT, ".mpj"); gf_export_message(dumper, GF_OK, "Dumping MPEG-J sample%s", szNum); 			break;		case GF_STREAM_OCI:			strcpy(szEXT, ".oci"); gf_export_message(dumper, GF_OK, "Dumping OCI sample%s", szNum); 			break;		case GF_STREAM_MPEG7:			strcpy(szEXT, ".mp7"); gf_export_message(dumper, GF_OK, "Dumping MPEG7 sample%s", szNum); 			break;		case GF_STREAM_IPMP:			strcpy(szEXT, ".ipmp"); gf_export_message(dumper, GF_OK, "Dumping IPMP sample%s", szNum); 			break;		case GF_STREAM_TEXT:			strcpy(szEXT, ".tx3g"); gf_export_message(dumper, GF_OK, "Dumping 3GP Text sample%s", szNum); 			break;		default:			gf_odf_desc_del((GF_Descriptor *) dcfg);			return gf_export_message(dumper, GF_NOT_SUPPORTED, "Cannot dump systems track ID %d sample%s - use NHNT", dumper->trackID, szNum);		}		gf_odf_desc_del((GF_Descriptor *) dcfg);	} else if ((m_stype==GF_ISOM_SUBTYPE_3GP_AMR) || (m_stype==GF_ISOM_SUBTYPE_3GP_AMR_WB)) {		strcpy(szEXT, ".amr");		gf_export_message(dumper, GF_OK, "Extracting AMR Audio sample%s", szNum);	} else if (m_stype==GF_ISOM_SUBTYPE_3GP_H263) {		gf_export_message(dumper, GF_OK, "Extracting H263 Video sample%s", szNum);		strcpy(szEXT, ".263");	} else if (m_stype==GF_ISOM_SUBTYPE_AVC_H264) {		strcpy(szEXT, ".h264");		gf_export_message(dumper, GF_OK, "Dumping MPEG-4 AVC-H264 Visual sample%s", szNum);	} else if (m_type==GF_ISOM_MEDIA_FLASH) {		gf_export_message(dumper, GF_OK, "Extracting Macromedia Flash Movie sample%s", szNum);		strcpy(szEXT, ".swf");	} else if (m_type==GF_ISOM_MEDIA_HINT) {		return gf_export_hint(dumper);	} else if (m_stype==GF_4CC('m','j','p','2')) {		strcpy(szEXT, ".jp2");		gf_export_message(dumper, GF_OK, "Dumping JPEG 2000 sample%s", szNum);		udesc = gf_isom_get_generic_sample_description(dumper->file, track, 1);		dsi = udesc->extension_buf;		dsi_size = udesc->extension_buf_size;		free(udesc);		is_mj2k = 1;	} else {		strcpy(szEXT, ".");		strcat(szEXT, gf_4cc_to_str(m_stype));		udesc = gf_isom_get_generic_sample_description(dumper->file, track, 1);		switch (m_type) {		case GF_ISOM_MEDIA_VISUAL: gf_export_message(dumper, GF_OK, "Extracting \'%s\' Video - Compressor %s", szEXT, udesc ? udesc->compressor_name: "Unknown"); break;		case GF_ISOM_MEDIA_AUDIO: gf_export_message(dumper, GF_OK, "Extracting \'%s\' Audio - Compressor %s", szEXT, udesc ? udesc->compressor_name : "Unknown"); break;		default:			gf_export_message(dumper, GF_OK, "Extracting \'%s\' Track (type '%s') - Compressor %s sample%s", szEXT, gf_4cc_to_str(m_type), udesc ? udesc->compressor_name : "Unknown", szNum);			break;		}		if (udesc->extension_buf) free(udesc->extension_buf);		if (udesc) free(udesc);	}	if (dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_OK;	if (dumper->sample_num) {		GF_ISOSample *samp = gf_isom_get_sample(dumper->file, track, dumper->sample_num, &di);		if (!samp) return GF_BAD_PARAM;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -