提交 45de32ae authored 作者: autulin's avatar autulin

1.优化停止的逻辑,解决停止崩溃的问题

2.添加注释 3.log优化
上级 efc1d748
...@@ -28,7 +28,7 @@ int GB28181_sender::initSender() { ...@@ -28,7 +28,7 @@ int GB28181_sender::initSender() {
isRuning = RUNING; isRuning = RUNING;
pthread_t thread; pthread_t thread;
pthread_create(&thread, NULL, GB28181_sender::processSend, this); pthread_create(&thread, NULL, GB28181_sender::processSend, this);
LOGI("发送器初始化完成") LOGI("[sender]init ok.")
return 0; return 0;
} }
...@@ -43,6 +43,7 @@ void *GB28181_sender::processSend(void *obj) { ...@@ -43,6 +43,7 @@ void *GB28181_sender::processSend(void *obj) {
uint64_t start_t = getCurrentTime(); uint64_t start_t = getCurrentTime();
uint8_t *pkt_buf = *gb28181Sender->pkt_queue.wait_and_pop().get(); uint8_t *pkt_buf = *gb28181Sender->pkt_queue.wait_and_pop().get();
if (!gb28181Sender->isRuning) break;
uint16_t len = bytes2short(pkt_buf); uint16_t len = bytes2short(pkt_buf);
uint64_t t1 = getCurrentTime(); uint64_t t1 = getCurrentTime();
...@@ -65,19 +66,21 @@ void *GB28181_sender::processSend(void *obj) { ...@@ -65,19 +66,21 @@ void *GB28181_sender::processSend(void *obj) {
delete(pkt_buf); delete(pkt_buf);
uint64_t t2 = getCurrentTime(); uint64_t t2 = getCurrentTime();
LOGI("[sender]队列获取用时:%lld\t发送用时:%lld", t1 - start_t, t2 - t1); LOGI("[sender]read from queue:%lld\t I/O time:%lld", t1 - start_t, t2 - t1);
} }
LOGI("发送结束"); LOGI("[sender]sending thread is over.");
gb28181Sender->closeSender(); gb28181Sender->closeSender();
return nullptr; return nullptr;
} }
int GB28181_sender::sendCloseSignal() { int GB28181_sender::sendCloseSignal() {
isRuning = STOPED; isRuning = STOPED;
pkt_queue.push(NULL);
return 0; return 0;
} }
int GB28181_sender::closeSender() { int GB28181_sender::closeSender() {
LOGE("[sender]start close sender.")
if (stoped) { if (stoped) {
return 0; return 0;
} else { } else {
...@@ -98,8 +101,9 @@ int GB28181_sender::closeSender() { ...@@ -98,8 +101,9 @@ int GB28181_sender::closeSender() {
break; break;
} }
if (n < 0) { if (n < 0) {
LOGE("close socket error"); LOGE("close socket error.(%d)", n);
} }
LOGE("[sender]close sender over.")
return n; return n;
} }
......
...@@ -39,7 +39,7 @@ private: ...@@ -39,7 +39,7 @@ private:
UserArguments * args; UserArguments * args;
ofstream fout; ofstream fout;
threadsafe_queue<uint8_t *> pkt_queue; threadsafe_queue<uint8_t *> pkt_queue;
int isRuning; volatile int isRuning;
volatile int stoped; volatile int stoped;
int sockfd; int sockfd;
......
...@@ -15,7 +15,7 @@ GB28181Muxer::GB28181Muxer(UserArguments *arg) : arguments(arg) { ...@@ -15,7 +15,7 @@ GB28181Muxer::GB28181Muxer(UserArguments *arg) : arguments(arg) {
* @return * @return
*/ */
int GB28181Muxer::initMuxer() { int GB28181Muxer::initMuxer() {
LOGI("视频编码器初始化开始"); LOGI("[muxer]init starting.");
av_register_all(); av_register_all();
pFormatCtx = avformat_alloc_context(); pFormatCtx = avformat_alloc_context();
...@@ -115,8 +115,7 @@ int GB28181Muxer::initMuxer() { ...@@ -115,8 +115,7 @@ int GB28181Muxer::initMuxer() {
pthread_create(&thread, NULL, GB28181Muxer::startMux, this); pthread_create(&thread, NULL, GB28181Muxer::startMux, this);
pthread_t thread2; pthread_t thread2;
pthread_create(&thread2, NULL, GB28181Muxer::startEncode, this); pthread_create(&thread2, NULL, GB28181Muxer::startEncode, this);
LOGI("视频编码器初始化完成") LOGI("[muxer]init over");
return 0; return 0;
} }
...@@ -131,11 +130,16 @@ int GB28181Muxer::sendVideoFrame(uint8_t *buf) { ...@@ -131,11 +130,16 @@ int GB28181Muxer::sendVideoFrame(uint8_t *buf) {
int64_t st1 = getCurrentTime(); int64_t st1 = getCurrentTime();
vFrame_queue.push(pNewFrame); vFrame_queue.push(pNewFrame);
int64_t et = getCurrentTime(); int64_t et = getCurrentTime();
LOGE("生成帧用时:%lld, 原始帧入队用时:%lld", st1 - st, et - st1); LOGI("[muxer][send in]gen AVFrame time:%lld, send AVFrame to queue time:%lld", st1 - st, et - st1);
videoFrameCnt++; videoFrameCnt++;
return 0; return 0;
} }
/**
* 将原始帧封装成为FFmpeg的AVFrame
* @param rawData 原始帧数据
* @return AVFrame
*/
AVFrame *GB28181Muxer::genFrame(uint8_t *rawData) { AVFrame *GB28181Muxer::genFrame(uint8_t *rawData) {
uint8_t *new_buf = (uint8_t *) malloc(in_y_size * 3 / 2); uint8_t *new_buf = (uint8_t *) malloc(in_y_size * 3 / 2);
memcpy(new_buf, rawData, in_y_size * 3 / 2); memcpy(new_buf, rawData, in_y_size * 3 / 2);
...@@ -151,7 +155,7 @@ AVFrame *GB28181Muxer::genFrame(uint8_t *rawData) { ...@@ -151,7 +155,7 @@ AVFrame *GB28181Muxer::genFrame(uint8_t *rawData) {
} else { } else {
pNewFrame->pts = (getCurrentTime() - startTime) * 90; pNewFrame->pts = (getCurrentTime() - startTime) * 90;
} }
LOGI("new Frame pts:%lld(%d)", LOGI("[muxer][gen frame]new Frame pts:%lld(%d)",
pNewFrame->pts, videoFrameCnt); pNewFrame->pts, videoFrameCnt);
return pNewFrame; return pNewFrame;
} }
...@@ -175,9 +179,14 @@ int GB28181Muxer::sendAudioFrame(uint8_t *buf) { ...@@ -175,9 +179,14 @@ int GB28181Muxer::sendAudioFrame(uint8_t *buf) {
} }
/**
* 编码的线程方法
* 不断的从AVFrame队列里面取帧出来,送到FFmpeg中编码
* @param obj
* @return
*/
void *GB28181Muxer::startEncode(void *obj) { void *GB28181Muxer::startEncode(void *obj) {
LOGE("start encode thread"); LOGE("[muxer][encode]start encode thread");
GB28181Muxer *gb28181Muxer = (GB28181Muxer *) obj; GB28181Muxer *gb28181Muxer = (GB28181Muxer *) obj;
while (!gb28181Muxer->is_end) { while (!gb28181Muxer->is_end) {
int64_t st = getCurrentTime(); int64_t st = getCurrentTime();
...@@ -185,24 +194,28 @@ void *GB28181Muxer::startEncode(void *obj) { ...@@ -185,24 +194,28 @@ void *GB28181Muxer::startEncode(void *obj) {
int64_t et1 = getCurrentTime(); int64_t et1 = getCurrentTime();
int ret = avcodec_send_frame(gb28181Muxer->pCodecCtx, pFrame); int ret = avcodec_send_frame(gb28181Muxer->pCodecCtx, pFrame);
while (ret == AVERROR(EAGAIN)) { while (ret == AVERROR(EAGAIN)) {
// LOGE("送入FFmpeg错误:%d.(重试)", ret); usleep(1000);
usleep(5000);
ret = avcodec_send_frame(gb28181Muxer->pCodecCtx, pFrame); ret = avcodec_send_frame(gb28181Muxer->pCodecCtx, pFrame);
} }
int64_t et2 = getCurrentTime(); int64_t et2 = getCurrentTime();
LOGE("fetch queue time:%lld(frame left:%d),in FFmpeg time:%lld.", et1 - st, gb28181Muxer->vFrame_queue.size(), et2 - et1); LOGI("fetch raw frame from queue time:%lld (frame quque left:%d),in FFmpeg time:%lld.", et1 - st, gb28181Muxer->vFrame_queue.size(), et2 - et1);
if (ret < 0) { if (ret < 0) {
LOGE("send FFmpeg error:%d.", ret); LOGE("send FFmpeg error:%d.", ret);
} }
} }
LOGI("[muxer][encode]encode thread is over.");
gb28181Muxer->endMux();
delete gb28181Muxer;
return 0;
} }
/** /**
* 启动编码线程 * 合并音视频并生成GB28181的线程方法
* @param obj * @param obj
* @return * @return
*/ */
void *GB28181Muxer::startMux(void *obj) { void *GB28181Muxer::startMux(void *obj) {
LOGE("start mux thread"); LOGE("[muxer][mux]start mux thread");
GB28181Muxer *gb28181Muxer = (GB28181Muxer *) obj; GB28181Muxer *gb28181Muxer = (GB28181Muxer *) obj;
while (!gb28181Muxer->is_end) { while (!gb28181Muxer->is_end) {
int ret; int ret;
...@@ -214,7 +227,7 @@ void *GB28181Muxer::startMux(void *obj) { ...@@ -214,7 +227,7 @@ void *GB28181Muxer::startMux(void *obj) {
} else{ } else{
gb28181Muxer->nowPkt = &gb28181Muxer->pkt; gb28181Muxer->nowPkt = &gb28181Muxer->pkt;
LOGI("got first encoded pkt!(pts:%lld, queue size: %d) \n", LOGI("got first encoded pkt!(pts:%lld, queue size: %d) \n",
gb28181Muxer->nowPkt->pts, gb28181Muxer->video_queue.size()); gb28181Muxer->nowPkt->pts, gb28181Muxer->vFrame_queue.size());
gb28181Muxer->lastPts = gb28181Muxer->nowPkt->pts; gb28181Muxer->lastPts = gb28181Muxer->nowPkt->pts;
gb28181Muxer->muxCnt++; gb28181Muxer->muxCnt++;
} }
...@@ -222,7 +235,7 @@ void *GB28181Muxer::startMux(void *obj) { ...@@ -222,7 +235,7 @@ void *GB28181Muxer::startMux(void *obj) {
ret = avcodec_receive_packet(gb28181Muxer->pCodecCtx, gb28181Muxer->nextPkt); ret = avcodec_receive_packet(gb28181Muxer->pCodecCtx, gb28181Muxer->nextPkt);
if (ret < 0) { if (ret < 0) {
// LOGE("Failed to send encode!(%d) \n", ret); // LOGE("Failed to send encode!(%d) \n", ret);
usleep(5000); usleep(1000);
} else { } else {
// LOGI("got encoded pkt!(pts:%lld, queue size: %d) \n", gb28181Muxer->nextPkt->pts, // LOGI("got encoded pkt!(pts:%lld, queue size: %d) \n", gb28181Muxer->nextPkt->pts,
// gb28181Muxer->video_queue.size()); // gb28181Muxer->video_queue.size());
...@@ -230,13 +243,13 @@ void *GB28181Muxer::startMux(void *obj) { ...@@ -230,13 +243,13 @@ void *GB28181Muxer::startMux(void *obj) {
} }
} }
int64_t et = getCurrentTime(); int64_t et = getCurrentTime();
if (ret >= 0) if (ret >= 0){
LOGE("mux one time:%lld", et - st); LOGI("mux one pkt over!(video queue size: %d, audio queue size: %d), time use: %lld",
} gb28181Muxer->vFrame_queue.size(), gb28181Muxer->audio_queue.size(), et - st);
if (gb28181Muxer->is_end) { }
gb28181Muxer->endMux();
delete gb28181Muxer;
} }
LOGI("[muxer][mux]mux thread is over.")
return 0; return 0;
} }
...@@ -359,13 +372,13 @@ GB28181Muxer::custom_filter(const GB28181Muxer *gb28181Muxer, const uint8_t *pic ...@@ -359,13 +372,13 @@ GB28181Muxer::custom_filter(const GB28181Muxer *gb28181Muxer, const uint8_t *pic
* @return * @return
*/ */
int GB28181Muxer::endMux() { int GB28181Muxer::endMux() {
LOGE("endMux"); LOGE("[muxer]ending");
gb28181Sender->sendCloseSignal(); gb28181Sender->sendCloseSignal();
LOGE("aduio queue left num: %d, video queue left num: %d", audio_queue.size(), LOGE("audio queue left num: %d, video queue left num: %d", audio_queue.size(),
video_queue.size()); vFrame_queue.size());
audio_queue.clear(); audio_queue.clear();
video_queue.clear(); vFrame_queue.clear();
//Clean //Clean
if (video_st) { if (video_st) {
...@@ -375,19 +388,24 @@ int GB28181Muxer::endMux() { ...@@ -375,19 +388,24 @@ int GB28181Muxer::endMux() {
} }
// avio_close(pFormatCtx->pb); // avio_close(pFormatCtx->pb);
avformat_free_context(pFormatCtx); avformat_free_context(pFormatCtx);
LOGI("视频编码结束") LOGI("[muxer]ended.")
// gb28181Sender->closeSender(); //再发一次防止之前没关掉 return 0;
return 1;
} }
/** /**
* 用户结束 * 用户选择结束
*/ */
void GB28181Muxer::user_end() { void GB28181Muxer::sendEndSignal() {
LOGE("call user end"); LOGE("[muxer]change mux status.(end)");
is_end = END_STATE; is_end = END_STATE;
} }
/**
* 将视频帧和音频帧打包的实际方法
* 一个视频帧对应多个音频帧
* @param gb28181Muxer
* @return
*/
int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) { int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
//init header buffer //init header buffer
...@@ -398,7 +416,7 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) { ...@@ -398,7 +416,7 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
int64_t newPts = gb28181Muxer->nextPkt->pts; int64_t newPts = gb28181Muxer->nextPkt->pts;
// 计算写入音频的个数 // calculate the num of audio frame in one video frame
int64_t frameDiv = newPts - gb28181Muxer->lastPts; int64_t frameDiv = newPts - gb28181Muxer->lastPts;
gb28181Muxer->frameAppend = (frameDiv + gb28181Muxer->frameAppend) % 3600; gb28181Muxer->frameAppend = (frameDiv + gb28181Muxer->frameAppend) % 3600;
int audioCnt = (frameDiv + gb28181Muxer->frameAppend) / 3600; int audioCnt = (frameDiv + gb28181Muxer->frameAppend) / 3600;
...@@ -416,14 +434,14 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) { ...@@ -416,14 +434,14 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
nSizePos += PS_HDR_LEN; nSizePos += PS_HDR_LEN;
//2 system header //2 system header
if (gb28181Muxer->nowPkt->flags == 1) { if (gb28181Muxer->nowPkt->flags == 1) {
// 如果是I帧的话,则添加系统头 // if I frame, add SYS_HEADER and PSM_HEADER
gb28181_make_sys_header(gb28181headerBuf + nSizePos, audioCnt); gb28181_make_sys_header(gb28181headerBuf + nSizePos, audioCnt);
nSizePos += SYS_HDR_LEN; nSizePos += SYS_HDR_LEN;
gb28181_make_psm_header(gb28181headerBuf + nSizePos); gb28181_make_psm_header(gb28181headerBuf + nSizePos);
nSizePos += PSM_HDR_LEN; nSizePos += PSM_HDR_LEN;
} }
nSize = gb28181Muxer->nowPkt->size; nSize = gb28181Muxer->nowPkt->size;
// video psm // video pem
gb28181_make_pes_header(gb28181headerBuf + nSizePos, 0xE0, nSize, gb28181Muxer->lastPts, gb28181_make_pes_header(gb28181headerBuf + nSizePos, 0xE0, nSize, gb28181Muxer->lastPts,
gb28181Muxer->lastPts); gb28181Muxer->lastPts);
nSizePos += PES_HDR_LEN; nSizePos += PES_HDR_LEN;
...@@ -464,8 +482,5 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) { ...@@ -464,8 +482,5 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
delete (audioFrame); delete (audioFrame);
} }
gb28181Sender->addPkt(pkt_full); gb28181Sender->addPkt(pkt_full);
LOGI("mux one pkt over!(video queue size: %d, audio queue size: %d)",
gb28181Muxer->video_queue.size(), gb28181Muxer->audio_queue.size());
return 0; return 0;
} }
\ No newline at end of file
...@@ -27,7 +27,7 @@ public: ...@@ -27,7 +27,7 @@ public:
int sendAudioFrame(uint8_t *buf); int sendAudioFrame(uint8_t *buf);
void user_end(); void sendEndSignal();
int endMux(); int endMux();
...@@ -42,10 +42,10 @@ private: ...@@ -42,10 +42,10 @@ private:
private: private:
UserArguments *arguments; UserArguments *arguments;
GB28181_sender *gb28181Sender; GB28181_sender *gb28181Sender;
int is_end = START_STATE; volatile int is_end = START_STATE;
int is_release = RELEASE_FALSE; volatile int is_release = RELEASE_FALSE;
threadsafe_queue<AVFrame *> vFrame_queue; threadsafe_queue<AVFrame *> vFrame_queue;
threadsafe_queue<uint8_t *> video_queue; // threadsafe_queue<uint8_t *> video_queue;
threadsafe_queue<uint8_t *> audio_queue; threadsafe_queue<uint8_t *> audio_queue;
AVFormatContext *pFormatCtx; AVFormatContext *pFormatCtx;
AVOutputFormat *fmt; AVOutputFormat *fmt;
......
...@@ -100,7 +100,7 @@ JNIEXPORT jint JNICALL ...@@ -100,7 +100,7 @@ JNIEXPORT jint JNICALL
Java_com_autulin_gb28181library_JNIBridge_endMux(JNIEnv *env, jclass type) { Java_com_autulin_gb28181library_JNIBridge_endMux(JNIEnv *env, jclass type) {
if (gb28181Muxer != NULL) { if (gb28181Muxer != NULL) {
gb28181Muxer->user_end(); gb28181Muxer->sendEndSignal();
gb28181Muxer = NULL; gb28181Muxer = NULL;
} }
return 0; return 0;
......
...@@ -24,7 +24,7 @@ public class MediaRecorderNative extends MediaRecorderBase implements MediaRecor ...@@ -24,7 +24,7 @@ public class MediaRecorderNative extends MediaRecorderBase implements MediaRecor
public void onPreviewFrame(byte[] data, Camera camera) { public void onPreviewFrame(byte[] data, Camera camera) {
if (mRecording) { if (mRecording) {
long nt = System.currentTimeMillis(); long nt = System.currentTimeMillis();
Log.e("now", "onPreviewFrame: "+ nt + ", div:" + (nt- t)); Log.i("Recorder", "onPreviewFrame: "+ nt + ", div:" + (nt- t) + ", pts div: " + (nt- t) * 90);
t = nt; t = nt;
JNIBridge.sendOneVideoFrame(data); JNIBridge.sendOneVideoFrame(data);
mPreviewFrameCallCount++; mPreviewFrameCallCount++;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论