朱老师,3518e系列,第六季

news2025/5/20 4:46:26

第一节:概述。

首先是 将 他写好的 rtsp 源码上传,用于分析。

已经拷贝完。

第二节: h264 编码概念。

编解码 可以用cpu, 也可以用 bsp

cpu 编解码的效果不好。做控制比较好。

h264  由  VCL, NAL 组成。

NAL 关心的是 压缩的 视频 如何传输。

宏块: MB, 多个像素组成的一块, 因为一幅图片的 一篇区域 颜色是一样的。

片: slice  , 比MB 大的概念,具体是什么 ,不清楚呀。

帧: frame

I帧:  非参考帧。

P帧: 参考前面的帧,  它记录的不是 像素,而是 与前面的帧的区别。

B帧: 及参考前面的,又参考后面的。

像素--->宏块---->片----->帧---->序列--->码流。

第三节+ 第四节+第五节+ 第六节, NAL 详解。

VCL是原厂的事情, 我们只关心 NAL。

NAL 是关于网络传输的封包。

SODB: string of data bits , 这就是纯视频流, 可以播放,但是不能传输。

RBSP:  raw byte sequence payload ,

NALU : network abstraction layer units

也就是说 NAL, 只是一个头,  SODB 就是 新鲜的刚刚压缩完的数据, RBSP trailing bits 不知道是什么,  也就是说说  NALU 加上了 纯数据。

RBSP trailing bits 不知道是什么意思。

海思的 h264的 码流是由 若干个sequence 组成的。

这就是一个 sequenece

一个 sequence 的组成是。

lsps + lpps + lsei +1个I帧 + 若干p帧。

那么 你怎么 知道 ,这个就是  lsps , lpps, lsei , i 帧, p 帧呢,

就是 通过 NALU 来区分的。

也就是说, NALU 就是 lsps, lpps, lsei , i帧, p帧。

分隔符: 00 00 00 01    不是有效数据。

也就是说,  lsps , lpps , lsei  I帧 ,都要加上分隔符, 后面的p帧  就不加 分隔符了。

分隔符 后面的第一个字节 就是 NALU,  每一个位 都是由特定含义的。

也就是 lsps, lpps, lsei ,I 帧 , p帧 ,都是由 NALU的。

他们的第一个字节  就是 NAL。

这是 8个字节。

0-3 位 ,

4-8 位, 共5位, 可以表示31个数。

5: 代表 I帧

1: 代表 P帧 ,如果没有 B帧的情况下。

7 : 代表 lsps

8: 代表  lpps

6: 代表 lsei

好了, 到目前 一个字节 ,就区分出了, 这个NAUL 是什么类型了, 那么从第一个字节之后,到 00000001 ,之前的解析 都要按照 这个 帧的类型 来去分析这些数据了。

h264 sps 解析。

sps + pps 会影响播放器的行为。

sps 中有 图像的 高 , 宽的分辨率。

这是 sps 的 第一个 字节, 8位的表示。 表示的是 profiel .

level  在后面的字节中有表示。

图像的宽高 也在 后面的字节中。

h264  的 profile  + level。

profile 指的是 总体的说明

level 指的是 , 具体的 分辨率啥的。

pps , lei 中的参数就不看了。

知道什么意思就行。

CBR, VBR , 固定码率与 可变码率。 码率就是 每秒钟 编码的次数。

总结一下:

1 、 这里的帧 ,就是 对每一幅图的 压缩。

2 、 然后压缩之后的 出来的 h264 的码流 ,就是 一个一个的sequence 。

3、 一个sequence 就是有   sps , pps , sei , i帧, p帧 , 组成的。

第七节, rtsp 传输源码分析。

这里关键是 他 怎么 打包的 h264 的。

在进行压缩的时候立马 就进入 common_venc 了

这里就解释了 为什么 运行 rtsp 之后 会有一个 空文件了。

它本来是要往里面写文件的。

但是 后来 就发送出去了,不写文件了。

目前不明白这里的一包数据 ,指的是什么。

还是再 官方的 venc 的基础上改的。

主要改的文件是  sample_venc.c  + sample_common_venc.c


    1 main
  3       RtspServer_init
            RtspServerListen
            vdRTPSendThread
    1     SAMPLE_VENC_720P_CLASSIC
    2         SAMPLE_COMM_VENC_StartGetStream
    3             SAMPLE_COMM_VENC_GetVencStreamProc
    4                 SAMPLE_COMM_VENC_Sentjin
                            VENC_Sent

总结:

1  改的内容与 ortp 的改的内容是一样的。

2  sample_venc.c 中, 多了一个 rtsp 的 init 函数。

3  samle_comm_venc. c  中 多了 , SAMPLE_COMM_VENC_Sentjin  这个发送函数,这个是自己实现的。

4 端口号的配置字段,  

5 允许链接的客户端的数量的字段。  MAX_RTSP_CLIENT  默认设置的是 1 .

它这里是用的 是 tcp 。 这里应该是  rtsp 协议。

rtsp , rtp , rtcp  与 udp , tcp

接下来分析 函数      RtspServerListen

    5 RtspServerListen
    4     socket
    3     bind
    2     listen
    1     accept
  16      RtspClientMsg

网络的5层模型。

rtsp 属于应用层。

这两种 消息的格式 ,对应着 , 代码中的 parse  + unparse 函数。

这种交互 ,是在 建立了 socket 之后的交互。

其实就是 client  与 server 通信的步骤。

可以看到 这里是 option , describe , setup , paly  , 而不是 什么 三次握手。

我想看看 这两部分 , 源码中 是怎么实现的。

接下来对 RtspClientMsg 进行分析。

    8     RtspClientMsg
    7       ParseRequestString
    6       OptionAnswer
    5       DescribeAnswer
    4       SetupAnswer
    3       PlayAnswer
    2       PauseAnswer
    1       TeardownAnswer
  24

descritbeanswer    里面 处理了 sdp , 这样 就不需要 在 vlc 设置 sdp 了。

SetupAnswer  函数 主要设置了  ip 端口的信息。

setup 是客户端 发起的,服务端 要进行解析,它解析出来,

setup 是 udp 的。

这里的东西比较重要。

也就是说,一个 client  , 有三个端口, 一个视频的 ,一个音频的,这两个通过 track 来区分。

还有就是, 一个rtcp 的端口,

另外这个 reqchn ,就是 通道,这个应该是 编码的通道吧?

第十一节,  rtsp 实战分析。

这里 server 在play 的时候,重新建立了 一个 udp 的连接。

他 把这个新的连接 叫做通道。

总结:

1  板子生成的 packet 是什么没搞清楚。

2 rtsp 发送的时候,看样子 就是 通过两个端口 发送的 音频+ 视频。

数据流 ,    rtp  ,  走的是  tcp

控制流, rtcp 走的是 tcp

rtsp 走的是 udp

疑问: 那么  rtcp 与 rtsp 什么关系呢?

服务器 listen 线程一直存在,  客户端 不连接之后,可以关闭 某个 客户端的线程。

   16 main
   15     RtspServer_init
   14       RtspServerListen
   13           socket
   12           bind
   11           listen
   10           accept
    9           RtspClientMsg
    8             ParseRequestString
    7             OptionAnswer
    6             DescribeAnswer
    5             SetupAnswer
    4             PlayAnswer
    3             PauseAnswer
    2             TeardownAnswer
    1       vdRTPSendThread
  18      SAMPLE_VENC_720P_CLASSIC
    1         SAMPLE_COMM_VENC_StartGetStream
    2             SAMPLE_COMM_VENC_GetVencStreamProc
    3                 SAMPLE_COMM_VENC_Sentjin
    4                     VENC_Sent

这里  vdRTPSendThread ,  也调用了 venc_send  , 不明白它 发送的是什么。

这是在发送一个 头信息。具体干什么的不知道。

    12 HI_VOID* vdRTPSendThread(HI_VOID *p)
    11 {
    10     while(1)
     9     {
     8         if(!list_empty(&RTPbuf_head))
     7         {
     6
     5             RTPbuf_s *p = get_first_item(&RTPbuf_head,RTPbuf_s,list);
     4             VENC_Sent(p->buf,p->len);
     3             list_del(&(p->list));
     2             free(p->buf);
     1             free(p);
  960              p = NULL;
     1             count--;
     2             //printf("count = %d\n",count);
     3
     4         }
     5         usleep(5000);
     6     }
     7 }

第十二节 , 直接发送与 环状发送。

为什么会有  缓冲区呢?

因为 消费 与 生产的 速度 是不一定的, 有时候 生产快,有时候消费快,如果 某一个是 固定快的话,那么就没有 缓冲区的必要了。

venc_send 就是 直接就发送了。

那么 缓冲区怎么实现的呢?

在 sample_comm_venc.c 中 。

打开 savestream

注释掉 sample_comm_venc_sendto

创建了一个队列, 并且往队列中放数据。


     9 HI_S32 saveStream(VENC_STREAM_S *pstStream)
     8 {
     7     HI_S32 i,j,lens=0;
     6
     5     for(j=0;j<MAX_RTSP_CLIENT;j++)//have atleast a connect
     4     {
     3         if(g_rtspClients[j].status == RTSP_SENDING)
     2         {
     1             for (i = 0; i < pstStream->u32PackCount; i++)
  896              {
     1                 RTPbuf_s *p = (RTPbuf_s *)malloc(sizeof(RTPbuf_s));
     2                 INIT_LIST_HEAD(&(p->list));
     3
     4                 lens = pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset;
     5                 p->buf = (char *)malloc(lens);
     6                 p->len = lens;
     7                 memcpy(p->buf,pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,lens);
     8
     9                 list_add_tail(&(p->list),&RTPbuf_head);
    10                 count++;
    11                 //printf("count = %d\n",count);
    12             }
    13         }
    14     }
    15
    16     return HI_SUCCESS;
    17 }

然后 再 sample_venc.c 中

将 rtpsendthread 打开。

每次从队列中 拿出一个  buffer.

    20 HI_VOID* vdRTPSendThread(HI_VOID *p)
    19 {
    18     while(1)
    17     {
    16         if(!list_empty(&RTPbuf_head))
    15         {
    14
    13             RTPbuf_s *p = get_first_item(&RTPbuf_head,RTPbuf_s,list);
    12             VENC_Sent(p->buf,p->len);
    11             list_del(&(p->list));
    10             free(p->buf);
     9             free(p);
     8             p = NULL;
     7             count--;
     6             //printf("count = %d\n",count);
     5
     4         }
     3         usleep(5000);
     2     }
⚑    1 }

总结: rtsp 并没有像  ortp 那样  , 去编译库文件, 而是  直接 改的 源码, 这样的话, 更容易编译。

第十三节,分包发送。

rtpstamp ,用来标记 一个 frame 的。

rtp 包头

如果是整包的话,就是 NALU .

如果分包了的话,就会 是 FU indicator  + FU header   替代的是 NALU。

就到这里吧。

----------------------------------------------------------

接下来就是 我自己的实验了。

这是重头戏。

首先总结一下, 需要改的东西。

sample_venc.c 中  

添加 所有的 函数

还需要 添加 头文件。

然后是添加 rtsp  init 函数。 这里注意将  vdRTPSendThread  函数注释掉, 因为 跟 venc_send 是 一样的。

sample_comm_venc.c 中  ,

再 最后保存的时候, 使用的是 自己的发送函数。

当然 依然是  去掉 h265的 部分。

这是我添加的代码:

首先是  sample_venc.c 文件。

#define RTSP_ENABLE 1
#if	RTSP_ENABLE

RTP_FIXED_HEADER        *rtp_hdr;

NALU_HEADER		*nalu_hdr;
FU_INDICATOR	*fu_ind;
FU_HEADER		*fu_hdr;


