add VideoStreamNew with camera2

add VideoStreamNew with camera2
pull/107/head
xufulong 5 years ago
parent a76ce7e52f
commit 94518f18e4
  1. 37
      Live/src/main/cpp/VideoStream.cpp
  2. 3
      Live/src/main/cpp/VideoStream.h
  3. 15
      Live/src/main/java/com/frank/live/LivePusherNew.java
  4. 151
      Live/src/main/java/com/frank/live/stream/VideoStreamNew.java

@ -1,5 +1,6 @@
#include <cstring>
#include <jni.h>
#include "VideoStream.h"
#include "include/rtmp/rtmp.h"
#include "PushGeneric.h"
@ -116,11 +117,40 @@ void VideoStream::encodeData(int8_t *data) {
pthread_mutex_unlock(&mutex);
}
void VideoStream::encodeDataNew(int8_t *y_plane, int8_t *u_plane, int8_t *v_plane) {
pthread_mutex_lock(&mutex);
//直接拷贝
memcpy(pic_in->img.plane[0], y_plane, (size_t) ySize);
memcpy(pic_in->img.plane[1], u_plane, (size_t) ySize/4);
memcpy(pic_in->img.plane[2], v_plane, (size_t) ySize/4);
x264_nal_t *pp_nal;
int pi_nal;
x264_picture_t pic_out;
x264_encoder_encode(videoCodec, &pp_nal, &pi_nal, pic_in, &pic_out);
int sps_len = 0;
int pps_len = 0;
uint8_t sps[100];
uint8_t pps[100];
for (int i = 0; i < pi_nal; ++i) {
if (pp_nal[i].i_type == NAL_SPS) {
sps_len = pp_nal[i].i_payload - 4;
memcpy(sps, pp_nal[i].p_payload + 4, static_cast<size_t>(sps_len));
} else if (pp_nal[i].i_type == NAL_PPS) {
pps_len = pp_nal[i].i_payload - 4;
memcpy(pps, pp_nal[i].p_payload + 4, static_cast<size_t>(pps_len));
sendSpsPps(sps, pps, sps_len, pps_len);
} else {
sendFrame(pp_nal[i].i_type, pp_nal[i].p_payload, pp_nal[i].i_payload);
}
}
pthread_mutex_unlock(&mutex);
}
void VideoStream::sendSpsPps(uint8_t *sps, uint8_t *pps, int sps_len, int pps_len) {
//看表
int bodySize = 13 + sps_len + 3 + pps_len;
RTMPPacket *packet = new RTMPPacket;
//
RTMPPacket_Alloc(packet, bodySize);
int i = 0;
//固定头
@ -139,7 +169,7 @@ void VideoStream::sendSpsPps(uint8_t *sps, uint8_t *pps, int sps_len, int pps_le
packet->m_body[i++] = sps[3];
packet->m_body[i++] = 0xFF;
//整个sps
//sps
packet->m_body[i++] = 0xE1;
//sps长度
packet->m_body[i++] = (sps_len >> 8) & 0xff;
@ -156,7 +186,6 @@ void VideoStream::sendSpsPps(uint8_t *sps, uint8_t *pps, int sps_len, int pps_le
//视频
packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;
packet->m_nBodySize = bodySize;
//随意分配一个管道(尽量避开rtmp.c中使用的)
packet->m_nChannel = 10;
//sps pps没有时间戳
packet->m_nTimeStamp = 0;

@ -19,6 +19,8 @@ public:
void encodeData(int8_t *data);
void encodeDataNew(int8_t *y_plane, int8_t *u_plane, int8_t *v_plane);
void setVideoCallback(VideoCallback videoCallback);
private:
@ -38,5 +40,4 @@ private:
void sendFrame(int type, uint8_t *payload, int i_payload);
};
#endif

@ -2,12 +2,14 @@ package com.frank.live;
import android.app.Activity;
import android.view.SurfaceHolder;
import android.view.TextureView;
import com.frank.live.listener.LiveStateChangeListener;
import com.frank.live.param.AudioParam;
import com.frank.live.param.VideoParam;
import com.frank.live.stream.AudioStream;
import com.frank.live.stream.VideoStream;
import com.frank.live.stream.VideoStreamNew;
public class LivePusherNew {
@ -32,6 +34,7 @@ public class LivePusherNew {
private AudioStream audioStream;
private VideoStream videoStream;
// private VideoStreamNew videoStream;
private LiveStateChangeListener liveStateChangeListener;
@ -42,6 +45,12 @@ public class LivePusherNew {
audioStream = new AudioStream(this, audioParam);
}
public LivePusherNew(Activity activity, VideoParam videoParam, AudioParam audioParam, TextureView textureView) {
native_init();
// videoStream = new VideoStreamNew(this, textureView, videoParam, activity);
audioStream = new AudioStream(this, audioParam);
}
public void setPreviewDisplay(SurfaceHolder surfaceHolder) {
videoStream.setPreviewDisplay(surfaceHolder);
}
@ -141,6 +150,10 @@ public class LivePusherNew {
native_pushVideo(data);
}
public void pushVideo(byte[] y, byte[] u, byte[] v) {
native_pushVideoNew(y, u, v);
}
private native void native_init();
private native void native_start(String path);
@ -155,6 +168,8 @@ public class LivePusherNew {
private native void native_pushVideo(byte[] data);
private native void native_pushVideoNew(byte[] y, byte[] u, byte[] v);
private native void native_stop();
private native void native_release();

@ -0,0 +1,151 @@
package com.frank.live.stream;
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.util.Log;
import android.util.Size;
import android.view.SurfaceHolder;
import android.view.TextureView;
import com.frank.live.LivePusherNew;
import com.frank.live.camera2.Camera2Helper;
import com.frank.live.camera2.Camera2Listener;
import com.frank.live.param.VideoParam;
/**
* 视频推流:使用Camera2
* Created by frank on 2020/02/12.
*/
public class VideoStreamNew implements TextureView.SurfaceTextureListener, Camera2Listener {
private static final String TAG = VideoStreamNew.class.getSimpleName();
private LivePusherNew mLivePusher;
private Camera2Helper camera2Helper;
private boolean isLiving;
private TextureView mTextureView;
private Context mContext;
private VideoParam mVideoParam;
public VideoStreamNew(LivePusherNew livePusher, TextureView textureView, VideoParam videoParam, Context context) {
this.mLivePusher = livePusher;
this.mTextureView = textureView;
this.mVideoParam = videoParam;
this.mContext = context;
mTextureView.setSurfaceTextureListener(this);
}
public void setPreviewDisplay(SurfaceHolder surfaceHolder) {
// cameraHelper.setPreviewDisplay(surfaceHolder);
}
/**
* 开始预览
*/
private void startPreview() {
int rotateDegree = 0;
if (mContext instanceof Activity) {
rotateDegree = ((Activity) mContext).getWindowManager().getDefaultDisplay().getRotation();
}
Log.e(TAG, "preview width=" + mTextureView.getWidth() + "--height=" + mTextureView.getHeight());
camera2Helper = new Camera2Helper.Builder()
.cameraListener(this)
.specificCameraId(Camera2Helper.CAMERA_ID_BACK)
.context(mContext.getApplicationContext())
.previewOn(mTextureView)
// .previewViewSize(new Point(mTextureView.getWidth(), mTextureView.getHeight()))
.previewViewSize(new Point(mVideoParam.getWidth(), mVideoParam.getHeight()))
.rotation(rotateDegree)
.build();
camera2Helper.start();
}
public void switchCamera() {
if (camera2Helper != null) {
camera2Helper.switchCamera();
}
}
public void startLive() {
isLiving = true;
}
public void stopLive() {
isLiving = false;
}
public void release() {
if (camera2Helper != null) {
camera2Helper.stop();
camera2Helper.release();
camera2Helper = null;
}
}
/**
* 停止预览
*/
private void stopPreview() {
if (camera2Helper != null) {
camera2Helper.stop();
}
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.e(TAG, "onSurfaceTextureAvailable...");
startPreview();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Log.e(TAG, "onSurfaceTextureDestroyed...");
stopPreview();
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
/**
* nv21摄像头数据
* @param y plane of y
* @param u plane of u
* @param v plane of v
*/
@Override
public void onPreviewFrame(byte[] y, byte[] u, byte[] v) {
if (isLiving && mLivePusher != null) {
mLivePusher.pushVideo(y, u, v);
}
}
@Override
public void onCameraOpened(Size previewSize, int displayOrientation) {
Log.e(TAG, "onCameraOpened previewSize=" + previewSize.toString());
if (mLivePusher != null && mVideoParam != null) {
mLivePusher.setVideoCodecInfo(previewSize.getWidth(), previewSize.getHeight(),
mVideoParam.getFrameRate(), mVideoParam.getBitRate());
}
}
@Override
public void onCameraClosed() {
Log.e(TAG, "onCameraClosed");
}
@Override
public void onCameraError(Exception e) {
Log.e(TAG, "onCameraError=" + e.toString());
}
}
Loading…
Cancel
Save