Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
han1202012 committed Jun 16, 2020
1 parent 5d28f24 commit 7dbb1d1
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 18 deletions.
31 changes: 21 additions & 10 deletions app/src/main/java/kim/hsl/rtmp/CameraManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public class CameraManager implements SurfaceHolder.Callback, Camera.PreviewCall
/**
* Camera 预览数据 NV21 格式
*/
private byte[] mNv21DataPreviewBuffer;

/**
* 存储实际向 JNI 层传输的数据
*/
private byte[] mNv21DataBuffer;

/**
Expand Down Expand Up @@ -123,9 +128,10 @@ private void startCameraNV21DataPreview() {
setCameraPreviewOrientation(parameters);
mCamera.setParameters(parameters);
// 6. 计算出 NV21 格式图像 mWidth * mHeight 像素数据大小
mNv21DataPreviewBuffer = new byte[mWidth * mHeight * 3 / 2];
mNv21DataBuffer = new byte[mWidth * mHeight * 3 / 2];
// 7. 设置 Camera 预览数据缓存区
mCamera.addCallbackBuffer(mNv21DataBuffer);
mCamera.addCallbackBuffer(mNv21DataPreviewBuffer);
// 8. 设置 Camera 数据采集回调函数, 采集完数据后
// 就会回调此 PreviewCallback 接口的
// void onPreviewFrame(byte[] data, Camera camera) 方法
Expand Down Expand Up @@ -190,14 +196,16 @@ private void setCameraPreviewOrientation(Camera.Parameters parameters) {
需要重新设置 x264 的编码参数
*/
mOnChangedSizeListener.onChanged(mHeight, mWidth);
//mOnChangedSizeListener.onChanged(mWidth, mHeight);
break;
case Surface.ROTATION_90:
degrees = 90;
mOnChangedSizeListener.onChanged(mWidth, mHeight);
break;
case Surface.ROTATION_180:
degrees = 180;
mOnChangedSizeListener.onChanged(mHeight, mWidth);
//degrees = 180;
//mOnChangedSizeListener.onChanged(mHeight, mWidth);
//mOnChangedSizeListener.onChanged(mWidth, mHeight);
break;
case Surface.ROTATION_270:
mOnChangedSizeListener.onChanged(mWidth, mHeight);
Expand Down Expand Up @@ -333,12 +341,16 @@ public void surfaceDestroyed(SurfaceHolder holder) {
public void onPreviewFrame(byte[] data, Camera camera) {
// 处理 NV21 数据旋转问题
if(mScreenRotation == Surface.ROTATION_0){
// 获取到数据后, 先将数据旋转, 然后再处理下面的内容
nv21PictureDataClockwiseRotation90(data);
}else{
mNv21DataBuffer = data;
}

// 此时 NV21 数据是颠倒的
mPreviewCallback.onPreviewFrame(data, camera);
camera.addCallbackBuffer(mNv21DataBuffer);
// 此时经过 nv21PictureDataClockwiseRotation90 方法处理后 NV21 数据图像方向是正的
// 通过该回调函数, 将旋转后的画面传递到 JNI 层
mPreviewCallback.onPreviewFrame(mNv21DataBuffer, camera);
camera.addCallbackBuffer(mNv21DataPreviewBuffer);
}

/**
Expand Down Expand Up @@ -373,7 +385,7 @@ private void nv21PictureDataClockwiseRotation90(byte[] data){
外层循环 : 逐行遍历, 从第一行遍历到最后一行, 从 0 到 mWidth - 1
内存循环 : 遍历每一行时, 从底部遍历到顶部, 从 mHeight - 1 到 0
*/
for (int i = 0; i < mWidth; i++) {
for (int i = 0; i <= mWidth - 1; i++) {
// 第 i 行, 从每一列的最后一个像素 ( 索引 mHeight - 1 ) 遍历到第一个像素 ( 索引 0 )
for (int j = mHeight - 1; j >= 0; j--) {
// 将读取到的 Y 灰度值存储到 mNv21DataBuffer 缓冲区中
Expand All @@ -400,7 +412,7 @@ private void nv21PictureDataClockwiseRotation90(byte[] data){
内层遍历时 : 遍历列, 从 mHeight / 2 - 1 遍历到 0
UV 数据也需要倒着读 , 从 mHeight / 2 - 1 遍历到 0
*/
for (int i = 0; i < mWidth / 2; i ++) {
for (int i = 0; i <= mWidth / 2 - 1; i ++) {
for (int j = UVByteHeight - 1; j >= 0; j--) {
// 读取数据时, 要从 YByteCount 之后的数据开始遍历
// 使用 mWidth 和 UVByteHeight 定位要遍历的位置
Expand All @@ -411,7 +423,6 @@ private void nv21PictureDataClockwiseRotation90(byte[] data){
}
}


}else if(mCameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT){
/*
前置摄像头处理
Expand Down Expand Up @@ -453,7 +464,7 @@ private void nv21PictureDataClockwiseRotation90(byte[] data){
UV 数据也需要倒着读 , 从 0 遍历到 mHeight / 2 - 1
*/
for (int i = mWidth / 2 - 1; i >= 0 ; i --) {
for (int j = 0; j < UVByteHeight; j++) {
for (int j = 0; j <= UVByteHeight - 1; j++) {
// 读取数据时, 要从 YByteCount 之后的数据开始遍历
// 使用 mWidth 和 UVByteHeight 定位要遍历的位置
// 拷贝 V 色彩值数据
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/kim/hsl/rtmp/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ protected void onCreate(Bundle savedInstanceState) {

// 创建直播推流器, 用于将采集的视频数据推流到服务器端
// 800_000 代表 800K 的码率
mLivePusher = new LivePusher(this, 800, 480, 800_000, 10, Camera.CameraInfo.CAMERA_FACING_BACK);
mLivePusher = new LivePusher(this, 640, 480, 800_000, 10, Camera.CameraInfo.CAMERA_FACING_BACK);

// 设置 Camera 采集的图像本地预览的组件, 在 mSurfaceView 界面先绘制摄像头
// 此处要为 SurfaceHolder 设置 SurfaceHolder.Callback 回调 , 通过里面的回调函数
Expand All @@ -92,7 +92,7 @@ public void onClick(View v) {
// rtmp://47.94.36.51/myapp/0
// 0 相当于 直播的 密码
// 配置好服务器后, 记录 IP 地址, 替换 47.94.36.51 IP 地址
mLivePusher.startLive("rtmp://47.94.36.51/myapp/mystream");
mLivePusher.startLive("rtmp://59.110.116.214/myapp/mystream");
}
});

Expand Down
12 changes: 6 additions & 6 deletions app/src/main/java/kim/hsl/rtmp/VideoChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class VideoChannel implements Camera.PreviewCallback, CameraManager.OnCha


private LivePusher mLivePusher;
private CameraManager mCameraHelper;
private CameraManager mCameraManager;

/**
* 视频码率
Expand All @@ -32,22 +32,22 @@ public VideoChannel(LivePusher livePusher, Activity activity, int width, int hei
mFps = fps;

// 1. 初始化 Camera 相关参数
mCameraHelper = new CameraManager(activity, cameraId, width, height);
mCameraManager = new CameraManager(activity, cameraId, width, height);
// 2. 设置 Camera 预览数据回调接口
// 通过该接口可以在本类中的实现的 onPreviewFrame 方法中
// 获取到 NV21 数据
mCameraHelper.setPreviewCallback(this);
mCameraManager.setPreviewCallback(this);
// 3. 通过该回调接口, 可以获取到真实的 Camera 尺寸数据
// 设置摄像头预览尺寸完成后, 会回调该接口
mCameraHelper.setOnChangedSizeListener(this);
mCameraManager.setOnChangedSizeListener(this);
}

/**
* 设置预览图像画布
* @param surfaceHolder
*/
public void setPreviewDisplay(SurfaceHolder surfaceHolder) {
mCameraHelper.setPreviewDisplay(surfaceHolder);
mCameraManager.setPreviewDisplay(surfaceHolder);
}


Expand All @@ -65,7 +65,7 @@ public void onPreviewFrame(byte[] data, Camera camera) {
}

public void switchCamera() {
mCameraHelper.switchCamera();
mCameraManager.switchCamera();
}

/**
Expand Down

0 comments on commit 7dbb1d1

Please sign in to comment.