RTSP_CLIENT g_rtspClients[MAX_RTSP_CLIENT];

int g_nSendDataChn = -1;
pthread_mutex_t g_mutex;
pthread_cond_t  g_cond;
pthread_mutex_t g_sendmutex;

pthread_t g_SendDataThreadId = 0;
//HAL_CLIENT_HANDLE hMainStreamClient = NULL,hSubStreamClient = NULL,hAudioClient = NULL;
char g_rtp_playload[20];
int   g_audio_rate = 8000;
//VIDEO_NORM_E gs_enNorm = VIDEO_ENCODING_MODE_NTSC;//30fps
int g_nframerate;

int exitok = 0;

int udpfd;

int count=0;


struct list_head RTPbuf_head = LIST_HEAD_INIT(RTPbuf_head);

static pthread_t gs_RtpPid;


static char const* dateHeader()
{
	static char buf[200];
#if !defined(_WIN32_WCE)
	time_t tt = time(NULL);
	strftime(buf, sizeof buf, "Date: %a, %b %d %Y %H:%M:%S GMT\r\n", gmtime(&tt));
#endif

	return buf;
}
static char* GetLocalIP(int sock)
{
	struct ifreq ifreq;
	struct sockaddr_in *sin;
	char * LocalIP = malloc(20);
	strcpy(ifreq.ifr_name,"wlan");
	if (!(ioctl (sock, SIOCGIFADDR,&ifreq)))
    	{ 
		sin = (struct sockaddr_in *)&ifreq.ifr_addr;
		sin->sin_family = AF_INET;
       	strcpy(LocalIP,inet_ntoa(sin->sin_addr)); 
		//inet_ntop(AF_INET, &sin->sin_addr,LocalIP, 16);
    	} 
	printf("--------------------------------------------%s\n",LocalIP);
	return LocalIP;
}

char* strDupSize(char const* str) 
{
  if (str == NULL) return NULL;
  size_t len = strlen(str) + 1;
  char* copy = malloc(len);

  return copy;
}

int ParseRequestString(char const* reqStr,
		       unsigned reqStrSize,
		       char* resultCmdName,
		       unsigned resultCmdNameMaxSize,
		       char* resultURLPreSuffix,
		       unsigned resultURLPreSuffixMaxSize,
		       char* resultURLSuffix,
		       unsigned resultURLSuffixMaxSize,
		       char* resultCSeq,
		       unsigned resultCSeqMaxSize) 
{
  // This parser is currently rather dumb; it should be made smarter #####

  // Read everything up to the first space as the command name:
  int parseSucceeded = FALSE;
  unsigned i;
  for (i = 0; i < resultCmdNameMaxSize-1 && i < reqStrSize; ++i) {
    char c = reqStr[i];
    if (c == ' ' || c == '\t') {
      parseSucceeded = TRUE;
      break;
    }

    resultCmdName[i] = c;
  }
  resultCmdName[i] = '\0';
  if (!parseSucceeded) return FALSE;
      
  // Skip over the prefix of any "rtsp://" or "rtsp:/" URL that follows:
  unsigned j = i+1;
  while (j < reqStrSize && (reqStr[j] == ' ' || reqStr[j] == '\t')) ++j; // skip over any additional white space
  for (j = i+1; j < reqStrSize-8; ++j) {
    if ((reqStr[j] == 'r' || reqStr[j] == 'R')
	&& (reqStr[j+1] == 't' || reqStr[j+1] == 'T')
	&& (reqStr[j+2] == 's' || reqStr[j+2] == 'S')
	&& (reqStr[j+3] == 'p' || reqStr[j+3] == 'P')
	&& reqStr[j+4] == ':' && reqStr[j+5] == '/') {
      j += 6;
      if (reqStr[j] == '/') {
	// This is a "rtsp://" URL; skip over the host:port part that follows:
	++j;
	while (j < reqStrSize && reqStr[j] != '/' && reqStr[j] != ' ') ++j;
      } else {
	// This is a "rtsp:/" URL; back up to the "/":
	--j;
      }
      i = j;
      break;
    }
  }

  // Look for the URL suffix (before the following "RTSP/"):
  parseSucceeded = FALSE;
  unsigned k;
  for (k = i+1; k < reqStrSize-5; ++k) {
    if (reqStr[k] == 'R' && reqStr[k+1] == 'T' &&
	reqStr[k+2] == 'S' && reqStr[k+3] == 'P' && reqStr[k+4] == '/') {
      while (--k >= i && reqStr[k] == ' ') {} // go back over all spaces before "RTSP/"
      unsigned k1 = k;
      while (k1 > i && reqStr[k1] != '/' && reqStr[k1] != ' ') --k1;
      // the URL suffix comes from [k1+1,k]

      // Copy "resultURLSuffix":
      if (k - k1 + 1 > resultURLSuffixMaxSize) return FALSE; // there's no room
      unsigned n = 0, k2 = k1+1;
      while (k2 <= k) resultURLSuffix[n++] = reqStr[k2++];
      resultURLSuffix[n] = '\0';

      // Also look for the URL 'pre-suffix' before this:
      unsigned k3 = --k1;
      while (k3 > i && reqStr[k3] != '/' && reqStr[k3] != ' ') --k3;
      // the URL pre-suffix comes from [k3+1,k1]

      // Copy "resultURLPreSuffix":
      if (k1 - k3 + 1 > resultURLPreSuffixMaxSize) return FALSE; // there's no room
      n = 0; k2 = k3+1;
      while (k2 <= k1) resultURLPreSuffix[n++] = reqStr[k2++];
      resultURLPreSuffix[n] = '\0';

      i = k + 7; // to go past " RTSP/"
      parseSucceeded = TRUE;
      break;
    }
  }
  if (!parseSucceeded) return FALSE;

  // Look for "CSeq:", skip whitespace,
  // then read everything up to the next \r or \n as 'CSeq':
  parseSucceeded = FALSE;
  for (j = i; j < reqStrSize-5; ++j) {
    if (reqStr[j] == 'C' && reqStr[j+1] == 'S' && reqStr[j+2] == 'e' &&
	reqStr[j+3] == 'q' && reqStr[j+4] == ':') {
      j += 5;
      unsigned n;
      while (j < reqStrSize && (reqStr[j] ==  ' ' || reqStr[j] == '\t')) ++j;
      for (n = 0; n < resultCSeqMaxSize-1 && j < reqStrSize; ++n,++j) {
	char c = reqStr[j];
	if (c == '\r' || c == '\n') {
	  parseSucceeded = TRUE;
	  break;
	}

	resultCSeq[n] = c;
      }
      resultCSeq[n] = '\0';
      break;
    }
  }
  if (!parseSucceeded) return FALSE;

  return TRUE;
}

int OptionAnswer(char *cseq, int sock)
{
	if (sock != 0)
	{
		char buf[1024];
		memset(buf,0,1024);
		char *pTemp = buf;
		pTemp += sprintf(pTemp,"RTSP/1.0 200 OK\r\nCSeq: %s\r\n%sPublic: %s\r\n\r\n",
			cseq,dateHeader(),"OPTIONS,DESCRIBE,SETUP,PLAY,PAUSE,TEARDOWN");
	
		int reg = send(sock, buf,strlen(buf),0);
		if(reg <= 0)
		{
			return FALSE;
		}
		else
		{
			printf(">>>>>%s\n",buf);
		}
		return TRUE;
	}
	return FALSE;
}

int DescribeAnswer(char *cseq,int sock,char * urlSuffix,char* recvbuf)
{
	if (sock != 0)
	{
		char sdpMsg[1024];
		char buf[2048];
		memset(buf,0,2048);
		memset(sdpMsg,0,1024);
		char*localip;
		localip = GetLocalIP(sock);
		
		char *pTemp = buf;
		pTemp += sprintf(pTemp,"RTSP/1.0 200 OK\r\nCSeq: %s\r\n",cseq);
		pTemp += sprintf(pTemp,"%s",dateHeader());
		pTemp += sprintf(pTemp,"Content-Type: application/sdp\r\n");
		

		char *pTemp2 = sdpMsg;
		pTemp2 += sprintf(pTemp2,"v=0\r\n");
		pTemp2 += sprintf(pTemp2,"o=StreamingServer 3331435948 1116907222000 IN IP4 %s\r\n",localip);
		pTemp2 += sprintf(pTemp2,"s=H.264\r\n");
		pTemp2 += sprintf(pTemp2,"c=IN IP4 0.0.0.0\r\n");
		pTemp2 += sprintf(pTemp2,"t=0 0\r\n");
		pTemp2 += sprintf(pTemp2,"a=control:*\r\n");
		

		/*H264 TrackID=0 RTP_PT 96*/
		pTemp2 += sprintf(pTemp2,"m=video 0 RTP/AVP 96\r\n");
		pTemp2 += sprintf(pTemp2,"a=control:trackID=0\r\n");
		pTemp2 += sprintf(pTemp2,"a=rtpmap:96 H264/90000\r\n");
		pTemp2 += sprintf(pTemp2,"a=fmtp:96 packetization-mode=1; sprop-parameter-sets=%s\r\n", "AAABBCCC");
#if 1
		
		/*G726*/
		
		pTemp2 += sprintf(pTemp2,"m=audio 0 RTP/AVP 97\r\n");
		pTemp2 += sprintf(pTemp2,"a=control:trackID=1\r\n");
		if(strcmp(g_rtp_playload,"AAC")==0)
		{
			pTemp2 += sprintf(pTemp2,"a=rtpmap:97 MPEG4-GENERIC/%d/2\r\n",16000);
			pTemp2 += sprintf(pTemp2,"a=fmtp:97 streamtype=5;profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1410\r\n");
		}
		else
		{
			pTemp2 += sprintf(pTemp2,"a=rtpmap:97 G726-32/%d/1\r\n",8000);
			pTemp2 += sprintf(pTemp2,"a=fmtp:97 packetization-mode=1\r\n");
		}	
#endif
		pTemp += sprintf(pTemp,"Content-length: %d\r\n", strlen(sdpMsg));     
		pTemp += sprintf(pTemp,"Content-Base: rtsp://%s/%s/\r\n\r\n",localip,urlSuffix);
		
		//printf("mem ready\n");
		strcat(pTemp, sdpMsg);
		free(localip);
		//printf("Describe ready sent\n");
		int re = send(sock, buf, strlen(buf),0);
		if(re <= 0)
		{
			return FALSE;
		}
		else
		{
			printf(">>>>>%s\n",buf);
		}
	}

	return TRUE;
}
void ParseTransportHeader(char const* buf,
						  StreamingMode* streamingMode,
						 char**streamingModeString,
						 char**destinationAddressStr,
						 u_int8_t* destinationTTL,
						 portNumBits* clientRTPPortNum, // if UDP
						 portNumBits* clientRTCPPortNum, // if UDP
						 unsigned char* rtpChannelId, // if TCP
						 unsigned char* rtcpChannelId // if TCP
						 )
 {
	// Initialize the result parameters to default values:
	*streamingMode = RTP_UDP;
	*streamingModeString = NULL;
	*destinationAddressStr = NULL;
	*destinationTTL = 255;
	*clientRTPPortNum = 0;
	*clientRTCPPortNum = 1; 
	*rtpChannelId = *rtcpChannelId = 0xFF;
	
	portNumBits p1, p2;
	unsigned ttl, rtpCid, rtcpCid;
	
	// First, find "Transport:"
	while (1) {
		if (*buf == '\0') return; // not found
		if (strncasecmp(buf, "Transport: ", 11) == 0) break;
		++buf;
	}
	
	// Then, run through each of the fields, looking for ones we handle:
	char const* fields = buf + 11;
	char* field = strDupSize(fields);
	while (sscanf(fields, "%[^;]", field) == 1) {
		if (strcmp(field, "RTP/AVP/TCP") == 0) {
			*streamingMode = RTP_TCP;
		} else if (strcmp(field, "RAW/RAW/UDP") == 0 ||
			strcmp(field, "MP2T/H2221/UDP") == 0) {
			*streamingMode = RAW_UDP;
			//*streamingModeString = strDup(field);
		} else if (strncasecmp(field, "destination=", 12) == 0)
		{
			//delete[] destinationAddressStr;
			free(destinationAddressStr);
			//destinationAddressStr = strDup(field+12);
		} else if (sscanf(field, "ttl%u", &ttl) == 1) {
			destinationTTL = (u_int8_t)ttl;
		} else if (sscanf(field, "client_port=%hu-%hu", &p1, &p2) == 2) {
			*clientRTPPortNum = p1;
			*clientRTCPPortNum = p2;
		} else if (sscanf(field, "client_port=%hu", &p1) == 1) {
			*clientRTPPortNum = p1;
			*clientRTCPPortNum = streamingMode == RAW_UDP ? 0 : p1 + 1;
		} else if (sscanf(field, "interleaved=%u-%u", &rtpCid, &rtcpCid) == 2) {
			*rtpChannelId = (unsigned char)rtpCid;
			*rtcpChannelId = (unsigned char)rtcpCid;
		}
		
		fields += strlen(field);
		while (*fields == ';') ++fields; // skip over separating ';' chars
		if (*fields == '\0' || *fields == '\r' || *fields == '\n') break;
	}
	free(field);
}


