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
589587a8
提交
589587a8
authored
9月 13, 2018
作者:
autulin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
将数据包合并发送到sender的队列中,由sender来进行发送操作
TODO:网络发送的具体实现
上级
83c6bb23
隐藏空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
195 行增加
和
63 行删除
+195
-63
CMakeLists.txt
gb28181library/CMakeLists.txt
+1
-0
GB28181_sender.cpp
gb28181library/src/main/cpp/GB28181_sender.cpp
+88
-0
GB28181_sender.h
gb28181library/src/main/cpp/GB28181_sender.h
+40
-0
base_include.h
gb28181library/src/main/cpp/base_include.h
+20
-0
gb28181_muxer.cpp
gb28181library/src/main/cpp/gb28181_muxer.cpp
+32
-47
gb28181_muxer.h
gb28181library/src/main/cpp/gb28181_muxer.h
+2
-4
native-lib.cpp
gb28181library/src/main/cpp/native-lib.cpp
+2
-1
user_arguments.h
gb28181library/src/main/cpp/user_arguments.h
+1
-1
DemoActivity.java
...rc/main/java/com/autulin/gb28181library/DemoActivity.java
+2
-0
activity_demo.xml
gb28181library/src/main/res/layout/activity_demo.xml
+7
-10
没有找到文件。
gb28181library/CMakeLists.txt
浏览文件 @
589587a8
...
...
@@ -20,6 +20,7 @@ add_library( # Sets the name of the library.
src/main/cpp/native-lib.cpp
src/main/cpp/gb28181_muxer.cpp
src/main/cpp/gb28181_sender.cpp
src/main/cpp/threadsafe_queue.cpp
)
...
...
gb28181library/src/main/cpp/GB28181_sender.cpp
0 → 100644
浏览文件 @
589587a8
//
// Created by autulin on 2018/9/13.
//
#include "GB28181_sender.h"
GB28181_sender
::
GB28181_sender
(
UserArguments
*
arg
)
:
args
(
arg
)
{}
int
GB28181_sender
::
initSender
()
{
switch
(
args
->
outType
)
{
case
0
:
// udp
LOGE
(
"ip:%s, port:%d"
,
args
->
ip_addr
,
args
->
port
);
break
;
case
1
:
// tcp
LOGE
(
"ip:%s, port:%d"
,
args
->
ip_addr
,
args
->
port
);
break
;
case
2
:
// file
//打开ps文件
LOGE
(
"media path: %s"
,
args
->
media_path
);
fout
.
open
(
args
->
media_path
,
ios
::
binary
);
break
;
default
:
break
;
}
isRuning
=
RUNING
;
pthread_t
thread
;
pthread_create
(
&
thread
,
NULL
,
GB28181_sender
::
processSend
,
this
);
LOGI
(
"发送器初始化完成"
)
return
0
;
}
int
GB28181_sender
::
addPkt
(
uint8_t
*
pkt
)
{
pkt_queue
.
push
(
pkt
);
return
0
;
}
void
*
GB28181_sender
::
processSend
(
void
*
obj
)
{
GB28181_sender
*
gb28181Sender
=
(
GB28181_sender
*
)
obj
;
while
(
gb28181Sender
->
isRuning
)
{
uint8_t
*
pkt_buf
=
*
gb28181Sender
->
pkt_queue
.
wait_and_pop
().
get
();
uint16_t
len
=
bytes2short
(
pkt_buf
);
LOGE
(
"get pkt len: %d"
,
len
);
switch
(
gb28181Sender
->
args
->
outType
)
{
case
0
:
// udp
break
;
case
1
:
// tcp
break
;
case
2
:
// file
gb28181Sender
->
fout
.
write
((
const
char
*
)
(
pkt_buf
+
2
),
len
);
break
;
default
:
break
;
}
delete
(
pkt_buf
);
}
LOGI
(
"发送结束"
);
gb28181Sender
->
closeSender
();
return
nullptr
;
}
int
GB28181_sender
::
sendCloseSignal
()
{
isRuning
=
STOPED
;
return
0
;
}
int
GB28181_sender
::
closeSender
()
{
if
(
stoped
)
{
return
0
;
}
else
{
stoped
=
1
;
}
switch
(
args
->
outType
)
{
case
0
:
// udp
break
;
case
1
:
// tcp
break
;
case
2
:
// file
fout
.
close
();
break
;
default
:
break
;
}
return
0
;
}
gb28181library/src/main/cpp/GB28181_sender.h
0 → 100644
浏览文件 @
589587a8
//
// Created by autulin on 2018/9/13.
//
#ifndef GB28181ANDROID_GB28181_SENDER_H
#define GB28181ANDROID_GB28181_SENDER_H
#include <fstream>
#include "base_include.h"
#include "user_arguments.h"
#define RUNING 1
#define STOPED 0
class
GB28181_sender
{
public
:
GB28181_sender
(
UserArguments
*
arg
);
static
void
*
processSend
(
void
*
obj
);
int
initSender
();
int
addPkt
(
uint8_t
*
pkt
);
int
sendCloseSignal
();
int
closeSender
();
private
:
UserArguments
*
args
;
ofstream
fout
;
threadsafe_queue
<
uint8_t
*>
pkt_queue
;
int
isRuning
;
volatile
int
stoped
;
};
#endif //GB28181ANDROID_GB28181_SENDER_H
gb28181library/src/main/cpp/base_include.h
浏览文件 @
589587a8
...
...
@@ -57,4 +57,24 @@ static uint64_t bytes2long(uint8_t b[]) {
return
res
;
}
static
uint16_t
bytes2short
(
uint8_t
b
[])
{
uint16_t
temp
=
0
;
uint16_t
res
=
0
;
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
res
<<=
8
;
temp
=
b
[
i
];
temp
=
(
uint16_t
)
(
temp
&
0xff
);
res
|=
temp
;
}
return
res
;
}
static
uint8_t
*
short2Bytes
(
uint16_t
i
)
{
uint16_t
temp
=
i
;
uint8_t
*
bytes
=
(
uint8_t
*
)
malloc
(
2
);
bytes
[
1
]
=
(
uint8_t
)
(
temp
&
0xff
);
temp
>>=
8
;
bytes
[
0
]
=
(
uint8_t
)
(
temp
&
0xff
);
return
bytes
;
}
#endif //BASE_INCLUDE_H
gb28181library/src/main/cpp/gb28181_muxer.cpp
浏览文件 @
589587a8
...
...
@@ -17,9 +17,6 @@ GB28181Muxer::GB28181Muxer(UserArguments *arg) : arguments(arg) {
int
GB28181Muxer
::
initMuxer
()
{
LOGI
(
"视频编码器初始化开始"
);
if
(
arguments
->
outType
<
2
)
LOGE
(
"ip:%s, port:%d"
,
arguments
->
ip_addr
,
arguments
->
port
);
av_register_all
();
pFormatCtx
=
avformat_alloc_context
();
...
...
@@ -98,7 +95,8 @@ int GB28181Muxer::initMuxer() {
return
-
1
;
}
initOutput
();
gb28181Sender
=
new
GB28181_sender
(
arguments
);
gb28181Sender
->
initSender
();
pFrame
=
av_frame_alloc
();
picture_size
=
avpicture_get_size
(
pCodecCtx
->
pix_fmt
,
pCodecCtx
->
width
,
pCodecCtx
->
height
);
...
...
@@ -178,7 +176,8 @@ void *GB28181Muxer::startMux(void *obj) {
int64_t
lastPTS
=
gb28181Muxer
->
pFrame
->
pts
;
if
(
gb28181Muxer
->
startTime
==
0
)
gb28181Muxer
->
startTime
=
v_time
;
gb28181Muxer
->
pFrame
->
pts
=
(
v_time
-
gb28181Muxer
->
startTime
)
*
90
;
LOGE
(
"v_time:%lld,startTime: %lld, now:%lld, lastPTS: %lld, new PTS: %lld, divid: %lld"
,
v_time
,
LOGE
(
"v_time:%lld,startTime: %lld, now:%lld, lastPTS: %lld, new PTS: %lld, divid: %lld"
,
v_time
,
gb28181Muxer
->
startTime
,
getCurrentTime
(),
lastPTS
,
gb28181Muxer
->
pFrame
->
pts
,
gb28181Muxer
->
pFrame
->
pts
-
lastPTS
);
gb28181Muxer
->
videoFrameCnt
++
;
...
...
@@ -321,9 +320,10 @@ GB28181Muxer::custom_filter(const GB28181Muxer *gb28181Muxer, const uint8_t *pic
*/
int
GB28181Muxer
::
endMux
()
{
LOGE
(
"endMux"
);
closeOutput
();
gb28181Sender
->
sendCloseSignal
();
LOGE
(
"aduio queue left num: %d, video queue left num: %d"
,
audio_queue
.
size
(),
video_queue
.
size
());
LOGE
(
"aduio queue left num: %d, video queue left num: %d"
,
audio_queue
.
size
(),
video_queue
.
size
());
audio_queue
.
clear
();
video_queue
.
clear
();
...
...
@@ -336,6 +336,7 @@ int GB28181Muxer::endMux() {
// avio_close(pFormatCtx->pb);
avformat_free_context
(
pFormatCtx
);
LOGI
(
"视频编码结束"
)
// gb28181Sender->closeSender(); //再发一次防止之前没关掉
return
1
;
}
...
...
@@ -352,6 +353,7 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
gb28181Muxer
->
nowPkt
=
&
gb28181Muxer
->
pkt
;
int64_t
append
=
0
;
int
cnt
=
0
;
int
aFrameLen
=
gb28181Muxer
->
arguments
->
a_frame_len
/
2
;
while
(
!
gb28181Muxer
->
is_end
)
{
char
szTempPacketHead
[
256
];
int
nSizePos
=
0
;
...
...
@@ -364,10 +366,10 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
int
in_y_size
=
gb28181Muxer
->
arguments
->
in_width
*
gb28181Muxer
->
arguments
->
in_height
;
gb28181Muxer
->
custom_filter
(
gb28181Muxer
,
picture_buf
+
8
,
in_y_size
,
gb28181Muxer
->
arguments
->
v_custom_format
);
delete
(
picture_buf
);
delete
(
picture_buf
);
gb28181Muxer
->
pFrame
->
pts
=
(
v_time
-
gb28181Muxer
->
startTime
)
*
90
;
LOGE
(
"v_time: %lld, get a pts:%lld (aduio queue left num: %d, video queue left num: %d)"
,
v_time
,
gb28181Muxer
->
pFrame
->
pts
,
audio_queue
.
size
(),
video_queue
.
size
());
LOGE
(
"v_time: %lld, get a pts:%lld (aduio queue left num: %d, video queue left num: %d)"
,
v_time
,
gb28181Muxer
->
pFrame
->
pts
,
audio_queue
.
size
(),
video_queue
.
size
());
int
got_picture
;
int
ret
=
avcodec_encode_video2
(
gb28181Muxer
->
pCodecCtx
,
gb28181Muxer
->
nextPkt
,
...
...
@@ -406,10 +408,21 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
// video psm
gb28181_make_pes_header
(
szTempPacketHead
+
nSizePos
,
0xE0
,
nSize
,
lastPts
,
lastPts
);
nSizePos
+=
PES_HDR_LEN
;
gb28181Muxer
->
fout
.
write
(
szTempPacketHead
,
nSizePos
);
gb28181Muxer
->
fout
.
write
(
reinterpret_cast
<
const
char
*>
(
gb28181Muxer
->
nowPkt
->
data
),
nSize
);
//
gb28181Muxer->fout.write(szTempPacketHead, nSizePos);
//
gb28181Muxer->fout.write(reinterpret_cast<const char *>(gb28181Muxer->nowPkt->data), nSize);
lastPts
=
gb28181Muxer
->
nextPkt
->
pts
;
uint16_t
pktPos
=
0
;
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
;
...
...
@@ -421,48 +434,21 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
while
(
audioCnt
>
0
)
{
uint8_t
*
audioFrame
=
*
gb28181Muxer
->
audio_queue
.
wait_and_pop
().
get
();
int64_t
audioPts
=
gb28181Muxer
->
audioFrameCnt
*
3600
;
// 音频默认25帧,90000/25=3600
int
aFrameLen
=
gb28181Muxer
->
arguments
->
a_frame_len
/
2
;
gb28181_make_pes_header
(
szTempPacketHead
+
nSizePos
,
0xC0
,
aFrameLen
,
audioPts
,
audioPts
);
fout
.
write
(
szTempPacketHead
+
nSizePos
,
PES_HDR_LEN
);
memcpy
(
pkt_full
+
pktPos
,
szTempPacketHead
+
nSizePos
,
PES_HDR_LEN
);
pktPos
+=
PES_HDR_LEN
;
// fout.write(szTempPacketHead + nSizePos, PES_HDR_LEN);
nSizePos
+=
PES_HDR_LEN
;
fout
.
write
(
reinterpret_cast
<
char
*>
(
audioFrame
),
aFrameLen
);
memcpy
(
pkt_full
+
pktPos
,
audioFrame
,
aFrameLen
);
pktPos
+=
aFrameLen
;
// fout.write(reinterpret_cast<char *>(audioFrame), aFrameLen);
gb28181Muxer
->
audioFrameCnt
++
;
audioCnt
--
;
delete
(
audioFrame
);
}
gb28181Sender
->
addPkt
(
pkt_full
);
}
LOGE
(
"mux over!"
);
return
0
;
}
void
GB28181Muxer
::
initOutput
()
{
switch
(
arguments
->
outType
)
{
case
0
:
// udp
break
;
case
1
:
// tcp
break
;
case
2
:
// file
//打开ps文件
LOGE
(
"media path: %s"
,
arguments
->
media_path
);
fout
.
open
(
arguments
->
media_path
,
ios
::
binary
);
break
;
default
:
break
;
}
}
void
GB28181Muxer
::
closeOutput
()
{
switch
(
arguments
->
outType
)
{
case
0
:
// udp
break
;
case
1
:
// tcp
break
;
case
2
:
// file
fout
.
close
();
break
;
default
:
break
;
}
}
\ No newline at end of file
gb28181library/src/main/cpp/gb28181_muxer.h
浏览文件 @
589587a8
...
...
@@ -8,6 +8,7 @@
#include "base_include.h"
#include "user_arguments.h"
#include "GB28181_sender.h"
#include <sys/time.h>
...
...
@@ -40,6 +41,7 @@ private:
private
:
UserArguments
*
arguments
;
GB28181_sender
*
gb28181Sender
;
int
is_end
=
START_STATE
;
int
is_release
=
RELEASE_FALSE
;
threadsafe_queue
<
uint8_t
*>
video_queue
;
...
...
@@ -60,12 +62,8 @@ private:
int
videoFrameCnt
=
0
;
int64_t
startTime
=
0
;
ofstream
fout
;
int
mux
(
GB28181Muxer
*
gb28181Muxer
);
void
initOutput
();
void
closeOutput
();
};
#endif //GB281818_MUXER_H
gb28181library/src/main/cpp/native-lib.cpp
浏览文件 @
589587a8
...
...
@@ -40,7 +40,8 @@ Java_com_autulin_gb28181library_JNIBridge_initMuxer(JNIEnv *env, jclass type, js
jclass
global_class
=
(
jclass
)
env
->
NewGlobalRef
(
type
);
UserArguments
*
arguments
=
(
UserArguments
*
)
malloc
(
sizeof
(
UserArguments
));
arguments
->
ip_addr
=
ip
;
arguments
->
ip_addr
=
(
char
*
)
malloc
(
strlen
(
ip
)
+
1
);
strcpy
(
arguments
->
ip_addr
,
ip
);
arguments
->
port
=
port
;
arguments
->
outType
=
outType
;
arguments
->
media_base_path
=
mediaBasePath
;
...
...
gb28181library/src/main/cpp/user_arguments.h
浏览文件 @
589587a8
...
...
@@ -6,7 +6,7 @@
#include "jni.h"
class
JNIHandler
;
typedef
struct
UserArguments
{
c
onst
c
har
*
ip_addr
;
char
*
ip_addr
;
int
port
;
int
outType
;
const
char
*
media_base_path
;
//文件储存地址
...
...
gb28181library/src/main/java/com/autulin/gb28181library/DemoActivity.java
浏览文件 @
589587a8
...
...
@@ -69,6 +69,7 @@ public class DemoActivity extends AppCompatActivity implements
// MediaRecorderBase.SMALL_VIDEO_HEIGHT = mediaRecorderConfig.getSmallVideoHeight();
// MediaRecorderBase.SMALL_VIDEO_WIDTH = mediaRecorderConfig.getSmallVideoWidth();
// MediaRecorderBase.mVideoBitrate = mediaRecorderConfig.getVideoBitrate();
Log
.
i
(
"debug"
,
"SMALL_VIDEO_HEIGHT: "
+
MediaRecorderBase
.
SMALL_VIDEO_HEIGHT
+
", SMALL_VIDEO_WIDTH:"
+
MediaRecorderBase
.
SMALL_VIDEO_WIDTH
);
}
private
void
initView
()
{
...
...
@@ -89,6 +90,7 @@ public class DemoActivity extends AppCompatActivity implements
// String fileName = String.valueOf(System.currentTimeMillis());
String
fileName
=
"tttttt"
;
mediaOutput
=
mMediaRecorder
.
setFileOutPut
(
fileName
);
// mediaOutput = mMediaRecorder.setUdpOutPut("10.112.181.160", 8888);
mMediaRecorder
.
setSurfaceHolder
(
mSurfaceView
.
getHolder
());
mMediaRecorder
.
prepare
();
...
...
gb28181library/src/main/res/layout/activity_demo.xml
浏览文件 @
589587a8
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
<RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
tools:context=
".DemoActivity"
>
>
<FrameLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
...
...
@@ -24,8 +22,7 @@
android:layout_marginLeft=
"8dp"
android:layout_marginRight=
"8dp"
android:layout_marginStart=
"8dp"
android:text=
"开始录制"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
android:layout_alignParentBottom=
"true"
android:layout_centerInParent=
"true"
android:text=
"开始录制"
/>
</RelativeLayout>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论