(memchr(it, 0xff, end - it));
28 | if (it == NULL) {
29 | break;
30 | }
31 | if (it[1] == 0xd9) {
32 | return LIBYUV_TRUE; // Success: Valid jpeg.
33 | }
34 | ++it; // Skip over current 0xff.
35 | }
36 | }
37 | // ERROR: Invalid jpeg end code not found. Size sample_size
38 | return LIBYUV_FALSE;
39 | }
40 |
41 | // Helper function to validate the jpeg appears intact.
42 | LIBYUV_BOOL ValidateJpeg(const uint8* sample, size_t sample_size) {
43 | // Maximum size that ValidateJpeg will consider valid.
44 | const size_t kMaxJpegSize = 0x7fffffffull;
45 | const size_t kBackSearchSize = 1024;
46 | if (sample_size < 64 || sample_size > kMaxJpegSize || !sample) {
47 | // ERROR: Invalid jpeg size: sample_size
48 | return LIBYUV_FALSE;
49 | }
50 | if (sample[0] != 0xff || sample[1] != 0xd8) { // SOI marker
51 | // ERROR: Invalid jpeg initial start code
52 | return LIBYUV_FALSE;
53 | }
54 |
55 | // Look for the End Of Image (EOI) marker near the end of the buffer.
56 | if (sample_size > kBackSearchSize) {
57 | if (ScanEOI(sample + sample_size - kBackSearchSize, kBackSearchSize)) {
58 | return LIBYUV_TRUE; // Success: Valid jpeg.
59 | }
60 | // Reduce search size for forward search.
61 | sample_size = sample_size - kBackSearchSize + 1;
62 | }
63 | // Step over SOI marker and scan for EOI.
64 | return ScanEOI(sample + 2, sample_size - 2);
65 | }
66 |
67 | #ifdef __cplusplus
68 | } // extern "C"
69 | } // namespace libyuv
70 | #endif
71 |
72 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | .gn
3 | pin-log.txt
4 | /base
5 | /build
6 | /buildtools
7 | /chromium/.gclient.tmp
8 | /chromium/.gclient.tmp_entries
9 | /chromium/.last_sync_chromium
10 | /chromium/src/
11 | /google_apis
12 | /links
13 | /net
14 | /out
15 | /sde-avx-sse-transition-out.txt
16 | /testing
17 | /third_party/android_platform
18 | /third_party/android_testrunner
19 | /third_party/android_tools
20 | /third_party/appurify-python
21 | /third_party/asan
22 | /third_party/ashmem
23 | /third_party/binutils
24 | /third_party/boringssl
25 | /third_party/BUILD.gn
26 | /third_party/clang_format
27 | /third_party/class-dump
28 | /third_party/colorama
29 | /third_party/cygwin
30 | /third_party/directxsdk
31 | /third_party/drmemory
32 | /third_party/expat
33 | /third_party/gaeunit
34 | /third_party/gflags/src
35 | /third_party/icu
36 | /third_party/instrumented_libraries
37 | /third_party/ijar
38 | /third_party/jsoncpp
39 | /third_party/jsr-305
40 | /third_party/junit
41 | /third_party/junit-jar
42 | /third_party/libc++
43 | /third_party/libc++abi
44 | /third_party/libevent
45 | /third_party/libjingle
46 | /third_party/libjpeg
47 | /third_party/libjpeg_turbo
48 | /third_party/libsrtp
49 | /third_party/libvpx_new
50 | /third_party/libxml
51 | /third_party/libudev
52 | /third_party/libyuv
53 | /third_party/llvm
54 | /third_party/llvm-build
55 | /third_party/lss
56 | /third_party/mockito
57 | /third_party/modp_b64
58 | /third_party/nss
59 | /third_party/oauth2
60 | /third_party/ocmock
61 | /third_party/openmax_dl
62 | /third_party/opus
63 | /third_party/proguard
64 | /third_party/protobuf
65 | /third_party/requests
66 | /third_party/robolectric
67 | /third_party/sqlite
68 | /third_party/syzygy
69 | /third_party/usrsctp
70 | /third_party/valgrind
71 | /third_party/WebKit
72 | /third_party/winsdk_samples/src
73 | /third_party/yasm
74 | /third_party/zlib
75 | /tools/android
76 | /tools/clang
77 | /tools/find_depot_tools.py
78 | /tools/generate_library_loader
79 | /tools/gn
80 | /tools/grit
81 | /tools/gyp
82 | /tools/isolate_driver.py
83 | /tools/memory
84 | /tools/protoc_wrapper
85 | /tools/python
86 | /tools/relocation_packer
87 | /tools/sanitizer_options
88 | /tools/swarming_client
89 | /tools/tsan_suppressions
90 | /tools/valgrind
91 | /tools/vim
92 | /tools/win
93 |
94 | # Files generated by CMake build
95 | cmake_install.cmake
96 | CMakeCache.txt
97 | CMakeFiles/
98 | convert
99 | libgtest.a
100 | libyuv.a
101 | libyuv_unittest
102 |
103 | # Files generated by winarm.mk build
104 | libyuv_arm.lib
105 | source/*.o
106 |
107 |
108 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/third_party/gflags/gflags.gyp:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2014 The LibYuv Project Authors. All rights reserved.
3 | #
4 | # Use of this source code is governed by a BSD-style license
5 | # that can be found in the LICENSE file in the root of the source
6 | # tree. An additional intellectual property rights grant can be found
7 | # in the file PATENTS. All contributing project authors may
8 | # be found in the AUTHORS file in the root of the source tree.
9 |
10 | # This is a copy of WebRTC's gflags.gyp.
11 |
12 | {
13 | 'variables': {
14 | 'gflags_root': '<(DEPTH)/third_party/gflags',
15 | 'conditions': [
16 | ['OS=="win"', {
17 | 'gflags_gen_arch_root': '<(gflags_root)/gen/win',
18 | }, {
19 | 'gflags_gen_arch_root': '<(gflags_root)/gen/posix',
20 | }],
21 | ],
22 | },
23 | 'targets': [
24 | {
25 | 'target_name': 'gflags',
26 | 'type': 'static_library',
27 | 'include_dirs': [
28 | '<(gflags_gen_arch_root)/include/private', # For config.h
29 | '<(gflags_gen_arch_root)/include', # For configured files.
30 | '<(gflags_root)/src', # For everything else.
31 | ],
32 | 'defines': [
33 | # These macros exist so flags and symbols are properly
34 | # exported when building DLLs. Since we don't build DLLs, we
35 | # need to disable them.
36 | 'GFLAGS_DLL_DECL=',
37 | 'GFLAGS_DLL_DECLARE_FLAG=',
38 | 'GFLAGS_DLL_DEFINE_FLAG=',
39 | ],
40 | 'direct_dependent_settings': {
41 | 'include_dirs': [
42 | '<(gflags_gen_arch_root)/include', # For configured files.
43 | '<(gflags_root)/src', # For everything else.
44 | ],
45 | 'defines': [
46 | 'GFLAGS_DLL_DECL=',
47 | 'GFLAGS_DLL_DECLARE_FLAG=',
48 | 'GFLAGS_DLL_DEFINE_FLAG=',
49 | ],
50 | },
51 | 'sources': [
52 | 'src/gflags.cc',
53 | 'src/gflags_completions.cc',
54 | 'src/gflags_reporting.cc',
55 | ],
56 | 'conditions': [
57 | ['OS=="win"', {
58 | 'sources': [
59 | 'src/windows/port.cc',
60 | ],
61 | # Suppress warnings about WIN32_LEAN_AND_MEAN and size_t truncation.
62 | 'msvs_disabled_warnings': [4005, 4267],
63 | }],
64 | # TODO(andrew): Look into fixing this warning upstream:
65 | # http://code.google.com/p/webrtc/issues/detail?id=760
66 | ['clang==1', {
67 | 'cflags!': ['-Wheader-hygiene',],
68 | 'xcode_settings': {
69 | 'WARNING_CFLAGS!': ['-Wheader-hygiene',],
70 | },
71 | }],
72 | ],
73 | },
74 | ],
75 | }
76 |
--------------------------------------------------------------------------------
/library/src/main/java/com/library/common/UdpBytes.java:
--------------------------------------------------------------------------------
1 | package com.library.common;
2 |
3 | import com.library.util.ByteUtil;
4 | import com.library.util.OtherUtil;
5 |
6 | import java.util.Arrays;
7 |
8 | /**
9 | * UDP协议内容:
10 | *
11 | * UDP头:----
12 | * 1字节 音视频tag 0音频 1视频
13 | * 4字节 包序号
14 | *
15 | * 视频:----
16 | * 1字节 帧标记tag 0帧头 1帧中间 2帧尾 3独立帧
17 | * 1字节 图像比例
18 | * 4字节 时间戳
19 | * 2字节 内容长度(纯数据部分)
20 | * length 数据内容
21 | *
22 | * 音频:----
23 | * 4字节 时间戳
24 | * 2字节 内容长度(纯数据部分)
25 | * length 数据内容
26 | * ......
27 | * 4字节 时间戳
28 | * 2字节 内容长度(纯数据部分)
29 | * length 数据内容
30 | * ......音频5帧一包,所以5个相同数据段
31 | */
32 | public class UdpBytes {
33 | private int tag;
34 | private int num;
35 | private byte[] bytes;
36 | private byte[] data;
37 | private int time;
38 | private double weight;
39 |
40 | private int frameTag;
41 | private int lengthnum;//记录音频偏移长度
42 |
43 | public UdpBytes(byte[] bytes) {
44 | tag = bytes[0];
45 | num = ByteUtil.byte_to_int(bytes[1], bytes[2], bytes[3], bytes[4]);
46 |
47 | if (tag == (byte) 0x01) {//视频
48 | frameTag = bytes[5];
49 | weight = OtherUtil.getWeight(bytes[6]);
50 | time = ByteUtil.byte_to_int(bytes[7], bytes[8], bytes[9], bytes[10]);
51 | //13是视频UDP包头+视频协议字长,data得到数据可能不足一帧视频
52 | data = Arrays.copyOfRange(bytes, 13, ByteUtil.byte_to_short(bytes[11], bytes[12]) + 13);
53 | } else if (tag == (byte) 0x00) {//音频
54 | this.bytes = bytes;
55 | time = ByteUtil.byte_to_int(bytes[5], bytes[6], bytes[7], bytes[8]);
56 | //11是音频UDP包头+音频协议字长,data得到的是包中第一帧音频
57 | data = Arrays.copyOfRange(bytes, 11, ByteUtil.byte_to_short(bytes[9], bytes[10]) + 11);
58 | lengthnum = data.length + 11;//记录偏移量
59 | }
60 | }
61 |
62 | public int getTag() {
63 | return tag;
64 | }
65 |
66 | public int getNum() {
67 | return num;
68 | }
69 |
70 | public int getTime() {
71 | return time;
72 | }
73 |
74 | public byte[] getData() {
75 | return data;
76 | }
77 |
78 | //视频帧标记
79 | public int getFrameTag() {
80 | return frameTag;
81 | }
82 |
83 | //图像比
84 | public double getWeight() {
85 | return weight;
86 | }
87 |
88 | //音频定位下一帧
89 | public void nextVoice() {
90 | time = ByteUtil.byte_to_int(bytes[lengthnum], bytes[lengthnum + 1], bytes[lengthnum + 2], bytes[lengthnum + 3]);
91 | //6是音频协议字长,data得到的是包中下一帧音频
92 | data = Arrays.copyOfRange(bytes, lengthnum + 6, ByteUtil.byte_to_short(bytes[lengthnum + 4], bytes[lengthnum + 5]) + lengthnum + 6);
93 | lengthnum = lengthnum + data.length + 6;//记录偏移量
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/libyuv.gypi:
--------------------------------------------------------------------------------
1 | # Copyright 2014 The LibYuv Project Authors. All rights reserved.
2 | #
3 | # Use of this source code is governed by a BSD-style license
4 | # that can be found in the LICENSE file in the root of the source
5 | # tree. An additional intellectual property rights grant can be found
6 | # in the file PATENTS. All contributing project authors may
7 | # be found in the AUTHORS file in the root of the source tree.
8 |
9 | {
10 | 'variables': {
11 | 'libyuv_sources': [
12 | # includes.
13 | 'include/libyuv.h',
14 | 'include/libyuv/basic_types.h',
15 | 'include/libyuv/compare.h',
16 | 'include/libyuv/convert.h',
17 | 'include/libyuv/convert_argb.h',
18 | 'include/libyuv/convert_from.h',
19 | 'include/libyuv/convert_from_argb.h',
20 | 'include/libyuv/cpu_id.h',
21 | 'include/libyuv/mjpeg_decoder.h',
22 | 'include/libyuv/planar_functions.h',
23 | 'include/libyuv/rotate.h',
24 | 'include/libyuv/rotate_argb.h',
25 | 'include/libyuv/rotate_row.h',
26 | 'include/libyuv/row.h',
27 | 'include/libyuv/scale.h',
28 | 'include/libyuv/scale_argb.h',
29 | 'include/libyuv/scale_row.h',
30 | 'include/libyuv/version.h',
31 | 'include/libyuv/video_common.h',
32 |
33 | # sources.
34 | 'source/compare.cc',
35 | 'source/compare_common.cc',
36 | 'source/compare_gcc.cc',
37 | 'source/compare_neon.cc',
38 | 'source/compare_neon64.cc',
39 | 'source/compare_win.cc',
40 | 'source/convert.cc',
41 | 'source/convert_argb.cc',
42 | 'source/convert_from.cc',
43 | 'source/convert_from_argb.cc',
44 | 'source/convert_jpeg.cc',
45 | 'source/convert_to_argb.cc',
46 | 'source/convert_to_i420.cc',
47 | 'source/cpu_id.cc',
48 | 'source/mjpeg_decoder.cc',
49 | 'source/mjpeg_validate.cc',
50 | 'source/planar_functions.cc',
51 | 'source/rotate.cc',
52 | 'source/rotate_any.cc',
53 | 'source/rotate_argb.cc',
54 | 'source/rotate_common.cc',
55 | 'source/rotate_gcc.cc',
56 | 'source/rotate_mips.cc',
57 | 'source/rotate_neon.cc',
58 | 'source/rotate_neon64.cc',
59 | 'source/rotate_win.cc',
60 | 'source/row_any.cc',
61 | 'source/row_common.cc',
62 | 'source/row_gcc.cc',
63 | 'source/row_mips.cc',
64 | 'source/row_neon.cc',
65 | 'source/row_neon64.cc',
66 | 'source/row_win.cc',
67 | 'source/scale.cc',
68 | 'source/scale_any.cc',
69 | 'source/scale_argb.cc',
70 | 'source/scale_common.cc',
71 | 'source/scale_gcc.cc',
72 | 'source/scale_mips.cc',
73 | 'source/scale_neon.cc',
74 | 'source/scale_neon64.cc',
75 | 'source/scale_win.cc',
76 | 'source/video_common.cc',
77 | ],
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/library/src/main/java/com/library/talk/Listen.java:
--------------------------------------------------------------------------------
1 | package com.library.talk;
2 |
3 | import com.library.common.UdpControlInterface;
4 | import com.library.talk.coder.ListenTrack;
5 | import com.library.talk.stream.ListenRecive;
6 |
7 | /**
8 | * Created by android1 on 2017/12/23.
9 | */
10 |
11 | public class Listen {
12 | private ListenTrack listenTrack;
13 | private ListenRecive listenRecive;
14 |
15 | private Listen(ListenRecive listenRecive, int udpPacketCacheMin, int voiceFrameCacheMin, UdpControlInterface udpControl, int multiple) {
16 | listenTrack = new ListenTrack(listenRecive);
17 | listenTrack.setVoiceIncreaseMultiple(multiple);
18 | listenRecive.setUdpControl(udpControl);
19 | listenRecive.setUdpPacketMin(udpPacketCacheMin);
20 | listenRecive.setVoiceFrameCacheMin(voiceFrameCacheMin);
21 | this.listenRecive = listenRecive;
22 | }
23 |
24 | public void start() {
25 | listenTrack.start();
26 | listenRecive.start();
27 | }
28 |
29 | public void stop() {
30 | listenRecive.stop();
31 | listenTrack.stop();
32 | }
33 |
34 | public void setVoiceIncreaseMultiple(int multiple) {
35 | listenTrack.setVoiceIncreaseMultiple(multiple);
36 | }
37 |
38 | public void destroy() {
39 | listenRecive.destroy();
40 | listenTrack.destroy();
41 | }
42 |
43 | public void write(byte[] bytes) {
44 | listenRecive.write(bytes);
45 | }
46 |
47 | public int getReciveStatus() {
48 | return listenRecive.getReciveStatus();
49 | }
50 |
51 |
52 | public static class Buider {
53 | private ListenRecive listenRecive;
54 | private int udpPacketCacheMin = 2;
55 | private int voiceFrameCacheMin = 5;
56 | private UdpControlInterface udpControl;
57 | private int multiple = 1;
58 |
59 | public Buider setPullMode(ListenRecive listenRecive) {
60 | this.listenRecive = listenRecive;
61 | return this;
62 | }
63 |
64 | public Buider setMultiple(int multiple) {
65 | this.multiple = multiple;
66 | return this;
67 | }
68 |
69 | public Buider setUdpPacketCacheMin(int udpPacketCacheMin) {
70 | this.udpPacketCacheMin = udpPacketCacheMin;
71 | return this;
72 | }
73 |
74 | public Buider setUdpControl(UdpControlInterface udpControl) {
75 | this.udpControl = udpControl;
76 | return this;
77 | }
78 |
79 | public Buider setVoiceFrameCacheMin(int voiceFrameCacheMin) {
80 | this.voiceFrameCacheMin = voiceFrameCacheMin;
81 | return this;
82 | }
83 |
84 | public Listen build() {
85 | return new Listen(listenRecive, udpPacketCacheMin, voiceFrameCacheMin, udpControl, multiple);
86 | }
87 | }
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/include/libyuv/compare_row.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 The LibYuv Project Authors. All rights reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #ifndef INCLUDE_LIBYUV_COMPARE_ROW_H_ // NOLINT
12 | #define INCLUDE_LIBYUV_COMPARE_ROW_H_
13 |
14 | #include "libyuv/basic_types.h"
15 |
16 | #ifdef __cplusplus
17 | namespace libyuv {
18 | extern "C" {
19 | #endif
20 |
21 | #if defined(__pnacl__) || defined(__CLR_VER) || \
22 | (defined(__i386__) && !defined(__SSE2__))
23 | #define LIBYUV_DISABLE_X86
24 | #endif
25 |
26 | // Visual C 2012 required for AVX2.
27 | #if defined(_M_IX86) && !defined(__clang__) && \
28 | defined(_MSC_VER) && _MSC_VER >= 1700
29 | #define VISUALC_HAS_AVX2 1
30 | #endif // VisualStudio >= 2012
31 |
32 | // clang >= 3.4.0 required for AVX2.
33 | #if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
34 | #if (__clang_major__ > 3) || (__clang_major__ == 3 && (__clang_minor__ >= 4))
35 | #define CLANG_HAS_AVX2 1
36 | #endif // clang >= 3.4
37 | #endif // __clang__
38 |
39 | #if defined(_M_IX86) && (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2))
40 | #define HAS_HASHDJB2_AVX2
41 | #endif
42 |
43 | // The following are available for Visual C and GCC:
44 | #if !defined(LIBYUV_DISABLE_X86) && \
45 | (defined(__x86_64__) || (defined(__i386__) || defined(_M_IX86)))
46 | #define HAS_HASHDJB2_SSE41
47 | #define HAS_SUMSQUAREERROR_SSE2
48 | #endif
49 |
50 | // The following are available for Visual C and clangcl 32 bit:
51 | #if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && \
52 | (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2))
53 | #define HAS_HASHDJB2_AVX2
54 | #define HAS_SUMSQUAREERROR_AVX2
55 | #endif
56 |
57 | // The following are available for Neon:
58 | #if !defined(LIBYUV_DISABLE_NEON) && \
59 | (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__))
60 | #define HAS_SUMSQUAREERROR_NEON
61 | #endif
62 |
63 | uint32 SumSquareError_C(const uint8* src_a, const uint8* src_b, int count);
64 | uint32 SumSquareError_SSE2(const uint8* src_a, const uint8* src_b, int count);
65 | uint32 SumSquareError_AVX2(const uint8* src_a, const uint8* src_b, int count);
66 | uint32 SumSquareError_NEON(const uint8* src_a, const uint8* src_b, int count);
67 |
68 | uint32 HashDjb2_C(const uint8* src, int count, uint32 seed);
69 | uint32 HashDjb2_SSE41(const uint8* src, int count, uint32 seed);
70 | uint32 HashDjb2_AVX2(const uint8* src, int count, uint32 seed);
71 |
72 | #ifdef __cplusplus
73 | } // extern "C"
74 | } // namespace libyuv
75 | #endif
76 |
77 | #endif // INCLUDE_LIBYUV_COMPARE_ROW_H_ NOLINT
78 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/include/libyuv/compare.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #ifndef INCLUDE_LIBYUV_COMPARE_H_ // NOLINT
12 | #define INCLUDE_LIBYUV_COMPARE_H_
13 |
14 | #include "libyuv/basic_types.h"
15 |
16 | #ifdef __cplusplus
17 | namespace libyuv {
18 | extern "C" {
19 | #endif
20 |
21 | // Compute a hash for specified memory. Seed of 5381 recommended.
22 | LIBYUV_API
23 | uint32 HashDjb2(const uint8* src, uint64 count, uint32 seed);
24 |
25 | // Scan an opaque argb image and return fourcc based on alpha offset.
26 | // Returns FOURCC_ARGB, FOURCC_BGRA, or 0 if unknown.
27 | LIBYUV_API
28 | uint32 ARGBDetect(const uint8* argb, int stride_argb, int width, int height);
29 |
30 | // Sum Square Error - used to compute Mean Square Error or PSNR.
31 | LIBYUV_API
32 | uint64 ComputeSumSquareError(const uint8* src_a,
33 | const uint8* src_b, int count);
34 |
35 | LIBYUV_API
36 | uint64 ComputeSumSquareErrorPlane(const uint8* src_a, int stride_a,
37 | const uint8* src_b, int stride_b,
38 | int width, int height);
39 |
40 | static const int kMaxPsnr = 128;
41 |
42 | LIBYUV_API
43 | double SumSquareErrorToPsnr(uint64 sse, uint64 count);
44 |
45 | LIBYUV_API
46 | double CalcFramePsnr(const uint8* src_a, int stride_a,
47 | const uint8* src_b, int stride_b,
48 | int width, int height);
49 |
50 | LIBYUV_API
51 | double I420Psnr(const uint8* src_y_a, int stride_y_a,
52 | const uint8* src_u_a, int stride_u_a,
53 | const uint8* src_v_a, int stride_v_a,
54 | const uint8* src_y_b, int stride_y_b,
55 | const uint8* src_u_b, int stride_u_b,
56 | const uint8* src_v_b, int stride_v_b,
57 | int width, int height);
58 |
59 | LIBYUV_API
60 | double CalcFrameSsim(const uint8* src_a, int stride_a,
61 | const uint8* src_b, int stride_b,
62 | int width, int height);
63 |
64 | LIBYUV_API
65 | double I420Ssim(const uint8* src_y_a, int stride_y_a,
66 | const uint8* src_u_a, int stride_u_a,
67 | const uint8* src_v_a, int stride_v_a,
68 | const uint8* src_y_b, int stride_y_b,
69 | const uint8* src_u_b, int stride_u_b,
70 | const uint8* src_v_b, int stride_v_b,
71 | int width, int height);
72 |
73 | #ifdef __cplusplus
74 | } // extern "C"
75 | } // namespace libyuv
76 | #endif
77 |
78 | #endif // INCLUDE_LIBYUV_COMPARE_H_ NOLINT
79 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/include/libyuv/cpu_id.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #ifndef INCLUDE_LIBYUV_CPU_ID_H_ // NOLINT
12 | #define INCLUDE_LIBYUV_CPU_ID_H_
13 |
14 | #include "libyuv/basic_types.h"
15 |
16 | #ifdef __cplusplus
17 | namespace libyuv {
18 | extern "C" {
19 | #endif
20 |
21 | // TODO(fbarchard): Consider overlapping bits for different architectures.
22 | // Internal flag to indicate cpuid requires initialization.
23 | #define kCpuInit 0x1
24 |
25 | // These flags are only valid on ARM processors.
26 | static const int kCpuHasARM = 0x2;
27 | static const int kCpuHasNEON = 0x4;
28 | // 0x8 reserved for future ARM flag.
29 |
30 | // These flags are only valid on x86 processors.
31 | static const int kCpuHasX86 = 0x10;
32 | static const int kCpuHasSSE2 = 0x20;
33 | static const int kCpuHasSSSE3 = 0x40;
34 | static const int kCpuHasSSE41 = 0x80;
35 | static const int kCpuHasSSE42 = 0x100;
36 | static const int kCpuHasAVX = 0x200;
37 | static const int kCpuHasAVX2 = 0x400;
38 | static const int kCpuHasERMS = 0x800;
39 | static const int kCpuHasFMA3 = 0x1000;
40 | // 0x2000, 0x4000, 0x8000 reserved for future X86 flags.
41 |
42 | // These flags are only valid on MIPS processors.
43 | static const int kCpuHasMIPS = 0x10000;
44 | static const int kCpuHasMIPS_DSP = 0x20000;
45 | static const int kCpuHasMIPS_DSPR2 = 0x40000;
46 |
47 | // Internal function used to auto-init.
48 | LIBYUV_API
49 | int InitCpuFlags(void);
50 |
51 | // Internal function for parsing /proc/cpuinfo.
52 | LIBYUV_API
53 | int ArmCpuCaps(const char* cpuinfo_name);
54 |
55 | // Detect CPU has SSE2 etc.
56 | // Test_flag parameter should be one of kCpuHas constants above.
57 | // returns non-zero if instruction set is detected
58 | static __inline int TestCpuFlag(int test_flag) {
59 | LIBYUV_API extern int cpu_info_;
60 | return (cpu_info_ == kCpuInit ? InitCpuFlags() : cpu_info_) & test_flag;
61 | }
62 |
63 | // For testing, allow CPU flags to be disabled.
64 | // ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3.
65 | // MaskCpuFlags(-1) to enable all cpu specific optimizations.
66 | // MaskCpuFlags(0) to disable all cpu specific optimizations.
67 | LIBYUV_API
68 | void MaskCpuFlags(int enable_flags);
69 |
70 | // Low level cpuid for X86. Returns zeros on other CPUs.
71 | // eax is the info type that you want.
72 | // ecx is typically the cpu number, and should normally be zero.
73 | LIBYUV_API
74 | void CpuId(uint32 eax, uint32 ecx, uint32* cpu_info);
75 |
76 | #ifdef __cplusplus
77 | } // extern "C"
78 | } // namespace libyuv
79 | #endif
80 |
81 | #endif // INCLUDE_LIBYUV_CPU_ID_H_ NOLINT
82 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/source/rotate_common.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #include "libyuv/row.h"
12 | #include "libyuv/rotate_row.h"
13 |
14 | #ifdef __cplusplus
15 | namespace libyuv {
16 | extern "C" {
17 | #endif
18 |
19 | void TransposeWx8_C(const uint8* src, int src_stride,
20 | uint8* dst, int dst_stride, int width) {
21 | int i;
22 | for (i = 0; i < width; ++i) {
23 | dst[0] = src[0 * src_stride];
24 | dst[1] = src[1 * src_stride];
25 | dst[2] = src[2 * src_stride];
26 | dst[3] = src[3 * src_stride];
27 | dst[4] = src[4 * src_stride];
28 | dst[5] = src[5 * src_stride];
29 | dst[6] = src[6 * src_stride];
30 | dst[7] = src[7 * src_stride];
31 | ++src;
32 | dst += dst_stride;
33 | }
34 | }
35 |
36 | void TransposeUVWx8_C(const uint8* src, int src_stride,
37 | uint8* dst_a, int dst_stride_a,
38 | uint8* dst_b, int dst_stride_b, int width) {
39 | int i;
40 | for (i = 0; i < width; ++i) {
41 | dst_a[0] = src[0 * src_stride + 0];
42 | dst_b[0] = src[0 * src_stride + 1];
43 | dst_a[1] = src[1 * src_stride + 0];
44 | dst_b[1] = src[1 * src_stride + 1];
45 | dst_a[2] = src[2 * src_stride + 0];
46 | dst_b[2] = src[2 * src_stride + 1];
47 | dst_a[3] = src[3 * src_stride + 0];
48 | dst_b[3] = src[3 * src_stride + 1];
49 | dst_a[4] = src[4 * src_stride + 0];
50 | dst_b[4] = src[4 * src_stride + 1];
51 | dst_a[5] = src[5 * src_stride + 0];
52 | dst_b[5] = src[5 * src_stride + 1];
53 | dst_a[6] = src[6 * src_stride + 0];
54 | dst_b[6] = src[6 * src_stride + 1];
55 | dst_a[7] = src[7 * src_stride + 0];
56 | dst_b[7] = src[7 * src_stride + 1];
57 | src += 2;
58 | dst_a += dst_stride_a;
59 | dst_b += dst_stride_b;
60 | }
61 | }
62 |
63 | void TransposeWxH_C(const uint8* src, int src_stride,
64 | uint8* dst, int dst_stride,
65 | int width, int height) {
66 | int i;
67 | for (i = 0; i < width; ++i) {
68 | int j;
69 | for (j = 0; j < height; ++j) {
70 | dst[i * dst_stride + j] = src[j * src_stride + i];
71 | }
72 | }
73 | }
74 |
75 | void TransposeUVWxH_C(const uint8* src, int src_stride,
76 | uint8* dst_a, int dst_stride_a,
77 | uint8* dst_b, int dst_stride_b,
78 | int width, int height) {
79 | int i;
80 | for (i = 0; i < width * 2; i += 2) {
81 | int j;
82 | for (j = 0; j < height; ++j) {
83 | dst_a[j + ((i >> 1) * dst_stride_a)] = src[i + (j * src_stride)];
84 | dst_b[j + ((i >> 1) * dst_stride_b)] = src[i + (j * src_stride) + 1];
85 | }
86 | }
87 | }
88 |
89 | #ifdef __cplusplus
90 | } // extern "C"
91 | } // namespace libyuv
92 | #endif
93 |
--------------------------------------------------------------------------------
/library/src/main/java/com/library/talk/Speak.java:
--------------------------------------------------------------------------------
1 | package com.library.talk;
2 |
3 | import com.library.common.UdpControlInterface;
4 | import com.library.common.WriteFileCallback;
5 | import com.library.talk.coder.SpeakRecord;
6 | import com.library.talk.stream.SpeakSend;
7 |
8 | /**
9 | * Created by android1 on 2017/12/23.
10 | */
11 |
12 | public class Speak {
13 | private SpeakRecord speakRecord;
14 | private SpeakSend speakSend;
15 |
16 | public Speak(int publishBitrate, UdpControlInterface udpControl, SpeakSend speakSend, String dirpath) {
17 | this.speakSend = speakSend;
18 | speakSend.setUdpControl(udpControl);
19 | speakRecord = new SpeakRecord(publishBitrate, speakSend, dirpath);
20 | }
21 |
22 | public void start() {
23 | speakSend.start();
24 | speakRecord.start();
25 | }
26 |
27 | public void stop() {
28 | speakRecord.stop();
29 | speakSend.stop();
30 | }
31 |
32 |
33 | public void startRecord() {
34 | speakRecord.startRecord();
35 | }
36 |
37 | public void stopRecord() {
38 | speakRecord.stopRecord();
39 | }
40 |
41 | public int getDecibel() {
42 | return speakRecord.getDecibel();
43 | }
44 |
45 | public void startJustSend() {
46 | speakSend.startJustSend();
47 | }
48 |
49 | public void stopJustSend() {
50 | speakSend.stop();
51 | }
52 |
53 | public void addbytes(byte[] voice) {
54 | speakSend.addbytes(voice);
55 | }
56 |
57 | public void destroy() {
58 | speakRecord.destroy();
59 | speakSend.destroy();
60 | }
61 |
62 | public int getPublishStatus() {
63 | return speakSend.getPublishStatus();
64 | }
65 |
66 | public int getRecodeStatus() {
67 | return speakRecord.getRecodeStatus();
68 | }
69 |
70 | public void setWriteFileCallback(WriteFileCallback writeFileCallback) {
71 | speakRecord.setWriteFileCallback(writeFileCallback);
72 | }
73 |
74 | public static class Buider {
75 | private int publishBitrate = 24 * 1024;
76 | private SpeakSend speakSend;
77 | private UdpControlInterface udpControl;
78 | private String dirpath = null;
79 |
80 | public Buider setPushMode(SpeakSend speakSend) {
81 | this.speakSend = speakSend;
82 | return this;
83 | }
84 |
85 | public Buider setPublishBitrate(int publishBitrate) {
86 | this.publishBitrate = Math.min(48 * 1024, publishBitrate);//限制最大48,因为发送会合并5个包,过大会导致溢出
87 | return this;
88 | }
89 |
90 |
91 | public Buider setUdpControl(UdpControlInterface udpControl) {
92 | this.udpControl = udpControl;
93 | return this;
94 | }
95 |
96 | public Buider setVoiceDirPath(String dirpath) {
97 | this.dirpath = dirpath;
98 | return this;
99 | }
100 |
101 | public Speak build() {
102 | return new Speak(publishBitrate, udpControl, speakSend, dirpath);
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/tools/valgrind-libyuv/libyuv_tests.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | :: Copyright (c) 2012 The LibYuv Project Authors. All rights reserved.
3 | ::
4 | :: Use of this source code is governed by a BSD-style license
5 | :: that can be found in the LICENSE file in the root of the source
6 | :: tree. An additional intellectual property rights grant can be found
7 | :: in the file PATENTS. All contributing project authors may
8 | :: be found in the AUTHORS file in the root of the source tree.
9 |
10 | :: This script is a copy of chrome_tests.bat with the following changes:
11 | :: - Invokes libyuv_tests.py instead of chrome_tests.py
12 | :: - Chromium's Valgrind scripts directory is added to the PYTHONPATH to make
13 | :: it possible to execute the Python scripts properly.
14 |
15 | :: TODO(timurrrr): batch files 'export' all the variables to the parent shell
16 | set THISDIR=%~dp0
17 | set TOOL_NAME="unknown"
18 |
19 | :: Get the tool name and put it into TOOL_NAME {{{1
20 | :: NB: SHIFT command doesn't modify %*
21 | :PARSE_ARGS_LOOP
22 | if %1 == () GOTO:TOOLNAME_NOT_FOUND
23 | if %1 == --tool GOTO:TOOLNAME_FOUND
24 | SHIFT
25 | goto :PARSE_ARGS_LOOP
26 |
27 | :TOOLNAME_NOT_FOUND
28 | echo "Please specify a tool (tsan or drmemory) by using --tool flag"
29 | exit /B 1
30 |
31 | :TOOLNAME_FOUND
32 | SHIFT
33 | set TOOL_NAME=%1
34 | :: }}}
35 | if "%TOOL_NAME%" == "drmemory" GOTO :SETUP_DRMEMORY
36 | if "%TOOL_NAME%" == "drmemory_light" GOTO :SETUP_DRMEMORY
37 | if "%TOOL_NAME%" == "drmemory_full" GOTO :SETUP_DRMEMORY
38 | if "%TOOL_NAME%" == "drmemory_pattern" GOTO :SETUP_DRMEMORY
39 | if "%TOOL_NAME%" == "tsan" GOTO :SETUP_TSAN
40 | echo "Unknown tool: `%TOOL_NAME%`! Only tsan and drmemory are supported."
41 | exit /B 1
42 |
43 | :SETUP_DRMEMORY
44 | if NOT "%DRMEMORY_COMMAND%"=="" GOTO :RUN_TESTS
45 | :: Set up DRMEMORY_COMMAND to invoke Dr. Memory {{{1
46 | set DRMEMORY_PATH=%THISDIR%..\..\third_party\drmemory
47 | set DRMEMORY_SFX=%DRMEMORY_PATH%\drmemory-windows-sfx.exe
48 | if EXIST %DRMEMORY_SFX% GOTO DRMEMORY_BINARY_OK
49 | echo "Can't find Dr. Memory executables."
50 | echo "See http://www.chromium.org/developers/how-tos/using-valgrind/dr-memory"
51 | echo "for the instructions on how to get them."
52 | exit /B 1
53 |
54 | :DRMEMORY_BINARY_OK
55 | %DRMEMORY_SFX% -o%DRMEMORY_PATH%\unpacked -y
56 | set DRMEMORY_COMMAND=%DRMEMORY_PATH%\unpacked\bin\drmemory.exe
57 | :: }}}
58 | goto :RUN_TESTS
59 |
60 | :SETUP_TSAN
61 | :: Set up PIN_COMMAND to invoke TSan {{{1
62 | set TSAN_PATH=%THISDIR%..\..\third_party\tsan
63 | set TSAN_SFX=%TSAN_PATH%\tsan-x86-windows-sfx.exe
64 | if EXIST %TSAN_SFX% GOTO TSAN_BINARY_OK
65 | echo "Can't find ThreadSanitizer executables."
66 | echo "See http://www.chromium.org/developers/how-tos/using-valgrind/threadsanitizer/threadsanitizer-on-windows"
67 | echo "for the instructions on how to get them."
68 | exit /B 1
69 |
70 | :TSAN_BINARY_OK
71 | %TSAN_SFX% -o%TSAN_PATH%\unpacked -y
72 | set PIN_COMMAND=%TSAN_PATH%\unpacked\tsan-x86-windows\tsan.bat
73 | :: }}}
74 | goto :RUN_TESTS
75 |
76 | :RUN_TESTS
77 | set PYTHONPATH=%THISDIR%..\python\google;%THISDIR%..\valgrind
78 | set RUNNING_ON_VALGRIND=yes
79 | python %THISDIR%libyuv_tests.py %*
80 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_recive_ready.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
21 |
22 |
30 |
31 |
32 |
36 |
37 |
43 |
44 |
52 |
53 |
54 |
55 |
56 |
62 |
63 |
68 |
69 |
76 |
77 |
83 |
84 |
85 |
91 |
92 |
--------------------------------------------------------------------------------
/library/src/main/java/com/library/live/vc/VoiceRecord.java:
--------------------------------------------------------------------------------
1 | package com.library.live.vc;
2 |
3 | import android.media.AudioFormat;
4 | import android.media.AudioRecord;
5 | import android.media.MediaRecorder;
6 |
7 | import com.library.live.file.WriteMp4;
8 | import com.library.live.stream.UdpSend;
9 | import com.library.util.OtherUtil;
10 | import com.library.util.SingleThreadExecutor;
11 |
12 | /**
13 | * Created by android1 on 2017/9/22.
14 | */
15 |
16 | public class VoiceRecord {
17 | private AudioRecord audioRecord;
18 | private int recBufSize;
19 | //音频推流编码
20 | private VCEncoder vencoder;
21 | //音频录制编码
22 | private RecordEncoderVC recordEncoderVC;
23 |
24 | private SingleThreadExecutor singleThreadExecutor;
25 |
26 | public VoiceRecord(UdpSend udpSend, int collectionbitrate_vc, int publishbitrate_vc, WriteMp4 writeMp4) {
27 | recBufSize = AudioRecord.getMinBufferSize(
28 | OtherUtil.samplerate,
29 | AudioFormat.CHANNEL_IN_STEREO,
30 | AudioFormat.ENCODING_PCM_16BIT);
31 | audioRecord = new AudioRecord(
32 | MediaRecorder.AudioSource.MIC,
33 | OtherUtil.samplerate,
34 | AudioFormat.CHANNEL_IN_STEREO,
35 | AudioFormat.ENCODING_PCM_16BIT,
36 | recBufSize);
37 | vencoder = new VCEncoder(publishbitrate_vc, recBufSize, udpSend);
38 | recordEncoderVC = new RecordEncoderVC(collectionbitrate_vc, recBufSize, writeMp4);
39 | singleThreadExecutor = new SingleThreadExecutor();
40 | }
41 |
42 | /**
43 | * 得到语音原始数据
44 | */
45 | public void start() {
46 | singleThreadExecutor.execute(new Runnable() {
47 | @Override
48 | public void run() {
49 | if (audioRecord != null) {
50 | byte[] buffer = new byte[recBufSize];
51 | int bufferReadResult;
52 | audioRecord.startRecording();//开始录制
53 | while (audioRecord != null && audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
54 | /*
55 | 两针间采集大概40ms,编码发送大概10ms,单线程顺序执行没有问题
56 | */
57 | bufferReadResult = audioRecord.read(buffer, 0, recBufSize);
58 |
59 | if (bufferReadResult == AudioRecord.ERROR_INVALID_OPERATION || bufferReadResult == AudioRecord.ERROR_BAD_VALUE || bufferReadResult == 0 || bufferReadResult == -1) {
60 | continue;
61 | }
62 | vencoder.encode(buffer, bufferReadResult);
63 | recordEncoderVC.encode(buffer, bufferReadResult);
64 | }
65 | }
66 | }
67 | });
68 | }
69 |
70 |
71 | public void destroy() {
72 | if (audioRecord != null) {
73 | audioRecord.release();
74 | audioRecord = null;
75 | }
76 | vencoder.destroy();
77 | recordEncoderVC.destroy();
78 | singleThreadExecutor.shutdownNow();
79 | }
80 |
81 | public void startRecode() {
82 | recordEncoderVC.startRecode();
83 | }
84 |
85 | public void stopRecode() {
86 | recordEncoderVC.stopRecode();
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/app/src/main/java/com/videolive/voice/Voice.java:
--------------------------------------------------------------------------------
1 | package com.videolive.voice;
2 |
3 | import android.os.Bundle;
4 | import android.os.Environment;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.view.View;
7 | import android.widget.Button;
8 |
9 | import com.library.talk.Listen;
10 | import com.library.talk.Speak;
11 | import com.library.talk.stream.ListenRecive;
12 | import com.library.talk.stream.SpeakSend;
13 | import com.videolive.R;
14 |
15 | import java.io.File;
16 | import java.net.DatagramSocket;
17 | import java.net.SocketException;
18 |
19 | public class Voice extends AppCompatActivity {
20 | private Button startVoice;
21 | private Button reciveVoice;
22 | private Speak speak;
23 | private Listen listen;
24 | private DatagramSocket socket = null;
25 |
26 | @Override
27 | protected void onCreate(Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 | setContentView(R.layout.activity_voice_send);
30 |
31 | startVoice = findViewById(R.id.startVoice);
32 | reciveVoice = findViewById(R.id.reciveVoice);
33 |
34 | try {
35 | socket = new DatagramSocket(getIntent().getExtras().getInt("port"));
36 | } catch (SocketException e) {
37 | e.printStackTrace();
38 | }
39 |
40 | speak = new Speak.Buider()
41 | .setPushMode(new SpeakSend(socket, getIntent().getExtras().getString("url"), getIntent().getExtras().getInt("port")))
42 | .setPublishBitrate(getIntent().getExtras().getInt("publishbitrate_vc"))
43 | .setVoiceDirPath(Environment.getExternalStorageDirectory().getPath() + File.separator + "VideoTalk")
44 | .build();
45 |
46 | listen = new Listen.Buider()
47 | .setPullMode(new ListenRecive(socket))
48 | .setUdpPacketCacheMin(2)
49 | .setVoiceFrameCacheMin(5)
50 | .setMultiple(getIntent().getExtras().getInt("multiple"))
51 | .build();
52 |
53 | startVoice.setOnClickListener(new View.OnClickListener() {
54 | @Override
55 | public void onClick(View view) {
56 | if (startVoice.getText().toString().equals("开始对讲")) {
57 | speak.start();
58 | speak.startRecord();
59 | startVoice.setText("停止对讲");
60 | } else {
61 | speak.stop();
62 | speak.stopRecord();
63 | startVoice.setText("开始对讲");
64 | }
65 | }
66 | });
67 |
68 | reciveVoice.setOnClickListener(new View.OnClickListener() {
69 | @Override
70 | public void onClick(View view) {
71 | if (reciveVoice.getText().toString().equals("开始接收")) {
72 | listen.start();
73 | reciveVoice.setText("停止接收");
74 | } else {
75 | listen.stop();
76 | reciveVoice.setText("开始接收");
77 | }
78 | }
79 | });
80 | }
81 |
82 | @Override
83 | protected void onDestroy() {
84 | speak.destroy();
85 | listen.destroy();
86 | socket.close();
87 | socket = null;
88 | super.onDestroy();
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/library/src/main/java/com/library/live/vc/VCEncoder.java:
--------------------------------------------------------------------------------
1 | package com.library.live.vc;
2 |
3 | import android.media.MediaCodec;
4 | import android.media.MediaCodecInfo;
5 | import android.media.MediaFormat;
6 |
7 | import com.library.live.stream.UdpSend;
8 | import com.library.util.OtherUtil;
9 | import com.library.util.VoiceUtil;
10 |
11 | import java.io.IOException;
12 | import java.nio.ByteBuffer;
13 |
14 | /**
15 | * Created by android1 on 2017/9/22.
16 | */
17 |
18 | public class VCEncoder {
19 | private final String AAC_MIME = MediaFormat.MIMETYPE_AUDIO_AAC;
20 | private MediaCodec mediaCodec;
21 | private UdpSend udpSend;
22 |
23 | public VCEncoder(int bitrate, int recBufSize, UdpSend udpSend) {
24 | this.udpSend = udpSend;
25 | try {
26 | mediaCodec = MediaCodec.createEncoderByType(AAC_MIME);
27 | } catch (IOException e) {
28 | e.printStackTrace();
29 | }
30 | MediaFormat format = new MediaFormat();
31 | format.setString(MediaFormat.KEY_MIME, AAC_MIME);
32 | format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
33 | format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2);
34 | format.setInteger(MediaFormat.KEY_SAMPLE_RATE, OtherUtil.samplerate);
35 | format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
36 | format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, recBufSize * 2);
37 |
38 | mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
39 | mediaCodec.start();
40 | }
41 |
42 | private MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
43 | private int outputBufferIndex;
44 | private int inputBufferIndex;
45 |
46 | /*
47 | 音频数据编码,音频数据处理较少,直接编码
48 | */
49 | public void encode(byte[] result, int length) {
50 | try {
51 | inputBufferIndex = mediaCodec.dequeueInputBuffer(OtherUtil.waitTime);
52 | if (inputBufferIndex >= 0) {
53 | ByteBuffer inputBuffer = mediaCodec.getInputBuffer(inputBufferIndex);
54 | inputBuffer.clear();
55 | inputBuffer.put(result, 0, length);
56 | mediaCodec.queueInputBuffer(inputBufferIndex, 0, length, OtherUtil.getFPS(), 0);
57 | }
58 |
59 | outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, OtherUtil.waitTime);
60 |
61 | while (outputBufferIndex >= 0) {
62 | ByteBuffer outputBuffer = mediaCodec.getOutputBuffer(outputBufferIndex);
63 | outputBuffer.position(bufferInfo.offset);
64 | outputBuffer.limit(bufferInfo.offset + bufferInfo.size);
65 |
66 | byte[] outData = new byte[bufferInfo.size + 7];
67 | VoiceUtil.addADTStoPacket(outData, bufferInfo.size + 7);
68 | outputBuffer.get(outData, 7, bufferInfo.size);
69 | //添加将要发送的音频数据
70 | udpSend.addVoice(outData);
71 |
72 | mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
73 | outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, OtherUtil.waitTime);
74 | }
75 | } catch (Exception e) {
76 | e.printStackTrace();
77 | }
78 | }
79 |
80 | public void destroy() {
81 | mediaCodec.release();
82 | mediaCodec = null;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/source/rotate_any.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 The LibYuv Project Authors. All rights reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #include "libyuv/rotate.h"
12 | #include "libyuv/rotate_row.h"
13 |
14 | #include "libyuv/basic_types.h"
15 |
16 | #ifdef __cplusplus
17 | namespace libyuv {
18 | extern "C" {
19 | #endif
20 |
21 | #define TANY(NAMEANY, TPOS_SIMD, MASK) \
22 | void NAMEANY(const uint8* src, int src_stride, \
23 | uint8* dst, int dst_stride, int width) { \
24 | int r = width & MASK; \
25 | int n = width - r; \
26 | if (n > 0) { \
27 | TPOS_SIMD(src, src_stride, dst, dst_stride, n); \
28 | } \
29 | TransposeWx8_C(src + n, src_stride, dst + n * dst_stride, dst_stride, r);\
30 | }
31 |
32 | #ifdef HAS_TRANSPOSEWX8_NEON
33 | TANY(TransposeWx8_Any_NEON, TransposeWx8_NEON, 7)
34 | #endif
35 | #ifdef HAS_TRANSPOSEWX8_SSSE3
36 | TANY(TransposeWx8_Any_SSSE3, TransposeWx8_SSSE3, 7)
37 | #endif
38 | #ifdef HAS_TRANSPOSEWX8_FAST_SSSE3
39 | TANY(TransposeWx8_Fast_Any_SSSE3, TransposeWx8_Fast_SSSE3, 15)
40 | #endif
41 | #ifdef HAS_TRANSPOSEWX8_MIPS_DSPR2
42 | TANY(TransposeWx8_Any_MIPS_DSPR2, TransposeWx8_MIPS_DSPR2, 7)
43 | #endif
44 | #undef TANY
45 |
46 | #define TUVANY(NAMEANY, TPOS_SIMD, MASK) \
47 | void NAMEANY(const uint8* src, int src_stride, \
48 | uint8* dst_a, int dst_stride_a, \
49 | uint8* dst_b, int dst_stride_b, int width) { \
50 | int r = width & MASK; \
51 | int n = width - r; \
52 | if (n > 0) { \
53 | TPOS_SIMD(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, \
54 | n); \
55 | } \
56 | TransposeUVWx8_C(src + n * 2, src_stride, \
57 | dst_a + n * dst_stride_a, dst_stride_a, \
58 | dst_b + n * dst_stride_b, dst_stride_b, r); \
59 | }
60 |
61 | #ifdef HAS_TRANSPOSEUVWX8_NEON
62 | TUVANY(TransposeUVWx8_Any_NEON, TransposeUVWx8_NEON, 7)
63 | #endif
64 | #ifdef HAS_TRANSPOSEUVWX8_SSE2
65 | TUVANY(TransposeUVWx8_Any_SSE2, TransposeUVWx8_SSE2, 7)
66 | #endif
67 | #ifdef HAS_TRANSPOSEUVWX8_MIPS_DSPR2
68 | TUVANY(TransposeUVWx8_Any_MIPS_DSPR2, TransposeUVWx8_MIPS_DSPR2, 7)
69 | #endif
70 | #undef TUVANY
71 |
72 | #ifdef __cplusplus
73 | } // extern "C"
74 | } // namespace libyuv
75 | #endif
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/util/cpuid.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 The LibYuv Project Authors. All rights reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #define INCLUDE_LIBYUV_COMPARE_H_
16 | #include "libyuv.h"
17 | #include "./psnr.h"
18 | #include "./ssim.h"
19 |
20 | int main(int argc, const char* argv[]) {
21 | int cpu_flags = TestCpuFlag(-1);
22 | int has_arm = TestCpuFlag(kCpuHasARM);
23 | int has_mips = TestCpuFlag(kCpuHasMIPS);
24 | int has_x86 = TestCpuFlag(kCpuHasX86);
25 | #if defined(__i386__) || defined(__x86_64__) || \
26 | defined(_M_IX86) || defined(_M_X64)
27 | if (has_x86) {
28 | uint32 family, model, cpu_info[4];
29 | // Vendor ID:
30 | // AuthenticAMD AMD processor
31 | // CentaurHauls Centaur processor
32 | // CyrixInstead Cyrix processor
33 | // GenuineIntel Intel processor
34 | // GenuineTMx86 Transmeta processor
35 | // Geode by NSC National Semiconductor processor
36 | // NexGenDriven NexGen processor
37 | // RiseRiseRise Rise Technology processor
38 | // SiS SiS SiS SiS processor
39 | // UMC UMC UMC UMC processor
40 | CpuId(0, 0, &cpu_info[0]);
41 | cpu_info[0] = cpu_info[1]; // Reorder output
42 | cpu_info[1] = cpu_info[3];
43 | cpu_info[3] = 0;
44 | printf("Cpu Vendor: %s\n", (char*)(&cpu_info[0]));
45 |
46 | // CPU Family and Model
47 | // 3:0 - Stepping
48 | // 7:4 - Model
49 | // 11:8 - Family
50 | // 13:12 - Processor Type
51 | // 19:16 - Extended Model
52 | // 27:20 - Extended Family
53 | CpuId(1, 0, &cpu_info[0]);
54 | family = ((cpu_info[0] >> 8) & 0x0f) | ((cpu_info[0] >> 16) & 0xff0);
55 | model = ((cpu_info[0] >> 4) & 0x0f) | ((cpu_info[0] >> 12) & 0xf0);
56 | printf("Cpu Family %d (0x%x), Model %d (0x%x)\n", family, family,
57 | model, model);
58 | }
59 | #endif
60 | printf("Cpu Flags %x\n", cpu_flags);
61 | printf("Has ARM %x\n", has_arm);
62 | printf("Has MIPS %x\n", has_mips);
63 | printf("Has X86 %x\n", has_x86);
64 | if (has_arm) {
65 | int has_neon = TestCpuFlag(kCpuHasNEON);
66 | printf("Has NEON %x\n", has_neon);
67 | }
68 | if (has_mips) {
69 | int has_mips_dsp = TestCpuFlag(kCpuHasMIPS_DSP);
70 | int has_mips_dspr2 = TestCpuFlag(kCpuHasMIPS_DSPR2);
71 | printf("Has MIPS DSP %x\n", has_mips_dsp);
72 | printf("Has MIPS DSPR2 %x\n", has_mips_dspr2);
73 | }
74 | if (has_x86) {
75 | int has_sse2 = TestCpuFlag(kCpuHasSSE2);
76 | int has_ssse3 = TestCpuFlag(kCpuHasSSSE3);
77 | int has_sse41 = TestCpuFlag(kCpuHasSSE41);
78 | int has_sse42 = TestCpuFlag(kCpuHasSSE42);
79 | int has_avx = TestCpuFlag(kCpuHasAVX);
80 | int has_avx2 = TestCpuFlag(kCpuHasAVX2);
81 | int has_erms = TestCpuFlag(kCpuHasERMS);
82 | int has_fma3 = TestCpuFlag(kCpuHasFMA3);
83 | printf("Has SSE2 %x\n", has_sse2);
84 | printf("Has SSSE3 %x\n", has_ssse3);
85 | printf("Has SSE4.1 %x\n", has_sse41);
86 | printf("Has SSE4.2 %x\n", has_sse42);
87 | printf("Has AVX %x\n", has_avx);
88 | printf("Has AVX2 %x\n", has_avx2);
89 | printf("Has ERMS %x\n", has_erms);
90 | printf("Has FMA3 %x\n", has_fma3);
91 | }
92 | return 0;
93 | }
94 |
95 |
--------------------------------------------------------------------------------
/library/src/main/java/com/library/util/OtherUtil.java:
--------------------------------------------------------------------------------
1 | package com.library.util;
2 |
3 | import java.io.Closeable;
4 | import java.io.File;
5 | import java.io.IOException;
6 | import java.util.concurrent.ArrayBlockingQueue;
7 |
8 | /**
9 | * Created by android1 on 2017/9/25.
10 | */
11 |
12 | public class OtherUtil {
13 | private static final double a = (double) 3 / 4;
14 | private static final double b = (double) 2 / 3;
15 | private static final double c = (double) 9 / 16;
16 | private static final double d = (double) 1 / 2;
17 | private static final double e = (double) 5 / 9;
18 | private static final double f = (double) 3 / 5;
19 | private static final double g = 1;
20 | private static final double h = (double) 9 / 11;
21 |
22 | public static final int QueueNum = 300;
23 |
24 | public static final int waitTime = 0;
25 | public static final int samplerate = 44100;
26 |
27 | public static byte setWeitht(double weitht) {
28 | if (weitht == a) {
29 | return (byte) 'a';
30 | } else if (weitht == b) {
31 | return (byte) 'b';
32 | } else if (weitht == c) {
33 | return (byte) 'c';
34 | } else if (weitht == d) {
35 | return (byte) 'd';
36 | } else if (weitht == e) {
37 | return (byte) 'e';
38 | } else if (weitht == f) {
39 | return (byte) 'f';
40 | } else if (weitht == g) {
41 | return (byte) 'g';
42 | } else if (weitht == h) {
43 | return (byte) 'h';
44 | }
45 | return (byte) 'a';
46 | }
47 |
48 | public static double getWeight(byte weitht) {
49 | double v;
50 | switch (weitht) {
51 | case (byte) 'a':
52 | v = a;
53 | break;
54 | case (byte) 'b':
55 | v = b;
56 | break;
57 | case (byte) 'c':
58 | v = c;
59 | break;
60 | case (byte) 'd':
61 | v = d;
62 | break;
63 | case (byte) 'e':
64 | v = e;
65 | break;
66 | case (byte) 'f':
67 | v = f;
68 | break;
69 | case (byte) 'g':
70 | v = g;
71 | break;
72 | case (byte) 'h':
73 | v = h;
74 | break;
75 | default:
76 | v = a;
77 | break;
78 | }
79 | return v;
80 | }
81 |
82 | public static int getTime() {
83 | return (int) (System.currentTimeMillis() % (long) 1000000000);
84 | }
85 |
86 | public static long getFPS() {
87 | return System.nanoTime() / 1000;
88 | }
89 |
90 | public static void addQueue(ArrayBlockingQueue queue, T t) {
91 | if (queue.size() >= QueueNum) {
92 | queue.poll();
93 | }
94 | queue.offer(t);
95 | }
96 |
97 | public static void close(T t) {
98 | if (t != null) {
99 | try {
100 | t.close();
101 | } catch (IOException e1) {
102 | e1.printStackTrace();
103 | }
104 | }
105 | }
106 |
107 | public static void CreateDirFile(String dirpath) {
108 | File dirfile = new File(dirpath);
109 | if (!dirfile.exists()) {
110 | dirfile.mkdirs();
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/app/src/main/java/com/videolive/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.videolive;
2 |
3 | import android.Manifest;
4 | import android.content.Intent;
5 | import android.content.pm.PackageManager;
6 | import android.os.Bundle;
7 | import android.support.annotation.NonNull;
8 | import android.support.v4.app.ActivityCompat;
9 | import android.support.v7.app.AppCompatActivity;
10 | import android.view.View;
11 | import android.widget.Button;
12 | import android.widget.Toast;
13 |
14 | import com.videolive.video.ReciveReady;
15 | import com.videolive.video.SendReady;
16 | import com.videolive.voice.VoiceReady;
17 |
18 | public class MainActivity extends AppCompatActivity {
19 | private final int REQUEST_CAMERA = 666;
20 | private Button push;
21 | private Button pull;
22 | private Button voice;
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.activity_main);
28 | requestpermission();
29 | }
30 |
31 | private void requestpermission() {
32 | //SD卡读写权限
33 | if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
34 | //权限已授权,功能操作
35 | gostart();
36 | } else {
37 | //未授权,提起权限申请
38 | if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
39 | Toast.makeText(this, "没有权限", Toast.LENGTH_SHORT).show();
40 | gostart();
41 | } else {
42 | //申请权限
43 | ActivityCompat.requestPermissions(this, new String[]{
44 | Manifest.permission.CAMERA,
45 | Manifest.permission.WRITE_EXTERNAL_STORAGE,
46 | Manifest.permission.RECORD_AUDIO
47 | }, REQUEST_CAMERA);
48 | }
49 |
50 | }
51 | }
52 |
53 | private void gostart() {
54 | push = findViewById(R.id.push);
55 | pull = findViewById(R.id.pull);
56 | voice = findViewById(R.id.voice);
57 | push.setOnClickListener(new View.OnClickListener() {
58 | @Override
59 | public void onClick(View view) {
60 | startActivity(new Intent(MainActivity.this, SendReady.class));
61 | }
62 | });
63 | pull.setOnClickListener(new View.OnClickListener() {
64 | @Override
65 | public void onClick(View view) {
66 | startActivity(new Intent(MainActivity.this, ReciveReady.class));
67 | }
68 | });
69 | voice.setOnClickListener(new View.OnClickListener() {
70 | @Override
71 | public void onClick(View view) {
72 | startActivity(new Intent(MainActivity.this, VoiceReady.class));
73 | }
74 | });
75 | }
76 |
77 | @Override
78 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
79 | //判断请求码,确定当前申请的权限
80 | if (requestCode == REQUEST_CAMERA) {
81 | //判断权限是否申请通过
82 | if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
83 | //授权成功
84 | gostart();
85 | } else {
86 | //授权失败
87 | Toast.makeText(this, "没有权限", Toast.LENGTH_SHORT).show();
88 | gostart();
89 | }
90 | } else {
91 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/gyp_libyuv:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2014 The LibYuv Project Authors. All rights reserved.
4 | #
5 | # Use of this source code is governed by a BSD-style license
6 | # that can be found in the LICENSE file in the root of the source
7 | # tree. An additional intellectual property rights grant can be found
8 | # in the file PATENTS. All contributing project authors may
9 | # be found in the AUTHORS file in the root of the source tree.
10 |
11 | # This script is used to run GYP for libyuv. It contains selected parts of the
12 | # main function from the src/build/gyp_chromium file.
13 |
14 | import glob
15 | import os
16 | import shlex
17 | import sys
18 |
19 | checkout_root = os.path.dirname(os.path.realpath(__file__))
20 |
21 | sys.path.insert(0, os.path.join(checkout_root, 'build'))
22 | import gyp_chromium
23 | import gyp_helper
24 | import vs_toolchain
25 |
26 | sys.path.insert(0, os.path.join(checkout_root, 'tools', 'gyp', 'pylib'))
27 | import gyp
28 |
29 | def GetSupplementalFiles():
30 | """Returns a list of the supplemental files that are included in all GYP
31 | sources."""
32 | # Can't use the one in gyp_chromium since the directory location of the root
33 | # is different.
34 | return glob.glob(os.path.join(checkout_root, '*', 'supplement.gypi'))
35 |
36 |
37 | if __name__ == '__main__':
38 | args = sys.argv[1:]
39 |
40 | # This could give false positives since it doesn't actually do real option
41 | # parsing. Oh well.
42 | gyp_file_specified = False
43 | for arg in args:
44 | if arg.endswith('.gyp'):
45 | gyp_file_specified = True
46 | break
47 |
48 | # If we didn't get a file, assume 'all.gyp' in the root of the checkout.
49 | if not gyp_file_specified:
50 | # Because of a bug in gyp, simply adding the abspath to all.gyp doesn't
51 | # work, but chdir'ing and adding the relative path does. Spooky :/
52 | os.chdir(checkout_root)
53 | args.append('all.gyp')
54 |
55 | # There shouldn't be a circular dependency relationship between .gyp files,
56 | args.append('--no-circular-check')
57 |
58 | # Default to ninja unless GYP_GENERATORS is set.
59 | if not os.environ.get('GYP_GENERATORS'):
60 | os.environ['GYP_GENERATORS'] = 'ninja'
61 |
62 | vs2013_runtime_dll_dirs = None
63 | if int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')):
64 | vs2013_runtime_dll_dirs = vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
65 |
66 | # Enforce gyp syntax checking. This adds about 20% execution time.
67 | args.append('--check')
68 |
69 | supplemental_includes = gyp_chromium.GetSupplementalFiles()
70 | gyp_vars_dict = gyp_chromium.GetGypVars(supplemental_includes)
71 |
72 | # Automatically turn on crosscompile support for platforms that need it.
73 | if all(('ninja' in os.environ.get('GYP_GENERATORS', ''),
74 | gyp_vars_dict.get('OS') in ['android', 'ios'],
75 | 'GYP_CROSSCOMPILE' not in os.environ)):
76 | os.environ['GYP_CROSSCOMPILE'] = '1'
77 |
78 | args.extend(['-I' + i for i in
79 | gyp_chromium.additional_include_files(supplemental_includes,
80 | args)])
81 |
82 | # Set the gyp depth variable to the root of the checkout.
83 | args.append('--depth=' + os.path.relpath(checkout_root))
84 |
85 | print 'Updating projects from gyp files...'
86 | sys.stdout.flush()
87 |
88 | # Off we go...
89 | gyp_rc = gyp.main(args)
90 |
91 | if vs2013_runtime_dll_dirs:
92 | x64_runtime, x86_runtime = vs2013_runtime_dll_dirs
93 | vs_toolchain.CopyVsRuntimeDlls(
94 | os.path.join(checkout_root, gyp_chromium.GetOutputDirectory()),
95 | (x86_runtime, x64_runtime))
96 |
97 | sys.exit(gyp_rc)
98 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/third_party/gflags/gen/posix/include/private/config.h:
--------------------------------------------------------------------------------
1 | /* src/config.h. Generated from config.h.in by configure. */
2 | /* src/config.h.in. Generated from configure.ac by autoheader. */
3 |
4 | /* Always the empty-string on non-windows systems. On windows, should be
5 | "__declspec(dllexport)". This way, when we compile the dll, we export our
6 | functions/classes. It's safe to define this here because config.h is only
7 | used internally, to compile the DLL, and every DLL source file #includes
8 | "config.h" before anything else. */
9 | #define GFLAGS_DLL_DECL /**/
10 |
11 | /* Namespace for Google classes */
12 | #define GOOGLE_NAMESPACE ::google
13 |
14 | /* Define to 1 if you have the header file. */
15 | #define HAVE_DLFCN_H 1
16 |
17 | /* Define to 1 if you have the header file. */
18 | #define HAVE_FNMATCH_H 1
19 |
20 | /* Define to 1 if you have the header file. */
21 | #define HAVE_INTTYPES_H 1
22 |
23 | /* Define to 1 if you have the header file. */
24 | #define HAVE_MEMORY_H 1
25 |
26 | /* define if the compiler implements namespaces */
27 | #define HAVE_NAMESPACES 1
28 |
29 | /* Define if you have POSIX threads libraries and header files. */
30 | #define HAVE_PTHREAD 1
31 |
32 | /* Define to 1 if you have the `putenv' function. */
33 | #define HAVE_PUTENV 1
34 |
35 | /* Define to 1 if you have the `setenv' function. */
36 | #define HAVE_SETENV 1
37 |
38 | /* Define to 1 if you have the header file. */
39 | #define HAVE_STDINT_H 1
40 |
41 | /* Define to 1 if you have the header file. */
42 | #define HAVE_STDLIB_H 1
43 |
44 | /* Define to 1 if you have the header file. */
45 | #define HAVE_STRINGS_H 1
46 |
47 | /* Define to 1 if you have the header file. */
48 | #define HAVE_STRING_H 1
49 |
50 | /* Define to 1 if you have the `strtoll' function. */
51 | #define HAVE_STRTOLL 1
52 |
53 | /* Define to 1 if you have the `strtoq' function. */
54 | #define HAVE_STRTOQ 1
55 |
56 | /* Define to 1 if you have the header file. */
57 | #define HAVE_SYS_STAT_H 1
58 |
59 | /* Define to 1 if you have the header file. */
60 | #define HAVE_SYS_TYPES_H 1
61 |
62 | /* Define to 1 if you have the header file. */
63 | #define HAVE_UNISTD_H 1
64 |
65 | /* define if your compiler has __attribute__ */
66 | #define HAVE___ATTRIBUTE__ 1
67 |
68 | /* Define to the sub-directory in which libtool stores uninstalled libraries.
69 | */
70 | #define LT_OBJDIR ".libs/"
71 |
72 | /* Name of package */
73 | #define PACKAGE "gflags"
74 |
75 | /* Define to the address where bug reports for this package should be sent. */
76 | #define PACKAGE_BUGREPORT "opensource@google.com"
77 |
78 | /* Define to the full name of this package. */
79 | #define PACKAGE_NAME "gflags"
80 |
81 | /* Define to the full name and version of this package. */
82 | #define PACKAGE_STRING "gflags 1.5"
83 |
84 | /* Define to the one symbol short name of this package. */
85 | #define PACKAGE_TARNAME "gflags"
86 |
87 | /* Define to the home page for this package. */
88 | #define PACKAGE_URL ""
89 |
90 | /* Define to the version of this package. */
91 | #define PACKAGE_VERSION "1.5"
92 |
93 | /* Define to necessary symbol if this constant uses a non-standard name on
94 | your system. */
95 | /* #undef PTHREAD_CREATE_JOINABLE */
96 |
97 | /* Define to 1 if you have the ANSI C header files. */
98 | #define STDC_HEADERS 1
99 |
100 | /* the namespace where STL code like vector<> is defined */
101 | #define STL_NAMESPACE std
102 |
103 | /* Version number of package */
104 | #define VERSION "1.5"
105 |
106 | /* Stops putting the code inside the Google namespace */
107 | #define _END_GOOGLE_NAMESPACE_ }
108 |
109 | /* Puts following code inside the Google namespace */
110 | #define _START_GOOGLE_NAMESPACE_ namespace google {
111 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/include/libyuv/basic_types.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #ifndef INCLUDE_LIBYUV_BASIC_TYPES_H_ // NOLINT
12 | #define INCLUDE_LIBYUV_BASIC_TYPES_H_
13 |
14 | #include // for NULL, size_t
15 |
16 | #if defined(__ANDROID__) || (defined(_MSC_VER) && (_MSC_VER < 1600))
17 | #include // for uintptr_t on x86
18 | #else
19 | #include // for uintptr_t
20 | #endif
21 |
22 | #ifndef GG_LONGLONG
23 | #ifndef INT_TYPES_DEFINED
24 | #define INT_TYPES_DEFINED
25 | #ifdef COMPILER_MSVC
26 | typedef unsigned __int64 uint64;
27 | typedef __int64 int64;
28 | #ifndef INT64_C
29 | #define INT64_C(x) x ## I64
30 | #endif
31 | #ifndef UINT64_C
32 | #define UINT64_C(x) x ## UI64
33 | #endif
34 | #define INT64_F "I64"
35 | #else // COMPILER_MSVC
36 | #if defined(__LP64__) && !defined(__OpenBSD__) && !defined(__APPLE__)
37 | typedef unsigned long uint64; // NOLINT
38 | typedef long int64; // NOLINT
39 | #ifndef INT64_C
40 | #define INT64_C(x) x ## L
41 | #endif
42 | #ifndef UINT64_C
43 | #define UINT64_C(x) x ## UL
44 | #endif
45 | #define INT64_F "l"
46 | #else // defined(__LP64__) && !defined(__OpenBSD__) && !defined(__APPLE__)
47 | typedef unsigned long long uint64; // NOLINT
48 | typedef long long int64; // NOLINT
49 | #ifndef INT64_C
50 | #define INT64_C(x) x ## LL
51 | #endif
52 | #ifndef UINT64_C
53 | #define UINT64_C(x) x ## ULL
54 | #endif
55 | #define INT64_F "ll"
56 | #endif // __LP64__
57 | #endif // COMPILER_MSVC
58 | typedef unsigned int uint32;
59 | typedef int int32;
60 | typedef unsigned short uint16; // NOLINT
61 | typedef short int16; // NOLINT
62 | typedef unsigned char uint8;
63 | typedef signed char int8;
64 | #endif // INT_TYPES_DEFINED
65 | #endif // GG_LONGLONG
66 |
67 | // Detect compiler is for x86 or x64.
68 | #if defined(__x86_64__) || defined(_M_X64) || \
69 | defined(__i386__) || defined(_M_IX86)
70 | #define CPU_X86 1
71 | #endif
72 | // Detect compiler is for ARM.
73 | #if defined(__arm__) || defined(_M_ARM)
74 | #define CPU_ARM 1
75 | #endif
76 |
77 | #ifndef ALIGNP
78 | #ifdef __cplusplus
79 | #define ALIGNP(p, t) \
80 | (reinterpret_cast(((reinterpret_cast(p) + \
81 | ((t) - 1)) & ~((t) - 1))))
82 | #else
83 | #define ALIGNP(p, t) \
84 | ((uint8*)((((uintptr_t)(p) + ((t) - 1)) & ~((t) - 1)))) /* NOLINT */
85 | #endif
86 | #endif
87 |
88 | #if !defined(LIBYUV_API)
89 | #if defined(_WIN32) || defined(__CYGWIN__)
90 | #if defined(LIBYUV_BUILDING_SHARED_LIBRARY)
91 | #define LIBYUV_API __declspec(dllexport)
92 | #elif defined(LIBYUV_USING_SHARED_LIBRARY)
93 | #define LIBYUV_API __declspec(dllimport)
94 | #else
95 | #define LIBYUV_API
96 | #endif // LIBYUV_BUILDING_SHARED_LIBRARY
97 | #elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__APPLE__) && \
98 | (defined(LIBYUV_BUILDING_SHARED_LIBRARY) || \
99 | defined(LIBYUV_USING_SHARED_LIBRARY))
100 | #define LIBYUV_API __attribute__ ((visibility ("default")))
101 | #else
102 | #define LIBYUV_API
103 | #endif // __GNUC__
104 | #endif // LIBYUV_API
105 |
106 | #define LIBYUV_BOOL int
107 | #define LIBYUV_FALSE 0
108 | #define LIBYUV_TRUE 1
109 |
110 | // Visual C x86 or GCC little endian.
111 | #if defined(__x86_64__) || defined(_M_X64) || \
112 | defined(__i386__) || defined(_M_IX86) || \
113 | defined(__arm__) || defined(_M_ARM) || \
114 | (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
115 | #define LIBYUV_LITTLE_ENDIAN
116 | #endif
117 |
118 | #endif // INCLUDE_LIBYUV_BASIC_TYPES_H_ NOLINT
119 |
--------------------------------------------------------------------------------
/library/src/main/java/com/library/talk/coder/ListenDecoder.java:
--------------------------------------------------------------------------------
1 | package com.library.talk.coder;
2 |
3 | import android.media.MediaCodec;
4 | import android.media.MediaCodecInfo;
5 | import android.media.MediaFormat;
6 |
7 | import com.library.common.VoiceCallback;
8 | import com.library.common.VoicePlayer;
9 | import com.library.util.OtherUtil;
10 | import com.library.util.mLog;
11 |
12 | import java.io.IOException;
13 | import java.nio.ByteBuffer;
14 |
15 | /**
16 | * Created by android1 on 2017/12/25.
17 | */
18 |
19 | public class ListenDecoder implements VoiceCallback {
20 | private final String AAC_MIME = MediaFormat.MIMETYPE_AUDIO_AAC;
21 |
22 | private MediaCodec mDecoder;
23 | private boolean isdecoder = false;
24 | private VoicePlayer voicePlayer;
25 |
26 | public ListenDecoder() {
27 | try {
28 | mDecoder = MediaCodec.createDecoderByType(AAC_MIME);
29 | MediaFormat mediaFormat = new MediaFormat();
30 | mediaFormat.setString(MediaFormat.KEY_MIME, AAC_MIME);
31 | mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2);
32 | mediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, OtherUtil.samplerate);
33 | mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
34 | //用来标记AAC是否有adts头,1->有
35 | mediaFormat.setInteger(MediaFormat.KEY_IS_ADTS, 1);
36 |
37 | byte[] data = new byte[]{(byte) 0x12, (byte) 0x10};
38 | mediaFormat.setByteBuffer("csd-0", ByteBuffer.wrap(data));
39 |
40 | mDecoder.configure(mediaFormat, null, null, 0);
41 | } catch (IOException e) {
42 | e.printStackTrace();
43 | }
44 | mDecoder.start();
45 | }
46 |
47 | public void register(VoicePlayer voicePlayer) {
48 | this.voicePlayer = voicePlayer;
49 | }
50 |
51 | @Override
52 | public void voiceCallback(byte[] voice) {
53 | if (isdecoder) {
54 | decoder(voice);
55 | }
56 | }
57 |
58 | private MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
59 | private int outputBufferIndex;
60 |
61 | public void decoder(byte[] voice) {
62 | try {
63 | int inputBufIndex = mDecoder.dequeueInputBuffer(OtherUtil.waitTime);
64 | if (inputBufIndex >= 0) {
65 | ByteBuffer dstBuf = mDecoder.getInputBuffer(inputBufIndex);
66 | dstBuf.clear();
67 | dstBuf.put(voice, 0, voice.length);
68 | mDecoder.queueInputBuffer(inputBufIndex, 0, voice.length, 0, 0);
69 | } else {
70 | mLog.log("dcoder_failure", "dcoder failure_VC");
71 | return;
72 | }
73 | outputBufferIndex = mDecoder.dequeueOutputBuffer(info, OtherUtil.waitTime);
74 |
75 | while (outputBufferIndex >= 0) {
76 | ByteBuffer outputBuffer = mDecoder.getOutputBuffer(outputBufferIndex);
77 | byte[] outData = new byte[info.size];
78 | outputBuffer.get(outData);
79 | outputBuffer.clear();
80 | if (voicePlayer != null) {
81 | //通过接口回调播放
82 | voicePlayer.voicePlayer(outData);
83 | }
84 | mDecoder.releaseOutputBuffer(outputBufferIndex, false);
85 | outputBufferIndex = mDecoder.dequeueOutputBuffer(info, OtherUtil.waitTime);
86 | }
87 | } catch (Exception e) {
88 | e.printStackTrace();
89 | }
90 | }
91 |
92 | public void start() {
93 | isdecoder = true;
94 | }
95 |
96 | /*
97 | * 释放资源
98 | */
99 | public void stop() {
100 | isdecoder = false;
101 | }
102 |
103 | public void destroy() {
104 | isdecoder = false;
105 | voicePlayer = null;
106 | mDecoder.release();
107 | mDecoder = null;
108 | }
109 | }
110 |
111 |
112 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_voice_send_ready.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
20 |
21 |
29 |
30 |
31 |
35 |
36 |
42 |
43 |
51 |
52 |
53 |
54 |
58 |
59 |
65 |
66 |
74 |
75 |
81 |
82 |
83 |
87 |
88 |
94 |
95 |
103 |
104 |
105 |
106 |
112 |
113 |
--------------------------------------------------------------------------------
/library/src/main/java/com/library/live/vc/VCDecoder.java:
--------------------------------------------------------------------------------
1 | package com.library.live.vc;
2 |
3 | import android.media.MediaCodec;
4 | import android.media.MediaCodecInfo;
5 | import android.media.MediaFormat;
6 |
7 | import com.library.common.VoiceCallback;
8 | import com.library.common.VoicePlayer;
9 | import com.library.live.stream.UdpRecive;
10 | import com.library.util.OtherUtil;
11 | import com.library.util.mLog;
12 |
13 | import java.io.IOException;
14 | import java.nio.ByteBuffer;
15 |
16 | /**
17 | * Created by android1 on 2017/9/23.
18 | */
19 |
20 | public class VCDecoder implements VoiceCallback {
21 | private final String AAC_MIME = MediaFormat.MIMETYPE_AUDIO_AAC;
22 |
23 | private MediaCodec mDecoder;
24 | private boolean isdecoder = false;
25 | private VoicePlayer voicePlayer;
26 |
27 | public VCDecoder(UdpRecive udpRecive) {
28 | udpRecive.setVoiceCallback(this);
29 | try {
30 | mDecoder = MediaCodec.createDecoderByType(AAC_MIME);
31 | MediaFormat mediaFormat = new MediaFormat();
32 | mediaFormat.setString(MediaFormat.KEY_MIME, AAC_MIME);
33 | mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2);
34 | mediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, OtherUtil.samplerate);
35 | mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
36 | //用来标记AAC是否有adts头,1->有
37 | mediaFormat.setInteger(MediaFormat.KEY_IS_ADTS, 1);
38 |
39 | byte[] data = new byte[]{(byte) 0x12, (byte) 0x10};
40 | mediaFormat.setByteBuffer("csd-0", ByteBuffer.wrap(data));
41 |
42 | mDecoder.configure(mediaFormat, null, null, 0);
43 | } catch (IOException e) {
44 | e.printStackTrace();
45 | }
46 | mDecoder.start();
47 | }
48 |
49 | public void register(VoicePlayer voicePlayer) {
50 | this.voicePlayer = voicePlayer;
51 | }
52 |
53 | @Override
54 | public void voiceCallback(byte[] voice) {
55 | if (isdecoder) {
56 | decoder(voice);
57 | }
58 | }
59 |
60 | private MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
61 | private int outputBufferIndex;
62 |
63 | private void decoder(byte[] voice) {
64 | try {
65 | int inputBufIndex = mDecoder.dequeueInputBuffer(OtherUtil.waitTime);
66 | if (inputBufIndex >= 0) {
67 | ByteBuffer dstBuf = mDecoder.getInputBuffer(inputBufIndex);
68 | dstBuf.clear();
69 | dstBuf.put(voice, 0, voice.length);
70 | mDecoder.queueInputBuffer(inputBufIndex, 0, voice.length, 0, 0);
71 | } else {
72 | mLog.log("dcoder_failure", "dcoder failure_VC");
73 | return;
74 | }
75 | outputBufferIndex = mDecoder.dequeueOutputBuffer(info, OtherUtil.waitTime);
76 |
77 | while (outputBufferIndex >= 0) {
78 | ByteBuffer outputBuffer = mDecoder.getOutputBuffer(outputBufferIndex);
79 | byte[] outData = new byte[info.size];
80 | outputBuffer.get(outData);
81 | outputBuffer.clear();
82 | if (voicePlayer != null) {
83 | //通过接口回调播放
84 | voicePlayer.voicePlayer(outData);
85 | }
86 | mDecoder.releaseOutputBuffer(outputBufferIndex, false);
87 | outputBufferIndex = mDecoder.dequeueOutputBuffer(info, OtherUtil.waitTime);
88 | }
89 | } catch (Exception e) {
90 | e.printStackTrace();
91 | }
92 | }
93 |
94 | public void start() {
95 | isdecoder = true;
96 | }
97 |
98 | /**
99 | * 释放资源
100 | */
101 | public void stop() {
102 | isdecoder = false;
103 | }
104 |
105 | public void destroy() {
106 | isdecoder = false;
107 | voicePlayer = null;
108 | mDecoder.release();
109 | mDecoder = null;
110 | }
111 | }
112 |
113 |
--------------------------------------------------------------------------------
/app/src/main/java/com/videolive/video/Send.java:
--------------------------------------------------------------------------------
1 | package com.videolive.video;
2 |
3 | import android.os.Bundle;
4 | import android.os.Environment;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.view.View;
7 | import android.widget.Button;
8 |
9 | import com.library.live.Publish;
10 | import com.library.live.stream.UdpSend;
11 | import com.library.live.view.PublishView;
12 | import com.videolive.R;
13 |
14 | import java.io.File;
15 |
16 | public class Send extends AppCompatActivity {
17 | private Publish publish;
18 | private Button tuistar;
19 | private Button rot;
20 | private Button record;
21 | private Button takePicture;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_send);
27 |
28 | tuistar = findViewById(R.id.tuistar);
29 | rot = findViewById(R.id.rot);
30 | takePicture = findViewById(R.id.takePicture);
31 | record = findViewById(R.id.record);
32 |
33 | publish = new Publish.Buider(this, (PublishView) findViewById(R.id.publishView))
34 | .setPushMode(new UdpSend(getIntent().getExtras().getString("url"), getIntent().getExtras().getInt("port")))
35 | .setFrameRate(getIntent().getExtras().getInt("framerate"))
36 | .setVideoCode(getIntent().getExtras().getString("videoCode"))
37 | .setIsPreview(getIntent().getExtras().getBoolean("ispreview"))
38 | .setPublishBitrate(getIntent().getExtras().getInt("publishbitrate"))
39 | .setCollectionBitrate(getIntent().getExtras().getInt("collectionbitrate"))
40 | .setCollectionBitrateVC(getIntent().getExtras().getInt("collectionbitrate_vc"))
41 | .setPublishBitrateVC(getIntent().getExtras().getInt("publishbitrate_vc"))
42 | .setPublishSize(getIntent().getExtras().getInt("pu_width"), getIntent().getExtras().getInt("pu_height"))
43 | .setPreviewSize(getIntent().getExtras().getInt("pr_width"), getIntent().getExtras().getInt("pr_height"))
44 | .setRotate(getIntent().getExtras().getBoolean("rotate"))
45 | .setVideoDirPath(Environment.getExternalStorageDirectory().getPath() + File.separator + "VideoLive")
46 | .setPictureDirPath(Environment.getExternalStorageDirectory().getPath() + File.separator + "VideoPicture")
47 | .setCenterScaleType(true)
48 | .setScreenshotsMode(Publish.TAKEPHOTO)
49 | .build();
50 |
51 | tuistar.setOnClickListener(new View.OnClickListener() {
52 | @Override
53 | public void onClick(View view) {
54 | if (tuistar.getText().toString().equals("开始推流")) {
55 | publish.start();
56 | tuistar.setText("停止推流");
57 | } else {
58 | publish.stop();
59 | tuistar.setText("开始推流");
60 | }
61 | }
62 | });
63 |
64 | record.setOnClickListener(new View.OnClickListener() {
65 | @Override
66 | public void onClick(View view) {
67 | if (record.getText().toString().equals("开始录制")) {
68 | publish.startRecode();
69 | record.setText("停止录制");
70 | } else {
71 | publish.stopRecode();
72 | record.setText("开始录制");
73 | }
74 | }
75 | });
76 |
77 | takePicture.setOnClickListener(new View.OnClickListener() {
78 | @Override
79 | public void onClick(View view) {
80 | publish.takePicture();
81 | }
82 | });
83 |
84 | rot.setOnClickListener(new View.OnClickListener() {
85 | @Override
86 | public void onClick(View view) {
87 | publish.rotate();
88 | }
89 | });
90 | }
91 |
92 | @Override
93 | protected void onDestroy() {
94 | publish.destroy();
95 | super.onDestroy();
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/BUILD.gn:
--------------------------------------------------------------------------------
1 | # Copyright 2014 The LibYuv Project Authors. All rights reserved.
2 | #
3 | # Use of this source code is governed by a BSD-style license
4 | # that can be found in the LICENSE file in the root of the source
5 | # tree. An additional intellectual property rights grant can be found
6 | # in the file PATENTS. All contributing project authors may
7 | # be found in the AUTHORS file in the root of the source tree.
8 |
9 | import("//build/config/arm.gni")
10 | import("//build/config/sanitizers/sanitizers.gni")
11 |
12 | config("libyuv_config") {
13 | include_dirs = [
14 | ".",
15 | "include",
16 | ]
17 | }
18 |
19 | use_neon = current_cpu == "arm" && (arm_use_neon || arm_optionally_use_neon)
20 |
21 | source_set("libyuv") {
22 | sources = [
23 | "include/libyuv.h",
24 | "include/libyuv/basic_types.h",
25 | "include/libyuv/compare.h",
26 | "include/libyuv/convert.h",
27 | "include/libyuv/convert_argb.h",
28 | "include/libyuv/convert_from.h",
29 | "include/libyuv/convert_from_argb.h",
30 | "include/libyuv/cpu_id.h",
31 | "include/libyuv/mjpeg_decoder.h",
32 | "include/libyuv/planar_functions.h",
33 | "include/libyuv/rotate.h",
34 | "include/libyuv/rotate_argb.h",
35 | "include/libyuv/rotate_row.h",
36 | "include/libyuv/row.h",
37 | "include/libyuv/scale.h",
38 | "include/libyuv/scale_argb.h",
39 | "include/libyuv/scale_row.h",
40 | "include/libyuv/version.h",
41 | "include/libyuv/video_common.h",
42 |
43 | # sources.
44 | "source/compare.cc",
45 | "source/compare_common.cc",
46 | "source/compare_gcc.cc",
47 | "source/compare_win.cc",
48 | "source/convert.cc",
49 | "source/convert_argb.cc",
50 | "source/convert_from.cc",
51 | "source/convert_from_argb.cc",
52 | "source/convert_jpeg.cc",
53 | "source/convert_to_argb.cc",
54 | "source/convert_to_i420.cc",
55 | "source/cpu_id.cc",
56 | "source/mjpeg_decoder.cc",
57 | "source/mjpeg_validate.cc",
58 | "source/planar_functions.cc",
59 | "source/rotate.cc",
60 | "source/rotate_any.cc",
61 | "source/rotate_argb.cc",
62 | "source/rotate_common.cc",
63 | "source/rotate_mips.cc",
64 | "source/rotate_gcc.cc",
65 | "source/rotate_win.cc",
66 | "source/row_any.cc",
67 | "source/row_common.cc",
68 | "source/row_mips.cc",
69 | "source/row_gcc.cc",
70 | "source/row_win.cc",
71 | "source/scale.cc",
72 | "source/scale_any.cc",
73 | "source/scale_argb.cc",
74 | "source/scale_common.cc",
75 | "source/scale_mips.cc",
76 | "source/scale_gcc.cc",
77 | "source/scale_win.cc",
78 | "source/video_common.cc",
79 | ]
80 |
81 | configs -= [ "//build/config/compiler:chromium_code" ]
82 | configs += [ "//build/config/compiler:no_chromium_code" ]
83 |
84 | public_configs = [ ":libyuv_config" ]
85 |
86 | defines = []
87 |
88 | if (!is_ios) {
89 | defines += [ "HAVE_JPEG" ]
90 | }
91 |
92 | if (is_msan) {
93 | # MemorySanitizer does not support assembly code yet.
94 | # http://crbug.com/344505
95 | defines += [ "LIBYUV_DISABLE_X86" ]
96 | }
97 |
98 | deps = [
99 | "//third_party:jpeg",
100 | ]
101 |
102 | if (use_neon) {
103 | deps += [ ":libyuv_neon" ]
104 | }
105 |
106 | if (is_nacl) {
107 | # Always enable optimization under NaCl to workaround crbug.com/538243 .
108 | configs -= [ "//build/config/compiler:default_optimization" ]
109 | configs += [ "//build/config/compiler:optimize_max" ]
110 | }
111 | }
112 |
113 | if (use_neon) {
114 | static_library("libyuv_neon") {
115 | sources = [
116 | "source/compare_neon.cc",
117 | "source/compare_neon64.cc",
118 | "source/rotate_neon.cc",
119 | "source/rotate_neon64.cc",
120 | "source/row_neon.cc",
121 | "source/row_neon64.cc",
122 | "source/scale_neon.cc",
123 | "source/scale_neon64.cc",
124 | ]
125 |
126 | public_configs = [ ":libyuv_config" ]
127 |
128 | configs -= [ "//build/config/compiler:compiler_arm_fpu" ]
129 | cflags = [ "-mfpu=neon" ]
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/library/src/main/cpp/libyuv/include/libyuv/scale.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 | *
4 | * Use of this source code is governed by a BSD-style license
5 | * that can be found in the LICENSE file in the root of the source
6 | * tree. An additional intellectual property rights grant can be found
7 | * in the file PATENTS. All contributing project authors may
8 | * be found in the AUTHORS file in the root of the source tree.
9 | */
10 |
11 | #ifndef INCLUDE_LIBYUV_SCALE_H_ // NOLINT
12 | #define INCLUDE_LIBYUV_SCALE_H_
13 |
14 | #include "libyuv/basic_types.h"
15 |
16 | #ifdef __cplusplus
17 | namespace libyuv {
18 | extern "C" {
19 | #endif
20 |
21 | // Supported filtering.
22 | typedef enum FilterMode {
23 | kFilterNone = 0, // Point sample; Fastest.
24 | kFilterLinear = 1, // Filter horizontally only.
25 | kFilterBilinear = 2, // Faster than box, but lower quality scaling down.
26 | kFilterBox = 3 // Highest quality.
27 | } FilterModeEnum;
28 |
29 | // Scale a YUV plane.
30 | LIBYUV_API
31 | void ScalePlane(const uint8* src, int src_stride,
32 | int src_width, int src_height,
33 | uint8* dst, int dst_stride,
34 | int dst_width, int dst_height,
35 | enum FilterMode filtering);
36 |
37 | LIBYUV_API
38 | void ScalePlane_16(const uint16* src, int src_stride,
39 | int src_width, int src_height,
40 | uint16* dst, int dst_stride,
41 | int dst_width, int dst_height,
42 | enum FilterMode filtering);
43 |
44 | // Scales a YUV 4:2:0 image from the src width and height to the
45 | // dst width and height.
46 | // If filtering is kFilterNone, a simple nearest-neighbor algorithm is
47 | // used. This produces basic (blocky) quality at the fastest speed.
48 | // If filtering is kFilterBilinear, interpolation is used to produce a better
49 | // quality image, at the expense of speed.
50 | // If filtering is kFilterBox, averaging is used to produce ever better
51 | // quality image, at further expense of speed.
52 | // Returns 0 if successful.
53 |
54 | LIBYUV_API
55 | int I420Scale(const uint8* src_y, int src_stride_y,
56 | const uint8* src_u, int src_stride_u,
57 | const uint8* src_v, int src_stride_v,
58 | int src_width, int src_height,
59 | uint8* dst_y, int dst_stride_y,
60 | uint8* dst_u, int dst_stride_u,
61 | uint8* dst_v, int dst_stride_v,
62 | int dst_width, int dst_height,
63 | enum FilterMode filtering);
64 |
65 | LIBYUV_API
66 | int I420Scale_16(const uint16* src_y, int src_stride_y,
67 | const uint16* src_u, int src_stride_u,
68 | const uint16* src_v, int src_stride_v,
69 | int src_width, int src_height,
70 | uint16* dst_y, int dst_stride_y,
71 | uint16* dst_u, int dst_stride_u,
72 | uint16* dst_v, int dst_stride_v,
73 | int dst_width, int dst_height,
74 | enum FilterMode filtering);
75 |
76 | #ifdef __cplusplus
77 | // Legacy API. Deprecated.
78 | LIBYUV_API
79 | int Scale(const uint8* src_y, const uint8* src_u, const uint8* src_v,
80 | int src_stride_y, int src_stride_u, int src_stride_v,
81 | int src_width, int src_height,
82 | uint8* dst_y, uint8* dst_u, uint8* dst_v,
83 | int dst_stride_y, int dst_stride_u, int dst_stride_v,
84 | int dst_width, int dst_height,
85 | LIBYUV_BOOL interpolate);
86 |
87 | // Legacy API. Deprecated.
88 | LIBYUV_API
89 | int ScaleOffset(const uint8* src_i420, int src_width, int src_height,
90 | uint8* dst_i420, int dst_width, int dst_height, int dst_yoffset,
91 | LIBYUV_BOOL interpolate);
92 |
93 | // For testing, allow disabling of specialized scalers.
94 | LIBYUV_API
95 | void SetUseReferenceImpl(LIBYUV_BOOL use);
96 | #endif // __cplusplus
97 |
98 | #ifdef __cplusplus
99 | } // extern "C"
100 | } // namespace libyuv
101 | #endif
102 |
103 | #endif // INCLUDE_LIBYUV_SCALE_H_ NOLINT
104 |
--------------------------------------------------------------------------------
/app/src/main/java/com/videolive/video/SendReady.java:
--------------------------------------------------------------------------------
1 | package com.videolive.video;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.view.View;
7 | import android.view.WindowManager;
8 | import android.widget.Button;
9 | import android.widget.EditText;
10 | import android.widget.RadioGroup;
11 |
12 | import com.library.live.vd.VDEncoder;
13 | import com.videolive.R;
14 |
15 | public class SendReady extends AppCompatActivity {
16 | private EditText url;
17 | private EditText port;
18 | private EditText framerate;
19 | private EditText publishbitrate;
20 | private EditText collectionbitrate;
21 | private EditText pu_width;
22 | private EditText pu_height;
23 | private EditText pr_width;
24 | private EditText pr_height;
25 | private EditText collectionbitrate_vc;
26 | private EditText publishbitrate_vc;
27 | private RadioGroup videoCode;
28 | private RadioGroup preview;
29 | private RadioGroup rotate;
30 | private Button begin;
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_send_ready);
36 |
37 | getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
38 |
39 | url = findViewById(R.id.url);
40 | port = findViewById(R.id.port);
41 | framerate = findViewById(R.id.framerate);
42 | publishbitrate = findViewById(R.id.publishbitrate);
43 | collectionbitrate = findViewById(R.id.collectionbitrate);
44 | pr_width = findViewById(R.id.pr_width);
45 | pr_height = findViewById(R.id.pr_height);
46 | collectionbitrate_vc = findViewById(R.id.collectionbitrate_vc);
47 | publishbitrate_vc = findViewById(R.id.publishbitrate_vc);
48 | pu_width = findViewById(R.id.pu_width);
49 | pu_height = findViewById(R.id.pu_height);
50 | videoCode = findViewById(R.id.svideoCode);
51 | preview = findViewById(R.id.preview);
52 | rotate = findViewById(R.id.rotate);
53 | begin = findViewById(R.id.begin);
54 |
55 | begin.setOnClickListener(new View.OnClickListener() {
56 | @Override
57 | public void onClick(View view) {
58 | start();
59 | }
60 | });
61 | }
62 |
63 | private void start() {
64 | Intent intent = new Intent(this, Send.class);
65 | Bundle bundle = new Bundle();
66 | bundle.putString("url", url.getText().toString());
67 | bundle.putInt("port", Integer.parseInt(port.getText().toString()));
68 | bundle.putInt("framerate", Integer.parseInt(framerate.getText().toString()));
69 | bundle.putInt("publishbitrate", Integer.parseInt(publishbitrate.getText().toString()) * 1024);
70 | bundle.putInt("collectionbitrate", Integer.parseInt(collectionbitrate.getText().toString()) * 1024);
71 | bundle.putInt("collectionbitrate_vc", Integer.parseInt(collectionbitrate_vc.getText().toString()) * 1024);
72 | bundle.putInt("publishbitrate_vc", Integer.parseInt(publishbitrate_vc.getText().toString()) * 1024);
73 | bundle.putInt("pu_width", Integer.parseInt(pu_width.getText().toString()));
74 | bundle.putInt("pu_height", Integer.parseInt(pu_height.getText().toString()));
75 | bundle.putInt("pr_width", Integer.parseInt(pr_width.getText().toString()));
76 | bundle.putInt("pr_height", Integer.parseInt(pr_height.getText().toString()));
77 |
78 | if (videoCode.getCheckedRadioButtonId() == R.id.sh264) {
79 | bundle.putString("videoCode", VDEncoder.H264);
80 | } else {
81 | bundle.putString("videoCode", VDEncoder.H265);
82 | }
83 | if (preview.getCheckedRadioButtonId() == R.id.haspreview) {
84 | bundle.putBoolean("ispreview", true);
85 | } else {
86 | bundle.putBoolean("ispreview", false);
87 | }
88 | if (rotate.getCheckedRadioButtonId() == R.id.front) {
89 | bundle.putBoolean("rotate", true);
90 | } else {
91 | bundle.putBoolean("rotate", false);
92 | }
93 |
94 | intent.putExtras(bundle);
95 | startActivity(intent);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/library/src/main/java/com/library/live/Player.java:
--------------------------------------------------------------------------------
1 | package com.library.live;
2 |
3 | import com.library.common.UdpControlInterface;
4 | import com.library.live.stream.UdpRecive;
5 | import com.library.live.vc.VoiceTrack;
6 | import com.library.live.vd.VDDecoder;
7 | import com.library.live.view.PlayerView;
8 |
9 | /**
10 | * Created by android1 on 2017/10/13.
11 | */
12 |
13 | public class Player {
14 | private VDDecoder vdDecoder;
15 | private VoiceTrack voiceTrack;
16 | private UdpRecive udpRecive;
17 | private PlayerView playerView;
18 |
19 | private Player(PlayerView playerView, String codetype, UdpRecive udpRecive, UdpControlInterface udpControl, int multiple) {
20 | this.udpRecive = udpRecive;
21 | this.playerView = playerView;
22 | this.udpRecive.setUdpControl(udpControl);
23 |
24 | vdDecoder = new VDDecoder(playerView, codetype, udpRecive);
25 | voiceTrack = new VoiceTrack(udpRecive);
26 | voiceTrack.setIncreaseMultiple(multiple);
27 | }
28 |
29 | public void setVoiceIncreaseMultiple(int multiple) {
30 | voiceTrack.setIncreaseMultiple(multiple);
31 | }
32 |
33 |
34 | public void start() {
35 | voiceTrack.start();
36 | vdDecoder.start();
37 | udpRecive.startRevice();
38 | }
39 |
40 | public void stop() {
41 | udpRecive.stopRevice();
42 | vdDecoder.stop();
43 | voiceTrack.stop();
44 | playerView.stop();
45 | }
46 |
47 | public void destroy() {
48 | udpRecive.destroy();
49 | vdDecoder.destroy();
50 | voiceTrack.destroy();
51 | }
52 |
53 | public void write(byte[] bytes) {
54 | udpRecive.write(bytes);
55 | }
56 |
57 | public int getReciveStatus() {
58 | return udpRecive.getReciveStatus();
59 | }
60 |
61 | public static class Buider {
62 | private PlayerView playerView;
63 | private UdpRecive udpRecive;
64 | private String codetype = VDDecoder.H264;
65 | private UdpControlInterface udpControl = null;
66 | private int multiple = 1;
67 |
68 | private IsOutBuffer isOutBuffer = null;//缓冲接口回调
69 |
70 | public Buider(PlayerView playerView) {
71 | this.playerView = playerView;
72 | }
73 |
74 | public Buider setVideoCode(String codetype) {
75 | this.codetype = codetype;
76 | return this;
77 | }
78 |
79 |
80 | public Buider setPullMode(UdpRecive udpRecive) {
81 | this.udpRecive = udpRecive;
82 | return this;
83 | }
84 |
85 | public Buider setUdpControl(UdpControlInterface udpControl) {
86 | this.udpControl = udpControl;
87 | return this;
88 | }
89 |
90 | public Buider setMultiple(int multiple) {
91 | this.multiple = multiple;
92 | return this;
93 | }
94 |
95 | public Buider setUdpPacketCacheMin(int udpPacketCacheMin) {
96 | udpRecive.setUdpPacketCacheMin(udpPacketCacheMin);
97 | return this;
98 | }
99 |
100 | public Buider setVideoFrameCacheMin(int videoFrameCacheMin) {
101 | udpRecive.setOther(videoFrameCacheMin);
102 | return this;
103 | }
104 |
105 |
106 | public Buider setIsOutBuffer(IsOutBuffer isOutBuffer) {
107 | this.isOutBuffer = isOutBuffer;
108 | return this;
109 | }
110 |
111 | public Buider setBufferAnimator(boolean bufferAnimator) {
112 | playerView.setBufferAnimator(bufferAnimator);
113 | return this;
114 | }
115 |
116 | public Buider setCenterScaleType(boolean isCenterScaleType) {
117 | playerView.setCenterScaleType(isCenterScaleType);
118 | return this;
119 | }
120 |
121 | public Player build() {
122 | udpRecive.setWeightCallback(playerView);//将playerView接口设置给baseRecive用以回调图像比例
123 | udpRecive.setIsInBuffer(playerView);//将playerView接口设置给baseRecive用以回调缓冲状态
124 | playerView.setIsOutBuffer(isOutBuffer);//给playerView设置isOutBuffer接口用以将缓冲状态回调给客户端
125 | return new Player(playerView, codetype, udpRecive, udpControl, multiple);
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/library/src/main/java/com/library/talk/coder/SpeakRecord.java:
--------------------------------------------------------------------------------
1 | package com.library.talk.coder;
2 |
3 | import android.media.AudioFormat;
4 | import android.media.AudioRecord;
5 | import android.media.MediaRecorder;
6 |
7 | import com.library.common.WriteFileCallback;
8 | import com.library.talk.stream.SpeakSend;
9 | import com.library.util.OtherUtil;
10 | import com.library.util.SingleThreadExecutor;
11 | import com.library.util.mLog;
12 |
13 | /**
14 | * Created by android1 on 2017/12/23.
15 | */
16 |
17 | public class SpeakRecord {
18 | private int recBufSize;
19 | private AudioRecord audioRecord;
20 | private SingleThreadExecutor singleThreadExecutor = null;
21 | private SpeakEncoder speakEncoder;
22 | private double decibel = 0;//平均振幅,用于计算分贝
23 |
24 | public SpeakRecord(int publishBitrate, SpeakSend speakSend, String dirpath) {
25 | recBufSize = AudioRecord.getMinBufferSize(
26 | OtherUtil.samplerate,
27 | AudioFormat.CHANNEL_IN_STEREO,
28 | AudioFormat.ENCODING_PCM_16BIT);
29 | audioRecord = new AudioRecord(
30 | MediaRecorder.AudioSource.VOICE_COMMUNICATION,//降噪配置
31 | OtherUtil.samplerate,
32 | AudioFormat.CHANNEL_IN_STEREO,
33 | AudioFormat.ENCODING_PCM_16BIT,
34 | recBufSize);
35 | singleThreadExecutor = new SingleThreadExecutor();
36 | speakEncoder = new SpeakEncoder(publishBitrate, recBufSize, speakSend, dirpath);
37 | }
38 |
39 | public void start() {
40 | if (audioRecord != null && audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_STOPPED) {
41 | speakEncoder.start();
42 | audioRecord.startRecording();
43 | startRead();
44 | }
45 | }
46 |
47 | public void stop() {
48 | if (audioRecord != null && audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
49 | audioRecord.stop();
50 | speakEncoder.stop();
51 | }
52 | }
53 |
54 | public void startRecord() {
55 | speakEncoder.startRecord();
56 | }
57 |
58 | public void stopRecord() {
59 | speakEncoder.stopRecord();
60 | }
61 |
62 | private void startRead() {
63 | singleThreadExecutor.execute(new Runnable() {
64 | @Override
65 | public void run() {
66 | byte[] buffer = new byte[recBufSize];
67 | int bufferReadResult;
68 | while (audioRecord != null && audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
69 | /*
70 | 两针间采集大概40ms,编码发送大概10ms,单线程顺序执行没有问题
71 | */
72 | bufferReadResult = audioRecord.read(buffer, 0, recBufSize);
73 |
74 | if (bufferReadResult == AudioRecord.ERROR_INVALID_OPERATION || bufferReadResult == AudioRecord.ERROR_BAD_VALUE || bufferReadResult == 0 || bufferReadResult == -1) {
75 | continue;
76 | }
77 | speakEncoder.encode(buffer, bufferReadResult);
78 | setDecibel(buffer, bufferReadResult / 2);
79 | }
80 | mLog.log("interrupt_Thread", "speak关闭线程");
81 | }
82 | });
83 | }
84 |
85 | private void setDecibel(byte[] buffer, int length) {
86 | long a = 0;
87 | for (int i = 0; i < length; i++) {
88 | a += Math.abs((short) ((buffer[i * 2] & 0xff) | (buffer[2 * i + 1] & 0xff) << 8));
89 | }
90 | decibel = a / (double) length;
91 | }
92 |
93 | public int getDecibel() {
94 | return (int) (20 * Math.log10(Math.max(1, Math.min(32767, decibel))));
95 | }
96 |
97 | public void destroy() {
98 | singleThreadExecutor.shutdownNow();
99 | if (audioRecord != null) {
100 | audioRecord.release();
101 | audioRecord = null;
102 | }
103 | speakEncoder.destroy();
104 | }
105 |
106 | public int getRecodeStatus() {
107 | return speakEncoder.getRecodeStatus();
108 | }
109 |
110 | public void setWriteFileCallback(WriteFileCallback writeFileCallback) {
111 | speakEncoder.setWriteFileCallback(writeFileCallback);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------