int SetupAnswer(char *cseq,int sock,int SessionId,char * urlSuffix,char* recvbuf,int* rtpport, int* rtcpport)
{
	if (sock != 0)
	{
		char buf[1024];
		memset(buf,0,1024);
		
		StreamingMode streamingMode;
		char* streamingModeString; // set when RAW_UDP streaming is specified
		char* clientsDestinationAddressStr;
		u_int8_t clientsDestinationTTL;
		portNumBits clientRTPPortNum, clientRTCPPortNum;
		unsigned char rtpChannelId, rtcpChannelId;
		ParseTransportHeader(recvbuf,&streamingMode, &streamingModeString,
			&clientsDestinationAddressStr, &clientsDestinationTTL,
			&clientRTPPortNum, &clientRTCPPortNum,
			&rtpChannelId, &rtcpChannelId);

		//Port clientRTPPort(clientRTPPortNum);
		//Port clientRTCPPort(clientRTCPPortNum);
		*rtpport = clientRTPPortNum;
		*rtcpport = clientRTCPPortNum;
		
		char *pTemp = buf;
		char*localip;
		localip = GetLocalIP(sock);
		pTemp += sprintf(pTemp,"RTSP/1.0 200 OK\r\nCSeq: %s\r\n%sTransport: RTP/AVP;unicast;destination=%s;client_port=%d-%d;server_port=%d-%d\r\nSession: %d\r\n\r\n",
			cseq,dateHeader(),localip,
			ntohs(htons(clientRTPPortNum)), 
			ntohs(htons(clientRTCPPortNum)), 
			ntohs(2000),
			ntohs(2001),
			SessionId);

		free(localip);
		int reg = send(sock, buf,strlen(buf),0);
		if(reg <= 0)
		{
			return FALSE;
		}
		else
		{
			printf(">>>>>%s",buf);
		}
		return TRUE;
	}
	return FALSE;
}

int PlayAnswer(char *cseq, int sock,int SessionId,char* urlPre,char* recvbuf)
{
	if (sock != 0)
	{
		char buf[1024];
		memset(buf,0,1024);
		char *pTemp = buf;
		char*localip;
		localip = GetLocalIP(sock);
		pTemp += sprintf(pTemp,"RTSP/1.0 200 OK\r\nCSeq: %s\r\n%sRange: npt=0.000-\r\nSession: %d\r\nRTP-Info: url=rtsp://%s/%s;seq=0\r\n\r\n",
			cseq,dateHeader(),SessionId,localip,urlPre);

		free(localip);
		
		int reg = send(sock, buf,strlen(buf),0);
		if(reg <= 0)
		{
			return FALSE;
		}
		else
		{
			printf(">>>>>%s",buf);
			udpfd = socket(AF_INET,SOCK_DGRAM,0);//UDP
			struct sockaddr_in server;
			server.sin_family=AF_INET;
		   	server.sin_port=htons(g_rtspClients[0].rtpport[0]);          
		   	server.sin_addr.s_addr=inet_addr(g_rtspClients[0].IP);
			connect(udpfd,(struct sockaddr *)&server,sizeof(server));
    		printf("udp up\n");
		}
		return TRUE;
	}
	return FALSE;
}

int PauseAnswer(char *cseq,int sock,char *recvbuf)
{
	if (sock != 0)
	{
		char buf[1024];
		memset(buf,0,1024);
		char *pTemp = buf;
		pTemp += sprintf(pTemp,"RTSP/1.0 200 OK\r\nCSeq: %s\r\n%s\r\n\r\n",
			cseq,dateHeader());
	
		int reg = send(sock, buf,strlen(buf),0);
		if(reg <= 0)
		{
			return FALSE;
		}
		else
		{
			printf(">>>>>%s",buf);
		}
		return TRUE;
	}
	return FALSE;
}

int TeardownAnswer(char *cseq,int sock,int SessionId,char *recvbuf)
{
	if (sock != 0)
	{
		char buf[1024];
		memset(buf,0,1024);
		char *pTemp = buf;
		pTemp += sprintf(pTemp,"RTSP/1.0 200 OK\r\nCSeq: %s\r\n%sSession: %d\r\n\r\n",
			cseq,dateHeader(),SessionId);
	
		int reg = send(sock, buf,strlen(buf),0);
		if(reg <= 0)
		{
			return FALSE;
		}
		else
		{
			printf(">>>>>%s",buf);
			close(udpfd);
		}
		return TRUE;
	}
	return FALSE;
}
void * RtspClientMsg(void*pParam)
{
	pthread_detach(pthread_self());
	int nRes;
	char pRecvBuf[RTSP_RECV_SIZE];
	RTSP_CLIENT * pClient = (RTSP_CLIENT*)pParam;
	memset(pRecvBuf,0,sizeof(pRecvBuf));
	printf("RTSP:-----Create Client %s\n",pClient->IP);
	while(pClient->status != RTSP_IDLE)
	{
		nRes = recv(pClient->socket, pRecvBuf, RTSP_RECV_SIZE,0);
		//printf("-------------------%d\n",nRes);
		if(nRes < 1)
		{
			//usleep(1000);
			printf("RTSP:Recv Error--- %d\n",nRes);
			g_rtspClients[pClient->index].status = RTSP_IDLE;
			g_rtspClients[pClient->index].seqnum = 0;
			g_rtspClients[pClient->index].tsvid = 0;
			g_rtspClients[pClient->index].tsaud = 0;
			close(pClient->socket);
			break;
		}
		char cmdName[PARAM_STRING_MAX];
		char urlPreSuffix[PARAM_STRING_MAX];
		char urlSuffix[PARAM_STRING_MAX];
		char cseq[PARAM_STRING_MAX];

		ParseRequestString(pRecvBuf,nRes,cmdName,sizeof(cmdName),urlPreSuffix,sizeof(urlPreSuffix),
			urlSuffix,sizeof(urlSuffix),cseq,sizeof(cseq));
		
		char *p = pRecvBuf;

		printf("<<<<<%s\n",p);

		//printf("\--------------------------\n");
		//printf("%s %s\n",urlPreSuffix,urlSuffix);

		if(strstr(cmdName, "OPTIONS"))
		{
			OptionAnswer(cseq,pClient->socket);
			
		}
		else if(strstr(cmdName, "DESCRIBE"))
		{
			DescribeAnswer(cseq,pClient->socket,urlSuffix,p);
			//printf("-----------------------------DescribeAnswer %s %s\n",
			//	urlPreSuffix,urlSuffix);
		}
		else if(strstr(cmdName, "SETUP"))
		{
			int rtpport,rtcpport;
			int trackID=0;
			SetupAnswer(cseq,pClient->socket,pClient->sessionid,urlPreSuffix,p,&rtpport,&rtcpport);

			sscanf(urlSuffix, "trackID=%u", &trackID);
			//printf("----------------------------------------------TrackId %d\n",trackID);
			if(trackID<0 || trackID>=2)trackID=0;
			g_rtspClients[pClient->index].rtpport[trackID] = rtpport;
			g_rtspClients[pClient->index].rtcpport= rtcpport;
			g_rtspClients[pClient->index].reqchn = atoi(urlPreSuffix);
			if(strlen(urlPreSuffix)<100)
				strcpy(g_rtspClients[pClient->index].urlPre,urlPreSuffix);
			//printf("-----------------------------SetupAnswer %s-%d-%d\n",
			//	urlPreSuffix,g_rtspClients[pClient->index].reqchn,rtpport);
		}
		else if(strstr(cmdName, "PLAY"))
		{
			PlayAnswer(cseq,pClient->socket,pClient->sessionid,g_rtspClients[pClient->index].urlPre,p);
			g_rtspClients[pClient->index].status = RTSP_SENDING;
			printf("Start Play\n",pClient->index);
			//printf("-----------------------------PlayAnswer %d %d\n",pClient->index);
			//usleep(100);
		}
		else if(strstr(cmdName, "PAUSE"))
		{
			PauseAnswer(cseq,pClient->socket,p);
		}
		else if(strstr(cmdName, "TEARDOWN"))
		{
			TeardownAnswer(cseq,pClient->socket,pClient->sessionid,p);
			g_rtspClients[pClient->index].status = RTSP_IDLE;
			g_rtspClients[pClient->index].seqnum = 0;
			g_rtspClients[pClient->index].tsvid = 0;
			g_rtspClients[pClient->index].tsaud = 0;
			close(pClient->socket);
		}
		//if(exitok){ exitok++;return NULL; } 
	}
	printf("RTSP:-----Exit Client %s\n",pClient->IP);
	return NULL;
}

