NuPlayerStreamListener.cpp revision f933441648ef6a71dee783d733aac17b9508b452
1/* 2 * Copyright (C) 2010 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_NDEBUG 0 18#define LOG_TAG "NuPlayerStreamListener" 19#include <utils/Log.h> 20 21#include "NuPlayerStreamListener.h" 22 23#include <binder/MemoryDealer.h> 24#include <media/stagefright/foundation/ADebug.h> 25 26namespace android { 27 28NuPlayer::NuPlayerStreamListener::NuPlayerStreamListener( 29 const sp<IStreamSource> &source, 30 ALooper::handler_id id) 31 : mSource(source), 32 mTargetID(id), 33 mEOS(false), 34 mSendDataNotification(true) { 35 mSource->setListener(this); 36 37 mMemoryDealer = new MemoryDealer(kNumBuffers * kBufferSize); 38 for (size_t i = 0; i < kNumBuffers; ++i) { 39 sp<IMemory> mem = mMemoryDealer->allocate(kBufferSize); 40 CHECK(mem != NULL); 41 42 mBuffers.push(mem); 43 } 44 mSource->setBuffers(mBuffers); 45} 46 47void NuPlayer::NuPlayerStreamListener::start() { 48 for (size_t i = 0; i < kNumBuffers; ++i) { 49 mSource->onBufferAvailable(i); 50 } 51} 52 53void NuPlayer::NuPlayerStreamListener::queueBuffer(size_t index, size_t size) { 54 QueueEntry entry; 55 entry.mIsCommand = false; 56 entry.mIndex = index; 57 entry.mSize = size; 58 entry.mOffset = 0; 59 60 Mutex::Autolock autoLock(mLock); 61 mQueue.push_back(entry); 62 63 if (mSendDataNotification) { 64 mSendDataNotification = false; 65 (new AMessage(kWhatMoreDataQueued, mTargetID))->post(); 66 } 67} 68 69void NuPlayer::NuPlayerStreamListener::issueCommand( 70 Command cmd, bool synchronous, const sp<AMessage> &extra) { 71 CHECK(!synchronous); 72 73 QueueEntry entry; 74 entry.mIsCommand = true; 75 entry.mCommand = cmd; 76 entry.mExtra = extra; 77 78 Mutex::Autolock autoLock(mLock); 79 mQueue.push_back(entry); 80 81 if (mSendDataNotification) { 82 mSendDataNotification = false; 83 (new AMessage(kWhatMoreDataQueued, mTargetID))->post(); 84 } 85} 86 87ssize_t NuPlayer::NuPlayerStreamListener::read(void *data, size_t size) { 88 CHECK_GT(size, 0u); 89 90 Mutex::Autolock autoLock(mLock); 91 92 if (mEOS) { 93 return 0; 94 } 95 96 if (mQueue.empty()) { 97 mSendDataNotification = true; 98 99 return -EWOULDBLOCK; 100 } 101 102 QueueEntry *entry = &*mQueue.begin(); 103 104 if (entry->mIsCommand) { 105 switch (entry->mCommand) { 106 case EOS: 107 { 108 mQueue.erase(mQueue.begin()); 109 entry = NULL; 110 111 mEOS = true; 112 return 0; 113 } 114 115 case DISCONTINUITY: 116 { 117 mQueue.erase(mQueue.begin()); 118 entry = NULL; 119 120 return INFO_DISCONTINUITY; 121 } 122 123 default: 124 TRESPASS(); 125 break; 126 } 127 } 128 129 size_t copy = entry->mSize; 130 if (copy > size) { 131 copy = size; 132 } 133 134 memcpy(data, 135 (const uint8_t *)mBuffers.editItemAt(entry->mIndex)->pointer() 136 + entry->mOffset, 137 copy); 138 139 entry->mOffset += copy; 140 entry->mSize -= copy; 141 142 if (entry->mSize == 0) { 143 mSource->onBufferAvailable(entry->mIndex); 144 mQueue.erase(mQueue.begin()); 145 entry = NULL; 146 } 147 148 return copy; 149} 150 151} // namespace android 152