Skip to content

Commit

Permalink
framework/media, apps/examples: sync from ecode
Browse files Browse the repository at this point in the history
sync media, focusmanager and example apps from Media

Co-authored-by: Kota Sai Krishna <kdotsaikrishna>
  • Loading branch information
kdotsaikrishna authored and vibhor-m committed Dec 18, 2024
1 parent 86222d1 commit 104d7bd
Show file tree
Hide file tree
Showing 24 changed files with 743 additions and 308 deletions.
28 changes: 21 additions & 7 deletions apps/examples/SoundPlayer/soundplayer_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ class SoundPlayer : public MediaPlayerObserverInterface,
{
public:
SoundPlayer() : mNumContents(0), mPlayIndex(-1), mHasFocus(false), mSampleRate(DEFAULT_SAMPLERATE_TYPE), \
mPaused(false), mIsPlaying(false), mStopped(false), mTrackFinished(false), mVolume(DEFAULT_VOLUME) {};
mPaused(false), mIsPlaying(false), mStopped(false), mTrackFinished(false), mVolume(DEFAULT_VOLUME), mLooping(false) {};
~SoundPlayer() {};
bool init(char *argv[]);
bool init(int argc, char *argv[]);
player_result_t startPlayback(void);
bool checkTrackFinished(void);
void handleError(player_error_t error);
Expand Down Expand Up @@ -85,6 +85,7 @@ class SoundPlayer : public MediaPlayerObserverInterface,
bool mTrackFinished;
unsigned int mSampleRate;
uint8_t mVolume;
bool mLooping;
void loadContents(const char *path);
};

Expand Down Expand Up @@ -149,6 +150,7 @@ void SoundPlayer::handleError(player_error_t error)
if (mHasFocus) {
auto &focusManager = FocusManager::getFocusManager();
focusManager.abandonFocus(mFocusRequest);
mHasFocus = false;
}
mp.unprepare();
mp.destroy();
Expand Down Expand Up @@ -195,7 +197,7 @@ void SoundPlayer::onFocusChange(int focusChange)
printf("it was paused, just start playback now\n");
res = mp.start();
if (res != PLAYER_OK) {
printf("start failed res : %d\n", res);
printf("player start failed res : %d\n", res);
}
} else {
res = startPlayback();
Expand All @@ -219,7 +221,7 @@ void SoundPlayer::onFocusChange(int focusChange)
}
}

bool SoundPlayer::init(char *argv[])
bool SoundPlayer::init(int argc, char *argv[])
{
struct stat st;
int ret;
Expand Down Expand Up @@ -266,6 +268,10 @@ bool SoundPlayer::init(char *argv[])
mSampleRate = atoi(argv[3]);
mTrackFinished = false;

if (argc > 5 && strcmp(argv[5], "1") == 0) {
mLooping = true;
}

auto &focusManager = FocusManager::getFocusManager();
printf("mp : %x request focus!!\n", &mp);
focusManager.requestFocus(mFocusRequest);
Expand All @@ -284,15 +290,21 @@ player_result_t SoundPlayer::startPlayback(void)
source->setPcmFormat(DEFAULT_FORMAT_TYPE);
res = mp.setDataSource(std::move(source));
if (res != PLAYER_OK) {
handleError((player_error_t)res);
printf("set Data source failed. res : %d\n", res);
return res;
}

res = mp.prepare();
if (res != PLAYER_OK) {
handleError((player_error_t)res);
printf("prepare failed res : %d\n", res);
return res;
}
if (mLooping) {
mp.setLooping(true);
printf("Looping is set to true\n");
}
uint8_t curVolume = 0;
mp.getVolume(&curVolume);
printf("Current volume : %d new Volume : %d\n", curVolume, mVolume);
Expand Down Expand Up @@ -384,11 +396,13 @@ int soundplayer_main(int argc, char *argv[])
auto player = std::shared_ptr<SoundPlayer>(new SoundPlayer());
printf("cur SoundPlayer : %x\n", &player);

if (argc != 5) {
if (argc != 6 && argc != 5) {
printf("invalid input\n");
printf("Usage : soundplayer [contents path] [volume] [sample rate] [stream policy] [looping]\n");
printf("looping argument is optional\n");
return -1;
}
if (!player->init(argv)) {
if (!player->init(argc, argv)) {
return -1;
}

Expand All @@ -400,4 +414,4 @@ int soundplayer_main(int argc, char *argv[])

return 0;
}
}
}
48 changes: 20 additions & 28 deletions apps/examples/wakerec/wakerec.cxx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/****************************************************************************
*
* Copyright 2023 Samsung Electronics All Rights Reserved.
* Copyright 2024 Samsung Electronics All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -24,7 +24,6 @@
#include <cstdio>
#include <debug.h>
#include <tinyara/init.h>
#include <tinyara/pm/pm.h>
#include <media/MediaPlayer.h>
#include <media/MediaPlayerObserverInterface.h>
#include <media/FileInputDataSource.h>
Expand All @@ -39,8 +38,7 @@
#include <iostream>
#include <memory>
#include <functional>

#define CONFIG_SUPPORT_GET_KD 0
#include <tinyara/pm/pm.h>

using namespace std;
using namespace media;
Expand All @@ -49,7 +47,7 @@ using namespace media::voice;

media::voice::SpeechDetector *sd;

static const char *filePath = "/tmp/record.pcm";
static const char *filePath = "/mnt/record.pcm";
uint8_t *gBuffer = NULL;
uint32_t bufferSize = 0;

Expand Down Expand Up @@ -104,21 +102,6 @@ class WakeRec : public media::voice::SpeechDetectorListenerInterface,public Focu
printf("#### onRecordStopError!! errCode : %d\n", errCode);
}

void onRecordStopped(media::MediaRecorder &mediaRecorder, media::recorder_error_t errCode) override
{
printf("##################################\n");
printf("#### onRecordStopped ####\n");
printf("##################################\n");

if (errCode == RECORDER_ERROR_DEVICE_DEAD) {
printf("#### Mic is unreachable ####\n");
mr.unprepare();
mr.destroy();
fclose(fp);
playRecordVoice();
}
}

void onRecordBufferDataReached(media::MediaRecorder &mediaRecorder, std::shared_ptr<unsigned char> data, size_t size) override
{
if (!isRecording) {
Expand Down Expand Up @@ -165,13 +148,17 @@ class WakeRec : public media::voice::SpeechDetectorListenerInterface,public Focu
sd->startKeywordDetect();
/* Now that we finished playback, we can go to sleep */
sleep(3); //for test, add sleep.