void * RtspServerListen(void*pParam)
{
	int s32Socket;
	struct sockaddr_in servaddr;
	int s32CSocket;
    	int s32Rtn;
    	int s32Socket_opt_value = 1;
	int nAddrLen;
	struct sockaddr_in addrAccept;
	int bResult;
	
	memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(RTSP_SERVER_PORT); 

	s32Socket = socket(AF_INET, SOCK_STREAM, 0);

	if (setsockopt(s32Socket ,SOL_SOCKET,SO_REUSEADDR,&s32Socket_opt_value,sizeof(int)) == -1)     
    {
        return (void *)(-1);
    }
    s32Rtn = bind(s32Socket, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in));
    if(s32Rtn < 0)
    {
        return (void *)(-2);
    }
    
    s32Rtn = listen(s32Socket, 50);   
    if(s32Rtn < 0)
    {

         return (void *)(-2);
    }


	nAddrLen = sizeof(struct sockaddr_in);
	int nSessionId = 1000;
    while ((s32CSocket = accept(s32Socket, (struct sockaddr*)&addrAccept, &nAddrLen)) >= 0)
    {
		printf("<<<<RTSP Client %s Connected...\n", inet_ntoa(addrAccept.sin_addr));

		int nMaxBuf = 10 * 1024; // 脧碌脥鲁艙芦禄谩路脰脜盲 2 x nMaxBuf 碌脛禄潞鲁氓沤贸脨隆
		if(setsockopt(s32CSocket, SOL_SOCKET, SO_SNDBUF, (char*)&nMaxBuf, sizeof(nMaxBuf)) == -1)
			printf("RTSP:!!!!!! Enalarge socket sending buffer error !!!!!!\n");
		int i;
		int bAdd=FALSE;
		for(i=0;i<MAX_RTSP_CLIENT;i++)
		{
			if(g_rtspClients[i].status == RTSP_IDLE)
			{
				memset(&g_rtspClients[i],0,sizeof(RTSP_CLIENT));
				g_rtspClients[i].index = i;
				g_rtspClients[i].socket = s32CSocket;
				g_rtspClients[i].status = RTSP_CONNECTED ;//RTSP_SENDING;
				g_rtspClients[i].sessionid = nSessionId++;
				strcpy(g_rtspClients[i].IP,inet_ntoa(addrAccept.sin_addr));
				pthread_t threadIdlsn = 0;
				
				struct sched_param sched;
				sched.sched_priority = 1;
				//to return ACKecho
				pthread_create(&threadIdlsn, NULL, RtspClientMsg, &g_rtspClients[i]);
				//pthread_setschedparam(threadIdlsn,SCHED_RR,&sched);
				
				bAdd = TRUE;
				break;
			}
		}
		if(bAdd==FALSE)
		{
			memset(&g_rtspClients[0],0,sizeof(RTSP_CLIENT));
			g_rtspClients[0].index = 0;
			g_rtspClients[0].socket = s32CSocket;
			g_rtspClients[0].status = RTSP_CONNECTED ;//RTSP_SENDING;
			g_rtspClients[0].sessionid = nSessionId++;
			strcpy(g_rtspClients[0].IP,inet_ntoa(addrAccept.sin_addr));
			pthread_t threadIdlsn = 0;
			struct sched_param sched;
			sched.sched_priority = 1;
			//to return ACKecho
			pthread_create(&threadIdlsn, NULL, RtspClientMsg, &g_rtspClients[0]);
			//pthread_setschedparam(threadIdlsn,SCHED_RR,&sched);
			bAdd = TRUE;
		}
		//if(exitok){ exitok++;return NULL; } 	
    }
    if(s32CSocket < 0)
    {
       // HI_OUT_Printf(0, "RTSP listening on port %d,accept err, %d\n", RTSP_SERVER_PORT, s32CSocket);
    }

	printf("----- INIT_RTSP_Listen() Exit !! \n");
	
	return NULL;
}
HI_S32 VENC_Sent(char *buffer,int buflen)
{
    HI_S32 i;
	int is=0;
	int nChanNum=0;

	for(is=0;is<MAX_RTSP_CLIENT;is++)
	{
		if(g_rtspClients[is].status!=RTSP_SENDING)
		{
		    continue;
		}
		int heart = g_rtspClients[is].seqnum % 10000;
		
		char* nalu_payload;
		int nAvFrmLen = 0;
		int nIsIFrm = 0;
		int nNaluType = 0;
		char sendbuf[500*1024+32];

	
		nAvFrmLen = buflen;

		struct sockaddr_in server;
		server.sin_family=AF_INET;
	   	server.sin_port=htons(g_rtspClients[is].rtpport[0]);          
	   	server.sin_addr.s_addr=inet_addr(g_rtspClients[is].IP);
		int	bytes=0;
		unsigned int timestamp_increse=0;
		
		timestamp_increse=(unsigned int)(90000.0 / 25);

		rtp_hdr =(RTP_FIXED_HEADER*)&sendbuf[0]; 
	
		rtp_hdr->payload     = RTP_H264;   
		rtp_hdr->version     = 2;          
		rtp_hdr->marker    = 0;           
		rtp_hdr->ssrc      = htonl(10);   

		if(nAvFrmLen<=nalu_sent_len)
		{
			rtp_hdr->marker=1;
			rtp_hdr->seq_no     = htons(g_rtspClients[is].seqnum++); 
			nalu_hdr =(NALU_HEADER*)&sendbuf[12]; 
			nalu_hdr->F=0; 
			nalu_hdr->NRI=  nIsIFrm; 
			nalu_hdr->TYPE=  nNaluType;
			nalu_payload=&sendbuf[13];
			memcpy(nalu_payload,buffer,nAvFrmLen);
            		g_rtspClients[is].tsvid = g_rtspClients[is].tsvid+timestamp_increse;            
			rtp_hdr->timestamp=htonl(g_rtspClients[is].tsvid);
			bytes=nAvFrmLen+ 13 ;				
			sendto(udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server));
		}
		else if(nAvFrmLen>nalu_sent_len)
		{
			int k=0,l=0;
			k=nAvFrmLen/nalu_sent_len;
			l=nAvFrmLen%nalu_sent_len;
			int t=0;        

            g_rtspClients[is].tsvid = g_rtspClients[is].tsvid+timestamp_increse;
            rtp_hdr->timestamp=htonl(g_rtspClients[is].tsvid);            
			while(t<=k)
			{
				rtp_hdr->seq_no = htons(g_rtspClients[is].seqnum++);
				if(t==0)
				{
					rtp_hdr->marker=0;
					fu_ind =(FU_INDICATOR*)&sendbuf[12];
					fu_ind->F= 0; 
					fu_ind->NRI= nIsIFrm;
					fu_ind->TYPE=28;
	
					fu_hdr =(FU_HEADER*)&sendbuf[13];
					fu_hdr->E=0;
					fu_hdr->R=0;
					fu_hdr->S=1;
					fu_hdr->TYPE=nNaluType;
	
					nalu_payload=&sendbuf[14];
					memcpy(nalu_payload,buffer,nalu_sent_len);
	
					bytes=nalu_sent_len+14;					
					sendto( udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server));
					t++;
	
				}
				else if(k==t)
				{
					rtp_hdr->marker=1;
					fu_ind =(FU_INDICATOR*)&sendbuf[12]; 
					fu_ind->F= 0 ;
					fu_ind->NRI= nIsIFrm ;
					fu_ind->TYPE=28;

					fu_hdr =(FU_HEADER*)&sendbuf[13];
					fu_hdr->R=0;
					fu_hdr->S=0;
					fu_hdr->TYPE= nNaluType;
					fu_hdr->E=1;
					nalu_payload=&sendbuf[14];
					memcpy(nalu_payload,buffer+t*nalu_sent_len,l);
					bytes=l+14;		
					sendto(udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server));
					t++;
				}
				else if(t<k && t!=0)
				{

					rtp_hdr->marker=0;

					fu_ind =(FU_INDICATOR*)&sendbuf[12]; 
					fu_ind->F=0; 
					fu_ind->NRI=nIsIFrm;
					fu_ind->TYPE=28;
					fu_hdr =(FU_HEADER*)&sendbuf[13];
					//fu_hdr->E=0;
					fu_hdr->R=0;
					fu_hdr->S=0;
					fu_hdr->E=0;
					fu_hdr->TYPE=nNaluType;
					nalu_payload=&sendbuf[14];
					memcpy(nalu_payload,buffer+t*nalu_sent_len,nalu_sent_len);
					bytes=nalu_sent_len+14;	
					sendto(udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server));
					t++;
				}
			}
		}

	}

	//------------------------------------------------------------
}
/******************************************************************************
* funciton : sent H264 stream
******************************************************************************/

HI_S32 SAMPLE_COMM_VENC_Sentjin(VENC_STREAM_S *pstStream)
{
    HI_S32 i,flag=0;

    for(i=0;i<MAX_RTSP_CLIENT;i++)//have atleast a connect
    {
		if(g_rtspClients[i].status == RTSP_SENDING)
		{
		    flag = 1;
		    break;
		}
    }
    if(flag)
    {
	    for (i = 0; i < pstStream->u32PackCount; i++)
	    {
		HI_S32 lens=0,j,lastadd=0,newadd=0,showflap=0;
		char sendbuf[320*1024];
		//char tmp[640*1024];
		lens = pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset;
		memcpy(&sendbuf[0],pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,lens);
		//printf("lens = %d, count= %d\n",lens,count++);
		VENC_Sent(sendbuf,lens);		
		lens = 0;
	    }

	
    }
    return HI_SUCCESS;
}

HI_S32 saveStream(VENC_STREAM_S *pstStream)
{
    HI_S32 i,j,lens=0;

    for(j=0;j<MAX_RTSP_CLIENT;j++)//have atleast a connect
    {
		if(g_rtspClients[j].status == RTSP_SENDING)
		{
		    for (i = 0; i < pstStream->u32PackCount; i++)
		    {
				RTPbuf_s *p = (RTPbuf_s *)malloc(sizeof(RTPbuf_s));
				INIT_LIST_HEAD(&(p->list));

				lens = pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset;
				p->buf = (char *)malloc(lens);
				p->len = lens;
				memcpy(p->buf,pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,lens);

				list_add_tail(&(p->list),&RTPbuf_head);
				count++;
				//printf("count = %d\n",count);
		    }
    	}
    }

    return HI_SUCCESS;
}


void RtspServer_init(void)
{
	int i;
	pthread_t threadId = 0;

	memset(&g_rtp_playload,0,sizeof(g_rtp_playload));
	strcpy(&g_rtp_playload,"G726-32");
	g_audio_rate = 8000;
	pthread_mutex_init(&g_sendmutex,NULL);
	pthread_mutex_init(&g_mutex,NULL);
	pthread_cond_init(&g_cond,NULL);
	memset(&g_rtspClients,0,sizeof(RTSP_CLIENT)*MAX_RTSP_CLIENT);
	
	//pthread_create(&g_SendDataThreadId, NULL, SendDataThread, NULL);
	
	struct sched_param thdsched;
	thdsched.sched_priority = 2;
	//to listen visiting
	pthread_create(&threadId, NULL, RtspServerListen, NULL);
	//pthread_setschedparam(threadId,SCHED_RR,&thdsched);
	printf("RTSP:-----Init Rtsp server\n");

	pthread_create(&gs_RtpPid, 0, vdRTPSendThread, NULL);
	
	//exitok++;

}
void RtspServer_exit(void)
{
	return;
}

HI_VOID* vdRTPSendThread(HI_VOID *p)
{
	while(1)
	{
		if(!list_empty(&RTPbuf_head))
		{
			
			RTPbuf_s *p = get_first_item(&RTPbuf_head,RTPbuf_s,list);
			VENC_Sent(p->buf,p->len);
			list_del(&(p->list));
			free(p->buf);
			free(p);
			p = NULL;
			count--;
			//printf("count = %d\n",count);
		
		}
		usleep(5000);
	}
}

#endif

main 函数里这么添加。

    11 #if RTSP_ENABLE
    10     RtspServer_init();
     9 #endif
     8
     7     ret = sample_venc_choose_mode(index);
     6     if (ret == TD_SUCCESS) {
     5         printf("program exit normally!\n");
     4     } else {
     3         printf("program exit abnormally!\n");
     2     }
     1

添加需要的库。

  17
     1 #define RTSP_ENABLE 1
     2
     3
     4 #if RTSP_ENABLE
     5
     6 #include <unistd.h>
     7 #include <stdio.h>
     8 #include <string.h>
     9 #include <stdlib.h>
    10 #include <time.h>
    11 #include <netdb.h>
    12 #include <sys/socket.h>
    13
    14 #include <sys/ioctl.h>
    15 #include <fcntl.h>
    16 #include <pthread.h>
    17 #include <sys/ipc.h>
    18 #include <sys/msg.h>
    19 #include <netinet/if_ether.h>
    20 #include <net/if.h>
    21
    22 #include <linux/if_ether.h>
    23 #include <linux/sockios.h>
    24 #include <netinet/in.h>
    25 #include <arpa/inet.h>
    26
    27 #endif
    28

然后是 sample_comm_venc.c  文件。

