mirror of
https://github.com/openharmony/applications_sample_camera.git
synced 2026-07-20 13:44:37 -04:00
add audio capture sample and add function to player sample
Signed-off-by: starfish002 <shaoyuan.zhang@huawei.com>
This commit is contained in:
@@ -29,6 +29,22 @@ executable("camera_sample") {
|
||||
output_dir = "$root_out_dir/dev_tools"
|
||||
}
|
||||
|
||||
executable("audio_capture_sample") {
|
||||
sources = [
|
||||
"audio_capture_sample.cpp",
|
||||
]
|
||||
cflags = ["-Wall"]
|
||||
cflags_cc = cflags
|
||||
|
||||
ldflags = ["-lstdc++"]
|
||||
ldflags += ["-lpthread"]
|
||||
ldflags += ["-Wl,-rpath-link=$ohos_root_path/$root_out_dir"]
|
||||
deps = [
|
||||
"//third_party/bounds_checking_function:libsec_shared",
|
||||
"//foundation/multimedia/audio_lite/frameworks:audio_capturer_lite",
|
||||
]
|
||||
output_dir = "$root_out_dir/dev_tools"
|
||||
}
|
||||
executable("player_sample") {
|
||||
sources = [ "player_sample.cpp" ]
|
||||
cflags = [ "-Wall" ]
|
||||
@@ -48,5 +64,6 @@ lite_component("media_sample") {
|
||||
features = [
|
||||
":camera_sample",
|
||||
":player_sample",
|
||||
":audio_capture_sample",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include "audio_capturer.h"
|
||||
#include "media_errors.h"
|
||||
#include "securec.h"
|
||||
|
||||
using namespace OHOS;
|
||||
using namespace OHOS::Audio;
|
||||
using namespace OHOS::Media;
|
||||
using namespace std;
|
||||
|
||||
struct AudioSourceInput {
|
||||
size_t framesize;
|
||||
uint8_t *buffer;
|
||||
AudioCapturer *audioCap;
|
||||
AudioCodecFormat audioFormat;
|
||||
std::thread processThread;
|
||||
bool bThreadRun;
|
||||
};
|
||||
|
||||
enum AppState {
|
||||
AV_ON,
|
||||
AV_OFF
|
||||
};
|
||||
|
||||
static AudioSourceInput g_audioSourceProcessInput;
|
||||
|
||||
static char *GernerateFileName(AudioCodecFormat format)
|
||||
{
|
||||
time_t stCurrent;
|
||||
char aszDatetime[0x100];
|
||||
(void)time(&stCurrent);
|
||||
struct tm *pstCurrentTime = localtime(&(stCurrent));
|
||||
if (pstCurrentTime == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (strftime(aszDatetime, 0x100, "%Y-%m-%d-%H-%M-%S", pstCurrentTime) > 0) {
|
||||
std::cout << "Current Time: " << aszDatetime << std::endl;
|
||||
}
|
||||
|
||||
string postfix;
|
||||
switch (format) {
|
||||
case PCM:
|
||||
postfix = "pcm";
|
||||
break;
|
||||
case AAC_LC:
|
||||
postfix = "aac";
|
||||
break;
|
||||
case G711A:
|
||||
postfix = "g711a";
|
||||
break;
|
||||
case G711U:
|
||||
postfix = "g711u";
|
||||
break;
|
||||
case G726:
|
||||
postfix = "g726";
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const int32_t size = 0x180;
|
||||
char *name = static_cast<char *>(malloc(size));
|
||||
if (name == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
(void)memset_s(name, size, 0, size);
|
||||
/* create file for save stream */
|
||||
if (snprintf_s(name, size, size - 1, "/sdcard/audio_%s.%s", aszDatetime, postfix.c_str()) < 0) {
|
||||
std::cout << "snprintf_s failed " << std::endl;
|
||||
free(name);
|
||||
return nullptr;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
static void AudioInputSourceProcess(AudioSourceInput *audioSourceInput)
|
||||
{
|
||||
std::cout << "audioSourceInput: " << audioSourceInput << std::endl;
|
||||
if (audioSourceInput == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *fileName = GernerateFileName(audioSourceInput->audioFormat);
|
||||
if (fileName == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *pfd = fopen(fileName, "w+");
|
||||
if (pfd == nullptr) {
|
||||
std::cout << "open file failed " << fileName << std::endl;
|
||||
free(fileName);
|
||||
return;
|
||||
}
|
||||
std::cout << "Open SUCCESS " << fileName << std::endl;
|
||||
int readCnt = 0;
|
||||
while (audioSourceInput->bThreadRun) {
|
||||
int ret = audioSourceInput->audioCap->Read(audioSourceInput->buffer,
|
||||
audioSourceInput->framesize, false);
|
||||
if (ret == -1) {
|
||||
std::cout << "audioCap Read failed ret:" << ret << std::endl;
|
||||
continue;
|
||||
}
|
||||
if (fwrite(audioSourceInput->buffer, 1, ret, pfd) != ret) {
|
||||
std::cout << "fwrite failed errno:"<< errno << std::endl;
|
||||
break;
|
||||
}
|
||||
readCnt++;
|
||||
std::cout << "audioCap Read readCnt: "<< readCnt << " size: " << ret << std::endl;
|
||||
}
|
||||
(void)fclose(pfd);
|
||||
free(fileName);
|
||||
}
|
||||
|
||||
struct CapturerInfo {
|
||||
AudioCodecFormat audioFormat;
|
||||
int32_t sampleRate;
|
||||
int32_t bitRate;
|
||||
};
|
||||
|
||||
static AudioCodecFormat GetAudioFormat(void)
|
||||
{
|
||||
std::cout << "*******************************************" << endl;
|
||||
std::cout << "SetCapturerInfo (PCM:1, AAC_LC:2, G711A:7, G711U:8, G726:9)" << endl;
|
||||
std::cout << "*******************************************" << endl;
|
||||
int32_t audioFormat;
|
||||
std::cin >> audioFormat;
|
||||
cout << "input audioFormat:" << audioFormat << endl;
|
||||
if (audioFormat != 1 && audioFormat != 0x2 && audioFormat != 0x7 &&
|
||||
audioFormat != 0x8 && audioFormat != 0x9) {
|
||||
std::cout << "Can't support input format:" << static_cast<int32_t> (audioFormat) << std::endl;
|
||||
return FORMAT_BUTT;
|
||||
}
|
||||
return static_cast<AudioCodecFormat> (audioFormat);
|
||||
}
|
||||
|
||||
static void GetDefaultSampleRateAndRateBaseFormat(AudioCodecFormat format, int32_t &sr, int32_t &rate)
|
||||
{
|
||||
const CapturerInfo audioCapturerInfo[] = {
|
||||
{PCM, 16000, 128000},
|
||||
{AAC_LC, 48000, 128000},
|
||||
{G711A, 8000, 64000},
|
||||
{G711U, 8000, 64000},
|
||||
{G726, 8000, 24000}
|
||||
};
|
||||
|
||||
int validCapInfoNum = sizeof(audioCapturerInfo) / sizeof(audioCapturerInfo[0]);
|
||||
for (int i = 0; i < validCapInfoNum; i++) {
|
||||
if (format == audioCapturerInfo[i].audioFormat) {
|
||||
sr = audioCapturerInfo[i].sampleRate;
|
||||
rate = audioCapturerInfo[i].bitRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t GetChannelCount(void)
|
||||
{
|
||||
std::cout << "*******************************************" << endl;
|
||||
std::cout << "SetCapturerInfo (channelCount:1, channelCount:2)" << endl;
|
||||
std::cout << "*******************************************" << endl;
|
||||
int32_t channelCount;
|
||||
std::cin >> channelCount;
|
||||
if (channelCount != 1 && channelCount != 0x2) {
|
||||
std::cout << "Can't support input channelCount:" << channelCount << std::endl;
|
||||
return -1;
|
||||
}
|
||||
return channelCount;
|
||||
}
|
||||
|
||||
static void ShowCmdInfo(void)
|
||||
{
|
||||
cout << "*******************************************" << endl;
|
||||
cout << "Select the behavior of audio capturer." << endl;
|
||||
cout << "s or S-----start audio capturer" << endl;
|
||||
cout << "p or P-----stop audio capturer" << endl;
|
||||
cout << "q or Q-----quit audio capturer" << endl;
|
||||
cout << "*******************************************" << endl;
|
||||
}
|
||||
|
||||
static void TaskQuit(AudioCapturer &audioCap, AppState &state)
|
||||
{
|
||||
if (state == AV_ON) {
|
||||
g_audioSourceProcessInput.bThreadRun = false;
|
||||
g_audioSourceProcessInput.processThread.join();
|
||||
if (!audioCap.Stop()) {
|
||||
std::cout << "Stop audioCap failed, quit record\n" << endl;
|
||||
}
|
||||
state = AV_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t TaskStop(AudioCapturer &audioCap, AppState &state)
|
||||
{
|
||||
if (state == AV_ON) {
|
||||
g_audioSourceProcessInput.bThreadRun = false;
|
||||
g_audioSourceProcessInput.processThread.join();
|
||||
if (!audioCap.Stop()) {
|
||||
std::cout << "Stop audioCap fialed, stop record " << endl;
|
||||
return -1;
|
||||
}
|
||||
state = AV_OFF;
|
||||
} else {
|
||||
std::cout << "Start recorder first." << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t TaskStart(AudioCapturer &audioCap, AppState &state)
|
||||
{
|
||||
if (state == AV_ON) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!audioCap.Start()) {
|
||||
std::cout << "Can't Start..." << endl;
|
||||
delete g_audioSourceProcessInput.buffer;
|
||||
return -1;
|
||||
}
|
||||
g_audioSourceProcessInput.audioCap = &audioCap;
|
||||
g_audioSourceProcessInput.bThreadRun = true;
|
||||
g_audioSourceProcessInput.processThread = std::thread(AudioInputSourceProcess,
|
||||
&g_audioSourceProcessInput);
|
||||
state = AV_ON;
|
||||
std::cout << "Recording..." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void RumCmd(AudioCapturer &audioCap)
|
||||
{
|
||||
ShowCmdInfo();
|
||||
char input;
|
||||
AppState state = AV_OFF;
|
||||
while (std::cin >> input) {
|
||||
switch (input) {
|
||||
case 's':
|
||||
case 'S':
|
||||
if (TaskStart(audioCap, state) != 0) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
if (TaskStop(audioCap, state) != 0) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
case 'Q':
|
||||
TaskQuit(audioCap, state);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::cout << "audio_capture_sample " << std::endl;
|
||||
int ret = 0;
|
||||
size_t frameCount;
|
||||
AudioCapturer audioCap;
|
||||
|
||||
AudioCapturerInfo info;
|
||||
info.inputSource = AUDIO_MIC;
|
||||
info.bitWidth = BIT_WIDTH_16;
|
||||
AudioCodecFormat audioFormat = GetAudioFormat();
|
||||
if (audioFormat == FORMAT_BUTT) {
|
||||
return -1;
|
||||
}
|
||||
info.audioFormat = audioFormat;
|
||||
g_audioSourceProcessInput.audioFormat = audioFormat;
|
||||
GetDefaultSampleRateAndRateBaseFormat(audioFormat, info.sampleRate, info.bitRate);
|
||||
|
||||
info.channelCount = GetChannelCount();
|
||||
if (info.channelCount == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cout << " SetCapturerInfo" << std::endl;
|
||||
if ((ret = audioCap.SetCapturerInfo(info)) != 0) {
|
||||
std::cout << "Can't SetCapturerInfo " << std::endl;
|
||||
delete g_audioSourceProcessInput.buffer;
|
||||
return -1;
|
||||
}
|
||||
frameCount = audioCap.GetFrameCount();
|
||||
std::cout << "GetFrameCount " << frameCount << std::endl;
|
||||
g_audioSourceProcessInput.framesize = frameCount * 0x400;
|
||||
g_audioSourceProcessInput.buffer = new uint8_t[g_audioSourceProcessInput.framesize];
|
||||
|
||||
RumCmd(audioCap);
|
||||
EXIT:
|
||||
audioCap.Release();
|
||||
delete g_audioSourceProcessInput.buffer;
|
||||
g_audioSourceProcessInput.buffer = nullptr;
|
||||
return 0;
|
||||
}
|
||||
+657
-221
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@@ -42,64 +42,54 @@ using OHOS::Media::StreamSource;
|
||||
using OHOS::Media::StreamCallback;
|
||||
using namespace OHOS::Media;
|
||||
|
||||
#define DOFUNC_STR_NORET(func , str) \
|
||||
do { \
|
||||
HI_S32 s32Ret = 0; \
|
||||
s32Ret = func; \
|
||||
if(s32Ret != 0) \
|
||||
{ \
|
||||
printf("[liteplayer_sample][%s:%d] ret:%d, %s \n", __FILE__, __LINE__, s32Ret,str); \
|
||||
return NULL;\
|
||||
} \
|
||||
} while (0)
|
||||
static int64_t GetCurTimeUs()
|
||||
{
|
||||
const int32_t SS2US = 1000000;
|
||||
struct timeval ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_usec = 0;
|
||||
gettimeofday(&ts, nullptr);
|
||||
return (static_cast<int64_t> (ts.tv_sec) * SS2US) + static_cast<int64_t> (ts.tv_usec);
|
||||
}
|
||||
|
||||
#define DOFUNC_STR_RET(func , str) \
|
||||
do { \
|
||||
HI_S32 s32Ret = 0; \
|
||||
s32Ret = func; \
|
||||
if(s32Ret != 0) \
|
||||
{ \
|
||||
printf("[liteplayer_sample][%s:%d] ret:%d, %s \n", __FILE__, __LINE__, s32Ret,str); \
|
||||
return -1;\
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define IS_OK(ret) \
|
||||
do { \
|
||||
if (ret != 0) { \
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SAMPLE_RETURN_VAL_IF_NULL(condition) \
|
||||
do { \
|
||||
if ((condition) == nullptr) { \
|
||||
printf("" #condition " is NULL error %s %d\n", __FUNCTION__, __LINE__); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
static int64_t GetCurTimeMs()
|
||||
{
|
||||
const int32_t US2MS = 1000;
|
||||
int64_t curTimeUs = GetCurTimeUs();
|
||||
return static_cast<int64_t>(curTimeUs / US2MS);
|
||||
}
|
||||
|
||||
class StreamSourceSample;
|
||||
typedef struct TagTestSample
|
||||
{
|
||||
struct TestSample {
|
||||
std::shared_ptr<Player> adapter;
|
||||
pthread_t process;
|
||||
pthread_mutex_t mutex;
|
||||
int32_t isThreadRunning;
|
||||
bool isThreadRunning;
|
||||
int32_t sourceType;
|
||||
char filePath[PATH_MAX];
|
||||
char filePath[PATH_MAX + 1];
|
||||
int64_t fileSize;
|
||||
int32_t pauseAfterPlay;
|
||||
Surface *surface;
|
||||
std::shared_ptr<StreamSourceSample> streamSample;
|
||||
} TestSample;
|
||||
std::shared_ptr<PlayerCallback> cb;
|
||||
int64_t newPlayerCost;
|
||||
int64_t setSourceCost;
|
||||
int64_t prepareCost;
|
||||
int64_t setSurfaceCost;
|
||||
int64_t playCost;
|
||||
int64_t RewindCost;
|
||||
int64_t RewindBegin;
|
||||
int64_t stopCost;
|
||||
int64_t releaseCost;
|
||||
};
|
||||
|
||||
typedef struct TagIdleBuffer{
|
||||
struct IdleBuffer {
|
||||
size_t idx;
|
||||
size_t offset;
|
||||
size_t size;
|
||||
} IdleBuffer;
|
||||
};
|
||||
|
||||
class StreamSourceSample :public StreamSource
|
||||
{
|
||||
class StreamSourceSample : public StreamSource {
|
||||
public:
|
||||
StreamSourceSample(void);
|
||||
virtual ~StreamSourceSample(void);
|
||||
@@ -107,7 +97,7 @@ public:
|
||||
void SetStreamCallback(const std::shared_ptr<StreamCallback> &callback);
|
||||
uint8_t *GetBufferAddress(size_t idx);
|
||||
void QueueBuffer(size_t index, size_t offset, size_t size, int64_t timestampUs, uint32_t flags);
|
||||
int GetAvailableBuffer(IdleBuffer* buffer);
|
||||
int GetAvailableBuffer(IdleBuffer *buffer);
|
||||
|
||||
private:
|
||||
std::weak_ptr<StreamCallback> m_callBack;
|
||||
@@ -163,7 +153,10 @@ void StreamSourceSample::OnBufferAvailable(size_t index, size_t offset, size_t s
|
||||
|
||||
int StreamSourceSample::GetAvailableBuffer(IdleBuffer* buffer)
|
||||
{
|
||||
SAMPLE_RETURN_VAL_IF_NULL(buffer);
|
||||
if (buffer == nullptr) {
|
||||
printf("buffer is nullptr error %s %d\n", __FUNCTION__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
if (aviableBuffer.empty()) {
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
@@ -175,22 +168,97 @@ int StreamSourceSample::GetAvailableBuffer(IdleBuffer* buffer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void* streamProcess(void* arg)
|
||||
class PlayerCallbackImpl : public PlayerCallback {
|
||||
public:
|
||||
PlayerCallbackImpl(TestSample &in);
|
||||
~PlayerCallbackImpl();
|
||||
void OnPlaybackComplete();
|
||||
void OnError(int32_t errorType, int32_t errorCode);
|
||||
void OnInfo(int type, int extra);
|
||||
void OnVideoSizeChanged(int width, int height);
|
||||
void OnRewindToComplete();
|
||||
|
||||
private:
|
||||
TestSample *sample;
|
||||
};
|
||||
|
||||
PlayerCallbackImpl::PlayerCallbackImpl(TestSample &in)
|
||||
{
|
||||
sample = ∈
|
||||
}
|
||||
|
||||
PlayerCallbackImpl::~PlayerCallbackImpl()
|
||||
{
|
||||
printf("dtor\n");
|
||||
}
|
||||
|
||||
void PlayerCallbackImpl::OnPlaybackComplete(void)
|
||||
{
|
||||
printf("OnPlaybackComplete test\n");
|
||||
}
|
||||
|
||||
void PlayerCallbackImpl::OnError(int32_t errorType, int32_t errorCode)
|
||||
{
|
||||
printf("OnError test, errorType:%d, errorCode:%d\n", errorType, errorCode);
|
||||
}
|
||||
|
||||
void PlayerCallbackImpl::OnInfo(int type, int extra)
|
||||
{
|
||||
printf("OnInfo test, type:%d, extra:%d\n", type, extra);
|
||||
}
|
||||
|
||||
void PlayerCallbackImpl::OnVideoSizeChanged(int width, int height)
|
||||
{
|
||||
printf("OnVideoSizeChanged test width:%d, height:%d\n", width, height);
|
||||
}
|
||||
|
||||
void PlayerCallbackImpl::OnRewindToComplete(void)
|
||||
{
|
||||
sample->RewindCost = GetCurTimeMs() - sample->RewindBegin;
|
||||
printf("OnRewindToComplete test\n");
|
||||
}
|
||||
|
||||
static void CostTestPrintf(TestSample &sample)
|
||||
{
|
||||
printf("\n\n\n##################player cost info begin\n");
|
||||
|
||||
printf("start cost total:%lld\n", sample.setSourceCost + sample.prepareCost + sample.setSurfaceCost +
|
||||
sample.playCost);
|
||||
printf("new player:%lld,\n setSourceCost:%lld,\n prepareCost:%lld,\n, setSurfaceCost:%lld,\n playCost:%lld,\n",
|
||||
sample.newPlayerCost, sample.setSourceCost, sample.prepareCost, sample.setSurfaceCost, sample.playCost);
|
||||
|
||||
printf("seek cost total:%lld\n", sample.RewindCost);
|
||||
|
||||
printf("destory cost total:%lld\n", sample.stopCost + sample.releaseCost);
|
||||
printf("stopCost:%lld,\n releaseCost:%lld,\n", sample.stopCost, sample.releaseCost);
|
||||
|
||||
printf("##################player cost info end\n\n\n");
|
||||
}
|
||||
|
||||
static void *streamProcess(void *arg)
|
||||
{
|
||||
const int32_t STEAM_PROCESS_SLEEP_TIME_US = 20000;
|
||||
uint8_t *data = nullptr;
|
||||
size_t readLen;
|
||||
size_t bufferSize;
|
||||
TestSample *sample = (TestSample *)arg;
|
||||
FILE* pFile = fopen(sample->filePath, "rb");
|
||||
if (pFile == NULL) {
|
||||
return NULL;
|
||||
if (pFile == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
prctl(PR_SET_NAME, "StreamProc", 0, 0, 0);
|
||||
printf("[%s,%d] file:%s\n", __func__, __LINE__, sample->filePath);
|
||||
while(sample->isThreadRunning) {
|
||||
while (true) {
|
||||
pthread_mutex_lock(&sample->mutex);
|
||||
if (!sample->isThreadRunning) {
|
||||
printf("[%s,%d] thread should exit\n", __func__, __LINE__);
|
||||
pthread_mutex_unlock(&sample->mutex);
|
||||
break;
|
||||
}
|
||||
pthread_mutex_unlock(&sample->mutex);
|
||||
data = sample->streamSample->GetSharedBuffer(bufferSize);
|
||||
if (data == nullptr) {
|
||||
usleep(20000);
|
||||
usleep(STEAM_PROCESS_SLEEP_TIME_US);
|
||||
continue;
|
||||
}
|
||||
readLen = fread(data, 1, bufferSize, pFile);
|
||||
@@ -203,146 +271,102 @@ static void* streamProcess(void* arg)
|
||||
}
|
||||
fclose(pFile);
|
||||
printf("[%s,%d]\n", __func__, __LINE__);
|
||||
return NULL;
|
||||
pthread_mutex_lock(&sample->mutex);
|
||||
sample->isThreadRunning = false;
|
||||
pthread_mutex_unlock(&sample->mutex);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void SampleCmd(TestSample &sample)
|
||||
static void GetFileSize(TestSample &sample)
|
||||
{
|
||||
char cmd[64]; /* 64: Array length */
|
||||
int ret;
|
||||
int64_t timeMs = 0;
|
||||
int64_t duration;
|
||||
int64_t currentPosition;
|
||||
int32_t videoWidth;
|
||||
int32_t videoHeight;
|
||||
float lvolume;
|
||||
float rvolume;
|
||||
int loop = 0;
|
||||
sample.fileSize = -1;
|
||||
if (sample.sourceType != 1 && sample.sourceType != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Input CMD: quit, show, pause(pu), play(pl), seek [ms], volume [lvol] [rvol], loop [bool], speed [float]"
|
||||
"\n");
|
||||
while (fgets(cmd, 20, stdin)) { /* 10: use array length */
|
||||
cmd[20] = '\0'; /* 10: end of string */
|
||||
if (strncmp(cmd, "quit", 4) == 0) {
|
||||
break;
|
||||
} else if (strncmp(cmd, "pause", 4) == 0 || strncmp(cmd, "pu", 2) == 0) {
|
||||
ret = sample.adapter->Pause();
|
||||
} else if (strncmp(cmd, "play", 4) == 0 || strncmp(cmd, "pl", 2) == 0) {
|
||||
ret = sample.adapter->Play();
|
||||
} else if (strncmp(cmd, "speed", 0x5) == 0) {
|
||||
float speed = 1.0;
|
||||
if (sscanf_s(cmd, "speed %f", &speed) != 1) {
|
||||
printf("ERR: not input seek time, example: speed 1.0!\n");
|
||||
continue;
|
||||
}
|
||||
ret = sample.adapter->SetPlaybackSpeed(speed);
|
||||
IS_OK(ret);
|
||||
} else if (strncmp(cmd, "seek", 4) == 0) {
|
||||
if (sscanf_s(cmd, "seek %d", &timeMs) != 1) {
|
||||
printf("ERR: not input seek time, example: seek 1000!\n");
|
||||
continue;
|
||||
}
|
||||
if (sample.sourceType < 2) {
|
||||
sample.adapter->Rewind(timeMs, PlayerSeekMode::PLAYER_SEEK_PREVIOUS_SYNC);
|
||||
}
|
||||
} else if (strncmp(cmd, "volume", 6) == 0) {
|
||||
if (sscanf_s(cmd, "volume %f %f", &lvolume, &rvolume) != 2) {
|
||||
printf("ERR: not input volume, example: volume 50 50!\n");
|
||||
continue;
|
||||
}
|
||||
printf("try set volume %f %f\n", lvolume, rvolume);
|
||||
ret = sample.adapter->SetVolume(lvolume, rvolume);
|
||||
} else if (strncmp(cmd, "show", 4) == 0) {
|
||||
printf("now show player info\n");
|
||||
|
||||
printf("player IsPlaying:%d IsSingleLooping:%d\n",
|
||||
sample.adapter->IsPlaying(), sample.adapter->IsSingleLooping());
|
||||
|
||||
ret = sample.adapter->GetDuration(duration);
|
||||
IS_OK(ret);
|
||||
ret = sample.adapter->GetCurrentTime(currentPosition);
|
||||
IS_OK(ret);
|
||||
printf("player duration:%lld GetCurrentTime:%ld\n", duration, currentPosition);
|
||||
|
||||
ret = sample.adapter->GetVideoWidth(videoWidth);
|
||||
IS_OK(ret);
|
||||
ret = sample.adapter->GetVideoHeight(videoHeight);
|
||||
IS_OK(ret);
|
||||
printf("player videoWidth:%d videoHeight:%d\n", videoWidth, videoHeight);
|
||||
int32_t state;
|
||||
ret = sample.adapter->GetPlayerState(state);
|
||||
IS_OK(ret);
|
||||
printf("player current state:%d\n", state);
|
||||
} else if (strncmp(cmd, "loop", 4) == 0) {
|
||||
if (sscanf_s(cmd, "loop %d", &loop) != 1) {
|
||||
printf("ERR: not input loop flag, example: loop 1!\n");
|
||||
continue;
|
||||
}
|
||||
printf("try set loop %d\n", loop);
|
||||
ret = sample.adapter->EnableSingleLooping(loop == 1);
|
||||
IS_OK(ret);
|
||||
printf("Set loop %d\n", loop);
|
||||
} else {
|
||||
printf("Input CMD: quit, show, pause(pu), play(pl), seek [ms], volume [lvol] [rvol], loop [bool], "
|
||||
"speed [float]\n");
|
||||
}
|
||||
FILE *fileTmp = fopen(sample.filePath, "rb");
|
||||
if (fileTmp != nullptr) {
|
||||
fseek(fileTmp, 0, SEEK_END);
|
||||
sample.fileSize = ftell(fileTmp);
|
||||
fclose(fileTmp);
|
||||
fileTmp = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SetSchParam(void)
|
||||
static int SetSurface(TestSample &sample)
|
||||
{
|
||||
struct sched_param param;
|
||||
pthread_attr_t attr;
|
||||
if (sample.surface != nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void)pthread_attr_getschedparam(&attr, ¶m);
|
||||
param.sched_priority = 9;
|
||||
(void)pthread_setschedparam(pthread_self(), SCHED_RR, ¶m);
|
||||
}
|
||||
int64_t begin = GetCurTimeMs();
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
prctl(PR_SET_NAME, "mainProc", 0, 0, 0);
|
||||
int32_t sourceType = 1;
|
||||
int32_t pauseAfterPlay = 0;
|
||||
SAMPLE_RETURN_VAL_IF_NULL(argv);
|
||||
if (argc < 2) { /* 2: Minimum number of inputs */
|
||||
printf("usage: %s filename (or vpss channel index)\n", argv[0]);
|
||||
sample.surface = Surface::CreateSurface();
|
||||
if (sample.surface == nullptr) {
|
||||
printf("[%s,%d] CreateSurface failed\n", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
if (argc >= 3) { /* 4: sourceType */
|
||||
sourceType = atoi(argv[2]); /* */
|
||||
if ((sourceType != 1) && (sourceType != 0x2)) {
|
||||
printf("unsuport sourceType:%d\n", sourceType);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (argc >= 4) {
|
||||
pauseAfterPlay = atoi(argv[2]);
|
||||
if (pauseAfterPlay != 1) {
|
||||
printf("unsuport pauseAfterPlay:%d, not enable pause after play mode\n", sourceType);
|
||||
pauseAfterPlay = 0;
|
||||
}
|
||||
sample.surface->SetUserData("region_position_x", "0");
|
||||
sample.surface->SetUserData("region_position_y", "0");
|
||||
sample.surface->SetUserData("region_width", "480");
|
||||
sample.surface->SetUserData("region_height", "480");
|
||||
int32_t ret = sample.adapter->SetVideoSurface(sample.surface);
|
||||
sample.setSurfaceCost = GetCurTimeMs() - begin;
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
TestSample sample = {0};
|
||||
sample.pauseAfterPlay = pauseAfterPlay;
|
||||
sample.sourceType = sourceType;
|
||||
if (realpath(argv[1], sample.filePath) == nullptr) {
|
||||
printf("realpath input file failed, errno: %d!\n", errno);
|
||||
return -1;
|
||||
static void DestorySurface(TestSample &sample)
|
||||
{
|
||||
if (sample.surface != nullptr) {
|
||||
delete(sample.surface);
|
||||
sample.surface = nullptr;
|
||||
}
|
||||
sample.adapter = std::make_shared<Player>();
|
||||
int64_t duration;
|
||||
int32_t width;
|
||||
int32_t heighth;
|
||||
}
|
||||
|
||||
static int SetCallback(TestSample &sample)
|
||||
{
|
||||
if (sample.cb == nullptr) {
|
||||
sample.cb = std::make_shared<PlayerCallbackImpl>(sample);
|
||||
sample.adapter->SetPlayerCallback(sample.cb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DestoryCallback(TestSample &sample)
|
||||
{
|
||||
if (sample.cb != nullptr) {
|
||||
sample.cb.reset();
|
||||
sample.cb = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static int SetStreamSourceProcess(TestSample &sample)
|
||||
{
|
||||
sample.streamSample = std::make_shared<StreamSourceSample>();
|
||||
Format formats;
|
||||
printf("[%s,%d]\n", __func__, __LINE__);
|
||||
SetSchParam();
|
||||
printf("[%s,%d]\n", __func__, __LINE__);
|
||||
formats.PutStringValue(CODEC_MIME, MIME_AUDIO_AAC);
|
||||
Source source(sample.streamSample, formats);
|
||||
sample.adapter->SetSource(source);
|
||||
sample.isThreadRunning = true;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setstacksize(&attr, 0x10000);
|
||||
int32_t ret = pthread_create(&sample.process, &attr, streamProcess, &sample);
|
||||
if (ret != 0) {
|
||||
printf("pthread_create failed %d\n", ret);
|
||||
sample.isThreadRunning = false;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("[%s,%d] sourceType:%d, path:%s, pauseAfterPlay:%d\n", __func__, __LINE__, sourceType, sample.filePath,
|
||||
pauseAfterPlay);
|
||||
if (sourceType == 1) {
|
||||
static int SetSourceProcess(TestSample &sample)
|
||||
{
|
||||
int64_t begin = GetCurTimeMs();
|
||||
if (sample.sourceType == 1) {
|
||||
std::string uri(sample.filePath);
|
||||
std::map<std::string, std::string> header;
|
||||
Source source(uri, header);
|
||||
@@ -353,22 +377,455 @@ int main(int argc, char** argv)
|
||||
printf("lstat %s failed, please check the file exist, errno:%d\n", sample.filePath, errno);
|
||||
return -1;
|
||||
}
|
||||
sample.streamSample = std::make_shared<StreamSourceSample>();
|
||||
formats.PutStringValue(CODEC_MIME, MIME_AUDIO_AAC);
|
||||
Source source(sample.streamSample, formats);
|
||||
sample.adapter->SetSource(source);
|
||||
pthread_mutex_init(&sample.mutex, nullptr);
|
||||
sample.isThreadRunning = 1;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setstacksize(&attr, 0x10000);
|
||||
int32_t ret = pthread_create(&sample.process, &attr, streamProcess, &sample);
|
||||
if (ret != 0) {
|
||||
printf("pthread_create failed %d\n", ret);
|
||||
sample.isThreadRunning = 0;
|
||||
if (SetStreamSourceProcess(sample) != 0) {
|
||||
printf("SetStreamSourceProcess failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
sample.setSourceCost = GetCurTimeMs() - begin;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int PrepareProcess(TestSample &sample)
|
||||
{
|
||||
int64_t begin = GetCurTimeMs();
|
||||
|
||||
if (sample.pauseAfterPlay != 0) {
|
||||
Format formatSetPauseAfterPlay;
|
||||
formatSetPauseAfterPlay.PutIntValue(PAUSE_AFTER_PLAY, true);
|
||||
sample.adapter->SetParameter(formatSetPauseAfterPlay);
|
||||
}
|
||||
sample.adapter->Prepare();
|
||||
sample.prepareCost = GetCurTimeMs() - begin;
|
||||
|
||||
SetCallback(sample);
|
||||
SetSurface(sample);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int PlayProcess(TestSample &sample)
|
||||
{
|
||||
int32_t ret;
|
||||
int64_t begin = GetCurTimeMs();
|
||||
|
||||
if (sample.pauseAfterPlay != 0) {
|
||||
ret = sample.adapter->Pause();
|
||||
} else {
|
||||
ret = sample.adapter->Play();
|
||||
}
|
||||
sample.playCost = GetCurTimeMs() - begin;
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ReleaseProcess(TestSample &sample)
|
||||
{
|
||||
int32_t ret;
|
||||
int64_t begin = GetCurTimeMs();
|
||||
|
||||
if (sample.pauseAfterPlay != 0) {
|
||||
ret = sample.adapter->Pause();
|
||||
} else {
|
||||
ret = sample.adapter->Play();
|
||||
}
|
||||
sample.playCost = GetCurTimeMs() - begin;
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void EndStreamSourceThread(TestSample &sample)
|
||||
{
|
||||
if (sample.sourceType == 0x2 && sample.process != -1) {
|
||||
pthread_mutex_lock(&sample.mutex);
|
||||
sample.isThreadRunning = false;
|
||||
pthread_mutex_unlock(&sample.mutex);
|
||||
pthread_join(sample.process, nullptr);
|
||||
sample.process = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int CreatePlayerProcess(TestSample &sample)
|
||||
{
|
||||
SetSourceProcess(sample);
|
||||
PrepareProcess(sample);
|
||||
PlayProcess(sample);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ReplayProcess(TestSample &sample)
|
||||
{
|
||||
EndStreamSourceThread(sample);
|
||||
sample.adapter->Stop();
|
||||
|
||||
sample.adapter->Release();
|
||||
sample.adapter.reset();
|
||||
|
||||
DestorySurface(sample);
|
||||
DestoryCallback(sample);
|
||||
if (sample.sourceType == 0x2) {
|
||||
sample.streamSample.reset();
|
||||
}
|
||||
|
||||
sample.adapter = std::make_shared<Player>();
|
||||
|
||||
return CreatePlayerProcess(sample);
|
||||
}
|
||||
|
||||
static int PlayNextProcess(TestSample &sample)
|
||||
{
|
||||
EndStreamSourceThread(sample);
|
||||
sample.adapter->Stop();
|
||||
sample.adapter->Reset();
|
||||
DestorySurface(sample);
|
||||
if (sample.sourceType == 0x2) {
|
||||
sample.streamSample.reset();
|
||||
}
|
||||
|
||||
return CreatePlayerProcess(sample);
|
||||
}
|
||||
|
||||
static int CostTest(TestSample &sample)
|
||||
{
|
||||
if (sample.sourceType >= 0x2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t begin;
|
||||
int64_t end;
|
||||
|
||||
EndStreamSourceThread(sample);
|
||||
begin = GetCurTimeMs();
|
||||
sample.adapter->Stop();
|
||||
end = GetCurTimeMs();
|
||||
sample.stopCost = end - begin;
|
||||
|
||||
begin = end;
|
||||
sample.adapter->Release();
|
||||
sample.adapter.reset();
|
||||
sample.releaseCost = GetCurTimeMs() - begin;
|
||||
|
||||
DestorySurface(sample);
|
||||
DestoryCallback(sample);
|
||||
if (sample.sourceType == 0x2) {
|
||||
sample.streamSample.reset();
|
||||
}
|
||||
CostTestPrintf(sample);
|
||||
|
||||
begin = GetCurTimeMs();
|
||||
sample.adapter = std::make_shared<Player>();
|
||||
sample.newPlayerCost = GetCurTimeMs() - begin;
|
||||
|
||||
CreatePlayerProcess(sample);
|
||||
|
||||
sleep(0xa); // sleep 10s and seek
|
||||
sample.RewindBegin = GetCurTimeMs();
|
||||
sample.adapter->Rewind(0, PlayerSeekMode::PLAYER_SEEK_PREVIOUS_SYNC);
|
||||
sleep(0x5); // sleep 5s after seek
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void RunCmdShow(TestSample &sample)
|
||||
{
|
||||
printf("now show player info\n");
|
||||
|
||||
printf("player IsPlaying:%d IsSingleLooping:%d\n", sample.adapter->IsPlaying(),
|
||||
sample.adapter->IsSingleLooping());
|
||||
|
||||
int64_t duration;
|
||||
int32_t ret = sample.adapter->GetDuration(duration);
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
|
||||
int64_t currentPosition;
|
||||
ret = sample.adapter->GetCurrentTime(currentPosition);
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
printf("player duration:%lld GetCurrentTime:%lld\n", duration, currentPosition);
|
||||
|
||||
int32_t videoWidth;
|
||||
int32_t videoHeight;
|
||||
ret = sample.adapter->GetVideoWidth(videoWidth);
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
ret = sample.adapter->GetVideoHeight(videoHeight);
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
printf("player videoWidth:%d videoHeight:%d\n", videoWidth, videoHeight);
|
||||
int32_t state;
|
||||
ret = sample.adapter->GetPlayerState(state);
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
printf("player current state:%d\n", state);
|
||||
}
|
||||
|
||||
static void RunCmdSetVolume(TestSample &sample, const char cmd[])
|
||||
{
|
||||
float lvolume;
|
||||
float rvolume;
|
||||
|
||||
if (sscanf_s(cmd, "volume %f %f", &lvolume, &rvolume) != 0x2) {
|
||||
printf("ERR: not input volume, example: volume 50 50!\n");
|
||||
return;
|
||||
}
|
||||
printf("try set volume %f %f\n", lvolume, rvolume);
|
||||
int32_t ret = sample.adapter->SetVolume(lvolume, rvolume);
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void RunCmdNext(TestSample &sample, const char cmd[])
|
||||
{
|
||||
int32_t cnt;
|
||||
|
||||
if (sscanf_s(cmd, "next %d", &cnt) != 1) {
|
||||
printf("ERR: not input next play count, example: next 10000!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (cnt > 0) {
|
||||
if (PlayNextProcess(sample) != 0) {
|
||||
printf("PlayNextProcess process failed\n");
|
||||
return;
|
||||
}
|
||||
sleep(0x5); // sleep 5s and loop
|
||||
cnt--;
|
||||
};
|
||||
}
|
||||
|
||||
static void RunCmdPressurePupl(TestSample &sample, const char cmd[])
|
||||
{
|
||||
int32_t cnt;
|
||||
int ret;
|
||||
|
||||
if (sscanf_s(cmd, "pressure_pupl %d", &cnt) != 1) {
|
||||
printf("ERR: not input replay count, example: pressure 10000!\n");
|
||||
return;
|
||||
}
|
||||
while (cnt > 0) {
|
||||
ret = sample.adapter->Pause();
|
||||
sleep(1);
|
||||
ret = sample.adapter->Play();
|
||||
sleep(1);
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
|
||||
static void RunCmdPressureSeek(TestSample &sample, const char cmd[])
|
||||
{
|
||||
int32_t cnt;
|
||||
int ret;
|
||||
|
||||
if (sscanf_s(cmd, "pressure_seek %d", &cnt) != 1) {
|
||||
printf("ERR: not input replay count, example: pressure 10000!\n");
|
||||
return;
|
||||
}
|
||||
if (sample.sourceType == 0x2) {
|
||||
printf("ERR: streamsource not support pressure_seek\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const int32_t rewindPos = 5000;
|
||||
int64_t currentPosition;
|
||||
while (cnt > 0) {
|
||||
sample.adapter->Rewind(rewindPos, PlayerSeekMode::PLAYER_SEEK_PREVIOUS_SYNC);
|
||||
ret = sample.adapter->GetCurrentTime(currentPosition);
|
||||
printf("##############player GetCurrentTime, ret:%d, time:%lld\n", ret, currentPosition);
|
||||
sleep(0x2);
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
|
||||
static void RunCmdLoop(TestSample &sample, const char cmd[])
|
||||
{
|
||||
int32_t loop;
|
||||
|
||||
if (sscanf_s(cmd, "loop %d", &loop) != 1) {
|
||||
printf("ERR: not input loop flag, example: loop 1!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("try set loop %d\n", loop);
|
||||
int32_t ret = sample.adapter->EnableSingleLooping(loop == 1);
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
printf("Set loop %d\n", loop);
|
||||
}
|
||||
|
||||
static void RunCmdSpeed(TestSample &sample, const char cmd[])
|
||||
{
|
||||
float speed = 1.0;
|
||||
if (sscanf_s(cmd, "speed %f", &speed) != 1) {
|
||||
printf("ERR: not input seek time, example: speed 1.0!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t ret = sample.adapter->SetPlaybackSpeed(speed);
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void RunCmdSeek(TestSample &sample, const char cmd[])
|
||||
{
|
||||
int64_t timeMs = 0;
|
||||
if (sscanf_s(cmd, "seek %d", &timeMs) != 1) {
|
||||
printf("ERR: not input seek time, example: seek 1000!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t ret = sample.adapter->Rewind(timeMs, PlayerSeekMode::PLAYER_SEEK_PREVIOUS_SYNC);
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void RunCmdSleep(const char cmd[])
|
||||
{
|
||||
int64_t timeS = 0;
|
||||
if (sscanf_s(cmd, "sleep %d", &timeS) != 1) {
|
||||
printf("ERR: not input replay count, example: sleep 100!\n");
|
||||
return;
|
||||
}
|
||||
sleep(timeS);
|
||||
}
|
||||
|
||||
static void RunCmdPlay(TestSample &sample)
|
||||
{
|
||||
int32_t ret = sample.adapter->Play();
|
||||
if (ret != 0) {
|
||||
printf("[%s: %d] Play failed ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void ShowCmdHelp(void)
|
||||
{
|
||||
printf("Input CMD: quit, show, pause(pu), play(pl), seek [ms], volume [lvol] [rvol], loop [bool], speed [float]"
|
||||
"replay, next [cnt], pressure_pupl [cnt], pressure_seek [cnt], sleep [s] cost_test\n");
|
||||
}
|
||||
|
||||
static void SampleCmd(TestSample &sample)
|
||||
{
|
||||
char cmd[0x40]; /* 64: Array length */
|
||||
int ret;
|
||||
char *retValue = nullptr;
|
||||
|
||||
ShowCmdHelp();
|
||||
while ((retValue = fgets(cmd, 0x20, stdin)) != nullptr) { /* 10: use array length */
|
||||
cmd[0x20] = '\0'; /* 10: end of string */
|
||||
if (strncmp(cmd, "quit", 0x4) == 0) {
|
||||
printf("quit\n");
|
||||
break;
|
||||
} else if (strncmp(cmd, "pause", 0x4) == 0 || strncmp(cmd, "pu", 0x2) == 0) {
|
||||
ret = sample.adapter->Pause();
|
||||
} else if (strncmp(cmd, "replay", 0x6) == 0) {
|
||||
if (ReplayProcess(sample) != 0) {
|
||||
printf("ReplayProcess process failed\n");
|
||||
break;
|
||||
}
|
||||
} else if (strncmp(cmd, "play", 0x4) == 0 || strncmp(cmd, "pl", 0x2) == 0) {
|
||||
RunCmdPlay(sample);
|
||||
} else if (strncmp(cmd, "speed", 0x5) == 0) {
|
||||
RunCmdSpeed(sample, cmd);
|
||||
} else if (strncmp(cmd, "seek", 0x4) == 0) {
|
||||
RunCmdSeek(sample, cmd);
|
||||
} else if (strncmp(cmd, "volume", 0x6) == 0) {
|
||||
RunCmdSetVolume(sample, cmd);
|
||||
} else if (strncmp(cmd, "show", 0x4) == 0) {
|
||||
RunCmdShow(sample);
|
||||
} else if (strncmp(cmd, "loop", 0x4) == 0) {
|
||||
RunCmdLoop(sample, cmd);
|
||||
} else if (strncmp(cmd, "next", 0x4) == 0) {
|
||||
RunCmdNext(sample, cmd);
|
||||
} else if (strncmp(cmd, "pressure_pupl", 0xd) == 0) {
|
||||
RunCmdPressurePupl(sample, cmd);
|
||||
} else if (strncmp(cmd, "pressure_seek", 0xd) == 0) {
|
||||
RunCmdPressureSeek(sample, cmd);
|
||||
} else if (strncmp(cmd, "sleep", 0x5) == 0) {
|
||||
RunCmdSleep(cmd);
|
||||
} else if (strncmp(cmd, "cost_test", 0x9) == 0) {
|
||||
CostTest(sample);
|
||||
} else {
|
||||
ShowCmdHelp();
|
||||
}
|
||||
}
|
||||
|
||||
printf("cmd test end\n");
|
||||
}
|
||||
|
||||
static int32_t ParseInputParam(int argc, char **argv, TestSample &sample)
|
||||
{
|
||||
int32_t sourceType = 1;
|
||||
int32_t pauseAfterPlay = 0;
|
||||
|
||||
if (argv == nullptr) {
|
||||
printf("argv is nullptr error %s %d\n", __FUNCTION__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc < 0x2) { /* 2: Minimum number of inputs */
|
||||
printf("usage: %s filename source_type(1:uri, 2:stream-source) pause-after-play(1:yes, ohter:no)\n", argv[0]);
|
||||
printf("eg: %s file 1 0\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if (argc >= 0x3) { /* 4: sourceType */
|
||||
sourceType = atoi(argv[0x2]); /* */
|
||||
if ((sourceType != 1) && (sourceType != 0x2)) {
|
||||
printf("unsuport sourceType:%d\n", sourceType);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (argc >= 0x4) {
|
||||
pauseAfterPlay = atoi(argv[0x3]);
|
||||
if (pauseAfterPlay != 1) {
|
||||
printf("unsuport pauseAfterPlay:%d, not enable pause after play mode\n", sourceType);
|
||||
pauseAfterPlay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_init(&sample.mutex, nullptr);
|
||||
sample.pauseAfterPlay = pauseAfterPlay;
|
||||
sample.sourceType = sourceType;
|
||||
|
||||
if ((sourceType == 0 || sourceType == 0x2) && (realpath(argv[1], sample.filePath) == nullptr)) {
|
||||
printf("realpath input file failed, errno: %d!\n", errno);
|
||||
return -1;
|
||||
} else if (strlen(argv[1]) < PATH_MAX) {
|
||||
if (memcpy_s(sample.filePath, PATH_MAX, argv[1], strlen(argv[1]) + 1) != 0) {
|
||||
printf("memcpy_s failed!\n");
|
||||
}
|
||||
} else {
|
||||
printf("input path too long!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("[%s,%d] sourceType:%d, path:%s, pauseAfterPlay:%d\n", __func__, __LINE__, sourceType, sample.filePath,
|
||||
pauseAfterPlay);
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
prctl(PR_SET_NAME, "mainProc", 0, 0, 0);
|
||||
TestSample sample = {0};
|
||||
sample.process = -1;
|
||||
|
||||
if (ParseInputParam(argc, argv, sample) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
GetFileSize(sample);
|
||||
sample.adapter = std::make_shared<Player>();
|
||||
SetSourceProcess(sample);
|
||||
|
||||
if (sample.pauseAfterPlay != 0) {
|
||||
Format formatSetPauseAfterPlay;
|
||||
@@ -377,44 +834,23 @@ int main(int argc, char** argv)
|
||||
}
|
||||
sample.adapter->Prepare();
|
||||
|
||||
sample.adapter->GetDuration(duration);
|
||||
printf("[%s,%d] GetDuration:%lld\n", __func__, __LINE__, duration);
|
||||
sample.adapter->GetVideoWidth(width);
|
||||
printf("[%s,%d] width:%d\n", __func__, __LINE__, width);
|
||||
sample.adapter->GetVideoHeight(heighth);
|
||||
printf("[%s,%d] heighth:%d\n", __func__, __LINE__, heighth);
|
||||
SetCallback(sample);
|
||||
SetSurface(sample);
|
||||
PlayProcess(sample);
|
||||
|
||||
Surface *surface = Surface::CreateSurface();
|
||||
if (surface == nullptr) {
|
||||
printf("[%s,%d] CreateSurface failed\n", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
surface->SetUserData("region_position_x", "0");
|
||||
surface->SetUserData("region_position_y", "0");
|
||||
surface->SetUserData("region_width", "480");
|
||||
surface->SetUserData("region_height", "480");
|
||||
sample.adapter->SetVideoSurface(surface);
|
||||
sleep(1);
|
||||
|
||||
if (sample.pauseAfterPlay != 0) {
|
||||
sample.adapter->Pause();
|
||||
} else {
|
||||
sample.adapter->Play();
|
||||
}
|
||||
|
||||
/* ¶¨ÖÆ»¯´¦Àí */
|
||||
SampleCmd(sample);
|
||||
EndStreamSourceThread(sample);
|
||||
int32_t ret = sample.adapter->Stop();
|
||||
printf("Stop, ret:%d\n", ret);
|
||||
|
||||
sample.adapter->Stop();
|
||||
sample.adapter->Reset();
|
||||
ret = sample.adapter->Release();
|
||||
printf("Release, ret:%d\n", ret);
|
||||
DestorySurface(sample);
|
||||
DestoryCallback(sample);
|
||||
pthread_mutex_destroy(&sample.mutex);
|
||||
|
||||
sample.adapter->Release();
|
||||
if (sample.sourceType == 2) {
|
||||
pthread_mutex_lock(&sample.mutex);
|
||||
sample.isThreadRunning = 0;
|
||||
pthread_mutex_unlock(&sample.mutex);
|
||||
pthread_join(sample.process, nullptr);
|
||||
pthread_mutex_destroy(&sample.mutex);
|
||||
}
|
||||
printf("[%s, %d] main end\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user