Andorid7.1 系统接口H264数据回调,并且支持修改分辨率,帧率等信息

前言

     公司是做车机的,车机行业会有一些特殊需求,需要做实时视频上传,这时候应用就需要将预览的YUV数据转换成h264数据再上传,但是公司要求将该工作交给系统处理,应用接收h264数据,然后上传就行,该h264数据支持分辨率,I帧间隔,码率,帧率等修改。这时候就需要去看系统源码,然后添加新的api给应用。

实现

   1.修改内容如下:

   

zhoujy@TP:~/data/android/sc826_cn_01_00/msm_8953_git$ git status
On branch sc826_cn_01_00
Your branch is up-to-date with 'origin/sc826_cn_01_00'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   frameworks/base/api/current.txt
        modified:   frameworks/base/api/system-current.txt
        modified:   frameworks/base/api/test-current.txt
        modified:   frameworks/base/core/java/android/hardware/Camera.java
        modified:   frameworks/base/core/jni/Android.mk
        modified:   frameworks/base/core/jni/android_hardware_Camera.cpp

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        frameworks/base/core/java/android/hardware/H264Encoder.java
        frameworks/base/core/jni/android/graphics/YuvConvert.cpp
        frameworks/base/core/jni/android/graphics/YuvConvert.h

no changes added to commit (use "git add" and/or "git commit -a")
zhoujy@TP:~/data/android/sc826_cn_01_00/msm_8953_git$ 

2.具体代码修改

