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

📄 theora_dec.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / XIPH.org module * *  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 "ogg_in.h"#ifdef GPAC_HAS_THEORA#include <theora/theora.h>typedef struct{    theora_info ti;	theora_state td;    theora_comment tc;    ogg_packet op;		u16 ES_ID;	Bool has_reconfigured;} TheoraDec;#define THEORACTX() TheoraDec *ctx = (TheoraDec *) ((OGGWraper *)ifcg->privateStack)->opaquestatic GF_Err THEO_AttachStream(GF_BaseDecoder *ifcg, u16 ES_ID, char *decSpecInfo, u32 decSpecInfoSize, u16 DependsOnES_ID, u32 objectTypeIndication, Bool UpStream){    ogg_packet oggpacket;	GF_BitStream *bs;	THEORACTX();	if (ctx->ES_ID) return GF_BAD_PARAM;		if (!decSpecInfo) return GF_NON_COMPLIANT_BITSTREAM;	if (objectTypeIndication != GPAC_OGG_MEDIA_OTI) return GF_NON_COMPLIANT_BITSTREAM;	if ( (decSpecInfoSize<9) || strncmp(&decSpecInfo[3], "theora", 6)) return GF_NON_COMPLIANT_BITSTREAM;	oggpacket.granulepos = -1;	oggpacket.b_o_s = 1;	oggpacket.e_o_s = 0;	oggpacket.packetno = 0;	ctx->ES_ID = ES_ID;    theora_info_init(&ctx->ti);    theora_comment_init(&ctx->tc);	bs = gf_bs_new(decSpecInfo, decSpecInfoSize, GF_BITSTREAM_READ);	while (gf_bs_available(bs)) {		oggpacket.bytes = gf_bs_read_u16(bs);		oggpacket.packet = malloc(sizeof(char) * oggpacket.bytes);		gf_bs_read_data(bs, oggpacket.packet, oggpacket.bytes);		if (theora_decode_header(&ctx->ti, &ctx->tc, &oggpacket) < 0 ) {			free(oggpacket.packet);			gf_bs_del(bs);			return GF_NON_COMPLIANT_BITSTREAM;		}		free(oggpacket.packet);	}    theora_decode_init(&ctx->td, &ctx->ti);	gf_bs_del(bs);	return GF_OK;}static GF_Err THEO_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID){	THEORACTX();	if (ctx->ES_ID != ES_ID) return GF_BAD_PARAM;	theora_clear(&ctx->td);     theora_info_clear(&ctx->ti);    theora_comment_clear(&ctx->tc);	ctx->ES_ID = 0;	return GF_OK;}static GF_Err THEO_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *capability){	THEORACTX();	switch (capability->CapCode) {	case GF_CODEC_WIDTH:		capability->cap.valueInt = ctx->ti.width;		break;	case GF_CODEC_HEIGHT:		capability->cap.valueInt = ctx->ti.height;		break;	case GF_CODEC_STRIDE:		capability->cap.valueInt = ctx->ti.width;		break;	case GF_CODEC_FPS:		capability->cap.valueFloat = (Float) ctx->ti.fps_numerator;		capability->cap.valueFloat /= ctx->ti.fps_denominator;		break;	case GF_CODEC_PIXEL_FORMAT:		capability->cap.valueInt = GF_PIXEL_YV12;		break;	case GF_CODEC_REORDER:		capability->cap.valueInt = 0;		break;	case GF_CODEC_RESILIENT:		capability->cap.valueInt = 1;		break;	case GF_CODEC_OUTPUT_SIZE:		capability->cap.valueInt = 3*ctx->ti.width * ctx->ti.height / 2;		break;	case GF_CODEC_BUFFER_MIN:		capability->cap.valueInt = 1;		break;	case GF_CODEC_BUFFER_MAX:		capability->cap.valueInt = 4;		break;	case GF_CODEC_PADDING_BYTES:		capability->cap.valueInt = 0;		break;	default:		capability->cap.valueInt = 0;		break;	}	return GF_OK;}static GF_Err THEO_SetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability capability){	/*return unsupported to avoid confusion by the player (like SR changing ...) */	return GF_NOT_SUPPORTED;}static GF_Err THEO_ProcessData(GF_MediaDecoder *ifcg, 		char *inBuffer, u32 inBufferLength,		u16 ES_ID,		char *outBuffer, u32 *outBufferLength,		u8 PaddingBits, u32 mmlevel){	ogg_packet op;	yuv_buffer yuv;	u32 i;	char *pYO, *pUO, *pVO;	unsigned char *pYD, *pUD, *pVD;	THEORACTX();	/*not using scalabilty*/	assert(ctx->ES_ID == ES_ID);	op.granulepos = -1;	op.b_o_s = 0;	op.e_o_s = 0;	op.packetno = 0;    op.packet = inBuffer;    op.bytes = inBufferLength;	*outBufferLength = 0;    if (theora_decode_packetin(&ctx->td, &op)<0) return GF_NON_COMPLIANT_BITSTREAM;	if (mmlevel	== GF_CODEC_LEVEL_SEEK) return GF_OK;    if (theora_decode_YUVout(&ctx->td, &yuv)<0) return GF_OK;	pYO = yuv.y;	pUO = yuv.u;	pVO = yuv.v;	pYD = outBuffer;	pUD = outBuffer + ctx->ti.width * ctx->ti.height;	pVD = outBuffer + 5 * ctx->ti.width * ctx->ti.height / 4;		for (i=0; i<(u32)yuv.y_height; i++) {		memcpy(pYD, pYO, sizeof(char) * yuv.y_width);		pYD += ctx->ti.width;		pYO += yuv.y_stride;		if (i%2) continue;		memcpy(pUD, pUO, sizeof(char) * yuv.uv_width);		memcpy(pVD, pVO, sizeof(char) * yuv.uv_width);		pUD += ctx->ti.width/2;		pVD += ctx->ti.width/2;		pUO += yuv.uv_stride;		pVO += yuv.uv_stride;	}	*outBufferLength = 3*ctx->ti.width*ctx->ti.height/2;	return GF_OK;}static const char *THEO_GetCodecName(GF_BaseDecoder *dec){	return "Theora Decoder";}u32 NewTheoraDecoder(GF_BaseDecoder *ifcd){	TheoraDec *dec;	GF_SAFEALLOC(dec, TheoraDec);	((OGGWraper *)ifcd->privateStack)->opaque = dec;	((OGGWraper *)ifcd->privateStack)->type = OGG_THEORA;	/*setup our own interface*/		ifcd->AttachStream = THEO_AttachStream;	ifcd->DetachStream = THEO_DetachStream;	ifcd->GetCapabilities = THEO_GetCapabilities;	ifcd->SetCapabilities = THEO_SetCapabilities;	((GF_MediaDecoder*)ifcd)->ProcessData = THEO_ProcessData;	ifcd->GetName = THEO_GetCodecName;	return 1;}void DeleteTheoraDecoder(GF_BaseDecoder *ifcg){	THEORACTX();	free(ctx);}#endif

⌨️ 快捷键说明

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