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

📄 decoder.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
			}		}		/*when using temporal scalability make sure we can decode*/		if (ch->esd->dependsOnESID && (codec->last_unit_dts > AU->DTS)){//			printf("SCALABLE STREAM DEAD!!\n");			goto drop;		}		if (ch->skip_sl) {			if (codec->bytes_per_sec) {				AU->CTS = codec->last_unit_cts + ch->ts_offset + codec->cur_audio_bytes * 1000 / codec->bytes_per_sec;			} else if (codec->fps) {				AU->CTS = codec->last_unit_cts + ch->ts_offset + (u32) (codec->cur_video_frames * 1000 / codec->fps);			}		}		if ( LockCompositionUnit(codec, AU->CTS, &cu_buf, &cu_buf_size) == GF_OUT_OF_MEM) 			return GF_OK;		now = gf_term_get_time(codec->odm->term);		e = mdec->ProcessData(mdec, AU->data, AU->dataLength, 			ch->esd->ESID, cu_buf, &cu_buf_size, AU->PaddingBits, mmlevel);		now = gf_term_get_time(codec->odm->term) - now;		/*input is too small, resize composition memory*/		switch (e) {		case GF_BUFFER_TOO_SMALL:			/*release but no dispatch*/			UnlockCompositionUnit(codec, AU->CTS, 0);			if (ResizeCompositionBuffer(codec, cu_buf_size)==GF_OK) continue;			break;		case GF_OK:			/*in seek don't dispatch any output*/			if (mmlevel	== GF_CODEC_LEVEL_SEEK) cu_buf_size = 0;			e = UnlockCompositionUnit(codec, AU->CTS, cu_buf_size);			codec_update_stats(codec, AU->dataLength, now);			if (ch->skip_sl) {				if (codec->bytes_per_sec) {					codec->cur_audio_bytes += cu_buf_size;					while (codec->cur_audio_bytes>codec->bytes_per_sec) {						codec->cur_audio_bytes -= codec->bytes_per_sec;						codec->last_unit_cts += 1000;					}				} else if (codec->fps && cu_buf_size) {					codec->cur_video_frames += 1;				}			}			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[Decoder %s] ODM%d: decoded frame TS %d in %d ms\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, AU->CTS, now));			break;		/*this happens a lot when using non-MPEG-4 streams (ex: ffmpeg demuxer)*/		case GF_PACKED_FRAMES:			/*in seek don't dispatch any output*/			if (mmlevel	== GF_CODEC_LEVEL_SEEK) cu_buf_size = 0;			e = UnlockCompositionUnit(codec, AU->CTS, cu_buf_size);			if (ch->skip_sl) {				if (codec->bytes_per_sec) {					codec->cur_audio_bytes += cu_buf_size;				} else if (codec->fps && cu_buf_size) {					codec->cur_video_frames += 1;				}			} else {			  u32 deltaTS = 0;				if (codec->bytes_per_sec) {					deltaTS = cu_buf_size * 1000 / codec->bytes_per_sec;				} else if (codec->fps && cu_buf_size) {					deltaTS = (u32) (1000.0f / codec->fps);				}				//AU->DTS += deltaTS;				AU->CTS += deltaTS;			}			codec_update_stats(codec, 0, now);			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[Decoder] ODM%d: decoded packed frame TS %d in %d ms\n", codec->odm->OD->objectDescriptorID, AU->CTS, now));			continue;		default:			UnlockCompositionUnit(codec, AU->CTS, 0);			/*error - if the object is in intitial buffering resume it!!*/			gf_cm_abort_buffering(codec->CB);			break;		}		codec->last_unit_dts = AU->DTS;		/*remember base layer timing*/		if (!ch->esd->dependsOnESID && !ch->skip_sl) codec->last_unit_cts = AU->CTS;drop:		gf_es_drop_au(ch);		if (e) {			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[Decoder %s] ODM%d: decoded error %s\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, gf_error_to_string(e) ));			return e;		}		/*escape from decoding loop only if above critical limit - this is to avoid starvation on audio*/		if (codec->CB->UnitCount > codec->CB->Min) {			now = gf_term_get_time(codec->odm->term);			if (now - entryTime >= TimeAvailable - TIME_CHECK) {				return GF_OK;			}		}		Decoder_GetNextAU(codec, &ch, &AU);		if (!ch || !AU) return GF_OK;	}	return GF_OK;}GF_Err gf_codec_process(GF_Codec *codec, u32 TimeAvailable){	if (codec->Status == GF_ESM_CODEC_STOP) return GF_OK;	codec->Muted = (codec->odm->media_ctrl && codec->odm->media_ctrl->control->mute) ? 1 : 0;	/*OCR: needed for OCR in pull mode (dummy streams used to sync various sources)*/	if (codec->type==GF_STREAM_OCR) {		GF_DBUnit *AU;		GF_Channel *ch;		/*fetch next AU on OCR (empty AUs)*/		Decoder_GetNextAU(codec, &ch, &AU);		/*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_term_stop_codec(codec);				/*if a mediacontrol is ruling this OCR*/				if (codec->odm->media_ctrl && codec->odm->media_ctrl->control->loop) MC_Restart(codec->odm); 			}		}	}	/*special case here (we tweak a bit the timing)*/	else if (codec->type==GF_STREAM_PRIVATE_SCENE) {		return PrivateScene_Process(codec, TimeAvailable);	} else if (codec->decio->InterfaceType==GF_MEDIA_DECODER_INTERFACE) {		return MediaCodec_Process(codec, TimeAvailable);	} else if (codec->decio->InterfaceType==GF_SCENE_DECODER_INTERFACE) {		return SystemCodec_Process(codec, TimeAvailable);	}	return GF_OK;}GF_Err gf_codec_get_capability(GF_Codec *codec, GF_CodecCapability *cap){	cap->cap.valueInt = 0;	if (!codec->decio) return GF_OK;	return codec->decio->GetCapabilities(codec->decio, cap);}GF_Err gf_codec_set_capability(GF_Codec *codec, GF_CodecCapability cap){	if (!codec->decio) return GF_OK;	return codec->decio->SetCapabilities(codec->decio, cap);}void gf_codec_set_status(GF_Codec *codec, u32 Status){	if (!codec) return;	if (Status == GF_ESM_CODEC_PAUSE) codec->Status = GF_ESM_CODEC_STOP;	else if (Status == GF_ESM_CODEC_BUFFER) codec->Status = GF_ESM_CODEC_PLAY;	else if (Status == GF_ESM_CODEC_PLAY) {		codec->last_unit_cts = 0;		codec->prev_au_size = 0;		codec->Status = Status;		codec->last_stat_start = codec->cur_bit_size = codec->max_bit_rate = codec->avg_bit_rate = 0;		codec->nb_dec_frames = codec->total_dec_time = codec->max_dec_time = 0;		codec->cur_audio_bytes = codec->cur_video_frames = 0;		codec->nb_droped = 0;	}	else codec->Status = Status;	if (!codec->CB) return;		/*notify CB*/	switch (Status) {	case GF_ESM_CODEC_PLAY:		gf_cm_set_status(codec->CB, CB_PLAY);		return;	case GF_ESM_CODEC_PAUSE:		gf_cm_set_status(codec->CB, CB_PAUSE);		return;	case GF_ESM_CODEC_STOP:		gf_cm_set_status(codec->CB, CB_STOP);		return;	case GF_ESM_CODEC_EOS:		/*do NOT notify CB yet, wait till last AU is decoded*/		return;	case GF_ESM_CODEC_BUFFER:	default:		return;	}}static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL){	char szPrefDec[500];	const char *sOpt;	GF_BaseDecoder *ifce;	u32 i, plugCount;	u32 ifce_type;	char *cfg;	u32 cfg_size;	GF_Terminal *term = codec->odm->term;	if (esd->decoderConfig->decoderSpecificInfo) {		cfg = esd->decoderConfig->decoderSpecificInfo->data;		cfg_size = esd->decoderConfig->decoderSpecificInfo->dataLength;	} else {		cfg = NULL;		cfg_size = 0;	}	ifce_type = GF_SCENE_DECODER_INTERFACE;	if ((esd->decoderConfig->streamType==GF_STREAM_AUDIO) 		|| (esd->decoderConfig->streamType==GF_STREAM_VISUAL)		|| (esd->decoderConfig->streamType==GF_STREAM_ND_SUBPIC)		)		ifce_type = GF_MEDIA_DECODER_INTERFACE;	/*a bit dirty, if FFMPEG is used for demuxer load it for decoder too*/	if (0 && !stricmp(codec->odm->net_service->ifce->module_name, "FFMPEG demuxer")) {		sOpt = "FFMPEG decoder";	} else {		/*use user-defined module if any*/		sOpt = NULL;		switch (esd->decoderConfig->streamType) {		case GF_STREAM_VISUAL:			if ((esd->decoderConfig->objectTypeIndication==0x6C) || (esd->decoderConfig->objectTypeIndication==0x6D)) 				sOpt = gf_cfg_get_key(term->user->config, "Systems", "DefImageDec");			else				sOpt = gf_cfg_get_key(term->user->config, "Systems", "DefVideoDec");			break;		case GF_STREAM_AUDIO:			sOpt = gf_cfg_get_key(term->user->config, "Systems", "DefAudioDec");			break;		default:			break;		}	}		if (sOpt) {		ifce = (GF_BaseDecoder *) gf_modules_load_interface_by_name(term->user->modules, sOpt, ifce_type);		if (ifce) {			if (ifce->CanHandleStream && ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication, cfg, cfg_size, PL) ) {				codec->decio = ifce;				return GF_OK;			}			gf_modules_close_interface((GF_BaseInterface *) ifce);				}	}	/*prefered codec module per streamType/objectType from config*/	sprintf(szPrefDec, "codec_%02x_%02x", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication);	sOpt = gf_cfg_get_key(term->user->config, "Systems", szPrefDec);	if (sOpt) {		ifce = (GF_BaseDecoder *) gf_modules_load_interface_by_name(term->user->modules, sOpt, ifce_type);		if (ifce) {			if (ifce->CanHandleStream && ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication, cfg, cfg_size, PL) ) {				codec->decio = ifce;				return GF_OK;			}			gf_modules_close_interface((GF_BaseInterface *) ifce);				}	}	/*not found, check all modules*/	plugCount = gf_modules_get_count(term->user->modules);	for (i = 0; i < plugCount ; i++) {		ifce = (GF_BaseDecoder *) gf_modules_load_interface(term->user->modules, i, ifce_type);		if (!ifce) continue;		if (ifce->CanHandleStream && ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication, cfg, cfg_size, PL) ) {			codec->decio = ifce;			return GF_OK;		}		gf_modules_close_interface((GF_BaseInterface *) ifce);	}	return GF_CODEC_NOT_FOUND;}GF_Err Codec_Load(GF_Codec *codec, GF_ESD *esd, u32 PL){	switch (esd->decoderConfig->streamType) {	/*OCR has no codec, just a channel*/	case GF_STREAM_OCR:		codec->decio = NULL;		return GF_OK;	/*InteractionStream is currently hardcoded*/	case GF_STREAM_INTERACT:		codec->decio = (GF_BaseDecoder *) NewISCodec(PL);		assert(codec->decio->InterfaceType == GF_SCENE_DECODER_INTERFACE);		return GF_OK;	/*load decoder module*/	default:		return Codec_LoadModule(codec, esd, PL);	}}void gf_codec_del(GF_Codec *codec){	if (gf_list_count(codec->inChannels)) return;	if (!(codec->flags & GF_ESM_CODEC_IS_USE)) {		switch (codec->type) {		/*input sensor streams are handled internally for now*/		case GF_STREAM_INTERACT:			gf_mx_p(codec->odm->term->net_mx);			ISDec_Delete(codec->decio);			gf_list_del_item(codec->odm->term->input_streams, codec);			gf_mx_v(codec->odm->term->net_mx);			break;		default:			gf_modules_close_interface((GF_BaseInterface *) codec->decio);			break;		}	}	if (codec->CB) gf_cm_del(codec->CB);	gf_list_del(codec->inChannels);	free(codec);}

⌨️ 快捷键说明

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