在最开头  添加。

    14 #define RTSP_ENABLE 1
  2865 static td_void sample_comm_fd_isset(sample_comm_venc_stream_proc_info *stream_proc_info, fd_set *read_fds,
     1     ot_venc_stream_buf_info *stream_buf_info, ot_payload_type *payload_type, sample_venc_getstream_para *para)
     2 {
     3     td_s32 i, ret;
     4
     5 //    for (i = 0; (i < stream_proc_info->chn_total) && (i < OT_VENC_MAX_CHN_NUM); i++) {
     6     //
     7 //topeet wang added
     8     for (i = 1; (i < stream_proc_info->chn_total) && (i < OT_VENC_MAX_CHN_NUM); i++) {
     9         if (FD_ISSET(stream_proc_info->venc_fd[i], read_fds)) {
    10             stream_proc_info->venc_chn = para->venc_chn[i];
    11             ret = sample_comm_get_stream_from_one_channl(stream_proc_info, i, stream_buf_info, payload_type);
    12             if (ret == SAMPLE_RETURN_CONTINUE) {
    13                 continue;
    14             } else if (ret == SAMPLE_RETURN_BREAK) {
    15                 break;
    16             }
    17         }
    18     }
    19 }

然后是  sample_comm_save_frame_to_file  函数。

     3 #ifndef __LITEOS__
     4     ot_unused(stream_buf_info);
     5
     6
     7
     8 #if RTSP_ENABLE
     9     SAMPLE_COMM_VENC_Sentjin(&stStream);
    10 #else
    11     ret = sample_comm_venc_save_stream(stream_proc_info->file[index], stream);
    12 #endif
    13

接下来编译一遍看看。

出现报错

.1.0/smp/a7_linux/source/mpp/sample/venc/../common/sample_comm_venc.c
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc/../common/sample_comm_venc.c: In function 'sample_comm_save_frame_to_file':
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc/../common/sample_comm_venc.c:2777:5: warning: implicit declaration of function 'SAMPLE_COMM_VENC_Sentjin' [-Wimplicit-function-declaration]
 2777 |     SAMPLE_COMM_VENC_Sentjin(&stStream);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc/../common/sample_comm_venc.c:2777:31: error: 'stStream' undeclared (first use in this function); did you mean 'stream'?
 2777 |     SAMPLE_COMM_VENC_Sentjin(&stStream);
      |                               ^~~~~~~~
      |                               stream
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc/../common/sample_comm_venc.c:2777:31: note: each undeclared identifier is reported only once for each function it appears in
make: *** [<builtin>: /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc/../common/sample_comm_venc.o] Error 1
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc#

将函数   SAMPLE_COMM_VENC_Sentjin(&stStream)   改为  SAMPLE_COMM_VENC_Sentjin(&stream)

依然有报错。

/include -I/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/out/include/exp_inc -DVER_X=1 -DVER_Y=0 -DVER_Z=0 -DVER_P=0 -DVER_B=10 -DUSER_BIT_32 -DKERNEL_BIT_32 -DOT
_RELEASE -Wno-date-time -DSENSOR0_TYPE=SC4336P_MIPI_4M_30FPS_10BIT -DSENSOR1_TYPE=SC4336P_MIPI_4M_30FPS_10BIT -DBOARD_TYPE=DMEB_QFN -DOT_ACODEC_TYPE_INNER -DOT_VQE_USE_STATIC_MODULE_REGI
STER -I/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc/../common -I/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/
venc/../audio/adp   -c -o sample_venc.o sample_venc.c
sample_venc.c:79:1: error: unknown type name 'RTP_FIXED_HEADER'
   79 | RTP_FIXED_HEADER        *rtp_hdr;
      | ^~~~~~~~~~~~~~~~
sample_venc.c:81:1: error: unknown type name 'NALU_HEADER'
   81 | NALU_HEADER  *nalu_hdr;
      | ^~~~~~~~~~~
sample_venc.c:82:1: error: unknown type name 'FU_INDICATOR'
   82 | FU_INDICATOR *fu_ind;
      | ^~~~~~~~~~~~
sample_venc.c:83:1: error: unknown type name 'FU_HEADER'
   83 | FU_HEADER  *fu_hdr;
      | ^~~~~~~~~
sample_venc.c:86:1: error: unknown type name 'RTSP_CLIENT'
   86 | RTSP_CLIENT g_rtspClients[MAX_RTSP_CLIENT];
      | ^~~~~~~~~~~
sample_venc.c:86:27: error: 'MAX_RTSP_CLIENT' undeclared here (not in a function)
   86 | RTSP_CLIENT g_rtspClients[MAX_RTSP_CLIENT];
      |                           ^~~~~~~~~~~~~~~
sample_venc.c:107:8: error: variable 'RTPbuf_head' has initializer but incomplete type
  107 | struct list_head RTPbuf_head = LIST_HEAD_INIT(RTPbuf_head);
      |        ^~~~~~~~~
sample_venc.c:107:32: warning: implicit declaration of function 'LIST_HEAD_INIT' [-Wimplicit-function-declaration]
  107 | struct list_head RTPbuf_head = LIST_HEAD_INIT(RTPbuf_head);
      |                                ^~~~~~~~~~~~~~
sample_venc.c:107:47: error: 'RTPbuf_head' has an incomplete type 'struct list_head'

解决: 

原来  在 sample_comm.h 中 还有 需要改动的内容。

添加这些内容。


#if	RTSP_ENABLE

#include "list.h"
#if !defined(WIN32)
	#define __PACKED__        __attribute__ ((__packed__))
#else
	#define __PACKED__ 
#endif

typedef enum
{
	RTSP_VIDEO=0,
	RTSP_VIDEOSUB=1,
	RTSP_AUDIO=2,
	RTSP_YUV422=3,
	RTSP_RGB=4,
	RTSP_VIDEOPS=5,
	RTSP_VIDEOSUBPS=6
}enRTSP_MonBlockType;

struct _RTP_FIXED_HEADER
{
    /**//* byte 0 */
    unsigned char csrc_len:4;        /**//* expect 0 */
    unsigned char extension:1;        /**//* expect 1, see RTP_OP below */
    unsigned char padding:1;        /**//* expect 0 */
    unsigned char version:2;        /**//* expect 2 */
    /**//* byte 1 */
    unsigned char payload:7;        /**//* RTP_PAYLOAD_RTSP */
    unsigned char marker:1;        /**//* expect 1 */
    /**//* bytes 2, 3 */
    unsigned short seq_no;            
    /**//* bytes 4-7 */
    unsigned  long timestamp;        
    /**//* bytes 8-11 */
    unsigned long ssrc;            /**//* stream number is used here. */
} __PACKED__;

typedef struct _RTP_FIXED_HEADER RTP_FIXED_HEADER;

struct _NALU_HEADER
{
    //byte 0
	unsigned char TYPE:5;
    	unsigned char NRI:2;
	unsigned char F:1;    
	
}__PACKED__; /**//* 1 BYTES */

typedef struct _NALU_HEADER NALU_HEADER;

struct _FU_INDICATOR
{
    	//byte 0
    	unsigned char TYPE:5;
	unsigned char NRI:2; 
	unsigned char F:1;    
	
}__PACKED__; /**//* 1 BYTES */

typedef struct _FU_INDICATOR FU_INDICATOR;

struct _FU_HEADER
{
   	 //byte 0
    	unsigned char TYPE:5;
	unsigned char R:1;
	unsigned char E:1;
	unsigned char S:1;    
} __PACKED__; /**//* 1 BYTES */
typedef struct _FU_HEADER FU_HEADER;

struct _AU_HEADER
{
    //byte 0, 1
    unsigned short au_len;
    //byte 2,3
    unsigned  short frm_len:13;  
    unsigned char au_index:3;
} __PACKED__; /**//* 1 BYTES */
typedef struct _AU_HEADER AU_HEADER;


extern void RtspServer_init(void);
extern void RtspServer_exit(void);

int AddFrameToRtspBuf(int nChanNum,enRTSP_MonBlockType eType, char * pData, unsigned int  nSize, unsigned int  nVidFrmNum,int bIFrm);

extern HI_S32 SAMPLE_COMM_VENC_Sentjin(VENC_STREAM_S *pstStream);
extern HI_S32 saveStream(VENC_STREAM_S *pstStream);
extern HI_VOID* vdRTPSendThread(HI_VOID *p);



#define nalu_sent_len        1400
//#define nalu_sent_len        1400
#define RTP_H264                    96
#define RTP_AUDIO              97
#define MAX_RTSP_CLIENT       1
#define RTSP_SERVER_PORT      554
#define RTSP_RECV_SIZE        1024
#define RTSP_MAX_VID          (640*1024)
#define RTSP_MAX_AUD          (15*1024)

#define AU_HEADER_SIZE    4
#define PARAM_STRING_MAX        100



typedef unsigned short u_int16_t;
typedef unsigned char u_int8_t;
typedef u_int16_t portNumBits;
typedef u_int32_t netAddressBits;
typedef long long _int64;
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE  1
#endif
#define AUDIO_RATE    8000
#define PACKET_BUFFER_END            (unsigned int)0x00000000


typedef struct 
{
	int startblock;//浠h〃寮€濮嬫枃浠跺潡鍙?
	int endblock;//浠h〃缁撴潫鏂囦欢鍧楀彿
	int BlockFileNum;//浠h〃褰曞儚娈垫暟
	
}IDXFILEHEAD_INFO;//.IDX鏂囦欢鐨勫ご淇℃伅

typedef struct 
{
	_int64 starttime;//浠h〃寮€濮媠hijian
	_int64 endtime;//浠h〃缁撴潫shijian 
	int startblock;//浠h〃寮€濮嬫枃浠跺潡鍙?
	int endblock;//浠h〃缁撴潫鏂囦欢鍧楀彿
	int stampnum;//浠h〃鏃堕棿鎴虫暟閲?
}IDXFILEBLOCK_INFO;//.IDX鏂囦欢娈典俊鎭?

typedef struct 
{
	int blockindex;//浠h〃鎵€鍦ㄦ枃浠跺潡鍙?
	int pos;//浠h〃璇ユ椂闂存埑鍦ㄦ枃浠跺潡鐨勪綅缃?
	_int64 time;//浠h〃鏃堕棿鎴虫椂闂存埑鐨勬椂闂寸偣
}IDXSTAMP_INFO;//.IDX鏂囦欢鐨勬椂闂存埑淇℃伅

typedef struct 
{
	char filename[150];//浠h〃鎵€鍦ㄦ枃浠跺潡鍙?
	int pos;//浠h〃璇ユ椂闂存埑鍦ㄦ枃浠跺潡鐨勪綅缃?
	_int64 time;//浠h〃鏃堕棿鎴虫椂闂存埑鐨勬椂闂寸偣
}FILESTAMP_INFO;//.IDX鏂囦欢鐨勬椂闂存埑淇℃伅

typedef struct 
{
	char channelid[9];
	_int64 starttime;//浠h〃寮€濮媠hijian
	_int64 endtime;//浠h〃缁撴潫shijian 
	_int64 session;
	int		type;	//绫诲瀷
	int		encodetype;//缂栫爜鏍煎紡;
}FIND_INFO;//.IDX鏂囦欢鐨勬椂闂存埑淇℃伅

typedef enum
{
	RTP_UDP,
	RTP_TCP,
	RAW_UDP
}StreamingMode;


RTP_FIXED_HEADER  *rtp_hdr;
NALU_HEADER		  *nalu_hdr;
FU_INDICATOR	  *fu_ind;
FU_HEADER		  *fu_hdr;
AU_HEADER            *au_hdr;


