Skip to content

Commit

Permalink
临时提交一下,
Browse files Browse the repository at this point in the history
  • Loading branch information
yetote committed Sep 16, 2019
1 parent a921b30 commit 89849d6
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 133 deletions.
7 changes: 4 additions & 3 deletions app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)
set(PATH_PROJECT D:/AndroidStudioWorkSpace/BambooMusic)
set(LIBS_PATH ${PATH_PROJECT}/app/libs)
set(OBOE_PATH D:/otherlib/oboe-1.2.0)

set(PATH_PROJECT D:/AndroidStudioProjects/BambooMusic)
set(LIBS_PATH ${PATH_PROJECT}/app/libs)
set(OBOE_PATH D:/audiotest/oboe-1.2.0)
file(GLOB util_lib "util/*.cpp")

add_subdirectory(${OBOE_PATH} ./oboe)
Expand Down Expand Up @@ -95,6 +95,7 @@ add_library( # Sets the name of the library.
decode/HardwareDecode.cpp
util/Callback.cpp
util/PlayStates.cpp
util/MediaInfo.cpp
audio/AudioPlay.cpp
video/EGLUtil.cpp
video/GLUtil.cpp
Expand Down
256 changes: 138 additions & 118 deletions app/src/main/cpp/decode/HardwareDecode.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// Created by ether on 2019/9/5.
//

Expand All @@ -11,35 +11,31 @@ int64_t systemnanotime() {
}

// @formatter:off
HardwareDecode::HardwareDecode(PlayStates &playStates, const Callback &callback) : playStates(
playStates), callback(callback) {
HardwareDecode::HardwareDecode(PlayStates &_playStates, const Callback &_callback) : playStates(_playStates), callback(_callback) {
// @formatter:on

}

// @formatter:off
HardwareDecode::HardwareDecode(AudioPlay *audioPlay, PlayStates &playStates,
const Callback &callback) : audioPlay(audioPlay),
playStates(playStates),
callback(callback) {
HardwareDecode::HardwareDecode(AudioPlay *_audioPlay, PlayStates &_playStates,const Callback &_callback) : audioPlay(_audioPlay),playStates(_playStates),callback(_callback) {
// @formatter:on
std::string path = "/storage/emulated/0/Android/data/com.yetote.bamboomusic/files/test.pcm";
file = fopen(path.c_str(), "wb+");
audioInfo = std::make_shared<MediaInfo>(MediaInfo::MEDIA_TYPE_AUDIO);
}

// @formatter:off
HardwareDecode::HardwareDecode(AudioPlay *audioPlay, VideoPlayer *videoPlayer,
PlayStates &playStates, const Callback &callback) : audioPlay(
audioPlay), videoPlayer(videoPlayer), playStates(playStates), callback(callback) {
HardwareDecode::HardwareDecode(AudioPlay *_audioPlay, VideoPlayer *_videoPlayer,PlayStates &_playStates, const Callback &_callback) : audioPlay(_audioPlay), videoPlayer(_videoPlayer), playStates(_playStates), callback(_callback) {
// @formatter:on

audioInfo = std::make_shared<MediaInfo>(MediaInfo::MEDIA_TYPE_AUDIO);
videoInfo = std::make_shared<MediaInfo>(MediaInfo::MEDIA_TYPE_VIDEO);
}

bool HardwareDecode::checkSupport(std::string path) {
bool HardwareDecode::checkSupport(std::string _path) {

media_status_t rst;
AMediaExtractor *pMediaExtractor = AMediaExtractor_new();
rst = AMediaExtractor_setDataSource(pMediaExtractor, path.c_str());
auto pMediaExtractor = AMediaExtractor_new();
rst = AMediaExtractor_setDataSource(pMediaExtractor, _path.c_str());
if (rst != AMEDIA_OK) {
LOGE(HardwareDecode_TAG, "%s:无法打开文件", __func__);
return false;
Expand All @@ -55,72 +51,88 @@ bool HardwareDecode::checkSupport(std::string path) {
return false;
} else if (strncmp(mime, "video/", 6) == 0) {
LOGE(HardwareDecode_TAG, "%s:找到视频解码器", __func__);
pVideoMediaExtractor = pMediaExtractor;
AMediaExtractor_selectTrack(pVideoMediaExtractor, i);
pVideoCodec = AMediaCodec_createDecoderByType(mime);
pVideoFmt = pFmt;
// LOGE(HardwareDecode_TAG, "%s:window%p", __func__,pWindow);

if (videoInfo) {
videoInfo->extractor = AMediaExtractor_new();
rst = AMediaExtractor_setDataSource(videoInfo->extractor, _path.c_str());
if (rst != AMEDIA_OK) {
LOGE(HardwareDecode_TAG, "%s:初始化视频解码器失败", __func__);
videoInfo->isSuccess = false;
}
AMediaExtractor_selectTrack(videoInfo->extractor, i);
videoInfo->codec = AMediaCodec_createDecoderByType(mime);
//todo pwindow这时无法获取
AMediaCodec_configure(audioInfo->codec, pFmt, nullptr, nullptr, 0);
}
} else if (strncmp(mime, "audio/", 6) == 0) {
// LOGE(HardwareDecode_TAG, "%s:找到音频解码器", __func__);
// int64_t totalTime = 0;
// AMediaFormat_getInt64(pFmt, "durationUs", &totalTime);
// audioPlay->totalTime = totalTime / 1000000;
// auto srst = AMediaFormat_getInt32(pFmt, "sample-rate", &sampleRate);
// if (!srst) {
// LOGE(HardwareDecode_TAG, "%s:获取采样率失败", __func__);
// sampleRate = 0;
// }
// auto crst = AMediaFormat_getInt32(pFmt, "channel-count", &channelCount);
// if (!crst) {
// LOGE(HardwareDecode_TAG, "%s:获取音频通道数失败", __func__);
// channelCount = 0;
// }
//
// pAudioMediaExtractor = pMediaExtractor;
// AMediaExtractor_selectTrack(pAudioMediaExtractor, i);
// pAudioCodec = AMediaCodec_createDecoderByType(mime);
// AMediaCodec_configure(pAudioCodec, pFmt, nullptr, nullptr, 0);
// AMediaCodec_start(pAudioCodec);
LOGE(HardwareDecode_TAG, "%s:找到音频解码器", __func__);
int64_t totalTime = 0;
AMediaFormat_getInt64(pFmt, "durationUs", &totalTime);
audioPlay->totalTime = totalTime / 1000000;
auto srst = AMediaFormat_getInt32(pFmt, "sample-rate", &sampleRate);
if (!srst) {
LOGE(HardwareDecode_TAG, "%s:获取采样率失败", __func__);
sampleRate = 0;
}
auto crst = AMediaFormat_getInt32(pFmt, "channel-count", &channelCount);
if (!crst) {
LOGE(HardwareDecode_TAG, "%s:获取音频通道数失败", __func__);
channelCount = 0;
}
if (audioInfo) {
audioInfo->extractor = AMediaExtractor_new();
rst = AMediaExtractor_setDataSource(audioInfo->extractor, _path.c_str());
if (rst != AMEDIA_OK) {
LOGE(HardwareDecode_TAG, "%s:初始化音频解码器失败", __func__);
audioInfo->isSuccess = false;
}
AMediaExtractor_selectTrack(audioInfo->extractor, i);
audioInfo->codec = AMediaCodec_createDecoderByType(mime);
AMediaCodec_configure(audioInfo->codec, pFmt, nullptr, nullptr, 0);
// AMediaCodec_start(pAudioCodec);
}
} else {
LOGE(HardwareDecode_TAG, "%s:非音轨或视频轨", __func__);
}
LOGE(HardwareDecode_TAG, "%s:释放fmt", __func__);
// AMediaFormat_delete(pFmt);
AMediaFormat_delete(pFmt);
}

AMediaExtractor_delete(pMediaExtractor);
return true;
}


void HardwareDecode::doDecodeWork() {
AMediaCodec_configure(pVideoCodec, pVideoFmt, pWindow, nullptr, 0);
AMediaCodec_start(pVideoCodec);
void HardwareDecode::doDecodeWork(std::shared_ptr<MediaInfo> _sharedPtr) {
int count = 0;
if (!_sharedPtr->isSuccess) {
return;
}
//todo 这时需要启动codec
while (!playStates.isStop()) {
if (playStates.isPause()) {
usleep(300000);
continue;
}
mutex.lock();
if (!isInputEOF) {
auto inputIndex = AMediaCodec_dequeueInputBuffer(pVideoCodec, -1);
if (!_sharedPtr->isInputEof) {
auto inputIndex = AMediaCodec_dequeueInputBuffer(_sharedPtr->codec, -1);
if (inputIndex >= 0) {
size_t bufsize;
auto inputBuffer = AMediaCodec_getInputBuffer(pVideoCodec, inputIndex, &bufsize);
auto dataSize = AMediaExtractor_readSampleData(pVideoMediaExtractor, inputBuffer,
auto inputBuffer = AMediaCodec_getInputBuffer(_sharedPtr->codec, inputIndex,
&bufsize);
auto dataSize = AMediaExtractor_readSampleData(_sharedPtr->extractor, inputBuffer,
bufsize);
if (dataSize < 0) {
dataSize = 0;
isInputEOF = true;
_sharedPtr->isInputEof = true;
LOGE(HardwareDecode_TAG, "%s:全部数据读取完毕", __func__);
}
auto presentationTimeUs = AMediaExtractor_getSampleTime(pVideoMediaExtractor);
AMediaCodec_queueInputBuffer(pVideoCodec, inputIndex, 0, dataSize,
auto presentationTimeUs = AMediaExtractor_getSampleTime(_sharedPtr->extractor);
AMediaCodec_queueInputBuffer(_sharedPtr->codec, inputIndex, 0, dataSize,
presentationTimeUs,
isInputEOF ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM
: 0);
AMediaExtractor_advance(pVideoMediaExtractor);
_sharedPtr->isInputEof
? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0);

AMediaExtractor_advance(_sharedPtr->extractor);
} else {
LOGE(HardwareDecode_TAG, "%s:放入数据失败,索引=%d", __func__, inputIndex);
// LOGE(HardwareDecode_TAG,"%s:s",__func__);
Expand All @@ -129,47 +141,53 @@ void HardwareDecode::doDecodeWork() {
}
}

if (!isOutputEOF) {
if (!_sharedPtr->isOutputEof) {
AMediaCodecBufferInfo info;
auto outputIndex = AMediaCodec_dequeueOutputBuffer(pVideoCodec, &info, 0);
auto outputIndex = AMediaCodec_dequeueOutputBuffer(_sharedPtr->codec, &info, 0);
if (outputIndex >= 0) {
if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
LOGE(HardwareDecode_TAG, "%s:解码数据全部取出", __func__);
isOutputEOF = true;
}
int64_t presentationNano = info.presentationTimeUs * 1000;
if (renderstart < 0) {
renderstart = presentationNano;
_sharedPtr->isOutputEof = true;
}
// audioPlay->currentTime = (info.presentationTimeUs) / 1000000;

auto readSize = info.size;
size_t bufSize;
uint8_t *buffer = AMediaCodec_getOutputBuffer(pVideoCodec, outputIndex, &bufSize);
if (bufSize < 0) {
LOGE(HardwareDecode_TAG, "%s:未读出解码数据%d", __func__, bufSize);
// mutex.unlock();
continue;

if (_sharedPtr->type == MediaInfo::MEDIA_TYPE_AUDIO) {
auto readSize = info.size;
size_t bufSize;
uint8_t *buffer = AMediaCodec_getOutputBuffer(_sharedPtr->codec, outputIndex,
&bufSize);
if (bufSize < 0) {
LOGE(HardwareDecode_TAG, "%s:未读出解码数据%d", __func__, bufSize);
continue;
}
uint8_t *data = new uint8_t[bufSize];
memcpy(data, buffer + info.offset, info.size);
LOGE(HardwareDecode_TAG, "%s:size=%d", __func__, info.size);
while (!audioPlay->canPush(info.size)) {
usleep(300000);
LOGE(HardwareDecode_TAG, "%s:休眠", __func__);
}
LOGE(HardwareDecode_TAG, "%s:开始填充数据", __func__);
audioPlay->pushData(data, info.size);
LOGE(HardwareDecode_TAG, "%s:数据填充完成", __func__);
delete[] data;
} else {
int64_t presentationNano = info.presentationTimeUs * 1000;
if (_sharedPtr->renderStart < 0) {
_sharedPtr->renderStart = systemnanotime() - presentationNano;
}
int64_t delay = (_sharedPtr->renderStart + presentationNano) - systemnanotime();
if (delay > 0) {
usleep(delay / 1000);
}
}
uint8_t *data = new uint8_t[bufSize];
memcpy(data, buffer + info.offset, info.size);
// fwrite(data, info.size, 1, file);
LOGE(HardwareDecode_TAG, "%s:size=%d", __func__, info.size);
// while (!audioPlay->canPush(info.size)) {
// usleep(300000);
// LOGE(HardwareDecode_TAG, "%s:休眠", __func__);
// }
// audioPlay->pushData(data, info.size);
// delete[] data;
AMediaCodec_releaseOutputBuffer(pVideoCodec, outputIndex, info.size != 0);
// mutex.unlock();
AMediaCodec_releaseOutputBuffer(_sharedPtr->codec, outputIndex, info.size != 0);
}
} else {
LOGE(HardwareDecode_TAG, "%s:取出解码数据失败", __func__);
mutex.unlock();
continue;
}
if (isInputEOF && isOutputEOF) {
if (_sharedPtr->isInputEof && _sharedPtr->isOutputEof) {
LOGE(HardwareDecode_TAG, "%s:退出解码", __func__);
playStates.setEof(true);
isFinish = true;
Expand Down Expand Up @@ -202,32 +220,32 @@ void HardwareDecode::stop() {
videoPlayer->stop();
videoPlayer = nullptr;
}
if (pAudioFmt != nullptr) {
AMediaFormat_delete(pAudioFmt);
pAudioFmt = nullptr;
}
if (pVideoFmt != nullptr) {
AMediaFormat_delete(pVideoFmt);
pVideoFmt = nullptr;
}
if (pAudioCodec != nullptr) {
AMediaCodec_stop(pAudioCodec);
AMediaCodec_delete(pAudioCodec);
pAudioCodec = nullptr;
}
if (pVideoCodec != nullptr) {
AMediaCodec_stop(pVideoCodec);
AMediaCodec_delete(pVideoCodec);
pVideoCodec = nullptr;
}
if (pAudioMediaExtractor != nullptr) {
AMediaExtractor_delete(pAudioMediaExtractor);
pAudioMediaExtractor = nullptr;
}
if (pVideoMediaExtractor != nullptr) {
AMediaExtractor_delete(pVideoMediaExtractor);
pVideoMediaExtractor = nullptr;
}
// if (pAudioFmt != nullptr) {
// AMediaFormat_delete(pAudioFmt);
// pAudioFmt = nullptr;
// }
// if (pVideoFmt != nullptr) {
// AMediaFormat_delete(pVideoFmt);
// pVideoFmt = nullptr;
// }
// if (pAudioCodec != nullptr) {
// AMediaCodec_stop(pAudioCodec);
// AMediaCodec_delete(pAudioCodec);
// pAudioCodec = nullptr;
// }
// if (pVideoCodec != nullptr) {
// AMediaCodec_stop(pVideoCodec);
// AMediaCodec_delete(pVideoCodec);
// pVideoCodec = nullptr;
// }
// if (pAudioMediaExtractor != nullptr) {
// AMediaExtractor_delete(pAudioMediaExtractor);
// pAudioMediaExtractor = nullptr;
// }
// if (pVideoMediaExtractor != nullptr) {
// AMediaExtractor_delete(pVideoMediaExtractor);
// pVideoMediaExtractor = nullptr;
// }
}

void HardwareDecode::decode() {
Expand All @@ -240,13 +258,15 @@ void HardwareDecode::playAudio() {
if (audioPlay != nullptr) {
audioPlay->init(sampleRate, channelCount);
audioPlay->play();
decode();
std::thread decodeThread(&HardwareDecode::doDecodeWork, this, audioInfo);
decodeThread.detach();
}
}

void HardwareDecode::playVideo(ANativeWindow *_pWindow) {
this->pWindow = _pWindow;
playAudio();
std::thread decodeThread(&HardwareDecode::doDecodeWork, this, videoInfo);
decodeThread.detach();
}

void HardwareDecode::pause() {
Expand All @@ -263,12 +283,12 @@ void HardwareDecode::resume() {

void HardwareDecode::seek(int progress) {
audioPlay->clear();
AMediaExtractor_seekTo(pAudioMediaExtractor, progress * 1000000,
AMEDIAEXTRACTOR_SEEK_NEXT_SYNC);
AMediaCodec_flush(pAudioCodec);
renderstart = -1;
isInputEOF = false;
isOutputEOF = false;
// AMediaExtractor_seekTo(pAudioMediaExtractor, progress * 1000000,
// AMEDIAEXTRACTOR_SEEK_NEXT_SYNC);
// AMediaCodec_flush(pAudioCodec);
// renderstart = -1;
// isInputEOF = false;
// isOutputEOF = false;
}

HardwareDecode::~HardwareDecode() {
Expand Down
Loading

0 comments on commit 89849d6

Please sign in to comment.