x264编码h264数据NV21

/**
 *
 * 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;
}

最新评论

  1. 发布于:2020-06-07 21:41 回复
    此代码不再有屏下方显示马赛克的问题了

sitemap