houjy@TP:~/data/android/sc826_cn_01_00/msm_8953_git$ git diff
diff --git a/frameworks/base/api/current.txt b/frameworks/base/api/current.txt
index a6b8a07..e3c6714 100644
--- a/frameworks/base/api/current.txt
+++ b/frameworks/base/api/current.txt
@@ -13312,6 +13312,8 @@ package android.hardware {
     method public final void setDisplayOrientation(int);
     method public final void setErrorCallback(android.hardware.Camera.ErrorCallback);
     method public final void setFaceDetectionListener(android.hardware.Camera.FaceDetectionListener);
+    method public final void setH264Callback(android.hardware.Camera.H264Callback);
+    method public final void setH264Paremeters(int, int, int, int, int);
     method public final void setOneShotPreviewCallback(android.hardware.Camera.PreviewCallback);
     method public void setParameters(android.hardware.Camera.Parameters);
     method public final void setPreviewCallback(android.hardware.Camera.PreviewCallback);
@@ -13376,6 +13378,10 @@ package android.hardware {
     method public abstract void onFaceDetection(android.hardware.Camera.Face[], android.hardware.Camera);
   }
 
+  public static abstract deprecated interface Camera.H264Callback {
+    method public abstract void onH264Frame(byte[], android.hardware.Camera);
+  }
+
   public static abstract deprecated interface Camera.OnZoomChangeListener {
     method public abstract void onZoomChange(int, boolean, android.hardware.Camera);
   }
diff --git a/frameworks/base/api/system-current.txt b/frameworks/base/api/system-current.txt
index dfb8aa7..0c2d0c1 100644
--- a/frameworks/base/api/system-current.txt
+++ b/frameworks/base/api/system-current.txt
@@ -13760,6 +13760,8 @@ package android.hardware {
     method public final void setDisplayOrientation(int);
     method public final void setErrorCallback(android.hardware.Camera.ErrorCallback);
     method public final void setFaceDetectionListener(android.hardware.Camera.FaceDetectionListener);
+    method public final void setH264Callback(android.hardware.Camera.H264Callback);
+    method public final void setH264Paremeters(int, int, int, int, int);
     method public final void setOneShotPreviewCallback(android.hardware.Camera.PreviewCallback);
     method public void setParameters(android.hardware.Camera.Parameters);
     method public final void setPreviewCallback(android.hardware.Camera.PreviewCallback);
@@ -13824,6 +13826,10 @@ package android.hardware {
     method public abstract void onFaceDetection(android.hardware.Camera.Face[], android.hardware.Camera);
   }
 
+  public static abstract deprecated interface Camera.H264Callback {
+    method public abstract void onH264Frame(byte[], android.hardware.Camera);
+  }
+
   public static abstract deprecated interface Camera.OnZoomChangeListener {
     method public abstract void onZoomChange(int, boolean, android.hardware.Camera);
   }
diff --git a/frameworks/base/api/test-current.txt b/frameworks/base/api/test-current.txt
index cd134ba..1a97754 100644
--- a/frameworks/base/api/test-current.txt
+++ b/frameworks/base/api/test-current.txt
@@ -13330,6 +13330,8 @@ package android.hardware {
     method public final void setDisplayOrientation(int);
     method public final void setErrorCallback(android.hardware.Camera.ErrorCallback);
     method public final void setFaceDetectionListener(android.hardware.Camera.FaceDetectionListener);
+    method public final void setH264Callback(android.hardware.Camera.H264Callback);
+    method public final void setH264Paremeters(int, int, int, int, int);
     method public final void setOneShotPreviewCallback(android.hardware.Camera.PreviewCallback);
     method public void setParameters(android.hardware.Camera.Parameters);
     method public final void setPreviewCallback(android.hardware.Camera.PreviewCallback);
@@ -13394,6 +13396,10 @@ package android.hardware {
     method public abstract void onFaceDetection(android.hardware.Camera.Face[], android.hardware.Camera);
   }
 
+  public static abstract deprecated interface Camera.H264Callback {
+    method public abstract void onH264Frame(byte[], android.hardware.Camera);
+  }
+
   public static abstract deprecated interface Camera.OnZoomChangeListener {
     method public abstract void onZoomChange(int, boolean, android.hardware.Camera);
   }
diff --git a/frameworks/base/core/java/android/hardware/Camera.java b/frameworks/base/core/java/android/hardware/Camera.java
index 3df0c49..20abf48 100755
--- a/frameworks/base/core/java/android/hardware/Camera.java
+++ b/frameworks/base/core/java/android/hardware/Camera.java
@@ -51,6 +51,8 @@ import java.util.LinkedHashMap;
 import java.util.List;
 
 import static android.system.OsConstants.*;
+import android.hardware.H264Encoder.IH264EncoderListener;
+
 
 /**
  * The Camera class is used to set image capture settings, start/stop preview,
@@ -169,6 +171,7 @@ public class Camera {
     private PictureCallback mRawImageCallback;
     private PictureCallback mJpegCallback;
     private PreviewCallback mPreviewCallback;
+       private H264Callback mH264Callback;
     private boolean mUsingPreviewAllocation;
     private PictureCallback mPostviewCallback;
     private AutoFocusCallback mAutoFocusCallback;
@@ -179,6 +182,13 @@ public class Camera {
     private boolean mOneShot;
     private boolean mWithBuffer;
     private boolean mFaceDetectionRunning = false;
+       private boolean isH264 = false;
+       private boolean isPreviewCallBack = false;
+       private H264Encoder mH264Encoder = null;
+       private int mPreviewWidth = 1280;
+       private int mPreviewHeight = 720;
+       private int scaleWidth = 1280;
+       private int scaleHeight = 720;
     private final Object mAutoFocusCallbackLock = new Object();
 
     private static final int NO_ERROR = 0;
@@ -548,7 +558,10 @@ public class Camera {
         mRawImageCallback = null;
         mJpegCallback = null;
         mPreviewCallback = null;
+               mH264Callback = null;
         mPostviewCallback = null;
+               isH264 = false;
+               isPreviewCallBack = false;
         mUsingPreviewAllocation = false;
         mZoomListener = null;
         /* ### QC ADD-ONS: START */
@@ -652,6 +665,9 @@ public class Camera {
 
     private native final void native_release();
 
+    private native static void yuvCompress(byte[] nv21Src, int width, int height, byte[] i420Dst, int dst_width, int dst_height, int mode);
+    private native static void yuvI420ToNV21(byte[] i420Src, int width, int height, byte[] nv21Dst);    
+
 
     /**
      * Disconnects and releases the Camera object resources.
@@ -827,6 +843,38 @@ public class Camera {
         void onPreviewFrame(byte[] data, Camera camera);
     };
 
+       /**
+     * Callback interface used to deliver copies of preview frames as
+     * they are displayed.
+     *
+     * @see #setH264Callback(Camera.H264Callback)
+     *
+     * @deprecated We recommend using the new {@link android.hardware.camera2} API for new
+     *             applications.
+     */
+
+    public interface H264Callback
+    {
+        /**
+         * Called as preview frames are displayed.  This callback is invoked
+         * on the event thread {@link #open(int)} was called from.
+         *
+         * <p>If using the {@link android.graphics.ImageFormat#YV12} format,
+         * refer to the equations in {@link Camera.Parameters#setPreviewFormat}
+         * for the arrangement of the pixel data in the preview callback
+         * buffers.
+         *
+         * @param data the contents of the preview frame in the format defined
+         *  by {@link android.graphics.ImageFormat}, which can be queried
+         *  with {@link android.hardware.Camera.Parameters#getPreviewFormat()}.
+         *  If {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}
+         *             is never called, the default will be the YCbCr_420_SP
+         *             (NV21) format.
+         * @param camera the Camera service object.
+         */
+        void onH264Frame(byte[] data, Camera camera);
+    };
+
     /**
      * Starts capturing and drawing preview frames to the screen.
      * Preview will not actually start until a surface is supplied
@@ -848,7 +896,10 @@ public class Camera {
     public final void stopPreview() {
         _stopPreview();
         mFaceDetectionRunning = false;
-
+               if(mH264Encoder != null) {
+                       mH264Encoder.stopEncoder();
+                       mH264Encoder = null;
+               }
         mShutterCallback = null;
         mRawImageCallback = null;
         mPostviewCallback = null;
@@ -857,6 +908,8 @@ public class Camera {
             mAutoFocusCallback = null;
         }
         mAutoFocusMoveCallback = null;
+               
+               
     }
 
     private native final void _stopPreview();
@@ -886,6 +939,11 @@ public class Camera {
      */
     public final void setPreviewCallback(PreviewCallback cb) {
         android.util.SeempLog.record(66);
+               if(cb != null) {
+                       isPreviewCallBack = true;
+               } else {
+                       isPreviewCallBack = false;
+               }
         mPreviewCallback = cb;
         mOneShot = false;
         mWithBuffer = false;
@@ -897,6 +955,47 @@ public class Camera {
         setHasPreviewCallback(cb != null, false);
     }
 
+       IH264EncoderListener mEncoderListener = new IH264EncoderListener() {
+
+        @Override
+        public void onH264(byte[] data, Camera camera) {
+            //Log.d(TAG,"onH264 data:"+data);
+                       if(mH264Callback != null) {
+                               mH264Callback.onH264Frame(data, camera);
+                       }
+                       
+        }
+    };
+       public final void setH264Paremeters(int viewWidth, int viewHeight, int mFrameRate, int mBitRate, int iFrame) {
+               if(mH264Encoder == null) {
+                       mH264Encoder = new H264Encoder(viewWidth, viewHeight, mFrameRate, mBitRate, iFrame, mEncoderListener);
+                       mH264Encoder.startEncoder();
+                       scaleWidth = viewWidth;
+                       scaleHeight = viewHeight;
+               }
+       }
+       public final void setH264Callback(H264Callback cb) {
+               if(cb != null){
+                       isH264 = true;
+               } else {
+                       isH264 = false;
+                       if(mH264Encoder != null) {
+                               mH264Encoder.stopEncoder();
+                               mH264Encoder = null;
+                       }
+               }
+        android.util.SeempLog.record(66);
+        mH264Callback= cb;
+        mOneShot = false;
+        mWithBuffer = false;
+        if (cb != null) {
+            mUsingPreviewAllocation = false;
+        }
+        // Always use one-shot mode. We fake camera preview mode by
+        // doing one-shot preview continuously.
+        setHasPreviewCallback(cb != null, false);
+    }
+
     /**
      * <p>Installs a callback to be invoked for the next preview frame in
      * addition to displaying it on the screen.  After one invocation, the
@@ -914,12 +1013,17 @@ public class Camera {
     public final void setOneShotPreviewCallback(PreviewCallback cb) {
         android.util.SeempLog.record(68);
         mPreviewCallback = cb;
+               if(cb != null) {
+                       isPreviewCallBack = true;
+               } else {
+                       isPreviewCallBack = false;
+               }
         mOneShot = true;
         mWithBuffer = false;
         if (cb != null) {
             mUsingPreviewAllocation = false;
         }
-        setHasPreviewCallback(cb != null, false);
+         setHasPreviewCallback(cb != null, false);
     }
 
     private native final void setHasPreviewCallback(boolean installed, boolean manualBuffer);
@@ -953,6 +1057,11 @@ public class Camera {
     public final void setPreviewCallbackWithBuffer(PreviewCallback cb) {
         android.util.SeempLog.record(67);
         mPreviewCallback = cb;
+               if(cb != null) {
+                       isPreviewCallBack = true;
+               } else {
+                       isPreviewCallBack = false;
+               }
         mOneShot = false;
         mWithBuffer = true;
         if (cb != null) {
@@ -1216,21 +1325,87 @@ public class Camera {
                 return;
 
             case CAMERA_MSG_PREVIEW_FRAME:
-                PreviewCallback pCb = mPreviewCallback;
-                if (pCb != null) {
-                    if (mOneShot) {
-                        // Clear the callback variable before the callback
-                        // in case the app calls setPreviewCallback from
-                        // the callback function
-                        mPreviewCallback = null;
-                    } else if (!mWithBuffer) {
-                        // We're faking the camera preview mode to prevent
-                        // the app from being flooded with preview frames.
-                        // Set to oneshot mode again.
-                        setHasPreviewCallback(true, false);
-                    }
-                    pCb.onPreviewFrame((byte[])msg.obj, mCamera);
-                }
+                               //Log.i(TAG,"zjy ===CAMERA_MSG_PREVIEW_FRAME isH264:"+isH264+",isPreviewCallBack:"+isPreviewCallBack);
+                               if(isH264 && isPreviewCallBack) {
+                                       //Log.i(TAG,"zjy ===CAMERA_MSG_PREVIEW_FRAME mPreviewCallback:"+mPreviewCallback+",mH264Callback:"+mH264Callback);
+                                       PreviewCallback pCb = mPreviewCallback;
+                       if (pCb != null) {
+                       if (mOneShot) {
+                               // Clear the callback variable before the callback
+                               // in case the app calls setPreviewCallback from
+                               // the callback function
+                               mPreviewCallback = null;
+                       } else if (!mWithBuffer) {
+                               // We're faking the camera preview mode to prevent
+                               // the app from being flooded with preview frames.
+                               // Set to oneshot mode again.
+                               setHasPreviewCallback(true, false);
+                       }
+                       pCb.onPreviewFrame((byte[])msg.obj, mCamera);
+                                               //Log.i(TAG,"zjy ===CAMERA_MSG_PREVIEW_FRAME onPreviewFrame");
+                       }
+                                       
+                                       H264Callback hCb = mH264Callback;
+                                       if (hCb != null) {
+                                               /**byte[] i420bytes = new byte[((byte[])msg.obj).length];
+                               //from YV20 to i420
+                               System.arraycopy((byte[])msg.obj, 0, i420bytes, 0, mPreviewWidth * mPreviewHeight);
+                               System.arraycopy((byte[])msg.obj, mPreviewWidth * mPreviewHeight + mPreviewWidth * mPreviewHeight / 4, i420bytes, mPreviewWidth * mPreviewHeight, mPreviewWidth * mPreviewHeight / 4);
+                               System.arraycopy((byte[])msg.obj, mPreviewWidth * mPreviewHeight, i420bytes, mPreviewWidth * mPreviewHeight + mPreviewWidth * mPreviewHeight / 4, mPreviewWidth * mPreviewHeight / 4);*/
+                               if(mH264Encoder != null) {
+                                                       final byte[] dstData = new byte[scaleWidth * scaleHeight * 3 / 2];
+                                                       Parameters p = getParameters();
+                                               Size previewSize = p.getPreviewSize();
+                                                       yuvCompress((byte[])msg.obj, previewSize.width, previewSize.height, dstData, scaleWidth, scaleHei
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值