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
83c6bb23
提交
83c6bb23
authored
9月 13, 2018
作者:
autulin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
1.适配32位机型
2.停止录制优化 todo:视频大小控制
上级
2652cbf3
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
83 行增加
和
78 行删除
+83
-78
base_include.h
gb28181library/src/main/cpp/base_include.h
+8
-6
gb28181_header_maker.c
gb28181library/src/main/cpp/gb28181_header_maker.c
+4
-4
gb28181_muxer.cpp
gb28181library/src/main/cpp/gb28181_muxer.cpp
+36
-38
gb28181_muxer.h
gb28181library/src/main/cpp/gb28181_muxer.h
+2
-4
native-lib.cpp
gb28181library/src/main/cpp/native-lib.cpp
+1
-15
user_arguments.h
gb28181library/src/main/cpp/user_arguments.h
+2
-2
DemoActivity.java
...rc/main/java/com/autulin/gb28181library/DemoActivity.java
+2
-1
JNIBridge.java
...y/src/main/java/com/autulin/gb28181library/JNIBridge.java
+0
-2
MediaRecorderBase.java
...in/java/com/autulin/gb28181library/MediaRecorderBase.java
+16
-1
libfdk-aac.so
gb28181library/src/main/jniLibs/armeabi-v7a/libfdk-aac.so
+0
-0
gradle.properties
gradle.properties
+12
-5
没有找到文件。
gb28181library/src/main/cpp/base_include.h
浏览文件 @
83c6bb23
...
...
@@ -10,6 +10,7 @@ extern "C"
}
#include "threadsafe_queue.cpp"
#include "log.h"
#include <jni.h>
#include <string>
...
...
@@ -37,19 +38,20 @@ extern "C"
using
namespace
std
;
static
long
getCurrentTime
()
{
static
uint64_t
getCurrentTime
()
{
struct
timeval
tv
;
gettimeofday
(
&
tv
,
NULL
);
return
tv
.
tv_sec
*
1000
+
tv
.
tv_usec
/
1000
;
return
(
int64_t
)
tv
.
tv_sec
*
1000
+
tv
.
tv_usec
/
1000
;
}
static
long
bytes2long
(
char
b
[])
{
long
temp
=
0
;
long
res
=
0
;
static
uint64_t
bytes2long
(
uint8_t
b
[])
{
uint64_t
temp
=
0
;
uint64_t
res
=
0
;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
{
res
<<=
8
;
temp
=
b
[
i
]
&
0xff
;
temp
=
b
[
i
];
temp
=
temp
&
0xff
;
res
|=
temp
;
}
return
res
;
...
...
gb28181library/src/main/cpp/gb28181_header_maker.c
浏览文件 @
83c6bb23
...
...
@@ -17,9 +17,9 @@
* s64Src [in] 时间戳
*@return: 0 success, others failed
*/
int
gb28181_make_ps_header
(
char
*
pData
,
unsigned
long
long
s64Scr
)
int
gb28181_make_ps_header
(
char
*
pData
,
int64_t
s64Scr
)
{
unsigned
long
long
lScrExt
=
0
;
//(s64Scr) % 100;
int64_t
lScrExt
=
0
;
//(s64Scr) % 100;
// s64Scr = s64Scr * 3600; // / 100; // 90000/fps
// 这里除以100是由于sdp协议返回的video的频率是90000,帧率是25帧/s,所以每次递增的量是3600,
// 所以实际你应该根据你自己编码里的时间戳来处理以保证时间戳的增量为3600即可,
...
...
@@ -141,7 +141,7 @@ int gb28181_make_psm_header(char *pData)
* dts [in]
*@return: 0 success, others failed
*/
int
gb28181_make_pes_header
(
char
*
pData
,
int
stream_id
,
int
payload_len
,
unsigned
long
long
pts
,
unsigned
long
long
dts
)
int
gb28181_make_pes_header
(
char
*
pData
,
int
stream_id
,
int
payload_len
,
int64_t
pts
,
int64_t
dts
)
{
bits_buffer_t
bitsBuffer
;
...
...
@@ -196,7 +196,7 @@ int gb28181_make_pes_header(char *pData, int stream_id, int payload_len, unsigne
*@param : pData [in] 填充ps头数据的地址
*@return: 0 success, others failed
*/
int
gb28181_make_rtp_header
(
char
*
pData
,
int
seqNum
,
unsigned
long
long
timestamp
,
int
ssrc
)
int
gb28181_make_rtp_header
(
char
*
pData
,
int
seqNum
,
int64_t
timestamp
,
int
ssrc
)
{
bits_buffer_t
bitsBuffer
;
...
...
gb28181library/src/main/cpp/gb28181_muxer.cpp
浏览文件 @
83c6bb23
...
...
@@ -47,13 +47,25 @@ int GB28181Muxer::initMuxer() {
pCodecCtx
->
height
=
arguments
->
out_width
;
}
LOGI
(
"in height: %d, in width: %d.
\n
out height: %d, out width: %d.
\n
context height: %d, context width: %d
\n
video bitrate:%lld, video framerate:%d,
\n
custom_format %d"
,
arguments
->
in_height
,
arguments
->
in_width
,
arguments
->
out_height
,
arguments
->
out_width
,
pCodecCtx
->
height
,
pCodecCtx
->
width
,
arguments
->
video_bit_rate
,
arguments
->
video_frame_rate
,
arguments
->
v_custom_format
)
pCodecCtx
->
bit_rate
=
arguments
->
video_bit_rate
;
//这里是设置关键帧的间隔
pCodecCtx
->
gop_size
=
25
;
pCodecCtx
->
thread_count
=
12
;
pCodecCtx
->
time_base
.
num
=
1
;
pCodecCtx
->
time_base
.
den
=
arguments
->
frame_rate
;
pCodecCtx
->
time_base
.
den
=
arguments
->
video_
frame_rate
;
// pCodecCtx->me_pre_cmp = 1;
//H264
//pCodecCtx->me_range = 16;
...
...
@@ -149,35 +161,25 @@ int GB28181Muxer::sendAudioFrame(uint8_t *buf) {
void
*
GB28181Muxer
::
startMux
(
void
*
obj
)
{
LOGE
(
"start mux thread"
);
GB28181Muxer
*
gb28181Muxer
=
(
GB28181Muxer
*
)
obj
;
while
(
!
gb28181Muxer
->
is_end
||
!
gb28181Muxer
->
video_queue
.
empty
())
{
if
(
gb28181Muxer
->
is_release
)
{
LOGE
(
"release data"
)
//Clean
if
(
gb28181Muxer
->
video_st
)
{
avcodec_close
(
gb28181Muxer
->
video_st
->
codec
);
av_free
(
gb28181Muxer
->
pFrame
);
}
avformat_free_context
(
gb28181Muxer
->
pFormatCtx
);
delete
gb28181Muxer
;
return
0
;
}
while
(
!
gb28181Muxer
->
is_end
)
{
if
(
gb28181Muxer
->
video_queue
.
empty
())
{
continue
;
}
uint8_t
*
picture_buf
=
*
gb28181Muxer
->
video_queue
.
wait_and_pop
().
get
();
long
v_time
=
bytes2long
(
reinterpret_cast
<
char
*>
(
picture_buf
)
);
int64_t
v_time
=
bytes2long
(
picture_buf
);
int
in_y_size
=
gb28181Muxer
->
arguments
->
in_width
*
gb28181Muxer
->
arguments
->
in_height
;
// 处理视频帧并到 h264_encoder->pFrame 中
gb28181Muxer
->
custom_filter
(
gb28181Muxer
,
picture_buf
+
8
,
in_y_size
,
gb28181Muxer
->
arguments
->
v_custom_format
);
delete
(
picture_buf
);
long
lastPTS
=
gb28181Muxer
->
pFrame
->
pts
;
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:%l
d, now:%ld, lastPTS: %ld, new PTS: %ld, divid: %
ld"
,
v_time
,
getCurrentTime
(),
lastPTS
,
gb28181Muxer
->
pFrame
->
pts
,
LOGE
(
"v_time:%l
ld,startTime: %lld, now:%lld, lastPTS: %lld, new PTS: %lld, divid: %l
ld"
,
v_time
,
g
b28181Muxer
->
startTime
,
g
etCurrentTime
(),
lastPTS
,
gb28181Muxer
->
pFrame
->
pts
,
gb28181Muxer
->
pFrame
->
pts
-
lastPTS
);
gb28181Muxer
->
videoFrameCnt
++
;
int
got_picture
=
0
;
...
...
@@ -192,10 +194,9 @@ void *GB28181Muxer::startMux(void *obj) {
if
(
got_picture
==
1
)
{
gb28181Muxer
->
mux
(
gb28181Muxer
);
}
delete
(
picture_buf
);
}
if
(
gb28181Muxer
->
is_end
)
{
gb28181Muxer
->
en
codeEnd
();
gb28181Muxer
->
en
dMux
();
delete
gb28181Muxer
;
}
return
0
;
...
...
@@ -318,8 +319,8 @@ GB28181Muxer::custom_filter(const GB28181Muxer *gb28181Muxer, const uint8_t *pic
* 视频编码结束
* @return
*/
int
GB28181Muxer
::
en
codeEnd
()
{
int
GB28181Muxer
::
en
dMux
()
{
LOGE
(
"endMux"
);
closeOutput
();
LOGE
(
"aduio queue left num: %d, video queue left num: %d"
,
audio_queue
.
size
(),
video_queue
.
size
());
...
...
@@ -339,24 +340,19 @@ int GB28181Muxer::encodeEnd() {
}
/**
* 用户
中断
* 用户
结束
*/
void
GB28181Muxer
::
user_end
()
{
LOGE
(
"call user end"
);
is_end
=
END_STATE
;
}
void
GB28181Muxer
::
release
()
{
is_release
=
RELEASE_TRUE
;
}
int
GB28181Muxer
::
mux
(
GB28181Muxer
*
gb28181Muxer
)
{
long
lastPts
=
gb28181Muxer
->
pkt
.
pts
;
int64_t
lastPts
=
gb28181Muxer
->
pkt
.
pts
;
gb28181Muxer
->
nowPkt
=
&
gb28181Muxer
->
pkt
;
int
append
=
0
;
int
64_t
append
=
0
;
int
cnt
=
0
;
while
(
!
gb28181Muxer
->
is_end
||
!
gb28181Muxer
->
video_queue
.
empty
()
)
{
while
(
!
gb28181Muxer
->
is_end
)
{
char
szTempPacketHead
[
256
];
int
nSizePos
=
0
;
int
nSize
=
0
;
...
...
@@ -364,12 +360,14 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
// read next frame
uint8_t
*
picture_buf
=
*
gb28181Muxer
->
video_queue
.
wait_and_pop
().
get
();
long
v_time
=
bytes2long
(
reinterpret_cast
<
char
*>
(
picture_buf
)
);
int64_t
v_time
=
bytes2long
(
picture_buf
);
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
);
gb28181Muxer
->
pFrame
->
pts
=
(
v_time
-
gb28181Muxer
->
startTime
)
*
90
;
LOGE
(
"get a pts:%ld"
,
gb28181Muxer
->
pFrame
->
pts
);
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
,
...
...
@@ -379,12 +377,12 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
}
// 读到了下一帧
long
newPts
=
gb28181Muxer
->
nextPkt
->
pts
;
int64_t
newPts
=
gb28181Muxer
->
nextPkt
->
pts
;
// 计算写入音频的个数
int
frameDiv
=
newPts
-
lastPts
;
int
64_t
frameDiv
=
newPts
-
lastPts
;
append
=
(
frameDiv
+
append
)
%
3600
;
int
audioCnt
=
(
frameDiv
+
append
)
/
3600
;
LOGE
(
"now pts:%l
d.|%ld| next pts:%
ld,audio count:%d"
,
LOGE
(
"now pts:%l
ld.|%lld| next pts:%l
ld,audio count:%d"
,
gb28181Muxer
->
nowPkt
->
pts
,
gb28181Muxer
->
nextPkt
->
pts
-
gb28181Muxer
->
nowPkt
->
pts
,
gb28181Muxer
->
nextPkt
->
pts
,
audioCnt
);
...
...
@@ -420,11 +418,9 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
gb28181Muxer
->
nextPkt
=
t
;
// LOGE("now frame:%ld", h264_encoder->nowPkt->pts);
while
(
audioCnt
>
0
)
{
uint8_t
*
audioFrame
=
*
gb28181Muxer
->
audio_queue
.
wait_and_pop
().
get
();
long
audioPts
=
gb28181Muxer
->
audioFrameCnt
*
(
90000
/
gb28181Muxer
->
arguments
->
frame_rate
);
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
);
...
...
@@ -436,6 +432,8 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
delete
(
audioFrame
);
}
}
LOGE
(
"mux over!"
);
return
0
;
}
void
GB28181Muxer
::
initOutput
()
{
...
...
gb28181library/src/main/cpp/gb28181_muxer.h
浏览文件 @
83c6bb23
...
...
@@ -27,9 +27,7 @@ public:
void
user_end
();
void
release
();
int
encodeEnd
();
int
endMux
();
void
custom_filter
(
const
GB28181Muxer
*
gb28181Muxer
,
const
uint8_t
*
picture_buf
,
int
in_y_size
,
...
...
@@ -60,7 +58,7 @@ private:
int
out_y_size
;
int
audioFrameCnt
=
0
;
int
videoFrameCnt
=
0
;
long
startTime
=
0
;
int64_t
startTime
=
0
;
ofstream
fout
;
...
...
gb28181library/src/main/cpp/native-lib.cpp
浏览文件 @
83c6bb23
...
...
@@ -55,7 +55,7 @@ Java_com_autulin_gb28181library_JNIBridge_initMuxer(JNIEnv *env, jclass type, js
strcat
(
arguments
->
media_path
,
MEDIA_FORMAT
);
arguments
->
video_bit_rate
=
bit_rate
;
arguments
->
frame_rate
=
frameRate
;
arguments
->
video_
frame_rate
=
frameRate
;
arguments
->
in_width
=
in_width
;
arguments
->
in_height
=
in_height
;
arguments
->
out_height
=
out_height
;
...
...
@@ -105,16 +105,3 @@ Java_com_autulin_gb28181library_JNIBridge_endMux(JNIEnv *env, jclass type) {
}
return
0
;
}
extern
"C"
JNIEXPORT
jint
JNICALL
Java_com_autulin_gb28181library_JNIBridge_release
(
JNIEnv
*
env
,
jclass
type
)
{
if
(
gb28181Muxer
!=
NULL
)
{
try
{
gb28181Muxer
->
release
();
}
catch
(
exception
e
){}
gb28181Muxer
=
NULL
;
}
return
0
;
}
\ No newline at end of file
gb28181library/src/main/cpp/user_arguments.h
浏览文件 @
83c6bb23
...
...
@@ -16,8 +16,8 @@ typedef struct UserArguments {
int
in_height
;
//输入高度
int
out_height
;
//输出高度
int
out_width
;
//输出宽度
int
frame_rate
;
//视频帧率控制
long
long
video_bit_rate
;
//视频比特率控制
int
video_
frame_rate
;
//视频帧率控制
int64_t
video_bit_rate
;
//视频比特率控制
int
v_custom_format
;
//一些滤镜操作控制
int
a_frame_len
;
JNIEnv
*
env
;
//env全局指针
...
...
gb28181library/src/main/java/com/autulin/gb28181library/DemoActivity.java
浏览文件 @
83c6bb23
...
...
@@ -86,7 +86,8 @@ public class DemoActivity extends AppCompatActivity implements
mMediaRecorder
.
setOnPreparedListener
(
this
);
// 设置输出
String
fileName
=
String
.
valueOf
(
System
.
currentTimeMillis
());
// String fileName = String.valueOf(System.currentTimeMillis());
String
fileName
=
"tttttt"
;
mediaOutput
=
mMediaRecorder
.
setFileOutPut
(
fileName
);
mMediaRecorder
.
setSurfaceHolder
(
mSurfaceView
.
getHolder
());
...
...
gb28181library/src/main/java/com/autulin/gb28181library/JNIBridge.java
浏览文件 @
83c6bb23
...
...
@@ -74,6 +74,4 @@ public class JNIBridge {
public
static
native
int
endMux
();
public
static
native
int
release
();
}
gb28181library/src/main/java/com/autulin/gb28181library/MediaRecorderBase.java
浏览文件 @
83c6bb23
...
...
@@ -410,6 +410,11 @@ public abstract class MediaRecorderBase implements Callback, PreviewCallback, IM
public
void
endMux
()
{
mRecording
=
false
;
// 停止音频录制
if
(
mAudioCollector
!=
null
)
{
mAudioCollector
.
interrupt
();
mAudioCollector
=
null
;
}
}
...
...
@@ -430,6 +435,15 @@ public abstract class MediaRecorderBase implements Callback, PreviewCallback, IM
return
;
List
<
Integer
>
rates
=
mParameters
.
getSupportedPreviewFrameRates
();
Log
.
e
(
"MedidaRecord"
,
"支持的帧率有 "
+
rates
.
toString
());
StringBuilder
sb
=
new
StringBuilder
();
for
(
Size
size:
mSupportedPreviewSizes
)
{
sb
.
append
(
size
.
width
);
sb
.
append
(
'x'
);
sb
.
append
(
size
.
height
);
sb
.
append
(
','
);
}
Log
.
e
(
"MedidaRecord"
,
"支持的预览大小有(宽x高):"
+
sb
.
toString
());
if
(
rates
!=
null
)
{
if
(
rates
.
contains
(
MAX_FRAME_RATE
))
{
mFrameRate
=
MAX_FRAME_RATE
;
...
...
@@ -471,6 +485,7 @@ public abstract class MediaRecorderBase implements Callback, PreviewCallback, IM
SMALL_VIDEO_HEIGHT
=
480
;
}
mParameters
.
setPreviewSize
(
mSupportedPreviewWidth
,
SMALL_VIDEO_HEIGHT
);
Log
.
e
(
"MedidaRecord"
,
"最终选择预览大小:"
+
mSupportedPreviewWidth
+
"x"
+
SMALL_VIDEO_HEIGHT
);
// 设置输出视频流尺寸,采样率
mParameters
.
setPreviewFormat
(
ImageFormat
.
YV12
);
...
...
@@ -606,7 +621,7 @@ public abstract class MediaRecorderBase implements Callback, PreviewCallback, IM
*/
public
void
release
()
{
JNIBridge
.
release
();
JNIBridge
.
endMux
();
// 停止视频预览
stopPreview
();
// 停止音频录制
...
...
gb28181library/src/main/jniLibs/armeabi-v7a/libfdk-aac.so
0 → 100644
浏览文件 @
83c6bb23
File added
gradle.properties
浏览文件 @
83c6bb23
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
## Project-wide Gradle settings.
#
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs
=
-Xmx1536m
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Wed Sep 12 17:58:18 CST 2018
systemProp.https.proxyPort
=
1080
systemProp.http.proxyHost
=
127.0.0.1
org.gradle.jvmargs
=
-Xmx1536m
systemProp.https.proxyHost
=
127.0.0.1
systemProp.http.proxyPort
=
1080
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论