1
0
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
4.8 KiB

//#define LOG_NDEBUG 0
#define LOG_TAG "RtspServer"
#include <utils/Log.h>
#include <stdlib.h>
#include <stdio.h>
#include "H264LiveVideoServerMediaSubsession.h"
#include "RtspServer.h"
RtspServer::RtspServer() : mEnv(NULL), mSms(NULL), mRtspServer(NULL), mProcThread(NULL), mCamDev(NULL), mEncoder(NULL)
{
ALOGD("RtspServer enter");
}
RtspServer::~RtspServer()
{
ALOGD("~RtspServer enter");
if (mProcThread != NULL) {
delete mProcThread;
mProcThread = NULL;
}
if (mCamDev != NULL) {
mCamDev->deinit();
delete mCamDev;
mCamDev = NULL;
}
if (mEncoder != NULL) {
delete mEncoder;
mEncoder = NULL;
}
}
bool RtspServer::init(MetaInfo* meta)
{
if (meta == NULL) {
ALOGE("Failed to get metaData");
return false;
}
if (mEnv == NULL) {
// begin by setting up our usage environment.
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
mEnv = BasicUsageEnvironment::createNew(*scheduler);
OutPacketBuffer::maxSize = 1920 * 1080 * 2;
mRtspServer = RTSPServer::createNew(*mEnv, meta->port_num);
if (mRtspServer == NULL) {
ALOGE("Failed to create RTSP server: %s", mEnv->getResultMsg());
return false;
}
strcpy(mStreamName, meta->stream_name);
}
return initOther(meta);
}
bool RtspServer::initOther(MetaInfo* meta)
{
mCamDev = new CamCaptureHelper();
// start CamCaptureHelper.
CamCaptureHelper::MetaInfo camInfo;
strcat(camInfo.video_dev, meta->dev_name);
camInfo.width = meta->width;
camInfo.height = meta->height;
camInfo.format = 0; // nv12
if (!mCamDev->init(&camInfo)) {
ALOGE("Failed to init mCamDev");
return false;
}
// start RKHWEncApi.
mEncoder = new RKHWEncApi();
RKHWEncApi::EncCfgInfo_t encInfo;
encInfo.width = meta->width;
encInfo.height = meta->height;
encInfo.format = ENC_INPUT_YUV420_SEMIPLANAR;
encInfo.framerate = 30; // 30fps
encInfo.bitRate = 8000000; // 500k default
encInfo.IDRInterval = 1;
encInfo.rc_mode = 1;
encInfo.qp = 20;
if (!mEncoder->init(&encInfo)) {
ALOGE("Failed to init mEncoder");
return false;
}
return true;
}
void RtspServer::onDoGetNextFrame(QMediaBuffer* outBuf)
{
bool ret = true;
QMediaBuffer camBuf;
ALOGI("onDoGetNextFrame");
if (mCamDev->getCameraBuffer(&camBuf)) {
ret = mEncoder->sendFrame(camBuf.getFd(), camBuf.getSize(), 0, 0);
if (!ret) {
ALOGD("Failed to sendFrame");
mCamDev->putCameraBuffer(&camBuf);
return;
}
EncoderOut_t encOut;
ret = mEncoder->getOutStream(&encOut);
if (ret) {
// fill live source data
outBuf->setData(encOut.data, encOut.size);
} else {
ALOGD("Failed to getOutStream");
}
mCamDev->putCameraBuffer(&camBuf);
} else {
ALOGD("Failed to get camera buffer");
}
}
bool RtspServer::start()
{
ALOGD("Start streaming...");
resetDoneFlag();
mProcThread = new std::thread(&RtspServer::doEventLoop, this);
mSms = ServerMediaSession::createNew(*mEnv, mStreamName, "test", "Session streamed by \"cameraPushTest\"");
mSms->addSubsession(H264LiveVideoServerMediaSubsession::createNew(*mEnv, True, this));
mRtspServer->addServerMediaSession(mSms);
char* url = mRtspServer->rtspURL(mSms);
ALOGD("Play this stream using the URL: %s", url);
delete[] url;
return true;
}
bool RtspServer::stop()
{
ALOGD("Stop streaming... Exit scheduler eventLoop");
setDoneFlag();
ALOGD("Exit procThread");
if (mProcThread != NULL) {
mProcThread->join();
delete mProcThread;
mProcThread = NULL;
}
if (mRtspServer != NULL) {
mRtspServer->deleteServerMediaSession(mStreamName);
}
if (mCamDev != NULL) {
mCamDev->deinit();
delete mCamDev;
mCamDev = NULL;
}
if (mEncoder != NULL) {
delete mEncoder;
mEncoder = NULL;
}
return true;
}
void RtspServer::doEventLoop()
{
ALOGD("Env doEventLoop");
mEnv->taskScheduler().doEventLoop(&fDoneFlag);
ALOGD("Env doEventLoop exit");
}
static RtspServer _g_rtsp_server;
int init_rtsp(const char* video_dev, int width, int height)
{
RtspServer::MetaInfo info;
info.width = width;
info.height = height;
info.port_num = 1234;
strcat(info.dev_name, video_dev);
strcat(info.stream_name, "v");
ALOGD("init_rtsp: video_dev %s w %d h %d", video_dev, width, height);
if (!_g_rtsp_server.init(&info)) {
ALOGE("Failed to init _g_rtsp_server");
return -1;
}
_g_rtsp_server.start();
return 0;
}
void deinit_rtsp()
{
ALOGD("deinit_rtsp enter");
_g_rtsp_server.stop();
}