metartc5_jz源码阅读-yang_ipc_rtcrecv_start_thread

发布时间:2024年01月01日
void* yang_ipc_rtcrecv_start_thread(void *obj) {
	//从形参拿到RtcSession
	YangIpcRtcSession* session=(YangIpcRtcSession*)obj;

	session->isConvert = 1;

	//重置流捕获变量,创建流捕获变量。
	YangStreamCapture data;
	memset(&data,0,sizeof(YangStreamCapture));
	yang_create_streamCapture(&data);

	//重置音频帧和视频帧,初始化音频帧和视频帧
	YangFrame audioFrame;
	YangFrame videoFrame;
	memset(&audioFrame,0,sizeof(YangFrame));
	memset(&videoFrame,0,sizeof(YangFrame));
	data.initAudio(data.context,session->avinfo->sys.transType,session->avinfo->audio.sample, session->avinfo->audio.channel,
			(YangAudioCodec) session->avinfo->audio.audioEncoderType);
	data.initVideo(data.context,session->avinfo->sys.transType);

	//获取视频编码类型
	YangVideoCodec videoType =	(YangVideoCodec) session->avinfo->video.videoEncoderType;

	int32_t ret = Yang_Ok;

	//初始化Meta变量
	session->avinfo->enc.createMeta=0;
	YangVideoMeta* vmd=NULL;
	if(session->avinfo->enc.createMeta==0){
		vmd=(YangVideoMeta*)calloc(sizeof( YangVideoMeta),1);
	}

	//初始化nalu
	YangH264NaluData nalu;

	while (session->isConvert == 1) {
		//如果当前没有任何已经加入的PeerConnection对象,则usleep 2毫秒后再次判断。
		if (session->pushs.vec.vsize == 0) {
			yang_usleep(2000);
			continue;
		}

		//如果removeList中的size大于0,则移除流。
		if(session->removeList.vsize>0){
			pthread_mutex_lock(&session->mutex);
			yang_ipc_rtcrecv_removeStream(session);
			pthread_mutex_unlock(&session->mutex);
			continue;
		}

		//如果videoBuffer中没有数据,则usleep 2毫秒后再次判断。
		if ((session->in_videoBuffer && session->in_videoBuffer->size(&session->in_videoBuffer->mediaBuffer) == 0)) {
				yang_usleep(2000);
				continue;
			}

		//如果videoBuffer中有数据,则继续执行if内的代码。
		if (session->in_videoBuffer && session->in_videoBuffer->size(&session->in_videoBuffer->mediaBuffer) > 0) {

			//从mediaBuffer中读取一帧视频并将读取的size大小放入payload中。
			videoFrame.payload = session->in_videoBuffer->getEVideoRef(&session->in_videoBuffer->mediaBuffer,&videoFrame);

			//如果帧类型是I帧
			if (videoFrame.frametype == YANG_Frametype_I) {

				if (!vmd->isInit) {
					//根据视频编码类型创建不同的Meta数据。
					if (videoType == Yang_VED_264) {
						yang_createH264Meta(vmd, &videoFrame);
						yang_getConfig_Flv_H264(&vmd->mp4Meta,vmd->livingMeta.buffer,&vmd->livingMeta.bufLen);
					} else if (videoType == Yang_VED_265) {
						yang_createH265Meta(vmd, &videoFrame);
						yang_getConfig_Flv_H265(&vmd->mp4Meta,vmd->livingMeta.buffer,&vmd->livingMeta.bufLen);
					}

					data.setVideoMeta(data.context,vmd->livingMeta.buffer,vmd->livingMeta.bufLen, videoType);
				}
				//设置视频帧类型为Spspps
				data.setVideoFrametype(data.context,YANG_Frametype_Spspps);

				//设置Meta的时间戳为视频帧的显示时间戳。
				data.setMetaTimestamp(data.context,videoFrame.pts);

				//将视频帧数据publish到p2p客户端
				ret = yang_ipc_rtcrecv_publishVideoData(session,&data);

				if (!session->avinfo->enc.createMeta) {
					//重置NaluData,并从videoFrame中拿到nalu数据放到nalu中。
					memset(&nalu, 0, sizeof(YangH264NaluData));
					yang_parseH264Nalu(&videoFrame, &nalu);

					//如果nalu中找到了关键帧的位置,则payload中将关键帧的size加进去,并从nb中将其减去。
					if (nalu.keyframePos > -1) {
						videoFrame.payload += nalu.keyframePos + 4;
						videoFrame.nb -= (nalu.keyframePos + 4);

					} else {
						videoFrame.payload = NULL;
						continue;
					}
				}
			}

			//从videoFrame中读取视频数据放入context中。
			data.setVideoData(data.context,&videoFrame, videoType);

			//将视频帧数据publish到p2p客户端
			if((ret = yang_ipc_rtcrecv_publishVideoData(session,&data))!=Yang_Ok){

			}

		}			//end
	}

	//当isConvert为0时将退出while循环,关闭流捕获。
	yang_destroy_streamCapture(&data);
	yang_free(vmd);
	return NULL;
}

文章来源:https://blog.csdn.net/fsmpeg/article/details/135320621
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。