├── .gitignore ├── Client ├── Makefile ├── RTSPClient.c ├── rtcp.c ├── rtcp.h ├── rtp.c └── videoQueue.c ├── LICENSE ├── README ├── README.md └── Server ├── Makefile ├── include ├── camera.h ├── hp_common.h ├── hp_fpn.h ├── hp_ipc.h ├── hp_sys.h ├── hp_venc.h ├── hp_vi.h ├── hp_vpss.h ├── public_api.h └── rtsp_server.h ├── readme.txt └── src ├── Makefile ├── camera.c ├── hp_fpn.c ├── hp_ipc.c ├── hp_sys.c ├── hp_venc.c ├── hp_vi.c ├── hp_vpss.c ├── rtsp_server.c └── sensor ├── ps3210k_api.c ├── ps3210k_api.h └── public_api.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | 3 | -------------------------------------------------------------------------------- /Client/Makefile: -------------------------------------------------------------------------------- 1 | SRC=$(wildcard *.c) 2 | OBJ=$(SRC:%.c=%.o) 3 | APP=main 4 | $SRC_UTILS=$(wildcard ../utils/*.c) 5 | OBJ_UTILS=$(SRC_UTILS:%.c=%.o) 6 | 7 | CFLAGS=-I../utils -I. -Iinclude -lpthread -lrt -lm 8 | 9 | all: $(APP) 10 | $(APP) : $(OBJ_UTILS) $(OBJ) 11 | $(CC) $(CFLAGS) -o $@ $^ 12 | 13 | $(OBJ) : %.o:%.c 14 | $(CC) $(CFLAGS) -c $^ -o $@ 15 | 16 | $(OBJ_UTILS) : %.o:%.c 17 | $(CC) $(CFLAGS) -c $^ -o $@ 18 | 19 | 20 | rm -f $(OBJ) 21 | 22 | .PHONY: clean 23 | clean: 24 | @rm -f $(APP) 25 | @rm -f $(OBJ) 26 | 27 | -------------------------------------------------------------------------------- /Client/RTSPClient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | // #include "./dbg_printf.h" 24 | 25 | #define OUR_DEV 26 | //#define HOME 27 | typedef void * HANDLE; 28 | #ifdef OUR_DEV 29 | #define URL "192.168.1.95" 30 | #define DEF_RTSP_URL "rtsp://192.168.1.95/264.264" 31 | // #define DEF_RTSP_URL "rtsp://192.168.0.28/trackID1" 32 | // #define DEF_RTSP_URL "rtsp://192.168.2.112/264.264" 33 | #else 34 | #define DEF_RTSP_URL "rtsp://192.168.0.29/" 35 | #endif 36 | 37 | #define RTSP_PORT 554 38 | #define PRG_NAME "main" 39 | #define UDP_RECV_PORT0 1023 40 | #define UDP_RECV_PORT1 1024 41 | #define max( a, b ) ( a > b ? a : b ) 42 | 43 | typedef enum RTSP_STAT 44 | { 45 | RTSP_NONE = 0, 46 | RTSP_OPTION, 47 | RTSP_DESCRIPT, 48 | RTSP_SETUP, 49 | RTSP_PLAY, 50 | RTSP_GETPARM, 51 | RTSP_KEEP, 52 | RTSP_PAUSE, 53 | RTSP_STOP 54 | }RTPS_STAT_E; 55 | 56 | typedef enum LINK_STAT 57 | { 58 | LINK_DISCONNECT = 0, 59 | LINK_CONNECTING, 60 | LINK_CONNECTED 61 | }LINK_STAT_E; 62 | 63 | typedef enum TRANSPORT 64 | { 65 | TRANS_UDP = 0, 66 | TRANS_TCP, 67 | TRANS_RAW 68 | }TRANSPORT_E; 69 | 70 | #define MAGIC_NUM 0x1a2b4c3d 71 | #define RTSP_INVALID( obj ) ( obj->magic != MAGIC_NUM ) 72 | 73 | typedef struct tagRtspClient 74 | { 75 | unsigned int magic; 76 | int fd; //rtsp web socket 77 | TRANSPORT_E stream_type; // 码流方式 78 | int recv_fd[2]; // 79 | int recv_port[2]; // 监听端口 80 | char rtsp_url[128]; // rtsp request url 81 | char server_ip[128]; 82 | int server_port[2]; 83 | char session[20]; 84 | char authName[64]; 85 | char authPwd[64]; 86 | int support_cmd; 87 | int bQuit; 88 | int trackId; 89 | time_t tou; 90 | RTPS_STAT_E stat; 91 | LINK_STAT_E link; 92 | int CSeq; 93 | void *recv_buf; 94 | int maxBufSize; 95 | HANDLE Filter; 96 | HANDLE Vdec; 97 | HANDLE rtp; 98 | pthread_t threadID; 99 | // struct list_head list; 100 | }RtspClient, *PVHRtspClient; 101 | 102 | #define SOCK_ERROR() do{\ 103 | if( len <= 0 )\ 104 | {\ 105 | fd = 0;\ 106 | printf("sock error, %s!\r\n", strerror(errno));\ 107 | break;\ 108 | }\ 109 | }while(0) 110 | 111 | /* TCP and UDP API*/ 112 | int sock_listen( int port, const char *ipbind, int backlog ) 113 | { 114 | struct sockaddr_in my_addr; 115 | int fd, tmp = 1; 116 | 117 | fd = socket(AF_INET,SOCK_STREAM,0); 118 | if (fd < 0) 119 | return -1; 120 | 121 | setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); 122 | 123 | memset(&my_addr, 0, sizeof(my_addr)); 124 | my_addr.sin_family = AF_INET; 125 | my_addr.sin_port = htons ((short)port); 126 | if( ipbind != NULL ) { 127 | inet_aton( ipbind, & my_addr.sin_addr ); 128 | } else { 129 | my_addr.sin_addr.s_addr = htonl (INADDR_ANY); 130 | } 131 | 132 | if( 0 == bind (fd, (struct sockaddr *) &my_addr, sizeof (my_addr)) ) 133 | { 134 | if( 0 == listen(fd, backlog) ) { 135 | return fd; 136 | } 137 | } 138 | close(fd); 139 | return -1; 140 | } 141 | 142 | 143 | int sock_dataready( int fd, int tout ) 144 | { 145 | fd_set rfd_set; 146 | struct timeval tv, *ptv; 147 | int nsel; 148 | 149 | FD_ZERO( &rfd_set ); 150 | FD_SET( fd, &rfd_set ); 151 | if ( tout == -1 ) 152 | { 153 | ptv = NULL; 154 | } 155 | else 156 | { 157 | tv.tv_sec = 0; 158 | tv.tv_usec = tout * 1000; 159 | ptv = &tv; 160 | } 161 | nsel = select( fd+1, &rfd_set, NULL, NULL, ptv ); 162 | if ( nsel > 0 && FD_ISSET( fd, &rfd_set ) ) 163 | return 1; 164 | return 0; 165 | } 166 | 167 | 168 | int sock_udp_bind( int port ) 169 | { 170 | struct sockaddr_in my_addr; 171 | int tmp=0; 172 | int udp_fd; 173 | 174 | // signal init, to avoid app quit while pipe broken 175 | // signal(SIGPIPE, SIG_IGN); 176 | 177 | if ( (udp_fd = socket( AF_INET, SOCK_DGRAM, 0 )) >= 0 ) 178 | { 179 | setsockopt( udp_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); 180 | 181 | memset(&my_addr, 0, sizeof(my_addr)); 182 | my_addr.sin_family = AF_INET; 183 | my_addr.sin_port = htons ((short)port); 184 | my_addr.sin_addr.s_addr = htonl (INADDR_ANY); // get_ifadapter_ip("eth0",NULL); 185 | 186 | if (bind ( udp_fd, (struct sockaddr *) &my_addr, sizeof (my_addr)) < 0) 187 | { 188 | close( udp_fd ); 189 | udp_fd = -EIO; 190 | } 191 | } 192 | return udp_fd; 193 | } 194 | 195 | int sock_udp_send( const char *ip, int port, const void* msg, int len ) 196 | { 197 | // SOCKADDR_IN udp_addr; 198 | struct sockaddr_in udp_addr; 199 | int sockfd, ret; 200 | 201 | sockfd = socket( AF_INET, SOCK_DGRAM, 0 ); 202 | if( sockfd <= 0 ) return -1; 203 | 204 | //setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); 205 | 206 | memset( & udp_addr, 0, sizeof(udp_addr) ); 207 | udp_addr.sin_family = AF_INET; 208 | inet_aton( ip, &udp_addr.sin_addr ); 209 | udp_addr.sin_port = htons( (short)port ); 210 | 211 | ret = sendto( sockfd, msg, len, 0, (const struct sockaddr *) & udp_addr, sizeof(udp_addr) ); 212 | close( sockfd ); 213 | return ret; 214 | } 215 | 216 | static sock_read( int fd , char *buf, int maxBuf ) 217 | { 218 | return read( fd, buf, maxBuf ); 219 | } 220 | 221 | int sock_connect( const char *host, int port ) 222 | { 223 | struct sockaddr_in destaddr; 224 | struct hostent *hp; 225 | int fd = 0; 226 | 227 | memset( & destaddr, 0, sizeof(destaddr) ); 228 | destaddr.sin_family = AF_INET; 229 | destaddr.sin_port = htons( (short)port ); 230 | if ((inet_aton(host, & destaddr.sin_addr)) == 0) 231 | { 232 | hp = gethostbyname(host); 233 | if(! hp) return -EINVAL; 234 | memcpy (& destaddr.sin_addr, hp->h_addr, sizeof(destaddr.sin_addr)); 235 | } 236 | 237 | fd = socket(PF_INET, SOCK_STREAM, 0); 238 | if (fd < 0) return -EIO; 239 | 240 | if ( connect(fd, (struct sockaddr *)&destaddr, sizeof(destaddr)) < 0 ) 241 | { 242 | close( fd ); 243 | return -EIO; 244 | } 245 | return fd; 246 | } 247 | 248 | static const char* to_b64 = 249 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 250 | "abcdefghijklmnopqrstuvwxyz" 251 | "0123456789+/"; 252 | 253 | /* encode 72 characters per line */ 254 | #define CHARS_PER_LINE 72 255 | 256 | typedef unsigned char byte; 257 | 258 | /* return value: 259 | * >0: encoded string length, -1 buf too small 260 | * Encoded string is terminated by '\0'. 261 | */ 262 | int str_b64enc(const char *src, char *buf, int bufsize ) 263 | { 264 | int size = strlen( src ); 265 | int div = size / 3; 266 | int rem = size % 3; 267 | int chars = div*4 + rem + 1; 268 | int newlines = (chars + CHARS_PER_LINE - 1) / CHARS_PER_LINE; 269 | int outsize = chars + newlines; 270 | const byte* data = (const byte *)src; 271 | byte* enc = (byte *)buf; 272 | 273 | if ( bufsize < outsize + 1 ) return -1; 274 | chars = 0; 275 | while (div > 0) 276 | { 277 | enc[0] = to_b64[ (data[0] >> 2) & 0x3f]; 278 | enc[1] = to_b64[((data[0] << 4) & 0x30) + ((data[1] >> 4) & 0xf)]; 279 | enc[2] = to_b64[((data[1] << 2) & 0x3c) + ((data[2] >> 6) & 0x3)]; 280 | enc[3] = to_b64[ data[2] & 0x3f]; 281 | data += 3; 282 | enc += 4; 283 | div--; 284 | chars += 4; 285 | if (chars == CHARS_PER_LINE) 286 | { 287 | chars = 0; 288 | // *(enc++) = '\n'; /* keep the encoded string in single line */ 289 | } 290 | } 291 | 292 | switch (rem) 293 | { 294 | case 2: 295 | enc[0] = to_b64[ (data[0] >> 2) & 0x3f]; 296 | enc[1] = to_b64[((data[0] << 4) & 0x30) + ((data[1] >> 4) & 0xf)]; 297 | enc[2] = to_b64[ (data[1] << 2) & 0x3c]; 298 | enc[3] = '='; 299 | enc += 4; 300 | chars += 4; 301 | break; 302 | case 1: 303 | enc[0] = to_b64[ (data[0] >> 2) & 0x3f]; 304 | enc[1] = to_b64[ (data[0] << 4) & 0x30]; 305 | enc[2] = '='; 306 | enc[3] = '='; 307 | enc += 4; 308 | chars += 4; 309 | break; 310 | } 311 | 312 | *enc = '\0'; 313 | return strlen(buf); // exclude the tail '\0' 314 | } 315 | 316 | /* 317 | * decode a base64 encoded string. 318 | * return -1: bufsize too small, \ 319 | * 0: string content error, 320 | * > 0: decoded string (null terminated). 321 | */ 322 | int str_b64dec(const char* string, char *buf, int bufsize) 323 | { 324 | register int length = string ? strlen(string) : 0; 325 | register byte* data = (byte *)buf; 326 | 327 | /* do a format verification first */ 328 | if (length > 0) 329 | { 330 | register int count = 0, rem = 0; 331 | register const char* tmp = string; 332 | 333 | while (length > 0) 334 | { 335 | register int skip = strspn(tmp, to_b64); 336 | count += skip; 337 | length -= skip; 338 | tmp += skip; 339 | if (length > 0) 340 | { 341 | register int i, vrfy = strcspn(tmp, to_b64); 342 | 343 | for (i = 0; i < vrfy; i++) 344 | { 345 | if (isspace(tmp[i])) continue; 346 | if (tmp[i] == '=') 347 | { 348 | /* we should check if we're close to the end of the string */ 349 | if ( (rem = count % 4) < 2 ) 350 | /* rem must be either 2 or 3, otherwise no '=' should be here */ 351 | return 0; 352 | /* end-of-message recognized */ 353 | break; 354 | } 355 | else 356 | { 357 | /* Invalid padding character. */ 358 | return 0; 359 | } 360 | } 361 | length -= vrfy; 362 | tmp += vrfy; 363 | } 364 | } 365 | if ( bufsize < (count/4 * 3 + (rem ? (rem-1) : 0)) ) 366 | return -1; 367 | 368 | if (count > 0) 369 | { 370 | register int i, qw = 0; 371 | 372 | length = strlen(string); 373 | for (i = 0; i < length; i++) 374 | { 375 | register char ch = string[i]; 376 | register byte bits; 377 | 378 | if (isspace(ch)) continue; 379 | 380 | bits = 0; 381 | if ((ch >= 'A') && (ch <= 'Z')) 382 | { 383 | bits = (byte) (ch - 'A'); 384 | } 385 | else if ((ch >= 'a') && (ch <= 'z')) 386 | { 387 | bits = (byte) (ch - 'a' + 26); 388 | } 389 | else if ((ch >= '0') && (ch <= '9')) 390 | { 391 | bits = (byte) (ch - '0' + 52); 392 | } 393 | else if (ch == '=') 394 | break; 395 | 396 | switch (qw++) 397 | { 398 | case 0: 399 | data[0] = (bits << 2) & 0xfc; 400 | break; 401 | case 1: 402 | data[0] |= (bits >> 4) & 0x03; 403 | data[1] = (bits << 4) & 0xf0; 404 | break; 405 | case 2: 406 | data[1] |= (bits >> 2) & 0x0f; 407 | data[2] = (bits << 6) & 0xc0; 408 | break; 409 | case 3: 410 | data[2] |= bits & 0x3f; 411 | break; 412 | } 413 | if (qw == 4) 414 | { 415 | qw = 0; 416 | data += 3; 417 | } 418 | } 419 | data += qw; 420 | *data = '\0'; 421 | } 422 | } 423 | return data - (unsigned char *)buf; 424 | } 425 | 426 | int strstartwith(const char *string, const char *prefix, int minmatch, char ** pleft) 427 | { 428 | int len = strlen(prefix); 429 | int n = strlen( string ); 430 | if ( n < len && n >=minmatch && minmatch ) len = n; 431 | 432 | if( 0 == strncmp(string, prefix, len) ) { 433 | if(pleft) *pleft = (char*)(string + len); 434 | return 1; 435 | } 436 | if(pleft) *pleft = NULL; 437 | return 0; 438 | } 439 | 440 | int stridxinargs( const char *key, int minmatch,...) 441 | { 442 | va_list va; 443 | char *matcharg; 444 | int matched_arg = -1; 445 | int arg_index = 0; 446 | 447 | va_start( va, minmatch ); 448 | while ( (matcharg = va_arg( va , char * )) != NULL ) 449 | { 450 | if ( (minmatch==0 && strcmp(key, matcharg)==0) || 451 | (minmatch && strstartwith( key, matcharg, minmatch, NULL) ) ) 452 | { 453 | matched_arg = arg_index; 454 | break; 455 | } 456 | arg_index++; 457 | } 458 | va_end(va); 459 | return matched_arg; 460 | } 461 | 462 | int strgetword( const char *string, char *buf, int size, char **pleft) 463 | { 464 | const char *ptr, *q; 465 | int len; 466 | 467 | /* skip leading white-space */ 468 | for(ptr=string; *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n'); ptr++); 469 | if ( *ptr=='\0' ) return 0; 470 | for(q=ptr; *q && *q!=' ' && *q!='\t' && *q!='\n'; q++); 471 | len = q - ptr; 472 | if ( len < size ) 473 | { 474 | memcpy( buf, ptr, len ); 475 | buf[len] = '\0'; 476 | if ( pleft ) 477 | *pleft=(char*)q; 478 | return len; 479 | } 480 | return 0; 481 | } 482 | /* TCP and UDP API EDN */ 483 | 484 | static const char *read_line( char *buf, char *line, char **dptr ) 485 | { 486 | if( !buf || *buf == '\0') return; 487 | char *ptr = buf; 488 | char *lineS = line; 489 | for( ;*ptr != '\n'; ptr++ ) *line++ = *ptr; 490 | *line++ = '\n'; 491 | *line = '\0'; 492 | *dptr = (ptr+1); 493 | return lineS; 494 | } 495 | 496 | static int new_sock( int type, PVHRtspClient client ) 497 | { 498 | int i = 0; 499 | client->stream_type = TRANS_TCP; 500 | if( type == 0 ) 501 | { 502 | client->stream_type = TRANS_UDP; 503 | printf("使用UDP方式获取码流!\r\n"); 504 | } 505 | else 506 | printf("使用TCP方式获取码流!\r\n"); 507 | int fd0, fd1; 508 | if( client->recv_fd[0] > 0 ) 509 | close( client->recv_fd[0] ); 510 | if( client->recv_fd[1] > 0 ) 511 | close( client->recv_fd[1] ); 512 | client->recv_port[0] = 0; 513 | client->recv_port[1] = 0; 514 | for( i; i < 100; i++ ) 515 | { 516 | if( client->stream_type == TRANS_UDP ) 517 | { 518 | fd0 = sock_udp_bind( 1024 + i ); 519 | if( fd0 < 0 ) 520 | continue; 521 | fd1 = sock_udp_bind( 1024 + i+1 ); 522 | if( fd1 < 0 ) 523 | { 524 | i++; 525 | close( fd0 ); 526 | continue; 527 | } 528 | client->recv_fd[0] = fd0; 529 | client->recv_fd[1] = fd1; 530 | client->recv_port[0] = 1024 + i; 531 | client->recv_port[1] = 1024 + i+1; 532 | printf("绑定本地UDP端口:%d -%d \r\n", client->recv_port[0], client->recv_port[1] ); 533 | break; 534 | }else if( client->stream_type == TRANS_TCP ){ 535 | fd0 = sock_listen(1024 + i, NULL, 0); 536 | if( fd0 < 0 ) 537 | continue; 538 | fd1 = sock_listen(1024 + i + 1, NULL, 0); 539 | if( fd1 < 0 ) 540 | { 541 | i++; 542 | close( fd0 ); 543 | continue; 544 | } 545 | client->recv_fd[0] = fd0; 546 | client->recv_fd[1] = fd1; 547 | client->recv_port[0] = 1024 + i; 548 | client->recv_port[1] = 1024 + i+1; 549 | break; 550 | } 551 | } 552 | if( client->recv_port[0] > 0 ) 553 | return 0; 554 | else 555 | return -1; 556 | } 557 | 558 | 559 | static int IsAnsOK( char *buf ) 560 | { 561 | int code = 0; 562 | if( buf == NULL ) 563 | return -1; 564 | sscanf( buf, "RTSP/1.0 %d", &code ); 565 | if( code == 200 ) 566 | return 0; 567 | printf("ANS ERROR:%s \r\n", buf ); 568 | return -1; 569 | } 570 | 571 | static void AnsOption( HANDLE handle, char *buf ) 572 | { 573 | PVHRtspClient obj = (PVHRtspClient)handle; 574 | obj->support_cmd = 0; 575 | if( IsAnsOK( buf ) != 0 ) 576 | return; 577 | char *ptr = NULL; 578 | ptr = strstr( buf, "\r\n\r\n" ); 579 | if( ptr ) 580 | { 581 | ptr += 4; 582 | if( *ptr == '\0' ) 583 | return; 584 | printf("Content:%s\r\n", ptr); 585 | } 586 | char *options = NULL; 587 | char key[30]; 588 | while( strgetword( options, key, sizeof( key ), &options ) != 0 ) 589 | { 590 | int index = stridxinargs( key, 5, "OPTIONS", "DESCRIBE", "SETUP", "PLAY", "TEARDOWN", "GET_PARAMETER" ); 591 | switch( index ) 592 | { 593 | case 0: obj->support_cmd |= (1)<<0; break; 594 | case 1: obj->support_cmd |= (1)<<1; break; 595 | case 2: obj->support_cmd |= (1)<<2; break; 596 | case 3: obj->support_cmd |= (1)<<3; break; 597 | case 4: obj->support_cmd |= (1)<<4; break; 598 | case 5: obj->support_cmd |= (1)<<5; break; 599 | case 6: obj->support_cmd |= (1)<<6; break; 600 | default: 601 | break; 602 | } 603 | } 604 | obj->stat = RTSP_DESCRIPT; 605 | } 606 | 607 | static void AnsDescript( HANDLE handle, char *buf ) 608 | { 609 | PVHRtspClient obj = (PVHRtspClient)handle; 610 | if( IsAnsOK( buf ) != 0 ) 611 | return; 612 | char *ptr , *q; 613 | char tmp[128] = {0}; 614 | ptr = strstr( buf, "\r\n\r\n" ); 615 | if( ptr ) 616 | { 617 | ptr += 4; 618 | if( *ptr == '\0' ) 619 | return; 620 | } 621 | // 获取Descript中关于Track的内容,由于Reply的Content里会有a=control:*部分,这部分我们不用,直接跳过,获取第一个track部分 622 | //定位到视频部分 623 | ptr = strstr( buf, "m=video" ); 624 | if( ptr ) 625 | { 626 | ptr = strstr( ptr, "a=control" ); 627 | if( ptr ) 628 | { 629 | for( ;*ptr != ':'; ptr++ ); 630 | ptr++; 631 | q = tmp; 632 | while( *ptr != '\r' && *ptr != ';' && *ptr != '\t' && *ptr != '\n') 633 | if( *ptr != ' ' ) 634 | *q++ = *ptr++; 635 | else 636 | ptr++; 637 | *q = '\0'; 638 | // 获取到的control后设置rtsp请求头,不然有问题 639 | // if( obj->rtsp_url[0] == '\0' ) 640 | sprintf( obj->rtsp_url, "rtsp://%s/%s", obj->server_ip, tmp ); 641 | printf("rtsp_url ip:%s \r\n", obj->rtsp_url ); 642 | }else{ 643 | printf("can not find the rtsp source"); 644 | obj->stat = RTSP_OPTION; 645 | } 646 | }else 647 | { 648 | printf("can not find the rtsp source"); 649 | obj->stat = RTSP_OPTION; 650 | } 651 | obj->stat = RTSP_SETUP; 652 | } 653 | 654 | static void AnsSetup( HANDLE handle, char *buf ) 655 | { 656 | PVHRtspClient obj = (PVHRtspClient)handle; 657 | if( IsAnsOK( buf ) != 0 ) 658 | return; 659 | char tmp[128]; 660 | char *ptr, *q; 661 | ptr = strstr( buf, "server_port=" ); 662 | if( ptr ) 663 | { 664 | ptr += 12; 665 | q = tmp; 666 | while( *ptr != '\r' && *ptr != ';' && *ptr != '\t' && *ptr != '\n') 667 | if( *ptr != ' ' ) 668 | *q++ = *ptr++; 669 | else 670 | ptr++; 671 | *q = '\0'; 672 | int start, end; 673 | sscanf( tmp, "%d-%d", &start, &end ); 674 | obj->server_port[0] = start; 675 | obj->server_port[1] = end; 676 | printf("Server listen port:%d - %d\r\n", start, end ); 677 | } 678 | ptr = strstr( buf, "Session:" ); 679 | if( ptr ) 680 | { 681 | q = tmp; 682 | ptr += 8; 683 | while( *ptr != '\r' && *ptr != ';' && *ptr != '\t' && *ptr != '\n') 684 | { 685 | if( *ptr != ' ' ) 686 | *q++ = *ptr++; 687 | else 688 | ptr++; 689 | } 690 | printf("Session:%s \r\n", tmp ); 691 | *q = '\0'; 692 | strcpy( obj->session, tmp ); 693 | }else{ 694 | printf("Not find ptr!\r\n"); 695 | obj->stat = RTSP_OPTION; 696 | } 697 | obj->stat = RTSP_PLAY; 698 | } 699 | 700 | static void AnsPlay( HANDLE handle, char *buf ) 701 | { 702 | PVHRtspClient obj = (PVHRtspClient)handle; 703 | if( IsAnsOK( buf ) != 0 ) 704 | return; 705 | char *ptr = NULL; 706 | obj->stat = RTSP_KEEP; 707 | ptr = strstr( buf, "\r\n\r\n" ); 708 | if( ptr ) 709 | { 710 | ptr += 4; 711 | if( *ptr == '\0' ) 712 | return; 713 | } 714 | } 715 | 716 | // 该接口没用过,等到以后需要使用的时候再说,也不知道该接口干嘛的 717 | static void AnsGetParam( HANDLE handle, char *buf ) 718 | { 719 | PVHRtspClient obj = (PVHRtspClient)handle; 720 | if( IsAnsOK( buf ) != 0 ) 721 | return; 722 | char *ptr = NULL; 723 | ptr = strstr( buf, "\r\n\r\n" ); 724 | if( ptr ) 725 | { 726 | ptr += 4; 727 | if( *ptr == '\0' ) 728 | return; 729 | printf("Content:%s\r\n", ptr); 730 | } 731 | obj->stat = RTSP_KEEP; 732 | } 733 | 734 | // 关闭数据流 735 | static void AnsStop( HANDLE handle, char *buf ) 736 | { 737 | if( IsAnsOK( buf ) != 0 ) 738 | return; 739 | char *ptr = NULL; 740 | ptr = strstr( buf, "\r\n\r\n" ); 741 | if( ptr ) 742 | { 743 | ptr += 4; 744 | if( *ptr == '\0' ) 745 | return; 746 | printf("Content:%s\r\n", ptr); 747 | } 748 | } 749 | 750 | static const char *getAuthurationInfo( HANDLE handle ) 751 | { 752 | //这边的内容待定,暂时没有用户名密码输入的需求,后期有的话再开发,大概这这么写的 753 | PVHRtspClient obj = (PVHRtspClient)handle; 754 | static char authon[256] = {0}; 755 | if( obj->authName[0] == '\0') 756 | { 757 | memset(authon, 0, sizeof( authon ) ); 758 | return authon; 759 | } 760 | char body[128] = {0}; 761 | char enBody[256] = {0}; 762 | char const* const authFmt = "Authorization: Basic %s\r\n"; 763 | unsigned usernamePasswordLength = strlen(obj->authName) + 1 + strlen(obj->authPwd); 764 | sprintf(body, "%s:%s", obj->authName, obj->authPwd); 765 | // int len = str_b64enc(body, enBody, sizeof( enBody )); 766 | // unsigned const authBufSize = strlen(authFmt) + strlen(enBody) + 1; 767 | sprintf(authon, authFmt, enBody ); 768 | return authon; 769 | } 770 | 771 | int SendRequest( HANDLE handle , RTPS_STAT_E type ) 772 | { 773 | PVHRtspClient obj = (PVHRtspClient)handle; 774 | char *cmd = NULL; 775 | if( type == RTSP_NONE ) 776 | obj->CSeq = 0; 777 | if( type != RTSP_PLAY ) 778 | obj->CSeq++; 779 | char Agent[128] = {0}, StrCSeq[30] = {0}, Authoration[128] = {0}; 780 | char contentLengthHeader[128] = {0}, extraHeaders[128] = {0}; 781 | char contentStr[512] = {0}; 782 | char const* protocolStr = "RTSP/1.0"; // by default 783 | char const* const cmdFmt = 784 | "%s %s %s\r\n" // type, url, rtsp 785 | "%s" // CSeq 786 | "%s" // Authuration 787 | "%s" // Agent 788 | "%s" // extraHeader 789 | "%s" // contentlen 790 | "\r\n" 791 | "%s"; // content 792 | switch( type ) 793 | { 794 | case RTSP_NONE: 795 | case RTSP_OPTION: 796 | cmd = "OPTIONS"; 797 | break; 798 | case RTSP_DESCRIPT: 799 | cmd = "DESCRIBE"; 800 | break; 801 | case RTSP_SETUP: 802 | cmd = "SETUP"; 803 | break; 804 | case RTSP_PLAY: 805 | cmd = "PLAY"; 806 | break; 807 | case RTSP_GETPARM: 808 | cmd = "GET_PARAMETER"; 809 | break; 810 | case RTSP_PAUSE: 811 | case RTSP_STOP: 812 | cmd = "TEARDOWN"; 813 | break; 814 | case RTSP_KEEP: 815 | return; 816 | break; 817 | default: 818 | break; 819 | } 820 | sprintf( Agent, "User-Agent: %s\r\n", PRG_NAME ); 821 | sprintf( StrCSeq, "CSeq: %d\r\n", obj->CSeq ); 822 | if( obj->session[0] != '\0' && obj->stat > RTSP_SETUP ) 823 | sprintf( extraHeaders, "Session: %s\r\nRange: npt=0.000-\r\n", obj->session ); 824 | else 825 | sprintf( extraHeaders, "Range: npt=0.000-\r\n" ); 826 | if( obj->stat == RTSP_SETUP ) 827 | { 828 | new_sock( TRANS_UDP, obj ); 829 | sprintf( extraHeaders, "Transport: RTP/AVP;unicast;client_port=%d-%d\r\n", obj->recv_port[0], obj->recv_port[1] ); 830 | } 831 | if( obj->stat <= RTSP_DESCRIPT ) 832 | sprintf( extraHeaders,"Accept: application/sdp\r\n"); 833 | // if we have contelen and content info 834 | sprintf( Authoration, "%s", getAuthurationInfo(obj)); 835 | sprintf( obj->recv_buf , cmdFmt, cmd, obj->rtsp_url, protocolStr,\ 836 | StrCSeq, Authoration, Agent, extraHeaders,\ 837 | contentLengthHeader, contentStr ); 838 | if( obj->fd > 0 ) 839 | { 840 | printf("Send Requtst:%s \r\n", obj->recv_buf ); 841 | write( obj->fd, obj->recv_buf, strlen( obj->recv_buf) ); 842 | } 843 | if( sock_dataready(obj->fd, 2000) ) 844 | { 845 | memset( obj->recv_buf, 0, obj->maxBufSize ); 846 | if( 0 >= read( obj->fd, obj->recv_buf, obj->maxBufSize ) ) 847 | { 848 | printf("No response!\r\n"); 849 | return; 850 | } 851 | printf("ANS:\n%s\r\n", obj->recv_buf ); 852 | switch( type ) 853 | { 854 | case RTSP_NONE: 855 | case RTSP_OPTION: 856 | AnsOption( obj, obj->recv_buf ); 857 | break; 858 | case RTSP_DESCRIPT: 859 | AnsDescript( obj, obj->recv_buf ); 860 | break; 861 | case RTSP_SETUP: 862 | AnsSetup( obj, obj->recv_buf ); 863 | break; 864 | case RTSP_PLAY: 865 | AnsPlay( obj, obj->recv_buf ); 866 | break; 867 | case RTSP_GETPARM: 868 | AnsGetParam( obj, obj->recv_buf ); 869 | break; 870 | case RTSP_PAUSE: 871 | case RTSP_STOP: 872 | AnsStop( obj, obj->recv_buf ); 873 | break; 874 | break; 875 | default: 876 | break; 877 | } 878 | } 879 | return 0; 880 | } 881 | 882 | // extern HANDLE NewFilter( int size , HANDLE Vde); 883 | extern int FilterWrite( HANDLE h, char *buf, int size ); 884 | const char *show_hex( const char *ch, int rlen) 885 | { 886 | int i = 0; 887 | char *ptr =(char*)ch; 888 | static char buf[1024]; 889 | memset( buf, 0, sizeof( buf )); 890 | char *off = buf; 891 | unsigned char val; 892 | int len = rlen > 300 ? 300 : rlen; 893 | memset( buf, 0, sizeof( buf )); 894 | for (i = 0; i < len; i++) 895 | { 896 | val = *ptr++; 897 | sprintf( off, "%02x ", val); 898 | off+=3; 899 | } 900 | *off = '\0'; 901 | return buf; 902 | } 903 | 904 | void RTCP_PackParse( PVHRtspClient client , char *buf, int size ) 905 | { 906 | memset( buf, 0, size ); 907 | int len = create_rtcp_reportinfo( buf, 128 ); 908 | // RTCP 包就回复一下就好了, 无所谓的,基本不用的 909 | sock_udp_send( client->server_ip, client->server_port[1], buf, len ); 910 | // printf("==================>>>>>>>>> Receive RTCP Rackage %s !\r\n", show_hex( buf, len )); 911 | } 912 | 913 | void RTP_PackParse( PVHRtspClient client, char *buf, int size ) 914 | { 915 | printf("receive pack:%d\r\n", size ); 916 | if( ParseRtp( client->rtp , buf, size ) == 1 ) 917 | { 918 | printf("Get a Full Nalu Packet!\r\n"); 919 | // 如果获取到足够发送的码流,发送到解码通道 920 | // if( client->Vdec ) 921 | // RTP_Send( client->rtp, client->Vdec ); 922 | } 923 | } 924 | 925 | void *rtsp_work_thread(void *args) 926 | { 927 | PVHRtspClient obj = (PVHRtspClient)args; 928 | obj->link = LINK_CONNECTING; 929 | int len; 930 | int fd; 931 | time_t tout; 932 | // 先创建访问RTSP的OPTION部分内容 933 | if( obj->rtsp_url[0] == '\0' ) 934 | sprintf( obj->rtsp_url, "rtsp://%s/", obj->server_ip ); 935 | while( !obj->bQuit ) 936 | { 937 | if( obj->link != LINK_CONNECTED ) 938 | obj->link = LINK_CONNECTING; 939 | obj->stat = RTSP_NONE; 940 | if(obj->link != LINK_CONNECTED && obj->stat == RTSP_NONE ) 941 | { 942 | fd = sock_connect( obj->server_ip, 554 ); 943 | if( fd < 0 ) 944 | { 945 | printf("connect failed! %s \r\n", strerror( errno )); 946 | usleep( 1000*1000 ); 947 | obj->link = LINK_DISCONNECT; 948 | continue; 949 | }else{ 950 | printf("connect success!\r\n"); 951 | obj->link = LINK_CONNECTED; 952 | } 953 | } 954 | obj->fd = fd; 955 | if( SendRequest(obj, RTSP_OPTION ) == 0 ) 956 | { 957 | printf("====> option OK!\r\n"); 958 | }else 959 | continue; 960 | if( SendRequest(obj, RTSP_DESCRIPT ) == 0 ) 961 | { 962 | printf("====> Descriput OK!\r\n"); 963 | 964 | }else 965 | continue; 966 | if( SendRequest(obj, RTSP_SETUP ) == 0 ) 967 | { 968 | 969 | printf("====> Setup OK!\r\n"); 970 | }else 971 | continue; 972 | if( SendRequest(obj, RTSP_PLAY ) == 0 ) 973 | { 974 | printf("Play OK!\r\n"); 975 | obj->stat = RTSP_KEEP; 976 | obj->tou = time(NULL) + 60; 977 | }else 978 | { 979 | printf("Play Error!\r\n"); 980 | continue; 981 | } 982 | tout = time( NULL ); 983 | while( obj->stat == RTSP_KEEP ) 984 | { 985 | // 如果一直连接,则接收码流数据,如果5秒还没收到码流数据,或者1分钟超时,就发送一次心跳包,就发个OPTION帧好了 986 | if( obj->tou < time(NULL) || ( tout + 5 ) < time( NULL ) ) 987 | { 988 | if( SendRequest(obj, RTSP_OPTION ) == 0 ) 989 | { 990 | obj->stat = RTSP_KEEP; 991 | // each 60s should be reconnect to rtsp send play as the heartbeat 992 | obj->tou = time(NULL) + 60; 993 | tout = time( NULL ); 994 | }else{ 995 | printf("has already disconnect!\r\n"); 996 | obj->stat = RTSP_NONE; 997 | } 998 | } 999 | if( obj->stream_type == TRANS_TCP ) 1000 | { 1001 | // tcp方式的话直接解析就好了,已经包含了RTP包了 1002 | // not supprt now! 1003 | }else if( obj->stream_type == TRANS_UDP ) 1004 | { 1005 | int maxFd = max( obj->recv_fd[0], obj->recv_fd[1] ); 1006 | struct timeval tv; 1007 | fd_set rfd_set; 1008 | int nsel; 1009 | FD_ZERO( &rfd_set ); 1010 | FD_SET( obj->recv_fd[0], &rfd_set ); 1011 | FD_SET( obj->recv_fd[1], &rfd_set ); 1012 | tv.tv_sec = 0; 1013 | tv.tv_usec = 10 * 1000; 1014 | nsel = select( maxFd + 1, &rfd_set, NULL, NULL, &tv ); 1015 | if ( nsel > 0 && FD_ISSET( obj->recv_fd[1], &rfd_set ) ) 1016 | { 1017 | len = sock_read( obj->recv_fd[1], obj->recv_buf, obj->maxBufSize ); 1018 | if( len > 4 ) 1019 | RTCP_PackParse( obj, obj->recv_buf, len ); 1020 | }else if( nsel > 0 && FD_ISSET( obj->recv_fd[0], &rfd_set )) 1021 | { 1022 | len = sock_read( obj->recv_fd[0], obj->recv_buf, obj->maxBufSize ); 1023 | if( len > 4 ) 1024 | RTP_PackParse( obj, obj->recv_buf, len ); 1025 | tout = time( NULL ); 1026 | } 1027 | } 1028 | } 1029 | } 1030 | close( obj->fd ); 1031 | } 1032 | 1033 | // 主码流次码流?现在不支持选择,只是放这边好了 1034 | HANDLE RTSP_New( const char *strIP , int maj, const char *usr, const char *pwd , HANDLE Vdec ) 1035 | { 1036 | if ( inet_addr(strIP) == -1 ) 1037 | { 1038 | printf("input ip invalid! :%s \r\n", strIP ); 1039 | return NULL; 1040 | } 1041 | RtspClient *client = malloc( sizeof( RtspClient )); 1042 | memset( client, 0, sizeof( RtspClient )); 1043 | client->magic = MAGIC_NUM; 1044 | strcpy( client->server_ip, strIP ); 1045 | if( usr ) 1046 | strcpy( client->authName, usr ); 1047 | if( pwd ) 1048 | strcpy( client->authPwd , pwd ); 1049 | client->maxBufSize = 5*1024; 1050 | client->recv_buf = malloc(client->maxBufSize); 1051 | client->Vdec = Vdec; 1052 | HANDLE rtp = RTP_Init(); 1053 | client->rtp = rtp; 1054 | pthread_create( &client->threadID, NULL, rtsp_work_thread, (void *)client ); 1055 | return client; 1056 | } 1057 | 1058 | void RTSP_Delete( HANDLE handle ) 1059 | { 1060 | RtspClient *obj = (RtspClient*)handle; 1061 | if( RTSP_INVALID( obj ) ) 1062 | return; 1063 | obj->bQuit = 1; 1064 | if( obj->recv_buf ) 1065 | free( obj->recv_buf ); 1066 | pthread_cancel( obj->threadID ); 1067 | pthread_join( obj->threadID, NULL ); 1068 | } 1069 | 1070 | int main(int argc, char *argv[]) 1071 | { 1072 | HANDLE rtsp = RTSP_New( "192.168.0.27", 0, NULL, NULL, NULL ); 1073 | while( 1 ) 1074 | usleep( 1 ); 1075 | } 1076 | -------------------------------------------------------------------------------- /Client/rtcp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "rtcp.h" 23 | 24 | #define RTCP_SR 200 25 | 26 | #define HeadInit( head, type ) do{\ 27 | rtcp_common_header_set_version(head, 2);\ 28 | rtcp_common_header_set_padbit(head, 0);\ 29 | rtcp_common_header_set_rc(head, 0);\ 30 | rtcp_common_header_set_packet_type(head, type);\ 31 | rtcp_common_header_set_length(head, sizeof( report_block_t ) );\ 32 | }while(0); 33 | 34 | int create_rtcp_reportinfo( char *Buffer, int maxBuffer ) 35 | { 36 | rtcp_common_header_t *head = (rtcp_common_header_t*)Buffer; 37 | report_block_t *block = (report_block_t*)(Buffer + sizeof(rtcp_common_header_t)); 38 | rtcp_common_header_set_version(head, 2); 39 | rtcp_common_header_set_padbit(head, 0); 40 | rtcp_common_header_set_rc(head, 0); 41 | rtcp_common_header_set_packet_type(head, RTCP_RR); 42 | rtcp_common_header_set_length(head, sizeof( report_block_t ) );\ 43 | // 设置 44 | memset( block, 0, sizeof( report_block_t )); 45 | report_block_set_fraction_lost(block, 0); 46 | report_block_set_cum_packet_lost(block, 0); 47 | return sizeof( rtcp_common_header_t ) + sizeof( report_block_t ); 48 | } 49 | 50 | 51 | int rtcp_parse( char *Buffer, int BufferSize ) 52 | { 53 | rtcp_common_header_t *header = (rtcp_common_header_t*)Buffer; 54 | printf("version:%d , pad:%d , rc:%d , type:%d, len:%d \r\n", 55 | rtcp_common_header_get_version(header), 56 | rtcp_common_header_get_padbit(header), 57 | rtcp_common_header_get_rc(header), 58 | rtcp_common_header_get_packet_type(header), 59 | rtcp_common_header_get_length(header) ); 60 | if( rtcp_common_header_get_packet_type(header) == RTCP_SR ) 61 | { 62 | printf("收到rtcp RTCP_SR包,解析!\r\n"); 63 | }else if(rtcp_common_header_get_packet_type(header) == RTCP_RR) { 64 | printf("收到rtcp RTCP_RR包,解析!\r\n"); 65 | }else if(rtcp_common_header_get_packet_type(header) == RTCP_SDES) { 66 | printf("收到rtcp RTCP_SDES包,解析!\r\n"); 67 | }else if(rtcp_common_header_get_packet_type(header) == RTCP_BYE) { 68 | printf("收到rtcp RTCP_BYE包,解析!\r\n"); 69 | }else if(rtcp_common_header_get_packet_type(header) == RTCP_APP) { 70 | printf("收到rtcp RTCP_APP包,解析!\r\n"); 71 | }else if(rtcp_common_header_get_packet_type(header) == RTCP_RTPFB) { 72 | printf("收到rtcp RTCP_RTPFB包,解析!\r\n"); 73 | }else if(rtcp_common_header_get_packet_type(header) == RTCP_PSFB) { 74 | printf("收到rtcp RTCP_PSFB包,解析!\r\n"); 75 | }else if(rtcp_common_header_get_packet_type(header) == RTCP_XR) { 76 | printf("收到rtcp RTCP_XR包,解析!\r\n"); 77 | }else{ 78 | printf("收到rtcp unkonw包,解析!\r\n"); 79 | } 80 | return 1; 81 | } 82 | 83 | static int read_rtcp( char *buf , int index ) 84 | { 85 | int len; 86 | char filename[120]; 87 | sprintf(filename, "rtcpslice%d.hex", index ); 88 | if( access( filename, F_OK ) == 0 ) 89 | { 90 | int fd = open( filename, O_RDONLY ); 91 | if( fd < 0 ) 92 | return; 93 | len = read( fd, buf, 1023 ); 94 | close( fd ); 95 | return len; 96 | } 97 | return -1; 98 | } 99 | #if 0 100 | const char *show_hex( const char *ch, int rlen) 101 | { 102 | int i = 0; 103 | char *ptr =(char*)ch; 104 | static char buf[1024]; 105 | memset( buf, 0, sizeof( buf )); 106 | char *off = buf; 107 | unsigned char val; 108 | int len = rlen > 300 ? 300 : rlen; 109 | memset( buf, 0, sizeof( buf )); 110 | for (i = 0; i < len; i++) 111 | { 112 | val = *ptr++; 113 | sprintf( off, "%02x ", val); 114 | off+=3; 115 | } 116 | *off = '\0'; 117 | return buf; 118 | } 119 | #endif 120 | 121 | /* 122 | 123 | void main() 124 | { 125 | int i = 0; 126 | char buf[1023]; 127 | int len; 128 | for( i = 0; i < 20 ; i++ ) 129 | { 130 | len = read_rtcp( buf, i ); 131 | if( len > 0 ) 132 | { 133 | rtcp_parse( buf, len ); 134 | len = create_rtcp_reportinfo( buf, sizeof( buf )); 135 | printf("return size %d \r\n", len ); 136 | if( len > 0 ) 137 | printf("return value:%s \r\n", show_hex( buf , len )); 138 | } 139 | 140 | } 141 | return; 142 | } 143 | */ 144 | -------------------------------------------------------------------------------- /Client/rtcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) implementation with additional features. 3 | * Copyright (C) 2017 Belledonne Communications SARL 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | */ 19 | 20 | 21 | #ifndef RTCP_H 22 | #define RTCP_H 23 | 24 | // #include 25 | 26 | #define RTCP_MAX_RECV_BUFSIZE 1500 27 | 28 | #define RTCP_SENDER_INFO_SIZE 20 29 | #define RTCP_REPORT_BLOCK_SIZE 24 30 | #define RTCP_COMMON_HEADER_SIZE 4 31 | #define RTCP_SSRC_FIELD_SIZE 4 32 | 33 | #ifdef __cplusplus 34 | extern "C"{ 35 | #endif 36 | 37 | /* RTCP common header */ 38 | 39 | typedef enum { 40 | RTCP_SR = 200, 41 | RTCP_RR = 201, 42 | RTCP_SDES = 202, 43 | RTCP_BYE = 203, 44 | RTCP_APP = 204, 45 | RTCP_RTPFB = 205, 46 | RTCP_PSFB = 206, 47 | RTCP_XR = 207 48 | } rtcp_type_t; 49 | 50 | typedef struct rtcp_common_header 51 | { 52 | #ifdef ORTP_BIGENDIAN 53 | uint16_t version:2; 54 | uint16_t padbit:1; 55 | uint16_t rc:5; 56 | uint16_t packet_type:8; 57 | #else 58 | uint16_t rc:5; 59 | uint16_t padbit:1; 60 | uint16_t version:2; 61 | uint16_t packet_type:8; 62 | #endif 63 | uint16_t length:16; 64 | } rtcp_common_header_t; 65 | 66 | #define rtcp_common_header_set_version(ch,v) (ch)->version=v 67 | #define rtcp_common_header_set_padbit(ch,p) (ch)->padbit=p 68 | #define rtcp_common_header_set_rc(ch,val) (ch)->rc=val 69 | #define rtcp_common_header_set_packet_type(ch,pt) (ch)->packet_type=pt 70 | #define rtcp_common_header_set_length(ch,l) (ch)->length=htons(l) 71 | 72 | #define rtcp_common_header_get_version(ch) ((ch)->version) 73 | #define rtcp_common_header_get_padbit(ch) ((ch)->padbit) 74 | #define rtcp_common_header_get_rc(ch) ((ch)->rc) 75 | #define rtcp_common_header_get_packet_type(ch) ((ch)->packet_type) 76 | #define rtcp_common_header_get_length(ch) ntohs((ch)->length) 77 | 78 | 79 | /* RTCP SR or RR packets */ 80 | 81 | typedef struct sender_info 82 | { 83 | uint32_t ntp_timestamp_msw; 84 | uint32_t ntp_timestamp_lsw; 85 | uint32_t rtp_timestamp; 86 | uint32_t senders_packet_count; 87 | uint32_t senders_octet_count; 88 | } sender_info_t; 89 | #define ORTP_INLINE inline 90 | 91 | 92 | static ORTP_INLINE uint64_t sender_info_get_ntp_timestamp(const sender_info_t *si) { 93 | return ((((uint64_t)ntohl(si->ntp_timestamp_msw)) << 32) + 94 | ((uint64_t) ntohl(si->ntp_timestamp_lsw))); 95 | } 96 | #define sender_info_get_rtp_timestamp(si) ntohl((si)->rtp_timestamp) 97 | #define sender_info_get_packet_count(si) \ 98 | ntohl((si)->senders_packet_count) 99 | #define sender_info_get_octet_count(si) \ 100 | ntohl((si)->senders_octet_count) 101 | 102 | 103 | typedef struct report_block 104 | { 105 | uint32_t ssrc; 106 | uint32_t fl_cnpl;/*fraction lost + cumulative number of packet lost*/ 107 | uint32_t ext_high_seq_num_rec; /*extended highest sequence number received */ 108 | uint32_t interarrival_jitter; 109 | uint32_t lsr; /*last SR */ 110 | uint32_t delay_snc_last_sr; /*delay since last sr*/ 111 | } report_block_t; 112 | 113 | static ORTP_INLINE uint32_t report_block_get_ssrc(const report_block_t * rb) { 114 | return ntohl(rb->ssrc); 115 | } 116 | static ORTP_INLINE uint32_t report_block_get_high_ext_seq(const report_block_t * rb) { 117 | return ntohl(rb->ext_high_seq_num_rec); 118 | } 119 | static ORTP_INLINE uint32_t report_block_get_interarrival_jitter(const report_block_t * rb) { 120 | return ntohl(rb->interarrival_jitter); 121 | } 122 | 123 | static ORTP_INLINE uint32_t report_block_get_last_SR_time(const report_block_t * rb) { 124 | return ntohl(rb->lsr); 125 | } 126 | static ORTP_INLINE uint32_t report_block_get_last_SR_delay(const report_block_t * rb) { 127 | return ntohl(rb->delay_snc_last_sr); 128 | } 129 | static ORTP_INLINE uint32_t report_block_get_fraction_lost(const report_block_t * rb) { 130 | return (ntohl(rb->fl_cnpl)>>24); 131 | } 132 | static ORTP_INLINE int32_t report_block_get_cum_packet_lost(const report_block_t * rb){ 133 | int cum_loss = ntohl(rb->fl_cnpl); 134 | if (((cum_loss>>23)&1)==0) 135 | return 0x00FFFFFF & cum_loss; 136 | else 137 | return 0xFF000000 | (cum_loss-0xFFFFFF-1); 138 | } 139 | 140 | static ORTP_INLINE void report_block_set_fraction_lost(report_block_t * rb, int fl){ 141 | rb->fl_cnpl = htonl( (ntohl(rb->fl_cnpl) & 0xFFFFFF) | (fl&0xFF)<<24); 142 | } 143 | 144 | static ORTP_INLINE void report_block_set_cum_packet_lost(report_block_t * rb, int64_t cpl) { 145 | uint32_t clamp = (uint32_t)((1<<24) + ((cpl>=0) ? (cpl>0x7FFFFF?0x7FFFFF:cpl) : (-cpl>0x800000?-0x800000:cpl))); 146 | 147 | rb->fl_cnpl=htonl( 148 | (ntohl(rb->fl_cnpl) & 0xFF000000) | 149 | (cpl >= 0 ? clamp&0x7FFFFF : clamp|0x800000) 150 | ); 151 | } 152 | 153 | /* SDES packets */ 154 | 155 | typedef enum { 156 | RTCP_SDES_END = 0, 157 | RTCP_SDES_CNAME = 1, 158 | RTCP_SDES_NAME = 2, 159 | RTCP_SDES_EMAIL = 3, 160 | RTCP_SDES_PHONE = 4, 161 | RTCP_SDES_LOC = 5, 162 | RTCP_SDES_TOOL = 6, 163 | RTCP_SDES_NOTE = 7, 164 | RTCP_SDES_PRIV = 8, 165 | RTCP_SDES_MAX = 9 166 | } rtcp_sdes_type_t; 167 | 168 | typedef struct sdes_chunk 169 | { 170 | uint32_t csrc; 171 | } sdes_chunk_t; 172 | 173 | 174 | #define sdes_chunk_get_csrc(c) ntohl((c)->csrc) 175 | 176 | typedef struct sdes_item 177 | { 178 | uint8_t item_type; 179 | uint8_t len; 180 | char content[1]; 181 | } sdes_item_t; 182 | 183 | #define RTCP_SDES_MAX_STRING_SIZE 255 184 | #define RTCP_SDES_ITEM_HEADER_SIZE 2 185 | #define RTCP_SDES_CHUNK_DEFAULT_SIZE 1024 186 | #define RTCP_SDES_CHUNK_HEADER_SIZE (sizeof(sdes_chunk_t)) 187 | 188 | /* RTCP bye packet */ 189 | 190 | typedef struct rtcp_bye_reason 191 | { 192 | uint8_t len; 193 | char content[1]; 194 | } rtcp_bye_reason_t; 195 | 196 | typedef struct rtcp_bye 197 | { 198 | rtcp_common_header_t ch; 199 | uint32_t ssrc[1]; /* the bye may contain several ssrc/csrc */ 200 | } rtcp_bye_t; 201 | #define RTCP_BYE_HEADER_SIZE sizeof(rtcp_bye_t) 202 | #define RTCP_BYE_REASON_MAX_STRING_SIZE 255 203 | 204 | 205 | /* RTCP XR packet */ 206 | 207 | #define RTCP_XR_VOIP_METRICS_CONFIG_PLC_STD ((1 << 7) | (1 << 6)) 208 | #define RTCP_XR_VOIP_METRICS_CONFIG_PLC_ENH (1 << 7) 209 | #define RTCP_XR_VOIP_METRICS_CONFIG_PLC_DIS (1 << 6) 210 | #define RTCP_XR_VOIP_METRICS_CONFIG_PLC_UNS 0 211 | #define RTCP_XR_VOIP_METRICS_CONFIG_JBA_ADA ((1 << 5) | (1 << 4)) 212 | #define RTCP_XR_VOIP_METRICS_CONFIG_JBA_NON (1 << 5) 213 | #define RTCP_XR_VOIP_METRICS_CONFIG_JBA_UNK 0 214 | 215 | typedef enum { 216 | RTCP_XR_LOSS_RLE = 1, 217 | RTCP_XR_DUPLICATE_RLE = 2, 218 | RTCP_XR_PACKET_RECEIPT_TIMES = 3, 219 | RTCP_XR_RCVR_RTT = 4, 220 | RTCP_XR_DLRR = 5, 221 | RTCP_XR_STAT_SUMMARY = 6, 222 | RTCP_XR_VOIP_METRICS = 7 223 | } rtcp_xr_block_type_t; 224 | 225 | typedef struct rtcp_xr_header { 226 | rtcp_common_header_t ch; 227 | uint32_t ssrc; 228 | } rtcp_xr_header_t; 229 | 230 | typedef struct rtcp_xr_generic_block_header { 231 | uint8_t bt; 232 | uint8_t flags; 233 | uint16_t length; 234 | } rtcp_xr_generic_block_header_t; 235 | 236 | typedef struct rtcp_xr_rcvr_rtt_report_block { 237 | rtcp_xr_generic_block_header_t bh; 238 | uint32_t ntp_timestamp_msw; 239 | uint32_t ntp_timestamp_lsw; 240 | } rtcp_xr_rcvr_rtt_report_block_t; 241 | 242 | typedef struct rtcp_xr_dlrr_report_subblock { 243 | uint32_t ssrc; 244 | uint32_t lrr; 245 | uint32_t dlrr; 246 | } rtcp_xr_dlrr_report_subblock_t; 247 | 248 | typedef struct rtcp_xr_dlrr_report_block { 249 | rtcp_xr_generic_block_header_t bh; 250 | rtcp_xr_dlrr_report_subblock_t content[1]; 251 | } rtcp_xr_dlrr_report_block_t; 252 | 253 | typedef struct rtcp_xr_stat_summary_report_block { 254 | rtcp_xr_generic_block_header_t bh; 255 | uint32_t ssrc; 256 | uint16_t begin_seq; 257 | uint16_t end_seq; 258 | uint32_t lost_packets; 259 | uint32_t dup_packets; 260 | uint32_t min_jitter; 261 | uint32_t max_jitter; 262 | uint32_t mean_jitter; 263 | uint32_t dev_jitter; 264 | uint8_t min_ttl_or_hl; 265 | uint8_t max_ttl_or_hl; 266 | uint8_t mean_ttl_or_hl; 267 | uint8_t dev_ttl_or_hl; 268 | } rtcp_xr_stat_summary_report_block_t; 269 | 270 | typedef struct rtcp_xr_voip_metrics_report_block { 271 | rtcp_xr_generic_block_header_t bh; 272 | uint32_t ssrc; 273 | uint8_t loss_rate; 274 | uint8_t discard_rate; 275 | uint8_t burst_density; 276 | uint8_t gap_density; 277 | uint16_t burst_duration; 278 | uint16_t gap_duration; 279 | uint16_t round_trip_delay; 280 | uint16_t end_system_delay; 281 | uint8_t signal_level; 282 | uint8_t noise_level; 283 | uint8_t rerl; 284 | uint8_t gmin; 285 | uint8_t r_factor; 286 | uint8_t ext_r_factor; 287 | uint8_t mos_lq; 288 | uint8_t mos_cq; 289 | uint8_t rx_config; 290 | uint8_t reserved2; 291 | uint16_t jb_nominal; 292 | uint16_t jb_maximum; 293 | uint16_t jb_abs_max; 294 | } rtcp_xr_voip_metrics_report_block_t; 295 | 296 | #define MIN_RTCP_XR_PACKET_SIZE (sizeof(rtcp_xr_header_t) + 4) 297 | 298 | /* RTCP FB packet */ 299 | typedef enum { 300 | RTCP_RTPFB_NACK = 1, 301 | RTCP_RTPFB_TMMBR = 3, 302 | RTCP_RTPFB_TMMBN = 4 303 | } rtcp_rtpfb_type_t; 304 | 305 | typedef enum { 306 | RTCP_PSFB_PLI = 1, 307 | RTCP_PSFB_SLI = 2, 308 | RTCP_PSFB_RPSI = 3, 309 | RTCP_PSFB_FIR = 4, 310 | RTCP_PSFB_AFB = 15 311 | } rtcp_psfb_type_t; 312 | 313 | typedef struct rtcp_fb_header { 314 | uint32_t packet_sender_ssrc; 315 | uint32_t media_source_ssrc; 316 | } rtcp_fb_header_t; 317 | 318 | typedef struct rtcp_fb_generic_nack_fci { 319 | uint16_t pid; 320 | uint16_t blp; 321 | } rtcp_fb_generic_nack_fci_t; 322 | 323 | #define rtcp_fb_generic_nack_fci_get_pid(nack) ntohs((nack)->pid) 324 | #define rtcp_fb_generic_nack_fci_set_pid(nack, value) ((nack)->pid) = htons(value) 325 | #define rtcp_fb_generic_nack_fci_get_blp(nack) ntohs((nack)->blp) 326 | #define rtcp_fb_generic_nack_fci_set_blp(nack, value) ((nack)->blp) = htons(value) 327 | 328 | typedef struct rtcp_fb_tmmbr_fci { 329 | uint32_t ssrc; 330 | uint32_t value; 331 | } rtcp_fb_tmmbr_fci_t; 332 | 333 | #define rtcp_fb_tmmbr_fci_get_ssrc(tmmbr) ntohl((tmmbr)->ssrc) 334 | #define rtcp_fb_tmmbr_fci_get_mxtbr_exp(tmmbr) \ 335 | ((uint8_t)((ntohl((tmmbr)->value) >> 26) & 0x0000003F)) 336 | #define rtcp_fb_tmmbr_fci_set_mxtbr_exp(tmmbr, mxtbr_exp) \ 337 | ((tmmbr)->value) = htonl((ntohl((tmmbr)->value) & 0x03FFFFFF) | (((mxtbr_exp) & 0x0000003F) << 26)) 338 | #define rtcp_fb_tmmbr_fci_get_mxtbr_mantissa(tmmbr) \ 339 | ((uint32_t)((ntohl((tmmbr)->value) >> 9) & 0x0001FFFF)) 340 | #define rtcp_fb_tmmbr_fci_set_mxtbr_mantissa(tmmbr, mxtbr_mantissa) \ 341 | ((tmmbr)->value) = htonl((ntohl((tmmbr)->value) & 0xFC0001FF) | (((mxtbr_mantissa) & 0x0001FFFF) << 9)) 342 | #define rtcp_fb_tmmbr_fci_get_measured_overhead(tmmbr) \ 343 | ((uint16_t)(ntohl((tmmbr)->value) & 0x000001FF)) 344 | #define rtcp_fb_tmmbr_fci_set_measured_overhead(tmmbr, measured_overhead) \ 345 | ((tmmbr)->value) = htonl((ntohl((tmmbr)->value) & 0xFFFFFE00) | ((measured_overhead) & 0x000001FF)) 346 | 347 | typedef struct rtcp_fb_fir_fci { 348 | uint32_t ssrc; 349 | uint8_t seq_nr; 350 | uint8_t pad1; 351 | uint16_t pad2; 352 | } rtcp_fb_fir_fci_t; 353 | 354 | #define rtcp_fb_fir_fci_get_ssrc(fci) ntohl((fci)->ssrc) 355 | #define rtcp_fb_fir_fci_get_seq_nr(fci) (fci)->seq_nr 356 | 357 | typedef struct rtcp_fb_sli_fci { 358 | uint32_t value; 359 | } rtcp_fb_sli_fci_t; 360 | 361 | #define rtcp_fb_sli_fci_get_first(fci) \ 362 | ((uint16_t)((ntohl((fci)->value) >> 19) & 0x00001FFF)) 363 | #define rtcp_fb_sli_fci_set_first(fci, first) \ 364 | ((fci)->value) = htonl((ntohl((fci)->value) & 0x0007FFFF) | (((first) & 0x00001FFF) << 19)) 365 | #define rtcp_fb_sli_fci_get_number(fci) \ 366 | ((uint16_t)((ntohl((fci)->value) >> 6) & 0x00001FFF)) 367 | #define rtcp_fb_sli_fci_set_number(fci, number) \ 368 | ((fci)->value) = htonl((ntohl((fci)->value) & 0xFFF8003F) | (((number) & 0x00001FFF) << 6)) 369 | #define rtcp_fb_sli_fci_get_picture_id(fci) \ 370 | ((uint8_t)(ntohl((fci)->value) & 0x0000003F)) 371 | #define rtcp_fb_sli_fci_set_picture_id(fci, picture_id) \ 372 | ((fci)->value) = htonl((ntohl((fci)->value) & 0xFFFFFFC0) | ((picture_id) & 0x0000003F)) 373 | 374 | typedef struct rtcp_fb_rpsi_fci { 375 | uint8_t pb; 376 | uint8_t payload_type; 377 | uint16_t bit_string[1]; 378 | } rtcp_fb_rpsi_fci_t; 379 | 380 | #define rtcp_fb_rpsi_fci_get_payload_type(fci) (fci)->payload_type 381 | #define rtcp_fb_rpsi_fci_get_bit_string(fci) ((uint8_t *)(fci)->bit_string) 382 | 383 | #define MIN_RTCP_PSFB_PACKET_SIZE (sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t)) 384 | #define MIN_RTCP_RTPFB_PACKET_SIZE (sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t)) 385 | 386 | /* RTCP structs */ 387 | 388 | typedef struct rtcp_sr{ 389 | rtcp_common_header_t ch; 390 | uint32_t ssrc; 391 | sender_info_t si; 392 | report_block_t rb[1]; 393 | } rtcp_sr_t; 394 | 395 | typedef struct rtcp_rr{ 396 | rtcp_common_header_t ch; 397 | uint32_t ssrc; 398 | report_block_t rb[1]; 399 | } rtcp_rr_t; 400 | 401 | typedef struct rtcp_app{ 402 | rtcp_common_header_t ch; 403 | uint32_t ssrc; 404 | char name[4]; 405 | } rtcp_app_t; 406 | 407 | 408 | #endif // RTCP_H 409 | 410 | -------------------------------------------------------------------------------- /Client/rtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: rtpc.c 5 | * 6 | * Description: this file is used to get a rtp package 7 | * stand by url: http://blog.csdn.net/chen495810242/article/details/39207305 8 | * 9 | * Version: 1.0 10 | * Created: 2017-03-15 09:44:10 PM 11 | * Revision: none 12 | * Compiler: gcc 13 | * 14 | * Author: (), 15 | * Company: 16 | * 17 | * ===================================================================================== 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | // 500K 应该够了 41 | #define MAX_RTP_BUFFER 1024*1000 42 | typedef void * HANDLE; 43 | #define __PACKED__ __attribute__ ((__packed__)) 44 | // 小端格式代码 45 | typedef unsigned int HI_U32; 46 | 47 | typedef enum 48 | { 49 | RTSP_VIDEO=0, 50 | RTSP_VIDEOSUB=1, 51 | RTSP_AUDIO=2, 52 | RTSP_YUV422=3, 53 | RTSP_RGB=4, 54 | RTSP_VIDEOPS=5, 55 | RTSP_VIDEOSUBPS=6 56 | }enRTSP_MonBlockType; 57 | 58 | struct _RTP_FIXED_HEADER 59 | { 60 | unsigned char version:2; /**//* expect 2 */ 61 | unsigned char padding:1; /**//* expect 0 */ 62 | unsigned char extension:1; /**//* expect 1, see RTP_OP below */ 63 | unsigned char csrc_len:4; /**//* expect 0 */ 64 | /**//* byte 0 */ 65 | /**//* bytes 2, 3 */ 66 | /**//* byte 1 */ 67 | unsigned char marker:1; /**//* expect 1 */ 68 | unsigned char payload:7; /**//* RTP_PAYLOAD_RTSP */ 69 | unsigned short seq_no; 70 | /**//* bytes 4-7 */ 71 | HI_U32 timestamp; 72 | /**//* bytes 8-11 */ 73 | HI_U32 ssrc; /**//* stream number is used here. */ 74 | } __PACKED__; 75 | 76 | typedef struct _RTP_FIXED_HEADER RTP_FIXED_HEADER; 77 | 78 | struct _NALU_HEADER 79 | { 80 | //byte 0 81 | unsigned char TYPE:5; 82 | unsigned char NRI:2; 83 | unsigned char F:1; 84 | }__PACKED__; /**//* 1 BYTES */ 85 | 86 | typedef struct _NALU_HEADER NALU_HEADER; 87 | 88 | struct _FU_INDICATOR 89 | { 90 | // byte 0 91 | unsigned char TYPE:5; 92 | unsigned char NRI:2; 93 | unsigned char F:1; 94 | }__PACKED__; /**//* 1 BYTES */ 95 | 96 | typedef struct _FU_INDICATOR FU_INDICATOR; 97 | 98 | struct _FU_HEADER 99 | { 100 | //byte 0 101 | unsigned char TYPE:5; 102 | unsigned char R:1; 103 | unsigned char E:1; 104 | unsigned char S:1; 105 | } __PACKED__; /**//* 1 BYTES */ 106 | typedef struct _FU_HEADER FU_HEADER; 107 | 108 | struct _AU_HEADER 109 | { 110 | //byte 0, 1 111 | unsigned short au_len; 112 | //byte 2,3 113 | unsigned short frm_len:13; 114 | unsigned char au_index:3; 115 | } __PACKED__; /**//* 1 BYTES */ 116 | typedef struct _AU_HEADER AU_HEADER; 117 | 118 | typedef enum tagNALU_E{ 119 | NALU_SIGNEL, // 单片包, 标准的NALU包 120 | NALU_MUTIL, // 聚合包 // 一个包里有多个分片内容 121 | NALU_SLICE // 分片包 // 多个小包拼接成大包 122 | }NALU_E; 123 | 124 | #define SLICE_NORMAL 0 // 常规单包 125 | #define SLICE_START 1 // 多包开始 126 | #define SLICE_MID 2 // 多包中包 127 | #define SLICE_END 3 // 多包尾包 128 | 129 | #define MAGIC_NUM 0xabcd1234 130 | #define RTP_INVALID( obj ) ( obj->magic != MAGIC_NUM ) 131 | 132 | typedef struct RTP_PACK 133 | { 134 | unsigned int magic; 135 | // 包序,没啥用 136 | int PreSeq; 137 | // 存放每次收到的RTP包 138 | char *buf; 139 | // 每次收到RTP包的时候都会计入offset偏移值里 140 | int offset; 141 | // 可以发送出去的帧buf 142 | char *frame; 143 | // 帧的长度,该frame里可能有多个小的帧信息 144 | int frame_offset; 145 | int size; 146 | // 本地包是否已经满了,满了的话在次进入时要重设偏移位置 147 | int hasFull; 148 | //这次收到的包类型 149 | char type; 150 | HI_U32 timestamp; // 每个包的timestamp,没啥用 151 | }RTP_PACK_S; 152 | 153 | static int AddH264Head(char *buf, char type) 154 | { 155 | unsigned char soh[10] = {0x00, 0x00, 0x0, 0x01, 0x65}; 156 | soh[4] = type; 157 | memcpy( buf, soh, sizeof( soh )); 158 | return 5; 159 | } 160 | 161 | static int AppendData( char *dst, int offset, char *buf, int size ) 162 | { 163 | memcpy( dst + offset, buf, size ); 164 | return size; 165 | } 166 | 167 | HANDLE RTP_Init() 168 | { 169 | RTP_PACK_S *obj = malloc( sizeof( RTP_PACK_S )); 170 | memset( obj, 0, sizeof( RTP_PACK_S )); 171 | obj->magic = MAGIC_NUM; 172 | obj->buf = malloc( MAX_RTP_BUFFER ); // 网络包小于1500 173 | obj->frame = malloc( MAX_RTP_BUFFER ); // 整包小于500K 174 | return obj; 175 | } 176 | 177 | int RTP_Exit( HANDLE handle) 178 | { 179 | RTP_PACK_S *obj = (RTP_PACK_S*)handle; 180 | if( RTP_INVALID( obj ) ) 181 | { 182 | printf("invalid obj !\r\n"); 183 | return -1; 184 | } 185 | free( obj->buf ); 186 | if( obj->frame ); 187 | free( obj->frame ); 188 | } 189 | 190 | int RTP_Send( HANDLE handle,HANDLE Vde) 191 | { 192 | RTP_PACK_S *obj = (RTP_PACK_S*)handle; 193 | if( RTP_INVALID( obj ) ) 194 | { 195 | printf("invlaid obj!\r\n"); 196 | return -1; 197 | } 198 | if( Vde ) 199 | { 200 | printf("Send Hex:%s \r\n", show_hex( obj->frame, 20 )); 201 | // you should add handle code here 202 | // Hi264DecFrame( Vde, obj->frame, obj->frame_offset, 0, NULL , 0 ); 203 | } 204 | obj->frame_offset = 0; 205 | } 206 | 207 | static int Append_frame( RTP_PACK_S *obj,char type ) 208 | { 209 | if( type == 0x61 || type == 0x65 || type == 0x06) 210 | { 211 | // I帧或BP帧 212 | if( (obj->frame_offset + obj->offset ) > MAX_RTP_BUFFER ) 213 | { 214 | printf("包已经超过了大小,抛弃该包!请设置最大包大小\r\n"); 215 | obj->hasFull = 1; 216 | return 0; 217 | } 218 | memcpy( obj->frame + obj->frame_offset, obj->buf, obj->offset ); 219 | obj->frame_offset += obj->offset; 220 | obj->hasFull = 1; 221 | return 1; 222 | } 223 | //帧头,不做发送处理,等待后续的数据帧 224 | memcpy( obj->frame + obj->frame_offset , obj->buf, obj->offset ); 225 | obj->frame_offset += obj->offset; 226 | return 0; 227 | } 228 | 229 | int ParseRtp( HANDLE handle , char *Buffer, int BufferSize ) 230 | { 231 | if( BufferSize < sizeof( RTP_FIXED_HEADER )) 232 | { 233 | printf("Package too small!\r\n"); 234 | return -1; 235 | } 236 | RTP_PACK_S *rtp_pack = (RTP_PACK_S*)handle; 237 | if( RTP_INVALID( rtp_pack )) 238 | { 239 | printf("rtp obj invalid!\r\n"); 240 | return -1; 241 | } 242 | if( rtp_pack->hasFull ) 243 | { 244 | rtp_pack->hasFull = 0; 245 | rtp_pack->frame_offset = 0; 246 | rtp_pack->offset = 0; 247 | } 248 | RTP_FIXED_HEADER *rtp_hdr; 249 | NALU_HEADER *nalu_hdr; 250 | FU_INDICATOR *fu_ind; 251 | FU_HEADER *fu_hdr; 252 | char *packBuf; 253 | unsigned char type; 254 | rtp_pack->size += BufferSize; 255 | int SliceSta; 256 | int offset = 12; 257 | rtp_hdr = (RTP_FIXED_HEADER*)Buffer; 258 | rtp_pack->timestamp = ntohl(rtp_hdr->timestamp); 259 | rtp_pack->PreSeq = ntohs(rtp_hdr->seq_no); 260 | NALU_E nalu_type = NALU_SIGNEL; 261 | nalu_hdr = (NALU_HEADER*)(Buffer+12); 262 | if( nalu_hdr->TYPE <= 23 ) 263 | nalu_type = NALU_SIGNEL; 264 | else if( 24 <= nalu_hdr->TYPE && nalu_hdr->TYPE <= 27 ) 265 | nalu_type = NALU_MUTIL; 266 | else if( 28 == nalu_hdr->TYPE || nalu_hdr->TYPE == 29 ) 267 | nalu_type = NALU_SLICE; 268 | else 269 | printf("Unkow NALU packge!\r\n"); 270 | if( nalu_type == NALU_SLICE ) 271 | { 272 | // 如果是分片包,处理 273 | fu_ind = (FU_INDICATOR*)(Buffer+12); 274 | fu_hdr = (FU_HEADER*)(Buffer+13); 275 | if( fu_hdr->S == 1 ) 276 | SliceSta = SLICE_START; 277 | else if( fu_hdr->E == 1 ) 278 | SliceSta = SLICE_END; 279 | else if( rtp_hdr->marker == 0 ) 280 | SliceSta = SLICE_MID; 281 | offset = 14; 282 | if( SliceSta == SLICE_START ) { 283 | type = (Buffer[12] & 0xe0) | (Buffer[13] & 0x1f ); 284 | rtp_pack->type = type; 285 | rtp_pack->offset = 0; 286 | rtp_pack->offset = AddH264Head(rtp_pack->buf, type); 287 | rtp_pack->offset += AppendData(rtp_pack->buf, rtp_pack->offset, Buffer + offset, BufferSize - offset); 288 | }else if( SliceSta == SLICE_MID ){ 289 | rtp_pack->offset += AppendData(rtp_pack->buf, rtp_pack->offset, Buffer + offset, BufferSize - offset); 290 | }else if( SliceSta == SLICE_END ) { 291 | rtp_pack->offset += AppendData(rtp_pack->buf, rtp_pack->offset, Buffer + offset, BufferSize - offset); 292 | // 仅在最后一次完成帧结构的时候去组织该帧 293 | return Append_frame(rtp_pack, rtp_pack->type ); 294 | }else{ 295 | printf("UnKnow package!\r\n"); 296 | } 297 | }else if( nalu_type == NALU_MUTIL ) { 298 | printf("聚合包,暂不支持!\r\n"); 299 | }else if( nalu_type == NALU_SIGNEL ) { 300 | // 整个包的解码方式就是在nalu前加上 00001 nalu帧头字节即可 301 | offset = 13; 302 | type = Buffer[12] ; 303 | rtp_pack->offset = 0; 304 | rtp_pack->offset += AddH264Head(rtp_pack->buf, type ); 305 | rtp_pack->offset += AppendData(rtp_pack->buf,rtp_pack->offset, Buffer + offset, BufferSize - offset); 306 | // 对于单一的nalu帧,我们还无法判定是否该直接push到解码通道里,因为还不清楚I帧是否到来 307 | return Append_frame( rtp_pack, type ); 308 | }else{ 309 | printf("unknow package !\r\n"); 310 | } 311 | return 0; 312 | } 313 | 314 | -------------------------------------------------------------------------------- /Client/videoQueue.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9crk/RtspClient/7501dd35c2a220d0777301a8b3d1c0ca6fb6c90b/Client/videoQueue.c -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. [http://fsf.org/] 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Client 端程序已经测试过,ok 2 | Server端代码是从网上下载的,之前已经查看过,协议的实现,对RTP包处理有点问题,后面有时间再改 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #RtspClient 2 | 3 | 鉴于在网上找的RTSP客户端程序都是基于live555的,虽然openRTSP很好用, 4 | 但是移植起来似乎不那么方便,而且基于嵌入式版本的rtsp客户端也不需 5 | 要太多的功能,基于简单的获取h264数据的需求,特实现了该简单的rtsp 6 | 客户端程序 7 | -------------------------------------------------------------------------------- /Server/Makefile: -------------------------------------------------------------------------------- 1 | # hp_ipc Makefile 2 | 3 | include ../Makefile.param 4 | 5 | INC := -I./include 6 | SRC := $(wildcard *.c) $(wildcard ./src/*.c) $(wildcard ./src/sensor/*.c) 7 | OBJ := $(SRC:%.c=%.o) 8 | 9 | CFLAGS += $(INC) 10 | 11 | TARGET := hp_ipc 12 | .PHONY : clean all 13 | 14 | all: $(TARGET) 15 | 16 | 17 | $(TARGET):$(OBJ) 18 | $(CC) $(CFLAGS) -lpthread -lm -o $@ $^ $(MPI_LIBS) $(AUDIO_LIBA) $(SENSOR_LIBS) 19 | 20 | clean: 21 | @rm -f $(TARGET) 22 | @rm -f $(OBJ) 23 | @rm -f $(COMM_OBJ) 24 | info: 25 | echo $(OBJ) 26 | cleanstream: 27 | @rm -f *.h264 28 | @rm -f *.jpg 29 | @rm -f *.mjp 30 | @rm -f *.mp4 31 | -------------------------------------------------------------------------------- /Server/include/camera.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAMERA_H__ 2 | #define __CAMERA_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | 9 | 10 | 11 | int camera_init(void); 12 | int camera_exit(void); 13 | 14 | 15 | 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /Server/include/hp_common.h: -------------------------------------------------------------------------------- 1 | #ifndef __HP_COMM_H__ 2 | #define __HP_COMM_H__ 3 | 4 | #include "hi_common.h" 5 | #include "hi_comm_sys.h" 6 | #include "hi_comm_vb.h" 7 | #include "hi_comm_isp.h" 8 | #include "hi_comm_vi.h" 9 | #include "hi_comm_vo.h" 10 | #include "hi_comm_venc.h" 11 | #include "hi_comm_vpss.h" 12 | #include "hi_comm_vdec.h" 13 | #include "hi_comm_region.h" 14 | #include "hi_comm_adec.h" 15 | #include "hi_comm_aenc.h" 16 | #include "hi_comm_ai.h" 17 | #include "hi_comm_ao.h" 18 | #include "hi_comm_aio.h" 19 | #include "hi_defines.h" 20 | 21 | #include "mpi_sys.h" 22 | #include "mpi_vb.h" 23 | #include "mpi_vi.h" 24 | #include "mpi_vo.h" 25 | #include "mpi_venc.h" 26 | #include "mpi_vpss.h" 27 | #include "mpi_vdec.h" 28 | #include "mpi_region.h" 29 | #include "mpi_adec.h" 30 | #include "mpi_aenc.h" 31 | #include "mpi_ai.h" 32 | #include "mpi_ao.h" 33 | #include "mpi_isp.h" 34 | #include "mpi_ae.h" 35 | #include "mpi_awb.h" 36 | #include "mpi_af.h" 37 | #include "hi_vreg.h" 38 | #include "hi_sns_ctrl.h" 39 | 40 | #ifdef __cplusplus 41 | #if __cplusplus 42 | extern "C"{ 43 | #endif 44 | #endif /* End of #ifdef __cplusplus */ 45 | 46 | 47 | 48 | 49 | 50 | #ifdef __cplusplus 51 | #if __cplusplus 52 | } 53 | #endif 54 | #endif /* End of #ifdef __cplusplus */ 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /Server/include/hp_fpn.h: -------------------------------------------------------------------------------- 1 | #ifndef __HP_FPN_H__ 2 | #define __HP_FPN_H__ 3 | 4 | #include "hp_common.h" 5 | 6 | 7 | #ifdef __cplusplus 8 | #if __cplusplus 9 | extern "C"{ 10 | #endif 11 | #endif /* End of #ifdef __cplusplus */ 12 | 13 | #define ALIGN_BACK(x, a) ((a) * (((x) / (a)))) 14 | 15 | typedef struct st_fpn_attr 16 | { 17 | SIZE_S stPicSize; 18 | VB_BLK VbBlk; 19 | VIDEO_FRAME_INFO_S stVideoFrame; 20 | HI_U32 u32FrmSize; 21 | ISP_FPN_TYPE_E enFpnType; 22 | }FPN_ATTR_S; 23 | 24 | extern HI_S32 FPN_init(const IPC_VEDIO_S* pstIpcVedio); 25 | 26 | 27 | #ifdef __cplusplus 28 | #if __cplusplus 29 | } 30 | #endif 31 | #endif /* End of #ifdef __cplusplus */ 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /Server/include/hp_ipc.h: -------------------------------------------------------------------------------- 1 | #ifndef __HP_IPC_H__ 2 | #define __HP_IPC_H__ 3 | 4 | #include "hp_common.h" 5 | 6 | #ifdef __cplusplus 7 | #if __cplusplus 8 | extern "C"{ 9 | #endif 10 | #endif /* End of #ifdef __cplusplus */ 11 | 12 | typedef struct{ 13 | PIC_SIZE_E e_Size; 14 | HI_FLOAT f32FrameRate; 15 | 16 | }FARMAT_S; 17 | 18 | extern HI_S32 IPC_Init(HI_U32 u32StreamNum, FARMAT_S *stFmt_a); 19 | extern HI_S32 IPC_exit(void); 20 | 21 | 22 | #ifdef __cplusplus 23 | #if __cplusplus 24 | } 25 | #endif 26 | #endif /* End of #ifdef __cplusplus */ 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /Server/include/hp_sys.h: -------------------------------------------------------------------------------- 1 | #ifndef __HP_SYS_H__ 2 | #define __HP_SYS_H__ 3 | 4 | 5 | #ifdef __cplusplus 6 | #if __cplusplus 7 | extern "C"{ 8 | #endif 9 | #endif /* End of #ifdef __cplusplus */ 10 | 11 | #define SYS_ALIGN_WIDTH 64 12 | #define STREAM_MAX_NUM 8 13 | 14 | 15 | typedef enum{ 16 | SENSOR_PIXELPLUS_PS4100K = 0, 17 | SENSOR_PIXELPLUS_PS1210K, 18 | SENSOR_PIXELPLUS_PS3210K, 19 | SENSOR_SONY_IMX290, 20 | }SENSOR_TYPE_E; 21 | 22 | typedef enum 23 | { 24 | HI3518EV200 = 0, 25 | HI3518EV201, 26 | }CHIP_E; 27 | 28 | typedef enum 29 | { 30 | RC_MODE_CBR = 0, 31 | RC_MODE_VBR, 32 | RC_MODE_FIXQP 33 | }RC_MODE_E; 34 | 35 | typedef struct{ 36 | SIZE_S stSize; 37 | PIC_SIZE_E e_Size; 38 | HI_FLOAT f32FrameRate; 39 | PAYLOAD_TYPE_E e_payload; 40 | RC_MODE_E e_RCMode; 41 | }STREAM_FORMAT_S; 42 | 43 | typedef struct{ 44 | CHIP_E e_chip; 45 | SENSOR_TYPE_E e_sensor_type; 46 | WDR_MODE_E e_wdrMode; 47 | PIXEL_FORMAT_E e_pixFmt; 48 | HI_U32 u32StreamNum;/*Number of Stream*/ 49 | STREAM_FORMAT_S astStreamFmt[STREAM_MAX_NUM]; 50 | }IPC_VEDIO_S; 51 | 52 | 53 | #define GET_VB_PIC_HEADER_SIZE(u32AlignHeight)\ 54 | ({\ 55 | unsigned int u32HeadSize;\ 56 | u32HeadSize = VB_HEADER_STRIDE * u32AlignHeight;/* compress header stride 16 */\ 57 | u32HeadSize;\ 58 | }) 59 | 60 | 61 | #define GET_VB_PIXEL_MULTIPLE(e_pixFmt)\ 62 | ({\ 63 | float f32Multiple = 1;\ 64 | switch(e_pixFmt)\ 65 | {\ 66 | case PIXEL_FORMAT_YUV_SEMIPLANAR_444:\ 67 | f32Multiple = 3;\ 68 | break;\ 69 | case PIXEL_FORMAT_YUV_SEMIPLANAR_422:\ 70 | f32Multiple = 2;\ 71 | break;\ 72 | case PIXEL_FORMAT_YUV_SEMIPLANAR_420:\ 73 | f32Multiple = 1.5;\ 74 | break;\ 75 | case PIXEL_FORMAT_YUV_400:\ 76 | f32Multiple = 1;\ 77 | break;\ 78 | default:;break;\ 79 | }\ 80 | f32Multiple;\ 81 | }) 82 | 83 | #define GET_VB_PIC_BLK_SIZE(Width, Height, e_pixFmt)\ 84 | ({\ 85 | unsigned int u32AlignWidth;\ 86 | unsigned int u32AlignHeight;\ 87 | unsigned int u32Size;\ 88 | u32AlignWidth = VB_ALIGN(Width, SYS_ALIGN_WIDTH);\ 89 | u32AlignHeight= VB_ALIGN(Height, SYS_ALIGN_WIDTH);\ 90 | u32Size = (u32AlignWidth * u32AlignHeight + GET_VB_PIC_HEADER_SIZE(u32AlignHeight))\ 91 | * GET_VB_PIXEL_MULTIPLE(e_pixFmt);\ 92 | u32Size;\ 93 | }) 94 | #define GET_VB_BLK_CNT(e_chip)\ 95 | ({\ 96 | unsigned int u32VbBlkCnt = 4;\ 97 | switch(e_chip)\ 98 | {\ 99 | case HI3518EV200:\ 100 | u32VbBlkCnt = 4;\ 101 | break;\ 102 | case HI3518EV201:\ 103 | u32VbBlkCnt = 2;\ 104 | break;\ 105 | default:;break;\ 106 | }\ 107 | u32VbBlkCnt;\ 108 | }) 109 | 110 | extern IPC_VEDIO_S g_stIpcVedio; 111 | 112 | extern HI_S32 mpi_sys_init(IPC_VEDIO_S *pstIpcVedio); 113 | extern HI_VOID mpi_sys_exit(void); 114 | extern HI_S32 s32GetPicSize(PIC_SIZE_E enPicSize, SIZE_S *pstSize); 115 | extern HI_S32 mpi_sys_Bind(IPC_VEDIO_S *pstIpcVedio); 116 | extern HI_S32 mpi_sys_UnBind(IPC_VEDIO_S *pstIpcVedio); 117 | 118 | 119 | #ifdef __cplusplus 120 | #if __cplusplus 121 | } 122 | #endif 123 | #endif /* End of #ifdef __cplusplus */ 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /Server/include/hp_venc.h: -------------------------------------------------------------------------------- 1 | #ifndef __HP_VENC_H__ 2 | #define __HP_VENC_H__ 3 | 4 | 5 | #ifdef __cplusplus 6 | #if __cplusplus 7 | extern "C"{ 8 | #endif 9 | #endif /* End of #ifdef __cplusplus */ 10 | typedef struct{ 11 | 12 | VENC_CHN vencChnNum; 13 | HI_BOOL bGetStreamProcThreadStart; 14 | }ST_VENC_ATTR; 15 | 16 | extern HI_S32 VENC_init(const IPC_VEDIO_S* pstIpcVedio); 17 | extern HI_S32 VENC_exit(void); 18 | 19 | #ifdef __cplusplus 20 | #if __cplusplus 21 | } 22 | #endif 23 | #endif /* End of #ifdef __cplusplus */ 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Server/include/hp_vi.h: -------------------------------------------------------------------------------- 1 | #ifndef __HP_VI_H__ 2 | #define __HP_VI_H__ 3 | 4 | #include "hi_mipi.h" 5 | 6 | #ifdef __cplusplus 7 | #if __cplusplus 8 | extern "C"{ 9 | #endif 10 | #endif /* End of #ifdef __cplusplus */ 11 | 12 | typedef struct{ 13 | ISP_DEV IspDev; 14 | VI_DEV ViDev; 15 | HI_U32 u32ChnNum; 16 | WDR_MODE_E enWDRMode; 17 | combo_dev_attr_t *pstcomboDevAttr; 18 | ISP_PUB_ATTR_S *pstIspPubAttr; 19 | VI_DEV_ATTR_S * pstViDevAttr; 20 | VI_CHN_ATTR_S * pstChnAttr; 21 | }VI_ATTR_S; 22 | 23 | extern HI_S32 VI_exit(void); 24 | extern HI_S32 VI_init(const IPC_VEDIO_S* pstIpcVedio); 25 | 26 | 27 | #ifdef __cplusplus 28 | #if __cplusplus 29 | } 30 | #endif 31 | #endif /* End of #ifdef __cplusplus */ 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /Server/include/hp_vpss.h: -------------------------------------------------------------------------------- 1 | #ifndef __HP_VPSS_H__ 2 | #define __HP_VPSS_H__ 3 | 4 | 5 | #ifdef __cplusplus 6 | #if __cplusplus 7 | extern "C"{ 8 | #endif 9 | #endif /* End of #ifdef __cplusplus */ 10 | typedef struct{ 11 | VPSS_GRP VpssGrp; 12 | VPSS_CHN VpssChnNum; 13 | VPSS_GRP_ATTR_S *pstVpssGrpAttr; 14 | VPSS_CHN_ATTR_S *pstVpssChnAttr; 15 | VPSS_CHN_MODE_S *pstVpssChnMode; 16 | }VPSS_ATTR_S; 17 | 18 | 19 | extern HI_S32 VPSS_exit(void); 20 | extern HI_S32 VPSS_init(const IPC_VEDIO_S* pstIpcVedio); 21 | 22 | #ifdef __cplusplus 23 | #if __cplusplus 24 | } 25 | #endif 26 | #endif /* End of #ifdef __cplusplus */ 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /Server/include/public_api.h: -------------------------------------------------------------------------------- 1 | #ifndef __public_API_H__ 2 | #define __public_API_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | 9 | #define SysRegRead HI_MPI_SYS_GetReg 10 | #define SysRegWrite HI_MPI_SYS_SetReg 11 | 12 | 13 | typedef enum IRCUT_SWITCH_DIRECTION 14 | { 15 | NORMAL_DIRECTION = 0, 16 | CONTRARY_DIRECTION 17 | }IRCUT_SWITCH_DIRECTION; 18 | 19 | typedef enum IRCUT_MODE 20 | { 21 | IRCUT_NIGHT = 0, 22 | IRCUT_DAY, 23 | }IRCUT_MODE; 24 | 25 | typedef enum IRCUT_SWITCH_MODE 26 | { 27 | IRCUT_SYN_INFRARED = 0, 28 | IRCUT_SWITCH_AUTO 29 | }IRCUT_SWITCH_MODE; 30 | 31 | typedef enum CAMERA_SCENE 32 | { 33 | SCENE_DAY = 0, 34 | SCENE_NIGHT 35 | }CAMERA_SCENE; 36 | 37 | 38 | typedef struct _public_sensor_interface 39 | { 40 | int (* sensor_init)(void); 41 | int (* sensor_exit)(void); 42 | int (* sensor_ircut_witch)(int mode); 43 | int (* sensor_get_infraredTypeOrYAVG)(IRCUT_SWITCH_MODE IRCut_switch_mode); 44 | 45 | }public_sensor_interface_st; 46 | 47 | 48 | extern int public_init(void); 49 | extern int public_exit(void); 50 | extern int public_ircut_switch(int mode); 51 | 52 | 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /Server/include/rtsp_server.h: -------------------------------------------------------------------------------- 1 | #ifndef RTSP_SERVER_H 2 | #define RTSP_SERVER_H 3 | #include "hp_common.h" 4 | #include "list.h" 5 | #if !defined(WIN32) 6 | #define __PACKED__ __attribute__ ((__packed__)) 7 | #else 8 | #define __PACKED__ 9 | #endif 10 | 11 | typedef enum 12 | { 13 | RTSP_VIDEO=0, 14 | RTSP_VIDEOSUB=1, 15 | RTSP_AUDIO=2, 16 | RTSP_YUV422=3, 17 | RTSP_RGB=4, 18 | RTSP_VIDEOPS=5, 19 | RTSP_VIDEOSUBPS=6 20 | }enRTSP_MonBlockType; 21 | 22 | struct _RTP_FIXED_HEADER 23 | { 24 | /**//* byte 0 */ 25 | unsigned char csrc_len:4; /**//* expect 0 */ 26 | unsigned char extension:1; /**//* expect 1, see RTP_OP below */ 27 | unsigned char padding:1; /**//* expect 0 */ 28 | unsigned char version:2; /**//* expect 2 */ 29 | /**//* byte 1 */ 30 | unsigned char payload:7; /**//* RTP_PAYLOAD_RTSP */ 31 | unsigned char marker:1; /**//* expect 1 */ 32 | /**//* bytes 2, 3 */ 33 | unsigned short seq_no; 34 | /**//* bytes 4-7 */ 35 | unsigned long timestamp; 36 | /**//* bytes 8-11 */ 37 | unsigned long ssrc; /**//* stream number is used here. */ 38 | } __PACKED__; 39 | 40 | typedef struct _RTP_FIXED_HEADER RTP_FIXED_HEADER; 41 | 42 | struct _NALU_HEADER 43 | { 44 | //byte 0 45 | unsigned char TYPE:5; 46 | unsigned char NRI:2; 47 | unsigned char F:1; 48 | 49 | }__PACKED__; /**//* 1 BYTES */ 50 | 51 | typedef struct _NALU_HEADER NALU_HEADER; 52 | 53 | struct _FU_INDICATOR 54 | { 55 | //byte 0 56 | unsigned char TYPE:5; 57 | unsigned char NRI:2; 58 | unsigned char F:1; 59 | 60 | }__PACKED__; /**//* 1 BYTES */ 61 | 62 | typedef struct _FU_INDICATOR FU_INDICATOR; 63 | 64 | struct _FU_HEADER 65 | { 66 | //byte 0 67 | unsigned char TYPE:5; 68 | unsigned char R:1; 69 | unsigned char E:1; 70 | unsigned char S:1; 71 | } __PACKED__; /**//* 1 BYTES */ 72 | typedef struct _FU_HEADER FU_HEADER; 73 | 74 | struct _AU_HEADER 75 | { 76 | //byte 0, 1 77 | unsigned short au_len; 78 | //byte 2,3 79 | unsigned short frm_len:13; 80 | unsigned char au_index:3; 81 | } __PACKED__; /**//* 1 BYTES */ 82 | typedef struct _AU_HEADER AU_HEADER; 83 | 84 | 85 | extern void RtspServer_init(void); 86 | extern void RtspServer_exit(void); 87 | 88 | int AddFrameToRtspBuf(int nChanNum,enRTSP_MonBlockType eType, char * pData, unsigned int nSize, unsigned int nVidFrmNum,int bIFrm); 89 | 90 | extern HI_S32 SAMPLE_COMM_VENC_Sentjin(VENC_STREAM_S *pstStream); 91 | extern HI_S32 saveStream(VENC_STREAM_S *pstStream); 92 | extern HI_VOID* vdRTPSendThread(HI_VOID *p); 93 | 94 | 95 | 96 | #define nalu_sent_len 1400 97 | //#define nalu_sent_len 1400 98 | #define RTP_H264 96 99 | #define RTP_AUDIO 97 100 | #define MAX_RTSP_CLIENT 1 101 | #define RTSP_SERVER_PORT 554 102 | #define RTSP_RECV_SIZE 1024 103 | #define RTSP_MAX_VID (640*1024) 104 | #define RTSP_MAX_AUD (15*1024) 105 | 106 | #define AU_HEADER_SIZE 4 107 | #define PARAM_STRING_MAX 100 108 | 109 | 110 | 111 | typedef unsigned short u_int16_t; 112 | typedef unsigned char u_int8_t; 113 | typedef u_int16_t portNumBits; 114 | typedef u_int32_t netAddressBits; 115 | typedef long long _int64; 116 | #ifndef FALSE 117 | #define FALSE 0 118 | #endif 119 | #ifndef TRUE 120 | #define TRUE 1 121 | #endif 122 | #define AUDIO_RATE 8000 123 | #define PACKET_BUFFER_END (unsigned int)0x00000000 124 | 125 | 126 | typedef struct 127 | { 128 | int startblock;//代表开始文件块号 129 | int endblock;//代表结束文件块号 130 | int BlockFileNum;//代表录像段数 131 | 132 | }IDXFILEHEAD_INFO;//.IDX文件的头信息 133 | 134 | typedef struct 135 | { 136 | _int64 starttime;//代表开始shijian 137 | _int64 endtime;//代表结束shijian 138 | int startblock;//代表开始文件块号 139 | int endblock;//代表结束文件块号 140 | int stampnum;//代表时间戳数量 141 | }IDXFILEBLOCK_INFO;//.IDX文件段信息 142 | 143 | typedef struct 144 | { 145 | int blockindex;//代表所在文件块号 146 | int pos;//代表该时间戳在文件块的位置 147 | _int64 time;//代表时间戳时间戳的时间点 148 | }IDXSTAMP_INFO;//.IDX文件的时间戳信息 149 | 150 | typedef struct 151 | { 152 | char filename[150];//代表所在文件块号 153 | int pos;//代表该时间戳在文件块的位置 154 | _int64 time;//代表时间戳时间戳的时间点 155 | }FILESTAMP_INFO;//.IDX文件的时间戳信息 156 | 157 | typedef struct 158 | { 159 | char channelid[9]; 160 | _int64 starttime;//代表开始shijian 161 | _int64 endtime;//代表结束shijian 162 | _int64 session; 163 | int type; //类型 164 | int encodetype;//编码格式; 165 | }FIND_INFO;//.IDX文件的时间戳信息 166 | 167 | typedef enum 168 | { 169 | RTP_UDP, 170 | RTP_TCP, 171 | RAW_UDP 172 | }StreamingMode; 173 | 174 | 175 | RTP_FIXED_HEADER *rtp_hdr; 176 | NALU_HEADER *nalu_hdr; 177 | FU_INDICATOR *fu_ind; 178 | FU_HEADER *fu_hdr; 179 | AU_HEADER *au_hdr; 180 | 181 | 182 | extern char g_rtp_playload[20];//ĬÈÏG726-32 183 | extern int g_audio_rate;//ĬÈÏ8000 184 | 185 | typedef enum 186 | { 187 | RTSP_IDLE = 0, 188 | RTSP_CONNECTED = 1, 189 | RTSP_SENDING = 2, 190 | }RTSP_STATUS; 191 | 192 | typedef struct 193 | { 194 | int nVidLen; 195 | int nAudLen; 196 | int bIsIFrm; 197 | int bWaitIFrm; 198 | int bIsFree; 199 | char vidBuf[RTSP_MAX_VID]; 200 | char audBuf[RTSP_MAX_AUD]; 201 | }RTSP_PACK; 202 | 203 | typedef struct 204 | { 205 | int index; 206 | int socket; 207 | int reqchn; 208 | int seqnum; 209 | int seqnum2; 210 | unsigned int tsvid; 211 | unsigned int tsaud; 212 | int status; 213 | int sessionid; 214 | int rtpport[2]; 215 | int rtcpport; 216 | char IP[20]; 217 | char urlPre[PARAM_STRING_MAX]; 218 | }RTSP_CLIENT; 219 | 220 | typedef struct 221 | { 222 | int vidLen; 223 | int audLen; 224 | int nFrameID; 225 | char vidBuf[RTSP_MAX_VID]; 226 | char audBuf[RTSP_MAX_AUD]; 227 | }FRAME_PACK; 228 | typedef struct 229 | { 230 | int startcodeprefix_len; //! 4 for parameter sets and first slice in picture, 3 for everything else (suggested) 231 | unsigned len; //! Length of the NAL unit (Excluding the start code, which does not belong to the NALU) 232 | unsigned max_size; //! Nal Unit Buffer size 233 | int forbidden_bit; //! should be always FALSE 234 | int nal_reference_idc; //! NALU_PRIORITY_xxxx 235 | int nal_unit_type; //! NALU_TYPE_xxxx 236 | char *buf; //! contains the first byte followed by the EBSP 237 | unsigned short lost_packets; //! true, if packet loss is detected 238 | } NALU_t; 239 | extern int udpfd; 240 | extern RTSP_CLIENT g_rtspClients[MAX_RTSP_CLIENT]; 241 | typedef struct _rtpbuf 242 | { 243 | struct list_head list; 244 | HI_S32 len; 245 | char * buf; 246 | }RTPbuf_s; 247 | extern struct list_head RTPbuf_head; 248 | 249 | 250 | #endif 251 | 252 | -------------------------------------------------------------------------------- /Server/readme.txt: -------------------------------------------------------------------------------- 1 | put directory hp-ipc into sdk.../mpp/sample/ 2 | cd hp-ipc 3 | make 4 | -------------------------------------------------------------------------------- /Server/src/Makefile: -------------------------------------------------------------------------------- 1 | SRC=$(wildcard *.c) 2 | OBJ=$(SRC:%.c=%.o) 3 | APP=rtsp 4 | $SRC_UTILS=$(wildcard ../utils/*.c) 5 | OBJ_UTILS=$(SRC_UTILS:%.c=%.o) 6 | 7 | CFLAGS=-I../include -I. -I./sensor/ 8 | 9 | all: $(APP) 10 | $(APP) : $(OBJ_UTILS) $(OBJ) 11 | $(CC) $(CFLAGS) -o $@ $^ -lpthread -lrt -lm 12 | 13 | 14 | $(OBJ) : %.o:%.c 15 | $(CC) $(CFLAGS) -c $^ -o $@ 16 | 17 | $(OBJ_UTILS) : %.o:%.c 18 | $(CC) $(CFLAGS) -c $^ -o $@ 19 | 20 | 21 | rm -f $(OBJ) 22 | 23 | .PHONY: clean 24 | clean: 25 | @rm -f $(APP) 26 | @rm -f $(OBJ) 27 | 28 | -------------------------------------------------------------------------------- /Server/src/camera.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "hp_common.h" 17 | #include "camera.h" 18 | #include "public_api.h" 19 | #include "rtsp_server.h" 20 | #include "hp_ipc.h" 21 | 22 | 23 | int camera_init(void) 24 | { 25 | FARMAT_S stFmt_a[3] = 26 | { 27 | {PIC_HD1080,16}, 28 | {PIC_VGA,30}, 29 | {PIC_QVGA,30} 30 | }; 31 | IPC_Init(1,stFmt_a); 32 | public_init(); 33 | RtspServer_init(); 34 | FPN_init(NULL); 35 | return 0; 36 | } 37 | int camera_exit(void) 38 | { 39 | 40 | IPC_exit(); 41 | public_exit(); 42 | RtspServer_exit(); 43 | return 0; 44 | } 45 | 46 | int main() 47 | { 48 | camera_init(); 49 | getchar(); 50 | getchar(); 51 | camera_exit(); 52 | return 0; 53 | } 54 | 55 | int camera_set_Ircut(int mode) 56 | { 57 | 58 | int ret = -1; 59 | ret = public_ircut_switch(mode); 60 | return ret; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /Server/src/hp_fpn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "hp_common.h" 17 | #include "hp_sys.h" 18 | #include "hp_fpn.h" 19 | 20 | VB_POOL g_Pool; 21 | char *FpnFileName= "PS3210_1920x1080_10bit.raw"; 22 | HI_S32 FPN_init(const IPC_VEDIO_S* pstIpcVedio) 23 | { 24 | VI_CHN_ATTR_S stTempChnAttr; 25 | VI_CHN ViChn = 0; 26 | FPN_ATTR_S stFPNattr = {0}; 27 | HI_S32 s32Ret = HI_SUCCESS; 28 | HI_U32 u32BlkSize; 29 | 30 | s32Ret = HI_MPI_VI_GetChnAttr(ViChn, &stTempChnAttr); 31 | if(HI_SUCCESS != s32Ret) 32 | { 33 | printf("get vi chn attr failed!"); 34 | return HI_FAILURE; 35 | } 36 | memcpy(&stFPNattr.stPicSize,&stTempChnAttr.stDestSize,sizeof(SIZE_S)); 37 | stFPNattr.enFpnType = ISP_FPN_TYPE_FRAME; 38 | stFPNattr.stVideoFrame.stVFrame.enPixelFormat = PIXEL_FORMAT_RGB_BAYER_10BPP; 39 | stFPNattr.stVideoFrame.stVFrame.enCompressMode = COMPRESS_MODE_NONE; 40 | stFPNattr.stVideoFrame.stVFrame.u32Field = VIDEO_FIELD_FRAME; 41 | 42 | /* FPN need one private 422 VB */ 43 | u32BlkSize = GET_VB_PIC_BLK_SIZE(stFPNattr.stPicSize.u32Width, stFPNattr.stPicSize.u32Height, PIXEL_FORMAT_YUV_SEMIPLANAR_422); 44 | g_Pool = HI_MPI_VB_CreatePool(u32BlkSize, 1, NULL); 45 | if ( VB_INVALID_POOLID == g_Pool ) 46 | { 47 | printf("create vb err\n"); 48 | return HI_FAILURE; 49 | } 50 | 51 | /* fpn calibrate, save dark frame file */ 52 | s32Ret = s32FPN_Calibrate(&stFPNattr); 53 | if (HI_SUCCESS != s32Ret) 54 | { 55 | printf("FPN calibrate failed %#x!\n", s32Ret); 56 | return HI_FAILURE; 57 | } 58 | 59 | /* fpn correction, read dark frame file */ 60 | s32Ret = s32FPN_Correction(&stFPNattr); 61 | if (HI_SUCCESS != s32Ret) 62 | { 63 | printf("FPN correction failed %#x!\n", s32Ret); 64 | return HI_FAILURE; 65 | } 66 | return HI_SUCCESS; 67 | } 68 | HI_S32 s32FPN_Calibrate(FPN_ATTR_S *pstFPNattr) 69 | { 70 | VI_CHN ViChn = 0; 71 | ISP_DEV IspDev = 0; 72 | ISP_FPN_CALIBRATE_ATTR_S stFpnCalAttr; 73 | 74 | HI_S32 s32Ret = HI_SUCCESS; 75 | 76 | 77 | s32Ret = s32GetVBFromPool(pstFPNattr); 78 | if(HI_SUCCESS != s32Ret) 79 | { 80 | printf("alloc mem failed!"); 81 | return HI_FAILURE; 82 | } 83 | printf("\n please turn off camera aperture!\n"); 84 | printf("\nhit the Enter key ,start calibrate!\n"); 85 | getchar(); 86 | 87 | s32Ret = HI_MPI_VI_DisableChn(ViChn); 88 | if(HI_SUCCESS != s32Ret) 89 | { 90 | printf("disable vi chn failed!"); 91 | return HI_FAILURE; 92 | } 93 | stFpnCalAttr.u32FrameNum = 16; 94 | stFpnCalAttr.u32Threshold = 512; 95 | stFpnCalAttr.enFpnType = pstFPNattr->enFpnType; 96 | memcpy(&stFpnCalAttr.stFpnCaliFrame.stFpnFrame, &pstFPNattr->stVideoFrame, sizeof(VIDEO_FRAME_INFO_S)); 97 | stFpnCalAttr.stFpnCaliFrame.u32Offset = 0; 98 | 99 | s32Ret = HI_MPI_ISP_FPNCalibrate(IspDev, &stFpnCalAttr); 100 | if (HI_SUCCESS != s32Ret) 101 | { 102 | printf("HI_MPI_ISP_FPNCalibrate err: 0x%x\n", s32Ret); 103 | return s32Ret; 104 | } 105 | /* save RAW data */ 106 | printf("\nafter calibrate, offset =0x%x,ISO = %d, frmsize = %d\n",\ 107 | stFpnCalAttr.stFpnCaliFrame.u32Offset,stFpnCalAttr.stFpnCaliFrame.u32Iso,stFpnCalAttr.stFpnCaliFrame.u32FrmSize); 108 | 109 | s32Ret = HI_MPI_VI_EnableChn(ViChn); 110 | if(HI_SUCCESS != s32Ret) 111 | { 112 | printf("enable vi chn failed!"); 113 | return HI_FAILURE; 114 | } 115 | 116 | s32Ret = s32SaveFpnData(&stFpnCalAttr.stFpnCaliFrame, pstFPNattr); 117 | s32Ret = s32ReleaseVBToPool(pstFPNattr); 118 | 119 | return HI_SUCCESS; 120 | } 121 | 122 | HI_S32 s32FPN_Correction(FPN_ATTR_S *pstFPNattr) 123 | { 124 | VI_CHN ViChn = 0; 125 | ISP_FPN_ATTR_S stFPNCorAttr; 126 | ISP_DEV IspDev = 0; 127 | HI_S32 s32Ret = HI_SUCCESS; 128 | 129 | s32Ret = s32ReadFpnData(&stFPNCorAttr.stFpnFrmInfo, pstFPNattr); 130 | if(HI_SUCCESS != s32Ret) 131 | { 132 | printf("read Fpn file failed!"); 133 | return HI_FAILURE; 134 | } 135 | 136 | memcpy(&stFPNCorAttr.stFpnFrmInfo.stFpnFrame, &pstFPNattr->stVideoFrame, sizeof(VIDEO_FRAME_INFO_S)); 137 | 138 | stFPNCorAttr.bEnable = HI_TRUE; 139 | stFPNCorAttr.enOpType = OP_TYPE_MANUAL; 140 | stFPNCorAttr.enFpnType = pstFPNattr->enFpnType; 141 | stFPNCorAttr.stManual.u32Strength = 0x100; 142 | 143 | s32Ret = HI_MPI_ISP_SetFPNAttr(IspDev, &stFPNCorAttr); 144 | if(HI_SUCCESS != s32Ret) 145 | { 146 | printf("fpn correction fail 0x%x\n", s32Ret); 147 | return HI_FAILURE; 148 | } 149 | s32Ret = s32ReleaseVBToPool(pstFPNattr); 150 | return HI_SUCCESS; 151 | } 152 | 153 | HI_S32 s32GetVBFromPool(FPN_ATTR_S *pstFPNattr) 154 | { 155 | HI_U32 u32Width; 156 | HI_U32 u32Height; 157 | PIXEL_FORMAT_E enPixelFormat; 158 | 159 | HI_U32 u32Stride; 160 | HI_U32 u32CStride; 161 | HI_U32 u32LumaSize; 162 | HI_U32 u32ChrmSize; 163 | HI_U32 u32Size; 164 | VB_BLK VbBlk; 165 | HI_U32 u32PhyAddr; 166 | HI_VOID *pVirAddr = NULL; 167 | VIDEO_FRAME_INFO_S *pstVFrameInfo = &pstFPNattr->stVideoFrame; 168 | u32Width = pstFPNattr->stPicSize.u32Width; 169 | u32Height = pstFPNattr->stPicSize.u32Height; 170 | enPixelFormat = pstFPNattr->stVideoFrame.stVFrame.enPixelFormat; 171 | 172 | /* alloc 16bit/pixel memory */ 173 | u32Stride = ALIGN_BACK(u32Width * 2, 16); 174 | printf("u32Stride: %d\n", u32Stride); 175 | u32CStride = u32Width; 176 | u32LumaSize = u32Stride * u32Height; 177 | if (PIXEL_FORMAT_YUV_SEMIPLANAR_422 == enPixelFormat) 178 | { 179 | u32ChrmSize = (u32CStride * u32Height) >> 1;/* YUV 422 */ 180 | } 181 | else if ((PIXEL_FORMAT_RGB_BAYER == enPixelFormat) 182 | ||(PIXEL_FORMAT_RGB_BAYER_12BPP == enPixelFormat) 183 | ||(PIXEL_FORMAT_RGB_BAYER_10BPP == enPixelFormat) 184 | ||(PIXEL_FORMAT_RGB_BAYER_8BPP == enPixelFormat)) 185 | { 186 | u32ChrmSize = 0; 187 | } 188 | else 189 | { 190 | u32ChrmSize = (u32CStride * u32Height) >> 2;/* YUV 420 */ 191 | } 192 | u32Size = u32LumaSize + (u32ChrmSize << 1); 193 | printf("===============u32Size: %d\n", u32Size); 194 | pstFPNattr->u32FrmSize = u32Size; 195 | 196 | /* alloc video buffer block ---------------------------------------------------------- */ 197 | VbBlk = HI_MPI_VB_GetBlock(g_Pool, pstFPNattr->u32FrmSize, HI_NULL); 198 | if (VB_INVALID_HANDLE == VbBlk) 199 | { 200 | printf("HI_MPI_VB_GetBlock err! size:%d\n",u32Size); 201 | return HI_FAILURE; 202 | } 203 | pstFPNattr->VbBlk = VbBlk; 204 | 205 | printf("VbBlk: 0x%x\n", VbBlk); 206 | 207 | u32PhyAddr = HI_MPI_VB_Handle2PhysAddr(VbBlk); 208 | if (0 == u32PhyAddr) 209 | { 210 | printf("HI_MPI_VB_Handle2PhysAddr err!\n"); 211 | return HI_FAILURE; 212 | } 213 | 214 | pstVFrameInfo->u32PoolId = HI_MPI_VB_Handle2PoolId(VbBlk); 215 | if (VB_INVALID_POOLID == pstVFrameInfo->u32PoolId) 216 | { 217 | printf("HI_MPI_VB_Handle2PoolId err!\n"); 218 | HI_MPI_SYS_Exit(); 219 | HI_MPI_VB_Exit(); 220 | return HI_FAILURE; 221 | } 222 | 223 | pstVFrameInfo->stVFrame.u32PhyAddr[0] = u32PhyAddr; 224 | pstVFrameInfo->stVFrame.u32PhyAddr[1] = pstVFrameInfo->stVFrame.u32PhyAddr[0] + u32LumaSize; 225 | pstVFrameInfo->stVFrame.u32PhyAddr[2] = pstVFrameInfo->stVFrame.u32PhyAddr[1] + u32ChrmSize; 226 | 227 | pstVFrameInfo->stVFrame.pVirAddr[0] = pVirAddr; 228 | pstVFrameInfo->stVFrame.pVirAddr[1] = pstVFrameInfo->stVFrame.pVirAddr[0] + u32LumaSize; 229 | pstVFrameInfo->stVFrame.pVirAddr[2] = pstVFrameInfo->stVFrame.pVirAddr[1] + u32ChrmSize; 230 | 231 | pstVFrameInfo->stVFrame.u32Width = u32Width; 232 | pstVFrameInfo->stVFrame.u32Height = u32Height; 233 | pstVFrameInfo->stVFrame.u32Stride[0] = u32Stride; 234 | pstVFrameInfo->stVFrame.u32Stride[1] = u32Stride; 235 | pstVFrameInfo->stVFrame.u32Stride[2] = u32Stride; 236 | 237 | return HI_SUCCESS; 238 | } 239 | 240 | 241 | HI_S32 s32SaveFpnData(ISP_FPN_FRAME_INFO_S *pVBuf, FPN_ATTR_S *pstFPNattr) 242 | { 243 | HI_U8* pU8VBufVirt_Y; 244 | HI_U32 phy_addr,size; 245 | HI_U8* pUserPageAddr[2]; 246 | FILE * pfd; 247 | 248 | pfd = fopen(FpnFileName, "wb"); 249 | if (NULL == pfd) 250 | { 251 | printf("open file %s err!\n",FpnFileName); 252 | return HI_FAILURE; 253 | } 254 | 255 | size = (pVBuf->stFpnFrame.stVFrame.u32Stride[0]) * (pVBuf->stFpnFrame.stVFrame.u32Height); 256 | printf("pVBuf->u32Stride[0]: %d, size: %d\n", pVBuf->stFpnFrame.stVFrame.u32Stride[0], size); 257 | phy_addr = pVBuf->stFpnFrame.stVFrame.u32PhyAddr[0]; 258 | 259 | pUserPageAddr[0] = (HI_U8 *) HI_MPI_SYS_Mmap(phy_addr, size); 260 | if (NULL == pUserPageAddr[0]) 261 | { 262 | printf("HI_MPI_SYS_Mmap null\n"); 263 | return HI_FAILURE; 264 | } 265 | 266 | pU8VBufVirt_Y = (HI_U8*)pUserPageAddr[0]; 267 | 268 | /* save Y ----------------------------------------------------------------*/ 269 | fprintf(stderr, "saving......Raw data......u32Stride[0]: %d, width: %d, height: %d\n" 270 | , pVBuf->stFpnFrame.stVFrame.u32Stride[0] 271 | , pVBuf->stFpnFrame.stVFrame.u32Width 272 | , pVBuf->stFpnFrame.stVFrame.u32Height); 273 | fflush(stderr); 274 | 275 | fwrite(pU8VBufVirt_Y, pVBuf->u32FrmSize, 1, pfd); 276 | 277 | /* save offset */ 278 | fwrite(&pVBuf->u32Offset, 4, 1, pfd); 279 | 280 | /* save fpn frame size */ 281 | fwrite(&pVBuf->u32FrmSize, 4, 1, pfd); 282 | 283 | /* save ISO */ 284 | fwrite(&pVBuf->u32Iso, 4, 1, pfd); 285 | fflush(pfd); 286 | 287 | fflush(stderr); 288 | 289 | HI_MPI_SYS_Munmap(pUserPageAddr[0], size); 290 | fclose(pfd); 291 | return HI_FAILURE; 292 | } 293 | 294 | HI_S32 s32ReadFpnData(ISP_FPN_FRAME_INFO_S *pVBuf, FPN_ATTR_S *pstFPNattr) 295 | { 296 | FILE *pfd; 297 | HI_S32 s32Ret = HI_SUCCESS; 298 | HI_U32 u32LStride; 299 | HI_U32 u32CStride; 300 | HI_U32 u32Width; 301 | HI_U32 u32Height; 302 | HI_U32 u32LumaSize = 0; 303 | HI_U32 u32ChrmSize = 0; 304 | HI_U32 u32Size; 305 | VB_BLK VbBlk; 306 | HI_U32 u32PhyAddr; 307 | HI_U8 *pVirAddr; 308 | HI_U32 u32Stride; 309 | VIDEO_FRAME_INFO_S *pstVFrameInfo = &pstFPNattr->stVideoFrame; 310 | 311 | /* open YUV file */ 312 | printf("open dark frame file: %s. \n", FpnFileName); 313 | pfd = fopen(FpnFileName, "rb"); 314 | if (!pfd) 315 | { 316 | printf("open file -> %s fail \n", FpnFileName); 317 | return HI_FAILURE; 318 | } 319 | 320 | u32Width = pstFPNattr->stPicSize.u32Width; 321 | u32Height = pstFPNattr->stPicSize.u32Height; 322 | 323 | /* read frame information from YUV file */ 324 | if (PIXEL_FORMAT_RGB_BAYER == pstVFrameInfo->stVFrame.enPixelFormat) 325 | { 326 | u32Stride = ALIGN_BACK(u32Width*2, 16); 327 | } 328 | else if (PIXEL_FORMAT_RGB_BAYER_10BPP == pstVFrameInfo->stVFrame.enPixelFormat) 329 | { 330 | u32Stride = (u32Width * 10 + 127) / 128 * 128 / 8; 331 | } 332 | else if (PIXEL_FORMAT_RGB_BAYER_8BPP == pstVFrameInfo->stVFrame.enPixelFormat) 333 | { 334 | u32Stride = (u32Width * 8 + 127) / 128 * 128 / 8; 335 | } 336 | else 337 | { 338 | printf("Func: %s() Line[%d], unsupported pixel format: %d\n", 339 | __FUNCTION__, __LINE__, pstVFrameInfo->stVFrame.enPixelFormat); 340 | return HI_FAILURE; 341 | } 342 | 343 | u32LStride = u32Stride; 344 | u32CStride = u32Stride; 345 | 346 | //////////////////////////////////////////////////////// 347 | /* seek end of file */ 348 | s32Ret = fseek(pfd, -8, SEEK_END); 349 | if (0 != s32Ret) 350 | { 351 | printf("Func: %s(), line: [%d], get frame size failed: %s\n", __FUNCTION__, __LINE__, strerror(errno)); 352 | return HI_FAILURE; 353 | } 354 | /* get fpn frame size */ 355 | fread(&u32Size, 1, 4, pfd); 356 | /* back to begin of file */ 357 | fseek(pfd, 0L, SEEK_SET); 358 | //////////////////////////////////////////////////////// 359 | 360 | /* alloc video buffer block ---------------------------------------------------------- */ 361 | VbBlk = HI_MPI_VB_GetBlock(g_Pool, u32Size, HI_NULL); 362 | if (VB_INVALID_HANDLE == VbBlk) 363 | { 364 | printf("HI_MPI_VB_GetBlock err! size:%d\n",u32Size); 365 | HI_MPI_SYS_Exit(); 366 | HI_MPI_VB_Exit(); 367 | return HI_FAILURE; 368 | } 369 | pstFPNattr->VbBlk = VbBlk; 370 | 371 | u32PhyAddr = HI_MPI_VB_Handle2PhysAddr(VbBlk); 372 | if (0 == u32PhyAddr) 373 | { 374 | printf("HI_MPI_VB_Handle2PhysAddr err!\n"); 375 | HI_MPI_SYS_Exit(); 376 | HI_MPI_VB_Exit(); 377 | return HI_FAILURE; 378 | } 379 | pVirAddr = (HI_U8 *) HI_MPI_SYS_Mmap(u32PhyAddr, u32Size); 380 | if (NULL == pVirAddr) 381 | { 382 | printf("HI_MPI_SYS_Mmap err!\n"); 383 | HI_MPI_SYS_Exit(); 384 | HI_MPI_VB_Exit(); 385 | return HI_FAILURE; 386 | } 387 | 388 | pstVFrameInfo->u32PoolId = HI_MPI_VB_Handle2PoolId(VbBlk); 389 | if (VB_INVALID_POOLID == pstVFrameInfo->u32PoolId) 390 | { 391 | HI_MPI_SYS_Exit(); 392 | HI_MPI_VB_Exit(); 393 | return HI_FAILURE; 394 | } 395 | 396 | pstVFrameInfo->stVFrame.u32PhyAddr[0] = u32PhyAddr; 397 | pstVFrameInfo->stVFrame.u32PhyAddr[1] = pstVFrameInfo->stVFrame.u32PhyAddr[0] + u32LumaSize; 398 | pstVFrameInfo->stVFrame.u32PhyAddr[2] = pstVFrameInfo->stVFrame.u32PhyAddr[1] + u32ChrmSize; 399 | 400 | pstVFrameInfo->stVFrame.pVirAddr[0] = pVirAddr; 401 | pstVFrameInfo->stVFrame.pVirAddr[1] = pstVFrameInfo->stVFrame.pVirAddr[0] + u32LumaSize; 402 | pstVFrameInfo->stVFrame.pVirAddr[2] = pstVFrameInfo->stVFrame.pVirAddr[1] + u32ChrmSize; 403 | 404 | pstVFrameInfo->stVFrame.u32Width = u32Width; 405 | pstVFrameInfo->stVFrame.u32Height = u32Height; 406 | pstVFrameInfo->stVFrame.u32Stride[0] = u32LStride; 407 | pstVFrameInfo->stVFrame.u32Stride[1] = u32CStride; 408 | pstVFrameInfo->stVFrame.u32Stride[2] = u32CStride; 409 | 410 | /***************************************************************** 411 | raw file storage layout: 412 | /////////////////////////////////////////////////// 413 | |-------------------------------------------------| 414 | |-------------------------------------------------| 415 | |-------------------------------------------------| 416 | |-------------------------------------------------| 417 | |-------------------------------------------------| 418 | |-------------------------------------------------| 419 | |-------------------|------|------|---------------| 420 | offset size u32iso 421 | ****************************************************************/ 422 | 423 | /* seek end of file */ 424 | s32Ret = fseek(pfd, -4, SEEK_END); 425 | if (0 != s32Ret) 426 | { 427 | printf("Func: %s(), line: [%d], get iso failed: %s\n", __FUNCTION__, __LINE__, strerror(errno)); 428 | return; 429 | } 430 | /* get calibrate ISO */ 431 | fread(&pVBuf->u32Iso, 4, 1, pfd); 432 | 433 | /* get fpn frame size */ 434 | pVBuf->u32FrmSize = u32Size; 435 | 436 | /* get fpn offset */ 437 | s32Ret = fseek(pfd, -12, SEEK_END); 438 | if (0 != s32Ret) 439 | { 440 | printf("Func: %s(), line: [%d], get fpn offset failed: %s\n", __FUNCTION__, __LINE__, strerror(errno)); 441 | return; 442 | } 443 | fread(&pVBuf->u32Offset, 4, 1, pfd); 444 | 445 | /* back to begin of file */ 446 | fseek(pfd, 0L, SEEK_SET); 447 | fread(pstVFrameInfo->stVFrame.pVirAddr[0], 1, u32Size, pfd); 448 | 449 | fclose(pfd); 450 | HI_MPI_SYS_Munmap(pVirAddr, u32Size); 451 | return s32Ret; 452 | } 453 | 454 | HI_S32 s32ReleaseVBToPool(FPN_ATTR_S *pstFPNattr) 455 | { 456 | HI_S32 s32Ret = HI_SUCCESS; 457 | s32Ret = HI_MPI_VB_ReleaseBlock(pstFPNattr->VbBlk); 458 | if (HI_SUCCESS != s32Ret) 459 | { 460 | printf("HI_MPI_VB_ReleaseBlock err: 0x%x\n", s32Ret); 461 | } 462 | return HI_FAILURE; 463 | } 464 | 465 | -------------------------------------------------------------------------------- /Server/src/hp_ipc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "hp_ipc.h" 17 | #include "hp_sys.h" 18 | #include "hp_vi.h" 19 | #include "hp_vpss.h" 20 | #include "hp_venc.h" 21 | 22 | 23 | HI_S32 IPC_Init(HI_U32 u32StreamNum, FARMAT_S *stFmt_a) 24 | { 25 | HI_S32 i,s32Ret; 26 | if((STREAM_MAX_NUM < u32StreamNum) || (NULL == stFmt_a)) 27 | { 28 | printf("Invalid parament\n"); 29 | return HI_FAILURE; 30 | } 31 | g_stIpcVedio.e_chip = HI3518EV200; 32 | g_stIpcVedio.e_sensor_type = SENSOR_PIXELPLUS_PS3210K; 33 | g_stIpcVedio.e_wdrMode = WDR_MODE_NONE; 34 | g_stIpcVedio.e_pixFmt = PIXEL_FORMAT_YUV_SEMIPLANAR_420; 35 | g_stIpcVedio.u32StreamNum = u32StreamNum; 36 | for(i = 0; i < u32StreamNum; i++) 37 | { 38 | s32GetPicSize(stFmt_a[i].e_Size,&(g_stIpcVedio.astStreamFmt[i].stSize)); 39 | g_stIpcVedio.astStreamFmt[i].e_Size = stFmt_a[i].e_Size; 40 | g_stIpcVedio.astStreamFmt[i].f32FrameRate = stFmt_a[i].f32FrameRate; 41 | g_stIpcVedio.astStreamFmt[i].e_payload = PT_H264; 42 | g_stIpcVedio.astStreamFmt[i].e_RCMode = RC_MODE_CBR; 43 | } 44 | 45 | 46 | s32Ret = mpi_sys_init(&g_stIpcVedio); 47 | if (HI_SUCCESS != s32Ret) 48 | { 49 | printf("system init failed with %d!\n", s32Ret); 50 | goto END_EXIT_0; 51 | } 52 | 53 | s32Ret = VI_init(&g_stIpcVedio); 54 | if (HI_SUCCESS != s32Ret) 55 | { 56 | printf("start vi failed!\n"); 57 | goto END_EXIT_1; 58 | } 59 | 60 | s32Ret = VPSS_init(&g_stIpcVedio); 61 | if (HI_SUCCESS != s32Ret) 62 | { 63 | printf("start vpss failed!\n"); 64 | goto END_EXIT_2; 65 | } 66 | 67 | s32Ret = mpi_sys_Bind(&g_stIpcVedio); 68 | if (HI_SUCCESS != s32Ret) 69 | { 70 | printf("Bind failed!\n"); 71 | goto END_EXIT_3; 72 | } 73 | 74 | s32Ret = VENC_init(&g_stIpcVedio); 75 | if (HI_SUCCESS != s32Ret) 76 | { 77 | printf("start venc failed!\n"); 78 | goto END_EXIT_4; 79 | } 80 | 81 | return HI_SUCCESS; 82 | 83 | END_EXIT_4: 84 | VENC_exit(); 85 | END_EXIT_3: 86 | mpi_sys_UnBind(&g_stIpcVedio); 87 | END_EXIT_2: 88 | VPSS_exit(); 89 | END_EXIT_1: 90 | VI_exit(); 91 | END_EXIT_0: 92 | mpi_sys_exit(); 93 | exit(0); 94 | return HI_SUCCESS; 95 | } 96 | 97 | HI_S32 IPC_exit(void) 98 | { 99 | VENC_exit(); 100 | mpi_sys_UnBind(&g_stIpcVedio); 101 | VPSS_exit(); 102 | VI_exit(); 103 | mpi_sys_exit(); 104 | return HI_SUCCESS; 105 | } 106 | 107 | 108 | -------------------------------------------------------------------------------- /Server/src/hp_sys.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | 21 | IPC_VEDIO_S g_stIpcVedio; 22 | 23 | /****************************************************************************** 24 | * function : vb init & MPI system init 25 | ******************************************************************************/ 26 | HI_S32 mpi_sys_init(IPC_VEDIO_S *pstIpcVedio) 27 | { 28 | MPP_SYS_CONF_S stSysConf = {0}; 29 | VB_CONF_S stVbConf; 30 | HI_S32 i,s32Ret = HI_FAILURE; 31 | SIZE_S *stSize; 32 | PIXEL_FORMAT_E e_pixFmt; 33 | HI_U32 u32VbBlkCnt; 34 | 35 | if (NULL == pstIpcVedio) 36 | { 37 | printf("input parameter is null, it is invaild!\n"); 38 | return HI_FAILURE; 39 | } 40 | HI_MPI_SYS_Exit(); 41 | HI_MPI_VB_Exit(); 42 | memset(&stVbConf,0,sizeof(VB_CONF_S)); 43 | stVbConf.u32MaxPoolCnt = 128; 44 | u32VbBlkCnt = GET_VB_BLK_CNT(pstIpcVedio->e_chip); 45 | for(i = 0; i < pstIpcVedio->u32StreamNum; i++) 46 | { 47 | stSize = &(pstIpcVedio->astStreamFmt[i].stSize); 48 | e_pixFmt = pstIpcVedio->e_pixFmt; 49 | stVbConf.astCommPool[i].u32BlkSize = GET_VB_PIC_BLK_SIZE(stSize->u32Width, stSize->u32Height, e_pixFmt); 50 | stVbConf.astCommPool[i].u32BlkCnt = u32VbBlkCnt; 51 | } 52 | 53 | s32Ret = HI_MPI_VB_SetConf(&stVbConf); 54 | if (HI_SUCCESS != s32Ret) 55 | { 56 | printf("HI_MPI_VB_SetConf failed!\n"); 57 | return HI_FAILURE; 58 | } 59 | 60 | s32Ret = HI_MPI_VB_Init(); 61 | if (HI_SUCCESS != s32Ret) 62 | { 63 | printf("HI_MPI_VB_Init failed!\n"); 64 | return HI_FAILURE; 65 | } 66 | 67 | stSysConf.u32AlignWidth = SYS_ALIGN_WIDTH; 68 | s32Ret = HI_MPI_SYS_SetConf(&stSysConf); 69 | if (HI_SUCCESS != s32Ret) 70 | { 71 | printf("HI_MPI_SYS_SetConf failed\n"); 72 | return HI_FAILURE; 73 | } 74 | 75 | s32Ret = HI_MPI_SYS_Init(); 76 | if (HI_SUCCESS != s32Ret) 77 | { 78 | printf("HI_MPI_SYS_Init failed!\n"); 79 | return HI_FAILURE; 80 | } 81 | 82 | return HI_SUCCESS; 83 | } 84 | 85 | /****************************************************************************** 86 | * function : vb exit & MPI system exit 87 | ******************************************************************************/ 88 | HI_VOID mpi_sys_exit(void) 89 | { 90 | HI_MPI_SYS_Exit(); 91 | HI_MPI_VB_Exit(); 92 | return; 93 | } 94 | 95 | 96 | /****************************************************************************** 97 | * function : get picture size(w*h), according Norm and enPicSize 98 | ******************************************************************************/ 99 | HI_S32 s32GetPicSize(PIC_SIZE_E enPicSize, SIZE_S *pstSize) 100 | { 101 | VIDEO_NORM_E enNorm = VIDEO_ENCODING_MODE_PAL; 102 | switch (enPicSize) 103 | { 104 | case PIC_QCIF: 105 | pstSize->u32Width = 176; 106 | pstSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?144:120; 107 | break; 108 | case PIC_CIF: 109 | pstSize->u32Width = 352; 110 | pstSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?288:240; 111 | break; 112 | case PIC_D1: 113 | pstSize->u32Width = 720; 114 | pstSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480; 115 | break; 116 | case PIC_960H: 117 | pstSize->u32Width = 960; 118 | pstSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480; 119 | break; 120 | case PIC_2CIF: 121 | pstSize->u32Width = 360; 122 | pstSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480; 123 | break; 124 | case PIC_QVGA: /* 320 * 240 */ 125 | pstSize->u32Width = 320; 126 | pstSize->u32Height = 240; 127 | break; 128 | case PIC_VGA: /* 640 * 480 */ 129 | pstSize->u32Width = 640; 130 | pstSize->u32Height = 480; 131 | break; 132 | case PIC_XGA: /* 1024 * 768 */ 133 | pstSize->u32Width = 1024; 134 | pstSize->u32Height = 768; 135 | break; 136 | case PIC_SXGA: /* 1400 * 1050 */ 137 | pstSize->u32Width = 1400; 138 | pstSize->u32Height = 1050; 139 | break; 140 | case PIC_UXGA: /* 1600 * 1200 */ 141 | pstSize->u32Width = 1600; 142 | pstSize->u32Height = 1200; 143 | break; 144 | case PIC_QXGA: /* 2048 * 1536 */ 145 | pstSize->u32Width = 2048; 146 | pstSize->u32Height = 1536; 147 | break; 148 | case PIC_WVGA: /* 854 * 480 */ 149 | pstSize->u32Width = 854; 150 | pstSize->u32Height = 480; 151 | break; 152 | case PIC_WSXGA: /* 1680 * 1050 */ 153 | pstSize->u32Width = 1680; 154 | pstSize->u32Height = 1050; 155 | break; 156 | case PIC_WUXGA: /* 1920 * 1200 */ 157 | pstSize->u32Width = 1920; 158 | pstSize->u32Height = 1200; 159 | break; 160 | case PIC_WQXGA: /* 2560 * 1600 */ 161 | pstSize->u32Width = 2560; 162 | pstSize->u32Height = 1600; 163 | break; 164 | case PIC_HD720: /* 1280 * 720 */ 165 | pstSize->u32Width = 1280; 166 | pstSize->u32Height = 720; 167 | break; 168 | case PIC_HD1080: /* 1920 * 1080 */ 169 | pstSize->u32Width = 1920; 170 | pstSize->u32Height = 1080; 171 | break; 172 | case PIC_5M: /* 2592 * 1944 */ 173 | pstSize->u32Width = 2592; 174 | pstSize->u32Height = 1944; 175 | break; 176 | 177 | default: 178 | return HI_FAILURE; 179 | } 180 | return HI_SUCCESS; 181 | } 182 | HI_S32 mpi_sys_Bind(IPC_VEDIO_S *pstIpcVedio) 183 | { 184 | HI_S32 j, s32Ret; 185 | 186 | MPP_CHN_S stSrcChn; 187 | MPP_CHN_S stDestChn; 188 | VI_DEV ViDev = 0; 189 | VI_CHN ViChn = 0; 190 | VPSS_GRP VpssGrp = 0; 191 | VPSS_CHN VpssChn = 0; 192 | VENC_CHN VencChn = 0; 193 | 194 | stSrcChn.enModId = HI_ID_VIU; 195 | stSrcChn.s32DevId = ViDev; 196 | stSrcChn.s32ChnId = ViChn; 197 | stDestChn.enModId = HI_ID_VPSS; 198 | stDestChn.s32DevId = VpssGrp; 199 | stDestChn.s32ChnId = VpssChn; 200 | s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn); 201 | if (s32Ret != HI_SUCCESS) 202 | { 203 | printf("VI Bind VPSS failed with %#x!\n", s32Ret); 204 | return HI_FAILURE; 205 | } 206 | for (j = 0; j < pstIpcVedio->u32StreamNum; j++) 207 | { 208 | VpssChn = j; 209 | VencChn = j; 210 | stSrcChn.enModId = HI_ID_VPSS; 211 | stSrcChn.s32DevId = VpssGrp; 212 | stSrcChn.s32ChnId = VpssChn; 213 | 214 | stDestChn.enModId = HI_ID_VENC; 215 | stDestChn.s32DevId = 0; 216 | stDestChn.s32ChnId = VencChn; 217 | 218 | s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn); 219 | if (s32Ret != HI_SUCCESS) 220 | { 221 | printf("VPSS Bind VENC failed with %#x!\n", s32Ret); 222 | return HI_FAILURE; 223 | } 224 | } 225 | return HI_SUCCESS; 226 | } 227 | 228 | HI_S32 mpi_sys_UnBind(IPC_VEDIO_S *pstIpcVedio) 229 | { 230 | HI_S32 j, s32Ret; 231 | 232 | MPP_CHN_S stSrcChn; 233 | MPP_CHN_S stDestChn; 234 | VI_DEV ViDev = 0; 235 | VI_CHN ViChn = 0; 236 | VPSS_GRP VpssGrp = 0; 237 | VPSS_CHN VpssChn = 0; 238 | VENC_CHN VencChn = 0; 239 | 240 | stSrcChn.enModId = HI_ID_VIU; 241 | stSrcChn.s32DevId = ViDev; 242 | stSrcChn.s32ChnId = ViChn; 243 | stDestChn.enModId = HI_ID_VPSS; 244 | stDestChn.s32DevId = VpssGrp; 245 | stDestChn.s32ChnId = VpssChn; 246 | s32Ret = HI_MPI_SYS_UnBind(&stSrcChn, &stDestChn); 247 | if (s32Ret != HI_SUCCESS) 248 | { 249 | printf("VI UnBind VPSS failed with %#x!\n", s32Ret); 250 | return HI_FAILURE; 251 | } 252 | for (j = 0; j < pstIpcVedio->u32StreamNum; j++) 253 | { 254 | VpssChn = j; 255 | VencChn = j; 256 | stSrcChn.enModId = HI_ID_VPSS; 257 | stSrcChn.s32DevId = VpssGrp; 258 | stSrcChn.s32ChnId = VpssChn; 259 | 260 | stDestChn.enModId = HI_ID_VENC; 261 | stDestChn.s32DevId = 0; 262 | stDestChn.s32ChnId = VencChn; 263 | 264 | s32Ret = HI_MPI_SYS_UnBind(&stSrcChn, &stDestChn); 265 | if (s32Ret != HI_SUCCESS) 266 | { 267 | printf("VPSS UnBind VENC failed with %#x!\n", s32Ret); 268 | return HI_FAILURE; 269 | } 270 | } 271 | return HI_SUCCESS; 272 | } 273 | 274 | 275 | -------------------------------------------------------------------------------- /Server/src/hp_venc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "hp_common.h" 17 | #include "hp_sys.h" 18 | #include "hp_ipc.h" 19 | #include "hp_venc.h" 20 | #include "rtsp_server.h" 21 | static ST_VENC_ATTR g_stVencAttr; 22 | static pthread_t gs_VencPid; 23 | 24 | 25 | static HI_S32 s32GetVencChnAttr(VENC_CHN VencChn,const IPC_VEDIO_S* pstIpcVedio, VENC_CHN_ATTR_S * pstVencChnAttr) 26 | { 27 | VENC_ATTR_H264_S stH264Attr; 28 | VENC_ATTR_H264_CBR_S stH264Cbr; 29 | VENC_ATTR_H264_VBR_S stH264Vbr; 30 | VENC_ATTR_H264_FIXQP_S stH264FixQp; 31 | VENC_ATTR_H265_S stH265Attr; 32 | VENC_ATTR_H265_CBR_S stH265Cbr; 33 | VENC_ATTR_H265_VBR_S stH265Vbr; 34 | VENC_ATTR_H265_FIXQP_S stH265FixQp; 35 | VENC_ATTR_MJPEG_S stMjpegAttr; 36 | VENC_ATTR_MJPEG_FIXQP_S stMjpegeFixQp; 37 | VENC_ATTR_JPEG_S stJpegAttr; 38 | SIZE_S stPicSize; 39 | PIC_SIZE_E enSize; 40 | PAYLOAD_TYPE_E enType; 41 | RC_MODE_E enRcMode; 42 | HI_U32 u32FrameRate; 43 | memcpy(&stPicSize,&(pstIpcVedio->astStreamFmt[VencChn].stSize),sizeof(stPicSize)); 44 | enSize = pstIpcVedio->astStreamFmt[VencChn].e_Size; 45 | enType = pstIpcVedio->astStreamFmt[VencChn].e_payload; 46 | enRcMode = pstIpcVedio->astStreamFmt[VencChn].e_RCMode; 47 | u32FrameRate = pstIpcVedio->astStreamFmt[VencChn].f32FrameRate; 48 | pstVencChnAttr->stVeAttr.enType = enType; 49 | 50 | switch(enType) 51 | { 52 | case PT_H264: 53 | { 54 | stH264Attr.u32MaxPicWidth = stPicSize.u32Width; 55 | stH264Attr.u32MaxPicHeight = stPicSize.u32Height; 56 | stH264Attr.u32PicWidth = stPicSize.u32Width;/*the picture width*/ 57 | stH264Attr.u32PicHeight = stPicSize.u32Height;/*the picture height*/ 58 | stH264Attr.u32BufSize = stPicSize.u32Width * stPicSize.u32Height;/*stream buffer size*/ 59 | stH264Attr.u32Profile = 0;/*0: baseline; 1:MP; 2:HP; 3:svc_t */ 60 | stH264Attr.bByFrame = HI_TRUE;/*get stream mode is slice mode or frame mode?*/ 61 | stH264Attr.u32BFrameNum = 0;/* 0: not support B frame; >=1: number of B frames */ 62 | stH264Attr.u32RefNum = 1;/* 0: default; number of refrence frame*/ 63 | memcpy(&(pstVencChnAttr->stVeAttr.stAttrH264e), &stH264Attr, sizeof(VENC_ATTR_H264_S)); 64 | 65 | if(RC_MODE_CBR == enRcMode) 66 | { 67 | pstVencChnAttr->stRcAttr.enRcMode = VENC_RC_MODE_H264CBR; 68 | stH264Cbr.u32Gop = 32; 69 | stH264Cbr.u32StatTime = 2; /* stream rate statics time(s) */ 70 | stH264Cbr.u32SrcFrmRate = u32FrameRate;/* input (vi) frame rate */ 71 | stH264Cbr.fr32DstFrmRate = u32FrameRate;/* target frame rate */ 72 | 73 | switch (enSize) 74 | { 75 | case PIC_QCIF: 76 | stH264Cbr.u32BitRate = 256; /* average bit rate */ 77 | break; 78 | case PIC_QVGA: /* 320 * 240 */ 79 | case PIC_CIF: 80 | 81 | stH264Cbr.u32BitRate = 512; 82 | break; 83 | 84 | case PIC_D1: 85 | case PIC_VGA: /* 640 * 480 */ 86 | stH264Cbr.u32BitRate = 1024*2; 87 | break; 88 | case PIC_HD720: /* 1280 * 720 */ 89 | stH264Cbr.u32BitRate = 1024*2; 90 | break; 91 | case PIC_HD1080: /* 1920 * 1080 */ 92 | stH264Cbr.u32BitRate = 1024*4; 93 | break; 94 | case PIC_5M: /* 2592 * 1944 */ 95 | stH264Cbr.u32BitRate = 1024*8; 96 | break; 97 | default : 98 | stH264Cbr.u32BitRate = 1024*4; 99 | break; 100 | } 101 | 102 | stH264Cbr.u32FluctuateLevel = 0; /* average bit rate */ 103 | memcpy(&(pstVencChnAttr->stRcAttr.stAttrH264Cbr), &stH264Cbr, sizeof(VENC_ATTR_H264_CBR_S)); 104 | } 105 | else if (RC_MODE_FIXQP == enRcMode) 106 | { 107 | pstVencChnAttr->stRcAttr.enRcMode = VENC_RC_MODE_H264FIXQP; 108 | stH264FixQp.u32Gop = 30; 109 | stH264FixQp.u32SrcFrmRate = u32FrameRate; 110 | stH264FixQp.fr32DstFrmRate = u32FrameRate; 111 | stH264FixQp.u32IQp = 20; 112 | stH264FixQp.u32PQp = 23; 113 | memcpy(&(pstVencChnAttr->stRcAttr.stAttrH264FixQp), &stH264FixQp,sizeof(VENC_ATTR_H264_FIXQP_S)); 114 | } 115 | else if (RC_MODE_VBR == enRcMode) 116 | { 117 | pstVencChnAttr->stRcAttr.enRcMode = VENC_RC_MODE_H264VBR; 118 | stH264Vbr.u32Gop = 30; 119 | stH264Vbr.u32StatTime = 1; 120 | stH264Vbr.u32SrcFrmRate = u32FrameRate; 121 | stH264Vbr.fr32DstFrmRate = u32FrameRate; 122 | stH264Vbr.u32MinQp = 10; 123 | stH264Vbr.u32MaxQp = 40; 124 | switch (enSize) 125 | { 126 | case PIC_QCIF: 127 | stH264Vbr.u32MaxBitRate= 256*3; /* average bit rate */ 128 | break; 129 | case PIC_QVGA: /* 320 * 240 */ 130 | case PIC_CIF: 131 | stH264Vbr.u32MaxBitRate = 512*3; 132 | break; 133 | case PIC_D1: 134 | case PIC_VGA: /* 640 * 480 */ 135 | stH264Vbr.u32MaxBitRate = 1024*2; 136 | break; 137 | case PIC_HD720: /* 1280 * 720 */ 138 | stH264Vbr.u32MaxBitRate = 1024*3; 139 | break; 140 | case PIC_HD1080: /* 1920 * 1080 */ 141 | stH264Vbr.u32MaxBitRate = 1024*6; 142 | break; 143 | case PIC_5M: /* 2592 * 1944 */ 144 | stH264Vbr.u32MaxBitRate = 1024*8; 145 | break; 146 | default : 147 | stH264Vbr.u32MaxBitRate = 1024*4; 148 | break; 149 | } 150 | memcpy(&(pstVencChnAttr->stRcAttr.stAttrH264Vbr), &stH264Vbr, sizeof(VENC_ATTR_H264_VBR_S)); 151 | } 152 | else 153 | { 154 | return HI_FAILURE; 155 | } 156 | } 157 | break; 158 | 159 | case PT_MJPEG: 160 | { 161 | stMjpegAttr.u32MaxPicWidth = stPicSize.u32Width; 162 | stMjpegAttr.u32MaxPicHeight = stPicSize.u32Height; 163 | stMjpegAttr.u32PicWidth = stPicSize.u32Width; 164 | stMjpegAttr.u32PicHeight = stPicSize.u32Height; 165 | stMjpegAttr.u32BufSize = (((stPicSize.u32Width+15)>>4)<<4) * (((stPicSize.u32Height+15)>>4)<<4); 166 | stMjpegAttr.bByFrame = HI_TRUE; /*get stream mode is field mode or frame mode*/ 167 | memcpy(&(pstVencChnAttr->stVeAttr.stAttrMjpeg), &stMjpegAttr, sizeof(VENC_ATTR_MJPEG_S)); 168 | 169 | if(RC_MODE_FIXQP == enRcMode) 170 | { 171 | pstVencChnAttr->stRcAttr.enRcMode = VENC_RC_MODE_MJPEGFIXQP; 172 | stMjpegeFixQp.u32Qfactor = 90; 173 | stMjpegeFixQp.u32SrcFrmRate = u32FrameRate; 174 | stMjpegeFixQp.fr32DstFrmRate = u32FrameRate; 175 | memcpy(&(pstVencChnAttr->stRcAttr.stAttrMjpegeFixQp), &stMjpegeFixQp, 176 | sizeof(VENC_ATTR_MJPEG_FIXQP_S)); 177 | } 178 | else if (RC_MODE_CBR == enRcMode) 179 | { 180 | pstVencChnAttr->stRcAttr.enRcMode = VENC_RC_MODE_MJPEGCBR; 181 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.u32StatTime = 1; 182 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.u32SrcFrmRate = u32FrameRate; 183 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.fr32DstFrmRate = u32FrameRate; 184 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.u32FluctuateLevel = 0; 185 | switch (enSize) 186 | { 187 | case PIC_QCIF: 188 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.u32BitRate = 384*3; /* average bit rate */ 189 | break; 190 | case PIC_QVGA: /* 320 * 240 */ 191 | case PIC_CIF: 192 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.u32BitRate = 768*3; 193 | break; 194 | case PIC_D1: 195 | case PIC_VGA: /* 640 * 480 */ 196 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.u32BitRate = 1024*3*3; 197 | break; 198 | case PIC_HD720: /* 1280 * 720 */ 199 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.u32BitRate = 1024*5*3; 200 | break; 201 | case PIC_HD1080: /* 1920 * 1080 */ 202 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.u32BitRate = 1024*10*3; 203 | break; 204 | case PIC_5M: /* 2592 * 1944 */ 205 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.u32BitRate = 1024*10*3; 206 | break; 207 | default : 208 | pstVencChnAttr->stRcAttr.stAttrMjpegeCbr.u32BitRate = 1024*10*3; 209 | break; 210 | } 211 | } 212 | else if (RC_MODE_VBR == enRcMode) 213 | { 214 | pstVencChnAttr->stRcAttr.enRcMode = VENC_RC_MODE_MJPEGVBR; 215 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32StatTime = 1; 216 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32SrcFrmRate = u32FrameRate; 217 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.fr32DstFrmRate = u32FrameRate; 218 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32MinQfactor = 50; 219 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32MaxQfactor = 95; 220 | switch (enSize) 221 | { 222 | case PIC_QCIF: 223 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32MaxBitRate= 256*3; /* average bit rate */ 224 | break; 225 | case PIC_QVGA: /* 320 * 240 */ 226 | case PIC_CIF: 227 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 512*3; 228 | break; 229 | case PIC_D1: 230 | case PIC_VGA: /* 640 * 480 */ 231 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 1024*2*3; 232 | break; 233 | case PIC_HD720: /* 1280 * 720 */ 234 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 1024*3*3; 235 | break; 236 | case PIC_HD1080: /* 1920 * 1080 */ 237 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 1024*6*3; 238 | break; 239 | case PIC_5M: /* 2592 * 1944 */ 240 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 1024*12*3; 241 | break; 242 | default : 243 | pstVencChnAttr->stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 1024*4*3; 244 | break; 245 | } 246 | } 247 | else 248 | { 249 | printf("cann't support other mode in this version!\n"); 250 | 251 | return HI_FAILURE; 252 | } 253 | } 254 | break; 255 | 256 | case PT_JPEG: 257 | stJpegAttr.u32PicWidth = stPicSize.u32Width; 258 | stJpegAttr.u32PicHeight = stPicSize.u32Height; 259 | stJpegAttr.u32MaxPicWidth = stPicSize.u32Width; 260 | stJpegAttr.u32MaxPicHeight = stPicSize.u32Height; 261 | stJpegAttr.u32BufSize = (((stPicSize.u32Width+15)>>4)<<4) * (((stPicSize.u32Height+15)>>4)<<4); 262 | stJpegAttr.bByFrame = HI_TRUE;/*get stream mode is field mode or frame mode*/ 263 | stJpegAttr.bSupportDCF = HI_FALSE; 264 | memcpy(&(pstVencChnAttr->stVeAttr.stAttrJpeg), &stJpegAttr, sizeof(VENC_ATTR_JPEG_S)); 265 | break; 266 | 267 | case PT_H265: 268 | { 269 | stH265Attr.u32MaxPicWidth = stPicSize.u32Width; 270 | stH265Attr.u32MaxPicHeight = stPicSize.u32Height; 271 | stH265Attr.u32PicWidth = stPicSize.u32Width;/*the picture width*/ 272 | stH265Attr.u32PicHeight = stPicSize.u32Height;/*the picture height*/ 273 | stH265Attr.u32BufSize = stPicSize.u32Width * stPicSize.u32Height * 2;/*stream buffer size*/ 274 | stH265Attr.u32Profile = 0;/*0:MP*/ 275 | stH265Attr.bByFrame = HI_TRUE;/*get stream mode is slice mode or frame mode?*/ 276 | stH265Attr.u32BFrameNum = 0;/* 0: not support B frame; >=1: number of B frames */ 277 | stH265Attr.u32RefNum = 1;/* 0: default; number of refrence frame*/ 278 | memcpy(&(pstVencChnAttr->stVeAttr.stAttrH265e), &stH265Attr, sizeof(VENC_ATTR_H265_S)); 279 | 280 | if(RC_MODE_CBR == enRcMode) 281 | { 282 | pstVencChnAttr->stRcAttr.enRcMode = VENC_RC_MODE_H265CBR; 283 | stH265Cbr.u32Gop = 30; 284 | stH265Cbr.u32StatTime = 1; /* stream rate statics time(s) */ 285 | stH265Cbr.u32SrcFrmRate = u32FrameRate;/* input (vi) frame rate */ 286 | stH265Cbr.fr32DstFrmRate = u32FrameRate;/* target frame rate */ 287 | switch (enSize) 288 | { 289 | case PIC_QCIF: 290 | stH265Cbr.u32BitRate = 256; /* average bit rate */ 291 | break; 292 | case PIC_QVGA: /* 320 * 240 */ 293 | case PIC_CIF: 294 | 295 | stH265Cbr.u32BitRate = 512; 296 | break; 297 | 298 | case PIC_D1: 299 | case PIC_VGA: /* 640 * 480 */ 300 | stH265Cbr.u32BitRate = 1024*2; 301 | break; 302 | case PIC_HD720: /* 1280 * 720 */ 303 | stH265Cbr.u32BitRate = 1024*3; 304 | break; 305 | case PIC_HD1080: /* 1920 * 1080 */ 306 | stH265Cbr.u32BitRate = 1024*4; 307 | break; 308 | case PIC_5M: /* 2592 * 1944 */ 309 | stH265Cbr.u32BitRate = 1024*8; 310 | break; 311 | default : 312 | stH265Cbr.u32BitRate = 1024*4; 313 | break; 314 | } 315 | 316 | stH265Cbr.u32FluctuateLevel = 0; /* average bit rate */ 317 | memcpy(&(pstVencChnAttr->stRcAttr.stAttrH265Cbr), &stH265Cbr, sizeof(VENC_ATTR_H265_CBR_S)); 318 | } 319 | else if (RC_MODE_FIXQP == enRcMode) 320 | { 321 | pstVencChnAttr->stRcAttr.enRcMode = VENC_RC_MODE_H265FIXQP; 322 | stH265FixQp.u32Gop = 30; 323 | stH265FixQp.u32SrcFrmRate = u32FrameRate; 324 | stH265FixQp.fr32DstFrmRate = u32FrameRate; 325 | stH265FixQp.u32IQp = 20; 326 | stH265FixQp.u32PQp = 23; 327 | memcpy(&(pstVencChnAttr->stRcAttr.stAttrH265FixQp), &stH265FixQp,sizeof(VENC_ATTR_H265_FIXQP_S)); 328 | } 329 | else if (RC_MODE_VBR == enRcMode) 330 | { 331 | pstVencChnAttr->stRcAttr.enRcMode = VENC_RC_MODE_H265VBR; 332 | stH265Vbr.u32Gop = 30; 333 | stH265Vbr.u32StatTime = 1; 334 | stH265Vbr.u32SrcFrmRate = u32FrameRate; 335 | stH265Vbr.fr32DstFrmRate = u32FrameRate; 336 | stH265Vbr.u32MinQp = 10; 337 | stH265Vbr.u32MaxQp = 40; 338 | switch (enSize) 339 | { 340 | case PIC_QCIF: 341 | stH265Vbr.u32MaxBitRate= 256*3; /* average bit rate */ 342 | break; 343 | case PIC_QVGA: /* 320 * 240 */ 344 | case PIC_CIF: 345 | stH265Vbr.u32MaxBitRate = 512*3; 346 | break; 347 | case PIC_D1: 348 | case PIC_VGA: /* 640 * 480 */ 349 | stH265Vbr.u32MaxBitRate = 1024*2; 350 | break; 351 | case PIC_HD720: /* 1280 * 720 */ 352 | stH265Vbr.u32MaxBitRate = 1024*3; 353 | break; 354 | case PIC_HD1080: /* 1920 * 1080 */ 355 | stH265Vbr.u32MaxBitRate = 1024*6; 356 | break; 357 | case PIC_5M: /* 2592 * 1944 */ 358 | stH265Vbr.u32MaxBitRate = 1024*8; 359 | break; 360 | default : 361 | stH265Vbr.u32MaxBitRate = 1024*4; 362 | break; 363 | } 364 | memcpy(&(pstVencChnAttr->stRcAttr.stAttrH265Vbr), &stH265Vbr, sizeof(VENC_ATTR_H265_VBR_S)); 365 | } 366 | else 367 | { 368 | return HI_FAILURE; 369 | } 370 | } 371 | break; 372 | default: 373 | return HI_ERR_VENC_NOT_SUPPORT; 374 | } 375 | return HI_SUCCESS; 376 | } 377 | 378 | static HI_S32 s32VencStartChn(VENC_CHN VencChn,VENC_CHN_ATTR_S * pstVencChnAttr) 379 | { 380 | HI_S32 s32Ret; 381 | 382 | s32Ret = HI_MPI_VENC_CreateChn(VencChn, pstVencChnAttr); 383 | if (HI_SUCCESS != s32Ret) 384 | { 385 | printf("HI_MPI_VENC_CreateChn [%d] faild with %#x!\n",\ 386 | VencChn, s32Ret); 387 | return s32Ret; 388 | } 389 | 390 | s32Ret = HI_MPI_VENC_StartRecvPic(VencChn); 391 | if (HI_SUCCESS != s32Ret) 392 | { 393 | printf("HI_MPI_VENC_StartRecvPic faild with%#x!\n", s32Ret); 394 | return HI_FAILURE; 395 | } 396 | 397 | return HI_SUCCESS; 398 | 399 | } 400 | 401 | /****************************************************************************** 402 | * funciton : get file postfix according palyload_type. 403 | ******************************************************************************/ 404 | static HI_S32 s32GetFilePostfix(PAYLOAD_TYPE_E enPayload, char *szFilePostfix) 405 | { 406 | if (PT_H264 == enPayload) 407 | { 408 | strcpy(szFilePostfix, ".h264"); 409 | } 410 | else if (PT_H265 == enPayload) 411 | { 412 | strcpy(szFilePostfix, ".h265"); 413 | } 414 | else if (PT_JPEG == enPayload) 415 | { 416 | strcpy(szFilePostfix, ".jpg"); 417 | } 418 | else if (PT_MJPEG == enPayload) 419 | { 420 | strcpy(szFilePostfix, ".mjp"); 421 | } 422 | else if (PT_MP4VIDEO == enPayload) 423 | { 424 | strcpy(szFilePostfix, ".mp4"); 425 | } 426 | else 427 | { 428 | printf("payload type err!\n"); 429 | return HI_FAILURE; 430 | } 431 | return HI_SUCCESS; 432 | } 433 | 434 | /****************************************************************************** 435 | * funciton : save mjpeg stream. 436 | ******************************************************************************/ 437 | static HI_S32 s32SaveMJpeg(FILE* fpMJpegFile, VENC_STREAM_S *pstStream) 438 | { 439 | VENC_PACK_S* pstData; 440 | HI_U32 i; 441 | 442 | //fwrite(g_SOI, 1, sizeof(g_SOI), fpJpegFile); //in Hi3531, user needn't write SOI! 443 | 444 | for (i = 0; i < pstStream->u32PackCount; i++) 445 | { 446 | pstData = &pstStream->pstPack[i]; 447 | fwrite(pstData->pu8Addr+pstData->u32Offset, pstData->u32Len-pstData->u32Offset, 1, fpMJpegFile); 448 | fflush(fpMJpegFile); 449 | } 450 | 451 | return HI_SUCCESS; 452 | } 453 | 454 | /****************************************************************************** 455 | * funciton : save jpeg stream. 456 | ******************************************************************************/ 457 | static HI_S32 s32SaveJpeg(FILE* fpJpegFile, VENC_STREAM_S *pstStream) 458 | { 459 | VENC_PACK_S* pstData; 460 | HI_U32 i; 461 | 462 | for (i = 0; i < pstStream->u32PackCount; i++) 463 | { 464 | pstData = &pstStream->pstPack[i]; 465 | fwrite(pstData->pu8Addr+pstData->u32Offset, pstData->u32Len-pstData->u32Offset, 1, fpJpegFile); 466 | fflush(fpJpegFile); 467 | } 468 | 469 | return HI_SUCCESS; 470 | } 471 | 472 | /****************************************************************************** 473 | * funciton : save H264 stream 474 | ******************************************************************************/ 475 | static HI_S32 s32SaveH264(FILE* fpH264File, VENC_STREAM_S *pstStream) 476 | { 477 | HI_S32 i; 478 | 479 | 480 | for (i = 0; i < pstStream->u32PackCount; i++) 481 | { 482 | fwrite(pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset, 483 | pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset, 1, fpH264File); 484 | 485 | fflush(fpH264File); 486 | } 487 | 488 | 489 | return HI_SUCCESS; 490 | } 491 | 492 | /****************************************************************************** 493 | * funciton : save H265 stream 494 | ******************************************************************************/ 495 | static HI_S32 s32SaveH265(FILE* fpH265File, VENC_STREAM_S *pstStream) 496 | { 497 | HI_S32 i; 498 | 499 | for (i = 0; i < pstStream->u32PackCount; i++) 500 | { 501 | fwrite(pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset, 502 | pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset, 1, fpH265File); 503 | 504 | fflush(fpH265File); 505 | } 506 | 507 | return HI_SUCCESS; 508 | } 509 | 510 | /****************************************************************************** 511 | * funciton : save jpeg stream 512 | ******************************************************************************/ 513 | static HI_S32 s32SaveJPEG(FILE *fpJpegFile, VENC_STREAM_S *pstStream) 514 | { 515 | VENC_PACK_S* pstData; 516 | HI_U32 i; 517 | 518 | for (i = 0; i < pstStream->u32PackCount; i++) 519 | { 520 | pstData = &pstStream->pstPack[i]; 521 | fwrite(pstData->pu8Addr+pstData->u32Offset, pstData->u32Len-pstData->u32Offset, 1, fpJpegFile); 522 | fflush(fpJpegFile); 523 | } 524 | 525 | return HI_SUCCESS; 526 | } 527 | 528 | 529 | /****************************************************************************** 530 | * funciton : save stream 531 | ******************************************************************************/ 532 | static HI_S32 s32SaveStream(PAYLOAD_TYPE_E enType,FILE *pFd, VENC_STREAM_S *pstStream) 533 | { 534 | HI_S32 s32Ret; 535 | 536 | if (PT_H264 == enType) 537 | { 538 | s32Ret = s32SaveH264(pFd, pstStream); 539 | } 540 | else if (PT_MJPEG == enType) 541 | { 542 | s32Ret = s32SaveMJpeg(pFd, pstStream); 543 | } 544 | else if (PT_H265 == enType) 545 | { 546 | s32Ret = s32SaveH265(pFd, pstStream); 547 | } 548 | else 549 | { 550 | return HI_FAILURE; 551 | } 552 | return s32Ret; 553 | } 554 | 555 | 556 | /****************************************************************************** 557 | * funciton : get stream from each channels and save them 558 | ******************************************************************************/ 559 | HI_VOID* vdGetVencStreamProc(HI_VOID *p) 560 | { 561 | HI_S32 i; 562 | HI_S32 s32ChnTotal; 563 | VENC_CHN_ATTR_S stVencChnAttr; 564 | HI_S32 maxfd = 0; 565 | struct timeval TimeoutVal; 566 | fd_set read_fds; 567 | HI_S32 VencFd[VENC_MAX_CHN_NUM]; 568 | HI_CHAR aszFileName[VENC_MAX_CHN_NUM][64]; 569 | FILE *pFile[VENC_MAX_CHN_NUM]; 570 | char szFilePostfix[10]; 571 | VENC_CHN_STAT_S stStat; 572 | VENC_STREAM_S stStream; 573 | HI_S32 s32Ret; 574 | VENC_CHN VencChn; 575 | PAYLOAD_TYPE_E enPayLoadType[VENC_MAX_CHN_NUM]; 576 | ST_VENC_ATTR * pstVencAttr; 577 | pstVencAttr = (ST_VENC_ATTR *)p; 578 | s32ChnTotal = ((ST_VENC_ATTR *)p)->vencChnNum; 579 | 580 | /****************************************** 581 | step 1: check & prepare save-file & venc-fd 582 | ******************************************/ 583 | if (s32ChnTotal >= VENC_MAX_CHN_NUM) 584 | { 585 | printf("input count invaild\n"); 586 | return NULL; 587 | } 588 | for (i = 0; i < s32ChnTotal; i++) 589 | { 590 | /* decide the stream file name, and open file to save stream */ 591 | VencChn = i; 592 | s32Ret = HI_MPI_VENC_GetChnAttr(VencChn, &stVencChnAttr); 593 | if(s32Ret != HI_SUCCESS) 594 | { 595 | printf("HI_MPI_VENC_GetChnAttr chn[%d] failed with %#x!\n", \ 596 | VencChn, s32Ret); 597 | return NULL; 598 | } 599 | enPayLoadType[i] = stVencChnAttr.stVeAttr.enType; 600 | 601 | s32Ret = s32GetFilePostfix(enPayLoadType[i], szFilePostfix); 602 | if(s32Ret != HI_SUCCESS) 603 | { 604 | printf("s32GetFilePostfix [%d] failed with %#x!\n", \ 605 | stVencChnAttr.stVeAttr.enType, s32Ret); 606 | return NULL; 607 | } 608 | sprintf(aszFileName[i], "stream_chn%d%s", i, szFilePostfix); 609 | pFile[i] = fopen(aszFileName[i], "wb"); 610 | if (!pFile[i]) 611 | { 612 | printf("open file[%s] failed!\n", 613 | aszFileName[i]); 614 | return NULL; 615 | } 616 | 617 | /* Set Venc Fd. */ 618 | VencFd[i] = HI_MPI_VENC_GetFd(i); 619 | if (VencFd[i] < 0) 620 | { 621 | printf("HI_MPI_VENC_GetFd failed with %#x!\n", 622 | VencFd[i]); 623 | return NULL; 624 | } 625 | if (maxfd <= VencFd[i]) 626 | { 627 | maxfd = VencFd[i]; 628 | } 629 | } 630 | 631 | /****************************************** 632 | step 2: Start to get streams of each channel. 633 | ******************************************/ 634 | while (HI_TRUE == pstVencAttr->bGetStreamProcThreadStart) 635 | { 636 | FD_ZERO(&read_fds); 637 | for (i = 0; i < s32ChnTotal; i++) 638 | { 639 | FD_SET(VencFd[i], &read_fds); 640 | } 641 | 642 | TimeoutVal.tv_sec = 2; 643 | TimeoutVal.tv_usec = 0; 644 | s32Ret = select(maxfd + 1, &read_fds, NULL, NULL, &TimeoutVal); 645 | if (s32Ret < 0) 646 | { 647 | printf("select failed!\n"); 648 | break; 649 | } 650 | else if (s32Ret == 0) 651 | { 652 | printf("get venc stream time out, exit thread\n"); 653 | continue; 654 | } 655 | else 656 | { 657 | for (i = 0; i < s32ChnTotal; i++) 658 | { 659 | if (FD_ISSET(VencFd[i], &read_fds)) 660 | { 661 | /******************************************************* 662 | step 2.1 : query how many packs in one-frame stream. 663 | *******************************************************/ 664 | memset(&stStream, 0, sizeof(stStream)); 665 | s32Ret = HI_MPI_VENC_Query(i, &stStat); 666 | if (HI_SUCCESS != s32Ret) 667 | { 668 | printf("HI_MPI_VENC_Query chn[%d] failed with %#x!\n", i, s32Ret); 669 | break; 670 | } 671 | 672 | /******************************************************* 673 | step 2.2 :suggest to check both u32CurPacks and u32LeftStreamFrames at the same time,for example: 674 | if(0 == stStat.u32CurPacks || 0 == stStat.u32LeftStreamFrames) 675 | { 676 | SAMPLE_PRT("NOTE: Current frame is NULL!\n"); 677 | continue; 678 | } 679 | *******************************************************/ 680 | if(0 == stStat.u32CurPacks) 681 | { 682 | printf("NOTE: Current frame is NULL!\n"); 683 | continue; 684 | } 685 | /******************************************************* 686 | step 2.3 : malloc corresponding number of pack nodes. 687 | *******************************************************/ 688 | stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks); 689 | if (NULL == stStream.pstPack) 690 | { 691 | printf("malloc stream pack failed!\n"); 692 | break; 693 | } 694 | 695 | /******************************************************* 696 | step 2.4 : call mpi to get one-frame stream 697 | *******************************************************/ 698 | stStream.u32PackCount = stStat.u32CurPacks; 699 | s32Ret = HI_MPI_VENC_GetStream(i, &stStream, HI_TRUE); 700 | if (HI_SUCCESS != s32Ret) 701 | { 702 | free(stStream.pstPack); 703 | stStream.pstPack = NULL; 704 | printf("HI_MPI_VENC_GetStream failed with %#x!\n", \ 705 | s32Ret); 706 | break; 707 | } 708 | 709 | /******************************************************* 710 | step 2.5 : save frame to file 711 | *******************************************************/ 712 | s32Ret = s32SaveStream(enPayLoadType[i], pFile[i], &stStream); 713 | //SAMPLE_COMM_VENC_Sentjin(&stStream); 714 | saveStream(&stStream); 715 | if (HI_SUCCESS != s32Ret) 716 | { 717 | free(stStream.pstPack); 718 | stStream.pstPack = NULL; 719 | printf("save stream failed!\n"); 720 | break; 721 | } 722 | /******************************************************* 723 | step 2.6 : release stream 724 | *******************************************************/ 725 | s32Ret = HI_MPI_VENC_ReleaseStream(i, &stStream); 726 | if (HI_SUCCESS != s32Ret) 727 | { 728 | free(stStream.pstPack); 729 | stStream.pstPack = NULL; 730 | break; 731 | } 732 | /******************************************************* 733 | step 2.7 : free pack nodes 734 | *******************************************************/ 735 | free(stStream.pstPack); 736 | stStream.pstPack = NULL; 737 | } 738 | } 739 | } 740 | } 741 | 742 | /******************************************************* 743 | * step 3 : close save-file 744 | *******************************************************/ 745 | for (i = 0; i < s32ChnTotal; i++) 746 | { 747 | fclose(pFile[i]); 748 | } 749 | 750 | return NULL; 751 | } 752 | 753 | /****************************************************************************** 754 | * funciton : start get venc stream process thread 755 | ******************************************************************************/ 756 | static HI_S32 s32StartGetStream(void) 757 | { 758 | g_stVencAttr.bGetStreamProcThreadStart = HI_TRUE; 759 | return pthread_create(&gs_VencPid, 0, vdGetVencStreamProc, (HI_VOID*)&g_stVencAttr); 760 | } 761 | 762 | 763 | static HI_S32 s32StartVENC(const IPC_VEDIO_S* pstIpcVedio) 764 | { 765 | VENC_CHN_ATTR_S stVencChnAttr; 766 | VENC_CHN VencChn; 767 | HI_S32 s32Ret; 768 | g_stVencAttr.vencChnNum = pstIpcVedio->u32StreamNum; 769 | for(VencChn = 0; VencChn < g_stVencAttr.vencChnNum; VencChn++) 770 | { 771 | s32GetVencChnAttr(VencChn, pstIpcVedio, &stVencChnAttr); 772 | s32Ret = s32VencStartChn(VencChn, &stVencChnAttr); 773 | if (HI_SUCCESS != s32Ret) 774 | { 775 | printf("Start Venc failed!\n"); 776 | return HI_FAILURE; 777 | } 778 | } 779 | s32StartGetStream(); 780 | return HI_SUCCESS; 781 | } 782 | static HI_S32 s32VencStopChn(VENC_CHN VencChn) 783 | { 784 | HI_S32 s32Ret; 785 | 786 | /****************************************** 787 | step 1: Stop Recv Pictures 788 | ******************************************/ 789 | s32Ret = HI_MPI_VENC_StopRecvPic(VencChn); 790 | if (HI_SUCCESS != s32Ret) 791 | { 792 | printf("HI_MPI_VENC_StopRecvPic vechn[%d] failed with %#x!\n",\ 793 | VencChn, s32Ret); 794 | return HI_FAILURE; 795 | } 796 | 797 | /****************************************** 798 | step 2: Distroy Venc Channel 799 | ******************************************/ 800 | s32Ret = HI_MPI_VENC_DestroyChn(VencChn); 801 | if (HI_SUCCESS != s32Ret) 802 | { 803 | printf("HI_MPI_VENC_DestroyChn vechn[%d] failed with %#x!\n",\ 804 | VencChn, s32Ret); 805 | return HI_FAILURE; 806 | } 807 | 808 | return HI_SUCCESS; 809 | } 810 | 811 | /****************************************************************************** 812 | * funciton : stop get venc stream process. 813 | ******************************************************************************/ 814 | static HI_S32 s32StopGetStream(void) 815 | { 816 | if(HI_TRUE == g_stVencAttr.bGetStreamProcThreadStart) 817 | { 818 | g_stVencAttr.bGetStreamProcThreadStart = HI_FALSE; 819 | pthread_join(gs_VencPid, 0); 820 | gs_VencPid = 0; 821 | } 822 | return HI_SUCCESS; 823 | } 824 | 825 | static HI_S32 s32StopVENC(void) 826 | { 827 | HI_S32 s32Ret = HI_SUCCESS; 828 | VENC_CHN VencChn; 829 | s32StopGetStream(); 830 | 831 | for(VencChn = 0; VencChn < g_stVencAttr.vencChnNum; VencChn++) 832 | { 833 | s32Ret = s32VencStopChn(VencChn); 834 | if (HI_SUCCESS != s32Ret) 835 | { 836 | printf("Stop Venc failed!\n"); 837 | return HI_FAILURE; 838 | } 839 | } 840 | return HI_SUCCESS; 841 | } 842 | 843 | HI_S32 VENC_init(const IPC_VEDIO_S* pstIpcVedio) 844 | { 845 | HI_S32 s32Ret = HI_SUCCESS; 846 | if(!pstIpcVedio) 847 | { 848 | printf("%s: null ptr\n", __FUNCTION__); 849 | return HI_FAILURE; 850 | } 851 | s32Ret = s32StartVENC(pstIpcVedio); 852 | return s32Ret; 853 | } 854 | 855 | HI_S32 VENC_exit(void) 856 | { 857 | HI_S32 s32Ret = HI_SUCCESS; 858 | s32Ret = s32StopVENC(); 859 | return s32Ret; 860 | } 861 | 862 | -------------------------------------------------------------------------------- /Server/src/hp_vi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | static pthread_t gs_IspPid = 0; 22 | static HI_BOOL gbIspInited = HI_FALSE; 23 | static VI_ATTR_S *g_pstViAttr; 24 | 25 | /****************************************************************************** 26 | * funciton : stop ISP, and stop isp thread 27 | ******************************************************************************/ 28 | static HI_VOID vdIspStop(VI_ATTR_S * pstViAttr) 29 | { 30 | ISP_DEV IspDev = pstViAttr->IspDev; 31 | 32 | if (!gbIspInited) 33 | { 34 | return; 35 | } 36 | 37 | HI_MPI_ISP_Exit(IspDev); 38 | if (gs_IspPid) 39 | { 40 | pthread_join(gs_IspPid, 0); 41 | gs_IspPid = 0; 42 | } 43 | gbIspInited = HI_FALSE; 44 | return; 45 | } 46 | static HI_S32 s32StopVi(VI_ATTR_S * pstViAttr) 47 | { 48 | HI_S32 i; 49 | HI_S32 s32Ret; 50 | HI_U32 u32ChnNum; 51 | 52 | if(!pstViAttr) 53 | { 54 | printf("%s: null ptr\n", __FUNCTION__); 55 | return HI_FAILURE; 56 | } 57 | 58 | /*** Stop VI Chn ***/ 59 | u32ChnNum = pstViAttr->u32ChnNum; 60 | for(i=0;i < u32ChnNum; i++) 61 | { 62 | /* Stop vi phy-chn */ 63 | s32Ret = HI_MPI_VI_DisableChn(i); 64 | if (HI_SUCCESS != s32Ret) 65 | { 66 | printf("HI_MPI_VI_DisableChn failed with %#x\n",s32Ret); 67 | return HI_FAILURE; 68 | } 69 | } 70 | 71 | /*** Stop VI Dev ***/ 72 | s32Ret = HI_MPI_VI_DisableDev(pstViAttr->ViDev); 73 | if (HI_SUCCESS != s32Ret) 74 | { 75 | printf("HI_MPI_VI_DisableDev failed with %#x\n", s32Ret); 76 | return HI_FAILURE; 77 | } 78 | return HI_SUCCESS; 79 | } 80 | 81 | static HI_S32 s32StartMIPI(VI_ATTR_S * pstViAttr) 82 | { 83 | HI_S32 fd; 84 | combo_dev_attr_t *pstcomboDevAttr = NULL; 85 | 86 | if (NULL == pstViAttr) 87 | { 88 | printf("Func %s() Line[%d], parament is null\n", __FUNCTION__, __LINE__); 89 | return HI_FAILURE; 90 | } 91 | 92 | pstcomboDevAttr = pstViAttr->pstcomboDevAttr; 93 | if (NULL == pstcomboDevAttr) 94 | { 95 | printf("Func %s() Line[%d], parament is null\n", __FUNCTION__, __LINE__); 96 | return HI_FAILURE; 97 | } 98 | 99 | /* mipi reset unrest */ 100 | fd = open("/dev/hi_mipi", O_RDWR); 101 | if (fd < 0) 102 | { 103 | printf("warning: open hi_mipi dev failed\n"); 104 | return HI_FAILURE; 105 | } 106 | if (ioctl(fd, HI_MIPI_SET_DEV_ATTR, pstcomboDevAttr)) 107 | { 108 | printf("set mipi attr failed\n"); 109 | close(fd); 110 | return HI_FAILURE; 111 | } 112 | close(fd); 113 | return HI_SUCCESS; 114 | } 115 | 116 | static HI_VOID* vdIspRun(HI_VOID *param) 117 | { 118 | ISP_DEV IspDev = 0; 119 | HI_MPI_ISP_Run(IspDev); 120 | 121 | return HI_NULL; 122 | } 123 | 124 | /****************************************************************************** 125 | * funciton : ISP init 126 | ******************************************************************************/ 127 | static HI_S32 s32IspInit(VI_ATTR_S * pstViAttr) 128 | { 129 | ISP_DEV IspDev = 0; 130 | HI_S32 s32Ret; 131 | ALG_LIB_S stLib; 132 | ISP_PUB_ATTR_S *pstPubAttr; 133 | ISP_WDR_MODE_S stWdrMode; 134 | 135 | if (NULL == pstViAttr) 136 | { 137 | printf("Func %s() Line[%d], parament is null\n", __FUNCTION__, __LINE__); 138 | return HI_FAILURE; 139 | } 140 | IspDev = pstViAttr->IspDev; 141 | pstPubAttr = pstViAttr->pstIspPubAttr; 142 | stWdrMode.enWDRMode = pstViAttr->enWDRMode; 143 | 144 | /* 1. sensor register callback */ 145 | s32Ret = sensor_register_callback(); 146 | if (s32Ret != HI_SUCCESS) 147 | { 148 | printf("%s: sensor_register_callback failed with %#x!\n", \ 149 | __FUNCTION__, s32Ret); 150 | return s32Ret; 151 | } 152 | 153 | /* 2. register hisi ae lib */ 154 | stLib.s32Id = 0; 155 | strcpy(stLib.acLibName, HI_AE_LIB_NAME); 156 | s32Ret = HI_MPI_AE_Register(IspDev, &stLib); 157 | if (s32Ret != HI_SUCCESS) 158 | { 159 | printf("%s: HI_MPI_AE_Register failed!\n", __FUNCTION__); 160 | return s32Ret; 161 | } 162 | 163 | /* 3. register hisi awb lib */ 164 | stLib.s32Id = 0; 165 | strcpy(stLib.acLibName, HI_AWB_LIB_NAME); 166 | s32Ret = HI_MPI_AWB_Register(IspDev, &stLib); 167 | if (s32Ret != HI_SUCCESS) 168 | { 169 | printf("%s: HI_MPI_AWB_Register failed!\n", __FUNCTION__); 170 | return s32Ret; 171 | } 172 | 173 | /* 4. register hisi af lib */ 174 | stLib.s32Id = 0; 175 | strcpy(stLib.acLibName, HI_AF_LIB_NAME); 176 | s32Ret = HI_MPI_AF_Register(IspDev, &stLib); 177 | if (s32Ret != HI_SUCCESS) 178 | { 179 | printf("%s: HI_MPI_AF_Register failed!\n", __FUNCTION__); 180 | return s32Ret; 181 | } 182 | 183 | /* 5. isp mem init */ 184 | s32Ret = HI_MPI_ISP_MemInit(IspDev); 185 | if (s32Ret != HI_SUCCESS) 186 | { 187 | printf("%s: HI_MPI_ISP_Init failed!\n", __FUNCTION__); 188 | return s32Ret; 189 | } 190 | 191 | /* 6. isp set WDR mode */ 192 | s32Ret = HI_MPI_ISP_SetWDRMode(IspDev, &stWdrMode); 193 | if (HI_SUCCESS != s32Ret) 194 | { 195 | printf("start ISP WDR failed!\n"); 196 | return s32Ret; 197 | } 198 | 199 | /* 7. isp set pub attributes */ 200 | s32Ret = HI_MPI_ISP_SetPubAttr(IspDev, pstPubAttr); 201 | if (s32Ret != HI_SUCCESS) 202 | { 203 | printf("%s: HI_MPI_ISP_SetPubAttr failed with %#x!\n", __FUNCTION__, s32Ret); 204 | return s32Ret; 205 | } 206 | 207 | /* 8. isp init */ 208 | s32Ret = HI_MPI_ISP_Init(IspDev); 209 | if (s32Ret != HI_SUCCESS) 210 | { 211 | printf("%s: HI_MPI_ISP_Init failed!\n", __FUNCTION__); 212 | return s32Ret; 213 | } 214 | gbIspInited = HI_TRUE; 215 | /*9. isp run*/ 216 | if (0 != pthread_create(&gs_IspPid, NULL, (void* (*)(void*))vdIspRun, NULL)) 217 | { 218 | printf("%s: create isp running thread failed!\n", __FUNCTION__); 219 | return HI_FAILURE; 220 | } 221 | usleep(1000); 222 | 223 | return HI_SUCCESS; 224 | } 225 | 226 | /***************************************************************************** 227 | * function : star vi dev 228 | *****************************************************************************/ 229 | static HI_S32 s32ViStartDev(VI_ATTR_S * pstViAttr) 230 | { 231 | HI_S32 s32Ret; 232 | VI_DEV ViDev; 233 | VI_DEV_ATTR_S * pstViDevAttr; 234 | 235 | if (NULL == pstViAttr) 236 | { 237 | printf("Func %s() Line[%d], parament is null\n", __FUNCTION__, __LINE__); 238 | return HI_FAILURE; 239 | } 240 | 241 | ViDev = pstViAttr->ViDev; 242 | pstViDevAttr = pstViAttr->pstViDevAttr; 243 | 244 | s32Ret = HI_MPI_VI_SetDevAttr(ViDev, pstViDevAttr); 245 | if (s32Ret != HI_SUCCESS) 246 | { 247 | printf("HI_MPI_VI_SetDevAttr failed with %#x!\n", s32Ret); 248 | return HI_FAILURE; 249 | } 250 | 251 | VI_WDR_ATTR_S stWdrAttr; 252 | stWdrAttr.enWDRMode = pstViAttr ->enWDRMode; 253 | stWdrAttr.bCompress = HI_FALSE; 254 | s32Ret = HI_MPI_VI_SetWDRAttr(ViDev, &stWdrAttr); 255 | if (s32Ret) 256 | { 257 | printf("HI_MPI_VI_SetWDRAttr failed with %#x!\n", s32Ret); 258 | return HI_FAILURE; 259 | } 260 | 261 | s32Ret = HI_MPI_VI_EnableDev(ViDev); 262 | if (s32Ret != HI_SUCCESS) 263 | { 264 | printf("HI_MPI_VI_EnableDev failed with %#x!\n", s32Ret); 265 | return HI_FAILURE; 266 | } 267 | return HI_SUCCESS; 268 | } 269 | 270 | /***************************************************************************** 271 | * function : star vi chn 272 | *****************************************************************************/ 273 | static HI_S32 s32ViStartChn(VI_CHN ViChn, VI_ATTR_S * pstViAttr) 274 | { 275 | HI_S32 s32Ret; 276 | VI_CHN_ATTR_S * pstChnAttr; 277 | 278 | if (NULL == pstViAttr) 279 | { 280 | printf("Func %s() Line[%d], parament is null\n", __FUNCTION__, __LINE__); 281 | return HI_FAILURE; 282 | } 283 | 284 | pstChnAttr = pstViAttr->pstChnAttr; 285 | s32Ret = HI_MPI_VI_SetChnAttr(ViChn, pstChnAttr); 286 | if (s32Ret != HI_SUCCESS) 287 | { 288 | printf("failed with %#x!\n", s32Ret); 289 | return HI_FAILURE; 290 | } 291 | 292 | s32Ret = HI_MPI_VI_EnableChn(ViChn); 293 | if (s32Ret != HI_SUCCESS) 294 | { 295 | printf("failed with %#x!\n", s32Ret); 296 | return HI_FAILURE; 297 | } 298 | 299 | return HI_SUCCESS; 300 | } 301 | 302 | 303 | static HI_S32 s32StartVi(VI_ATTR_S *pstViAttr) 304 | { 305 | HI_S32 i, s32Ret = HI_SUCCESS; 306 | VI_CHN ViChn; 307 | HI_U32 u32ChnNum; 308 | 309 | if(!pstViAttr) 310 | { 311 | printf("%s: null ptr\n", __FUNCTION__); 312 | return HI_FAILURE; 313 | } 314 | 315 | /****************************************** 316 | step 1: mipi configure 317 | ******************************************/ 318 | s32Ret = s32StartMIPI(pstViAttr); 319 | if (HI_SUCCESS != s32Ret) 320 | { 321 | printf("%s: MIPI init failed!\n", __FUNCTION__); 322 | return HI_FAILURE; 323 | } 324 | 325 | /****************************************** 326 | step 2: configure sensor and ISP (include WDR mode). 327 | note: you can jump over this step, if you do not use interal isp. 328 | ******************************************/ 329 | s32Ret = s32IspInit(pstViAttr); 330 | if (HI_SUCCESS != s32Ret) 331 | { 332 | printf("%s: Sensor init failed!\n", __FUNCTION__); 333 | return HI_FAILURE; 334 | } 335 | 336 | /****************************************************** 337 | step 3 : config & start vicap dev 338 | ******************************************************/ 339 | s32Ret = s32ViStartDev(pstViAttr); 340 | if (HI_SUCCESS != s32Ret) 341 | { 342 | printf("%s: start vi dev[%d] failed!\n", __FUNCTION__, pstViAttr->ViDev); 343 | return HI_FAILURE; 344 | } 345 | 346 | /****************************************************** 347 | * Step 4: config & start vicap chn (max 1) 348 | ******************************************************/ 349 | u32ChnNum = pstViAttr->u32ChnNum; 350 | for (i = 0; i < u32ChnNum; i++) 351 | { 352 | ViChn = i; 353 | s32Ret = s32ViStartChn(ViChn,pstViAttr); 354 | if (HI_SUCCESS != s32Ret) 355 | { 356 | printf("%s: start vi chn[%d] failed!\n", __FUNCTION__, ViChn); 357 | return HI_FAILURE; 358 | } 359 | } 360 | 361 | return s32Ret; 362 | } 363 | 364 | static HI_VOID viAttrInit(const IPC_VEDIO_S* pstIpcVedio,VI_ATTR_S **pstViAttr) 365 | { 366 | static combo_dev_attr_t MIPI_CMOS3V3_ATTR = 367 | { 368 | /* input mode */ 369 | .input_mode = INPUT_MODE_CMOS_33V, 370 | { 371 | 372 | } 373 | }; 374 | static ISP_PUB_ATTR_S ISP_PUB_ATTR = 375 | { 376 | .stWndRect = {0, 0, 1920, 1080}, 377 | .f32FrameRate = 30, 378 | .enBayer = BAYER_RGGB, 379 | }; 380 | 381 | /* the attributes of a VI device */ 382 | static VI_DEV_ATTR_S VI_DEV_ATTR = 383 | { 384 | .enIntfMode = VI_MODE_DIGITAL_CAMERA, /* Interface mode */ 385 | .enWorkMode = VI_WORK_MODE_1Multiplex, /*1-, 2-, or 4-channel multiplexed work mode */ 386 | .au32CompMask = {0x3FF00000, 0x0}, /* r_mask g_mask b_mask*/ 387 | .enScanMode = VI_SCAN_PROGRESSIVE, /* Input scanning mode (progressive or interlaced) */ 388 | .s32AdChnId = {-1, -1, -1, -1}, /* AD channel ID. Typically, the default value -1 is recommended */ 389 | 390 | /* The below members must be configured in BT.601 mode or DC mode and are invalid in other modes */ 391 | .enDataSeq = VI_INPUT_DATA_YUYV, /* Input data sequence (only the YUV format is supported) */ 392 | .stSynCfg = 393 | { 394 | VI_VSYNC_PULSE, /*Vsync*/ 395 | VI_VSYNC_NEG_HIGH, /*VsyncNeg*/ 396 | VI_HSYNC_VALID_SINGNAL, /*Hsync*/ 397 | VI_HSYNC_NEG_HIGH, /*HsyncNeg*/ 398 | VI_VSYNC_VALID_SINGAL, /*VsyncValid*/ 399 | VI_VSYNC_VALID_NEG_HIGH,/*VsyncValidNeg*/ 400 | /*The below TimingBlank only for BT.601*/ 401 | /*hsync_hfb hsync_act hsync_hhb*/ 402 | {0, 1920, 0, 403 | /*vsync0_vhb vsync0_act vsync0_hhb*/ 404 | 0, 1080, 0, 405 | /*vsync1_vhb vsync1_act vsync1_hhb*/ 406 | 0, 0, 0} 407 | }, 408 | .enDataPath = VI_PATH_ISP, /* ISP enable or bypass */ 409 | .enInputDataType = VI_DATA_TYPE_RGB,/* RGB: CSC-709 or CSC-601, PT YUV444 disable; YUV: default yuv CSC coef PT YUV444 enable. */ 410 | .bDataRev = HI_FALSE, /* Data Reverse */ 411 | .stDevRect = {0, 0, 1920, 1080} /* Dev capture rect */ 412 | }; 413 | 414 | /* the attributes of a VI channel */ 415 | static VI_CHN_ATTR_S VI_CHN_ATTR = 416 | { 417 | .stCapRect = {0, 0, 1920, 1080}, 418 | .stDestSize = {1920, 1080}, 419 | .enCapSel = VI_CAPSEL_BOTH, 420 | .enPixFormat = PIXEL_FORMAT_YUV_SEMIPLANAR_420, 421 | .enCompressMode = COMPRESS_MODE_NONE, 422 | .bMirror = HI_FALSE, 423 | .bFlip = HI_FALSE, 424 | .s32SrcFrameRate = -1, 425 | .s32DstFrameRate = -1 426 | }; 427 | 428 | static VI_ATTR_S VI_ATTR = 429 | { 430 | .IspDev = 0, 431 | .ViDev = 0, 432 | .u32ChnNum = 1, 433 | .enWDRMode = WDR_MODE_NONE, 434 | .pstcomboDevAttr = &MIPI_CMOS3V3_ATTR, 435 | .pstIspPubAttr = &ISP_PUB_ATTR, 436 | .pstViDevAttr = &VI_DEV_ATTR, 437 | .pstChnAttr = &VI_CHN_ATTR 438 | }; 439 | /*sync isp pub attr*/ 440 | VI_ATTR.pstIspPubAttr->stWndRect.u32Width = pstIpcVedio->astStreamFmt[0].stSize.u32Width; 441 | VI_ATTR.pstIspPubAttr->stWndRect.u32Height = pstIpcVedio->astStreamFmt[0].stSize.u32Height; 442 | VI_ATTR.pstIspPubAttr->f32FrameRate = 25;//pstIpcVedio->astStreamFmt[0].f32FrameRate; 443 | /*sync vi dev attr*/ 444 | VI_ATTR.pstViDevAttr->stDevRect.u32Width = pstIpcVedio->astStreamFmt[0].stSize.u32Width; 445 | VI_ATTR.pstViDevAttr->stDevRect.u32Height = pstIpcVedio->astStreamFmt[0].stSize.u32Height; 446 | /*sync vi chn attr*/ 447 | VI_ATTR.pstChnAttr->stCapRect.u32Width = pstIpcVedio->astStreamFmt[0].stSize.u32Width; 448 | VI_ATTR.pstChnAttr->stCapRect.u32Height = pstIpcVedio->astStreamFmt[0].stSize.u32Height; 449 | VI_ATTR.pstChnAttr->stDestSize.u32Width = pstIpcVedio->astStreamFmt[0].stSize.u32Width; 450 | VI_ATTR.pstChnAttr->stDestSize.u32Height = pstIpcVedio->astStreamFmt[0].stSize.u32Height; 451 | VI_ATTR.pstChnAttr->enPixFormat = pstIpcVedio->e_pixFmt; 452 | /*sync wdr mode*/ 453 | VI_ATTR.enWDRMode = pstIpcVedio->e_wdrMode; 454 | 455 | *pstViAttr = &VI_ATTR; 456 | } 457 | HI_S32 VI_init(const IPC_VEDIO_S* pstIpcVedio) 458 | { 459 | HI_S32 s32Ret = HI_SUCCESS; 460 | if(!pstIpcVedio) 461 | { 462 | printf("%s: null ptr\n", __FUNCTION__); 463 | return HI_FAILURE; 464 | } 465 | viAttrInit(pstIpcVedio,&g_pstViAttr); 466 | s32Ret = s32StartVi(g_pstViAttr); 467 | return s32Ret; 468 | } 469 | 470 | HI_S32 VI_exit(void) 471 | { 472 | HI_S32 s32Ret = HI_SUCCESS; 473 | s32Ret = s32StopVi(g_pstViAttr); 474 | vdIspStop(g_pstViAttr); 475 | return s32Ret; 476 | } 477 | 478 | -------------------------------------------------------------------------------- /Server/src/hp_vpss.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9crk/RtspClient/7501dd35c2a220d0777301a8b3d1c0ca6fb6c90b/Server/src/hp_vpss.c -------------------------------------------------------------------------------- /Server/src/rtsp_server.c: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | #if __cplusplus 3 | extern "C"{ 4 | #endif 5 | #endif /* End of #ifdef __cplusplus */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "rtsp_server.h" 29 | 30 | 31 | 32 | //static bool flag = true; 33 | RTP_FIXED_HEADER *rtp_hdr; 34 | 35 | NALU_HEADER *nalu_hdr; 36 | FU_INDICATOR *fu_ind; 37 | FU_HEADER *fu_hdr; 38 | 39 | 40 | RTSP_CLIENT g_rtspClients[MAX_RTSP_CLIENT]; 41 | 42 | int g_nSendDataChn = -1; 43 | pthread_mutex_t g_mutex; 44 | pthread_cond_t g_cond; 45 | pthread_mutex_t g_sendmutex; 46 | 47 | pthread_t g_SendDataThreadId = 0; 48 | //HAL_CLIENT_HANDLE hMainStreamClient = NULL,hSubStreamClient = NULL,hAudioClient = NULL; 49 | char g_rtp_playload[20]; 50 | int g_audio_rate = 8000; 51 | VIDEO_NORM_E gs_enNorm = VIDEO_ENCODING_MODE_NTSC;//30fps 52 | int g_nframerate; 53 | //VIDEO_NORM_E gs_enNorm = VIDEO_ENCODING_MODE_PAL;//15fps 54 | //int g_nframerate = 15; 55 | int exitok = 0; 56 | 57 | int udpfd; 58 | 59 | struct list_head RTPbuf_head = LIST_HEAD_INIT(RTPbuf_head); 60 | 61 | static pthread_t gs_RtpPid; 62 | 63 | 64 | static char const* dateHeader() 65 | { 66 | static char buf[200]; 67 | #if !defined(_WIN32_WCE) 68 | time_t tt = time(NULL); 69 | strftime(buf, sizeof buf, "Date: %a, %b %d %Y %H:%M:%S GMT\r\n", gmtime(&tt)); 70 | #endif 71 | 72 | return buf; 73 | } 74 | static char* GetLocalIP(int sock) 75 | { 76 | struct ifreq ifreq; 77 | struct sockaddr_in *sin; 78 | char * LocalIP = malloc(20); 79 | strcpy(ifreq.ifr_name,"eth0"); 80 | if (!(ioctl (sock, SIOCGIFADDR,&ifreq))) 81 | { 82 | sin = (struct sockaddr_in *)&ifreq.ifr_addr; 83 | sin->sin_family = AF_INET; 84 | strcpy(LocalIP,inet_ntoa(sin->sin_addr)); 85 | //inet_ntop(AF_INET, &sin->sin_addr,LocalIP, 16); 86 | } 87 | printf("--------------------------------------------%s\n",LocalIP); 88 | return LocalIP; 89 | } 90 | 91 | char* strDupSize(char const* str) 92 | { 93 | if (str == NULL) return NULL; 94 | size_t len = strlen(str) + 1; 95 | char* copy = malloc(len); 96 | 97 | return copy; 98 | } 99 | 100 | int ParseRequestString(char const* reqStr, 101 | unsigned reqStrSize, 102 | char* resultCmdName, 103 | unsigned resultCmdNameMaxSize, 104 | char* resultURLPreSuffix, 105 | unsigned resultURLPreSuffixMaxSize, 106 | char* resultURLSuffix, 107 | unsigned resultURLSuffixMaxSize, 108 | char* resultCSeq, 109 | unsigned resultCSeqMaxSize) 110 | { 111 | // This parser is currently rather dumb; it should be made smarter ##### 112 | 113 | // Read everything up to the first space as the command name: 114 | int parseSucceeded = FALSE; 115 | unsigned i; 116 | for (i = 0; i < resultCmdNameMaxSize-1 && i < reqStrSize; ++i) { 117 | char c = reqStr[i]; 118 | if (c == ' ' || c == '\t') { 119 | parseSucceeded = TRUE; 120 | break; 121 | } 122 | 123 | resultCmdName[i] = c; 124 | } 125 | resultCmdName[i] = '\0'; 126 | if (!parseSucceeded) return FALSE; 127 | 128 | // Skip over the prefix of any "rtsp://" or "rtsp:/" URL that follows: 129 | unsigned j = i+1; 130 | while (j < reqStrSize && (reqStr[j] == ' ' || reqStr[j] == '\t')) ++j; // skip over any additional white space 131 | for (j = i+1; j < reqStrSize-8; ++j) { 132 | if ((reqStr[j] == 'r' || reqStr[j] == 'R') 133 | && (reqStr[j+1] == 't' || reqStr[j+1] == 'T') 134 | && (reqStr[j+2] == 's' || reqStr[j+2] == 'S') 135 | && (reqStr[j+3] == 'p' || reqStr[j+3] == 'P') 136 | && reqStr[j+4] == ':' && reqStr[j+5] == '/') { 137 | j += 6; 138 | if (reqStr[j] == '/') { 139 | // This is a "rtsp://" URL; skip over the host:port part that follows: 140 | ++j; 141 | while (j < reqStrSize && reqStr[j] != '/' && reqStr[j] != ' ') ++j; 142 | } else { 143 | // This is a "rtsp:/" URL; back up to the "/": 144 | --j; 145 | } 146 | i = j; 147 | break; 148 | } 149 | } 150 | 151 | // Look for the URL suffix (before the following "RTSP/"): 152 | parseSucceeded = FALSE; 153 | unsigned k; 154 | for (k = i+1; k < reqStrSize-5; ++k) { 155 | if (reqStr[k] == 'R' && reqStr[k+1] == 'T' && 156 | reqStr[k+2] == 'S' && reqStr[k+3] == 'P' && reqStr[k+4] == '/') { 157 | while (--k >= i && reqStr[k] == ' ') {} // go back over all spaces before "RTSP/" 158 | unsigned k1 = k; 159 | while (k1 > i && reqStr[k1] != '/' && reqStr[k1] != ' ') --k1; 160 | // the URL suffix comes from [k1+1,k] 161 | 162 | // Copy "resultURLSuffix": 163 | if (k - k1 + 1 > resultURLSuffixMaxSize) return FALSE; // there's no room 164 | unsigned n = 0, k2 = k1+1; 165 | while (k2 <= k) resultURLSuffix[n++] = reqStr[k2++]; 166 | resultURLSuffix[n] = '\0'; 167 | 168 | // Also look for the URL 'pre-suffix' before this: 169 | unsigned k3 = --k1; 170 | while (k3 > i && reqStr[k3] != '/' && reqStr[k3] != ' ') --k3; 171 | // the URL pre-suffix comes from [k3+1,k1] 172 | 173 | // Copy "resultURLPreSuffix": 174 | if (k1 - k3 + 1 > resultURLPreSuffixMaxSize) return FALSE; // there's no room 175 | n = 0; k2 = k3+1; 176 | while (k2 <= k1) resultURLPreSuffix[n++] = reqStr[k2++]; 177 | resultURLPreSuffix[n] = '\0'; 178 | 179 | i = k + 7; // to go past " RTSP/" 180 | parseSucceeded = TRUE; 181 | break; 182 | } 183 | } 184 | if (!parseSucceeded) return FALSE; 185 | 186 | // Look for "CSeq:", skip whitespace, 187 | // then read everything up to the next \r or \n as 'CSeq': 188 | parseSucceeded = FALSE; 189 | for (j = i; j < reqStrSize-5; ++j) { 190 | if (reqStr[j] == 'C' && reqStr[j+1] == 'S' && reqStr[j+2] == 'e' && 191 | reqStr[j+3] == 'q' && reqStr[j+4] == ':') { 192 | j += 5; 193 | unsigned n; 194 | while (j < reqStrSize && (reqStr[j] == ' ' || reqStr[j] == '\t')) ++j; 195 | for (n = 0; n < resultCSeqMaxSize-1 && j < reqStrSize; ++n,++j) { 196 | char c = reqStr[j]; 197 | if (c == '\r' || c == '\n') { 198 | parseSucceeded = TRUE; 199 | break; 200 | } 201 | 202 | resultCSeq[n] = c; 203 | } 204 | resultCSeq[n] = '\0'; 205 | break; 206 | } 207 | } 208 | if (!parseSucceeded) return FALSE; 209 | 210 | return TRUE; 211 | } 212 | 213 | int OptionAnswer(char *cseq, int sock) 214 | { 215 | if (sock != 0) 216 | { 217 | char buf[1024]; 218 | memset(buf,0,1024); 219 | char *pTemp = buf; 220 | pTemp += sprintf(pTemp,"RTSP/1.0 200 OK\r\nCSeq: %s\r\n%sPublic: %s\r\n\r\n", 221 | cseq,dateHeader(),"OPTIONS,DESCRIBE,SETUP,PLAY,PAUSE,TEARDOWN"); 222 | 223 | int reg = send(sock, buf,strlen(buf),0); 224 | if(reg <= 0) 225 | { 226 | return FALSE; 227 | } 228 | else 229 | { 230 | printf(">>>>>%s\n",buf); 231 | } 232 | return TRUE; 233 | } 234 | return FALSE; 235 | } 236 | 237 | int DescribeAnswer(char *cseq,int sock,char * urlSuffix,char* recvbuf) 238 | { 239 | if (sock != 0) 240 | { 241 | char sdpMsg[1024]; 242 | char buf[2048]; 243 | memset(buf,0,2048); 244 | memset(sdpMsg,0,1024); 245 | char*localip; 246 | localip = GetLocalIP(sock); 247 | 248 | char *pTemp = buf; 249 | pTemp += sprintf(pTemp,"RTSP/1.0 200 OK\r\nCSeq: %s\r\n",cseq); 250 | pTemp += sprintf(pTemp,"%s",dateHeader()); 251 | pTemp += sprintf(pTemp,"Content-Type: application/sdp\r\n"); 252 | 253 | //TODO °?ò?D?1ì???μ???a?ˉì??μ 254 | char *pTemp2 = sdpMsg; 255 | pTemp2 += sprintf(pTemp2,"v=0\r\n"); 256 | pTemp2 += sprintf(pTemp2,"o=StreamingServer 3331435948 1116907222000 IN IP4 %s\r\n",localip); 257 | pTemp2 += sprintf(pTemp2,"s=H.264\r\n"); 258 | pTemp2 += sprintf(pTemp2,"c=IN IP4 0.0.0.0\r\n"); 259 | pTemp2 += sprintf(pTemp2,"t=0 0\r\n"); 260 | pTemp2 += sprintf(pTemp2,"a=control:*\r\n"); 261 | 262 | /*êó?μ??ì??èê?*/ 263 | /*H264 TrackID=0 RTP_PT 96*/ 264 | pTemp2 += sprintf(pTemp2,"m=video 0 RTP/AVP 96\r\n"); 265 | pTemp2 += sprintf(pTemp2,"a=control:trackID=0\r\n"); 266 | pTemp2 += sprintf(pTemp2,"a=rtpmap:96 H264/90000\r\n"); 267 | pTemp2 += sprintf(pTemp2,"a=fmtp:96 packetization-mode=1; sprop-parameter-sets=%s\r\n", "AAABBCCC"); 268 | #if 1 269 | /*ò??μ??ì??èê?*/ 270 | /*G726*/ 271 | /*TODO ò??μ*/ 272 | pTemp2 += sprintf(pTemp2,"m=audio 0 RTP/AVP 97\r\n"); 273 | pTemp2 += sprintf(pTemp2,"a=control:trackID=1\r\n"); 274 | if(strcmp(g_rtp_playload,"AAC")==0) 275 | { 276 | pTemp2 += sprintf(pTemp2,"a=rtpmap:97 MPEG4-GENERIC/%d/2\r\n",16000); 277 | 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"); 278 | } 279 | else 280 | { 281 | pTemp2 += sprintf(pTemp2,"a=rtpmap:97 G726-32/%d/1\r\n",8000); 282 | pTemp2 += sprintf(pTemp2,"a=fmtp:97 packetization-mode=1\r\n"); 283 | } 284 | #endif 285 | pTemp += sprintf(pTemp,"Content-length: %d\r\n", strlen(sdpMsg)); 286 | pTemp += sprintf(pTemp,"Content-Base: rtsp://%s/%s/\r\n\r\n",localip,urlSuffix); 287 | 288 | //printf("mem ready\n"); 289 | strcat(pTemp, sdpMsg); 290 | free(localip); 291 | //printf("Describe ready sent\n"); 292 | int re = send(sock, buf, strlen(buf),0); 293 | if(re <= 0) 294 | { 295 | return FALSE; 296 | } 297 | else 298 | { 299 | printf(">>>>>%s\n",buf); 300 | } 301 | } 302 | 303 | return TRUE; 304 | } 305 | void ParseTransportHeader(char const* buf, 306 | StreamingMode* streamingMode, 307 | char**streamingModeString, 308 | char**destinationAddressStr, 309 | u_int8_t* destinationTTL, 310 | portNumBits* clientRTPPortNum, // if UDP 311 | portNumBits* clientRTCPPortNum, // if UDP 312 | unsigned char* rtpChannelId, // if TCP 313 | unsigned char* rtcpChannelId // if TCP 314 | ) 315 | { 316 | // Initialize the result parameters to default values: 317 | *streamingMode = RTP_UDP; 318 | *streamingModeString = NULL; 319 | *destinationAddressStr = NULL; 320 | *destinationTTL = 255; 321 | *clientRTPPortNum = 0; 322 | *clientRTCPPortNum = 1; 323 | *rtpChannelId = *rtcpChannelId = 0xFF; 324 | 325 | portNumBits p1, p2; 326 | unsigned ttl, rtpCid, rtcpCid; 327 | 328 | // First, find "Transport:" 329 | while (1) { 330 | if (*buf == '\0') return; // not found 331 | if (strncasecmp(buf, "Transport: ", 11) == 0) break; 332 | ++buf; 333 | } 334 | 335 | // Then, run through each of the fields, looking for ones we handle: 336 | char const* fields = buf + 11; 337 | char* field = strDupSize(fields); 338 | while (sscanf(fields, "%[^;]", field) == 1) { 339 | if (strcmp(field, "RTP/AVP/TCP") == 0) { 340 | *streamingMode = RTP_TCP; 341 | } else if (strcmp(field, "RAW/RAW/UDP") == 0 || 342 | strcmp(field, "MP2T/H2221/UDP") == 0) { 343 | *streamingMode = RAW_UDP; 344 | //*streamingModeString = strDup(field); 345 | } else if (strncasecmp(field, "destination=", 12) == 0) 346 | { 347 | //delete[] destinationAddressStr; 348 | free(destinationAddressStr); 349 | //destinationAddressStr = strDup(field+12); 350 | } else if (sscanf(field, "ttl%u", &ttl) == 1) { 351 | destinationTTL = (u_int8_t)ttl; 352 | } else if (sscanf(field, "client_port=%hu-%hu", &p1, &p2) == 2) { 353 | *clientRTPPortNum = p1; 354 | *clientRTCPPortNum = p2; 355 | } else if (sscanf(field, "client_port=%hu", &p1) == 1) { 356 | *clientRTPPortNum = p1; 357 | *clientRTCPPortNum = streamingMode == RAW_UDP ? 0 : p1 + 1; 358 | } else if (sscanf(field, "interleaved=%u-%u", &rtpCid, &rtcpCid) == 2) { 359 | *rtpChannelId = (unsigned char)rtpCid; 360 | *rtcpChannelId = (unsigned char)rtcpCid; 361 | } 362 | 363 | fields += strlen(field); 364 | while (*fields == ';') ++fields; // skip over separating ';' chars 365 | if (*fields == '\0' || *fields == '\r' || *fields == '\n') break; 366 | } 367 | free(field); 368 | } 369 | 370 | 371 | int SetupAnswer(char *cseq,int sock,int SessionId,char * urlSuffix,char* recvbuf,int* rtpport, int* rtcpport) 372 | { 373 | if (sock != 0) 374 | { 375 | char buf[1024]; 376 | memset(buf,0,1024); 377 | 378 | StreamingMode streamingMode; 379 | char* streamingModeString; // set when RAW_UDP streaming is specified 380 | char* clientsDestinationAddressStr; 381 | u_int8_t clientsDestinationTTL; 382 | portNumBits clientRTPPortNum, clientRTCPPortNum; 383 | unsigned char rtpChannelId, rtcpChannelId; 384 | ParseTransportHeader(recvbuf,&streamingMode, &streamingModeString, 385 | &clientsDestinationAddressStr, &clientsDestinationTTL, 386 | &clientRTPPortNum, &clientRTCPPortNum, 387 | &rtpChannelId, &rtcpChannelId); 388 | 389 | //Port clientRTPPort(clientRTPPortNum); 390 | //Port clientRTCPPort(clientRTCPPortNum); 391 | *rtpport = clientRTPPortNum; 392 | *rtcpport = clientRTCPPortNum; 393 | 394 | char *pTemp = buf; 395 | char*localip; 396 | localip = GetLocalIP(sock); 397 | 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", 398 | cseq,dateHeader(),localip, 399 | ntohs(htons(clientRTPPortNum)), 400 | ntohs(htons(clientRTCPPortNum)), 401 | ntohs(2000), 402 | ntohs(2001), 403 | SessionId); 404 | 405 | free(localip); 406 | int reg = send(sock, buf,strlen(buf),0); 407 | if(reg <= 0) 408 | { 409 | return FALSE; 410 | } 411 | else 412 | { 413 | printf(">>>>>%s",buf); 414 | } 415 | return TRUE; 416 | } 417 | return FALSE; 418 | } 419 | 420 | int PlayAnswer(char *cseq, int sock,int SessionId,char* urlPre,char* recvbuf) 421 | { 422 | if (sock != 0) 423 | { 424 | char buf[1024]; 425 | memset(buf,0,1024); 426 | char *pTemp = buf; 427 | char*localip; 428 | localip = GetLocalIP(sock); 429 | 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", 430 | cseq,dateHeader(),SessionId,localip,urlPre); 431 | 432 | free(localip); 433 | 434 | int reg = send(sock, buf,strlen(buf),0); 435 | if(reg <= 0) 436 | { 437 | return FALSE; 438 | } 439 | else 440 | { 441 | printf(">>>>>%s",buf); 442 | udpfd = socket(AF_INET,SOCK_DGRAM,0);//UDP 443 | struct sockaddr_in server; 444 | server.sin_family=AF_INET; 445 | server.sin_port=htons(g_rtspClients[0].rtpport[0]); 446 | server.sin_addr.s_addr=inet_addr(g_rtspClients[0].IP); 447 | connect(udpfd,(struct sockaddr *)&server,sizeof(server)); 448 | printf("udp up\n"); 449 | } 450 | return TRUE; 451 | } 452 | return FALSE; 453 | } 454 | 455 | int PauseAnswer(char *cseq,int sock,char *recvbuf) 456 | { 457 | if (sock != 0) 458 | { 459 | char buf[1024]; 460 | memset(buf,0,1024); 461 | char *pTemp = buf; 462 | pTemp += sprintf(pTemp,"RTSP/1.0 200 OK\r\nCSeq: %s\r\n%s\r\n\r\n", 463 | cseq,dateHeader()); 464 | 465 | int reg = send(sock, buf,strlen(buf),0); 466 | if(reg <= 0) 467 | { 468 | return FALSE; 469 | } 470 | else 471 | { 472 | printf(">>>>>%s",buf); 473 | } 474 | return TRUE; 475 | } 476 | return FALSE; 477 | } 478 | 479 | int TeardownAnswer(char *cseq,int sock,int SessionId,char *recvbuf) 480 | { 481 | if (sock != 0) 482 | { 483 | char buf[1024]; 484 | memset(buf,0,1024); 485 | char *pTemp = buf; 486 | pTemp += sprintf(pTemp,"RTSP/1.0 200 OK\r\nCSeq: %s\r\n%sSession: %d\r\n\r\n", 487 | cseq,dateHeader(),SessionId); 488 | 489 | int reg = send(sock, buf,strlen(buf),0); 490 | if(reg <= 0) 491 | { 492 | return FALSE; 493 | } 494 | else 495 | { 496 | printf(">>>>>%s",buf); 497 | close(udpfd); 498 | } 499 | return TRUE; 500 | } 501 | return FALSE; 502 | } 503 | void * RtspClientMsg(void*pParam) 504 | { 505 | pthread_detach(pthread_self()); 506 | int nRes; 507 | char pRecvBuf[RTSP_RECV_SIZE]; 508 | RTSP_CLIENT * pClient = (RTSP_CLIENT*)pParam; 509 | memset(pRecvBuf,0,sizeof(pRecvBuf)); 510 | printf("RTSP:-----Create Client %s\n",pClient->IP); 511 | while(pClient->status != RTSP_IDLE) 512 | { 513 | nRes = recv(pClient->socket, pRecvBuf, RTSP_RECV_SIZE,0); 514 | //printf("-------------------%d\n",nRes); 515 | if(nRes < 1) 516 | { 517 | //usleep(1000); 518 | printf("RTSP:Recv Error--- %d\n",nRes); 519 | g_rtspClients[pClient->index].status = RTSP_IDLE; 520 | g_rtspClients[pClient->index].seqnum = 0; 521 | g_rtspClients[pClient->index].tsvid = 0; 522 | g_rtspClients[pClient->index].tsaud = 0; 523 | close(pClient->socket); 524 | break; 525 | } 526 | char cmdName[PARAM_STRING_MAX]; 527 | char urlPreSuffix[PARAM_STRING_MAX]; 528 | char urlSuffix[PARAM_STRING_MAX]; 529 | char cseq[PARAM_STRING_MAX]; 530 | 531 | ParseRequestString(pRecvBuf,nRes,cmdName,sizeof(cmdName),urlPreSuffix,sizeof(urlPreSuffix), 532 | urlSuffix,sizeof(urlSuffix),cseq,sizeof(cseq)); 533 | 534 | char *p = pRecvBuf; 535 | 536 | printf("<<<<<%s\n",p); 537 | 538 | //printf("\--------------------------\n"); 539 | //printf("%s %s\n",urlPreSuffix,urlSuffix); 540 | 541 | if(strstr(cmdName, "OPTIONS")) 542 | { 543 | OptionAnswer(cseq,pClient->socket); 544 | 545 | } 546 | else if(strstr(cmdName, "DESCRIBE")) 547 | { 548 | DescribeAnswer(cseq,pClient->socket,urlSuffix,p); 549 | //printf("-----------------------------DescribeAnswer %s %s\n", 550 | // urlPreSuffix,urlSuffix); 551 | } 552 | else if(strstr(cmdName, "SETUP")) 553 | { 554 | int rtpport,rtcpport; 555 | int trackID=0; 556 | SetupAnswer(cseq,pClient->socket,pClient->sessionid,urlPreSuffix,p,&rtpport,&rtcpport); 557 | 558 | sscanf(urlSuffix, "trackID=%u", &trackID); 559 | //printf("----------------------------------------------TrackId %d\n",trackID); 560 | if(trackID<0 || trackID>=2)trackID=0; 561 | g_rtspClients[pClient->index].rtpport[trackID] = rtpport; 562 | g_rtspClients[pClient->index].rtcpport= rtcpport; 563 | g_rtspClients[pClient->index].reqchn = atoi(urlPreSuffix); 564 | if(strlen(urlPreSuffix)<100) 565 | strcpy(g_rtspClients[pClient->index].urlPre,urlPreSuffix); 566 | //printf("-----------------------------SetupAnswer %s-%d-%d\n", 567 | // urlPreSuffix,g_rtspClients[pClient->index].reqchn,rtpport); 568 | } 569 | else if(strstr(cmdName, "PLAY")) 570 | { 571 | PlayAnswer(cseq,pClient->socket,pClient->sessionid,g_rtspClients[pClient->index].urlPre,p); 572 | g_rtspClients[pClient->index].status = RTSP_SENDING; 573 | printf("Start Play\n",pClient->index); 574 | //printf("-----------------------------PlayAnswer %d %d\n",pClient->index); 575 | //usleep(100); 576 | } 577 | else if(strstr(cmdName, "PAUSE")) 578 | { 579 | PauseAnswer(cseq,pClient->socket,p); 580 | } 581 | else if(strstr(cmdName, "TEARDOWN")) 582 | { 583 | TeardownAnswer(cseq,pClient->socket,pClient->sessionid,p); 584 | g_rtspClients[pClient->index].status = RTSP_IDLE; 585 | g_rtspClients[pClient->index].seqnum = 0; 586 | g_rtspClients[pClient->index].tsvid = 0; 587 | g_rtspClients[pClient->index].tsaud = 0; 588 | close(pClient->socket); 589 | } 590 | //if(exitok){ exitok++;return NULL; } 591 | } 592 | printf("RTSP:-----Exit Client %s\n",pClient->IP); 593 | return NULL; 594 | } 595 | 596 | void * RtspServerListen(void*pParam) 597 | { 598 | int s32Socket; 599 | struct sockaddr_in servaddr; 600 | int s32CSocket; 601 | int s32Rtn; 602 | int s32Socket_opt_value = 1; 603 | int nAddrLen; 604 | struct sockaddr_in addrAccept; 605 | int bResult; 606 | 607 | memset(&servaddr, 0, sizeof(servaddr)); 608 | servaddr.sin_family = AF_INET; 609 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 610 | servaddr.sin_port = htons(RTSP_SERVER_PORT); 611 | 612 | s32Socket = socket(AF_INET, SOCK_STREAM, 0); 613 | 614 | if (setsockopt(s32Socket ,SOL_SOCKET,SO_REUSEADDR,&s32Socket_opt_value,sizeof(int)) == -1) 615 | { 616 | return (void *)(-1); 617 | } 618 | s32Rtn = bind(s32Socket, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in)); 619 | if(s32Rtn < 0) 620 | { 621 | return (void *)(-2); 622 | } 623 | 624 | s32Rtn = listen(s32Socket, 50); /*50,×??óμ?á??óêy*/ 625 | if(s32Rtn < 0) 626 | { 627 | 628 | return (void *)(-2); 629 | } 630 | 631 | 632 | nAddrLen = sizeof(struct sockaddr_in); 633 | int nSessionId = 1000; 634 | while ((s32CSocket = accept(s32Socket, (struct sockaddr*)&addrAccept, &nAddrLen)) >= 0) 635 | { 636 | printf("<<<payload = RTP_H264; 727 | rtp_hdr->version = 2; 728 | rtp_hdr->marker = 0; 729 | rtp_hdr->ssrc = htonl(10); 730 | 731 | if(nAvFrmLen<=nalu_sent_len) 732 | { 733 | rtp_hdr->marker=1; 734 | rtp_hdr->seq_no = htons(g_rtspClients[is].seqnum++); 735 | nalu_hdr =(NALU_HEADER*)&sendbuf[12]; 736 | nalu_hdr->F=0; 737 | nalu_hdr->NRI= nIsIFrm; 738 | nalu_hdr->TYPE= nNaluType; 739 | nalu_payload=&sendbuf[13]; 740 | memcpy(nalu_payload,buffer,nAvFrmLen); 741 | g_rtspClients[is].tsvid = g_rtspClients[is].tsvid+timestamp_increse; 742 | rtp_hdr->timestamp=htonl(g_rtspClients[is].tsvid); 743 | bytes=nAvFrmLen+ 13 ; 744 | sendto(udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server)); 745 | } 746 | else if(nAvFrmLen>nalu_sent_len) 747 | { 748 | int k=0,l=0; 749 | // 包数 750 | k=nAvFrmLen/nalu_sent_len; 751 | // 最后一个包的剩余字节数 752 | l=nAvFrmLen%nalu_sent_len; 753 | int t=0; 754 | 755 | g_rtspClients[is].tsvid = g_rtspClients[is].tsvid+timestamp_increse; 756 | rtp_hdr->timestamp=htonl(g_rtspClients[is].tsvid); 757 | while(t<=k) 758 | { 759 | rtp_hdr->seq_no = htons(g_rtspClients[is].seqnum++); 760 | if(t==0) 761 | { 762 | // the first pack 763 | //éè??rtp M ??£? 764 | rtp_hdr->marker=0; 765 | fu_ind =(FU_INDICATOR*)&sendbuf[12]; 766 | fu_ind->F= 0; 767 | fu_ind->NRI= nIsIFrm; 768 | fu_ind->TYPE=28; 769 | 770 | //éè??FU HEADER,2¢???a??HEADERì?è?sendbuf[13] 771 | fu_hdr =(FU_HEADER*)&sendbuf[13]; 772 | fu_hdr->E=0; 773 | fu_hdr->R=0; 774 | fu_hdr->S=1; 775 | fu_hdr->TYPE=nNaluType; 776 | 777 | nalu_payload=&sendbuf[14]; 778 | memcpy(nalu_payload,buffer,nalu_sent_len); 779 | 780 | bytes=nalu_sent_len+14; 781 | sendto( udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server)); 782 | t++; 783 | 784 | } 785 | else if(k==t) 786 | { 787 | // the last pack 788 | //éè??rtp M ??£?μ±?°′?ê?μ?ê?×?oóò???·???ê±??????1 789 | rtp_hdr->marker=1; 790 | fu_ind =(FU_INDICATOR*)&sendbuf[12]; 791 | fu_ind->F= 0 ; 792 | fu_ind->NRI= nIsIFrm ; 793 | fu_ind->TYPE=28; 794 | //éè??FU HEADER,2¢???a??HEADERì?è?sendbuf[13] 795 | fu_hdr =(FU_HEADER*)&sendbuf[13]; 796 | fu_hdr->R=0; 797 | fu_hdr->S=0; 798 | fu_hdr->TYPE= nNaluType; 799 | fu_hdr->E=1; 800 | nalu_payload=&sendbuf[14]; 801 | memcpy(nalu_payload,buffer+t*nalu_sent_len,l); 802 | bytes=l+14; 803 | sendto(udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server)); 804 | t++; 805 | } 806 | else if(tmarker=0; 811 | //éè??FU INDICATOR,2¢???a??HEADERì?è?sendbuf[12] 812 | fu_ind =(FU_INDICATOR*)&sendbuf[12]; 813 | fu_ind->F=0; 814 | fu_ind->NRI=nIsIFrm; 815 | fu_ind->TYPE=28; 816 | fu_hdr =(FU_HEADER*)&sendbuf[13]; 817 | //fu_hdr->E=0; 818 | fu_hdr->R=0; 819 | fu_hdr->S=0; 820 | fu_hdr->E=0; 821 | fu_hdr->TYPE=nNaluType; 822 | nalu_payload=&sendbuf[14]; 823 | memcpy(nalu_payload,buffer+t*nalu_sent_len,nalu_sent_len); 824 | bytes=nalu_sent_len+14; 825 | sendto(udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server)); 826 | t++; 827 | } 828 | } 829 | } 830 | 831 | } 832 | 833 | //------------------------------------------------------------ 834 | } 835 | /****************************************************************************** 836 | * funciton : sent H264 stream 837 | ******************************************************************************/ 838 | 839 | HI_S32 SAMPLE_COMM_VENC_Sentjin(VENC_STREAM_S *pstStream) 840 | { 841 | HI_S32 i,flag=0; 842 | 843 | for(i=0;iu32PackCount; i++) 855 | { 856 | HI_S32 lens=0,j,lastadd=0,newadd=0,showflap=0; 857 | char sendbuf[320*1024]; 858 | //char tmp[640*1024]; 859 | lens = pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset; 860 | memcpy(&sendbuf[0],pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,lens); 861 | //printf("lens = %fkB\n",lens/1024.0); 862 | VENC_Sent(sendbuf,lens); 863 | 864 | lens = 0; 865 | } 866 | 867 | 868 | } 869 | /* 870 | if(flag) 871 | { 872 | //printf("a"); 873 | for (i = 0; i < pstStream->u32PackCount; i++) 874 | { 875 | VENC_Sent(pstStream->pstPack[i].pu8Addr[0],pstStream->pstPack[i].u32Len[0]); 876 | if (pstStream->pstPack[i].u32Len[1] > 0) 877 | { 878 | VENC_Sent(pstStream->pstPack[i].pu8Addr[1],pstStream->pstPack[i].u32Len[1]); 879 | } 880 | } 881 | } 882 | */ 883 | /* 884 | if(flag) 885 | { 886 | //printf("a"); 887 | for (i = 0; i < pstStream->u32PackCount; i++) 888 | { 889 | HI_S32 lens=0; 890 | char sendbuf[64*1024]; 891 | char *tmp; 892 | lens = pstStream->pstPack[i].u32Len[0]; 893 | memcpy(&sendbuf[0],pstStream->pstPack[i].pu8Addr[0],lens); 894 | 895 | if (pstStream->pstPack[i].u32Len[1] > 0) 896 | { 897 | memcpy(&sendbuf[lens],pstStream->pstPack[i].pu8Addr[1],lens+pstStream->pstPack[i].u32Len[1]); 898 | } 899 | VENC_Sent(sendbuf,lens); 900 | lens = 0; 901 | } 902 | } 903 | */ 904 | 905 | return HI_SUCCESS; 906 | } 907 | int count=0; 908 | HI_S32 saveStream(VENC_STREAM_S *pstStream) 909 | { 910 | HI_S32 i,j,lens=0; 911 | 912 | for(j=0;ju32PackCount; i++) 917 | { 918 | RTPbuf_s *p = (RTPbuf_s *)malloc(sizeof(RTPbuf_s)); 919 | INIT_LIST_HEAD(&(p->list)); 920 | 921 | lens = pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset; 922 | p->buf = (char *)malloc(lens); 923 | p->len = lens; 924 | memcpy(p->buf,pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,lens); 925 | 926 | list_add_tail(&(p->list),&RTPbuf_head); 927 | //count++; 928 | //printf("count = %d\n",count); 929 | } 930 | } 931 | } 932 | 933 | return HI_SUCCESS; 934 | } 935 | 936 | 937 | void RtspServer_init(void) 938 | { 939 | int i; 940 | pthread_t threadId = 0; 941 | 942 | memset(&g_rtp_playload,0,sizeof(g_rtp_playload)); 943 | strcpy(&g_rtp_playload,"G726-32"); 944 | g_audio_rate = 8000; 945 | pthread_mutex_init(&g_sendmutex,NULL); 946 | pthread_mutex_init(&g_mutex,NULL); 947 | pthread_cond_init(&g_cond,NULL); 948 | memset(&g_rtspClients,0,sizeof(RTSP_CLIENT)*MAX_RTSP_CLIENT); 949 | 950 | //pthread_create(&g_SendDataThreadId, NULL, SendDataThread, NULL); 951 | 952 | struct sched_param thdsched; 953 | thdsched.sched_priority = 2; 954 | //to listen visiting 955 | pthread_create(&threadId, NULL, RtspServerListen, NULL); 956 | //pthread_setschedparam(threadId,SCHED_RR,&thdsched); 957 | printf("RTSP:-----Init Rtsp server\n"); 958 | 959 | pthread_create(&gs_RtpPid, 0, vdRTPSendThread, NULL); 960 | 961 | //exitok++; 962 | 963 | } 964 | void RtspServer_exit(void) 965 | { 966 | return; 967 | } 968 | 969 | HI_VOID* vdRTPSendThread(HI_VOID *p) 970 | { 971 | while(1) 972 | { 973 | if(!list_empty(&RTPbuf_head)) 974 | { 975 | 976 | RTPbuf_s *p = get_first_item(&RTPbuf_head,RTPbuf_s,list); 977 | VENC_Sent(p->buf,p->len); 978 | list_del(&(p->list)); 979 | free(p->buf); 980 | free(p); 981 | p = NULL; 982 | //count--; 983 | //printf("count = %d\n",count); 984 | 985 | } 986 | usleep(5000); 987 | } 988 | } 989 | 990 | int loop() 991 | { 992 | while(1) 993 | { 994 | usleep(1000); 995 | if(exitok>0)exitok++; 996 | if(exitok>10)exit(0); 997 | } 998 | return 1; 999 | 1000 | 1001 | } 1002 | /***************************************************************** 1003 | Function: è??úμ?oˉêy 1004 | Description: ó?ó?3ìDòè??úμ? 1005 | Input: argc, 2?êy??êy 1006 | argv, 2?êy×?·???????êy×é 1007 | Return: 2ù×÷3é1?£??ò·μ??0£??T?ò·μ??<0 1008 | 1009 | ******************************************************************/ 1010 | 1011 | #ifdef __cplusplus 1012 | #if __cplusplus 1013 | } 1014 | #endif 1015 | #endif /* End of #ifdef __cplusplus */ 1016 | 1017 | -------------------------------------------------------------------------------- /Server/src/sensor/ps3210k_api.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "hp_common.h" 19 | #include "ps3210k_api.h" 20 | #include "public_api.h" 21 | 22 | 23 | 24 | static int PS3210k_init(void); 25 | static int PS3210k_exit(void); 26 | static void *PS3210k_auto_adjust(void *p); 27 | static void PS3210k_config(void); 28 | static int PS3210k_GetDenoiseLevel(int intTimes, float gainTimes); 29 | static void PS3210k_SetExposure(int level); 30 | static void PS3210k_SetGamma(int level); 31 | static void PS3210k_SetCCM(int level); 32 | static void PS3210k_SetSharpen(int level); 33 | static void PS3210k_SetNRDenoise(int level); 34 | static void PS3210k_SetNR3D(int level); 35 | static void PS3210k_SetUVNR(int level); 36 | static void PS3210k_SetDRC(int level); 37 | static void PS3210k_SetDCI(int level); 38 | static void PS3210k_SetCrosstalk(int level); 39 | static void PS3210k_SetSaturation(int level); 40 | static void PS3210k_SetDefog(int level); 41 | 42 | 43 | static int PS3210k_ircut_switch(int mode); 44 | static int PS3210k_get_infraredTypeOrYAVG(IRCUT_SWITCH_MODE IRCut_switch_mode); 45 | 46 | 47 | 48 | static pthread_t po1210k_autoAdjust_threadID = -1; 49 | 50 | const public_sensor_interface_st PS3210k_sensor = 51 | { 52 | .sensor_init = &PS3210k_init, 53 | .sensor_exit = &PS3210k_exit, 54 | .sensor_ircut_witch = &PS3210k_ircut_switch, 55 | .sensor_get_infraredTypeOrYAVG = &PS3210k_get_infraredTypeOrYAVG, 56 | }; 57 | 58 | 59 | /*== Gamma start ==*/ 60 | const HI_U16 GammaAttr[][GAMMA_NODE_NUM]= 61 | { 62 | /* day */ 63 | {0x0 , 0x41 , 0x82 , 0xC5 , 0x109, 0x14C, 0x190, 0x1D4, 0x217, 0x25A, 0x29B, 0x2DB, 0x31A, 0x356, 0x390, 0x3C8, 64 | 0x3FD, 0x42F, 0x460, 0x48E, 0x4BB, 0x4E6, 0x50F, 0x537, 0x55D, 0x583, 0x5A7, 0x5CA, 0x5EC, 0x60E, 0x62F, 0x64F, 65 | 0x66F, 0x68E, 0x6AC, 0x6C8, 0x6E4, 0x6FE, 0x717, 0x730, 0x748, 0x75F, 0x775, 0x78C, 0x7A1, 0x7B7, 0x7CC, 0x7E1, 66 | 0x7F6, 0x80B, 0x81F, 0x833, 0x846, 0x859, 0x86C, 0x87E, 0x88F, 0x8A1, 0x8B2, 0x8C2, 0x8D3, 0x8E3, 0x8F3, 0x903, 67 | 0x913, 0x923, 0x932, 0x940, 0x94F, 0x95D, 0x96B, 0x979, 0x986, 0x994, 0x9A1, 0x9AE, 0x9BA, 0x9C7, 0x9D4, 0x9E0, 68 | 0x9ED, 0x9F9, 0xA06, 0xA12, 0xA1E, 0xA2A, 0xA35, 0xA41, 0xA4C, 0xA58, 0xA63, 0xA6E, 0xA79, 0xA84, 0xA90, 0xA9B, 69 | 0xAA6, 0xAB1, 0xABC, 0xAC8, 0xAD3, 0xADE, 0xAE9, 0xAF4, 0xAFF, 0xB0A, 0xB15, 0xB20, 0xB2B, 0xB35, 0xB40, 0xB4B, 70 | 0xB55, 0xB5F, 0xB6A, 0xB74, 0xB7E, 0xB89, 0xB93, 0xB9D, 0xBA7, 0xBB1, 0xBBB, 0xBC4, 0xBCE, 0xBD8, 0xBE1, 0xBEB, 71 | 0xBF4, 0xBFD, 0xC06, 0xC0F, 0xC18, 0xC21, 0xC29, 0xC32, 0xC3A, 0xC43, 0xC4B, 0xC54, 0xC5C, 0xC65, 0xC6E, 0xC76, 72 | 0xC7F, 0xC88, 0xC91, 0xC9A, 0xCA3, 0xCAC, 0xCB5, 0xCBE, 0xCC7, 0xCD0, 0xCD9, 0xCE2, 0xCEB, 0xCF4, 0xCFD, 0xD06, 73 | 0xD0F, 0xD18, 0xD21, 0xD2A, 0xD33, 0xD3D, 0xD46, 0xD4F, 0xD58, 0xD61, 0xD6A, 0xD73, 0xD7C, 0xD85, 0xD8E, 0xD96, 74 | 0xD9F, 0xDA7, 0xDB0, 0xDB8, 0xDC0, 0xDC8, 0xDD0, 0xDD8, 0xDE0, 0xDE8, 0xDF0, 0xDF8, 0xE00, 0xE08, 0xE10, 0xE18, 75 | 0xE20, 0xE28, 0xE30, 0xE38, 0xE41, 0xE49, 0xE51, 0xE59, 0xE61, 0xE69, 0xE72, 0xE7A, 0xE82, 0xE8A, 0xE92, 0xE9A, 76 | 0xEA2, 0xEAA, 0xEB2, 0xEBA, 0xEC2, 0xEC9, 0xED1, 0xED9, 0xEE1, 0xEE8, 0xEF0, 0xEF8, 0xEFF, 0xF07, 0xF0F, 0xF16, 77 | 0xF1E, 0xF26, 0xF2D, 0xF35, 0xF3C, 0xF44, 0xF4C, 0xF53, 0xF5B, 0xF62, 0xF6A, 0xF71, 0xF78, 0xF80, 0xF87, 0xF8E, 78 | 0xF95, 0xF9C, 0xFA3, 0xFAA, 0xFB0, 0xFB7, 0xFBE, 0xFC4, 0xFCB, 0xFD1, 0xFD8, 0xFDE, 0xFE5, 0xFEB, 0xFF2, 0xFF8, 79 | 0xFFF, }, 80 | 81 | /*night*/ 82 | {0x0 , 0x36 , 0x6A , 0x9E , 0xD1 , 0x103, 0x134, 0x164, 0x193, 0x1C2, 0x1EF, 0x21C, 0x248, 0x274, 0x29E, 0x2C9, 83 | 0x2F2, 0x31B, 0x343, 0x36A, 0x391, 0x3B7, 0x3DD, 0x402, 0x426, 0x44A, 0x46D, 0x490, 0x4B3, 0x4D4, 0x4F6, 0x517, 84 | 0x537, 0x557, 0x576, 0x595, 0x5B4, 0x5D2, 0x5F0, 0x60D, 0x62A, 0x647, 0x663, 0x67F, 0x69A, 0x6B5, 0x6D0, 0x6EA, 85 | 0x704, 0x71E, 0x738, 0x751, 0x769, 0x782, 0x79A, 0x7B2, 0x7C9, 0x7E1, 0x7F8, 0x80E, 0x825, 0x83B, 0x851, 0x866, 86 | 0x87C, 0x891, 0x8A6, 0x8BB, 0x8CF, 0x8E3, 0x8F7, 0x90B, 0x91F, 0x932, 0x945, 0x958, 0x96B, 0x97D, 0x98F, 0x9A1, 87 | 0x9B3, 0x9C5, 0x9D7, 0x9E8, 0x9F9, 0xA0A, 0xA1B, 0xA2B, 0xA3C, 0xA4C, 0xA5C, 0xA6C, 0xA7C, 0xA8C, 0xA9B, 0xAAB, 88 | 0xABA, 0xAC9, 0xAD8, 0xAE6, 0xAF5, 0xB03, 0xB12, 0xB20, 0xB2E, 0xB3C, 0xB4A, 0xB57, 0xB65, 0xB72, 0xB80, 0xB8D, 89 | 0xB9A, 0xBA7, 0xBB4, 0xBC0, 0xBCD, 0xBD9, 0xBE6, 0xBF2, 0xBFE, 0xC0A, 0xC16, 0xC22, 0xC2E, 0xC39, 0xC45, 0xC50, 90 | 0xC5C, 0xC67, 0xC72, 0xC7D, 0xC88, 0xC93, 0xC9E, 0xCA8, 0xCB3, 0xCBE, 0xCC8, 0xCD2, 0xCDD, 0xCE7, 0xCF1, 0xCFB, 91 | 0xD05, 0xD0F, 0xD18, 0xD22, 0xD2C, 0xD35, 0xD3F, 0xD48, 0xD52, 0xD5B, 0xD64, 0xD6D, 0xD76, 0xD7F, 0xD88, 0xD91, 92 | 0xD9A, 0xDA2, 0xDAB, 0xDB4, 0xDBC, 0xDC5, 0xDCD, 0xDD5, 0xDDE, 0xDE6, 0xDEE, 0xDF6, 0xDFE, 0xE06, 0xE0E, 0xE16, 93 | 0xE1E, 0xE25, 0xE2D, 0xE35, 0xE3C, 0xE44, 0xE4C, 0xE53, 0xE5A, 0xE62, 0xE69, 0xE70, 0xE77, 0xE7F, 0xE86, 0xE8D, 94 | 0xE94, 0xE9B, 0xEA2, 0xEA8, 0xEAF, 0xEB6, 0xEBD, 0xEC3, 0xECA, 0xED1, 0xED7, 0xEDE, 0xEE4, 0xEEB, 0xEF1, 0xEF7, 95 | 0xEFE, 0xF04, 0xF0A, 0xF10, 0xF17, 0xF1D, 0xF23, 0xF29, 0xF2F, 0xF35, 0xF3B, 0xF41, 0xF46, 0xF4C, 0xF52, 0xF58, 96 | 0xF5D, 0xF63, 0xF69, 0xF6E, 0xF74, 0xF7A, 0xF7F, 0xF85, 0xF8A, 0xF8F, 0xF95, 0xF9A, 0xF9F, 0xFA5, 0xFAA, 0xFAF, 97 | 0xFB4, 0xFBA, 0xFBF, 0xFC4, 0xFC9, 0xFCE, 0xFD3, 0xFD8, 0xFDD, 0xFE2, 0xFE7, 0xFEC, 0xFF1, 0xFF5, 0xFFA, 0xFFF, 98 | 0xFFF, }, 99 | }; 100 | /*== Gamma end ==*/ 101 | 102 | 103 | /*== ExposureAttr start ==*/ 104 | const HI_U16 AEAttr[][2]= 105 | { 106 | /*Compensation EVBias*/ 107 | {62, 1024,}, 108 | {63, 1024,}, 109 | {64, 1024,}, 110 | }; 111 | /*== ExposureAttr end ==*/ 112 | 113 | /*== CCM start ==*/ 114 | const HI_U16 au16CCM[][3][9] = 115 | { 116 | { 117 | { 118 | 0x230, 0x8135, 0x8015, 119 | 0x8075, 0x265, 0x80a0, 120 | 0x8025, 0x8100, 0x230 121 | }, 122 | { 123 | 0x260, 0x8070, 0x8100, 124 | 0x80a2, 0x255, 0x8070, 125 | 0x8050, 0x81b0, 0x300 126 | }, 127 | { 128 | 0x280, 0x8020, 0x8130, 129 | 0x80a5, 0x240, 0x8030, 130 | 0x8075, 0x81b0, 0x320 131 | } 132 | },//gain:0-7 133 | 134 | { 135 | { 136 | 0x230, 0x8140, 0x8010, 137 | 0x8065, 0x290, 0x8030, 138 | 0x8025, 0x8110, 0x240 139 | }, 140 | { 141 | 0x260, 0x8070, 0x8100, 142 | 0x80a2, 0x255, 0x8070, 143 | 0x8050, 0x81b0, 0x300 144 | }, 145 | { 146 | 0x280, 0x8020, 0x8130, 147 | 0x80a5, 0x240, 0x8030, 148 | 0x8075, 0x81b0, 0x320 149 | } 150 | },//gain:7-20 151 | 152 | { 153 | { 154 | 155 | 0x1ff, 0x0, 0x0, 156 | 0x0, 0x1ff, 0x0, 157 | 0x0, 0x0, 0x1ff 158 | }, 159 | { 160 | 0x1ff, 0x0, 0x0, 161 | 0x0, 0x1ff, 0x0, 162 | 0x0, 0x0, 0x1ff 163 | }, 164 | { 165 | 0x1ff, 0x0, 0x0, 166 | 0x0, 0x1ff, 0x0, 167 | 0x0, 0x0, 0x1ff 168 | } 169 | },//gain:20-32 170 | 171 | }; 172 | 173 | /*== CCM end ==*/ 174 | 175 | /*== NR/3DNR start ==*/ 176 | const VPSS_NR_PARAM_U NrParam_3Ddenoise[]= 177 | { 178 | {15, 115,64, 12, 0,0, 30,22,20, 32,40,16,1}, //gain:0-7 179 | {10, 123,64, 12, 0,0, 30,20,16, 64,80,32,1},//gain:7-20 180 | {10, 130,64, 11, 0,0, 30,19,12, 64,80,32,1},//gain:20-32 181 | }; 182 | 183 | const HI_U8 au8VarStrength[][16] = 184 | { 185 | /*1 2 4 8 16 32 64 128*/ 186 | {160, 160, 180, 180, 180, 180, 180, 180, 150, 150,150,150,150,150,150,150,150}, 187 | 188 | }; 189 | 190 | const HI_U8 au8FixStrength[][16] = 191 | { 192 | /*1 2 4 8 16 32 64 128*/ 193 | {0, 0, 0, 0, 0, 0, 0, 0, 110, 110,110,110,110,110,110,110}, 194 | 195 | }; 196 | 197 | const HI_U8 au8LowFreqSlope[][16] = 198 | { 199 | /*1 2 4 8 16 32 64 128*/ 200 | {0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6}, 201 | 202 | }; 203 | 204 | const HI_U16 au16Threshold[][16] = 205 | { 206 | /*1 2 4 8 16 32 64 128*/ 207 | {1500,1500,2800,2800,2800,2800,2800,2800,1375,1375,1375,1375,1375,1375,1375,1375}, 208 | }; 209 | /*== NR/3DNR end ==*/ 210 | 211 | 212 | 213 | /*== Sharpen start ==*/ 214 | const HI_U8 au8SharpenD[][16] = 215 | { 216 | /*1 2 4 8 16 32 64 128*/ 217 | {150, 145, 139, 133, 110, 100, 100, 60, 60,60,60,60,60,60,60,60}, 218 | }; 219 | 220 | const HI_U8 au8SharpenUd[][16] = 221 | { 222 | /*1 2 4 8 16 32 64 128*/ 223 | {115, 112, 98, 95, 90, 80, 80, 80, 70,70,70,70,70,70,70,70}, 224 | }; 225 | 226 | HI_U8 au8OverShoot[][16] = 227 | { 228 | /*1 2 4 8 16 32 64 128*/ 229 | {70, 68, 64, 50, 48, 32, 36, 40, 40,40,40,40,40,40,40,40}, 230 | }; 231 | 232 | const HI_U8 au8UnderShoot[][16] = 233 | { 234 | /*1 2 4 8 16 32 64 128*/ 235 | {107, 100, 91, 64, 55, 40, 47, 54, 80,80,80,80,80,80,80,80}, 236 | }; 237 | 238 | const HI_U8 au8TextureNoiseThd[][16] = 239 | { 240 | /*1 2 4 8 16 32 64 128*/ 241 | {0, 0, 0, 0, 0, 1, 1, 1, 1,1,1,1,1,1,1,1}, 242 | }; 243 | 244 | const HI_U8 au8EdgeNoiseThd[][16] = 245 | { 246 | /*1 2 4 8 16 32 64 128*/ 247 | {0, 0, 0, 0, 0, 1, 1, 1, 1,1,1,1,1,1,1,1}, 248 | }; 249 | 250 | const HI_BOOL abEnLowLumaShoot[][16] = 251 | { 252 | /*1 2 4 8 16 32 64 128*/ 253 | {0, 0, 0, 0, 0, 1, 1, 1, 1,1,1,1,1,1,1,1}, 254 | }; 255 | /*== Sharpen end ==*/ 256 | 257 | /*== UVNR start ==*/ 258 | const HI_U8 au8ColorCast[][16] = 259 | { 260 | /*1 2 4 8 16 32 64 128*/ 261 | {0, 0, 2, 3, 3, 3, 3, 3, 1,1,1,1,1,1,1,1}, 262 | }; 263 | 264 | const HI_U8 au8UvnrThreshold[][16] = 265 | { 266 | /*1 2 4 8 16 32 64 128*/ 267 | {20, 20, 20, 20, 20, 20, 20, 20, 1,1,1,1,1,1,1,1}, 268 | }; 269 | 270 | const HI_U8 au8UvnrStrength[][16] = 271 | { 272 | /*1 2 4 8 16 32 64 128*/ 273 | {34, 34, 34, 34, 34, 34, 34, 34, 1,1,1,1,1,1,1,1}, 274 | }; 275 | /*== UVNR end ==*/ 276 | 277 | /*== DRC start==*/ 278 | const ISP_DRC_ATTR_S stDRC[]= 279 | { /* 280 | HI_BOOL bEnable; 281 | 282 | HI_U8 u8SpatialVar; 283 | HI_U8 u8RangeVar; 284 | 285 | HI_U8 u8Asymmetry; 286 | HI_U8 u8SecondPole; 287 | HI_U8 u8Stretch; 288 | HI_U8 u8LocalMixingThres; 289 | 290 | HI_U16 u16DarkGainLmtY; 291 | HI_U16 u16DarkGainLmtC; 292 | HI_U16 u16BrightGainLmt; 293 | 294 | ISP_OP_TYPE_E enOpType; 295 | ISP_DRC_MANUAL_ATTR_S stManual; 296 | ISP_DRC_AUTO_ATTR_S stAuto; 297 | */ 298 | {1, 10,0, 2,192,60,2, 0,48,0, OP_TYPE_MANUAL, {40,0,32}, {128,54,32},}, 299 | {1, 10,0, 2,192,60,2, 0,48,0, OP_TYPE_MANUAL, {20,0,32}, {128,54,32},}, 300 | {0, 10,0, 2,192,60,2, 0,48,0, OP_TYPE_MANUAL, {20,0,32}, {128,54,32},}, 301 | }; 302 | /*== DRC end==*/ 303 | 304 | /*== DCI start==*/ 305 | const VI_DCI_PARAM_S stDciParam[]= 306 | { 307 | {1, 40,45,0 }, 308 | {1, 50,55,40}, 309 | {1, 63,63,63}, 310 | }; 311 | /*== DCI end==*/ 312 | 313 | /*== Crosstalk Removal start==*/ 314 | const ISP_CR_ATTR_S stCRAttr[]= 315 | { 316 | {1,{1024,1024,1024,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048},8192,7,7,8192}, 317 | }; 318 | /*== Crosstalk Removal end==*/ 319 | 320 | /*== Saturation start ==*/ 321 | const HI_U8 au8Saturation[][16] = 322 | { 323 | /*1 2 4 8 16 32 64 128*/ 324 | {135, 128, 120, 110, 100, 78, 70, 60,56,56,56,56,56,56,56,56}, 325 | {135, 135, 120, 120, 113, 90, 90, 60,56,56,56,56,56,56,56,56}, 326 | {200, 200, 200, 200, 200, 180, 180, 180,56,56,56,56,56,56,56,56}, 327 | }; 328 | /*== Saturation end ==*/ 329 | 330 | /*== Defog start ==*/ 331 | ISP_DEFOG_ATTR_S stDefogAttr[]= 332 | { 333 | {1, 16,15,OP_TYPE_MANUAL, {100},{128}}, 334 | {0, 16,15,OP_TYPE_MANUAL, {100},{128}}, 335 | }; 336 | /*== Defog end ==*/ 337 | 338 | int PS3210k_init(void) 339 | { 340 | pthread_create(&po1210k_autoAdjust_threadID, NULL, PS3210k_auto_adjust, NULL); 341 | return 0; 342 | } 343 | int PS3210k_exit(void) 344 | { 345 | //pthread_cancel(po1210k_autoAdjust_threadID); 346 | //pthread_jion(); 347 | return 0; 348 | } 349 | 350 | void PS3210k_config(void) 351 | { 352 | ISP_DEV IspDev = 0; 353 | /*== ExposureAttr ==*/ 354 | ISP_EXPOSURE_ATTR_S stExpAttr; 355 | HI_MPI_ISP_GetExposureAttr(IspDev, &stExpAttr); 356 | stExpAttr.stAuto.stExpTimeRange.u32Max = 70000; 357 | stExpAttr.stAuto.stAGainRange.u32Max = 16384; 358 | stExpAttr.stAuto.stDGainRange.u32Max = 1024; 359 | stExpAttr.stAuto.stISPDGainRange.u32Max = 2048; 360 | stExpAttr.stAuto.enAEMode = AE_MODE_SLOW_SHUTTER; 361 | HI_MPI_ISP_SetExposureAttr(IspDev,&stExpAttr); 362 | 363 | /*== Demosaic ==*/ 364 | ISP_DEMOSAIC_ATTR_S stDemosaicAttr; 365 | //HI_MPI_ISP_GetDemosaicAttr(IspDev, &stDemosaicAttr); 366 | //HI_MPI_ISP_SetDemosaicAttr(IspDev, &stDemosaicAttr); 367 | 368 | PS3210k_SetExposure(0); 369 | PS3210k_SetGamma(0); 370 | PS3210k_SetCCM(0); 371 | PS3210k_SetSaturation(0); 372 | PS3210k_SetSharpen(0); 373 | PS3210k_SetNRDenoise(0); 374 | PS3210k_SetNR3D(0); 375 | PS3210k_SetUVNR(0); 376 | PS3210k_SetDRC(0); 377 | PS3210k_SetDCI(0); 378 | PS3210k_SetCrosstalk(0); 379 | 380 | } 381 | 382 | void *PS3210k_auto_adjust(void *p) 383 | { 384 | ISP_EXP_INFO_S stExpInfo; 385 | ISP_DEV IspDev = 0; 386 | float GainTimes; 387 | int IntTimeLines; 388 | int level = 0; 389 | int prelevel = -1; 390 | 391 | usleep(1000000); //wait sensor init ,vi ,vpss, venc start 392 | 393 | PS3210k_config(); 394 | 395 | /**** auto denoise ***/ 396 | while(1) 397 | { 398 | HI_MPI_ISP_QueryExposureInfo(IspDev, &stExpInfo); 399 | GainTimes = (stExpInfo.u32AGain * stExpInfo.u32ISPDGain) / (1024.0 * 1024.0); 400 | IntTimeLines = stExpInfo.u32ExpTime / 29.63; //25fps, the time of 1 line is 29.63us 401 | 402 | level = PS3210k_GetDenoiseLevel(IntTimeLines,GainTimes); 403 | 404 | if(prelevel != level) 405 | { 406 | printf("level = %d\n",level); 407 | HI_MPI_ISP_SetFMWState(IspDev,ISP_FMW_STATE_FREEZE); 408 | PS3210k_SetExposure(level); 409 | PS3210k_SetNR3D(level); 410 | PS3210k_SetGamma(level); 411 | PS3210k_SetCCM(level); 412 | PS3210k_SetDCI(level); 413 | PS3210k_SetDRC(level); 414 | PS3210k_SetSaturation(level); 415 | HI_MPI_ISP_SetFMWState(IspDev,ISP_FMW_STATE_RUN); 416 | 417 | } 418 | prelevel = level; 419 | 420 | /*only use for Defog*/ 421 | if(IntTimeLines < 100) 422 | { 423 | PS3210k_SetDefog(0); 424 | } 425 | else 426 | { 427 | PS3210k_SetDefog(1); 428 | } 429 | /*only use for Defog*/ 430 | 431 | usleep(30000); 432 | } 433 | 434 | return NULL; 435 | } 436 | int PS3210k_GetDenoiseLevel(int intTimes, float gainTimes) 437 | { 438 | int level_t; 439 | if(gainTimes < 7.0) 440 | { 441 | level_t = 0; 442 | } 443 | else if(gainTimes < 20.0) 444 | { 445 | level_t = 1; 446 | } 447 | else 448 | { 449 | level_t = 2; 450 | } 451 | 452 | return level_t; 453 | } 454 | 455 | 456 | /*== Gamma ==*/ 457 | void PS3210k_SetGamma(int level) 458 | { 459 | ISP_DEV IspDev = 0; 460 | ISP_GAMMA_ATTR_S stGammaAttr; 461 | level = level / 2; 462 | HI_MPI_ISP_GetGammaAttr(IspDev, &stGammaAttr); 463 | stGammaAttr.enCurveType = ISP_GAMMA_CURVE_USER_DEFINE; 464 | memcpy(stGammaAttr.u16Table,&GammaAttr[level],sizeof(stGammaAttr.u16Table)); 465 | HI_MPI_ISP_SetGammaAttr(IspDev, &stGammaAttr); 466 | } 467 | 468 | /*== CCM ==*/ 469 | void PS3210k_SetCCM(int level) 470 | { 471 | ISP_DEV IspDev = 0; 472 | ISP_COLORMATRIX_ATTR_S stCCMAttr; 473 | HI_MPI_ISP_GetCCMAttr(IspDev, &stCCMAttr); 474 | memcpy(stCCMAttr.stAuto.au16HighCCM,&au16CCM[level][0],sizeof(stCCMAttr.stAuto.au16HighCCM)); 475 | memcpy(stCCMAttr.stAuto.au16MidCCM,&au16CCM[level][1],sizeof(stCCMAttr.stAuto.au16MidCCM)); 476 | memcpy(stCCMAttr.stAuto.au16LowCCM,&au16CCM[level][2],sizeof(stCCMAttr.stAuto.au16LowCCM)); 477 | HI_MPI_ISP_SetCCMAttr(IspDev, &stCCMAttr); 478 | } 479 | 480 | 481 | /*== ExposureAttr ==*/ 482 | void PS3210k_SetExposure(int level) 483 | { 484 | ISP_DEV IspDev = 0; 485 | ISP_EXPOSURE_ATTR_S stExpAttr; 486 | HI_MPI_ISP_GetExposureAttr(IspDev, &stExpAttr); 487 | stExpAttr.stAuto.u8Compensation = AEAttr[level][0]; 488 | stExpAttr.stAuto.u16EVBias = AEAttr[level][1]; 489 | HI_MPI_ISP_SetExposureAttr(IspDev,&stExpAttr); 490 | } 491 | 492 | /*== Sharpen ==*/ 493 | void PS3210k_SetSharpen(int level) 494 | { 495 | ISP_DEV IspDev = 0; 496 | ISP_SHARPEN_ATTR_S stSharpenAttr; 497 | HI_MPI_ISP_GetSharpenAttr(IspDev, &stSharpenAttr); 498 | memcpy(stSharpenAttr.stAuto.au8SharpenD, &au8SharpenD[level], sizeof(stSharpenAttr.stAuto.au8SharpenD)); 499 | memcpy(stSharpenAttr.stAuto.au8SharpenUd, &au8SharpenUd[level], sizeof(stSharpenAttr.stAuto.au8SharpenUd)); 500 | memcpy(stSharpenAttr.stAuto.au8OverShoot, &au8OverShoot[level], sizeof(stSharpenAttr.stAuto.au8OverShoot)); 501 | memcpy(stSharpenAttr.stAuto.au8UnderShoot, &au8UnderShoot[level], sizeof(stSharpenAttr.stAuto.au8UnderShoot)); 502 | memcpy(stSharpenAttr.stAuto.au8TextureNoiseThd, &au8TextureNoiseThd[level], sizeof(stSharpenAttr.stAuto.au8TextureNoiseThd)); 503 | memcpy(stSharpenAttr.stAuto.au8EdgeNoiseThd, &au8EdgeNoiseThd[level], sizeof(stSharpenAttr.stAuto.au8EdgeNoiseThd)); 504 | memcpy(stSharpenAttr.stAuto.abEnLowLumaShoot, &abEnLowLumaShoot[level], sizeof(stSharpenAttr.stAuto.abEnLowLumaShoot)); 505 | HI_MPI_ISP_SetSharpenAttr(IspDev, &stSharpenAttr); 506 | } 507 | 508 | /*== NR/3DNR==*/ 509 | void PS3210k_SetNRDenoise(int level) 510 | { 511 | ISP_DEV IspDev = 0; 512 | ISP_NR_ATTR_S stNRAttr; 513 | HI_MPI_ISP_GetNRAttr(IspDev,&stNRAttr); 514 | memcpy(stNRAttr.stAuto.au8VarStrength, &au8VarStrength[level], sizeof(stNRAttr.stAuto.au8VarStrength)); 515 | memcpy(stNRAttr.stAuto.au8FixStrength, &au8FixStrength[level], sizeof(stNRAttr.stAuto.au8FixStrength)); 516 | memcpy(stNRAttr.stAuto.au8LowFreqSlope, &au8LowFreqSlope[level], sizeof(stNRAttr.stAuto.au8LowFreqSlope)); 517 | memcpy(stNRAttr.stAuto.au16Threshold, &au16Threshold[level], sizeof(stNRAttr.stAuto.au16Threshold)); 518 | HI_MPI_ISP_SetNRAttr(IspDev,&stNRAttr); 519 | } 520 | 521 | void PS3210k_SetNR3D(int level) 522 | { 523 | VPSS_GRP VpssGrp =0; 524 | HI_MPI_VPSS_SetNRParam(VpssGrp, &NrParam_3Ddenoise[level]); 525 | } 526 | 527 | /*== UVNR ==*/ 528 | void PS3210k_SetUVNR(int level) 529 | { 530 | ISP_DEV IspDev = 0; 531 | ISP_UVNR_ATTR_S stUvnrAttr; 532 | HI_MPI_ISP_GetUVNRAttr(IspDev,&stUvnrAttr); 533 | memcpy(stUvnrAttr.stAuto.au8ColorCast, &au8ColorCast[level], sizeof(stUvnrAttr.stAuto.au8ColorCast)); 534 | memcpy(stUvnrAttr.stAuto.au8UvnrThreshold, &au8UvnrThreshold[level], sizeof(stUvnrAttr.stAuto.au8UvnrThreshold)); 535 | memcpy(stUvnrAttr.stAuto.au8UvnrStrength, &au8UvnrStrength[level], sizeof(stUvnrAttr.stAuto.au8UvnrStrength)); 536 | HI_MPI_ISP_SetUVNRAttr(IspDev,&stUvnrAttr); 537 | } 538 | 539 | /*== DRC ==*/ 540 | void PS3210k_SetDRC(int level) 541 | { 542 | ISP_DEV IspDev = 0; 543 | HI_MPI_ISP_SetDRCAttr(IspDev,&stDRC[level]); 544 | } 545 | 546 | /*== DCI ==*/ 547 | void PS3210k_SetDCI(int level) 548 | { 549 | VI_DEV ViDev = 0; 550 | HI_MPI_VI_SetDCIParam(ViDev, &stDciParam[level]); 551 | } 552 | 553 | /*== Crosstalk Removal ==*/ 554 | void PS3210k_SetCrosstalk(int level) 555 | { 556 | ISP_DEV IspDev = 0; 557 | HI_MPI_ISP_SetCrosstalkAttr(IspDev,&stCRAttr[level]); 558 | } 559 | 560 | /*== Saturation ==*/ 561 | void PS3210k_SetSaturation(int level) 562 | { 563 | ISP_DEV IspDev = 0; 564 | ISP_SATURATION_ATTR_S stSatAttr; 565 | HI_MPI_ISP_GetSaturationAttr(IspDev, &stSatAttr); 566 | memcpy(stSatAttr.stAuto.au8Sat, &au8Saturation[level], sizeof(stSatAttr.stAuto.au8Sat)); 567 | HI_MPI_ISP_SetSaturationAttr(IspDev, &stSatAttr); 568 | } 569 | 570 | /*== Defog ==*/ 571 | void PS3210k_SetDefog(int level) 572 | { 573 | ISP_DEV IspDev = 0; 574 | HI_MPI_ISP_SetDeFogAttr(IspDev, &stDefogAttr[level]); 575 | } 576 | 577 | /* IR CUT*/ 578 | int PS3210k_ircut_switch(int mode) 579 | { 580 | int var; 581 | SysRegWrite(0x200F0100, 0x1);//GPIO8_0 582 | SysRegWrite(0x200F0104, 0x1);//GPIO8_1 583 | SysRegRead(0x201C0400, &var); 584 | var = var | 0x03; 585 | SysRegWrite(0x201C0400, var); 586 | if(IRCUT_NIGHT == mode) 587 | { 588 | SysRegWrite(0x201C000C ,0x01); 589 | } 590 | else 591 | { 592 | SysRegWrite(0x201C000C ,0x02); 593 | } 594 | usleep(120000); 595 | SysRegWrite(0x201C000C,0x00); 596 | return 0; 597 | } 598 | int PS3210k_get_infraredTypeOrYAVG(IRCUT_SWITCH_MODE IRCut_switch_mode) 599 | { 600 | unsigned int data = 0; 601 | if( IRCUT_SYN_INFRARED == IRCut_switch_mode) 602 | { 603 | SysRegWrite(0x200F00FC,0x01);//gpio7_7 604 | SysRegRead(0x201B0400, &data); 605 | data &= (~(1 << 7)); 606 | SysRegWrite(0x201B0400, data); 607 | 608 | data = 0; 609 | SysRegRead(0x201B0200,&data); 610 | data = ((0 != data) ? 0 : 1); 611 | } 612 | else 613 | { 614 | data = 0xFFFF; 615 | } 616 | return data; 617 | } 618 | 619 | -------------------------------------------------------------------------------- /Server/src/sensor/ps3210k_api.h: -------------------------------------------------------------------------------- 1 | #ifndef __PS3210_API_H__ 2 | #define __PS3210_API_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "public_api.h" 9 | 10 | extern const public_sensor_interface_st PS3210k_sensor; 11 | 12 | 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif 19 | 20 | 21 | -------------------------------------------------------------------------------- /Server/src/sensor/public_api.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "hp_common.h" 17 | #include "ps3210k_api.h" 18 | #include "public_api.h" 19 | 20 | static pthread_t public_monitor_threadID = -1; 21 | public_sensor_interface_st * public_sensor_interface = NULL; 22 | 23 | static IRCUT_SWITCH_DIRECTION ircutDirectioin = NORMAL_DIRECTION; 24 | static IRCUT_MODE ircutMode = IRCUT_DAY; 25 | static IRCUT_SWITCH_MODE ircut_switch_mode = IRCUT_SYN_INFRARED; 26 | static CAMERA_SCENE public_camera_scene = SCENE_DAY; 27 | 28 | #define CHECK_INTERFACE(interface)\ 29 | do{\ 30 | if(interface == NULL)\ 31 | {\ 32 | printf("not register sensor %s\n",#interface);\ 33 | exit(1);\ 34 | }\ 35 | }while(0); 36 | 37 | #define REGISTER_SENSOR(interface) \ 38 | do{\ 39 | public_sensor_interface = &(interface);\ 40 | }while(0); 41 | 42 | static void * pubic_monitor(void *p); 43 | 44 | 45 | 46 | 47 | 48 | int public_init(void) 49 | { 50 | ircutDirectioin = NORMAL_DIRECTION; 51 | ircutMode = IRCUT_DAY; 52 | ircut_switch_mode = IRCUT_SYN_INFRARED; 53 | public_camera_scene = SCENE_DAY; 54 | REGISTER_SENSOR(PS3210k_sensor); 55 | pthread_create(&public_monitor_threadID, NULL, pubic_monitor, NULL); 56 | return 0; 57 | } 58 | int public_exit(void) 59 | { 60 | CHECK_INTERFACE(public_sensor_interface->sensor_exit); 61 | public_sensor_interface->sensor_exit(); 62 | return 0; 63 | } 64 | void * pubic_monitor(void *p) 65 | { 66 | CHECK_INTERFACE(public_sensor_interface->sensor_init); 67 | public_sensor_interface->sensor_init(); 68 | public_ircut_init(); 69 | 70 | while(1) 71 | { 72 | 73 | usleep(200000); 74 | public_auto_scene_control(); 75 | 76 | 77 | } 78 | 79 | } 80 | int public_scene_switch(CAMERA_SCENE scene_t) 81 | { 82 | ISP_DEV IspDev = 0; 83 | ISP_SATURATION_ATTR_S stSatAttr; 84 | if(SCENE_DAY == scene_t) 85 | { 86 | public_ircut_switch(IRCUT_DAY); 87 | HI_MPI_ISP_GetSaturationAttr(IspDev, &stSatAttr); 88 | stSatAttr.enOpType = OP_TYPE_AUTO; 89 | stSatAttr.stManual.u8Saturation = 0; 90 | HI_MPI_ISP_SetSaturationAttr(IspDev, &stSatAttr); 91 | } 92 | else if(SCENE_NIGHT == scene_t) 93 | { 94 | public_ircut_switch(IRCUT_NIGHT); 95 | HI_MPI_ISP_GetSaturationAttr(IspDev, &stSatAttr); 96 | stSatAttr.enOpType = OP_TYPE_MANUAL; 97 | stSatAttr.stManual.u8Saturation = 0; 98 | HI_MPI_ISP_SetSaturationAttr(IspDev, &stSatAttr); 99 | } 100 | return 0; 101 | } 102 | 103 | CAMERA_SCENE public_get_scene(IRCUT_SWITCH_MODE ircut_sw_m) 104 | { 105 | CAMERA_SCENE camera_scene = SCENE_DAY; 106 | int val_t = 0; 107 | CHECK_INTERFACE(public_sensor_interface->sensor_get_infraredTypeOrYAVG); 108 | val_t = public_sensor_interface->sensor_get_infraredTypeOrYAVG(ircut_sw_m); 109 | if( IRCUT_SYN_INFRARED == ircut_sw_m) 110 | { 111 | camera_scene = (val_t == 0) ? SCENE_DAY : SCENE_NIGHT; 112 | } 113 | else if(IRCUT_SWITCH_AUTO == ircut_sw_m) 114 | { 115 | camera_scene = SCENE_DAY; 116 | } 117 | return camera_scene; 118 | } 119 | int public_auto_scene_control(void) 120 | { 121 | CAMERA_SCENE scene_t; 122 | static int ircut_day_time = 0; 123 | static int ircut_night_time = 0; 124 | scene_t = public_get_scene(ircut_switch_mode); 125 | if((SCENE_DAY == scene_t) && (SCENE_DAY != public_camera_scene)) 126 | { 127 | ircut_day_time++; 128 | if(5 <= ircut_day_time) 129 | { 130 | ircut_day_time = 0; 131 | public_camera_scene = SCENE_DAY; 132 | public_scene_switch(public_camera_scene); 133 | 134 | 135 | } 136 | ircut_night_time = 0; 137 | } 138 | else if((SCENE_NIGHT == scene_t) && (SCENE_NIGHT != public_camera_scene)) 139 | { 140 | 141 | ircut_night_time++; 142 | if(5 <= ircut_night_time) 143 | { 144 | ircut_night_time = 0; 145 | public_camera_scene = SCENE_NIGHT; 146 | public_scene_switch(public_camera_scene); 147 | } 148 | ircut_day_time = 0; 149 | } 150 | else 151 | { 152 | ircut_day_time = 0; 153 | ircut_night_time = 0; 154 | } 155 | return 0; 156 | } 157 | 158 | int public_ircut_init(void) 159 | { 160 | public_ircut_switch(IRCUT_NIGHT); 161 | sleep(1); 162 | public_ircut_switch(IRCUT_DAY); 163 | return 0; 164 | } 165 | 166 | int public_ircut_switch(int mode) 167 | { 168 | CHECK_INTERFACE(public_sensor_interface->sensor_ircut_witch); 169 | if(NORMAL_DIRECTION == ircutDirectioin) 170 | { 171 | ircutMode = mode; 172 | } 173 | else 174 | { 175 | ircutMode = !mode; 176 | } 177 | public_sensor_interface->sensor_ircut_witch(ircutMode); 178 | return 0; 179 | } 180 | --------------------------------------------------------------------------------