编码器使用的是x264的开源库,
很容易看懂的
简单的封装了一个JNI库
编码库在BBS里 CSDN的资源太难用了
http://www.eoeandroid.com/forum.php?mod=viewthread&tid=52739&extra=
x264的编译放方法
export ARM_ROOT=$ANDROID_NDK_ROOT
export ARM_INC=$ARM_ROOT/build/platforms/android-5/arch-arm/usr/include/
export ARM_LIB=$ARM_ROOT/build/platforms/android-5/arch-arm/usr/lib/
export ARM_TOOL=$ARM_ROOT/build/prebuilt/windows/arm-eabi-4.4.0
export ARM_LIBO=$ARM_TOOL/lib/gcc/arm-eabi/4.4.0
export PATH=$ARM_TOOL/bin:$PATH
export ARM_PRE=arm-eabi
./configure --prefix=/home/egmkang/libx264 --enable-shared /
-disable-asm --host=arm-linux --cross-prefix=arm-eabi-/
--extra-cflags=" -I$ARM_INC -fPIC -DANDROID -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float
-mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wa,--noexecstack -MMD -MP "/
--extra-ldflags="-nostdlib -Bdynamic -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$ARM_LIB -nostdlib $ARM_LIB/crtbegin_dynamic.o $ARM_LIB/crtend_android.o
-lc -lm -ldl -lgcc"
这里生成的是x264的静态库
整个工程唯一有点麻烦的是 生成 JNI 动态库的时候 报错 。。
后来发现是少链接了一个库,
于是根据x264的编译方法 在Android.mk添加一些配置就可以了。当然这就是难点,在网上查了很多都没有结果。
有些目录的参数自己调整哈
我把前面生成的libx264.a 和 x264.h 文件放到jni的libx264目录下了 有问题自己调整
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES +=$(LOCAL_PATH)/libx264/include
LOCAL_MODULE := H264Android
LOCAL_SRC_FILES := H264Android.c
LOCAL_LDFLAGS += $(LOCAL_PATH)/libx264/lib/libx264.a
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lgcc
include $(BUILD_SHARED_LIBRARY)
估计很多人都会发现很熟悉 嘻嘻 这个就是根据
http://www.cnblogs.com/mcodec/articles/1780598.html
改的 连文件名字都没有换!!比较懒
另: 编码的效率很低下啊
AndroidVideo.java
-
importjava.io.File;
-
importjava.io.RandomAccessFile;
-
importandroid.app.Activity;
-
importandroid.content.Intent;
-
importandroid.os.Bundle;
-
importandroid.view.View;
-
importandroid.content.res.Configuration;
-
importandroid.os.Bundle;
-
importandroid.util.Log;
-
importandroid.view.SurfaceHolder;
-
importandroid.view.SurfaceView;
-
importandroid.view.Window;
-
importandroid.view.WindowManager;
-
importandroid.view.SurfaceHolder.Callback;
-
importandroid.graphics.PixelFormat;
-
importandroid.hardware.Camera;
-
publicclassAndroidVideoextendsActivityimplementsCallback,
-
Camera.PictureCallback{
-
privateSurfaceViewmSurfaceView=null;
-
privateSurfaceHoldermSurfaceHolder=null;
-
privateCameramCamera=null;
-
privatebooleanmPreviewRunning=false;
-
publicvoidonCreate(BundlesavedInstanceState){
-
super.onCreate(savedInstanceState);
-
getWindow().setFormat(PixelFormat.TRANSLUCENT);
-
requestWindowFeature(Window.FEATURE_NO_TITLE);
-
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
-
WindowManager.LayoutParams.FLAG_FULLSCREEN);
-
setContentView(R.layout.camera);
-
mSurfaceView=(SurfaceView)this.findViewById(R.id.surface_camera);
-
mSurfaceHolder=mSurfaceView.getHolder();
-
mSurfaceHolder.addCallback(this);
-
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
-
}
-
-
@Override
-
publicvoidonPictureTaken(byte[]data,Cameracamera){
-
}
-
@Override
-
publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,
-
intheight){
-
if(mPreviewRunning){
-
mCamera.stopPreview();
-
}
-
Camera.Parametersp=mCamera.getParameters();
-
p.setPreviewSize(352,288);
-
mCamera.setPreviewCallback(newH264Encoder(352,288));
-
mCamera.setParameters(p);
-
try{
-
mCamera.setPreviewDisplay(holder);
-
}catch(Exceptionex){
-
}
-
mCamera.startPreview();
-
mPreviewRunning=true;
-
}
-
@Override
-
publicvoidsurfaceCreated(SurfaceHolderholder){
-
mCamera=Camera.open();
-
}
-
@Override
-
publicvoidsurfaceDestroyed(SurfaceHolderholder){
-
if(mCamera!=null){
-
mCamera.setPreviewCallback(null);
-
mCamera.stopPreview();
-
mPreviewRunning=false;
-
mCamera.release();
-
mCamera=null;
-
}
-
}
-
publicvoidonConfigurationChanged(ConfigurationnewConfig){
-
try{
-
super.onConfigurationChanged(newConfig);
-
if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE){
-
}elseif(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT){
-
}
-
}catch(Exceptionex){
-
}
-
}
-
}
-
classH264EncoderimplementsCamera.PreviewCallback{
-
longencoder=0;
-
RandomAccessFileraf=null;
-
byte[]h264Buff=null;
-
static{
-
System.loadLibrary("H264Android");
-
}
-
privateH264Encoder(){};
-
-
publicH264Encoder(intwidth,intheight){
-
encoder=CompressBegin(width,height);
-
h264Buff=newbyte[width*height*8];
-
try{
-
Filefile=newFile("/sdcard/camera.h264");
-
raf=newRandomAccessFile(file,"rw");
-
}catch(Exceptionex){
-
Log.v("System.out",ex.toString());
-
}
-
-
};
-
protectedvoidfinalize()
-
{
-
CompressEnd(encoder);
-
if(null!=raf)
-
{
-
try{
-
raf.close();
-
}catch(Exceptionex){
-
Log.v("System.out",ex.toString());
-
}
-
}
-
try{
-
super.finalize();
-
}catch(Throwablee){
-
-
e.printStackTrace();
-
}
-
}
-
privatenativelongCompressBegin(intwidth,intheight);
-
privatenativeintCompressBuffer(longencoder,inttype,byte[]in,intinsize,byte[]out);
-
privatenativeintCompressEnd(longencoder);
-
@Override
-
publicvoidonPreviewFrame(byte[]data,Cameracamera){
-
-
intresult=CompressBuffer(encoder,-1,data,data.length,h264Buff);
-
try{
-
if(result>0)
-
raf.write(h264Buff,0,result);
-
}catch(Exceptionex){
-
Log.v("System.out",ex.toString());
-
}
-
}
-
-
}
H264Android.c
-
#include<string.h>
-
#include<jni.h>
-
#include<stdio.h>
-
#include<stdlib.h>
-
#include<arpa/inet.h>
-
#include<x264.h>
-
#defineDATA_MAX3000000
-
#defineH264_MTU1024
-
typedefstruct
-
{
-
x264_param_t*param;
-
x264_t*handle;
-
x264_picture_t*picture;
-
x264_nal_t*nal;
-
}Encoder;
-
jlongJava_h264_com_H264Encoder_CompressBegin(JNIEnv*env,jobjectthiz,
-
jintwidth,jintheight){
-
Encoder*en=(Encoder*)malloc(sizeof(Encoder));
-
en->param=(x264_param_t*)malloc(sizeof(x264_param_t));
-
en->picture=(x264_param_t*)malloc(sizeof(x264_picture_t));
-
x264_param_default(en->param);
-
-
en->param->i_log_level=X264_LOG_NONE;
-
en->param->i_width=width;
-
en->param->i_height=height;
-
en->param->rc.i_lookahead=0;
-
en->param->i_bframe=0;
-
en->param->i_fps_num=5;
-
en->param->i_fps_den=1;
-
if((en->handle=x264_encoder_open(en->param))==0){
-
return0;
-
}
-
-
x264_picture_alloc(en->picture,X264_CSP_I420,en->param->i_width,
-
en->param->i_height);
-
return(jlong)en;
-
}
-
jintJava_h264_com_H264Encoder_CompressEnd(JNIEnv*env,jobjectthiz,jlonghandle)
-
{
-
Encoder*en=(Encoder*)handle;
-
if(en->picture)
-
{
-
x264_picture_clean(en->picture);
-
free(en->picture);
-
en->picture=0;
-
}
-
if(en->param)
-
{
-
free(en->param);
-
en->param=0;
-
}
-
if(en->handle)
-
{
-
x264_encoder_close(en->handle);
-
}
-
free(en);
-
return0;
-
}
-
jintJava_h264_com_H264Encoder_CompressBuffer(JNIEnv*env,jobjectthiz,jlonghandle,jinttype,jbyteArrayin,jintinsize,jbyteArrayout)
-
{
-
Encoder*en=(Encoder*)handle;
-
x264_picture_tpic_out;
-
inti_data=0;
-
intnNal=-1;
-
intresult=0;
-
inti=0,j=0;
-
intnPix=0;
-
jbyte*Buf=(jbyte*)(*env)->GetByteArrayElements(env,in,0);
-
jbyte*h264Buf=(jbyte*)(*env)->GetByteArrayElements(env,out,0);
-
unsignedchar*pTmpOut=h264Buf;
-
intnPicSize=en->param->i_width*en->param->i_height;
-
-
-
-
-
-
-
jbyte*y=en->picture->img.plane[0];
-
jbyte*v=en->picture->img.plane[1];
-
jbyte*u=en->picture->img.plane[2];
-
memcpy(en->picture->img.plane[0],Buf,nPicSize);
-
for(i=0;i<nPicSize/4;i++)
-
{
-
*(u+i)=*(Buf+nPicSize+i*2);
-
*(v+i)=*(Buf+nPicSize+i*2+1);
-
}
-
switch(type)
-
{
-
case0:
-
en->picture->i_type=X264_TYPE_P;
-
break;
-
case1:
-
en->picture->i_type=X264_TYPE_IDR;
-
break;
-
case2:
-
en->picture->i_type=X264_TYPE_I;
-
break;
-
default:
-
en->picture->i_type=X264_TYPE_AUTO;
-
break;
-
}
-
if(x264_encoder_encode(en->handle,&(en->nal),&nNal,en->picture,&pic_out)<0)
-
{
-
return-1;
-
}
-
for(i=0;i<nNal;i++){
-
memcpy(pTmpOut,en->nal[i].p_payload,en->nal[i].i_payload);
-
pTmpOut+=en->nal[i].i_payload;
-
result+=en->nal[i].i_payload;
-
}
-
returnresult;
-
}
转自http://blog.chinaunix.net/link.php?url=http://blog.csdn.net%2Fzblue78%2Farchive%2F2010%2F12%2F06%2F6058147.aspx%23
分享到:
相关推荐
热烈庆祝国产编程语言R++1.8研发成功-附件资源
使用Android Studio工具开发 语言为Java语言 主要功能:规章、学习专栏、两优、庆祝百年、改革、标志
庆祝申奥成功一周年.doc
Android-Konfetti.zip,用这种轻质的五彩粒子系统庆祝更多,安卓系统是谷歌在2008年设计和制造的。操作系统主要写在爪哇,C和C 的核心组件。它是在linux内核之上构建的,具有安全性优势。
跨年烟花代码+js+庆祝 一个小小的跨年烟花寄托了我们对新的一年的美好期盼 代码运行非常简单: 只需要在浏览器中打开index.html页面即可
都是给学生定制的都符合学校或者学生考试期末作业的水平,有的有js,有的视频+音乐+flash的等元素的插入。 原生(HTML+CSS+JS),网页作品代码简单,可使用任意HTML编辑软件(如:`Dreamweaver、HBuilder、Vscode 、...
HTML5 Canvas绘制的一款酷炫彩色烟花庆祝动画特效,可以用来做公司成立周年庆放烟花动画效果。
庆祝五一劳动节模板
一个好看的烟花web,圣诞树,真的好用
祝贺高考成功经典贺词
小学主题班会庆祝国庆PPT教案.pptx
庆祝三八妇女节ppt模板
圣诞快乐庆祝圣诞节PPT模板。一套圣诞节主题幻灯片模板,喜庆红色主色调,适合庆祝圣诞节使用。
中国航天梦热烈庆祝神舟12号载人航天飞船发射成功PPT课件(带内容).pptx
js特效-HTML5-庆祝2018年烟花动画特效
这是一个简单漂亮的元旦倒计时小程序。 本项目只需要js文件和html文件即可 运行策略非常简单 1. 下载项目包 fireworks.zip 2. 解压fireworks.zip 3. 在浏览器中打开 index.html 页面 有烟花的效果,有绚丽的文字
纯CSS3+SVG实现的节日庆祝五彩纸屑动画效果源码.zip
这是一份卡通风格的生日主题的PPT动态模板。背景以卡通小动物、生日蛋糕、彩虹、白云等元素为背景,内页用各种可爱的小图标装饰,适合给孩子庆祝生日使用。