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
ed6a66cd
提交
ed6a66cd
authored
9月 19, 2018
作者:
autulin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
大改造之使用新的API来完成读写分离,但是仍旧拯救不了性能
上级
e6b27d10
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
224 行增加
和
151 行删除
+224
-151
GB28181_sender.cpp
gb28181library/src/main/cpp/GB28181_sender.cpp
+40
-9
GB28181_sender.h
gb28181library/src/main/cpp/GB28181_sender.h
+1
-1
gb28181_muxer.cpp
gb28181library/src/main/cpp/gb28181_muxer.cpp
+144
-126
gb28181_muxer.h
gb28181library/src/main/cpp/gb28181_muxer.h
+9
-0
native-lib.cpp
gb28181library/src/main/cpp/native-lib.cpp
+2
-3
user_arguments.h
gb28181library/src/main/cpp/user_arguments.h
+1
-2
DemoActivity.java
...rc/main/java/com/autulin/gb28181library/DemoActivity.java
+3
-2
JNIBridge.java
...y/src/main/java/com/autulin/gb28181library/JNIBridge.java
+2
-1
MediaOutput.java
...src/main/java/com/autulin/gb28181library/MediaOutput.java
+11
-1
MediaRecorderBase.java
...in/java/com/autulin/gb28181library/MediaRecorderBase.java
+5
-5
MediaRecorderNative.java
.../java/com/autulin/gb28181library/MediaRecorderNative.java
+6
-1
没有找到文件。
gb28181library/src/main/cpp/GB28181_sender.cpp
浏览文件 @
ed6a66cd
...
@@ -46,15 +46,15 @@ void *GB28181_sender::processSend(void *obj) {
...
@@ -46,15 +46,15 @@ void *GB28181_sender::processSend(void *obj) {
uint16_t
len
=
bytes2short
(
pkt_buf
);
uint16_t
len
=
bytes2short
(
pkt_buf
);
uint64_t
t1
=
getCurrentTime
();
uint64_t
t1
=
getCurrentTime
();
// char strBuf[16];
ssize_t
n
;
// sprintf(strBuf, "get pkt len: %d", len);
int
n
;
switch
(
gb28181Sender
->
args
->
outType
)
{
switch
(
gb28181Sender
->
args
->
outType
)
{
case
0
:
// udp
case
0
:
// udp
n
=
gb28181Sender
->
sendData
(
pkt_buf
+
2
,
len
);
n
=
gb28181Sender
->
sendData
(
pkt_buf
+
2
,
len
);
LOG
E
(
"[sender]get pkt len: %d. sent %
d. (queue left size: %d)"
,
len
,
n
,
gb28181Sender
->
pkt_queue
.
size
());
LOG
I
(
"[sender][udp]get pkt len: %d. sent %l
d. (queue left size: %d)"
,
len
,
n
,
gb28181Sender
->
pkt_queue
.
size
());
break
;
break
;
case
1
:
// tcp
case
1
:
// tcp
n
=
gb28181Sender
->
sendData
(
pkt_buf
,
len
+
2
);
LOGI
(
"[sender][tcp]get pkt len: %d. sent %ld. (queue left size: %d)"
,
len
,
n
,
gb28181Sender
->
pkt_queue
.
size
());
break
;
break
;
case
2
:
// file
case
2
:
// file
gb28181Sender
->
fout
.
write
((
const
char
*
)
(
pkt_buf
+
2
),
len
);
gb28181Sender
->
fout
.
write
((
const
char
*
)
(
pkt_buf
+
2
),
len
);
...
@@ -104,13 +104,23 @@ int GB28181_sender::closeSender() {
...
@@ -104,13 +104,23 @@ int GB28181_sender::closeSender() {
}
}
int
GB28181_sender
::
initSocket
(
char
*
hostname
,
int
port
)
{
int
GB28181_sender
::
initSocket
(
char
*
hostname
,
int
port
)
{
//todo
switch
(
args
->
outType
)
{
sockfd
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
case
0
:
// udp
sockfd
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
break
;
case
1
:
// tcp
sockfd
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
break
;
default
:
sockfd
=
-
99
;
}
if
(
sockfd
<
0
){
if
(
sockfd
<
0
){
LOGE
(
"ERROR opening socket
"
);
LOGE
(
"ERROR opening socket
.(%d)"
,
sockfd
);
return
sockfd
;
return
sockfd
;
}
}
// 域名解析相关
// struct hostent *server;
// struct hostent *server;
// server = gethostbyname(hostname);
// server = gethostbyname(hostname);
// if (server == NULL) {
// if (server == NULL) {
...
@@ -127,11 +137,32 @@ int GB28181_sender::initSocket(char *hostname, int port) {
...
@@ -127,11 +137,32 @@ int GB28181_sender::initSocket(char *hostname, int port) {
serveraddr
.
sin_port
=
htons
(
port
);
serveraddr
.
sin_port
=
htons
(
port
);
serverlen
=
sizeof
(
serveraddr
);
serverlen
=
sizeof
(
serveraddr
);
if
(
args
->
outType
==
1
)
{
// tcp
int
ret
=
connect
(
sockfd
,
(
const
sockaddr
*
)
&
serveraddr
,
serverlen
);
if
(
ret
<
0
){
LOGE
(
"ERROR connect.(%d)"
,
ret
);
return
ret
;
}
}
return
0
;
return
0
;
}
}
int
GB28181_sender
::
sendData
(
uint8_t
*
buf
,
int
len
)
{
ssize_t
GB28181_sender
::
sendData
(
uint8_t
*
buf
,
int
len
)
{
int
n
=
sendto
(
sockfd
,
buf
,
len
,
0
,
(
const
sockaddr
*
)
&
serveraddr
,
serverlen
);
ssize_t
n
=
0
;
switch
(
args
->
outType
)
{
case
0
:
// udp
n
=
sendto
(
sockfd
,
buf
,
len
,
0
,
(
const
sockaddr
*
)
&
serveraddr
,
serverlen
);
break
;
case
1
:
// tcp
n
=
send
(
sockfd
,
buf
,
len
,
0
);
break
;
default
:
return
-
1
;
}
if
(
n
<
0
)
{
LOGE
(
"send error.(%ld)"
,
n
);
}
return
n
;
return
n
;
}
}
...
...
gb28181library/src/main/cpp/GB28181_sender.h
浏览文件 @
ed6a66cd
...
@@ -47,7 +47,7 @@ private:
...
@@ -47,7 +47,7 @@ private:
int
serverlen
;
int
serverlen
;
int
initSocket
(
char
*
hostname
,
int
port
);
int
initSocket
(
char
*
hostname
,
int
port
);
in
t
sendData
(
uint8_t
*
buf
,
int
len
);
ssize_
t
sendData
(
uint8_t
*
buf
,
int
len
);
int
closeSocket
();
int
closeSocket
();
...
...
gb28181library/src/main/cpp/gb28181_muxer.cpp
浏览文件 @
ed6a66cd
...
@@ -59,7 +59,7 @@ int GB28181Muxer::initMuxer() {
...
@@ -59,7 +59,7 @@ int GB28181Muxer::initMuxer() {
pCodecCtx
->
bit_rate
=
arguments
->
video_bit_rate
;
pCodecCtx
->
bit_rate
=
arguments
->
video_bit_rate
;
//这里是设置关键帧的间隔
//这里是设置关键帧的间隔
pCodecCtx
->
gop_size
=
25
;
pCodecCtx
->
gop_size
=
25
;
pCodecCtx
->
thread_count
=
12
;
pCodecCtx
->
thread_count
=
3
;
pCodecCtx
->
time_base
.
num
=
1
;
pCodecCtx
->
time_base
.
num
=
1
;
pCodecCtx
->
time_base
.
den
=
arguments
->
video_frame_rate
;
pCodecCtx
->
time_base
.
den
=
arguments
->
video_frame_rate
;
...
@@ -106,11 +106,15 @@ int GB28181Muxer::initMuxer() {
...
@@ -106,11 +106,15 @@ int GB28181Muxer::initMuxer() {
av_new_packet
(
&
pkt
,
picture_size
);
av_new_packet
(
&
pkt
,
picture_size
);
av_new_packet
(
&
nPkt
,
picture_size
);
av_new_packet
(
&
nPkt
,
picture_size
);
nextPkt
=
&
nPkt
;
nextPkt
=
&
nPkt
;
g711aFrameLen
=
arguments
->
a_frame_len
/
2
;
scrPerFrame
=
90000
/
arguments
->
video_frame_rate
;
out_y_size
=
pCodecCtx
->
width
*
pCodecCtx
->
height
;
out_y_size
=
pCodecCtx
->
width
*
pCodecCtx
->
height
;
is_end
=
START_STATE
;
is_end
=
START_STATE
;
pthread_t
thread
;
pthread_t
thread
;
pthread_create
(
&
thread
,
NULL
,
GB28181Muxer
::
startMux
,
this
);
pthread_create
(
&
thread
,
NULL
,
GB28181Muxer
::
startMux
,
this
);
pthread_t
thread2
;
pthread_create
(
&
thread2
,
NULL
,
GB28181Muxer
::
startEncode
,
this
);
LOGI
(
"视频编码器初始化完成"
)
LOGI
(
"视频编码器初始化完成"
)
return
0
;
return
0
;
...
@@ -122,17 +126,17 @@ int GB28181Muxer::initMuxer() {
...
@@ -122,17 +126,17 @@ int GB28181Muxer::initMuxer() {
* @return
* @return
*/
*/
int
GB28181Muxer
::
sendVideoFrame
(
uint8_t
*
buf
)
{
int
GB28181Muxer
::
sendVideoFrame
(
uint8_t
*
buf
)
{
int64_t
st
=
getCurrentTime
();
AVFrame
*
pNewFrame
=
genFrame
(
buf
);
AVFrame
*
pNewFrame
=
genFrame
(
buf
);
int
ret
=
avcodec_send_frame
(
pCodecCtx
,
pNewFrame
);
int64_t
st1
=
getCurrentTime
();
LOGE
(
"!!!!!!!!!!!!!!!!!!!!
\n
"
);
vFrame_queue
.
push
(
pNewFrame
);
if
(
ret
<
0
)
{
int64_t
et
=
getCurrentTime
();
LOGE
(
"Failed to send encode!
\n
"
);
LOGE
(
"生成帧用时:%lld, 原始帧入队用时:%lld"
,
st1
-
st
,
et
-
st1
);
}
videoFrameCnt
++
;
videoFrameCnt
++
;
return
0
;
return
0
;
}
}
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
);
...
@@ -147,8 +151,9 @@ AVFrame * GB28181Muxer::genFrame(uint8_t *rawData) {
...
@@ -147,8 +151,9 @@ AVFrame * GB28181Muxer::genFrame(uint8_t *rawData) {
}
else
{
}
else
{
pNewFrame
->
pts
=
(
getCurrentTime
()
-
startTime
)
*
90
;
pNewFrame
->
pts
=
(
getCurrentTime
()
-
startTime
)
*
90
;
}
}
LOGE
(
"new Frame pts:%lld"
,
LOGI
(
"new Frame pts:%lld(%d)"
,
pNewFrame
->
pts
);
pNewFrame
->
pts
,
videoFrameCnt
);
return
pNewFrame
;
}
}
/**
/**
...
@@ -169,6 +174,28 @@ int GB28181Muxer::sendAudioFrame(uint8_t *buf) {
...
@@ -169,6 +174,28 @@ int GB28181Muxer::sendAudioFrame(uint8_t *buf) {
return
0
;
return
0
;
}
}
void
*
GB28181Muxer
::
startEncode
(
void
*
obj
)
{
LOGE
(
"start encode thread"
);
GB28181Muxer
*
gb28181Muxer
=
(
GB28181Muxer
*
)
obj
;
while
(
!
gb28181Muxer
->
is_end
)
{
int64_t
st
=
getCurrentTime
();
AVFrame
*
pFrame
=
*
gb28181Muxer
->
vFrame_queue
.
wait_and_pop
();
int64_t
et1
=
getCurrentTime
();
int
ret
=
avcodec_send_frame
(
gb28181Muxer
->
pCodecCtx
,
pFrame
);
while
(
ret
==
AVERROR
(
EAGAIN
))
{
// LOGE("送入FFmpeg错误:%d.(重试)", ret);
usleep
(
5000
);
ret
=
avcodec_send_frame
(
gb28181Muxer
->
pCodecCtx
,
pFrame
);
}
int64_t
et2
=
getCurrentTime
();
LOGE
(
"从队列取耗时:%lld(队列剩余帧:%d),送入FFmpeg耗时:%lld."
,
et1
-
st
,
gb28181Muxer
->
vFrame_queue
.
size
(),
et2
-
et1
);
if
(
ret
<
0
)
{
LOGE
(
"送入FFmpeg错误:%d."
,
ret
);
}
}
}
/**
/**
* 启动编码线程
* 启动编码线程
* @param obj
* @param obj
...
@@ -178,14 +205,33 @@ void *GB28181Muxer::startMux(void *obj) {
...
@@ -178,14 +205,33 @@ void *GB28181Muxer::startMux(void *obj) {
LOGE
(
"start mux thread"
);
LOGE
(
"start mux thread"
);
GB28181Muxer
*
gb28181Muxer
=
(
GB28181Muxer
*
)
obj
;
GB28181Muxer
*
gb28181Muxer
=
(
GB28181Muxer
*
)
obj
;
while
(
!
gb28181Muxer
->
is_end
)
{
while
(
!
gb28181Muxer
->
is_end
)
{
sleep
(
2
);
int
ret
;
AVPacket
*
pAVPkt
;
int64_t
st
=
getCurrentTime
();
int
ret
=
avcodec_receive_packet
(
gb28181Muxer
->
pCodecCtx
,
pAVPkt
);
if
(
gb28181Muxer
->
muxCnt
==
0
)
{
// 获得首帧
if
(
ret
<
0
)
{
ret
=
avcodec_receive_packet
(
gb28181Muxer
->
pCodecCtx
,
&
gb28181Muxer
->
pkt
);
LOGE
(
"Failed to send encode!(%d)
\n
"
,
ret
);
if
(
ret
<
0
)
{
usleep
(
5000
);
}
else
{
gb28181Muxer
->
nowPkt
=
&
gb28181Muxer
->
pkt
;
LOGI
(
"got first encoded pkt!(pts:%lld, queue size: %d)
\n
"
,
gb28181Muxer
->
nowPkt
->
pts
,
gb28181Muxer
->
video_queue
.
size
());
gb28181Muxer
->
lastPts
=
gb28181Muxer
->
nowPkt
->
pts
;
gb28181Muxer
->
muxCnt
++
;
}
}
else
{
}
else
{
LOGE
(
"got encoded pkt!(pts:%lld)
\n
"
,
pAVPkt
->
pts
);
ret
=
avcodec_receive_packet
(
gb28181Muxer
->
pCodecCtx
,
gb28181Muxer
->
nextPkt
);
if
(
ret
<
0
)
{
// LOGE("Failed to send encode!(%d) \n", ret);
usleep
(
5000
);
}
else
{
// LOGI("got encoded pkt!(pts:%lld, queue size: %d) \n", gb28181Muxer->nextPkt->pts,
// gb28181Muxer->video_queue.size());
gb28181Muxer
->
mux
(
gb28181Muxer
);
}
}
}
int64_t
et
=
getCurrentTime
();
if
(
ret
>=
0
)
LOGE
(
"消费用时:%lld"
,
et
-
st
);
}
}
if
(
gb28181Muxer
->
is_end
)
{
if
(
gb28181Muxer
->
is_end
)
{
gb28181Muxer
->
endMux
();
gb28181Muxer
->
endMux
();
...
@@ -231,13 +277,13 @@ GB28181Muxer::custom_filter(const GB28181Muxer *gb28181Muxer, const uint8_t *pic
...
@@ -231,13 +277,13 @@ GB28181Muxer::custom_filter(const GB28181Muxer *gb28181Muxer, const uint8_t *pic
uint8_t
v
=
*
(
picture_buf
+
in_y_size
+
index
);
uint8_t
v
=
*
(
picture_buf
+
in_y_size
+
index
);
uint8_t
u
=
*
(
picture_buf
+
in_y_size
*
5
/
4
+
index
);
uint8_t
u
=
*
(
picture_buf
+
in_y_size
*
5
/
4
+
index
);
*
(
pFrame
->
data
[
2
]
+
(
j
*
gb28181Muxer
->
arguments
->
out_height
/
2
+
*
(
pFrame
->
data
[
2
]
+
(
j
*
gb28181Muxer
->
arguments
->
out_height
/
2
+
(
gb28181Muxer
->
arguments
->
out_height
/
2
-
(
gb28181Muxer
->
arguments
->
out_height
/
2
-
(
i
-
uv_height_start_index
)
-
(
i
-
uv_height_start_index
)
-
1
)))
=
v
;
1
)))
=
v
;
*
(
pFrame
->
data
[
1
]
+
(
j
*
gb28181Muxer
->
arguments
->
out_height
/
2
+
*
(
pFrame
->
data
[
1
]
+
(
j
*
gb28181Muxer
->
arguments
->
out_height
/
2
+
(
gb28181Muxer
->
arguments
->
out_height
/
2
-
(
gb28181Muxer
->
arguments
->
out_height
/
2
-
(
i
-
uv_height_start_index
)
-
(
i
-
uv_height_start_index
)
-
1
)))
=
u
;
1
)))
=
u
;
}
}
}
}
}
else
if
(
format
==
ROTATE_0_CROP_LT
)
{
}
else
if
(
format
==
ROTATE_0_CROP_LT
)
{
...
@@ -343,112 +389,83 @@ void GB28181Muxer::user_end() {
...
@@ -343,112 +389,83 @@ void GB28181Muxer::user_end() {
}
}
int
GB28181Muxer
::
mux
(
GB28181Muxer
*
gb28181Muxer
)
{
int
GB28181Muxer
::
mux
(
GB28181Muxer
*
gb28181Muxer
)
{
int64_t
lastPts
=
gb28181Muxer
->
pkt
.
pts
;
gb28181Muxer
->
nowPkt
=
&
gb28181Muxer
->
pkt
;
//init header buffer
int64_t
append
=
0
;
char
gb28181headerBuf
[
256
];
int
cnt
=
0
;
int
nSizePos
=
0
;
int
aFrameLen
=
gb28181Muxer
->
arguments
->
a_frame_len
/
2
;
int
nSize
=
0
;
while
(
!
gb28181Muxer
->
is_end
)
{
memset
(
gb28181headerBuf
,
0
,
256
);
char
szTempPacketHead
[
256
];
int
nSizePos
=
0
;
int64_t
newPts
=
gb28181Muxer
->
nextPkt
->
pts
;
int
nSize
=
0
;
memset
(
szTempPacketHead
,
0
,
256
);
// 计算写入音频的个数
int64_t
frameDiv
=
newPts
-
gb28181Muxer
->
lastPts
;
uint64_t
start_t
=
getCurrentTime
();
gb28181Muxer
->
frameAppend
=
(
frameDiv
+
gb28181Muxer
->
frameAppend
)
%
3600
;
int
audioCnt
=
(
frameDiv
+
gb28181Muxer
->
frameAppend
)
/
3600
;
// read next frame
LOGI
(
"now pts:%lld.|%lld| next pts:%lld,audio count:%d"
,
gb28181Muxer
->
nowPkt
->
pts
,
uint8_t
*
picture_buf
=
*
gb28181Muxer
->
video_queue
.
wait_and_pop
().
get
();
gb28181Muxer
->
nextPkt
->
pts
-
gb28181Muxer
->
nowPkt
->
pts
,
uint64_t
t1
=
getCurrentTime
();
gb28181Muxer
->
nextPkt
->
pts
,
audioCnt
);
uint64_t
t2
=
getCurrentTime
();
// 0 rtp header
gb28181_make_rtp_header
(
gb28181headerBuf
+
nSizePos
,
gb28181Muxer
->
muxCnt
++
,
int
got_picture
;
gb28181Muxer
->
lastPts
,
gb28181Muxer
->
arguments
->
ssrc
,
RTP_PKT_END
);
// 送入编码器
nSizePos
+=
RTP_HDR_LEN
;
// 1 package for ps header
uint64_t
t3
=
getCurrentTime
();
gb28181_make_ps_header
(
gb28181headerBuf
+
nSizePos
,
gb28181Muxer
->
lastPts
);
nSizePos
+=
PS_HDR_LEN
;
// 读到了下一帧
//2 system header
int64_t
newPts
=
gb28181Muxer
->
nextPkt
->
pts
;
if
(
gb28181Muxer
->
nowPkt
->
flags
==
1
)
{
// 计算写入音频的个数
// 如果是I帧的话,则添加系统头
int64_t
frameDiv
=
newPts
-
lastPts
;
gb28181_make_sys_header
(
gb28181headerBuf
+
nSizePos
,
audioCnt
);
append
=
(
frameDiv
+
append
)
%
3600
;
nSizePos
+=
SYS_HDR_LEN
;
int
audioCnt
=
(
frameDiv
+
append
)
/
3600
;
gb28181_make_psm_header
(
gb28181headerBuf
+
nSizePos
);
// LOGE("now pts:%lld.|%lld| next pts:%lld,audio count:%d",
nSizePos
+=
PSM_HDR_LEN
;
// gb28181Muxer->nowPkt->pts,
}
// gb28181Muxer->nextPkt->pts - gb28181Muxer->nowPkt->pts,
nSize
=
gb28181Muxer
->
nowPkt
->
size
;
// gb28181Muxer->nextPkt->pts, audioCnt);
// video psm
gb28181_make_pes_header
(
gb28181headerBuf
+
nSizePos
,
0xE0
,
nSize
,
gb28181Muxer
->
lastPts
,
// 0 rtp header
gb28181Muxer
->
lastPts
);
gb28181_make_rtp_header
(
szTempPacketHead
+
nSizePos
,
cnt
++
,
lastPts
,
1
,
RTP_PKT_END
);
nSizePos
+=
PES_HDR_LEN
;
nSizePos
+=
RTP_HDR_LEN
;
gb28181Muxer
->
lastPts
=
gb28181Muxer
->
nextPkt
->
pts
;
// 1 package for ps header
gb28181_make_ps_header
(
szTempPacketHead
+
nSizePos
,
lastPts
);
uint16_t
pktPos
=
0
;
nSizePos
+=
PS_HDR_LEN
;
uint16_t
pkt_len
=
(
uint16_t
)
(
nSizePos
+
nSize
+
//2 system header
audioCnt
*
(
PES_HDR_LEN
+
gb28181Muxer
->
g711aFrameLen
));
if
(
gb28181Muxer
->
nowPkt
->
flags
==
1
)
{
uint8_t
*
pkt_full
=
(
uint8_t
*
)
malloc
(
pkt_len
+
2
);
// 如果是I帧的话,则添加系统头
memcpy
(
pkt_full
,
short2Bytes
(
pkt_len
),
2
);
gb28181_make_sys_header
(
szTempPacketHead
+
nSizePos
,
audioCnt
);
pktPos
+=
2
;
nSizePos
+=
SYS_HDR_LEN
;
memcpy
(
pkt_full
+
pktPos
,
gb28181headerBuf
,
nSizePos
);
gb28181_make_psm_header
(
szTempPacketHead
+
nSizePos
);
pktPos
+=
nSizePos
;
nSizePos
+=
PSM_HDR_LEN
;
memcpy
(
pkt_full
+
pktPos
,
gb28181Muxer
->
nowPkt
->
data
,
nSize
);
}
pktPos
+=
nSize
;
nSize
=
gb28181Muxer
->
nowPkt
->
size
;
// video psm
// next packet
gb28181_make_pes_header
(
szTempPacketHead
+
nSizePos
,
0xE0
,
nSize
,
lastPts
,
lastPts
);
gb28181Muxer
->
nowPkt
->
stream_index
=
gb28181Muxer
->
video_st
->
index
;
AVPacket
*
t
=
gb28181Muxer
->
nowPkt
;
av_free_packet
(
gb28181Muxer
->
nowPkt
);
gb28181Muxer
->
nowPkt
=
gb28181Muxer
->
nextPkt
;
gb28181Muxer
->
nextPkt
=
t
;
// audio part
while
(
audioCnt
>
0
)
{
uint8_t
*
audioFrame
=
*
gb28181Muxer
->
audio_queue
.
wait_and_pop
().
get
();
int64_t
audioPts
=
gb28181Muxer
->
audioFrameCnt
*
3600
;
// 音频默认25帧,90000/25=3600
gb28181_make_pes_header
(
gb28181headerBuf
+
nSizePos
,
0xC0
,
gb28181Muxer
->
g711aFrameLen
,
audioPts
,
audioPts
);
memcpy
(
pkt_full
+
pktPos
,
gb28181headerBuf
+
nSizePos
,
PES_HDR_LEN
);
pktPos
+=
PES_HDR_LEN
;
nSizePos
+=
PES_HDR_LEN
;
nSizePos
+=
PES_HDR_LEN
;
// gb28181Muxer->fout.write(szTempPacketHead, nSizePos);
memcpy
(
pkt_full
+
pktPos
,
audioFrame
,
gb28181Muxer
->
g711aFrameLen
);
// gb28181Muxer->fout.write(reinterpret_cast<const char *>(gb28181Muxer->nowPkt->data), nSize);
pktPos
+=
gb28181Muxer
->
g711aFrameLen
;
lastPts
=
gb28181Muxer
->
nextPkt
->
pts
;
gb28181Muxer
->
audioFrameCnt
++
;
audioCnt
--
;
uint16_t
pktPos
=
0
;
delete
(
audioFrame
);
uint16_t
pkt_len
=
(
uint16_t
)
(
nSizePos
+
nSize
+
audioCnt
*
(
PES_HDR_LEN
+
aFrameLen
));
// LOGE("pkt_len in muxer: %d", pkt_len);
uint8_t
*
pkt_full
=
(
uint8_t
*
)
malloc
(
pkt_len
+
2
);
memcpy
(
pkt_full
,
short2Bytes
(
pkt_len
),
2
);
pktPos
+=
2
;
memcpy
(
pkt_full
+
pktPos
,
szTempPacketHead
,
nSizePos
);
pktPos
+=
nSizePos
;
memcpy
(
pkt_full
+
pktPos
,
gb28181Muxer
->
nowPkt
->
data
,
nSize
);
pktPos
+=
nSize
;
// LOGE("orgin frame:%ld", h264_encoder->nowPkt->pts);
gb28181Muxer
->
nowPkt
->
stream_index
=
gb28181Muxer
->
video_st
->
index
;
AVPacket
*
t
=
gb28181Muxer
->
nowPkt
;
av_free_packet
(
gb28181Muxer
->
nowPkt
);
gb28181Muxer
->
nowPkt
=
gb28181Muxer
->
nextPkt
;
gb28181Muxer
->
nextPkt
=
t
;
// LOGE("now frame:%ld", h264_encoder->nowPkt->pts);
uint64_t
t4
=
getCurrentTime
();
while
(
audioCnt
>
0
)
{
uint8_t
*
audioFrame
=
*
gb28181Muxer
->
audio_queue
.
wait_and_pop
().
get
();
int64_t
audioPts
=
gb28181Muxer
->
audioFrameCnt
*
3600
;
// 音频默认25帧,90000/25=3600
gb28181_make_pes_header
(
szTempPacketHead
+
nSizePos
,
0xC0
,
aFrameLen
,
audioPts
,
audioPts
);
memcpy
(
pkt_full
+
pktPos
,
szTempPacketHead
+
nSizePos
,
PES_HDR_LEN
);
pktPos
+=
PES_HDR_LEN
;
// fout.write(szTempPacketHead + nSizePos, PES_HDR_LEN);
nSizePos
+=
PES_HDR_LEN
;
memcpy
(
pkt_full
+
pktPos
,
audioFrame
,
aFrameLen
);
pktPos
+=
aFrameLen
;
// fout.write(reinterpret_cast<char *>(audioFrame), aFrameLen);
gb28181Muxer
->
audioFrameCnt
++
;
audioCnt
--
;
delete
(
audioFrame
);
}
uint64_t
t5
=
getCurrentTime
();
gb28181Sender
->
addPkt
(
pkt_full
);
LOGI
(
"[muxer]从队列取:%lld
\t
格式转换:%lld
\t
送入编码器:%lld
\t
视频Header制作:%lld
\t
音频Header制作:%lld
\t
"
,
t1
-
start_t
,
t2
-
t1
,
t3
-
t2
,
t4
-
t3
,
t5
-
t4
)
}
}
LOGE
(
"mux over!"
);
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
gb28181library/src/main/cpp/gb28181_muxer.h
浏览文件 @
ed6a66cd
...
@@ -21,6 +21,7 @@ public:
...
@@ -21,6 +21,7 @@ public:
int
initMuxer
();
int
initMuxer
();
static
void
*
startMux
(
void
*
obj
);
static
void
*
startMux
(
void
*
obj
);
static
void
*
startEncode
(
void
*
obj
);
int
sendVideoFrame
(
uint8_t
*
buf
);
int
sendVideoFrame
(
uint8_t
*
buf
);
...
@@ -43,6 +44,7 @@ private:
...
@@ -43,6 +44,7 @@ private:
GB28181_sender
*
gb28181Sender
;
GB28181_sender
*
gb28181Sender
;
int
is_end
=
START_STATE
;
int
is_end
=
START_STATE
;
int
is_release
=
RELEASE_FALSE
;
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
;
threadsafe_queue
<
uint8_t
*>
audio_queue
;
AVFormatContext
*
pFormatCtx
;
AVFormatContext
*
pFormatCtx
;
...
@@ -61,6 +63,13 @@ private:
...
@@ -61,6 +63,13 @@ private:
int64_t
startTime
=
0
;
int64_t
startTime
=
0
;
int
in_y_size
;
int
in_y_size
;
//合成相关的参数
int
g711aFrameLen
=
0
;
int64_t
lastPts
=
0
;
int64_t
frameAppend
=
0
;
int
scrPerFrame
;
int
muxCnt
=
0
;
int
mux
(
GB28181Muxer
*
gb28181Muxer
);
int
mux
(
GB28181Muxer
*
gb28181Muxer
);
AVFrame
*
genFrame
(
uint8_t
*
rawData
);
AVFrame
*
genFrame
(
uint8_t
*
rawData
);
};
};
...
...
gb28181library/src/main/cpp/native-lib.cpp
浏览文件 @
ed6a66cd
...
@@ -32,7 +32,7 @@ Java_com_autulin_gb28181library_JNIBridge_initMuxer(JNIEnv *env, jclass type, js
...
@@ -32,7 +32,7 @@ Java_com_autulin_gb28181library_JNIBridge_initMuxer(JNIEnv *env, jclass type, js
jstring
mediaBasePath_
,
jstring
mediaName_
,
jstring
mediaBasePath_
,
jstring
mediaName_
,
jint
filter
,
jint
in_width
,
jint
in_height
,
jint
filter
,
jint
in_width
,
jint
in_height
,
jint
out_width
,
jint
out_height
,
jint
frameRate
,
jint
out_width
,
jint
out_height
,
jint
frameRate
,
jlong
bit_rate
,
jint
audioFrameLen
)
{
jlong
bit_rate
,
jint
audioFrameLen
,
jint
ssrc
)
{
const
char
*
ip
=
env
->
GetStringUTFChars
(
ip_
,
0
);
const
char
*
ip
=
env
->
GetStringUTFChars
(
ip_
,
0
);
const
char
*
mediaBasePath
=
env
->
GetStringUTFChars
(
mediaBasePath_
,
0
);
const
char
*
mediaBasePath
=
env
->
GetStringUTFChars
(
mediaBasePath_
,
0
);
const
char
*
mediaName
=
env
->
GetStringUTFChars
(
mediaName_
,
0
);
const
char
*
mediaName
=
env
->
GetStringUTFChars
(
mediaName_
,
0
);
...
@@ -44,8 +44,7 @@ Java_com_autulin_gb28181library_JNIBridge_initMuxer(JNIEnv *env, jclass type, js
...
@@ -44,8 +44,7 @@ Java_com_autulin_gb28181library_JNIBridge_initMuxer(JNIEnv *env, jclass type, js
strcpy
(
arguments
->
ip_addr
,
ip
);
strcpy
(
arguments
->
ip_addr
,
ip
);
arguments
->
port
=
port
;
arguments
->
port
=
port
;
arguments
->
outType
=
outType
;
arguments
->
outType
=
outType
;
arguments
->
media_base_path
=
mediaBasePath
;
arguments
->
ssrc
=
ssrc
;
arguments
->
media_name
=
mediaName
;
size_t
m_path_size
=
strlen
(
mediaBasePath
)
+
strlen
(
mediaName
)
+
strlen
(
MEDIA_FORMAT
)
+
1
;
size_t
m_path_size
=
strlen
(
mediaBasePath
)
+
strlen
(
mediaName
)
+
strlen
(
MEDIA_FORMAT
)
+
1
;
arguments
->
media_path
=
(
char
*
)
malloc
(
m_path_size
+
1
);
arguments
->
media_path
=
(
char
*
)
malloc
(
m_path_size
+
1
);
...
...
gb28181library/src/main/cpp/user_arguments.h
浏览文件 @
ed6a66cd
...
@@ -9,8 +9,6 @@ typedef struct UserArguments {
...
@@ -9,8 +9,6 @@ typedef struct UserArguments {
char
*
ip_addr
;
char
*
ip_addr
;
int
port
;
int
port
;
int
outType
;
int
outType
;
const
char
*
media_base_path
;
//文件储存地址
const
char
*
media_name
;
// 文件命令前缀
char
*
media_path
;
//合成后的MP4储存地址
char
*
media_path
;
//合成后的MP4储存地址
int
in_width
;
//输出宽度
int
in_width
;
//输出宽度
int
in_height
;
//输入高度
int
in_height
;
//输入高度
...
@@ -20,6 +18,7 @@ typedef struct UserArguments {
...
@@ -20,6 +18,7 @@ typedef struct UserArguments {
int64_t
video_bit_rate
;
//视频比特率控制
int64_t
video_bit_rate
;
//视频比特率控制
int
v_custom_format
;
//一些滤镜操作控制
int
v_custom_format
;
//一些滤镜操作控制
int
a_frame_len
;
int
a_frame_len
;
int
ssrc
;
JNIEnv
*
env
;
//env全局指针
JNIEnv
*
env
;
//env全局指针
JavaVM
*
javaVM
;
//jvm指针
JavaVM
*
javaVM
;
//jvm指针
jclass
java_class
;
//java接口类的calss对象
jclass
java_class
;
//java接口类的calss对象
...
...
gb28181library/src/main/java/com/autulin/gb28181library/DemoActivity.java
浏览文件 @
ed6a66cd
...
@@ -119,8 +119,9 @@ public class DemoActivity extends AppCompatActivity implements
...
@@ -119,8 +119,9 @@ public class DemoActivity extends AppCompatActivity implements
// 设置输出
// 设置输出
// String fileName = String.valueOf(System.currentTimeMillis());
// String fileName = String.valueOf(System.currentTimeMillis());
String
fileName
=
"tttttt"
;
String
fileName
=
"tttttt"
;
// mediaOutput = mMediaRecorder.setFileOutPut(fileName); //输出到文件,这里demo是/sdcard/DCIM/pstest/tttttt.ps
mediaOutput
=
mMediaRecorder
.
setFileOutPut
(
fileName
);
//输出到文件,这里demo是/sdcard/DCIM/pstest/tttttt.ps
mediaOutput
=
mMediaRecorder
.
setUdpOutPut
(
"10.112.181.160"
,
8888
);
// int ssrc = 1;
// mediaOutput = mMediaRecorder.setUdpOutPut("10.112.181.160", 8888, ssrc);
mMediaRecorder
.
setSurfaceHolder
(
mSurfaceView
.
getHolder
());
mMediaRecorder
.
setSurfaceHolder
(
mSurfaceView
.
getHolder
());
mMediaRecorder
.
prepare
();
mMediaRecorder
.
prepare
();
...
...
gb28181library/src/main/java/com/autulin/gb28181library/JNIBridge.java
浏览文件 @
ed6a66cd
...
@@ -64,7 +64,8 @@ public class JNIBridge {
...
@@ -64,7 +64,8 @@ public class JNIBridge {
int
out_height
,
int
out_height
,
int
frameRate
,
int
frameRate
,
long
bit_rate
,
long
bit_rate
,
int
audioFrameLen
int
audioFrameLen
,
int
ssrc
);
);
public
static
native
int
sendOneVideoFrame
(
byte
[]
data
);
public
static
native
int
sendOneVideoFrame
(
byte
[]
data
);
...
...
gb28181library/src/main/java/com/autulin/gb28181library/MediaOutput.java
浏览文件 @
ed6a66cd
...
@@ -6,13 +6,15 @@ public class MediaOutput {
...
@@ -6,13 +6,15 @@ public class MediaOutput {
private
String
outputDir
;
private
String
outputDir
;
private
String
outputName
;
private
String
outputName
;
private
int
outputType
;
private
int
outputType
;
private
int
ssrc
;
public
MediaOutput
(
String
ip
,
int
port
,
String
outputDir
,
String
outputName
,
int
outputType
)
{
public
MediaOutput
(
String
ip
,
int
port
,
String
outputDir
,
String
outputName
,
int
outputType
,
int
ssrc
)
{
this
.
ip
=
ip
;
this
.
ip
=
ip
;
this
.
port
=
port
;
this
.
port
=
port
;
this
.
outputDir
=
outputDir
;
this
.
outputDir
=
outputDir
;
this
.
outputName
=
outputName
;
this
.
outputName
=
outputName
;
this
.
outputType
=
outputType
;
this
.
outputType
=
outputType
;
this
.
ssrc
=
ssrc
;
}
}
public
String
getIp
()
{
public
String
getIp
()
{
...
@@ -54,4 +56,12 @@ public class MediaOutput {
...
@@ -54,4 +56,12 @@ public class MediaOutput {
public
void
setOutputType
(
int
outputType
)
{
public
void
setOutputType
(
int
outputType
)
{
this
.
outputType
=
outputType
;
this
.
outputType
=
outputType
;
}
}
public
int
getSsrc
()
{
return
ssrc
;
}
public
void
setSsrc
(
int
ssrc
)
{
this
.
ssrc
=
ssrc
;
}
}
}
gb28181library/src/main/java/com/autulin/gb28181library/MediaRecorderBase.java
浏览文件 @
ed6a66cd
...
@@ -712,13 +712,13 @@ public abstract class MediaRecorderBase implements Callback, PreviewCallback, IM
...
@@ -712,13 +712,13 @@ public abstract class MediaRecorderBase implements Callback, PreviewCallback, IM
this
.
mFrameRateCmd
=
String
.
format
(
" -r %d"
,
rate
);
this
.
mFrameRateCmd
=
String
.
format
(
" -r %d"
,
rate
);
}
}
public
MediaOutput
setTcpOutPut
(
String
ip
,
int
port
)
{
public
MediaOutput
setTcpOutPut
(
String
ip
,
int
port
,
int
ssrc
)
{
mediaOutput
=
new
MediaOutput
(
ip
,
port
,
""
,
""
,
JNIBridge
.
TCP
);
mediaOutput
=
new
MediaOutput
(
ip
,
port
,
""
,
""
,
JNIBridge
.
TCP
,
ssrc
);
return
mediaOutput
;
return
mediaOutput
;
}
}
public
MediaOutput
setUdpOutPut
(
String
ip
,
int
port
)
{
public
MediaOutput
setUdpOutPut
(
String
ip
,
int
port
,
int
ssrc
)
{
mediaOutput
=
new
MediaOutput
(
ip
,
port
,
""
,
""
,
JNIBridge
.
UDP
);
mediaOutput
=
new
MediaOutput
(
ip
,
port
,
""
,
""
,
JNIBridge
.
UDP
,
ssrc
);
return
mediaOutput
;
return
mediaOutput
;
}
}
...
@@ -741,7 +741,7 @@ public abstract class MediaRecorderBase implements Callback, PreviewCallback, IM
...
@@ -741,7 +741,7 @@ public abstract class MediaRecorderBase implements Callback, PreviewCallback, IM
if
(!
file
.
exists
())
{
if
(!
file
.
exists
())
{
file
.
mkdirs
();
file
.
mkdirs
();
}
}
mediaOutput
=
new
MediaOutput
(
""
,
0
,
path
,
fileName
,
JNIBridge
.
FILE
);
mediaOutput
=
new
MediaOutput
(
""
,
0
,
path
,
fileName
,
JNIBridge
.
FILE
,
0
);
return
mediaOutput
;
return
mediaOutput
;
}
}
}
}
gb28181library/src/main/java/com/autulin/gb28181library/MediaRecorderNative.java
浏览文件 @
ed6a66cd
...
@@ -16,12 +16,16 @@ public class MediaRecorderNative extends MediaRecorderBase implements MediaRecor
...
@@ -16,12 +16,16 @@ public class MediaRecorderNative extends MediaRecorderBase implements MediaRecor
JNIBridge
.
endMux
();
JNIBridge
.
endMux
();
}
}
long
t
=
System
.
currentTimeMillis
();
/**
/**
* 视频数据回调
* 视频数据回调
*/
*/
@Override
@Override
public
void
onPreviewFrame
(
byte
[]
data
,
Camera
camera
)
{
public
void
onPreviewFrame
(
byte
[]
data
,
Camera
camera
)
{
if
(
mRecording
)
{
if
(
mRecording
)
{
long
nt
=
System
.
currentTimeMillis
();
Log
.
e
(
"now"
,
"onPreviewFrame: "
+
nt
+
", div:"
+
(
nt
-
t
));
t
=
nt
;
JNIBridge
.
sendOneVideoFrame
(
data
);
JNIBridge
.
sendOneVideoFrame
(
data
);
mPreviewFrameCallCount
++;
mPreviewFrameCallCount
++;
}
}
...
@@ -81,7 +85,8 @@ public class MediaRecorderNative extends MediaRecorderBase implements MediaRecor
...
@@ -81,7 +85,8 @@ public class MediaRecorderNative extends MediaRecorderBase implements MediaRecor
SMALL_VIDEO_HEIGHT
,
SMALL_VIDEO_HEIGHT
,
mFrameRate
,
mFrameRate
,
mVideoBitrate
,
mVideoBitrate
,
mAudioCollector
.
getFrameLen
()
mAudioCollector
.
getFrameLen
(),
mediaOutput
.
getSsrc
()
);
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论