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

📄 decoder.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / Media terminal 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/terminal_dev.h>#include <gpac/internal/renderer_dev.h>#include <gpac/constants.h>#include "media_memory.h"#include "media_control.h"#include "input_sensor.h"/*update config of object*/void MO_UpdateCaps(GF_MediaObject *mo);#define TIME_CHECK		3GF_Err Codec_Load(GF_Codec *codec, GF_ESD *esd, u32 PL);GF_Codec *gf_codec_new(GF_ObjectManager *odm, GF_ESD *base_layer, s32 PL, GF_Err *e){	GF_Codec *tmp;	GF_SAFEALLOC(tmp, GF_Codec);	if (! tmp) {		*e = GF_OUT_OF_MEM;		return NULL;	}	tmp->odm = odm;	if (PL<0) PL = 0xFF;	*e = Codec_Load(tmp, base_layer, PL);		if (*e) {		free(tmp);		return NULL;	}	/*remember codec type*/	tmp->type = base_layer->decoderConfig->streamType;	tmp->inChannels = gf_list_new();		tmp->Status = GF_ESM_CODEC_STOP;		return tmp;}GF_Codec *gf_codec_use_codec(GF_Codec *codec, GF_ObjectManager *odm){	GF_Codec *tmp;	if (!codec->decio) return NULL;	GF_SAFEALLOC(tmp, GF_Codec);	tmp->type = codec->type;	tmp->inChannels = gf_list_new();		tmp->Status = GF_ESM_CODEC_STOP;	tmp->odm = odm;	tmp->flags = codec->flags | GF_ESM_CODEC_IS_USE;	tmp->decio = codec->decio;	return tmp;}GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch){	GF_Err e;	GF_NetworkCommand com;	GF_Channel *a_ch;	char *dsi;	u32 dsiSize, CUsize, i;	GF_CodecCapability cap;	u32 min, max;	/*only for valid codecs (eg not OCR)*/	if (codec->decio) {		com.get_dsi.dsi = NULL;		dsi = NULL;		dsiSize = 0;		if (ch->esd->decoderConfig->upstream) codec->flags |= GF_ESM_CODEC_HAS_UPSTREAM;		if (ch->esd->decoderConfig->decoderSpecificInfo) {			dsi = ch->esd->decoderConfig->decoderSpecificInfo->data;			dsiSize = ch->esd->decoderConfig->decoderSpecificInfo->dataLength;		} 		/*For objects declared in OD stream, override with network DSI if any*/		if (ch->service && !(ch->odm->flags & GF_ODM_NOT_IN_OD_STREAM) ) {			com.command_type = GF_NET_CHAN_GET_DSI;			com.base.on_channel = ch;			e = gf_term_service_command(ch->service, &com);			if (!e && com.get_dsi.dsi) {				dsi = com.get_dsi.dsi;				dsiSize = com.get_dsi.dsi_len;			}		}		e = codec->decio->AttachStream(codec->decio, ch->esd->ESID, 					dsi, dsiSize, ch->esd->dependsOnESID, ch->esd->decoderConfig->objectTypeIndication, ch->esd->decoderConfig->upstream);		if (com.get_dsi.dsi) {			if (ch->esd->decoderConfig->decoderSpecificInfo->data) free(ch->esd->decoderConfig->decoderSpecificInfo->data);			ch->esd->decoderConfig->decoderSpecificInfo->data = com.get_dsi.dsi;			ch->esd->decoderConfig->decoderSpecificInfo->dataLength = com.get_dsi.dsi_len;		}		if (e) return e;		/*ask codec for desired output capacity - note this may be 0 if stream is not yet configured*/		cap.CapCode = GF_CODEC_OUTPUT_SIZE;		gf_codec_get_capability(codec, &cap);		if (codec->CB && (cap.cap.valueInt != codec->CB->UnitSize)) {			gf_cm_del(codec->CB);			codec->CB = NULL;		}		CUsize = cap.cap.valueInt;		/*get desired amount of units and minimal fullness (used for scheduling)*/		switch(codec->type) {		case GF_STREAM_VISUAL:		case GF_STREAM_AUDIO:			cap.CapCode = GF_CODEC_BUFFER_MIN;			gf_codec_get_capability(codec, &cap);			min = cap.cap.valueInt;			cap.CapCode = GF_CODEC_BUFFER_MAX;			gf_codec_get_capability(codec, &cap);			max = cap.cap.valueInt;			break;		case GF_STREAM_ND_SUBPIC:			max = 1;			min = 0;			break;		default:			min = max = 0;		}		if ((codec->type==GF_STREAM_AUDIO) && (max<2)) max = 2;		/*setup CB*/		if (!codec->CB && max) {			codec->CB = gf_cm_new(CUsize, max);			codec->CB->Min = min;			codec->CB->odm = codec->odm;		}		/*check re-ordering*/		cap.CapCode = GF_CODEC_REORDER;		gf_codec_get_capability(codec, &cap);		if (cap.cap.valueInt) codec->is_reordering = 1;		/*setup net channel config*/		if (ch->service) {			memset(&com, 0, sizeof(GF_NetworkCommand));			com.command_type = GF_NET_CHAN_CONFIG;			com.base.on_channel = ch;			com.cfg.priority = ch->esd->streamPriority;			com.cfg.sync_id = (u32) ch->clock;			memcpy(&com.cfg.sl_config, ch->esd->slConfig, sizeof(GF_SLConfig));			/*get the frame duration if audio (used by some network stack)*/			if (ch->odm->codec && (ch->odm->codec->type==GF_STREAM_AUDIO) ) {				cap.CapCode = GF_CODEC_SAMPLERATE;				gf_codec_get_capability(ch->odm->codec, &cap);				com.cfg.sample_rate = cap.cap.valueInt;				cap.CapCode = GF_CODEC_CU_DURATION;				gf_codec_get_capability(ch->odm->codec, &cap);				com.cfg.frame_duration = cap.cap.valueInt;			} 			gf_term_service_command(ch->service, &com);		}	}	/*assign the first base layer as the codec clock by default, or current channel clock if no clock set	Also assign codec priority here*/	if (!ch->esd->dependsOnESID || !codec->ck) {		codec->ck = ch->clock;		codec->Priority = ch->esd->streamPriority;		/*insert base layer first - note we are sure this is a stream of the same type		as the codec (other streams - OCI, MPEG7, MPEGJ - are not added that way)*/		return gf_list_insert(codec->inChannels, ch, 0);	}	else {		/*make sure all channels are in order*/		i=0;		while ((a_ch = (GF_Channel*)gf_list_enum(codec->inChannels, &i))) {			if (ch->esd->dependsOnESID == a_ch->esd->ESID) {				return gf_list_insert(codec->inChannels, ch, i);			}			if (a_ch->esd->dependsOnESID == ch->esd->ESID) {				return gf_list_insert(codec->inChannels, ch, i-1);			}		}		/*by default append*/		return gf_list_add(codec->inChannels, ch);	}}Bool gf_codec_remove_channel(GF_Codec *codec, struct _es_channel *ch){	s32 i;	i = gf_list_find(codec->inChannels, ch);	if (i>=0) {		if (codec->decio) codec->decio->DetachStream(codec->decio, ch->esd->ESID);		gf_list_rem(codec->inChannels, (u32) i);		return 1;	}	return 0;}static void codec_update_stats(GF_Codec *codec, u32 dataLength, u32 dec_time){	codec->total_dec_time += dec_time;	codec->nb_dec_frames++;	if (dec_time>codec->max_dec_time) codec->max_dec_time = dec_time;	if (dataLength) {		u32 now = gf_clock_time(codec->ck);		if (codec->last_stat_start + 1000 <= now) {			if (!codec->cur_bit_size) {				codec->last_stat_start = now;			} else {				codec->avg_bit_rate = codec->cur_bit_size;				if (codec->avg_bit_rate > codec->max_bit_rate) codec->max_bit_rate = codec->avg_bit_rate;				codec->last_stat_start = now;				codec->cur_bit_size = 0;			}		}		codec->cur_bit_size += 8*dataLength;	}}/*scalable browsing of input channels: find the AU with the lowest DTS on all input channels*/static void Decoder_GetNextAU(GF_Codec *codec, GF_Channel **activeChannel, GF_DBUnit **nextAU){	GF_Channel *ch;	GF_DBUnit *AU;	u32 count, minDTS, i;	count = gf_list_count(codec->inChannels);	*nextAU = NULL;	*activeChannel = NULL;	if (!count) return;	minDTS = (u32) -1;	/*reverse browsing to make sure we fill enhancement before base layer*/	for (i=count;i>0;i--) {		ch = (GF_Channel*)gf_list_get(codec->inChannels, i-1);		if ((codec->type==GF_STREAM_OCR) && ch->IsClockInit) {			/*check duration - we assume that scalable OCR streams are just pure nonsense...*/			if (ch->is_pulling && codec->odm->duration) {				if (gf_clock_time(codec->ck) > codec->odm->duration) 					gf_es_on_eos(ch);			}			return;		}		AU = gf_es_get_au(ch);		if (!AU) {			if (! (*activeChannel)) *activeChannel = ch;			continue;		}		/*we use <= to make sure we first fetch data on base layer if same		DTS (which is possible in spatial scalability)*/		if (AU->DTS <= minDTS) {			minDTS = AU->DTS;			*activeChannel = ch;			*nextAU = AU;		}	}	/*FIXME - we're breaking sync (couple of frames delay)*/	if (*nextAU && codec->is_reordering) (*nextAU)->CTS = (*nextAU)->DTS;}static GF_Err SystemCodec_Process(GF_Codec *codec, u32 TimeAvailable){	GF_DBUnit *AU;	GF_Channel *ch;	u32 now, obj_time, mm_level, au_time;	Bool scene_locked;	Bool check_next_unit;	GF_SceneDecoder *sdec = (GF_SceneDecoder *)codec->decio;	GF_Err e = GF_OK;	scene_locked = 0;		/*for resync, if needed - the logic behind this is that there is no composition memory on sytems codecs so	"frame dropping" is done by preventing the renderer from redrawing after an update and decoding following AU	so that the renderer is always woken up once all late systems AUs are decoded. This flag is overriden when 	seeking*/	check_next_unit = (codec->odm->term->flags & GF_TERM_SYSDEC_RESYNC) ? 1 : 0;	check_unit:	/*muting systems codec means we don't decode until mute is off - likely there will be visible however	there is no other way to decode system AUs without modifying the content, which is what mute is about on visual...*/	if (codec->Muted) goto exit;	/*fetch next AU in DTS order for this codec*/	Decoder_GetNextAU(codec, &ch, &AU);	/*get the object time*/	obj_time = gf_clock_time(codec->ck);	/*no active channel return*/	if (!AU || !ch) {		/*if the codec is in EOS state, move to STOP*/		if (codec->Status == GF_ESM_CODEC_EOS) {			GF_CodecCapability cap;

⌨️ 快捷键说明

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