1 /* 2 * Copyright 2016, 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 #include <gui/Surface.h> 18 19 #include <media/ICrypto.h> 20 #include <media/stagefright/foundation/ABuffer.h> 21 #include <media/stagefright/foundation/ALooper.h> 22 #include <media/stagefright/foundation/AMessage.h> 23 #include <media/stagefright/foundation/AUtils.h> 24 #include <media/stagefright/MediaBuffer.h> 25 #include <media/stagefright/MediaCodecList.h> 26 #include <media/stagefright/MediaCodec.h> 27 #include <media/stagefright/MetaData.h> 28 #include <media/stagefright/SimpleDecodingSource.h> 29 #include <media/stagefright/Utils.h> 30 31 using namespace android; 32 33 const int64_t kTimeoutWaitForOutputUs = 500000; // 0.5 seconds 34 const int64_t kTimeoutWaitForInputUs = 5000; // 5 milliseconds 35 36 //static 37 sp<SimpleDecodingSource> SimpleDecodingSource::Create( 38 const sp<IMediaSource> &source, uint32_t flags, const sp<ANativeWindow> &nativeWindow, 39 const char *desiredCodec) { 40 sp<Surface> surface = static_cast<Surface*>(nativeWindow.get()); 41 const char *mime = NULL; 42 sp<MetaData> meta = source->getFormat(); 43 CHECK(meta->findCString(kKeyMIMEType, &mime)); 44 45 sp<AMessage> format = new AMessage; 46 if (convertMetaDataToMessage(source->getFormat(), &format) != OK) { 47 return NULL; 48 } 49 50 Vector<AString> matchingCodecs; 51 MediaCodecList::findMatchingCodecs( 52 mime, false /* encoder */, flags, &matchingCodecs); 53 54 sp<ALooper> looper = new ALooper; 55 looper->setName("stagefright"); 56 looper->start(); 57 58 sp<MediaCodec> codec; 59 60 for (size_t i = 0; i < matchingCodecs.size(); ++i) { 61 const AString &componentName = matchingCodecs[i]; 62 if (desiredCodec != NULL && componentName.compare(desiredCodec)) { 63 continue; 64 } 65 66 ALOGV("Attempting to allocate codec '%s'", componentName.c_str()); 67 68 codec = MediaCodec::CreateByComponentName(looper, componentName); 69 if (codec != NULL) { 70 ALOGI("Successfully allocated codec '%s'", componentName.c_str()); 71 72 status_t err = codec->configure(format, surface, NULL /* crypto */, 0 /* flags */); 73 if (err == OK) { 74 err = codec->getOutputFormat(&format); 75 } 76 if (err == OK) { 77 return new SimpleDecodingSource(codec, source, looper, surface != NULL, format); 78 } 79 80 ALOGD("Failed to configure codec '%s'", componentName.c_str()); 81 codec->release(); 82 codec = NULL; 83 } 84 } 85 86 looper->stop(); 87 ALOGE("No matching decoder! (mime: %s)", mime); 88 return NULL; 89 } 90 91 SimpleDecodingSource::SimpleDecodingSource( 92 const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper, 93 bool usingSurface, const sp<AMessage> &format) 94 : mCodec(codec), 95 mSource(source), 96 mLooper(looper), 97 mUsingSurface(usingSurface), 98 mProtectedState(format) { 99 mCodec->getName(&mComponentName); 100 } 101 102 SimpleDecodingSource::~SimpleDecodingSource() { 103 mCodec->release(); 104 mLooper->stop(); 105 } 106 107 status_t SimpleDecodingSource::start(MetaData *params) { 108 (void)params; 109 Mutexed<ProtectedState>::Locked me(mProtectedState); 110 if (me->mState != INIT) { 111 return -EINVAL; 112 } 113 status_t res = mCodec->start(); 114 if (res == OK) { 115 res = mSource->start(); 116 } 117 118 if (res == OK) { 119 me->mState = STARTED; 120 me->mQueuedInputEOS = false; 121 me->mGotOutputEOS = false; 122 } else { 123 me->mState = ERROR; 124 } 125 126 return res; 127 } 128 129 status_t SimpleDecodingSource::stop() { 130 Mutexed<ProtectedState>::Locked me(mProtectedState); 131 if (me->mState != STARTED) { 132 return -EINVAL; 133 } 134 135 // wait for any pending reads to complete 136 me->mState = STOPPING; 137 while (me->mReading) { 138 me.waitForCondition(me->mReadCondition); 139 } 140 141 status_t res1 = mCodec->stop(); 142 if (res1 != OK) { 143 mCodec->release(); 144 } 145 status_t res2 = mSource->stop(); 146 if (res1 == OK && res2 == OK) { 147 me->mState = STOPPED; 148 } else { 149 me->mState = ERROR; 150 } 151 return res1 != OK ? res1 : res2; 152 } 153 154 sp<MetaData> SimpleDecodingSource::getFormat() { 155 Mutexed<ProtectedState>::Locked me(mProtectedState); 156 if (me->mState == STARTED || me->mState == INIT) { 157 sp<MetaData> meta = new MetaData(); 158 convertMessageToMetaData(me->mFormat, meta); 159 return meta; 160 } 161 return NULL; 162 } 163 164 SimpleDecodingSource::ProtectedState::ProtectedState(const sp<AMessage> &format) 165 : mReading(false), 166 mFormat(format), 167 mState(INIT), 168 mQueuedInputEOS(false), 169 mGotOutputEOS(false) { 170 } 171 172 status_t SimpleDecodingSource::read( 173 MediaBuffer **buffer, const ReadOptions *options) { 174 *buffer = NULL; 175 176 Mutexed<ProtectedState>::Locked me(mProtectedState); 177 if (me->mState != STARTED) { 178 return ERROR_END_OF_STREAM; 179 } 180 me->mReading = true; 181 182 status_t res = doRead(me, buffer, options); 183 184 me.lock(); 185 me->mReading = false; 186 if (me->mState != STARTED) { 187 me->mReadCondition.signal(); 188 } 189 190 return res; 191 } 192 193 status_t SimpleDecodingSource::doRead( 194 Mutexed<ProtectedState>::Locked &me, MediaBuffer **buffer, const ReadOptions *options) { 195 // |me| is always locked on entry, but is allowed to be unlocked on exit 196 CHECK_EQ(me->mState, STARTED); 197 198 size_t out_ix, in_ix, out_offset, out_size; 199 int64_t out_pts; 200 uint32_t out_flags; 201 status_t res; 202 203 // flush codec on seek 204 IMediaSource::ReadOptions::SeekMode mode; 205 if (options != NULL && options->getSeekTo(&out_pts, &mode)) { 206 me->mQueuedInputEOS = false; 207 me->mGotOutputEOS = false; 208 mCodec->flush(); 209 } 210 211 if (me->mGotOutputEOS) { 212 return ERROR_END_OF_STREAM; 213 } 214 215 for (int retries = 0; ++retries; ) { 216 // If we fill all available input buffers, we should expect that 217 // the codec produces at least one output buffer. Also, the codec 218 // should produce an output buffer in at most 1 seconds. Retry a 219 // few times nonetheless. 220 while (!me->mQueuedInputEOS) { 221 // allow some time to get input buffer after flush 222 res = mCodec->dequeueInputBuffer(&in_ix, kTimeoutWaitForInputUs); 223 if (res == -EAGAIN) { 224 // no available input buffers 225 break; 226 } 227 228 sp<ABuffer> in_buffer; 229 if (res == OK) { 230 res = mCodec->getInputBuffer(in_ix, &in_buffer); 231 } 232 233 if (res != OK || in_buffer == NULL) { 234 ALOGW("[%s] could not get input buffer #%zu", 235 mComponentName.c_str(), in_ix); 236 me->mState = ERROR; 237 return UNKNOWN_ERROR; 238 } 239 240 MediaBuffer *in_buf; 241 while (true) { 242 in_buf = NULL; 243 me.unlock(); 244 res = mSource->read(&in_buf, options); 245 me.lock(); 246 if (res != OK || me->mState != STARTED) { 247 if (in_buf != NULL) { 248 in_buf->release(); 249 in_buf = NULL; 250 } 251 252 // queue EOS 253 me->mQueuedInputEOS = true; 254 if (mCodec->queueInputBuffer( 255 in_ix, 0 /* offset */, 0 /* size */, 256 0 /* pts */, MediaCodec::BUFFER_FLAG_EOS) != OK) { 257 ALOGI("[%s] failed to queue input EOS", mComponentName.c_str()); 258 me->mState = ERROR; 259 return UNKNOWN_ERROR; 260 } 261 262 // don't stop on EOS, but report error or EOS on stop 263 if (res != ERROR_END_OF_STREAM) { 264 me->mState = ERROR; 265 return res; 266 } 267 if (me->mState != STARTED) { 268 return ERROR_END_OF_STREAM; 269 } 270 break; 271 } 272 if (in_buf == NULL) { // should not happen 273 continue; 274 } else if (in_buf->range_length() != 0) { 275 break; 276 } 277 in_buf->release(); 278 } 279 280 if (in_buf != NULL) { 281 int64_t timestampUs = 0; 282 CHECK(in_buf->meta_data()->findInt64(kKeyTime, ×tampUs)); 283 if (in_buf->range_length() > in_buffer->capacity()) { 284 ALOGW("'%s' received %zu input bytes for buffer of size %zu", 285 mComponentName.c_str(), 286 in_buf->range_length(), in_buffer->capacity()); 287 } 288 memcpy(in_buffer->base(), (uint8_t *)in_buf->data() + in_buf->range_offset(), 289 min(in_buf->range_length(), in_buffer->capacity())); 290 291 res = mCodec->queueInputBuffer( 292 in_ix, 0 /* offset */, in_buf->range_length(), 293 timestampUs, 0 /* flags */); 294 if (res != OK) { 295 ALOGI("[%s] failed to queue input buffer #%zu", mComponentName.c_str(), in_ix); 296 me->mState = ERROR; 297 } 298 in_buf->release(); 299 } 300 } 301 302 me.unlock(); 303 res = mCodec->dequeueOutputBuffer( 304 &out_ix, &out_offset, &out_size, &out_pts, 305 &out_flags, kTimeoutWaitForOutputUs /* timeoutUs */); 306 me.lock(); 307 // abort read on stop 308 if (me->mState != STARTED) { 309 if (res == OK) { 310 mCodec->releaseOutputBuffer(out_ix); 311 } 312 return ERROR_END_OF_STREAM; 313 } 314 315 if (res == -EAGAIN) { 316 ALOGD("[%s] did not produce an output buffer. retry count: %d", 317 mComponentName.c_str(), retries); 318 continue; 319 } else if (res == INFO_FORMAT_CHANGED) { 320 if (mCodec->getOutputFormat(&me->mFormat) != OK) { 321 me->mState = ERROR; 322 res = UNKNOWN_ERROR; 323 } 324 return res; 325 } else if (res == INFO_OUTPUT_BUFFERS_CHANGED) { 326 ALOGV("output buffers changed"); 327 continue; 328 } else if (res != OK) { 329 me->mState = ERROR; 330 return res; 331 } 332 333 sp<ABuffer> out_buffer; 334 res = mCodec->getOutputBuffer(out_ix, &out_buffer); 335 if (res != OK) { 336 ALOGW("[%s] could not get output buffer #%zu", 337 mComponentName.c_str(), out_ix); 338 me->mState = ERROR; 339 return UNKNOWN_ERROR; 340 } 341 if (out_flags & MediaCodec::BUFFER_FLAG_EOS) { 342 me->mGotOutputEOS = true; 343 // return EOS immediately if last buffer is empty 344 if (out_size == 0) { 345 mCodec->releaseOutputBuffer(out_ix); 346 return ERROR_END_OF_STREAM; 347 } 348 } 349 350 if (mUsingSurface && out_size > 0) { 351 *buffer = new MediaBuffer(0); 352 mCodec->renderOutputBufferAndRelease(out_ix); 353 } else { 354 *buffer = new MediaBuffer(out_size); 355 CHECK_LE(out_buffer->size(), (*buffer)->size()); 356 memcpy((*buffer)->data(), out_buffer->data(), out_buffer->size()); 357 (*buffer)->meta_data()->setInt64(kKeyTime, out_pts); 358 mCodec->releaseOutputBuffer(out_ix); 359 } 360 return OK; 361 } 362 363 return TIMED_OUT; 364 } 365