Skip to content

Commit 17838ed

Browse files
author
limin
committed
增加audioplayer
1 parent 3431e14 commit 17838ed

6 files changed

Lines changed: 261 additions & 2 deletions

File tree

codec_native/src/main/cpp/native/processor/Java_VideoProcessor.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ JNIEXPORT void JNICALL Java_com_lmy_hwvcnative_processor_VideoProcessor_setSourc
3737
char *str = new char[len];
3838
memcpy(str, pPath, len);
3939
getHandler(handler)->setSource(str);
40-
delete[]str;
4140
env->ReleaseStringUTFChars(path, pPath);
4241
}
4342
}

hwvc/src/codec/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ file(
6969
${PROJECT_SOURCE_DIR}/*cpp
7070
${PROJECT_SOURCE_DIR}/decoder/*cpp
7171
${PROJECT_SOURCE_DIR}/entity/*cpp
72+
${PROJECT_SOURCE_DIR}/media/*cpp
7273
)
7374
add_library( # Sets the name of the library.
7475
hwvc_codec
@@ -97,4 +98,5 @@ target_link_libraries( # Specifies the target library.
9798
hwvcom
9899
# Links the target library to the log library
99100
# included in the NDK.
101+
OpenSLES
100102
${log-lib})
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2018-present, lmyooyo@gmail.com.
3+
*
4+
* This source code is licensed under the GPL license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
#ifndef HARDWAREVIDEOCODEC_AUDIOPLAYER_H
8+
#define HARDWAREVIDEOCODEC_AUDIOPLAYER_H
9+
10+
#include <string>
11+
#include "../log/log.h"
12+
#include <SLES/OpenSLES.h>
13+
#include <SLES/OpenSLES_Android.h>
14+
#include <Object.h>
15+
16+
using namespace std;
17+
18+
class AudioPlayer : public Object {
19+
public:
20+
AudioPlayer(int channels, int sampleHz);
21+
22+
virtual ~AudioPlayer();
23+
24+
virtual int start();
25+
26+
virtual void stop();
27+
28+
virtual int write(uint8_t *buffer, size_t size);
29+
30+
string getString();
31+
32+
uint8_t *readBuffer(size_t *size);
33+
34+
private:
35+
unsigned int channels = 0;
36+
unsigned int sampleHz = 0;
37+
bool requestRead = false;
38+
size_t size = 0;
39+
uint8_t *buffer = nullptr;
40+
size_t quietSize = 0;
41+
uint8_t *quietBuffer = nullptr;
42+
SLObjectItf engineObject = nullptr;
43+
SLEngineItf engineItf = nullptr;
44+
SLObjectItf mixObject = nullptr;
45+
SLObjectItf playObject = nullptr;
46+
SLPlayItf playItf = nullptr;
47+
SLBufferQueueItf bufferQueueItf = nullptr;
48+
slBufferQueueCallback callback = [](SLBufferQueueItf slBufferQueueItf, void *context) {
49+
AudioPlayer *player = static_cast<AudioPlayer *>(context);
50+
size_t size = 0;
51+
uint8_t *buf = player->readBuffer(&size);
52+
// LOGE("getQueueCallBack, size=%d", size);
53+
(*slBufferQueueItf)->Enqueue(slBufferQueueItf, buf, size);
54+
};
55+
56+
int createEngine();
57+
58+
void destroyEngine();
59+
60+
int createBufferQueueAudioPlayer();
61+
};
62+
63+
64+
#endif //HARDWAREVIDEOCODEC_AUDIOPLAYER_H
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/*
2+
* Copyright (c) 2018-present, lmyooyo@gmail.com.
3+
*
4+
* This source code is licensed under the GPL license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
#include "../include/AudioPlayer.h"
8+
9+
AudioPlayer::AudioPlayer(int channels, int sampleHz) {
10+
this->channels = channels;
11+
this->sampleHz = sampleHz;
12+
this->quietSize = static_cast<size_t>(sampleHz / 1000 * 2);
13+
this->quietBuffer = static_cast<uint8_t *>(malloc(this->quietSize));
14+
memset(this->quietBuffer, 0, this->quietSize);
15+
LOGI("Create AudioPlayer, channels=%d, sampleHz=%d, quietSize=%d",
16+
this->channels,
17+
this->sampleHz,
18+
this->quietSize);
19+
engineObject = nullptr;
20+
engineItf = nullptr;
21+
mixObject = nullptr;
22+
playObject = nullptr;
23+
playItf = nullptr;
24+
}
25+
26+
AudioPlayer::~AudioPlayer() {
27+
LOGI("~AudioPlayer");
28+
stop();
29+
}
30+
31+
int AudioPlayer::createEngine() {
32+
SLresult result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
33+
if (SL_RESULT_SUCCESS != result) {
34+
LOGE("slCreateEngine failed!");
35+
return 0;
36+
}
37+
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
38+
if (SL_RESULT_SUCCESS != result) {
39+
LOGE("Engine Realize failed!");
40+
return 0;
41+
}
42+
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineItf);
43+
if (SL_RESULT_SUCCESS != result) {
44+
LOGE("Engine GetInterface failed!");
45+
return 0;
46+
}
47+
48+
result = (*engineItf)->CreateOutputMix(engineItf, &mixObject, 0, nullptr, nullptr);
49+
if (SL_RESULT_SUCCESS != result) {
50+
LOGE("CreateOutputMix failed!");
51+
return 0;
52+
}
53+
result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE);
54+
if (SL_RESULT_SUCCESS != result) {
55+
LOGE("OutputMix Realize failed!");
56+
return 0;
57+
}
58+
return createBufferQueueAudioPlayer();
59+
}
60+
61+
int AudioPlayer::start() {
62+
int ret = createEngine();
63+
if (!ret) {
64+
stop();
65+
}
66+
return ret;
67+
}
68+
69+
string AudioPlayer::getString() {
70+
return "Test";
71+
}
72+
73+
uint8_t *AudioPlayer::readBuffer(size_t *size) {
74+
if (!requestRead) {
75+
*size = this->quietSize;
76+
return this->quietBuffer;
77+
}
78+
requestRead = false;
79+
*size = this->size;
80+
return this->buffer;
81+
}
82+
83+
static SLuint32 getChannelMask(int channels) {
84+
switch (channels) {
85+
case 1:
86+
return SL_SPEAKER_FRONT_CENTER;
87+
case 3:
88+
return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER;
89+
case 2:
90+
default:
91+
return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
92+
}
93+
}
94+
95+
int AudioPlayer::createBufferQueueAudioPlayer() {
96+
SLDataLocator_BufferQueue queue = {SL_DATALOCATOR_BUFFERQUEUE, 2};
97+
SLDataFormat_PCM pcm = {SL_DATAFORMAT_PCM,
98+
channels,
99+
sampleHz * 1000,
100+
SL_PCMSAMPLEFORMAT_FIXED_16,
101+
SL_PCMSAMPLEFORMAT_FIXED_16,
102+
getChannelMask(channels),
103+
SL_BYTEORDER_LITTLEENDIAN};
104+
SLDataSource dataSource = {&queue, &pcm};
105+
SLDataLocator_OutputMix slDataLocator_outputMix = {SL_DATALOCATOR_OUTPUTMIX, mixObject};
106+
SLDataSink slDataSink = {&slDataLocator_outputMix, NULL};
107+
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
108+
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
109+
SLresult result = (*engineItf)->CreateAudioPlayer(engineItf,
110+
&playObject,
111+
&dataSource,
112+
&slDataSink,
113+
2,
114+
ids,
115+
req);
116+
if (SL_RESULT_SUCCESS != result) {
117+
LOGE("CreateAudioPlayer failed! ret=%d", result);
118+
return 0;
119+
}
120+
result = (*playObject)->Realize(playObject, SL_BOOLEAN_FALSE);
121+
if (SL_RESULT_SUCCESS != result) {
122+
LOGE("Player Realize failed!");
123+
return 0;
124+
}
125+
result = (*playObject)->GetInterface(playObject, SL_IID_PLAY, &playItf);
126+
if (SL_RESULT_SUCCESS != result) {
127+
LOGE("Player GetInterface failed!");
128+
return 0;
129+
}
130+
result = (*playObject)->GetInterface(playObject, SL_IID_BUFFERQUEUE, &bufferQueueItf);
131+
if (SL_RESULT_SUCCESS != result) {
132+
LOGE("Player GetInterface buffer queue failed!");
133+
return 0;
134+
}
135+
result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
136+
if (SL_RESULT_SUCCESS != result) {
137+
LOGE("Player SetPlayState stop failed!");
138+
return 0;
139+
}
140+
result = (*bufferQueueItf)->RegisterCallback(bufferQueueItf,
141+
callback,
142+
this);
143+
if (SL_RESULT_SUCCESS != result) {
144+
LOGE("Player RegisterCallback failed!");
145+
return 0;
146+
}
147+
result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
148+
if (SL_RESULT_SUCCESS != result) {
149+
LOGE("Player SetPlayState start failed!");
150+
return 0;
151+
}
152+
callback(bufferQueueItf, this);
153+
return 1;
154+
}
155+
156+
int AudioPlayer::write(uint8_t *buffer, size_t size) {
157+
this->size = size;
158+
this->buffer = buffer;
159+
this->requestRead = true;
160+
// (*bufferQueueItf)->Clear(bufferQueueItf);
161+
return 1;
162+
}
163+
164+
void AudioPlayer::stop() {
165+
destroyEngine();
166+
if (nullptr != quietBuffer) {
167+
free(quietBuffer);
168+
quietBuffer = nullptr;
169+
quietSize = 0;
170+
}
171+
callback = nullptr;
172+
}
173+
174+
void AudioPlayer::destroyEngine() {
175+
if (nullptr != playObject) {
176+
(*playObject)->Destroy(playObject);
177+
playObject = nullptr;
178+
bufferQueueItf = nullptr;
179+
playItf = nullptr;
180+
}
181+
if (nullptr != mixObject) {
182+
(*mixObject)->Destroy(mixObject);
183+
mixObject = nullptr;
184+
}
185+
if (nullptr != engineObject) {
186+
(*engineObject)->Destroy(engineObject);
187+
engineObject = nullptr;
188+
engineItf = nullptr;
189+
}
190+
}

hwvc/src/render/units/Video.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ void Video::release() {
4848
delete decoder;
4949
decoder = nullptr;
5050
}
51+
if (path) {
52+
delete[]path;
53+
path = nullptr;
54+
}
5155
}
5256

5357
bool Video::eventPrepare(Message *msg) {

samplenative/src/main/java/com/lmy/samplenative/VideoActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class VideoActivity : BaseActivity(), TextureView.SurfaceTextureListener {
2222
// mFilterController.chooseFilter(this)
2323
processor?.start()
2424
}
25-
processor?.setSource("${Environment.getExternalStorageDirectory().path}/out.mp4")
25+
processor?.setSource("${Environment.getExternalStorageDirectory().path}/002.mp4")
2626
surfaceView.keepScreenOn = true
2727
surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
2828
override fun surfaceChanged(holder: SurfaceHolder?, p1: Int, p2: Int, p3: Int) {

0 commit comments

Comments
 (0)