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

📄 rtp_pck_mpeg4.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
		gf_rtp_build_au_hdr_write(builder, pckSize, builder->rtp_header.TimeStamp);				//notify the user of our data structure		if (builder->OnDataReference) 			builder->OnDataReference(builder->cbk_obj, pckSize, data_size - bytesLeftInPacket);		else			gf_bs_write_data(builder->payload, data + (data_size - bytesLeftInPacket), pckSize);		bytesLeftInPacket -= pckSize;		builder->bytesInPacket += pckSize;		/*update IV*/		builder->IV += pckSize;		builder->sl_header.paddingFlag = 0;		builder->sl_header.accessUnitStartFlag = 0;		//we are splitting a payload, auto increment SL seq num		if (bytesLeftInPacket) {			builder->sl_header.packetSequenceNumber += 1;		} else if (! (builder->flags & GP_RTP_PCK_USE_MULTI) ) {			builder->rtp_header.Marker = 1;			flush_pck = 1;		}		//first SL in RTP is done		builder->first_sl_in_rtp = 0;		//store current sl		builder->last_au_sn = builder->sl_header.AU_sequenceNumber;		if (!flush_pck) continue;		//done with the packetflush_packet:		gf_bs_align(builder->pck_hdr);		/*no aux data yet*/		if (builder->slMap.AuxiliaryDataSizeLength)	{			//write RSLH after the MSLH			gf_bs_write_int(builder->pck_hdr, 0, builder->slMap.AuxiliaryDataSizeLength);					}						/*rewrite the size header*/		if (builder->has_AU_header) {			pos = (u32) gf_bs_get_position(builder->pck_hdr);					gf_bs_seek(builder->pck_hdr, 0);			builder->auh_size -= 16;			gf_bs_write_int(builder->pck_hdr, builder->auh_size, 16);			gf_bs_seek(builder->pck_hdr, pos);		}		sl_buffer = NULL;		gf_bs_get_content(builder->pck_hdr, &sl_buffer, &sl_buffer_size);		//delete our bitstream		gf_bs_del(builder->pck_hdr);		builder->pck_hdr = NULL;		payl_buffer = NULL;		payl_buffer_size = 0;		if (!builder->OnDataReference) 			gf_bs_get_content(builder->payload, &payl_buffer, &payl_buffer_size);		gf_bs_del(builder->payload);		builder->payload = NULL;		/*notify header*/		builder->OnData(builder->cbk_obj, sl_buffer, sl_buffer_size, 1);		/*notify payload*/		if (payl_buffer) {			builder->OnData(builder->cbk_obj, payl_buffer, payl_buffer_size, 0);			free(payl_buffer);		}		/*flush packet*/		builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);		free(sl_buffer);	}	//packet is done, update AU markers	if (IsAUEnd) {		builder->sl_header.accessUnitStartFlag = 1;		builder->sl_header.accessUnitEndFlag = 0;	}	return GF_OK;}GF_Err gp_rtp_builder_do_avc(GP_RTPPacketizer *builder, char *nalu, u32 nalu_size, u8 IsAUEnd, u32 FullAUSize){	u32 do_flush, bytesLeft, size, nal_type;	char shdr[2];	char stap_hdr;	do_flush = 0;	if (!nalu) do_flush = 1;	/*we only do STAP or SINGLE modes*/	else if (builder->sl_header.accessUnitStartFlag) do_flush = 1;	/*we must NOT fragment a NALU*/	else if (builder->bytesInPacket + nalu_size >= builder->Path_MTU) do_flush = 2;	if (builder->bytesInPacket && do_flush) {		builder->rtp_header.Marker = (do_flush==1) ? 1 : 0;		builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);		builder->bytesInPacket = 0;	}	if (!nalu) return GF_OK;	/*need a new RTP packet*/	if (!builder->bytesInPacket) {		builder->rtp_header.PayloadType = builder->PayloadType;		builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp;		builder->rtp_header.SequenceNumber += 1;		builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);		builder->avc_non_idr = 1;	}	/*check NAL type to see if disposable or not*/	nal_type = nalu[0] & 0x1F;	switch (nal_type) {	case GF_AVC_NALU_NON_IDR_SLICE:	case GF_AVC_NALU_ACCESS_UNIT:	case GF_AVC_NALU_END_OF_SEQ:	case GF_AVC_NALU_END_OF_STREAM:	case GF_AVC_NALU_FILLER_DATA:		break;	default:		builder->avc_non_idr = 0;		break;	}	/*at this point we're sure the NALU fits in current packet OR must be splitted*/	/*pb: we don't know if next NALU from this AU will be small enough to fit in the packet, so we always	go for stap...*/	if (builder->bytesInPacket+nalu_size<builder->Path_MTU) {		Bool use_stap = 1;		/*if this is the AU end and no NALU in packet, go for single mode*/		if (IsAUEnd && !builder->bytesInPacket) use_stap = 0;				if (use_stap) {			/*declare STAP-A NAL*/			if (!builder->bytesInPacket) {				/*copy over F and NRI from first nal in packet and assign type*/				stap_hdr = (nalu[0] & 0xE0) | 24;				builder->OnData(builder->cbk_obj, (char *) &stap_hdr, 1, 0);				builder->bytesInPacket = 1;			}			/*add NALU size*/			shdr[0] = nalu_size>>8;			shdr[1] = nalu_size&0x00ff;			builder->OnData(builder->cbk_obj, (char *)shdr, 2, 0);			builder->bytesInPacket += 2;		}		/*add data*/		if (builder->OnDataReference) 			builder->OnDataReference(builder->cbk_obj, nalu_size, 0);		else			builder->OnData(builder->cbk_obj, nalu, nalu_size, 0);		builder->bytesInPacket += nalu_size;		if (IsAUEnd) {			builder->rtp_header.Marker = 1;			builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);			builder->bytesInPacket = 0;		}	}	/*fragmentation unit*/	else {		u32 offset;		assert(nalu_size>=builder->Path_MTU);		assert(!builder->bytesInPacket);		/*FU payload doesn't have the NAL hdr*/		bytesLeft = nalu_size - 1;		offset = 1;		while (bytesLeft) {			if (2 + bytesLeft > builder->Path_MTU) {				size = builder->Path_MTU - 2;			} else {				size = bytesLeft;			}			/*copy over F and NRI from nal in packet and assign type*/			shdr[0] = (nalu[0] & 0xE0) | 28;			/*copy over NAL type from nal and set start bit and end bit*/			shdr[1] = (nalu[0] & 0x1F);			/*start bit*/			if (offset==1) shdr[1] |= 0x80;			/*end bit*/			else if (size == bytesLeft) shdr[1] |= 0x40;			builder->OnData(builder->cbk_obj, (char *)shdr, 2, 0);			/*add data*/			if (builder->OnDataReference) 				builder->OnDataReference(builder->cbk_obj, size, offset);			else				builder->OnData(builder->cbk_obj, nalu+offset, size, 0);			offset += size;			bytesLeft -= size;			/*flush no matter what (FUs cannot be agreggated)*/			builder->rtp_header.Marker = bytesLeft ? 0 : 1;			builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);			builder->bytesInPacket = 0;			if (bytesLeft) {				builder->rtp_header.PayloadType = builder->PayloadType;				builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp;				builder->rtp_header.SequenceNumber += 1;				builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);			}		}	}	return GF_OK;}void latm_flush(GP_RTPPacketizer *builder){	if (builder->bytesInPacket) {		builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); 		builder->bytesInPacket = 0;	}	builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp; }GF_Err gp_rtp_builder_do_latm(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration) {	u32 size, latm_hdr_size, i, data_offset; 	Bool fragmented; 	unsigned char *latm_hdr; 	if (!data) {		latm_flush(builder);		return GF_OK; 	}		if ((builder->flags & GP_RTP_PCK_USE_MULTI) && builder->max_ptime) {		if ((u32) builder->sl_header.compositionTimeStamp + duration >= builder->rtp_header.TimeStamp + builder->max_ptime) 			latm_flush(builder);	}	/*compute max size for frame, flush current if this doesn't fit*/	latm_hdr_size = (data_size / 255) + 1; 	if (latm_hdr_size+data_size > builder->Path_MTU - builder->bytesInPacket) {		latm_flush(builder);	}	data_offset = 0;	fragmented = 0;	while (data_size > 0) { 		latm_hdr_size = (data_size / 255) + 1; 		/*fragmenting*/		if (latm_hdr_size + data_size > builder->Path_MTU) {			assert(!builder->bytesInPacket);			fragmented = 1;			latm_hdr_size = (builder->Path_MTU / 255) + 1; 			size = builder->Path_MTU - latm_hdr_size; 			builder->rtp_header.Marker = 0; 		}		/*last fragment or full AU*/		else { 			fragmented = 0;			size = data_size; 			builder->rtp_header.Marker = 1; 		} 		data_size -= size; 				/*create new RTP Packet if needed*/ 		if (!builder->bytesInPacket) {			builder->rtp_header.SequenceNumber += 1; 			builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp; 			builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header); 		}			/* compute AudioMuxUnit header */ 		latm_hdr_size = (size / 255) + 1; 		latm_hdr = (unsigned char *)malloc( sizeof(char) * latm_hdr_size); 		for (i=0; i<latm_hdr_size-1; i++)  latm_hdr[i] = 255; 		latm_hdr[latm_hdr_size-1] = size % 255; 				/*add LATM header IN ORDER in case we aggregate audioMuxElements in RTP*/ 		builder->OnData(builder->cbk_obj, (char*) latm_hdr, latm_hdr_size, 0);		builder->bytesInPacket += latm_hdr_size;		free(latm_hdr);				/*add payload*/ 		if (builder->OnDataReference) {			builder->OnDataReference(builder->cbk_obj, size, data_offset); 		} else 			builder->OnData(builder->cbk_obj, data, size, 0); 		builder->bytesInPacket += size;		data_offset += size;		/*fragmented AU, always flush packet*/		if (!builder->rtp_header.Marker) latm_flush(builder);	} 	/*if the AU has been fragmented or we don't use RTP aggregation, flush*/	if (! (builder->flags & GP_RTP_PCK_USE_MULTI) ) fragmented = 1;	if (fragmented) latm_flush(builder);		return GF_OK; }

⌨️ 快捷键说明

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