/**
*
* 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;
}
最新评论