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

📄 decoder.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
			cap.CapCode = GF_CODEC_MEDIA_NOT_OVER;			cap.cap.valueInt = 0;			sdec->GetCapabilities(codec->decio, &cap);			if (!cap.cap.valueInt) {				gf_term_stop_codec(codec);				if ((codec->type==GF_STREAM_OD) && (codec->nb_dec_frames==1)) {					/*this is just by safety, since seeking is only allowed when a single clock is present 					in the scene*/					if (gf_list_count(codec->odm->net_service->Clocks)==1)						codec->odm->subscene->static_media_ressources=1;				}			}		}		goto exit;	}		/*clock is not started*///	if (ch->first_au_fetched && !gf_clock_is_started(ch->clock)) goto exit;	/*check timing based on the input channel and main FPS*///	if ( (AU->DTS > obj_time + codec->odm->term->half_frame_duration) ) goto exit;	if ( (AU->DTS > obj_time ) ) goto exit;	/*check seeking and update timing - do NOT use the base layer, since BIFS streams may depend on other 	streams not on the same clock*/	if (codec->last_unit_cts == AU->CTS ) {		/*hack for RTSP streaming of systems streams, except InputSensor*/		if (!ch->is_pulling && (codec->type != GF_STREAM_INTERACT) && (AU->dataLength == codec->prev_au_size)) {			gf_es_drop_au(ch);			GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[Decoder] Same MPEG-4 Systems AU detected - dropping\n"));			goto check_unit;		}		/*seeking for systems is done by not releasing the graph until seek is done*/		check_next_unit = 1;		mm_level = GF_CODEC_LEVEL_SEEK;		au_time = AU->DTS;	} 	/*set system stream timing*/	else {		codec->last_unit_cts = AU->CTS;		/*we're droping the frame*/		if (scene_locked) codec->nb_droped ++;		mm_level = GF_CODEC_LEVEL_NORMAL;		au_time = AU->DTS;	}	/*lock scene*/	if (!scene_locked) {		gf_term_lock_renderer(codec->odm->term, 1);		scene_locked = 1;		/*if terminal is paused, force step-mode: it won't hurt in regular pause/play and ensures proper frame dumping*/		if (codec->odm->term->play_state) codec->odm->term->renderer->step_mode=1;	}	/*current media time for system objects is the clock time, since the media is likely to have random 	updates in time*/	codec->odm->current_time = gf_clock_time(codec->ck);	now = gf_term_get_time(codec->odm->term);	e = sdec->ProcessData(sdec, AU->data, AU->dataLength, ch->esd->ESID, au_time, mm_level);	now = gf_term_get_time(codec->odm->term) - now;	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[SysDec] Codec %s Processing AU CTS %d\n", sdec->module_name , AU->CTS));	codec_update_stats(codec, AU->dataLength, now);	codec->prev_au_size = AU->dataLength;	/*destroy this AU*/	gf_es_drop_au(ch);	if (e) {		ch->stream_state = 2;		goto exit;	}	/*OD acts as scene codec, regenerate scene*/	if (codec->flags & GF_ESM_CODEC_IS_SCENE_OD) gf_is_regenerate(codec->odm->subscene ? codec->odm->subscene : codec->odm->parentscene);	/*in broadcast mode, generate a scene if none is available*/	else if (codec->ck->no_time_ctrl) {		GF_InlineScene *is = codec->odm->subscene ? codec->odm->subscene : codec->odm->parentscene;		/*static OD resources (embedded in ESD) in broadcast mode, reset time*/		if (codec->flags & GF_ESM_CODEC_IS_STATIC_OD) gf_clock_reset(codec->ck);		/*generate a temp scene if none is in place*/		if (is->graph_attached != 1 ) {			Bool prev_dyn = is->is_dynamic_scene; 			is->is_dynamic_scene = 1;			gf_is_regenerate(is);			is->graph_attached = 2;			is->is_dynamic_scene = prev_dyn;			GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[Decoder] Got OD resources before scene - generating temporary scene\n"));		}	}	/*if no release restart*/	if (check_next_unit) goto check_unit;	exit:	if (scene_locked) gf_term_lock_renderer(codec->odm->term, 0);	return e;}/*special handling of decoders not using ESM*/static GF_Err PrivateScene_Process(GF_Codec *codec, u32 TimeAvailable){	Bool resume_clock;	u32 now;	GF_Channel *ch;	GF_SceneDecoder *sdec = (GF_SceneDecoder *)codec->decio;	GF_Err e = GF_OK;		/*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) return GF_OK;	if (codec->Status == GF_ESM_CODEC_EOS) {		gf_term_stop_codec(codec);		return GF_OK;	}	ch = (GF_Channel*)gf_list_get(codec->inChannels, 0);	if (!ch) return GF_OK;	resume_clock = 0;	/*init channel clock*/	if (!ch->IsClockInit) {		gf_es_init_dummy(ch);		if (!gf_clock_is_started(ch->clock)) return GF_OK;		/*let's be nice to the scene loader (that usually involves quite some parsing), pause clock while		parsing*/		gf_clock_pause(ch->clock);		codec->last_unit_dts = 0;	}	codec->odm->current_time = codec->last_unit_cts = gf_clock_time(codec->ck);	/*lock scene*/	gf_term_lock_renderer(codec->odm->term, 1);	now = gf_term_get_time(codec->odm->term);	e = sdec->ProcessData(sdec, NULL, codec->odm->current_time, ch->esd->ESID, codec->odm->current_time, GF_CODEC_LEVEL_NORMAL);	now = gf_term_get_time(codec->odm->term) - now;	codec->last_unit_dts ++;	/*resume on error*/	if (e && (codec->last_unit_dts<2) ) {		gf_clock_resume(ch->clock);		codec->last_unit_dts = 2;	}	/*resume clock on 2nd decode (we assume parsing is done in 2 steps, one for first frame display, one for complete parse)*/	else if (codec->last_unit_dts==2) {		gf_clock_resume(ch->clock);	}	codec_update_stats(codec, 0, now);	gf_term_lock_renderer(codec->odm->term, 0);	if (e==GF_EOS) {		/*first end of stream, evaluate duration*/		if (!codec->odm->duration) gf_odm_set_duration(codec->odm, ch, codec->odm->current_time);		gf_es_on_eos(ch);		return GF_OK;	}	return e;}/*Get a pointer to the next CU buffer*/static GFINLINE GF_Err LockCompositionUnit(GF_Codec *dec, u32 CU_TS, char **outBuffer, u32 *availableSize){	GF_CMUnit *cu;	*outBuffer = NULL;	*availableSize = 0;	if (!dec->CB) return GF_BAD_PARAM;		cu = gf_cm_lock_input(dec->CB, CU_TS);	if (!cu ) return GF_OUT_OF_MEM;		cu->TS = CU_TS;	*outBuffer = cu->data;	*availableSize = dec->CB->UnitSize;	return GF_OK;}static GFINLINE GF_Err UnlockCompositionUnit(GF_Codec *dec, u32 CTS, u32 NbBytes){	/*temporal scalability disabling: if we already rendered this, no point getting further*/	if (CTS < dec->CB->LastRenderedTS) NbBytes = 0;	/*unlock the CB*/	gf_cm_unlock_input(dec->CB, CTS, NbBytes);	return GF_OK;}static GF_Err ResizeCompositionBuffer(GF_Codec *dec, u32 NewSize){	if (!dec || !dec->CB) return GF_BAD_PARAM;		/*update config*/	MO_UpdateCaps(dec->odm->mo);	/*bytes per sec not available: either video or audio not configured*/	if (!dec->bytes_per_sec) {		if (NewSize && (NewSize != dec->CB->UnitSize) ) gf_cm_resize(dec->CB, NewSize);	} 	/*audio: make sure we have enough data in CM to entirely fill the HW audio buffer...*/	else {		u32 unit_size, audio_buf_len, unit_count;		GF_CodecCapability cap;		unit_size = NewSize;		/*a bit ugly, make some extra provision for speed >1. this is the drawback of working with pre-allocated memory		for composition, we may get into cases where there will never be enough data for high speeds...		FIXME - WE WILL NEED TO MOVE TO DYNAMIC CU BLOCKS IN ORDER TO SUPPORT ANY SPEED, BUT WHAT IS THE IMPACT		FOR LOW RESOURCES DEVICES ??*///		audio_buf_len = 1000;		audio_buf_len = 200;		cap.CapCode = GF_CODEC_BUFFER_MAX;		gf_codec_get_capability(dec, &cap);		unit_count = cap.cap.valueInt;		/*at least 2 units for dec and render ...*/		if (unit_count<2) unit_count = 2;		while (unit_size*unit_count*1000 < dec->bytes_per_sec*audio_buf_len) unit_count++;#ifdef __SYMBIAN32__		/*FIXME - symbian tests*/		unit_count = 10;#endif		gf_cm_reinit(dec->CB, unit_size, unit_count);		dec->CB->Min = unit_count/3;		if (!dec->CB->Min) dec->CB->Min = 1;	}	if ((dec->type==GF_STREAM_VISUAL) && dec->odm->parentscene->is_dynamic_scene) {		gf_is_force_scene_size_video(dec->odm->parentscene, dec->odm->mo);	}	return GF_OK;}static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable){	GF_DBUnit *AU;	GF_Channel *ch;	char *cu_buf;	u32 cu_buf_size, mmlevel;	u32 first, entryTime, now, obj_time;	GF_MediaDecoder *mdec = (GF_MediaDecoder*)codec->decio;	GF_Err e = GF_OK;	/*if video codec muted don't decode (try to saves ressources)	if audio codec muted we dispatch to keep sync in place*/	if (codec->Muted && (codec->type==GF_STREAM_VISUAL) ) return GF_OK;	entryTime = gf_term_get_time(codec->odm->term);	/*fetch next AU in DTS order for this codec*/	Decoder_GetNextAU(codec, &ch, &AU);	/*no active channel return*/	if (!AU || !ch) {		/*if the codec is in EOS state, assume we're done*/		if (codec->Status == GF_ESM_CODEC_EOS) {			/*if codec is reordering, try to flush it*/			if (codec->is_reordering) {				if ( LockCompositionUnit(codec, codec->last_unit_cts+1, &cu_buf, &cu_buf_size) == GF_OUT_OF_MEM) 					return GF_OK;				e = mdec->ProcessData(mdec, NULL, 0, 0, cu_buf, &cu_buf_size, 0, 0);				if (e==GF_OK) e = UnlockCompositionUnit(codec, codec->last_unit_cts+1, cu_buf_size);			}			gf_term_stop_codec(codec);			if (codec->CB) gf_cm_set_eos(codec->CB);		}		/*if no data, and channel not buffering, ABORT CB buffer (data timeout or EOS not detectable)*/		else if (ch && !ch->BufferOn) 			gf_cm_abort_buffering(codec->CB);		return GF_OK;	}	/*get the object time*/	obj_time = gf_clock_time(codec->ck);	/*Media Time for media codecs is updated in the CB*/	if (!codec->CB) {		gf_es_drop_au(ch);		return GF_BAD_PARAM;	}	/*image codecs - usually only one image is tolerated in the stream, but just in case force reset of CB*/	if ((codec->CB->Capacity==1) && codec->CB->UnitCount && (obj_time>=AU->CTS)) {		codec->CB->output->dataLength = 0;		codec->CB->UnitCount = 0;	}	/*try to refill the full buffer*/	first = 1;	while (codec->CB->Capacity > codec->CB->UnitCount) {		/*set media processing level*/		mmlevel = GF_CODEC_LEVEL_NORMAL;		/*SEEK: if the last frame had the same TS, we are seeking. Ask the codec to drop*/		if (!ch->skip_sl && codec->last_unit_cts && (codec->last_unit_cts == AU->CTS) && !ch->esd->dependsOnESID) {			mmlevel = GF_CODEC_LEVEL_SEEK;			/*object clock is paused by media control or terminal is paused: exact frame seek*/			if ((codec->ck->mc && codec->ck->mc->paused) || (codec->odm->term->play_state)) {				gf_cm_rewind_input(codec->CB);				mmlevel = GF_CODEC_LEVEL_NORMAL;				/*force staying in step-mode*/				codec->odm->term->renderer->step_mode=1;			}		}		/*only perform drop in normal playback*/		else if (codec->CB->Status == CB_PLAY) {			/*extremely late, set the level to drop			 NOTE: the 100 ms safety gard is to avoid discarding audio*/			if (!ch->skip_sl && (AU->CTS + 100 < obj_time) ) {				mmlevel = GF_CODEC_LEVEL_DROP;				GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[Decoder] ODM%d: frame too late (%d vs %d) - using drop level\n", codec->odm->OD->objectDescriptorID, AU->CTS, obj_time));			}			/*we are late according to the media manager*/			else if (codec->PriorityBoost) {				mmlevel = GF_CODEC_LEVEL_VERY_LATE;			}			/*otherwise we must have an idea of the load in order to set the right level			use the composition buffer for that, only on the first frame*/			else if (first) {				//if the CB is almost empty set to very late				if (codec->CB->UnitCount <= codec->CB->Min+1) {					mmlevel = GF_CODEC_LEVEL_VERY_LATE;				} else if (codec->CB->UnitCount * 2 <= codec->CB->Capacity) {					mmlevel = GF_CODEC_LEVEL_LATE;				}				first = 0;

⌨️ 快捷键说明

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