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
494dae45
提交
494dae45
authored
10月 09, 2018
作者:
autulin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
1.恢复使用原始raw视频队列,将生成帧的方法移动到发送帧的线程线程方法中(复用AVFrame防止内存泄漏)
2.修复tcp的bug
上级
c18e4ece
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
36 行增加
和
43 行删除
+36
-43
DemoActivity.java
...ava/com/example/autulin/gb28181_android/DemoActivity.java
+4
-4
GB28181_sender.cpp
gb28181library/src/main/cpp/GB28181_sender.cpp
+1
-0
gb28181_muxer.cpp
gb28181library/src/main/cpp/gb28181_muxer.cpp
+29
-37
gb28181_muxer.h
gb28181library/src/main/cpp/gb28181_muxer.h
+2
-2
没有找到文件。
app/src/main/java/com/example/autulin/gb28181_android/DemoActivity.java
浏览文件 @
494dae45
...
...
@@ -104,10 +104,10 @@ public class DemoActivity extends AppCompatActivity implements
// 设置输出
// String fileName = String.valueOf(System.currentTimeMillis());
String
fileName
=
"tttttt"
;
mediaOutput
=
mMediaRecorder
.
setFileOutPut
(
fileName
);
//输出到文件,这里demo是/sdcard/DCIM
/pstest/tttttt.ps
//
int ssrc = 1;
// mediaOutput = mMediaRecorder.setUdpOutPut("10.112.181.160
", 8888, ssrc);
//
String fileName = "tttttt";
// mediaOutput = mMediaRecorder.setFileOutPut(fileName); //输出到文件,这里demo是/sdcard
/pstest/tttttt.ps
int
ssrc
=
1
;
mediaOutput
=
mMediaRecorder
.
setTcpOutPut
(
"10.112.154.194
"
,
8888
,
ssrc
);
mMediaRecorder
.
setSurfaceHolder
(
mSurfaceView
.
getHolder
());
mMediaRecorder
.
prepare
();
...
...
gb28181library/src/main/cpp/GB28181_sender.cpp
浏览文件 @
494dae45
...
...
@@ -15,6 +15,7 @@ int GB28181_sender::initSender() {
break
;
case
1
:
// tcp
LOGE
(
"ip:%s, port:%d, out_type:%d"
,
args
->
ip_addr
,
args
->
port
,
args
->
outType
);
initSocket
(
args
->
ip_addr
,
args
->
port
);
break
;
case
2
:
// file
//打开ps文件
...
...
gb28181library/src/main/cpp/gb28181_muxer.cpp
浏览文件 @
494dae45
...
...
@@ -126,39 +126,15 @@ int GB28181Muxer::initMuxer() {
*/
int
GB28181Muxer
::
sendVideoFrame
(
uint8_t
*
buf
)
{
int64_t
st
=
getCurrentTime
();
AVFrame
*
pNewFrame
=
genFrame
(
buf
);
int64_t
st1
=
getCurrentTime
(
);
v
Frame_queue
.
push
(
pNewFrame
);
uint8_t
*
new_buf
=
(
uint8_t
*
)
malloc
(
in_y_size
*
3
/
2
);
memcpy
(
new_buf
,
buf
,
in_y_size
*
3
/
2
);
v
ideo_queue
.
push
(
new_buf
);
int64_t
et
=
getCurrentTime
();
LOGI
(
"[muxer][send in]
gen AVFrame time:%lld, send AVFrame to queue time:%lld"
,
st1
-
st
,
et
-
st1
);
LOGI
(
"[muxer][send in]
send raw Frame to queue time:%lld"
,
et
-
st
);
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
);
AVFrame
*
pNewFrame
=
av_frame_alloc
();
uint8_t
*
buf
=
(
uint8_t
*
)
av_malloc
(
picture_size
);
avpicture_fill
((
AVPicture
*
)
pNewFrame
,
buf
,
pCodecCtx
->
pix_fmt
,
pCodecCtx
->
width
,
pCodecCtx
->
height
);
custom_filter
(
this
,
new_buf
,
pNewFrame
);
if
(
startTime
==
0
)
{
startTime
=
getCurrentTime
();
pNewFrame
->
pts
=
0
;
}
else
{
pNewFrame
->
pts
=
(
getCurrentTime
()
-
startTime
)
*
90
;
}
LOGI
(
"[muxer][gen frame]new Frame pts:%lld(%d)"
,
pNewFrame
->
pts
,
videoFrameCnt
);
return
pNewFrame
;
}
/**
* 编码并发送一音频帧到编码队列
...
...
@@ -181,24 +157,40 @@ int GB28181Muxer::sendAudioFrame(uint8_t *buf) {
/**
* 编码的线程方法
* 不断的从
AVFrame
队列里面取帧出来,送到FFmpeg中编码
* 不断的从
视频原始帧
队列里面取帧出来,送到FFmpeg中编码
* @param obj
* @return
*/
void
*
GB28181Muxer
::
startEncode
(
void
*
obj
)
{
LOGE
(
"[muxer][encode]start encode thread"
);
GB28181Muxer
*
gb28181Muxer
=
(
GB28181Muxer
*
)
obj
;
//初始化一个AVFrame,这个AVFrame是可以复用多次的
AVFrame
*
pNewFrame
=
av_frame_alloc
();
uint8_t
*
buf
=
(
uint8_t
*
)
av_malloc
(
gb28181Muxer
->
picture_size
);
avpicture_fill
((
AVPicture
*
)
pNewFrame
,
buf
,
gb28181Muxer
->
pCodecCtx
->
pix_fmt
,
gb28181Muxer
->
pCodecCtx
->
width
,
gb28181Muxer
->
pCodecCtx
->
height
);
while
(
!
gb28181Muxer
->
is_end
)
{
int64_t
st
=
getCurrentTime
();
AVFrame
*
pFrame
=
*
gb28181Muxer
->
vFrame_queue
.
wait_and_pop
();
uint8_t
*
new_buf
=
*
gb28181Muxer
->
video_queue
.
wait_and_pop
();
gb28181Muxer
->
custom_filter
(
gb28181Muxer
,
new_buf
,
pNewFrame
);
delete
new_buf
;
if
(
gb28181Muxer
->
startTime
==
0
)
{
gb28181Muxer
->
startTime
=
getCurrentTime
();
pNewFrame
->
pts
=
0
;
}
else
{
pNewFrame
->
pts
=
(
getCurrentTime
()
-
gb28181Muxer
->
startTime
)
*
90
;
}
int64_t
et1
=
getCurrentTime
();
int
ret
=
avcodec_send_frame
(
gb28181Muxer
->
pCodecCtx
,
pFrame
);
int
ret
=
avcodec_send_frame
(
gb28181Muxer
->
pCodecCtx
,
p
New
Frame
);
while
(
ret
==
AVERROR
(
EAGAIN
))
{
usleep
(
1000
);
ret
=
avcodec_send_frame
(
gb28181Muxer
->
pCodecCtx
,
pFrame
);
ret
=
avcodec_send_frame
(
gb28181Muxer
->
pCodecCtx
,
p
New
Frame
);
}
int64_t
et2
=
getCurrentTime
();
LOGI
(
"fetch raw frame from queue time:%lld (
frame quque left:%d),in FFmpeg time:%lld."
,
et1
-
st
,
gb28181Muxer
->
vFrame
_queue
.
size
(),
et2
-
et1
);
LOGI
(
"fetch raw frame from queue time:%lld (
video frame queue left:%d),in FFmpeg time:%lld."
,
et1
-
st
,
gb28181Muxer
->
video
_queue
.
size
(),
et2
-
et1
);
if
(
ret
<
0
)
{
LOGE
(
"send FFmpeg error:%d."
,
ret
);
}
...
...
@@ -227,7 +219,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
Frame
_queue
.
size
());
gb28181Muxer
->
nowPkt
->
pts
,
gb28181Muxer
->
v
ideo
_queue
.
size
());
gb28181Muxer
->
lastPts
=
gb28181Muxer
->
nowPkt
->
pts
;
gb28181Muxer
->
muxCnt
++
;
}
...
...
@@ -245,7 +237,7 @@ void *GB28181Muxer::startMux(void *obj) {
int64_t
et
=
getCurrentTime
();
if
(
ret
>=
0
){
LOGI
(
"mux one pkt over!(video queue size: %d, audio queue size: %d), time use: %lld"
,
gb28181Muxer
->
v
Frame
_queue
.
size
(),
gb28181Muxer
->
audio_queue
.
size
(),
et
-
st
);
gb28181Muxer
->
v
ideo
_queue
.
size
(),
gb28181Muxer
->
audio_queue
.
size
(),
et
-
st
);
}
}
...
...
@@ -376,9 +368,9 @@ int GB28181Muxer::endMux() {
gb28181Sender
->
sendCloseSignal
();
LOGE
(
"audio queue left num: %d, video queue left num: %d"
,
audio_queue
.
size
(),
v
Frame
_queue
.
size
());
v
ideo
_queue
.
size
());
audio_queue
.
clear
();
v
Frame
_queue
.
clear
();
v
ideo
_queue
.
clear
();
//Clean
if
(
video_st
)
{
...
...
gb28181library/src/main/cpp/gb28181_muxer.h
浏览文件 @
494dae45
...
...
@@ -44,8 +44,8 @@ private:
GB28181_sender
*
gb28181Sender
;
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<AVFrame *> vFrame_queue;
threadsafe_queue
<
uint8_t
*>
video_queue
;
threadsafe_queue
<
uint8_t
*>
audio_queue
;
AVFormatContext
*
pFormatCtx
;
AVOutputFormat
*
fmt
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论