extern char g_rtp_playload[20];//脛卢脠脧G726-32
extern int   g_audio_rate;//脛卢脠脧8000

typedef enum
{
	RTSP_IDLE = 0,
	RTSP_CONNECTED = 1,
	RTSP_SENDING = 2,
}RTSP_STATUS;

typedef struct
{
	int  nVidLen;
	int  nAudLen;
	int bIsIFrm;
	int bWaitIFrm;
	int bIsFree;
	char vidBuf[RTSP_MAX_VID];
	char audBuf[RTSP_MAX_AUD];
}RTSP_PACK;

typedef struct
{
	int index;
	int socket;
	int reqchn;
	int seqnum;
	int seqnum2;
	unsigned int tsvid;
	unsigned int tsaud;
	int status;
	int sessionid;
	int rtpport[2];
	int rtcpport;
	char IP[20];
	char urlPre[PARAM_STRING_MAX];
}RTSP_CLIENT;

typedef struct
{
	int  vidLen;
	int  audLen;
	int  nFrameID;
	char vidBuf[RTSP_MAX_VID];
	char audBuf[RTSP_MAX_AUD];
}FRAME_PACK;
typedef struct
{
  int startcodeprefix_len;      //! 4 for parameter sets and first slice in picture, 3 for everything else (suggested)
  unsigned len;                 //! Length of the NAL unit (Excluding the start code, which does not belong to the NALU)
  unsigned max_size;            //! Nal Unit Buffer size
  int forbidden_bit;            //! should be always FALSE
  int nal_reference_idc;        //! NALU_PRIORITY_xxxx
  int nal_unit_type;            //! NALU_TYPE_xxxx
  char *buf;                    //! contains the first byte followed by the EBSP
  unsigned short lost_packets;  //! true, if packet loss is detected
} NALU_t;
extern int udpfd;
extern RTSP_CLIENT g_rtspClients[MAX_RTSP_CLIENT];
typedef struct _rtpbuf
{
	struct list_head list;
	HI_S32 len;
	char * buf;
}RTPbuf_s;
extern struct list_head RTPbuf_head;

#endif

依然后报错。

rt_demo region scene_auto security_subsys smart_ae svc_venc svp uvc_app venc vgs vie cccccccc
make[1]: Entering directory '/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common'
~~~~~~~~~~Start build audio~~~~~~~~~~
make[1]: Entering directory '/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/audio'
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/bin/../lib/gcc/arm-linux-musleabi/10.3.0/../../../../arm-linux-musleabi/bin/ld: /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/audio/../common/sample_comm_venc.o: in function `sample_comm_venc_get_venc_stream_proc':
sample_comm_venc.c:(.text.sample_comm_venc_get_venc_stream_proc+0x59a): undefined reference to `SAMPLE_COMM_VENC_Sentjin'
collect2: error: ld returned 1 exit status
make[1]: *** [/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/audio/../smp_linux.mak:14: sample_audio] Error 1
make[1]: Leaving directory '/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/audio'
make: *** [Makefile:31: audio] Error 2
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample#
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample#

解决:  我需要重新编译一下  sample_comm_venc.c

但是依然有报错。

