高通安卓Android 下camera nv12格式编码h264测试例程

/*

 
最简单的基于X264的视频编码器

  Simplest X264 Encoder

 
jiangyu

  

 
本程序可以YUV格式的像素数据编码为H.264码流,是最简单的

  基于libx264的视频编码器

 


  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"

 

if defined ( __cplusplus)

extern "C"

{

include "x264.h"

};

else

include "x264.h"

endif

 

int width=1280;

int height=960;

int csp=X264_CSP_NV12;

 // nv12 转 yuv 并写入本地

 #if 0

void nv12toYuv(uint8_t NV12, uint8_t I420,size_t pixelWidth,size_t pixelHeight,const char resultCString,const char resultCString2){

    unsigned char ybuf = (unsigned char )malloc(pixelHeight pixelWidth);

    unsigned char
ubuf = (unsigned char )malloc((pixelHeight/2) (pixelWidth/2));

    unsigned char vbuf = (unsigned char )malloc((pixelHeight/2) (pixelWidth/2));

    unsigned char
y = ybuf;

    unsigned char u = ubuf;

    unsigned char
v = vbuf;

    int len = (int)pixelHeight pixelWidth + pixelHeight pixelWidth / 2;

    FILE fpyuv = fopen(resultCString, "wb");

    for (int i = 0; i < len; i ++) {

        if (i < (pixelWidth
pixelHeight)) {  //yyyyy

            y = NV12;

            y++;

        }

        else{//uvuvuv

            if (i % 2 == 0) {//uuuuu

                u = NV12;

                u ++;

            }else{//vvvvv

                v = NV12;

                v ++;

            }

        }

        NV12 ++;

    }

    fwrite(ybuf, 1, pixelWidthpixelHeight, fpyuv);

    fwrite(ubuf, 1, pixelWidth
pixelHeight/4, fpyuv);

    fwrite(vbuf, 1, pixelWidth*pixelHeight/4, fpyuv);

    fclose(fpyuv);

    free(ybuf);

    free(ubuf);

    free(vbuf);

}

endif

int main(int argc, char* argv)

{

 

         int ret;

         int y_size;

         int i,j;

         unsigned char tmpbufu[307200];

unsigned char tmpbufv[307200];

         FILE
fp_src  = fopen("./1280x960.yuv", "rb");

         FILE fp_dst = fopen("output.h264", "wb");

        

         //Encode frame number

         //if set 0, encode all frame

         int frame_num=0;

         

         int iNal   = 0;

         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));

        

         //Check

         if(fp_src==NULL||fp_dst==NULL){

                   printf("Error open files.\n");

                   return -1;

         }

 

         x264_param_default(pParam);   //给参数结构体赋默认值

         x264_param_default_preset(pParam, "fast" , "zerolatency" );  //设置preset和tune

 

         //修改部分参数

         pParam->i_csp=csp;

         pParam->i_width   = width;   // 宽度

         pParam->i_height  = height;  // 高度

         pParam->i_fps_num  = 25;     // 设置帧率(分子)

         pParam->i_fps_den  = 1;      // 设置帧率时间1s(分母)

         

         pParam->i_threads  = X264_SYNC_LOOKAHEAD_AUTO;

         pParam->i_keyint_max = 10;              //在此间隔设置IDR关键帧

 

         pParam->rc.i_bitrate = 1200;       // 设置码率,在ABR(平均码率)模式下才生效,且必须在设置ABR前先设置bitrate

         pParam->rc.i_rc_method = X264_RC_ABR;  // 码率控制方法,CQP(恒定质量),CRF(恒定码率,缺省值23),ABR(平均码率)

         

         /


         //Param

         pParam->i_log_level  = X264_LOG_DEBUG;

         pParam->i_frame_total = 0;

         pParam->i_bframe  = 5;

         pParam->b_open_gop  = 0;

         pParam->i_bframe_pyramid = 0;

         pParam->rc.i_qp_constant=0;

         pParam->rc.i_qp_max=0;

         pParam->rc.i_qp_min=0;

         pParam->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;

         pParam->i_timebase_den = pParam->i_fps_num;

         pParam->i_timebase_num = pParam->i_fps_den;

         /

 

         //set profile

         x264_param_apply_profile(pParam, "baseline");

         

         //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 = X264_CSP_NV12;

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);

 

         ret = x264_encoder_headers(pHandle, &pNals, &iNal);

 

         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_size3);break;

                   case X264_CSP_I422:frame_num=ftell(fp_src)/(y_size
2);break;

                   case X264_CSP_I420:frame_num=ftell(fp_src)/(y_size3/2);break;

   case X264_CSP_NV12:frame_num=ftell(fp_src)/(y_size
3/2);break;

                   default:printf("Colorspace Not Support.\n");return -1;

                   }

                   fseek(fp_src,0,SEEK_SET);

         }

        

         //Loop to Encode

         for( i=0;i<frame_num;i++){

                   switch(csp){

                   case X264_CSP_I420:{

                            fread(pPic_in->img.plane[0],y_size,1,fp_src);         //Y

                            fread(pPic_in->img.plane[1],y_size/4,1,fp_src);       //U

                            fread(pPic_in->img.plane[2],y_size/4,1,fp_src);       //V

                            break;}

case X264_CSP_NV12:

         printf("nv12 enc y\n");

fread(pPic_in->img.plane[0],y_size,1,fp_src);         //Y

fread(pPic_in->img.plane[1],y_size/2,1,fp_src);      //uv

printf("nv12 enc uv end\n");

break;



                   default:{

                            printf("Colorspace Not Support.\n");

                            return -1;}

                   }

                   pPic_in->i_pts = i;

 

                   ret = x264_encoder_encode(pHandle, &pNals, &iNal, pPic_in, pPic_out);

                   if (ret< 0){

                            printf("Error.\n");

                            return -1;

                   }

 

                   printf("Succeed encode frame: %5d\n",i);

 

                   for ( j = 0; j < iNal; ++j){

                             fwrite(pNals[j].p_payload, 1, pNals[j].i_payload, fp_dst);

                   }

         }

         i=0;

         //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++;

         }
/

         x264_picture_clean(pPic_in);

         x264_encoder_close(pHandle);

         pHandle = NULL;

 

         free(pPic_in);

         free(pPic_out);

         free(pParam);

 

         fclose(fp_src);

         fclose(fp_dst);

 

         return 0;

}

##### Make sure all is the first target.
all:

CXX ?= g++
CC  ?= gcc

CFLAGS  += -g -pthread -Wall 
CFLAGS  += -rdynamic -funwind-tables
CFLAGS  += -I./include  
CFLAGS  +=  -I${SDKTARGETSYSROOT}/usr/include/linux-headers/usr/include 
CFLAGS += -D__unused="__attribute__((__unused__))"

#LDFLAGS += -L./usr/lib/gpac
LDFLAGS += -lx264 -ldl
LDFLAGS += -L./lib/

C_SRC=
C_SRC+=src/main.c
CXX_SRC=
OBJ=
DEP=
#LDFLAGS+= -lcamera
OBJ_CAM_SRV = src/main.o
TARGETS    += x264-test
$(TARGETS): $(OBJ_CAM_SRV)
TARGET_OBJ += $(OBJ_CAM_SRV)

FILE_LIST := files.txt
COUNT := ./make/count.sh
MK := $(word 1,$(MAKEFILE_LIST))
ME := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))

OBJ=$(CXX_SRC:.cpp=.o) $(C_SRC:.c=.o)
DEP=$(OBJ:.o=.d) $(TARGET_OBJ:.o=.d)

CXXFLAGS += -std=c++11 $(CFLAGS)
#include ./common.mk
.PHONY: all clean distclean

all: $(TARGETS)

clean:
rm -f $(TARGETS) $(FILE_LIST)
find . -name "*.o" -delete
find . -name "*.d" -delete

distclean:
rm -f $(TARGETS) $(FILE_LIST)
find . -name "*.o" -delete
find . -name "*.d" -delete

-include $(DEP)

%.o: %.c $(MK) $(ME)
@[ -f $(COUNT) ] && $(COUNT) $(FILE_LIST) $^ || true
@$(CC) -c $< -MM -MT $@ -MF $(@:.o=.d) $(CFLAGS) $(LIBQCAM_CFLAGS)
$(CC) -c $< $(CFLAGS) -o $@ $(LIBQCAM_CFLAGS)

%.o: %.cpp $(MK) $(ME)
@[ -f $(COUNT) ] && $(COUNT) $(FILE_LIST) $^ || true
@$(CXX) -c $< -MM -MT $@ -MF $(@:.o=.d) $(CXXFLAGS)
$(CXX) -c $< $(CXXFLAGS) -o $@

$(TARGETS): $(OBJ)
$(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS)
@[ -f $(COUNT) -a -n "$(FILES)" ] && $(COUNT) $(FILE_LIST) $(FILES) || true
@[ -f $(COUNT) ] && $(COUNT) $(FILE_LIST) || true



安卓下执行 ./x264-test

sitemap