pm_resume(PM_IDLE_DOMAIN);
}

void onPlaybackStopped(media::MediaPlayer &mediaPlayer) override
{
mPaused = false;
mp.unprepare();
mp.destroy();
printf("###################################\n");
printf("#### Wait for wakeup triggered ####\n");
printf("###################################\n");
sd->startKeywordDetect();
}

void onPlaybackError(media::MediaPlayer &mediaPlayer, media::player_error_t error) override
Expand Down Expand Up @@ -203,7 +190,6 @@ class WakeRec : public media::voice::SpeechDetectorListenerInterface,public Focu
printf("#### onSpeechDetectionListener\n");
if (event == SPEECH_DETECT_KD) {
/* take wakelock as soon as possible, and we hold it until we play recorded data */
pm_suspend(PM_IDLE_DOMAIN);
printf("Event SPEECH_DETECT_KD\n");
printf("#### [SD] keyword detected.\n");
fp = fopen(filePath, "wb");
Expand Down Expand Up @@ -243,7 +229,9 @@ class WakeRec : public media::voice::SpeechDetectorListenerInterface,public Focu
printf("it was paused, just start playback now\n");
res = mp.start();
if (res != PLAYER_OK) {
printf("start failed res : %d\n", res);
printf("player start failed res : %d\n", res);
auto &focusManager = FocusManager::getFocusManager();
focusManager.abandonFocus(mFocusRequest);
}
} else {
auto source = std::move(unique_ptr<media::stream::FileInputDataSource>(new media::stream::FileInputDataSource(filePath)));
Expand All @@ -253,11 +241,18 @@ class WakeRec : public media::voice::SpeechDetectorListenerInterface,public Focu
mp.setDataSource(std::move(source));
mp.prepare();
mp.setVolume(10);
mp.start();
res = mp.start();
if (res != PLAYER_OK) {
printf("player start failed res : %d\n", res);
auto &focusManager = FocusManager::getFocusManager();
focusManager.abandonFocus(mFocusRequest);
}
}
} break;
case FOCUS_LOSS: {
mp.stop();
auto &focusManager = FocusManager::getFocusManager();
focusManager.abandonFocus(mFocusRequest); // call abandon focus when FOCUS_GAIN callback not required.
} break;
case FOCUS_LOSS_TRANSIENT: {
mp.pause(); //it will be played again
Expand Down Expand Up @@ -347,8 +342,6 @@ int wakerec_main(int argc, char *argv[])
}
}
sd->startKeywordDetect();
/* similar to wake lock, we release wake lock as we started our thread */
pm_resume(PM_IDLE_DOMAIN);

