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

📄 channel.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (hdr.randomAccessPointFlag) ch->IsRap = 1;	/*check OCR*/	if (hdr.OCRflag) {		s64 OCR_TS = (s64) (((s64) hdr.objectClockReference) * ch->ocr_scale);		gf_clock_set_time(ch->clock, (u32) OCR_TS);		ch->IsClockInit = 1;	}	/*get AU end state*/		OldLength = ch->buffer ? ch->len : 0;	EndAU = hdr.accessUnitEndFlag;	if (ch->AULength == OldLength + StreamLength) EndAU = 1;	if (EndAU) ch->NextIsAUStart = 1;	if (!StreamLength && EndAU && ch->buffer) {		GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: Empty packet, flushing buffer\n", ch->esd->ESID));		Channel_DispatchAU(ch, 0);		return;	}	if (!StreamLength) return;	/*missed begining, unusable*/	if (!ch->buffer && !NewAU) {		if (ch->esd->slConfig->useAccessUnitStartFlag) {			GF_LOG(GF_LOG_ERROR, GF_LOG_SYNC, ("[SyncLayer] ES%d: missed begin of AU\n", ch->esd->ESID));		}		return;	}	/*Write the Packet payload to the buffer*/	if (NewAU) {		/*we should NEVER have a bitstream at this stage*/		assert(!ch->buffer);		/*ignore length fields*/		size = StreamLength + ch->media_padding_bytes;		ch->buffer = (char*)malloc(sizeof(char) * size);		if (!ch->buffer) {			assert(0);			return;		}		ch->allocSize = size;		memset(ch->buffer, 0, sizeof(char) * size);		ch->len = 0;	}	if (!ch->esd->slConfig->usePaddingFlag) hdr.paddingFlag = 0;	/*if no bitstream, we missed the AU Start packet. Unusable ...*/	if (!ch->buffer) {		GF_LOG(GF_LOG_ERROR, GF_LOG_SYNC, ("[SyncLayer] ES%d: Empty buffer - missed begining of AU\n", ch->esd->ESID));		return;	}		if (ch->ipmp_tool) {		GF_IPMPEvent evt;		memset(&evt, 0, sizeof(evt));		evt.event_type=GF_IPMP_TOOL_PROCESS_DATA;		evt.channel = ch;		evt.data = payload;		evt.data_size = StreamLength;		evt.is_encrypted = hdr.isma_encrypted;		evt.isma_BSO = hdr.isma_BSO;		ch->ipmp_tool->process(ch->ipmp_tool, &evt);	}	if (hdr.paddingFlag && !EndAU) {			/*to do - this shouldn't happen anyway */	} else {		/*check if enough space*/		size = ch->allocSize;		if (size && (StreamLength + ch->len <= size)) {			memcpy(ch->buffer+ch->len, payload, StreamLength);			ch->len += StreamLength;		} else {			size = StreamLength + ch->len + ch->media_padding_bytes;			ch->buffer = (char*)realloc(ch->buffer, sizeof(char) * size);			memcpy(ch->buffer+ch->len, payload, StreamLength);			ch->allocSize = size;			ch->len += StreamLength;		}		if (hdr.paddingFlag) ch->padingBits = hdr.paddingBits;	}	if (EndAU) Channel_DispatchAU(ch, hdr.au_duration);}/*notification of End of stream on this channel*/void gf_es_on_eos(GF_Channel *ch){	if (!ch || ch->IsEndOfStream) return;	ch->IsEndOfStream = 1;		/*flush buffer*/	ch_buffer_off(ch);	ch->clock->has_seen_eos = 1;	gf_odm_on_eos(ch->odm, ch);}GF_DBUnit *gf_es_get_au(GF_Channel *ch){	Bool comp, is_new_data;	GF_Err e, state;	GF_SLHeader slh;	if (ch->es_state != GF_ESM_ES_RUNNING) return NULL;	if (!ch->is_pulling) {		/*we must update buffering before fetching in order to stop buffering for streams with very few		updates (especially streams with one update, like most of OD streams)*/		if (ch->BufferOn) Channel_UpdateBuffering(ch, 0);		if (ch->first_au_fetched && ch->BufferOn) return NULL;		return ch->AU_buffer_first;	}	/*pull from stream - resume clock if needed*/	ch_buffer_off(ch);	e = gf_term_channel_get_sl_packet(ch->service, ch, (char **) &ch->AU_buffer_pull->data, &ch->AU_buffer_pull->dataLength, &slh, &comp, &state, &is_new_data);	if (e) state = e;	switch (state) {	case GF_EOS:		gf_es_on_eos(ch);		return NULL;	case GF_OK:		break;	default:		gf_term_message(ch->odm->term, ch->service->url , "Data reception failure", state);		return NULL;	}	assert(!comp);	/*update timing if new stream data but send no data*/	if (is_new_data) {		gf_es_receive_sl_packet(ch->service, ch, NULL, 0, &slh, GF_OK);		if (ch->ipmp_tool) {			GF_IPMPEvent evt;			memset(&evt, 0, sizeof(evt));			evt.event_type=GF_IPMP_TOOL_PROCESS_DATA;			evt.data = ch->AU_buffer_pull->data;			evt.data_size = ch->AU_buffer_pull->dataLength;			evt.is_encrypted = slh.isma_encrypted;			evt.isma_BSO = slh.isma_BSO;			evt.channel = ch;			e = ch->ipmp_tool->process(ch->ipmp_tool, &evt);			if (e && 0) {				gf_term_channel_release_sl_packet(ch->service, ch);				return NULL;			}		}	}	/*this may happen in file streaming when data has not arrived yet, in which case we discard the AU*/	if (!ch->AU_buffer_pull->data) {		gf_term_channel_release_sl_packet(ch->service, ch);		return NULL;	}	ch->AU_buffer_pull->CTS = (u32) ch->CTS;	ch->AU_buffer_pull->DTS = (u32) ch->DTS;	ch->AU_buffer_pull->PaddingBits = ch->padingBits;	ch->AU_buffer_pull->RAP = ch->IsRap;	return ch->AU_buffer_pull;}void gf_es_init_dummy(GF_Channel *ch){	GF_SLHeader slh;	Bool comp, is_new_data;	GF_Err e, state;	if (!ch->is_pulling) return;	/*pull from stream - resume clock if needed*/	ch_buffer_off(ch);	e = gf_term_channel_get_sl_packet(ch->service, ch, (char **) &ch->AU_buffer_pull->data, &ch->AU_buffer_pull->dataLength, &slh, &comp, &state, &is_new_data);	if (e) state = e;	if ((state==GF_OK) && is_new_data) gf_es_receive_sl_packet(ch->service, ch, NULL, 0, &slh, GF_OK);	gf_term_channel_release_sl_packet(ch->service, ch);}void gf_es_drop_au(GF_Channel *ch){	GF_DBUnit *au;	if (ch->is_pulling) {		assert(ch->AU_buffer_pull);		gf_term_channel_release_sl_packet(ch->service, ch);		ch->AU_buffer_pull->data = NULL;		ch->AU_buffer_pull->dataLength = 0;		ch->first_au_fetched = 1;		return;	}	if (!ch->AU_buffer_first) return;	/*lock the channel before touching the queue*/	gf_es_lock(ch, 1);	ch->first_au_fetched = 1;	au = ch->AU_buffer_first;	ch->AU_buffer_first = au->next;	au->next = NULL;	gf_db_unit_del(au);	ch->AU_Count -= 1;	if (!ch->AU_Count && ch->AU_buffer_first) {		ch->AU_buffer_first = NULL;	}	if (!ch->AU_buffer_first) ch->AU_buffer_last = NULL;	Channel_UpdateBufferTime(ch);	/*if we get under our limit, rebuffer EXCEPT WHEN EOS is signaled*/	if (!ch->IsEndOfStream && Channel_NeedsBuffering(ch, 1)) {		ch_buffer_on(ch);	}	/*unlock the channel*/	gf_es_lock(ch, 0);}/*(un)locks channel*/void gf_es_lock(GF_Channel *ch, u32 LockIt){	if (LockIt) {		gf_mx_p(ch->mx);	} else {		gf_mx_v(ch->mx);	}}/*performs final setup upon connection confirm*/void gf_es_on_connect(GF_Channel *ch){	Bool can_buffer;	GF_NetworkCommand com;	/*check whether we can work in pull mode or not*/	can_buffer = 1;	/*if local interaction streams no buffer nor pull*/	if ((ch->esd->decoderConfig->streamType == GF_STREAM_INTERACT) && !ch->esd->URLString) can_buffer = 0;	com.base.on_channel = ch;	ch->is_pulling = 0;	if (can_buffer) {		/*request padding*/		com.command_type = GF_NET_CHAN_SET_PADDING;		com.pad.padding_bytes = ch->media_padding_bytes;		if (!com.pad.padding_bytes || (gf_term_service_command(ch->service, &com) == GF_OK)) {			/*request pull if possible*/			if (ch->service->ifce->ChannelGetSLP && ch->service->ifce->ChannelReleaseSLP) {				com.command_type = GF_NET_CHAN_SET_PULL;				if (gf_term_service_command(ch->service, &com) == GF_OK) {					ch->is_pulling = 1;					can_buffer = 0;				}			}		}	}	/*checks whether the stream is interactive or not*/	com.command_type = GF_NET_CHAN_INTERACTIVE;	if (gf_term_service_command(ch->service, &com)!=GF_OK) {		ch->clock->no_time_ctrl = 1;		ch->odm->flags |= GF_ODM_NO_TIME_CTRL;		gf_odm_refresh_uninteractives(ch->odm);	}	/*signal channel state*/	if (ch->es_state == GF_ESM_ES_WAIT_FOR_ACK) 		ch->es_state = GF_ESM_ES_CONNECTED;	/*signal only once connected to prevent PLAY trigger on connection callback*/	ch->odm->pending_channels--;	/*remember channels connected on service*/	if (ch->esd->URLString) ch->service->nb_ch_users++;	/*buffer setup*/	ch->MinBuffer = ch->MaxBuffer = 0;	if (can_buffer) {		const char *sOpt;		com.command_type = GF_NET_CHAN_BUFFER;		com.base.on_channel = ch;		/*set default values*/		com.buffer.max = 1000;		sOpt = gf_cfg_get_key(ch->odm->term->user->config, "Network", "BufferLength");		if (sOpt) com.buffer.max = atoi(sOpt);		com.buffer.min = 0;		sOpt = gf_cfg_get_key(ch->odm->term->user->config, "Network", "RebufferLength");		if (sOpt) com.buffer.min = atoi(sOpt);		if (gf_term_service_command(ch->service, &com) == GF_OK) {			ch->MinBuffer = com.buffer.min;			ch->MaxBuffer = com.buffer.max;		}	}	/*get duration*/	com.command_type = GF_NET_CHAN_DURATION;	com.base.on_channel = ch;	if (gf_term_service_command(ch->service, &com) == GF_OK)		gf_odm_set_duration(ch->odm, ch, (u64) (1000*com.duration.duration));}void gf_es_config_drm(GF_Channel *ch, GF_NetComDRMConfig *drm_cfg){	GF_Terminal *term = ch->odm->term;	u32 i, count;	GF_Err e;	GF_IPMPEvent evt;	GF_OMADRM2Config cfg;	GF_OMADRM2Config isma_cfg;	/*always buffer when fetching keys*/	ch_buffer_on(ch);	ch->is_protected = 1;	memset(&evt, 0, sizeof(GF_IPMPEvent));	evt.event_type = GF_IPMP_TOOL_SETUP;	evt.channel = ch;	/*push all cfg data*/	if (drm_cfg->contentID) {		evt.config_data_code = GF_4CC('o','d','r','m');		memset(&cfg, 0, sizeof(cfg));		cfg.scheme_version = drm_cfg->scheme_version;		cfg.scheme_type = drm_cfg->scheme_type;		cfg.scheme_uri = drm_cfg->scheme_uri;		cfg.kms_uri = drm_cfg->kms_uri;		memcpy(cfg.hash, drm_cfg->hash, sizeof(char)*20);		cfg.contentID = drm_cfg->contentID;		cfg.oma_drm_crypt_type = drm_cfg->oma_drm_crypt_type;		cfg.oma_drm_use_pad = drm_cfg->oma_drm_use_pad;		cfg.oma_drm_use_hdr = drm_cfg->oma_drm_use_hdr;		cfg.oma_drm_textual_headers = drm_cfg->oma_drm_textual_headers;		cfg.oma_drm_textual_headers_len = drm_cfg->oma_drm_textual_headers_len;		evt.config_data = &cfg;	} else {		evt.config_data_code = GF_4CC('i','s','m','a');		memset(&isma_cfg, 0, sizeof(isma_cfg));		isma_cfg.scheme_version = drm_cfg->scheme_version;		isma_cfg.scheme_type = drm_cfg->scheme_type;		isma_cfg.scheme_uri = drm_cfg->scheme_uri;		isma_cfg.kms_uri = drm_cfg->kms_uri;		evt.config_data = &isma_cfg;			}	if (ch->ipmp_tool) {		e = ch->ipmp_tool->process(ch->ipmp_tool, &evt);		if (e) gf_term_message(ch->odm->term, ch->service->url, "Error setting up DRM tool", e);		ch_buffer_off(ch);		return;	}	/*browse all available tools*/	count = gf_modules_get_count(term->user->modules);	for (i=0; i< count; i++) {		ch->ipmp_tool = (GF_IPMPTool *) gf_modules_load_interface(term->user->modules, i, GF_IPMP_TOOL_INTERFACE);		if (!ch->ipmp_tool) continue;		GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[IPMP] Checking if IPMP tool %s can handle channel protection scheme\n", ch->ipmp_tool->module_name));		e = ch->ipmp_tool->process(ch->ipmp_tool, &evt);		if (e==GF_OK) {			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[IPMP] Associating IPMP tool %s to channel %d\n", ch->ipmp_tool->module_name, ch->esd->ESID));			ch_buffer_off(ch);			return;		}		gf_modules_close_interface((GF_BaseInterface *) ch->ipmp_tool);		ch->ipmp_tool = NULL;	}	gf_term_message(ch->odm->term, ch->service->url, "No IPMP tool suitable to handle channel protection", GF_NOT_SUPPORTED);	ch_buffer_off(ch);}

⌨️ 快捷键说明

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