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