机器人车技术开发分享网
x264编码h264数据NV21
  • 首页 > 视频图像处理
  • 作者:小v
  • 2020年2月28日 9:01 星期五
  • 浏览:373
  • 字号:
  • 评论:1
  • /**
     *
     * This software encode YUV data to H.264 bitstream.
     * It's the simplest encoder example based on libx264.
     */
    #include <stdio.h>
    #include <stdlib.h>
     
    #include "stdint.h"
     #include <cutils/properties.h>
    
    // System dependencies
    #include <dlfcn.h>//#include <dlfcn.h> dlopen dlsym
    #include <errno.h>
    #include <fcntl.h>
    #include <linux/msm_ion.h>
    
    #include <linux/mman.h>
    // Camera dependencies
    #include "mm_qcamera_dbg.h"
    #include "mm_qcamera_app.h"
    
    
    #include "x264.h"
    
    #include "socket_h264.h"
    
    
     
    int width=  640 ;//1280;
    int height=480;//  960;
    int csp=X264_CSP_NV12;//和高通的摄像头进行对应
    x264_nal_t* pNals = NULL;
    x264_t* pHandle   = NULL;
    x264_picture_t* pPic_in ;//= (x264_picture_t*)malloc(sizeof(x264_picture_t));
    x264_picture_t* pPic_out;// = (x264_picture_t*)malloc(sizeof(x264_picture_t));
    x264_param_t* pParam ;//= (x264_param_t*)malloc(sizeof(x264_param_t));
    FILE* fp_dst;
    struct message_header{		
    	int type;		
    	int size;	
    };
    
     char *new_pack_data ;
     struct message_header header_send;
     int x264_init()
     {
    
    		pPic_in = (x264_picture_t*)malloc(sizeof(x264_picture_t));
    		pPic_out = (x264_picture_t*)malloc(sizeof(x264_picture_t));
    		pParam = (x264_param_t*)malloc(sizeof(x264_param_t));
    		x264_param_default(pParam);   
    		x264_param_default_preset(pParam, "ultrafast" , "zerolatency" );  
    
    		pParam->i_csp=csp;
    		pParam->i_width   = width;   
    		pParam->i_height  = height; 
    		pParam->i_fps_num  = 25;     
    		pParam->i_fps_den  = 1;     
            #if  1			 
    		pParam->i_keyint_max =10;
    		pParam->i_frame_total =0;
    		pParam->i_bframe =0;//关闭 b帧
    		pParam->b_open_gop =0;
    
    		pParam->b_repeat_headers =1;;//sps pps帧放到前边
    		pParam->rc.i_lookahead = 0;//强制编码不能等40针凑齐编码
    		
    		pParam->i_bframe_pyramid =0;
    		pParam->i_bframe_adaptive =X264_B_ADAPT_TRELLIS;
    		#endif
    		pParam->i_threads  = X264_SYNC_LOOKAHEAD_AUTO;
    
    		pParam->rc.i_bitrate = 1200;       
    		pParam->rc.i_rc_method = X264_RC_ABR; 
    
    		pParam->i_keyint_max = 250 ; //几秒钟刷新一个I帧 
    		pParam->i_keyint_min = 25 ; 
    		pParam->b_intra_refresh  = 1;
    		pParam->b_annexb = 1;
    		//set profile
    		x264_param_apply_profile(pParam, x264_profile_names[0]);
             
             //open encoder
             pHandle = x264_encoder_open(pParam);
               if(csp == X264_CSP_NV12){
    			pPic_in->img.i_stride[0] = pParam->i_width;
    			pPic_in->img.i_stride[1] = pParam->i_width;
    			pPic_in->img.i_stride[2] = 0;
    			pPic_in->img.i_csp = csp;
    			pPic_in->img.i_plane = 2;
    		} else { // 其他暂认为都是YUV420格式
    			 pPic_in->img.i_stride[0] = pParam->i_width;
    			 pPic_in->img.i_stride[1] = pParam->i_width>>1;
    			 pPic_in->img.i_stride[2] = pParam->i_width>>1;
    			 pPic_in->img.i_csp = X264_CSP_I420;
    			 pPic_in->img.i_plane = 3;
        } 
             x264_picture_init(pPic_out);
             x264_picture_alloc(pPic_in, csp, pParam->i_width, pParam->i_height);
    
       new_pack_data = malloc(1280*960);
    	if (new_pack_data == NULL)
    	{
    		printf("malloc new_pack_data error!!!\n");
    	}
         
     }
      int x264_destroy()
      {
    
         x264_picture_clean(pPic_in);
         x264_encoder_close(pHandle);
         pHandle = NULL;
    
         free(pPic_in);
         free(pPic_out);
         free(pParam);
    
         free(new_pack_data);
      //   fclose(fp_dst);
      }
      
    int encode_oneFrame(mm_camera_buf_def_t *frame,
                           char *name,
                           char *ext,
                           uint32_t frame_idx)
    {
     
             int ret;
             int y_size;
             int i,j,k,m;	 
             int frame_num=1; //每次编码一帧
             int iNal   = 0;     
             int offset = 0;     
    	 
             y_size = pParam->i_width * pParam->i_height;
             //detect frame number
         /*    if(frame_num==0){
                       fseek(fp_src,0,SEEK_END);
                       switch(csp){
                       case X264_CSP_I444:frame_num=ftell(fp_src)/(y_size*3);break;
                       case X264_CSP_I422:frame_num=ftell(fp_src)/(y_size*2);break;
                       case X264_CSP_I420:frame_num=ftell(fp_src)/(y_size*3/2);break;
                       default:printf("Colorspace Not Support.\n");return -1;
                       }
                       fseek(fp_src,0,SEEK_SET);
             }
            */
         
        if ( frame != NULL) {
          //  printf("planes count:%d \n",frame->planes_buf.num_planes);//planes count:2 		 	   						        
                       switch(csp){ 
                      case X264_CSP_NV12:
    			          //   printf("nv12 enc y\n");
    				       memcpy(pPic_in->img.plane[0],(uint8_t *)frame->buffer ,y_size);//就  Y 分量						          
    					   memcpy(pPic_in->img.plane[1],(uint8_t *)frame->buffer+y_size  ,y_size/2);
    							
    				//	printf("nv12 enc uv end\n");
    					break;
    				case X264_CSP_I420:
    					 memcpy(pPic_in->img.plane[0],(uint8_t *)frame->buffer ,y_size);//就shi  Y 分量						          
    					memcpy(pPic_in->img.plane[1],(uint8_t *)frame->buffer+y_size  ,y_size/4);
    				 	memcpy(pPic_in->img.plane[2],(uint8_t *)frame->buffer +y_size+y_size/4 ,y_size/4);
    
    					break;
                       default:
                                printf("Colorspace Not Support.\n");
                                return -1;
                       }
    		
                       pPic_in->i_pts ++;//= frame_idx;//
                       
                       ret = x264_encoder_encode(pHandle, &pNals, &iNal, pPic_in, pPic_out);
                       if (ret< 0){
                                printf("Error.\n");
                                return -1;
                       }
    					  long int i_data =0;
    					  for(i = 0;i < iNal; i ++){
                           memcpy(new_pack_data +i_data,pNals[i].p_payload,pNals[i].i_payload);
    							i_data = i_data+pNals[i].i_payload;
    						}
    					 printf("succed encode iNal :%d \n",iNal);
    #if 1
    				
    					
    						header_send.type = 0x5a5a5a5a;
    						header_send.size = i_data;
    
    						ret = send(new_server_socket, &header_send, 8, 0);
    						if (ret < 0)
    						{
    							printf("Socket Send Message  Failed!\n");
    						}
    						//printf("socket send data:%d!!!\n",ret);
    
    						ret = send(new_server_socket, new_pack_data, header_send.size, 0);
    						if ( ret < 0)
    						{
    							printf("Socket Send Data  Failed!\n");
    							
    						}
    						printf("Socket Send Data  over!\n");
    #endif
    
    
           
             //flush encoder
            /* while(1){
                       ret = x264_encoder_encode(pHandle, &pNals, &iNal, NULL, pPic_out);
                       if(ret==0){
                                break;
                       }
                       printf("Flush 1 frame.\n");
                       for (j = 0; j < iNal; ++j){
                                fwrite(pNals[j].p_payload, 1, pNals[j].i_payload, fp_dst);
                       }
                       i++;
             }*/
         }
     
             return 0;
    }
    
    
      您阅读这篇文章共花了:  
    二维码加载中...
    本文作者:小v      文章标题: x264编码h264数据NV21
    本文地址:http://blog.cvosrobot.com/?post=477
    版权声明:若无注明,本文皆为“机器人车技术开发分享网”原创,转载请保留文章出处。

    此代码不再有屏下方显示马赛克的问题了
    返回顶部| 首页| 手气不错| 捐赠支持| 自定义链接| 自定义链接| 自定义链接| 手机版本|后花园

    Copyright © 2014-2017 机器人车技术开发分享网   京ICP备14059411 Copyright 2014-2019 小v工作室 版权所有 All Rights Reserved

    sitemap