while (1) {
sleep(67);
Expand All @@ -358,4 +351,3 @@ int wakerec_main(int argc, char *argv[])
return 0;
}
}

4 changes: 3 additions & 1 deletion build/configs/rtl8730e/audio/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,8 @@ CONFIG_HTTPSOURCE_DOWNLOAD_BUFFER_THRESHOLD=2048
CONFIG_HTTPSOURCE_DOWNLOAD_STACKSIZE=8192
CONFIG_DATASOURCE_PREPARSE_BUFFER_SIZE=4096
CONFIG_CONTAINER_FORMAT=y
CONFIG_FOCUS_MANAGER_STACKSIZE=4096
CONFIG_FOCUS_MANAGER_THREAD_PRIORITY=199

#
# Containers for multi-media
Expand Down Expand Up @@ -1063,7 +1065,7 @@ CONFIG_FILE_DATASOURCE_STREAM_BUFFER_SIZE=4096
CONFIG_FILE_DATASOURCE_STREAM_BUFFER_THRESHOLD=2048
CONFIG_BUFFER_DATASOURCE_STREAM_BUFFER_SIZE=4096
CONFIG_BUFFER_DATASOURCE_STREAM_BUFFER_THRESHOLD=1
CONFIG_HANDLER_STREAM_BUFFER_SIZE=4096
CONFIG_HANDLER_STREAM_BUFFER_SIZE=16384
CONFIG_HANDLER_STREAM_BUFFER_THRESHOLD=2048
CONFIG_AUDIO_CODEC=y
CONFIG_AUDIO_CODEC_RINGBUFFER_SIZE=16384
Expand Down
4 changes: 3 additions & 1 deletion build/configs/rtl8730e/loadable_audio/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,8 @@ CONFIG_HTTPSOURCE_DOWNLOAD_BUFFER_THRESHOLD=2048
CONFIG_HTTPSOURCE_DOWNLOAD_STACKSIZE=8192
CONFIG_DATASOURCE_PREPARSE_BUFFER_SIZE=4096
CONFIG_CONTAINER_FORMAT=y
CONFIG_FOCUS_MANAGER_STACKSIZE=4096
CONFIG_FOCUS_MANAGER_THREAD_PRIORITY=199

#
# Containers for multi-media
Expand Down Expand Up @@ -1094,7 +1096,7 @@ CONFIG_FILE_DATASOURCE_STREAM_BUFFER_SIZE=4096
CONFIG_FILE_DATASOURCE_STREAM_BUFFER_THRESHOLD=2048
CONFIG_BUFFER_DATASOURCE_STREAM_BUFFER_SIZE=4096
CONFIG_BUFFER_DATASOURCE_STREAM_BUFFER_THRESHOLD=1
CONFIG_HANDLER_STREAM_BUFFER_SIZE=4096
CONFIG_HANDLER_STREAM_BUFFER_SIZE=16384
CONFIG_HANDLER_STREAM_BUFFER_THRESHOLD=2048

#
Expand Down
17 changes: 16 additions & 1 deletion framework/include/audio/SoundManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,24 @@ bool setMicMute(void);
*/
bool setMicUnmute(void);

/**
* @brief Sets mute state for the given stream.
* @param[in] stream_policy Policy of the stream.
* @param[in] mute The mute state to be set. true for mute, false for unmute.
* @return true if the operation was successful, false otherwise.
*/
bool setStreamMute(stream_policy_t stream_policy, bool mute);

/**
* @brief Gets mute state for the given stream.
* @param[in] stream_policy Policy of the stream.
* @param[in] mute Pointer to store the mute state. true for mute, false for unmute.
* @return true if the operation was successful, false otherwise.
*/
bool getStreamMuteState(stream_policy_t stream_policy, bool *mute);

#if defined(__cplusplus)
}
#endif

#endif

37 changes: 23 additions & 14 deletions framework/include/media/FocusManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@

