1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "AudioStreamOutSink" 18 //#define LOG_NDEBUG 0 19 20 #include <utils/Log.h> 21 #include <audio_utils/clock.h> 22 #include <media/audiohal/StreamHalInterface.h> 23 #include <media/nbaio/AudioStreamOutSink.h> 24 25 namespace android { 26 27 AudioStreamOutSink::AudioStreamOutSink(sp<StreamOutHalInterface> stream) : 28 NBAIO_Sink(), 29 mStream(stream), 30 mStreamBufferSizeBytes(0) 31 { 32 ALOG_ASSERT(stream != 0); 33 } 34 35 AudioStreamOutSink::~AudioStreamOutSink() 36 { 37 mStream.clear(); 38 } 39 40 ssize_t AudioStreamOutSink::negotiate(const NBAIO_Format offers[], size_t numOffers, 41 NBAIO_Format counterOffers[], size_t& numCounterOffers) 42 { 43 if (!Format_isValid(mFormat)) { 44 status_t result; 45 result = mStream->getBufferSize(&mStreamBufferSizeBytes); 46 if (result != OK) return result; 47 audio_format_t streamFormat; 48 uint32_t sampleRate; 49 audio_channel_mask_t channelMask; 50 result = mStream->getAudioProperties(&sampleRate, &channelMask, &streamFormat); 51 if (result != OK) return result; 52 mFormat = Format_from_SR_C(sampleRate, 53 audio_channel_count_from_out_mask(channelMask), streamFormat); 54 mFrameSize = Format_frameSize(mFormat); 55 } 56 return NBAIO_Sink::negotiate(offers, numOffers, counterOffers, numCounterOffers); 57 } 58 59 ssize_t AudioStreamOutSink::write(const void *buffer, size_t count) 60 { 61 if (!mNegotiated) { 62 return NEGOTIATE; 63 } 64 ALOG_ASSERT(Format_isValid(mFormat)); 65 size_t written; 66 status_t ret = mStream->write(buffer, count * mFrameSize, &written); 67 if (ret == OK && written > 0) { 68 written /= mFrameSize; 69 mFramesWritten += written; 70 return written; 71 } else { 72 // FIXME verify HAL implementations are returning the correct error codes e.g. WOULD_BLOCK 73 ALOGE_IF(ret != OK, "Error while writing data to HAL: %d", ret); 74 return ret; 75 } 76 } 77 78 status_t AudioStreamOutSink::getTimestamp(ExtendedTimestamp ×tamp) 79 { 80 uint64_t position64; 81 struct timespec time; 82 if (mStream->getPresentationPosition(&position64, &time) != OK) { 83 return INVALID_OPERATION; 84 } 85 timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = position64; 86 timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = audio_utils_ns_from_timespec(&time); 87 return OK; 88 } 89 90 } // namespace android 91