(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common# make clean
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common# make
In file included from /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm_sys.c:5:
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm.h:143:8: error: unknown type name 'HI_S32'
  143 | extern HI_S32 SAMPLE_COMM_VENC_Sentjin(VENC_STREAM_S *pstStream);
      |        ^~~~~~
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm.h:143:40: error: unknown type name 'VENC_STREAM_S'
  143 | extern HI_S32 SAMPLE_COMM_VENC_Sentjin(VENC_STREAM_S *pstStream);
      |                                        ^~~~~~~~~~~~~
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm.h:144:8: error: unknown type name 'HI_S32'
  144 | extern HI_S32 saveStream(VENC_STREAM_S *pstStream);
      |        ^~~~~~
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm.h:144:26: error: unknown type name 'VENC_STREAM_S'
  144 | extern HI_S32 saveStream(VENC_STREAM_S *pstStream);
      |                          ^~~~~~~~~~~~~
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm.h:145:8: error: unknown type name 'HI_VOID'
  145 | extern HI_VOID* vdRTPSendThread(HI_VOID *p);
      |        ^~~~~~~
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm.h:145:33: error: unknown type name 'HI_VOID'
  145 | extern HI_VOID* vdRTPSendThread(HI_VOID *p);
      |                                 ^~~~~~~
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm.h:167:9: error: unknown type name 'u_int32_t'
  167 | typedef u_int32_t netAddressBits;
      |         ^~~~~~~~~
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm.h:297:2: error: unknown type name 'HI_S32'
  297 |  HI_S32 len;
      |  ^~~~~~
make: *** [Makefile:14: /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm_sys.o] Error 1

这个报错 就是 改类型。

我是这么改的。

改的是 sample_comm.h

    12 #define HI_VOID         void
    11 typedef int HI_S32;
    10 typedef unsigned int  u_int32_t;
     9

     5 //extern HI_S32 SAMPLE_COMM_VENC_Sentjin(VENC_STREAM_S *pstStream);
     6 //extern HI_S32 saveStream(VENC_STREAM_S *pstStream);
     7 //
     8 extern HI_S32 SAMPLE_COMM_VENC_Sentjin(ot_venc_stream *pstStream);
     9 extern HI_S32 saveStream(ot_venc_stream *pstStream);
    10
    11 extern HI_VOID* vdRTPSendThread(HI_VOID *p);

编译通过。

(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common# make clean
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common# make
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm_venc.c: In function 'sample_comm_save_frame_to_file':
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm_venc.c:2777:30: warning: passing argument 1 of 'SAMPLE_COMM_VENC_Sentjin' from incompatible pointer type [-Wincompatible-pointer-types]
 2777 |     SAMPLE_COMM_VENC_Sentjin(&stream);
      |                              ^~~~~~~
      |                              |
      |                              ot_venc_stream **
In file included from /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm_venc.c:23:
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm.h:147:56: note: expected 'ot_venc_stream *' but argument is of type 'ot_venc_stream **'
  147 | extern HI_S32 SAMPLE_COMM_VENC_Sentjin(ot_venc_stream *pstStream);
      |                                        ~~~~~~~~~~~~~~~~^~~~~~~~~
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm_venc.c: In function 'sample_comm_venc_get_venc_stream_proc':
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm_venc.c:2787:8: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
 2787 |     if (ret != TD_SUCCESS) {
      |        ^
/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common/../common/sample_comm_venc.c:2744:12: note: 'ret' was declared here
 2744 |     td_s32 ret, fd;
      |            ^~~
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common#
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common#
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common#
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common#
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/common#

然后去编译  sample_venc.c 文件。

依然是有报错。

sample_venc.c:773:12: warning: unused variable 'i' [-Wunused-variable]
  773 |     HI_S32 i;
      |            ^
sample_venc.c: At top level:
sample_venc.c:910:33: error: unknown type name 'VENC_STREAM_S'
  910 | HI_S32 SAMPLE_COMM_VENC_Sentjin(VENC_STREAM_S *pstStream)
      |                                 ^~~~~~~~~~~~~
sample_venc.c:941:19: error: unknown type name 'VENC_STREAM_S'
  941 | HI_S32 saveStream(VENC_STREAM_S *pstStream)
      |                   ^~~~~~~~~~~~~
sample_venc.c: In function 'RtspServer_init':
sample_venc.c:976:9: warning: passing argument 1 of 'strcpy' from incompatible pointer type [-Wincompatible-pointer-types]
  976 |  strcpy(&g_rtp_playload,"G726-32");
      |         ^~~~~~~~~~~~~~~
      |         |
      |         char (*)[20]
In file included from sample_venc.c:7:
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/target/usr/include/string.h:33:15: note: expected 'char * restrict' but argument is of type 'char (*)[20]'
   33 | char *strcpy (char *__restrict, const char *__restrict);
      |               ^
sample_venc.c:985:21: warning: variable 'thdsched' set but not used [-Wunused-but-set-variable]
  985 |  struct sched_param thdsched;

解决: 在这个文件中 依然去改 这个函数。

改的 是 sample_venc.c

    36 /******************************************************************************
    35 * funciton : sent H264 stream
    34 ******************************************************************************/
    33
    32 HI_S32 SAMPLE_COMM_VENC_Sentjin(ot_venc_stream *pstStream)
    31 {
    30     HI_S32 i,flag=0;
    29
    28     for(i=0;i<MAX_RTSP_CLIENT;i++)//have atleast a connect
    27     {
    26         if(g_rtspClients[i].status == RTSP_SENDING)
    25         {
    24             flag = 1;
    23             break;
    22         }
    21     }
    20     if(flag)
    19     {
    18         for (i = 0; i < pstStream->u32PackCount; i++)
    17         {
    16         HI_S32 lens=0,j,lastadd=0,newadd=0,showflap=0;
    15         char sendbuf[320*1024];
    14         //char tmp[640*1024];
    13         lens = pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset;
    12         memcpy(&sendbuf[0],pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,lens);
    11         //printf("lens = %d, count= %d\n",lens,count++);
    10         VENC_Sent(sendbuf,lens);
     9         lens = 0;
     8         }
     7
     6
     5     }
     4     return HI_SUCCESS;
     3 }
     2
     1 HI_S32 saveStream(ot_venc_stream *pstStream)
  942  {
     1     HI_S32 i,j,lens=0;
     2
     3     for(j=0;j<MAX_RTSP_CLIENT;j++)//have atleast a connect
     4     {
     5         if(g_rtspClients[j].status == RTSP_SENDING)
     6         {
     7             for (i = 0; i < pstStream->u32PackCount; i++)
     8             {

重新编译之后 依然是 有错误。

sample_venc.c:773:12: warning: unused variable 'i' [-Wunused-variable]
  773 |     HI_S32 i;
      |            ^
sample_venc.c: In function 'SAMPLE_COMM_VENC_Sentjin':
sample_venc.c:924:31: error: 'ot_venc_stream' has no member named 'u32PackCount'
  924 |      for (i = 0; i < pstStream->u32PackCount; i++)
      |                               ^~
sample_venc.c:929:21: error: 'ot_venc_stream' has no member named 'pstPack'; did you mean 'pack'?
  929 |   lens = pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset;
      |                     ^~~~~~~
      |                     pack
sample_venc.c:929:50: error: 'ot_venc_stream' has no member named 'pstPack'; did you mean 'pack'?
  929 |   lens = pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset;
      |                                                  ^~~~~~~
      |                                                  pack
sample_venc.c:930:33: error: 'ot_venc_stream' has no member named 'pstPack'; did you mean 'pack'?
  930 |   memcpy(&sendbuf[0],pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,lens);
      |                                 ^~~~~~~
      |                                 pack
sample_venc.c:930:63: error: 'ot_venc_stream' has no member named 'pstPack'; did you mean 'pack'?
  930 |   memcpy(&sendbuf[0],pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,lens);
      |                                                               ^~~~~~~
      |                                                               pack
sample_venc.c:926:38: warning: unused variable 'showflap' [-Wunused-variable]
  926 |   HI_S32 lens=0,j,lastadd=0,newadd=0,showflap=0;
      |                                      ^~~~~~~~
sample_venc.c:926:29: warning: unused variable 'newadd' [-Wunused-variable]
  926 |   HI_S32 lens=0,j,lastadd=0,newadd=0,showflap=0;
      |                             ^~~~~~
sample_venc.c:926:19: warning: unused variable 'lastadd' [-Wunused-variable]
  926 |   HI_S32 lens=0,j,lastadd=0,newadd=0,showflap=0;
      |                   ^~~~~~~
sample_venc.c:926:17: warning: unused variable 'j' [-Wunused-variable]
  926 |   HI_S32 lens=0,j,lastadd=0,newadd=0,showflap=0;
      |                 ^
sample_venc.c:938:12: error: 'HI_SUCCESS' undeclared (first use in this function); did you mean 'TD_SUCCESS'?
  938 |     return HI_SUCCESS;
      |            ^~~~~~~~~~

这个错误 也好改,依然是 结构体的问题。

解决:

解释照着 ortp 去改。

改动文件, sample_venc.c

改动如下:

       4 /******************************************************************************
     3 * funciton : sent H264 stream
     2 ******************************************************************************/
     1
  910  HI_S32 SAMPLE_COMM_VENC_Sentjin(ot_venc_stream *pstStream)
     1 {
     2     HI_S32 i,flag=0;
     3
     4     for(i=0;i<MAX_RTSP_CLIENT;i++)//have atleast a connect
     5     {
     6         if(g_rtspClients[i].status == RTSP_SENDING)
     7         {
     8             flag = 1;
     9             break;
    10         }
    11     }
    12     if(flag)
    13     {
    14        // for (i = 0; i < pstStream->u32PackCount; i++)
    15         for (i = 0; i < pstStream->pack_cnt; i++)
    16         {
    17         HI_S32 lens=0,j,lastadd=0,newadd=0,showflap=0;
    18         char sendbuf[320*1024];
    19         //char tmp[640*1024];
    20     //  lens = pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset;
    21     //  memcpy(&sendbuf[0],pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,lens);
    22         lens = pstStream->pack[i].len-pstStream->pack[i].offset;
    23         memcpy(&sendbuf[0],pstStream->pack[i].addr+pstStream->pack[i].offset,lens);
    24         //printf("lens = %d, count= %d\n",lens,count++);
    25         VENC_Sent(sendbuf,lens);
    26         lens = 0;
    27         }
    28
    29
    30     }
    31     return TD_SUCCESS;
    32 }
  


4 HI_S32 saveStream(ot_venc_stream *pstStream)
     5 {
     6     HI_S32 i,j,lens=0;
     7
     8     for(j=0;j<MAX_RTSP_CLIENT;j++)//have atleast a connect
     9     {
    10         if(g_rtspClients[j].status == RTSP_SENDING)
    11         {
    12           //  for (i = 0; i < pstStream->u32PackCount; i++)
    13             for (i = 0; i < pstStream->pack_cnt; i++)
    14             {
    15                 RTPbuf_s *p = (RTPbuf_s *)malloc(sizeof(RTPbuf_s));
    16                 INIT_LIST_HEAD(&(p->list));
    17
    18                 lens = pstStream->pack[i].len-pstStream->pack[i].offset;
    19                 p->buf = (char *)malloc(lens);
    20                 p->len = lens;
    21                 memcpy(p->buf,pstStream->pack[i].addr+pstStream->pack[i].offset,lens);
    22
    23                 list_add_tail(&(p->list),&RTPbuf_head);
    24                 count++;
    25                 //printf("count = %d\n",count);
    26             }
    27         }
    28     }
    29
    30     return TD_SUCCESS;
    31 }
    32

重新编译 但是依然是报错。

sample_venc.c:140:18: warning: 'gs_RtpPid' defined but not used [-Wunused-variable]
  140 | static pthread_t gs_RtpPid;
      |                  ^~~~~~~~~
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/bin/../lib/gcc/arm-linux-musleabi/10.3.0/../../../../arm-linux-musleabi/bin/ld: /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_
linux/source/mpp/sample/venc/../common/sample_comm_isp.o:(.bss.au_hdr+0x0): multiple definition of `au_hdr'; /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sam
ple/venc/../common/sample_comm_sys.o:(.bss.au_hdr+0x0): first defined here
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/bin/../lib/gcc/arm-linux-musleabi/10.3.0/../../../../arm-linux-musleabi/bin/ld: /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_
linux/source/mpp/sample/venc/../common/sample_comm_isp.o:(.bss.fu_hdr+0x0): multiple definition of `fu_hdr'; /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sam
ple/venc/../common/sample_comm_sys.o:(.bss.fu_hdr+0x0): first defined here
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/bin/../lib/gcc/arm-linux-musleabi/10.3.0/../../../../arm-linux-musleabi/bin/ld: /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_
linux/source/mpp/sample/venc/../common/sample_comm_isp.o:(.bss.fu_ind+0x0): multiple definition of `fu_ind'; /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sam
ple/venc/../common/sample_comm_sys.o:(.bss.fu_ind+0x0): first defined here
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/bin/../lib/gcc/arm-linux-musleabi/10.3.0/../../../../arm-linux-musleabi/bin/ld: /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_
linux/source/mpp/sample/venc/../common/sample_comm_isp.o:(.bss.nalu_hdr+0x0): multiple definition of `nalu_hdr'; /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp
/sample/venc/../common/sample_comm_sys.o:(.bss.nalu_hdr+0x0): first defined here
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/bin/../lib/gcc/arm-linux-musleabi/10.3.0/../../../../arm-linux-musleabi/bin/ld: /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_
linux/source/mpp/sample/venc/../common/sample_comm_isp.o:(.bss.rtp_hdr+0x0): multiple definition of `rtp_hdr'; /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/s
ample/venc/../common/sample_comm_sys.o:(.bss.rtp_hdr+0x0): first defined here
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/bin/../lib/gcc/arm-linux-musleabi/10.3.0/../../../../arm-linux-musleabi/bin/ld: /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_
linux/source/mpp/sample/venc/../common/sample_comm_vi.o:(.bss.au_hdr+0x0): multiple definition of `au_hdr'; /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/samp
le/venc/../common/sample_comm_sys.o:(.bss.au_hdr+0x0): first defined here
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/bin/../lib/gcc/arm-linux-musleabi/10.3.0/../../../../arm-linux-musleabi/bin/ld: /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_
linux/source/mpp/sample/venc/../common/sample_comm_vi.o:(.bss.fu_hdr+0x0): multiple definition of `fu_hdr'; /home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/samp
le/venc/../common/sample_comm_sys.o:(.bss.fu_hdr+0x0): first defined here
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/bin/../lib/gcc/arm-linux-musleabi/10.3.0/../../../../arm-linux-musl

解决:

最终在 sample_comm.h 中   注释掉定义。

    18 typedef enum
    17 {
    16     RTP_UDP,
    15     RTP_TCP,
    14     RAW_UDP
    13 }StreamingMode;
    12
    11
    10 // RTP_FIXED_HEADER  *rtp_hdr;
     9 // NALU_HEADER        *nalu_hdr;
     8 // FU_INDICATOR   *fu_ind;
     7 // FU_HEADER          *fu_hdr;
     6 // AU_HEADER            *au_hdr;
     5
     4
     3 extern char g_rtp_playload[20];//脛卢脠脧G726-32
     2 extern int   g_audio_rate;//脛卢脠脧8000
     1
  244  typedef enum
     1 {
     2     RTSP_IDLE = 0,
     3     RTSP_CONNECTED = 1,
     4     RTSP_SENDING = 2,

然后在  sample_venc.c 中 ,加上 static .

    11
    10 #if RTSP_ENABLE
     9
     8 static RTP_FIXED_HEADER        *rtp_hdr;
     7 static NALU_HEADER      *nalu_hdr;
     6 static  FU_INDICATOR    *fu_ind;
     5 static  FU_HEADER       *fu_hdr;
     4
     3
     2 RTSP_CLIENT g_rtspClients[MAX_RTSP_CLIENT];
     1
  118  int g_nSendDataChn = -1;
E    1 pthread_mutex_t g_mutex;     ■ Unknown type name 'pthread_mutex_t'
E    2 pthread_cond_t  g_cond;     ■ Unknown type name 'pthread_cond_t'; did you mean 'thread_contrl'? (fix available)
E    3 pthread_mutex_t g_sendmutex; 

最终编译通过。

      |         |
      |         char (*)[20]
In file included from sample_venc.c:7:
/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc/target/usr/include/string.h:33:15: note: expected 'char * restrict' but argument is of type 'char (*)[20]'
   33 | char *strcpy (char *__restrict, const char *__restrict);
      |               ^
sample_venc.c:988:21: warning: variable 'thdsched' set but not used [-Wunused-but-set-variable]
  988 |  struct sched_param thdsched;
      |                     ^~~~~~~~
sample_venc.c:975:6: warning: unused variable 'i' [-Wunused-variable]
  975 |  int i;
      |      ^
sample_venc.c: In function 'VENC_Sent':
sample_venc.c:904:1: warning: control reaches end of non-void function [-Wreturn-type]
  904 | }
      | ^
At top level:
sample_venc.c:139:18: warning: 'gs_RtpPid' defined but not used [-Wunused-variable]
  139 | static pthread_t gs_RtpPid;
      |                  ^~~~~~~~~
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc#
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc#
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc#
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc#
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc#
(myenv) root@topeet:/home/topeet/source_code/Hi3516CV610_SDK_V1.0.1.0/smp/a7_linux/source/mpp/sample/venc#

接下来 放到 板子上 测试一下 , 程序能不能运行。

先不管 vlc .

居然没有报错。

~ # ./sample_venc 0
RTSP:-----Init Rtsp server
wrap online is 1, buf line is 128, buf size is 458544

[MPP] Version: [HI3516CV610_MPP_V1.0.1.0 B040 Release], Build Time[Sep  7 2024, 17:51:12]

linear mode
===================================================================================
vi_pipe:0,== SC4336P_MIPI_27Minput_2lane_10bit_630Mbps_2560x1440_30fps Init OK! ==
===================================================================================
ISP Dev 0 running !
please input choose gop mode!
         0) normal p.
         1) dual p.
         2) smart p.
random: crng init done
0
please input choose rc mode!
         c) cbr.
         v) vbr.
         b) abr.
         a) avbr.
         x) cvbr.
         q) qvbr.
         f) fix_qp
c
please press twice ENTER to exit this sample


program exit normally!
~ #

继续测试,当我 打开 vlc 时 出现这个报错。

linear mode
===================================================================================
vi_pipe:0,== SC4336P_MIPI_27Minput_2lane_10bit_630Mbps_2560x1440_30fps Init OK! ==
===================================================================================
ISP Dev 0 running !
please input choose gop mode!
         0) normal p.
         1) dual p.
         2) smart p.
random: crng init done
0
please input choose rc mode!
         c) cbr.
         v) vbr.
         b) abr.
         a) avbr.
         x) cvbr.
         q) qvbr.
         f) fix_qp
c
please press twice ENTER to exit this sample
<<<<RTSP Client 192.168.1.114 Connected...
RTSP:-----Create Client 192.168.1.114
<<<<<SETUP rtsp://192.168.1.121:554/stream_chn.h264 RTSP/1.0
CSeq: 0
Transport: RTP/AVP;unicast;client_port=9284-9285


--------------------------------------------
>>>>>RTSP/1.0 200 OK
CSeq: 0
Date: Thu, Jan 01 1970 00:01:10 GMT
Transport: RTP/AVP;unicast;destination=;client_port=9284-9285;server_port=53255-53511
Session: 1000

<<<<<PLAY rtsp://192.168.1.121:554/stream=0 RTSP/1.0
CSeq: 1
Session: 1000

: RTP/AVP;unicast;client_port=9284-9285


--------------------------------------------
>>>>>RTSP/1.0 200 OK
CSeq: 1
Date: Thu, Jan 01 1970 00:01:10 GMT
Range: npt=0.000-
Session: 1000
RTP-Info: url=rtsp:///;seq=0

udp up
Start Play
Segmentation fault
~ #

感觉跟我之前的重复定义 是 有关的。

这个报错解决不了了。

但是我发现一个 重要的错误。

注意:

他可以这样写。

但是我必须这样写。

因为我这里 本身已经是指针了。

报错终于改好了。

改的是 ,去掉头文件的重复的定义,

并且 在 sample_venc.c 中的函数中。

改了这些 结构体。

出现过 , pstStream 的地方 ,都要做相应的改动。

最终测试 结果可以了。


>>>>>RTSP/1.0 200 OK
CSeq: 3
Date: Thu, Jan 01 1970 00:03:30 GMT
Content-Type: application/sdp
Content-length: 357
Content-Base: rtsp://client_port=62728-62/stream_chn0.h264/

v=0
o=StreamingServer 3331435948 1116907222000 IN IP4 client_port=62728-62
s=H.264
c=IN IP4 0.0.0.0
t=0 0
a=control:*
m=video 0 RTP/AVP 96
a=control:trackID=0
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; sprop-parameter-sets=AAABBCCC
m=audio 0 RTP/AVP 97
a=control:trackID=1
a=rtpmap:97 G726-32/8000/1
a=fmtp:97 packetization-mode=1

<<<<<SETUP rtsp://client_port=62728-62/stream_chn0.h264/trackID=0 RTSP/1.0
CSeq: 4
User-Agent: LibVLC/2.2.6 (LIVE555 Streaming Media v2016.02.22)
Transport: RTP/AVP;unicast;client_port=53120-53121


--------------------------------------------client_port=62728-62
>>>>>RTSP/1.0 200 OK
CSeq: 4
Date: Thu, Jan 01 1970 00:03:30 GMT
Transport: RTP/AVP;unicast;destination=client_port=62728-62;client_port=53120-53121;server_port=53255-53511
Session: 1002

<<<<<SETUP rtsp://client_port=62728-62/stream_chn0.h264/trackID=1 RTSP/1.0
CSeq: 5
User-Agent: LibVLC/2.2.6 (LIVE555 Streaming Media v2016.02.22)
Transport: RTP/AVP;unicast;client_port=53122-53123
Session: 1002


--------------------------------------------client_port=53120-53
>>>>>RTSP/1.0 200 OK
CSeq: 5
Date: Thu, Jan 01 1970 00:03:30 GMT
Transport: RTP/AVP;unicast;destination=client_port=53120-53;client_port=53122-53123;server_port=53255-53511
Session: 1002

<<<<<PLAY rtsp://client_port=62728-62/stream_chn0.h264/ RTSP/1.0
CSeq: 6
User-Agent: LibVLC/2.2.6 (LIVE555 Streaming Media v2016.02.22)
Session: 1002
Range: npt=0.000-

;client_port=53122-53123
Session: 1002


--------------------------------------------client_port=62728-62
>>>>>RTSP/1.0 200 OK
CSeq: 6
Date: Thu, Jan 01 1970 00:03:30 GMT
Range: npt=0.000-
Session: 1002
RTP-Info: url=rtsp://client_port=62728-62/stream_chn0.h264;seq=0

udp up
Start Play
<<<<<TEARDOWN rtsp://client_port=62728-62/stream_chn0.h264/ RTSP/1.0
CSeq: 7
User-Agent: LibVLC/2.2.6 (LIVE555 Streaming Media v2016.02.22)
Session: 1002

 npt=0.000-

;client_port=53122-53123
Session: 1002


>>>>>RTSP/1.0 200 OK
CSeq: 7
Date: Thu, Jan 01 1970 00:03:50 GMT
Session: 1002

RTSP:-----Exit Client 192.168.1.114
^C^Cprogram exit normally!
~ # ^C

将 ortp 可以的代码 +  rtsp 可以的代码 打包  保存到网盘中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2379714.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ElasticSearch-集群

本篇文章依据ElasticSearch权威指南进行实操和记录 1&#xff0c;空集群 即不包含任何节点的集群 集群大多数分为两类&#xff0c;主节点和数据节点 主节点 职责&#xff1a;主节点负责管理集群的状态&#xff0c;例如分配分片、添加和删除节点、监控节点故障等。它们不直接…

一文掌握工业相机选型计算

目录 一、基本概念 1.1 物方和像方 1.2 工作距离和视场 1.3 放大倍率 1.4 相机芯片尺寸 二、公式计算 三、实例应用 一、基本概念 1.1 物方和像方 在光学领域&#xff0c;物方&#xff08;Object Space&#xff09;是与像方&#xff08;Image Space&#xff09;相对的…

LabVIEW机械振动信号分析与故障诊断

利用 LabVIEW 开发机械振动信号分析与故障诊断系统&#xff0c;融合小波变换、时频分布、高阶统计量&#xff08;双谱&#xff09;等先进信号处理技术&#xff0c;实现对齿轮、发动机等机械部件的非平稳非高斯振动信号的特征提取与故障诊断。系统通过虚拟仪器技术将理论算法转化…

【Spring】Spring中的适配器模式

欢迎来到啾啾的博客&#x1f431;。 记录学习点滴。分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 欢迎评论交流&#xff0c;感谢您的阅读&#x1f604;。 目录 适配器模式Spring MVC的适配器模式 适配器模式 适配器模式&#xff08;Adapter Pattern&a…

2、ubuntu系统配置OpenSSH | 使用vscode或pycharm远程连接

1、OpenSSH介绍 OpenSSH&#xff08;Open Secure Shell&#xff09;是一套基于SSH协议的开源工具&#xff0c;用于在计算机网络中提供安全的加密通信。它被广泛用于远程系统管理、文件传输和网络服务的安全隧道搭建&#xff0c;是保护网络通信免受窃听和攻击的重要工具。 1.1…

RPC与SOAP的区别

一.RPC&#xff08;远程过程调用&#xff09;和SOAP&#xff08;简单对象访问协议&#xff09;均用于实现分布式系统中的远程通信&#xff0c;但两者在设计理念、协议实现及应用场景上存在显著差异。 二.对比 1.设计理念 2.协议规范 3.技术特性 4.典型应用场景 5.总结 三.总结…

Day11-苍穹外卖(数据统计篇)

前言&#xff1a; 今天写day11的内容&#xff0c;主要讲了四个统计接口的制作。看起来内容较多&#xff0c;其实代码逻辑都是相似的&#xff0c;这里我们过一遍。 今日所学&#xff1a; Apache ECharts营业额统计用户统计订单统计销量排行统计 1. Apache ECharts 1.1 介绍 A…

Tomcat简述介绍

文章目录 Web服务器Tomcat的作用Tomcat分析目录结构 Web服务器 Web服务器的作用是接收客户端的请求&#xff0c;给客户端作出响应。 知名Java Web服务器 Tomcat&#xff08;Apache&#xff09;&#xff1a;用来开发学习使用&#xff1b;免费&#xff0c;开源JBoss&#xff0…

《从零开始:Spring Cloud Eureka 配置与服务注册全流程》​

关于Eureka的学习&#xff0c;主要学习如何搭建Eureka&#xff0c;将order-service和product-service都注册到Eureka。 1.为什么使用Eureka? 我在实现一个查询订单功能时&#xff0c;希望可以根据订单中productId去获取对应商品的详细信息&#xff0c;但是产品服务和订单服…

FPGA学习知识(汇总)

1. wire与reg理解&#xff0c;阻塞与非阻塞 2. 时序取值&#xff0c;时钟触发沿向左看 3. ip核/setup debug 添加 ila 一、ila使用小技巧 二、同步复位、异步复位和异步复位同步释放 设计复位设计&#xff0c;尽量使用 异步复位同步释放&#xff1b;尽管该方法仍然对毛刺敏感…

Redisson分布式锁-锁的可重入、可重试、WatchDog超时续约、multLock联锁(一文全讲透,超详细!!!)

本文涉及到使用Redis实现基础分布式锁以及Lua脚本的内容&#xff0c;如有需要可以先参考博主的上一篇文章&#xff1a;Redis实现-优惠卷秒杀(基础版本) 一、功能介绍 (1)前面分布式锁存在的问题 在JDK当中就存在一种可重入锁ReentrantLock&#xff0c;可重入指的是在同一线…

语言模型:AM-Thinking-v1 能和大参数语言模型媲美的 32B 单卡推理模型

介绍 a-m-team 是北科 &#xff08;Ke.com&#xff09; 的一个内部团队&#xff0c;致力于探索 AGI 技术。这是一个专注于增强推理能力的 32B 密集语言模型。 a-m-team / AM-Thinking-v1 是其旗下的一个语言模型&#xff0c;采用低成本的方式能实现和大参数模型媲美。 DeepSe…

ChatGPT:OpenAI Codex—一款基于云的软件工程 AI 代理,赋能 ChatGPT,革新软件开发模式

ChatGPT&#xff1a;OpenAI Codex—一款基于云的软件工程 AI 代理&#xff0c;赋能 ChatGPT&#xff0c;革新软件开发模式 导读&#xff1a;2025年5月16日&#xff0c;OpenAI 发布了 Codex&#xff0c;一个基于云的软件工程 AI 代理&#xff0c;它集成在 ChatGPT 中&#xff0c…

智能视觉检测技术:制造业质量管控的“隐形守护者”

在工业4.0浪潮的推动下&#xff0c;制造业正经历一场以智能化为核心的变革。传统人工质检模式因效率低、误差率高、成本高昂等问题&#xff0c;逐渐难以满足现代生产对高精度、高速度的需求。智能视觉检测技术作为人工智能与机器视觉融合的产物&#xff0c;正成为制造业质量管控…

利用html制作简历网页和求职信息网页

前言 大家好&#xff0c;我是maybe。今天下午初步学习了html的基础知识。做了两个小网页&#xff0c;一个网页是简历网页&#xff0c;一个网页是求职信息填写网页。跟大家分享一波~ 说明:我不打算上传图片。所以如果有朋友按照我的代码运行网页&#xff0c;会出现一个没有图片…

卷积神经网络进阶:转置卷积与棋盘效应详解

【内容摘要】 本文深入解析卷积神经网络中的转置卷积&#xff08;反卷积&#xff09;技术&#xff0c;重点阐述标准卷积与转置卷积的计算过程、转置卷积的上采样作用&#xff0c;以及其常见问题——棋盘效应的产生原因与解决方法&#xff0c;为图像分割、超分辨率等任务提供理论…

2025年5月13日第一轮

1.百词斩 2.安全状态和死锁 3.银行家算法和状态图 4.Vue运行 5.英语听力 6.词汇 7.英语 长篇:数学竞赛 8.数学 间断点类型和数量 The rapid development of artificial intelligence has led to widerspareasd concreasns about job displacemant.As AI technology conti…

小结:Android系统架构

https://developer.android.com/topic/architecture?hlzh-cn Android系统的架构&#xff0c;分为四个主要层次&#xff1a;应用程序层、应用框架层、库和运行时层以及Linux内核层。&#xff1a; 1. 应用程序层&#xff08;Applications&#xff09; 功能&#xff1a;这一层包…

基于C#的MQTT通信实战:从EMQX搭建到发布订阅全解析

MQTT(Message Queueing Telemetry Transport) 消息队列遥测传输&#xff0c;在物联网领域应用的很广泛&#xff0c;它是基于Publish/Subscribe模式&#xff0c;具有简单易用&#xff0c;支持QoS&#xff0c;传输效率高的特点。 它被设计用于低带宽&#xff0c;不稳定或高延迟的…

ISP中拖影问题的处理

有时候会出现如下的阴影问题该如何处理呢&#xff1f;本文将提供几个思路。 1、降低曝光时间 如果曝光时间过大&#xff0c;会统计整个曝光时间内的图像信息&#xff0c;就会导致拖影的产生&#xff0c;这个时候可以考虑降低一下曝光时间。 2、时域降噪过大 只要明白时域降噪…