namespace media {

static const int FOCUS_REQUEST_SUCCESS = 0;
static const int FOCUS_REQUEST_FAIL = -1;
static const int FOCUS_REQUEST_DELAY = -2;
static const int FOCUS_REQUEST_SUCCESS = 0; /* Request accepted, onFocusChange will be called with appropriate values */
static const int FOCUS_REQUEST_GAINED = 1; /* Focus already gained. */
static const int FOCUS_REQUEST_FAIL = -1; /* Requested operation failed */
/*@ToDo: change FOCUS_REQUEST_DELAY value to positive number as it is not a failure case.*/
static const int FOCUS_REQUEST_DELAY = -2; /* Requested operation delayed. onFocusChange will be called with appropriate values */

/**
* @class
Expand All @@ -59,35 +61,41 @@ class FocusManager
*/
static FocusManager &getFocusManager();
/**
* @brief Abandon Focus
* @brief Abandon focus by passing it's Focus Request variable as argument. This is asynchronous function call. Focus will be revoked and request wll be removed from queue.
* @details @b #include <media/FocusManager.h>
* param[in] focusRequest FocusRequest to abandon
* @return return FOCUS_REQUEST_SUCCESS on Success, else return FOCUS_REQUEST_FAIL
* @return FOCUS_REQUEST_SUCCESS: successful request and there is no callback for abandon focus.
* FOCUS_REQUEST_FAIL: parameter is not valid. Request is ignored.
* @since TizenRT v2.0
*/
int abandonFocus(std::shared_ptr<FocusRequest> focusRequest);
/**
* @brief Request Focus
* @brief Requests focus by passing it's Focus Request variable as argument. This is asynchronous function call. Focus gained / lost is shared in onFocusChange callback. An application must have gained focus before calling MediaPlayer API. MediaPlayer API without focus gain may return error.
* @details @b #include <media/FocusManager.h>
* param[in] focusRequest FocusRequest to request
* @return return FOCUS_REQUEST_SUCCESS on immediate GAIN and FOCUS_REQUEST_DELAY for GAIN later, else return FOCUS_REQUEST_FAIL
* param[in] focusRequest FocusRequest object corresponding to a media type
* @return FOCUS_REQUEST_GAINED: if requesting application already has gained focus. No callback will be called in this case.
* FOCUS_REQUEST_FAIL: parameter is not valid. Request is ignored. Callback function will not be called.
* FOCUS_REQUEST_SUCCESS: successful request and result will be shared via callback function. FOCUS_REQUEST_SUCCESS does not mean focus is gained and application must wait for callback function before proceeding further.
* @since TizenRT v2.0
*/
int requestFocus(std::shared_ptr<FocusRequest> focusRequest);

/**
* @brief Request Transient Focus
* @brief Requests Transient focus by passing it's Focus Request variable as argument. This is asynchronous function call. Focus gained / lost is shared in onFocusChange callback. An application must have gained focus before calling MediaPlayer API. MediaPlayer API without focus gained may return error.
* @details @b #include <media/FocusManager.h>
* param[in] focusRequest FocusRequest to request
* @return return FOCUS_REQUEST_SUCCESS on immediate GAIN and FOCUS_REQUEST_DELAY for GAIN later, else return FOCUS_REQUEST_FAIL
* param[in] focusRequest FocusRequest object corresponding to a media type
* @return FOCUS_REQUEST_GAINED: if requesting application already has gained focus. No callback will be called in this case.
* FOCUS_REQUEST_FAIL: parameter is not valid. Request is ignored. Callback function will not be called.
* FOCUS_REQUEST_SUCCESS: successful request and result will be shared via callback function. FOCUS_REQUEST_SUCCESS does not mean focus is gained and application must wait for callback function before proceeding further.
* @since TizenRT v2.0
*/
int requestFocusTransient(std::shared_ptr<FocusRequest> focusRequest);

/**
* @brief Get current focussed stream info
* @details @b #include <media/FocusManager.h>
* @return return STREAM_FOCUS_STATE_ACQUIRED if stream has focus, else return STREAM_FOCUS_STATE_RELEASED
* @return STREAM_FOCUS_STATE_ACQUIRED: if stream has focus.
* STREAM_FOCUS_STATE_RELEASED: if stream does not have focus.
*/
stream_info_t getCurrentStreamInfo(void);

Expand All @@ -108,9 +116,10 @@ class FocusManager
std::shared_ptr<FocusChangeListener> mListener;
};

FocusManager() = default;
FocusManager();
virtual ~FocusManager() = default;
int insertFocusElement(std::shared_ptr<FocusRequest> focusRequest, bool isTransientRequest);
void insertFocusElement(std::shared_ptr<FocusRequest> focusRequest, bool isTransientRequest);
void removeFocusAndNotify(std::shared_ptr<FocusRequest> focusRequest);
void removeFocusElement(std::shared_ptr<FocusRequest> focusRequest);
std::list<std::shared_ptr<FocusRequester>> mFocusList;
std::mutex mFocusLock;
Expand Down
Loading

0 comments on commit 104d7bd

Please sign in to comment.