Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
G
GB28181Android
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
规范查询wiki:
http://gitlab.anweitech.com/root/AW-Project-Manage/wikis/pages
Open sidebar
Administrator
GB28181Android
Commits
45de32ae
提交
45de32ae
authored
9月 21, 2018
作者:
autulin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
1.优化停止的逻辑,解决停止崩溃的问题
2.添加注释 3.log优化
上级
efc1d748
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
66 行增加
和
48 行删除
+66
-48
GB28181_sender.cpp
gb28181library/src/main/cpp/GB28181_sender.cpp
+8
-4
GB28181_sender.h
gb28181library/src/main/cpp/GB28181_sender.h
+1
-1
gb28181_muxer.cpp
gb28181library/src/main/cpp/gb28181_muxer.cpp
+51
-37
gb28181_muxer.h
gb28181library/src/main/cpp/gb28181_muxer.h
+4
-4
native-lib.cpp
gb28181library/src/main/cpp/native-lib.cpp
+1
-1
MediaRecorderNative.java
.../java/com/autulin/gb28181library/MediaRecorderNative.java
+1
-1
没有找到文件。
gb28181library/src/main/cpp/GB28181_sender.cpp
浏览文件 @
45de32ae
...
...
@@ -28,7 +28,7 @@ int GB28181_sender::initSender() {
isRuning
=
RUNING
;
pthread_t
thread
;
pthread_create
(
&
thread
,
NULL
,
GB28181_sender
::
processSend
,
this
);
LOGI
(
"
发送器初始化完成
"
)
LOGI
(
"
[sender]init ok.
"
)
return
0
;
}
...
...
@@ -43,6 +43,7 @@ void *GB28181_sender::processSend(void *obj) {
uint64_t
start_t
=
getCurrentTime
();
uint8_t
*
pkt_buf
=
*
gb28181Sender
->
pkt_queue
.
wait_and_pop
().
get
();
if
(
!
gb28181Sender
->
isRuning
)
break
;
uint16_t
len
=
bytes2short
(
pkt_buf
);
uint64_t
t1
=
getCurrentTime
();
...
...
@@ -65,19 +66,21 @@ void *GB28181_sender::processSend(void *obj) {
delete
(
pkt_buf
);
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
();
return
nullptr
;
}
int
GB28181_sender
::
sendCloseSignal
()
{
isRuning
=
STOPED
;
pkt_queue
.
push
(
NULL
);
return
0
;
}
int
GB28181_sender
::
closeSender
()
{
LOGE
(
"[sender]start close sender."
)
if
(
stoped
)
{
return
0
;
}
else
{
...
...
@@ -98,8 +101,9 @@ int GB28181_sender::closeSender() {
break
;
}
if
(
n
<
0
)
{
LOGE
(
"close socket error
"
);
LOGE
(
"close socket error
.(%d)"
,
n
);
}
LOGE
(
"[sender]close sender over."
)
return
n
;
}
...
...
gb28181library/src/main/cpp/GB28181_sender.h
浏览文件 @
45de32ae
...
...
@@ -39,7 +39,7 @@ private:
UserArguments
*
args
;
ofstream
fout
;
threadsafe_queue
<
uint8_t
*>
pkt_queue
;
int
isRuning
;
volatile
int
isRuning
;
volatile
int
stoped
;
int
sockfd
;
...
...
gb28181library/src/main/cpp/gb28181_muxer.cpp
浏览文件 @
45de32ae
...
...
@@ -15,7 +15,7 @@ GB28181Muxer::GB28181Muxer(UserArguments *arg) : arguments(arg) {
* @return
*/
int
GB28181Muxer
::
initMuxer
()
{
LOGI
(
"
视频编码器初始化开始
"
);
LOGI
(
"
[muxer]init starting.
"
);
av_register_all
();
pFormatCtx
=
avformat_alloc_context
();
...
...
@@ -115,8 +115,7 @@ int GB28181Muxer::initMuxer() {
pthread_create
(
&
thread
,
NULL
,
GB28181Muxer
::
startMux
,
this
);
pthread_t
thread2
;
pthread_create
(
&
thread2
,
NULL
,
GB28181Muxer
::
startEncode
,
this
);
LOGI
(
"视频编码器初始化完成"
)
LOGI
(
"[muxer]init over"
);
return
0
;
}
...
...
@@ -131,11 +130,16 @@ int GB28181Muxer::sendVideoFrame(uint8_t *buf) {
int64_t
st1
=
getCurrentTime
();
vFrame_queue
.
push
(
pNewFrame
);
int64_t
et
=
getCurrentTime
();
LOG
E
(
"生成帧用时:%lld, 原始帧入队用时
:%lld"
,
st1
-
st
,
et
-
st1
);
LOG
I
(
"[muxer][send in]gen AVFrame time:%lld, send AVFrame to queue time
:%lld"
,
st1
-
st
,
et
-
st1
);
videoFrameCnt
++
;
return
0
;
}
/**
* 将原始帧封装成为FFmpeg的AVFrame
* @param rawData 原始帧数据
* @return AVFrame
*/
AVFrame
*
GB28181Muxer
::
genFrame
(
uint8_t
*
rawData
)
{
uint8_t
*
new_buf
=
(
uint8_t
*
)
malloc
(
in_y_size
*
3
/
2
);
memcpy
(
new_buf
,
rawData
,
in_y_size
*
3
/
2
);
...
...
@@ -151,7 +155,7 @@ AVFrame *GB28181Muxer::genFrame(uint8_t *rawData) {
}
else
{
pNewFrame
->
pts
=
(
getCurrentTime
()
-
startTime
)
*
90
;
}
LOGI
(
"new Frame pts:%lld(%d)"
,
LOGI
(
"
[muxer][gen frame]
new Frame pts:%lld(%d)"
,
pNewFrame
->
pts
,
videoFrameCnt
);
return
pNewFrame
;
}
...
...
@@ -175,9 +179,14 @@ int GB28181Muxer::sendAudioFrame(uint8_t *buf) {
}
/**
* 编码的线程方法
* 不断的从AVFrame队列里面取帧出来,送到FFmpeg中编码
* @param obj
* @return
*/
void
*
GB28181Muxer
::
startEncode
(
void
*
obj
)
{
LOGE
(
"start encode thread"
);
LOGE
(
"
[muxer][encode]
start encode thread"
);
GB28181Muxer
*
gb28181Muxer
=
(
GB28181Muxer
*
)
obj
;
while
(
!
gb28181Muxer
->
is_end
)
{
int64_t
st
=
getCurrentTime
();
...
...
@@ -185,24 +194,28 @@ void *GB28181Muxer::startEncode(void *obj) {
int64_t
et1
=
getCurrentTime
();
int
ret
=
avcodec_send_frame
(
gb28181Muxer
->
pCodecCtx
,
pFrame
);
while
(
ret
==
AVERROR
(
EAGAIN
))
{
// LOGE("送入FFmpeg错误:%d.(重试)", ret);
usleep
(
5000
);
usleep
(
1000
);
ret
=
avcodec_send_frame
(
gb28181Muxer
->
pCodecCtx
,
pFrame
);
}
int64_t
et2
=
getCurrentTime
();
LOG
E
(
"fetch queue time:%lld(frame left:%d)
,in FFmpeg time:%lld."
,
et1
-
st
,
gb28181Muxer
->
vFrame_queue
.
size
(),
et2
-
et1
);
LOG
I
(
"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
)
{
LOGE
(
"send FFmpeg error:%d."
,
ret
);
}
}
LOGI
(
"[muxer][encode]encode thread is over."
);
gb28181Muxer
->
endMux
();
delete
gb28181Muxer
;
return
0
;
}
/**
*
启动编码线程
*
合并音视频并生成GB28181的线程方法
* @param obj
* @return
*/
void
*
GB28181Muxer
::
startMux
(
void
*
obj
)
{
LOGE
(
"start mux thread"
);
LOGE
(
"
[muxer][mux]
start mux thread"
);
GB28181Muxer
*
gb28181Muxer
=
(
GB28181Muxer
*
)
obj
;
while
(
!
gb28181Muxer
->
is_end
)
{
int
ret
;
...
...
@@ -214,7 +227,7 @@ void *GB28181Muxer::startMux(void *obj) {
}
else
{
gb28181Muxer
->
nowPkt
=
&
gb28181Muxer
->
pkt
;
LOGI
(
"got first encoded pkt!(pts:%lld, queue size: %d)
\n
"
,
gb28181Muxer
->
nowPkt
->
pts
,
gb28181Muxer
->
v
ideo
_queue
.
size
());
gb28181Muxer
->
nowPkt
->
pts
,
gb28181Muxer
->
v
Frame
_queue
.
size
());
gb28181Muxer
->
lastPts
=
gb28181Muxer
->
nowPkt
->
pts
;
gb28181Muxer
->
muxCnt
++
;
}
...
...
@@ -222,7 +235,7 @@ void *GB28181Muxer::startMux(void *obj) {
ret
=
avcodec_receive_packet
(
gb28181Muxer
->
pCodecCtx
,
gb28181Muxer
->
nextPkt
);
if
(
ret
<
0
)
{
// LOGE("Failed to send encode!(%d) \n", ret);
usleep
(
5
000
);
usleep
(
1
000
);
}
else
{
// LOGI("got encoded pkt!(pts:%lld, queue size: %d) \n", gb28181Muxer->nextPkt->pts,
// gb28181Muxer->video_queue.size());
...
...
@@ -230,13 +243,13 @@ void *GB28181Muxer::startMux(void *obj) {
}
}
int64_t
et
=
getCurrentTime
();
if
(
ret
>=
0
)
LOGE
(
"mux one time:%lld"
,
et
-
st
);
}
if
(
gb28181Muxer
->
is_end
)
{
gb28181Muxer
->
endMux
();
delete
gb28181Muxer
;
if
(
ret
>=
0
){
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
);
}
}
LOGI
(
"[muxer][mux]mux thread is over."
)
return
0
;
}
...
...
@@ -359,13 +372,13 @@ GB28181Muxer::custom_filter(const GB28181Muxer *gb28181Muxer, const uint8_t *pic
* @return
*/
int
GB28181Muxer
::
endMux
()
{
LOGE
(
"
endMux
"
);
LOGE
(
"
[muxer]ending
"
);
gb28181Sender
->
sendCloseSignal
();
LOGE
(
"a
du
io queue left num: %d, video queue left num: %d"
,
audio_queue
.
size
(),
v
ideo
_queue
.
size
());
LOGE
(
"a
ud
io queue left num: %d, video queue left num: %d"
,
audio_queue
.
size
(),
v
Frame
_queue
.
size
());
audio_queue
.
clear
();
v
ideo
_queue
.
clear
();
v
Frame
_queue
.
clear
();
//Clean
if
(
video_st
)
{
...
...
@@ -375,19 +388,24 @@ int GB28181Muxer::endMux() {
}
// avio_close(pFormatCtx->pb);
avformat_free_context
(
pFormatCtx
);
LOGI
(
"视频编码结束"
)
// gb28181Sender->closeSender(); //再发一次防止之前没关掉
return
1
;
LOGI
(
"[muxer]ended."
)
return
0
;
}
/**
* 用户结束
* 用户
选择
结束
*/
void
GB28181Muxer
::
user_end
()
{
LOGE
(
"
call user end
"
);
void
GB28181Muxer
::
sendEndSignal
()
{
LOGE
(
"
[muxer]change mux status.(end)
"
);
is_end
=
END_STATE
;
}
/**
* 将视频帧和音频帧打包的实际方法
* 一个视频帧对应多个音频帧
* @param gb28181Muxer
* @return
*/
int
GB28181Muxer
::
mux
(
GB28181Muxer
*
gb28181Muxer
)
{
//init header buffer
...
...
@@ -398,7 +416,7 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
int64_t
newPts
=
gb28181Muxer
->
nextPkt
->
pts
;
//
计算写入音频的个数
//
calculate the num of audio frame in one video frame
int64_t
frameDiv
=
newPts
-
gb28181Muxer
->
lastPts
;
gb28181Muxer
->
frameAppend
=
(
frameDiv
+
gb28181Muxer
->
frameAppend
)
%
3600
;
int
audioCnt
=
(
frameDiv
+
gb28181Muxer
->
frameAppend
)
/
3600
;
...
...
@@ -416,14 +434,14 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
nSizePos
+=
PS_HDR_LEN
;
//2 system header
if
(
gb28181Muxer
->
nowPkt
->
flags
==
1
)
{
//
如果是I帧的话,则添加系统头
//
if I frame, add SYS_HEADER and PSM_HEADER
gb28181_make_sys_header
(
gb28181headerBuf
+
nSizePos
,
audioCnt
);
nSizePos
+=
SYS_HDR_LEN
;
gb28181_make_psm_header
(
gb28181headerBuf
+
nSizePos
);
nSizePos
+=
PSM_HDR_LEN
;
}
nSize
=
gb28181Muxer
->
nowPkt
->
size
;
// video p
s
m
// video p
e
m
gb28181_make_pes_header
(
gb28181headerBuf
+
nSizePos
,
0xE0
,
nSize
,
gb28181Muxer
->
lastPts
,
gb28181Muxer
->
lastPts
);
nSizePos
+=
PES_HDR_LEN
;
...
...
@@ -464,8 +482,5 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
delete
(
audioFrame
);
}
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
;
}
\ No newline at end of file
gb28181library/src/main/cpp/gb28181_muxer.h
浏览文件 @
45de32ae
...
...
@@ -27,7 +27,7 @@ public:
int
sendAudioFrame
(
uint8_t
*
buf
);
void
user_end
();
void
sendEndSignal
();
int
endMux
();
...
...
@@ -42,10 +42,10 @@ private:
private
:
UserArguments
*
arguments
;
GB28181_sender
*
gb28181Sender
;
int
is_end
=
START_STATE
;
int
is_release
=
RELEASE_FALSE
;
volatile
int
is_end
=
START_STATE
;
volatile
int
is_release
=
RELEASE_FALSE
;
threadsafe_queue
<
AVFrame
*>
vFrame_queue
;
threadsafe_queue
<
uint8_t
*>
video_queue
;
//
threadsafe_queue<uint8_t *> video_queue;
threadsafe_queue
<
uint8_t
*>
audio_queue
;
AVFormatContext
*
pFormatCtx
;
AVOutputFormat
*
fmt
;
...
...
gb28181library/src/main/cpp/native-lib.cpp
浏览文件 @
45de32ae
...
...
@@ -100,7 +100,7 @@ JNIEXPORT jint JNICALL
Java_com_autulin_gb28181library_JNIBridge_endMux
(
JNIEnv
*
env
,
jclass
type
)
{
if
(
gb28181Muxer
!=
NULL
)
{
gb28181Muxer
->
user_end
();
gb28181Muxer
->
sendEndSignal
();
gb28181Muxer
=
NULL
;
}
return
0
;
...
...
gb28181library/src/main/java/com/autulin/gb28181library/MediaRecorderNative.java
浏览文件 @
45de32ae
...
...
@@ -24,7 +24,7 @@ public class MediaRecorderNative extends MediaRecorderBase implements MediaRecor
public
void
onPreviewFrame
(
byte
[]
data
,
Camera
camera
)
{
if
(
mRecording
)
{
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
;
JNIBridge
.
sendOneVideoFrame
(
data
);
mPreviewFrameCallCount
++;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论