void MediaRecorderImpl::unprepareRecorder(recorder_result_t& ret) { medvdbg("unprepareRecorder mCurState : %d\n", (recorder_state_t)mCurState); if (mCurState == RECORDER_STATE_NONE || mCurState == RECORDER_STATE_IDLE) { meddbg("unprepare Failed : %d\n", (recorder_state_t)mCurState); return notifySync(); } audio_manager_result_t result = reset_audio_stream_in(); if (result != AUDIO_MANAGER_SUCCESS) { meddbg("reset_audio_stream_in failed ret : %d\n", result); return notifySync(); } if (mOutputDataSource->isPrepare()) { mOutputDataSource->close(); } if (mBuffer) { delete[] mBuffer; mBuffer = nullptr; } mBuffSize = 0; mDuration = 0; mTotalFrames = 0; mCapturedFrames = 0; mCurState = RECORDER_STATE_IDLE; ret = RECORDER_OK; notifySync(); }
void MediaRecorderImpl::stopRecorder(bool completed) { medvdbg("stopRecorder mCurState : %d\n", (recorder_state_t)mCurState); if ((mCurState != RECORDER_STATE_RECORDING && mCurState != RECORDER_STATE_PAUSED)) { notifyObserver(OBSERVER_COMMAND_ERROR); meddbg("stopRecorder Failed mCurState : %d\n", (recorder_state_t)mCurState); return; } audio_manager_result_t result = stop_audio_stream_in(); if (result != AUDIO_MANAGER_SUCCESS) { notifyObserver(OBSERVER_COMMAND_ERROR); meddbg("stop_audio_stream_in failed ret : %d\n", result); return; } mCurState = RECORDER_STATE_READY; if (completed) { notifyObserver(OBSERVER_COMMAND_FINISHIED); } else { notifyObserver(OBSERVER_COMMAND_ERROR); } RecorderWorker& mrw = RecorderWorker::getWorker(); mrw.setCurrentRecorder(nullptr); }
void MediaRecorderImpl::startRecorder() { medvdbg("startRecorder() mCurState : %d\n", (recorder_state_t)mCurState); if (mCurState != RECORDER_STATE_READY && mCurState != RECORDER_STATE_PAUSED) { notifyObserver(OBSERVER_COMMAND_ERROR); meddbg("startRecorder Failed mCurState : %d\n", (recorder_state_t)mCurState); return; } RecorderWorker& mrw = RecorderWorker::getWorker(); auto prevRecorder = mrw.getCurrentRecorder(); auto curRecorder = shared_from_this(); if (prevRecorder != curRecorder) { if (prevRecorder) { /** TODO Should be considered Audiofocus later **/ meddbg("stop prevRecorder\n"); prevRecorder->pauseRecorder(); } meddbg("set Current Recorder!!\n"); mrw.setCurrentRecorder(curRecorder); } mCurState = RECORDER_STATE_RECORDING; notifyObserver(OBSERVER_COMMAND_STARTED); }
ssize_t FileInputDataSource::read(unsigned char *buf, size_t size) { if (!isPrepare()) { meddbg("%s[line : %d] Fail : FileInputDataSource is not prepared\n", __func__, __LINE__); return EOF; } if (buf == nullptr) { meddbg("%s[line : %d] Fail : buf is nullptr\n", __func__, __LINE__); return EOF; } size_t rlen = fread(buf, sizeof(unsigned char), size, mFp); medvdbg("read size : %d\n", rlen); if (rlen == 0) { /* If file position reaches end of file, it's a normal case, we returns 0 */ if (feof(mFp)) { medvdbg("eof!!!\n"); return 0; } /* Otherwise, an error occurred, we also returns error */ return EOF; } return rlen; }
bool SocketOutputDataSource::open() { socklen_t addrlen; struct sockaddr_in serveraddr; if (mSockFd != INVALID_SOCKET) { meddbg("Error: Socket is already open\n"); return false; } mSockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (mSockFd == INVALID_SOCKET) { meddbg("Error: Fail to open socket\n"); return false; } serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(mPort); serveraddr.sin_addr.s_addr = inet_addr(mIpAddr.c_str()); addrlen = sizeof(struct sockaddr); if (connect(mSockFd, (struct sockaddr *)&serveraddr, addrlen) < 0) { meddbg("Errro: Fail to connect socket (errno=%d)\n", errno); ::close(mSockFd); return false; } medvdbg("Connected to the server, fd = %d\n", mSockFd); return true; }
void MediaRecorderImpl::capture() { medvdbg("MediaRecorderImpl::capture()\n"); unsigned int frameSize = get_input_frame_count(); if (mTotalFrames > 0) { int64_t remainFrames = mTotalFrames - mCapturedFrames; /* almost reaches size limit, adjust frame size before request capture to audio_manager */ if (remainFrames < frameSize) { frameSize = remainFrames; } } int frames = start_audio_stream_in(mBuffer, frameSize); if (frames > 0) { mCapturedFrames += frames; if (mCapturedFrames > INT_MAX) { mCapturedFrames = 0; meddbg("Too huge value : %d, set 0 to prevent overflow\n", mCapturedFrames); } int ret = 0; int size = get_input_frames_to_byte(frames); while (size > 0) { int written = mOutputDataSource->write(mBuffer + ret, size); medvdbg("written : %d size : %d frames : %d\n", written, size, frames); medvdbg("mCapturedFrames : %ld totalduration : %d mTotalFrames : %ld\n", mCapturedFrames, mDuration, mTotalFrames); /* For Error case, we stop Capture */ if (written == EOF) { meddbg("MediaRecorderImpl::capture() failed : errno : %d written : %d\n", errno, written); RecorderWorker& mrw = RecorderWorker::getWorker(); mrw.enQueue(&MediaRecorderImpl::stopRecorder, shared_from_this(), false); break; } /* It finished Successfully refer to file size or frame numbers*/ if ((written == 0) || (mTotalFrames == mCapturedFrames)) { medvdbg("File write Ended\n"); RecorderWorker& mrw = RecorderWorker::getWorker(); mrw.enQueue(&MediaRecorderImpl::stopRecorder, shared_from_this(), true); break; } size -= written; ret += written; } } else { std::lock_guard<std::mutex> lock(mCmdMtx); meddbg("Too small frames : %d\n", frames); RecorderWorker& mrw = RecorderWorker::getWorker(); mrw.enQueue(&MediaRecorderImpl::stopRecorder, shared_from_this(), false); } }
MediaRecorderImpl::~MediaRecorderImpl() { medvdbg("MediaRecorderImpl::~MediaRecorderImpl()\n"); if (mCurState > RECORDER_STATE_IDLE) { if (unprepare() != RECORDER_OK) { meddbg("unprepare failed\n"); } } if (mCurState == RECORDER_STATE_IDLE) { if (destroy() != RECORDER_OK) { meddbg("destroy failed\n"); } } }
ssize_t BufferOutputDataSource::write(unsigned char* buf, size_t size) { if (!buf) { meddbg("buf is nullptr, hence return EOF\n"); return EOF; } if (size <= 0) { meddbg("size is 0 or less, hence return EOF\n"); return EOF; } ssize_t ret; ret = mCallback(buf, size); //TODO - The return value of Callback will be modified. return ret; }
void MediaRecorderImpl::prepareRecorder(recorder_result_t& ret) { medvdbg("prepareRecorder mCurState : %d\n", (recorder_state_t)mCurState); if (mCurState != RECORDER_STATE_IDLE || mOutputDataSource == nullptr) { meddbg("prepare Failed mCurState: %d mOutputDataSource : %s\n", (recorder_state_t)mCurState, \ (mOutputDataSource == nullptr ? "nullptr" : "not null")); return notifySync(); } if (!mOutputDataSource->open()) { meddbg("open() failed\n"); return notifySync(); } audio_manager_result_t result = set_audio_stream_in(mOutputDataSource->getChannels(), mOutputDataSource->getSampleRate(), (pcm_format)mOutputDataSource->getPcmFormat()); if (result != AUDIO_MANAGER_SUCCESS) { meddbg("set_audio_stream_in failed : result : %d channel %d sample rate : %d format : %d\n", result, \ mOutputDataSource->getChannels(), mOutputDataSource->getSampleRate(), (pcm_format)mOutputDataSource->getPcmFormat()); mOutputDataSource->close(); return notifySync(); } mBuffSize = get_input_frames_to_byte(get_input_frame_count()); if (mBuffSize <= 0) { meddbg("Buffer size is too small size : %d\n", mBuffSize); mOutputDataSource->close(); return notifySync(); } medvdbg("mBuffer size : %d\n", mBuffSize); mBuffer = new unsigned char[mBuffSize]; if (!mBuffer) { meddbg("mBuffer alloc failed\n"); mOutputDataSource->close(); return notifySync(); } if (mDuration > 0) { mTotalFrames = mDuration * mOutputDataSource->getSampleRate(); } mCurState = RECORDER_STATE_READY; ret = RECORDER_OK; notifySync(); }
recorder_result_t MediaRecorderImpl::destroy() { std::unique_lock<std::mutex> lock(mCmdMtx); medvdbg("MediaRecorderImpl::destroy()\n"); RecorderWorker& mrw = RecorderWorker::getWorker(); if (!mrw.isAlive()) { meddbg("Worker is not alive\n"); return RECORDER_ERROR; } recorder_result_t ret = RECORDER_ERROR; mrw.enQueue(&MediaRecorderImpl::destroyRecorder, shared_from_this(), std::ref(ret)); mSyncCv.wait(lock); if (ret == RECORDER_OK) { if (mRecorderObserver) { RecorderObserverWorker& row = RecorderObserverWorker::getWorker(); row.stopWorker(); mRecorderObserver = nullptr; } mrw.stopWorker(); } return ret; }
void MediaRecorderImpl::setRecorderDataSource(std::shared_ptr<stream::OutputDataSource> dataSource, recorder_result_t& ret) { if (mCurState != RECORDER_STATE_IDLE) { meddbg("setDataSource failed mCurState : %d\n", (recorder_state_t)mCurState); return notifySync(); } if (!dataSource) { meddbg("DataSource is nullptr\n"); return notifySync(); } mOutputDataSource = dataSource; ret = RECORDER_OK; notifySync(); }
bool FileOutputDataSource::close() { if (mFp) { int ret = fclose(mFp); if (ret == OK) { mFp = nullptr; medvdbg("close success!!\n"); return true; } else { meddbg("close failed ret : %d error : %d\n", ret, errno); return false; } } meddbg("close failed, mFp is nullptr!!\n"); return false; }
bool FileInputDataSource::close() { bool ret = true; if (mFp) { if (fclose(mFp) == OK) { mFp = nullptr; medvdbg("close success!!\n"); } else { meddbg("close failed ret : %d error : %d\n", ret, errno); ret = false; } } else { meddbg("close failed, mFp is nullptr!!\n"); ret = false; } return ret; }
void MediaRecorderImpl::createRecorder(recorder_result_t& ret) { medvdbg("createRecorder mCurState : %d\n", (recorder_state_t)mCurState); if (mCurState != RECORDER_STATE_NONE) { meddbg("mCurState != RECORDER_STATE_NONE mCurState : %d\n", (recorder_state_t)mCurState); return notifySync(); } audio_manager_result_t result = init_audio_stream_in(); if (result != AUDIO_MANAGER_SUCCESS) { meddbg("Fail to initialize input audio stream : %d\n", result); return notifySync(); } mCurState = RECORDER_STATE_IDLE; ret = RECORDER_OK; notifySync(); }
void MediaRecorderImpl::pauseRecorder() { medvdbg("pauseRecorder() mCurState : %d\n", (recorder_state_t)mCurState); if (mCurState != RECORDER_STATE_RECORDING) { notifyObserver(OBSERVER_COMMAND_ERROR); meddbg("pause Failed mCurState : %d\n", (recorder_state_t)mCurState); return; } audio_manager_result_t result = pause_audio_stream_in(); if (result != AUDIO_MANAGER_SUCCESS) { notifyObserver(OBSERVER_COMMAND_ERROR); meddbg("pause_audio_stream_in failed ret : %d\n", result); return; } mCurState = RECORDER_STATE_PAUSED; notifyObserver(OBSERVER_COMMAND_PAUSED); }
void MediaRecorderImpl::setRecorderVolume(int vol, recorder_result_t& ret) { medvdbg("setRecorderVolume\n"); int maxVolume = get_max_audio_volume(); if (vol < 0 || vol > maxVolume) { meddbg("Volume is out of range vol : %d (recorder ranage 0 ~ %d)\n", vol, maxVolume); return notifySync(); } audio_manager_result_t result = set_input_audio_volume((uint8_t)vol); if (result != AUDIO_MANAGER_SUCCESS) { meddbg("set_input_audio_volume failed vol : %d ret : %d\n", vol, result); return notifySync(); } medvdbg("setVolume is success vol : %d\n", vol); ret = RECORDER_OK; notifySync(); }
bool Encoder::init(void) { #ifdef CONFIG_AUDIO_CODEC switch (mAudioType) { #ifdef CONFIG_CODEC_LIBOPUS case AUDIO_TYPE_OPUS: { opus_enc_external_t ext = {0}; // params for opus encoding #if defined(CONFIG_OPUS_APPLICATION_VOIP) ext.applicationMode = OPUS_APPLICATION_VOIP; #elif defined(CONFIG_OPUS_APPLICATION_AUDIO) ext.applicationMode = OPUS_APPLICATION_AUDIO; #elif defined(CONFIG_OPUS_APPLICATION_RESTRICTED_LOWDELAY) ext.applicationMode = OPUS_APPLICATION_RESTRICTED_LOWDELAY; #else ext.applicationMode = OPUS_APPLICATION_AUDIO; #endif ext.complexity = CONFIG_OPUS_ENCODE_COMPLEXITY; ext.frameSizeMS = CONFIG_OPUS_ENCODE_FRAMESIZE; ext.bitrate = CONFIG_OPUS_ENCODE_BITRATE; ext.bandWidth = OPUS_AUTO; // allocate memory resource size_t inSamples = mSampleRate * mChannels * ext.frameSizeMS / MSEC_PER_SECOND; inputBuf = new signed short[inSamples]; outputBuf = new unsigned char[MAX_PACKET_SIZE]; // params for streaming ext.pOutputBuffer = outputBuf; ext.outputBufferMaxLength = sizeof(unsigned char) * MAX_PACKET_SIZE; ext.pInputBuffer = inputBuf; ext.inputBufferMaxLength = sizeof(signed short) * inSamples; // params about PCM source ext.inputChannels = mChannels; ext.inputSampleRate = mSampleRate; // Initialize encoder if (audio_encoder_init(&mEncoder, CONFIG_AUDIO_CODEC_RINGBUFFER_SIZE, AUDIO_TYPE_OPUS, &ext) != AUDIO_ENCODER_OK) { meddbg("Error! audio_encoder_init failed!\n"); return false; } return true; } #endif default: return false; } #else return false; #endif }
std::shared_ptr<Encoder> Encoder::create(audio_type_t audioType, unsigned short channels, unsigned int sampleRate) { #ifdef CONFIG_AUDIO_CODEC medvdbg("(%d,%d,%d)\n", audioType, channels, sampleRate); if (audioType == AUDIO_TYPE_UNKNOWN) { meddbg("%s[line : %d] Fail : audio type is unknown\n", __func__, __LINE__); return nullptr; } auto instance = std::make_shared<Encoder>(audioType, channels, sampleRate); if (instance && instance->init()) { return instance; } else { meddbg("%s[line : %d] Fail : init is failed\n", __func__, __LINE__); meddbg("audioType : %d, channels : %d, sampleRate : %d\n", audioType, channels, sampleRate); return nullptr; } #else return nullptr; #endif }
void MediaRecorderImpl::destroyRecorder(recorder_result_t& ret) { medvdbg("destroyRecorder mCurState : %d\n", (recorder_state_t)mCurState); if (mCurState != RECORDER_STATE_IDLE) { meddbg("mCurState != RECORDER_STATE_IDLE mCurState : %d\n", (recorder_state_t)mCurState); return notifySync(); } mCurState = RECORDER_STATE_NONE; ret = RECORDER_OK; notifySync(); }
Encoder::~Encoder() { #ifdef CONFIG_AUDIO_CODEC if (audio_encoder_finish(&mEncoder) != AUDIO_ENCODER_OK) { meddbg("Error! audio_encoder_finish failed!\n"); } if (inputBuf) { delete[] inputBuf; } if (outputBuf) { delete[] outputBuf; } #endif }
recorder_result_t MediaRecorderImpl::prepare() { std::unique_lock<std::mutex> lock(mCmdMtx); medvdbg("MediaRecorderImpl::prepare()\n"); RecorderWorker& mrw = RecorderWorker::getWorker(); if (!mrw.isAlive()) { meddbg("Worker is not alive\n"); return RECORDER_ERROR; } recorder_result_t ret = RECORDER_ERROR; mrw.enQueue(&MediaRecorderImpl::prepareRecorder, shared_from_this(), std::ref(ret)); mSyncCv.wait(lock); return ret; }
void MediaRecorderImpl::setRecorderDuration(int second, recorder_result_t& ret) { medvdbg("setRecorderDuration mCurState : %d\n", (recorder_state_t)mCurState); if (mCurState != RECORDER_STATE_IDLE) { meddbg("setRecorderDuration Failed mCurState: %d\n", (recorder_state_t)mCurState); return notifySync(); } if (second > 0) { medvdbg("second is greater than zero, set limit : %d\n", second); mDuration = second; } ret = RECORDER_OK; notifySync(); }
recorder_result_t MediaRecorderImpl::setObserver(std::shared_ptr<MediaRecorderObserverInterface> observer) { std::unique_lock<std::mutex> lock(mCmdMtx); medvdbg("setObserver\n"); RecorderWorker& mrw = RecorderWorker::getWorker(); if (!mrw.isAlive()) { meddbg("Worker is not alive"); return RECORDER_ERROR; } mrw.enQueue(&MediaRecorderImpl::setRecorderObserver, shared_from_this(), observer); mSyncCv.wait(lock); return RECORDER_OK; }
recorder_result_t MediaRecorderImpl::setDataSource(std::unique_ptr<stream::OutputDataSource> dataSource) { std::unique_lock<std::mutex> lock(mCmdMtx); medvdbg("setDataSource\n"); RecorderWorker& mrw = RecorderWorker::getWorker(); if (!mrw.isAlive()) { meddbg("Worker is not alive\n"); return RECORDER_ERROR; } recorder_result_t ret = RECORDER_ERROR; std::shared_ptr<stream::OutputDataSource> sharedDataSource = std::move(dataSource); mrw.enQueue(&MediaRecorderImpl::setRecorderDataSource, shared_from_this(), sharedDataSource, std::ref(ret)); mSyncCv.wait(lock); return ret; }
bool FileOutputDataSource::open() { if (!mFp) { setAudioType(utils::getAudioTypeFromPath(mDataPath)); mFp = fopen(mDataPath.c_str(), "wb"); if (mFp) { medvdbg("file open success\n"); return true; } else { meddbg("file open failed error : %d\n", errno); return false; } } medvdbg("file already exists\n"); /** return true if mFp is not null, because it means it using now */ return true; }
size_t audio_decoder_get_frames(audio_decoder_p decoder, unsigned char *buf, size_t max, unsigned int *sr, unsigned short *ch) { priv_data_p priv = (priv_data_p) decoder->priv_data; pcm_data_p pcm = &priv->pcm; // Output size, in bytes size_t size = 0; // Check 2 bytes aligned, due to 16bit-PCM format. assert((max % 2) == 0); while (size < max) { if (pcm->samples) { // Copy remained data to decoder output buffer size_t nSamples = (max - size) / BYTES_PER_SAMPLE; if (pcm->length <= nSamples) { // Copy all data memcpy(buf + size, pcm->samples, pcm->length * BYTES_PER_SAMPLE); size += pcm->length * BYTES_PER_SAMPLE; // Clear remained data record pcm->samples = NULL; pcm->length = 0; continue; } else { // Copy part of data required memcpy(buf + size, pcm->samples, nSamples * BYTES_PER_SAMPLE); size = max; // Update remained data record pcm->samples += nSamples; pcm->length -= nSamples; break; } } // Decode more if (!_get_frame(decoder)) { // Need to push more data for further decoding. // In this case, *size < max. medvdbg("there's not enough data, need to push more.\n"); break; } if (_frame_decoder(decoder, pcm) != AUDIO_DECODER_OK) { // Decoding failed meddbg("frame decoding failed!\n"); break; } } // Output sample rate if desired if (sr != NULL) { *sr = pcm->samplerate; } // Output channel num if desired if (ch != NULL) { *ch = pcm->channels; } return size; }