NuPlayerDecoder.cpp revision 37ff0e6639e90ca49d4f0386a76c09437b459efd
1/*
2 * Copyright 2014 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 "NuPlayerDecoder"
19#include <utils/Log.h>
20#include <inttypes.h>
21
22#include <algorithm>
23
24#include "NuPlayerCCDecoder.h"
25#include "NuPlayerDecoder.h"
26#include "NuPlayerDrm.h"
27#include "NuPlayerRenderer.h"
28#include "NuPlayerSource.h"
29
30#include <cutils/properties.h>
31#include <media/ICrypto.h>
32#include <media/MediaCodecBuffer.h>
33#include <media/stagefright/foundation/ABuffer.h>
34#include <media/stagefright/foundation/ADebug.h>
35#include <media/stagefright/foundation/AMessage.h>
36#include <media/stagefright/MediaBuffer.h>
37#include <media/stagefright/MediaCodec.h>
38#include <media/stagefright/MediaDefs.h>
39#include <media/stagefright/MediaErrors.h>
40#include <media/stagefright/SurfaceUtils.h>
41#include <gui/Surface.h>
42
43#include "avc_utils.h"
44#include "ATSParser.h"
45
46namespace android {
47
48static float kDisplayRefreshingRate = 60.f; // TODO: get this from the display
49
50// The default total video frame rate of a stream when that info is not available from
51// the source.
52static float kDefaultVideoFrameRateTotal = 30.f;
53
54static inline bool getAudioDeepBufferSetting() {
55    return property_get_bool("media.stagefright.audio.deep", false /* default_value */);
56}
57
58NuPlayer::Decoder::Decoder(
59        const sp<AMessage> &notify,
60        const sp<Source> &source,
61        pid_t pid,
62        uid_t uid,
63        const sp<Renderer> &renderer,
64        const sp<Surface> &surface,
65        const sp<CCDecoder> &ccDecoder)
66    : DecoderBase(notify),
67      mSurface(surface),
68      mSource(source),
69      mRenderer(renderer),
70      mCCDecoder(ccDecoder),
71      mPid(pid),
72      mUid(uid),
73      mSkipRenderingUntilMediaTimeUs(-1ll),
74      mNumFramesTotal(0ll),
75      mNumInputFramesDropped(0ll),
76      mNumOutputFramesDropped(0ll),
77      mVideoWidth(0),
78      mVideoHeight(0),
79      mIsAudio(true),
80      mIsVideoAVC(false),
81      mIsSecure(false),
82      mFormatChangePending(false),
83      mTimeChangePending(false),
84      mFrameRateTotal(kDefaultVideoFrameRateTotal),
85      mPlaybackSpeed(1.0f),
86      mNumVideoTemporalLayerTotal(1), // decode all layers
87      mNumVideoTemporalLayerAllowed(1),
88      mCurrentMaxVideoTemporalLayerId(0),
89      mResumePending(false),
90      mComponentName("decoder") {
91    mCodecLooper = new ALooper;
92    mCodecLooper->setName("NPDecoder-CL");
93    mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
94    mVideoTemporalLayerAggregateFps[0] = mFrameRateTotal;
95}
96
97NuPlayer::Decoder::~Decoder() {
98    // Need to stop looper first since mCodec could be accessed on the mDecoderLooper.
99    stopLooper();
100    if (mCodec != NULL) {
101        mCodec->release();
102    }
103    releaseAndResetMediaBuffers();
104}
105
106sp<AMessage> NuPlayer::Decoder::getStats() const {
107    mStats->setInt64("frames-total", mNumFramesTotal);
108    mStats->setInt64("frames-dropped-input", mNumInputFramesDropped);
109    mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped);
110    return mStats;
111}
112
113status_t NuPlayer::Decoder::setVideoSurface(const sp<Surface> &surface) {
114    if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) {
115        return BAD_VALUE;
116    }
117
118    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
119
120    msg->setObject("surface", surface);
121    sp<AMessage> response;
122    status_t err = msg->postAndAwaitResponse(&response);
123    if (err == OK && response != NULL) {
124        CHECK(response->findInt32("err", &err));
125    }
126    return err;
127}
128
129void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
130    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
131
132    switch (msg->what()) {
133        case kWhatCodecNotify:
134        {
135            int32_t cbID;
136            CHECK(msg->findInt32("callbackID", &cbID));
137
138            ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d",
139                    mIsAudio ? "audio" : "video", cbID, mPaused);
140
141            if (mPaused) {
142                break;
143            }
144
145            switch (cbID) {
146                case MediaCodec::CB_INPUT_AVAILABLE:
147                {
148                    int32_t index;
149                    CHECK(msg->findInt32("index", &index));
150
151                    handleAnInputBuffer(index);
152                    break;
153                }
154
155                case MediaCodec::CB_OUTPUT_AVAILABLE:
156                {
157                    int32_t index;
158                    size_t offset;
159                    size_t size;
160                    int64_t timeUs;
161                    int32_t flags;
162
163                    CHECK(msg->findInt32("index", &index));
164                    CHECK(msg->findSize("offset", &offset));
165                    CHECK(msg->findSize("size", &size));
166                    CHECK(msg->findInt64("timeUs", &timeUs));
167                    CHECK(msg->findInt32("flags", &flags));
168
169                    handleAnOutputBuffer(index, offset, size, timeUs, flags);
170                    break;
171                }
172
173                case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
174                {
175                    sp<AMessage> format;
176                    CHECK(msg->findMessage("format", &format));
177
178                    handleOutputFormatChange(format);
179                    break;
180                }
181
182                case MediaCodec::CB_ERROR:
183                {
184                    status_t err;
185                    CHECK(msg->findInt32("err", &err));
186                    ALOGE("Decoder (%s) reported error : 0x%x",
187                            mIsAudio ? "audio" : "video", err);
188
189                    handleError(err);
190                    break;
191                }
192
193                default:
194                {
195                    TRESPASS();
196                    break;
197                }
198            }
199
200            break;
201        }
202
203        case kWhatRenderBuffer:
204        {
205            if (!isStaleReply(msg)) {
206                onRenderBuffer(msg);
207            }
208            break;
209        }
210
211        case kWhatAudioOutputFormatChanged:
212        {
213            if (!isStaleReply(msg)) {
214                status_t err;
215                if (msg->findInt32("err", &err) && err != OK) {
216                    ALOGE("Renderer reported 0x%x when changing audio output format", err);
217                    handleError(err);
218                }
219            }
220            break;
221        }
222
223        case kWhatSetVideoSurface:
224        {
225            sp<AReplyToken> replyID;
226            CHECK(msg->senderAwaitsResponse(&replyID));
227
228            sp<RefBase> obj;
229            CHECK(msg->findObject("surface", &obj));
230            sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null
231            int32_t err = INVALID_OPERATION;
232            // NOTE: in practice mSurface is always non-null, but checking here for completeness
233            if (mCodec != NULL && mSurface != NULL) {
234                // TODO: once AwesomePlayer is removed, remove this automatic connecting
235                // to the surface by MediaPlayerService.
236                //
237                // at this point MediaPlayerService::client has already connected to the
238                // surface, which MediaCodec does not expect
239                err = nativeWindowDisconnect(surface.get(), "kWhatSetVideoSurface(surface)");
240                if (err == OK) {
241                    err = mCodec->setSurface(surface);
242                    ALOGI_IF(err, "codec setSurface returned: %d", err);
243                    if (err == OK) {
244                        // reconnect to the old surface as MPS::Client will expect to
245                        // be able to disconnect from it.
246                        (void)nativeWindowConnect(mSurface.get(), "kWhatSetVideoSurface(mSurface)");
247                        mSurface = surface;
248                    }
249                }
250                if (err != OK) {
251                    // reconnect to the new surface on error as MPS::Client will expect to
252                    // be able to disconnect from it.
253                    (void)nativeWindowConnect(surface.get(), "kWhatSetVideoSurface(err)");
254                }
255            }
256
257            sp<AMessage> response = new AMessage;
258            response->setInt32("err", err);
259            response->postReply(replyID);
260            break;
261        }
262
263        case kWhatDrmReleaseCrypto:
264        {
265            ALOGV("kWhatDrmReleaseCrypto");
266            onReleaseCrypto(msg);
267            break;
268        }
269
270        default:
271            DecoderBase::onMessageReceived(msg);
272            break;
273    }
274}
275
276void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
277    CHECK(mCodec == NULL);
278
279    mFormatChangePending = false;
280    mTimeChangePending = false;
281
282    ++mBufferGeneration;
283
284    AString mime;
285    CHECK(format->findString("mime", &mime));
286
287    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
288    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
289
290    mComponentName = mime;
291    mComponentName.append(" decoder");
292    ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());
293
294    mCodec = MediaCodec::CreateByType(
295            mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid, mUid);
296    int32_t secure = 0;
297    if (format->findInt32("secure", &secure) && secure != 0) {
298        if (mCodec != NULL) {
299            mCodec->getName(&mComponentName);
300            mComponentName.append(".secure");
301            mCodec->release();
302            ALOGI("[%s] creating", mComponentName.c_str());
303            mCodec = MediaCodec::CreateByComponentName(
304                    mCodecLooper, mComponentName.c_str(), NULL /* err */, mPid, mUid);
305        }
306    }
307    if (mCodec == NULL) {
308        ALOGE("Failed to create %s%s decoder",
309                (secure ? "secure " : ""), mime.c_str());
310        handleError(UNKNOWN_ERROR);
311        return;
312    }
313    mIsSecure = secure;
314
315    mCodec->getName(&mComponentName);
316
317    status_t err;
318    if (mSurface != NULL) {
319        // disconnect from surface as MediaCodec will reconnect
320        err = nativeWindowDisconnect(mSurface.get(), "onConfigure");
321        // We treat this as a warning, as this is a preparatory step.
322        // Codec will try to connect to the surface, which is where
323        // any error signaling will occur.
324        ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
325    }
326
327    // Modular DRM
328    void *pCrypto;
329    if (!format->findPointer("crypto", &pCrypto)) {
330        pCrypto = NULL;
331    }
332    sp<ICrypto> crypto = (ICrypto*)pCrypto;
333    ALOGV("onConfigure mCrypto: %p (%d)  mIsSecure: %d",
334            crypto.get(), (crypto != NULL ? crypto->getStrongCount() : 0), mIsSecure);
335
336    err = mCodec->configure(
337            format, mSurface, crypto, 0 /* flags */);
338
339    if (err != OK) {
340        ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
341        mCodec->release();
342        mCodec.clear();
343        handleError(err);
344        return;
345    }
346    rememberCodecSpecificData(format);
347
348    // the following should work in configured state
349    CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat));
350    CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat));
351
352    mStats->setString("mime", mime.c_str());
353    mStats->setString("component-name", mComponentName.c_str());
354
355    if (!mIsAudio) {
356        int32_t width, height;
357        if (mOutputFormat->findInt32("width", &width)
358                && mOutputFormat->findInt32("height", &height)) {
359            mStats->setInt32("width", width);
360            mStats->setInt32("height", height);
361        }
362    }
363
364    sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
365    mCodec->setCallback(reply);
366
367    err = mCodec->start();
368    if (err != OK) {
369        ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
370        mCodec->release();
371        mCodec.clear();
372        handleError(err);
373        return;
374    }
375
376    releaseAndResetMediaBuffers();
377
378    mPaused = false;
379    mResumePending = false;
380}
381
382void NuPlayer::Decoder::onSetParameters(const sp<AMessage> &params) {
383    bool needAdjustLayers = false;
384    float frameRateTotal;
385    if (params->findFloat("frame-rate-total", &frameRateTotal)
386            && mFrameRateTotal != frameRateTotal) {
387        needAdjustLayers = true;
388        mFrameRateTotal = frameRateTotal;
389    }
390
391    int32_t numVideoTemporalLayerTotal;
392    if (params->findInt32("temporal-layer-count", &numVideoTemporalLayerTotal)
393            && numVideoTemporalLayerTotal >= 0
394            && numVideoTemporalLayerTotal <= kMaxNumVideoTemporalLayers
395            && mNumVideoTemporalLayerTotal != numVideoTemporalLayerTotal) {
396        needAdjustLayers = true;
397        mNumVideoTemporalLayerTotal = std::max(numVideoTemporalLayerTotal, 1);
398    }
399
400    if (needAdjustLayers && mNumVideoTemporalLayerTotal > 1) {
401        // TODO: For now, layer fps is calculated for some specific architectures.
402        // But it really should be extracted from the stream.
403        mVideoTemporalLayerAggregateFps[0] =
404            mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - 1));
405        for (int32_t i = 1; i < mNumVideoTemporalLayerTotal; ++i) {
406            mVideoTemporalLayerAggregateFps[i] =
407                mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - i))
408                + mVideoTemporalLayerAggregateFps[i - 1];
409        }
410    }
411
412    float playbackSpeed;
413    if (params->findFloat("playback-speed", &playbackSpeed)
414            && mPlaybackSpeed != playbackSpeed) {
415        needAdjustLayers = true;
416        mPlaybackSpeed = playbackSpeed;
417    }
418
419    if (needAdjustLayers) {
420        float decodeFrameRate = mFrameRateTotal;
421        // enable temporal layering optimization only if we know the layering depth
422        if (mNumVideoTemporalLayerTotal > 1) {
423            int32_t layerId;
424            for (layerId = 0; layerId < mNumVideoTemporalLayerTotal - 1; ++layerId) {
425                if (mVideoTemporalLayerAggregateFps[layerId] * mPlaybackSpeed
426                        >= kDisplayRefreshingRate * 0.9) {
427                    break;
428                }
429            }
430            mNumVideoTemporalLayerAllowed = layerId + 1;
431            decodeFrameRate = mVideoTemporalLayerAggregateFps[layerId];
432        }
433        ALOGV("onSetParameters: allowed layers=%d, decodeFps=%g",
434                mNumVideoTemporalLayerAllowed, decodeFrameRate);
435
436        if (mCodec == NULL) {
437            ALOGW("onSetParameters called before codec is created.");
438            return;
439        }
440
441        sp<AMessage> codecParams = new AMessage();
442        codecParams->setFloat("operating-rate", decodeFrameRate * mPlaybackSpeed);
443        mCodec->setParameters(codecParams);
444    }
445}
446
447void NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
448    mRenderer = renderer;
449}
450
451void NuPlayer::Decoder::onResume(bool notifyComplete) {
452    mPaused = false;
453
454    if (notifyComplete) {
455        mResumePending = true;
456    }
457    mCodec->start();
458}
459
460void NuPlayer::Decoder::doFlush(bool notifyComplete) {
461    if (mCCDecoder != NULL) {
462        mCCDecoder->flush();
463    }
464
465    if (mRenderer != NULL) {
466        mRenderer->flush(mIsAudio, notifyComplete);
467        mRenderer->signalTimeDiscontinuity();
468    }
469
470    status_t err = OK;
471    if (mCodec != NULL) {
472        err = mCodec->flush();
473        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator
474        ++mBufferGeneration;
475    }
476
477    if (err != OK) {
478        ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err);
479        handleError(err);
480        // finish with posting kWhatFlushCompleted.
481        // we attempt to release the buffers even if flush fails.
482    }
483    releaseAndResetMediaBuffers();
484    mPaused = true;
485}
486
487
488void NuPlayer::Decoder::onFlush() {
489    doFlush(true);
490
491    if (isDiscontinuityPending()) {
492        // This could happen if the client starts seeking/shutdown
493        // after we queued an EOS for discontinuities.
494        // We can consider discontinuity handled.
495        finishHandleDiscontinuity(false /* flushOnTimeChange */);
496    }
497
498    sp<AMessage> notify = mNotify->dup();
499    notify->setInt32("what", kWhatFlushCompleted);
500    notify->post();
501}
502
503void NuPlayer::Decoder::onShutdown(bool notifyComplete) {
504    status_t err = OK;
505
506    // if there is a pending resume request, notify complete now
507    notifyResumeCompleteIfNecessary();
508
509    if (mCodec != NULL) {
510        err = mCodec->release();
511        mCodec = NULL;
512        ++mBufferGeneration;
513
514        if (mSurface != NULL) {
515            // reconnect to surface as MediaCodec disconnected from it
516            status_t error = nativeWindowConnect(mSurface.get(), "onShutdown");
517            ALOGW_IF(error != NO_ERROR,
518                    "[%s] failed to connect to native window, error=%d",
519                    mComponentName.c_str(), error);
520        }
521        mComponentName = "decoder";
522    }
523
524    releaseAndResetMediaBuffers();
525
526    if (err != OK) {
527        ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err);
528        handleError(err);
529        // finish with posting kWhatShutdownCompleted.
530    }
531
532    if (notifyComplete) {
533        sp<AMessage> notify = mNotify->dup();
534        notify->setInt32("what", kWhatShutdownCompleted);
535        notify->post();
536        mPaused = true;
537    }
538}
539
540/*
541 * returns true if we should request more data
542 */
543bool NuPlayer::Decoder::doRequestBuffers() {
544    if (isDiscontinuityPending()) {
545        return false;
546    }
547    status_t err = OK;
548    while (err == OK && !mDequeuedInputBuffers.empty()) {
549        size_t bufferIx = *mDequeuedInputBuffers.begin();
550        sp<AMessage> msg = new AMessage();
551        msg->setSize("buffer-ix", bufferIx);
552        err = fetchInputData(msg);
553        if (err != OK && err != ERROR_END_OF_STREAM) {
554            // if EOS, need to queue EOS buffer
555            break;
556        }
557        mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin());
558
559        if (!mPendingInputMessages.empty()
560                || !onInputBufferFetched(msg)) {
561            mPendingInputMessages.push_back(msg);
562        }
563    }
564
565    return err == -EWOULDBLOCK
566            && mSource->feedMoreTSData() == OK;
567}
568
569void NuPlayer::Decoder::handleError(int32_t err)
570{
571    // We cannot immediately release the codec due to buffers still outstanding
572    // in the renderer.  We signal to the player the error so it can shutdown/release the
573    // decoder after flushing and increment the generation to discard unnecessary messages.
574
575    ++mBufferGeneration;
576
577    sp<AMessage> notify = mNotify->dup();
578    notify->setInt32("what", kWhatError);
579    notify->setInt32("err", err);
580    notify->post();
581}
582
583status_t NuPlayer::Decoder::releaseCrypto()
584{
585    ALOGV("releaseCrypto");
586
587    sp<AMessage> msg = new AMessage(kWhatDrmReleaseCrypto, this);
588
589    sp<AMessage> response;
590    status_t status = msg->postAndAwaitResponse(&response);
591    if (status == OK && response != NULL) {
592        CHECK(response->findInt32("status", &status));
593        ALOGV("releaseCrypto ret: %d ", status);
594    } else {
595        ALOGE("releaseCrypto err: %d", status);
596    }
597
598    return status;
599}
600
601void NuPlayer::Decoder::onReleaseCrypto(const sp<AMessage>& msg)
602{
603    status_t status = INVALID_OPERATION;
604    if (mCodec != NULL) {
605        status = mCodec->releaseCrypto();
606    } else {
607        // returning OK if the codec has been already released
608        status = OK;
609        ALOGE("onReleaseCrypto No mCodec. err: %d", status);
610    }
611
612    sp<AMessage> response = new AMessage;
613    response->setInt32("status", status);
614
615    sp<AReplyToken> replyID;
616    CHECK(msg->senderAwaitsResponse(&replyID));
617    response->postReply(replyID);
618}
619
620bool NuPlayer::Decoder::handleAnInputBuffer(size_t index) {
621    if (isDiscontinuityPending()) {
622        return false;
623    }
624
625    sp<MediaCodecBuffer> buffer;
626    mCodec->getInputBuffer(index, &buffer);
627
628    if (buffer == NULL) {
629        handleError(UNKNOWN_ERROR);
630        return false;
631    }
632
633    if (index >= mInputBuffers.size()) {
634        for (size_t i = mInputBuffers.size(); i <= index; ++i) {
635            mInputBuffers.add();
636            mMediaBuffers.add();
637            mInputBufferIsDequeued.add();
638            mMediaBuffers.editItemAt(i) = NULL;
639            mInputBufferIsDequeued.editItemAt(i) = false;
640        }
641    }
642    mInputBuffers.editItemAt(index) = buffer;
643
644    //CHECK_LT(bufferIx, mInputBuffers.size());
645
646    if (mMediaBuffers[index] != NULL) {
647        mMediaBuffers[index]->release();
648        mMediaBuffers.editItemAt(index) = NULL;
649    }
650    mInputBufferIsDequeued.editItemAt(index) = true;
651
652    if (!mCSDsToSubmit.isEmpty()) {
653        sp<AMessage> msg = new AMessage();
654        msg->setSize("buffer-ix", index);
655
656        sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
657        ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
658        msg->setBuffer("buffer", buffer);
659        mCSDsToSubmit.removeAt(0);
660        if (!onInputBufferFetched(msg)) {
661            handleError(UNKNOWN_ERROR);
662            return false;
663        }
664        return true;
665    }
666
667    while (!mPendingInputMessages.empty()) {
668        sp<AMessage> msg = *mPendingInputMessages.begin();
669        if (!onInputBufferFetched(msg)) {
670            break;
671        }
672        mPendingInputMessages.erase(mPendingInputMessages.begin());
673    }
674
675    if (!mInputBufferIsDequeued.editItemAt(index)) {
676        return true;
677    }
678
679    mDequeuedInputBuffers.push_back(index);
680
681    onRequestInputBuffers();
682    return true;
683}
684
685bool NuPlayer::Decoder::handleAnOutputBuffer(
686        size_t index,
687        size_t offset,
688        size_t size,
689        int64_t timeUs,
690        int32_t flags) {
691//    CHECK_LT(bufferIx, mOutputBuffers.size());
692    sp<MediaCodecBuffer> buffer;
693    mCodec->getOutputBuffer(index, &buffer);
694
695    if (buffer == NULL) {
696        handleError(UNKNOWN_ERROR);
697        return false;
698    }
699
700    if (index >= mOutputBuffers.size()) {
701        for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
702            mOutputBuffers.add();
703        }
704    }
705
706    mOutputBuffers.editItemAt(index) = buffer;
707
708    buffer->setRange(offset, size);
709    buffer->meta()->clear();
710    buffer->meta()->setInt64("timeUs", timeUs);
711
712    bool eos = flags & MediaCodec::BUFFER_FLAG_EOS;
713    // we do not expect CODECCONFIG or SYNCFRAME for decoder
714
715    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
716    reply->setSize("buffer-ix", index);
717    reply->setInt32("generation", mBufferGeneration);
718
719    if (eos) {
720        ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
721
722        buffer->meta()->setInt32("eos", true);
723        reply->setInt32("eos", true);
724    } else if (mSkipRenderingUntilMediaTimeUs >= 0) {
725        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
726            ALOGV("[%s] dropping buffer at time %lld as requested.",
727                     mComponentName.c_str(), (long long)timeUs);
728
729            reply->post();
730            return true;
731        }
732
733        mSkipRenderingUntilMediaTimeUs = -1;
734    }
735
736    mNumFramesTotal += !mIsAudio;
737
738    // wait until 1st frame comes out to signal resume complete
739    notifyResumeCompleteIfNecessary();
740
741    if (mRenderer != NULL) {
742        // send the buffer to renderer.
743        mRenderer->queueBuffer(mIsAudio, buffer, reply);
744        if (eos && !isDiscontinuityPending()) {
745            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
746        }
747    }
748
749    return true;
750}
751
752void NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) {
753    if (!mIsAudio) {
754        int32_t width, height;
755        if (format->findInt32("width", &width)
756                && format->findInt32("height", &height)) {
757            mStats->setInt32("width", width);
758            mStats->setInt32("height", height);
759        }
760        sp<AMessage> notify = mNotify->dup();
761        notify->setInt32("what", kWhatVideoSizeChanged);
762        notify->setMessage("format", format);
763        notify->post();
764    } else if (mRenderer != NULL) {
765        uint32_t flags;
766        int64_t durationUs;
767        bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
768        if (getAudioDeepBufferSetting() // override regardless of source duration
769                || (mSource->getDuration(&durationUs) == OK
770                        && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) {
771            flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
772        } else {
773            flags = AUDIO_OUTPUT_FLAG_NONE;
774        }
775
776        sp<AMessage> reply = new AMessage(kWhatAudioOutputFormatChanged, this);
777        reply->setInt32("generation", mBufferGeneration);
778        mRenderer->changeAudioFormat(
779                format, false /* offloadOnly */, hasVideo,
780                flags, mSource->isStreaming(), reply);
781    }
782}
783
784void NuPlayer::Decoder::releaseAndResetMediaBuffers() {
785    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
786        if (mMediaBuffers[i] != NULL) {
787            mMediaBuffers[i]->release();
788            mMediaBuffers.editItemAt(i) = NULL;
789        }
790    }
791    mMediaBuffers.resize(mInputBuffers.size());
792    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
793        mMediaBuffers.editItemAt(i) = NULL;
794    }
795    mInputBufferIsDequeued.clear();
796    mInputBufferIsDequeued.resize(mInputBuffers.size());
797    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
798        mInputBufferIsDequeued.editItemAt(i) = false;
799    }
800
801    mPendingInputMessages.clear();
802    mDequeuedInputBuffers.clear();
803    mSkipRenderingUntilMediaTimeUs = -1;
804}
805
806void NuPlayer::Decoder::requestCodecNotification() {
807    if (mCodec != NULL) {
808        sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
809        reply->setInt32("generation", mBufferGeneration);
810        mCodec->requestActivityNotification(reply);
811    }
812}
813
814bool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) {
815    int32_t generation;
816    CHECK(msg->findInt32("generation", &generation));
817    return generation != mBufferGeneration;
818}
819
820status_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) {
821    sp<ABuffer> accessUnit;
822    bool dropAccessUnit = true;
823    do {
824        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit);
825
826        if (err == -EWOULDBLOCK) {
827            return err;
828        } else if (err != OK) {
829            if (err == INFO_DISCONTINUITY) {
830                int32_t type;
831                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
832
833                bool formatChange =
834                    (mIsAudio &&
835                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
836                    || (!mIsAudio &&
837                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
838
839                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
840
841                ALOGI("%s discontinuity (format=%d, time=%d)",
842                        mIsAudio ? "audio" : "video", formatChange, timeChange);
843
844                bool seamlessFormatChange = false;
845                sp<AMessage> newFormat = mSource->getFormat(mIsAudio);
846                if (formatChange) {
847                    seamlessFormatChange =
848                        supportsSeamlessFormatChange(newFormat);
849                    // treat seamless format change separately
850                    formatChange = !seamlessFormatChange;
851                }
852
853                // For format or time change, return EOS to queue EOS input,
854                // then wait for EOS on output.
855                if (formatChange /* not seamless */) {
856                    mFormatChangePending = true;
857                    err = ERROR_END_OF_STREAM;
858                } else if (timeChange) {
859                    rememberCodecSpecificData(newFormat);
860                    mTimeChangePending = true;
861                    err = ERROR_END_OF_STREAM;
862                } else if (seamlessFormatChange) {
863                    // reuse existing decoder and don't flush
864                    rememberCodecSpecificData(newFormat);
865                    continue;
866                } else {
867                    // This stream is unaffected by the discontinuity
868                    return -EWOULDBLOCK;
869                }
870            }
871
872            // reply should only be returned without a buffer set
873            // when there is an error (including EOS)
874            CHECK(err != OK);
875
876            reply->setInt32("err", err);
877            return ERROR_END_OF_STREAM;
878        }
879
880        dropAccessUnit = false;
881        if (!mIsAudio && !mIsSecure) {
882            int32_t layerId = 0;
883            bool haveLayerId = accessUnit->meta()->findInt32("temporal-layer-id", &layerId);
884            if (mRenderer->getVideoLateByUs() > 100000ll
885                    && mIsVideoAVC
886                    && !IsAVCReferenceFrame(accessUnit)) {
887                dropAccessUnit = true;
888            } else if (haveLayerId && mNumVideoTemporalLayerTotal > 1) {
889                // Add only one layer each time.
890                if (layerId > mCurrentMaxVideoTemporalLayerId + 1
891                        || layerId >= mNumVideoTemporalLayerAllowed) {
892                    dropAccessUnit = true;
893                    ALOGV("dropping layer(%d), speed=%g, allowed layer count=%d, max layerId=%d",
894                            layerId, mPlaybackSpeed, mNumVideoTemporalLayerAllowed,
895                            mCurrentMaxVideoTemporalLayerId);
896                } else if (layerId > mCurrentMaxVideoTemporalLayerId) {
897                    mCurrentMaxVideoTemporalLayerId = layerId;
898                } else if (layerId == 0 && mNumVideoTemporalLayerTotal > 1 && IsIDR(accessUnit)) {
899                    mCurrentMaxVideoTemporalLayerId = mNumVideoTemporalLayerTotal - 1;
900                }
901            }
902            if (dropAccessUnit) {
903                if (layerId <= mCurrentMaxVideoTemporalLayerId && layerId > 0) {
904                    mCurrentMaxVideoTemporalLayerId = layerId - 1;
905                }
906                ++mNumInputFramesDropped;
907            }
908        }
909    } while (dropAccessUnit);
910
911    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video");
912#if 0
913    int64_t mediaTimeUs;
914    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
915    ALOGV("[%s] feeding input buffer at media time %.3f",
916         mIsAudio ? "audio" : "video",
917         mediaTimeUs / 1E6);
918#endif
919
920    if (mCCDecoder != NULL) {
921        mCCDecoder->decode(accessUnit);
922    }
923
924    reply->setBuffer("buffer", accessUnit);
925
926    return OK;
927}
928
929bool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
930    size_t bufferIx;
931    CHECK(msg->findSize("buffer-ix", &bufferIx));
932    CHECK_LT(bufferIx, mInputBuffers.size());
933    sp<MediaCodecBuffer> codecBuffer = mInputBuffers[bufferIx];
934
935    sp<ABuffer> buffer;
936    bool hasBuffer = msg->findBuffer("buffer", &buffer);
937    bool needsCopy = true;
938
939    if (buffer == NULL /* includes !hasBuffer */) {
940        int32_t streamErr = ERROR_END_OF_STREAM;
941        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
942
943        CHECK(streamErr != OK);
944
945        // attempt to queue EOS
946        status_t err = mCodec->queueInputBuffer(
947                bufferIx,
948                0,
949                0,
950                0,
951                MediaCodec::BUFFER_FLAG_EOS);
952        if (err == OK) {
953            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
954        } else if (streamErr == ERROR_END_OF_STREAM) {
955            streamErr = err;
956            // err will not be ERROR_END_OF_STREAM
957        }
958
959        if (streamErr != ERROR_END_OF_STREAM) {
960            ALOGE("Stream error for %s (err=%d), EOS %s queued",
961                    mComponentName.c_str(),
962                    streamErr,
963                    err == OK ? "successfully" : "unsuccessfully");
964            handleError(streamErr);
965        }
966    } else {
967        sp<AMessage> extra;
968        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
969            int64_t resumeAtMediaTimeUs;
970            if (extra->findInt64(
971                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
972                ALOGI("[%s] suppressing rendering until %lld us",
973                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
974                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
975            }
976        }
977
978        int64_t timeUs = 0;
979        uint32_t flags = 0;
980        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
981
982        int32_t eos, csd;
983        // we do not expect SYNCFRAME for decoder
984        if (buffer->meta()->findInt32("eos", &eos) && eos) {
985            flags |= MediaCodec::BUFFER_FLAG_EOS;
986        } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
987            flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
988        }
989
990        // Modular DRM
991        MediaBuffer *mediaBuf = NULL;
992        NuPlayerDrm::CryptoInfo *cryptInfo = NULL;
993
994        // copy into codec buffer
995        if (needsCopy) {
996            if (buffer->size() > codecBuffer->capacity()) {
997                handleError(ERROR_BUFFER_TOO_SMALL);
998                mDequeuedInputBuffers.push_back(bufferIx);
999                return false;
1000            }
1001
1002            if (buffer->data() != NULL) {
1003                codecBuffer->setRange(0, buffer->size());
1004                memcpy(codecBuffer->data(), buffer->data(), buffer->size());
1005            } else { // No buffer->data()
1006                //Modular DRM
1007                mediaBuf = (MediaBuffer*)buffer->getMediaBufferBase();
1008                if (mediaBuf != NULL) {
1009                    codecBuffer->setRange(0, mediaBuf->size());
1010                    memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size());
1011
1012                    sp<MetaData> meta_data = mediaBuf->meta_data();
1013                    cryptInfo = NuPlayerDrm::getSampleCryptoInfo(meta_data);
1014
1015                    // since getMediaBuffer() has incremented the refCount
1016                    mediaBuf->release();
1017                } else { // No mediaBuf
1018                    ALOGE("onInputBufferFetched: buffer->data()/mediaBuf are NULL for %p",
1019                            buffer.get());
1020                    handleError(UNKNOWN_ERROR);
1021                    return false;
1022                }
1023            } // buffer->data()
1024        } // needsCopy
1025
1026        status_t err;
1027        AString errorDetailMsg;
1028        if (cryptInfo != NULL) {
1029            err = mCodec->queueSecureInputBuffer(
1030                    bufferIx,
1031                    codecBuffer->offset(),
1032                    cryptInfo->subSamples,
1033                    cryptInfo->numSubSamples,
1034                    cryptInfo->key,
1035                    cryptInfo->iv,
1036                    cryptInfo->mode,
1037                    cryptInfo->pattern,
1038                    timeUs,
1039                    flags,
1040                    &errorDetailMsg);
1041            // synchronous call so done with cryptInfo here
1042            free(cryptInfo);
1043        } else {
1044            err = mCodec->queueInputBuffer(
1045                    bufferIx,
1046                    codecBuffer->offset(),
1047                    codecBuffer->size(),
1048                    timeUs,
1049                    flags,
1050                    &errorDetailMsg);
1051        } // no cryptInfo
1052
1053        if (err != OK) {
1054            ALOGE("onInputBufferFetched: queue%sInputBuffer failed for %s (err=%d, %s)",
1055                    (cryptInfo != NULL ? "Secure" : ""),
1056                    mComponentName.c_str(), err, errorDetailMsg.c_str());
1057            handleError(err);
1058        } else {
1059            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
1060        }
1061
1062    }   // buffer != NULL
1063    return true;
1064}
1065
1066void NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
1067    status_t err;
1068    int32_t render;
1069    size_t bufferIx;
1070    int32_t eos;
1071    CHECK(msg->findSize("buffer-ix", &bufferIx));
1072
1073    if (!mIsAudio) {
1074        int64_t timeUs;
1075        sp<MediaCodecBuffer> buffer = mOutputBuffers[bufferIx];
1076        buffer->meta()->findInt64("timeUs", &timeUs);
1077
1078        if (mCCDecoder != NULL && mCCDecoder->isSelected()) {
1079            mCCDecoder->display(timeUs);
1080        }
1081    }
1082
1083    if (msg->findInt32("render", &render) && render) {
1084        int64_t timestampNs;
1085        CHECK(msg->findInt64("timestampNs", &timestampNs));
1086        err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs);
1087    } else {
1088        mNumOutputFramesDropped += !mIsAudio;
1089        err = mCodec->releaseOutputBuffer(bufferIx);
1090    }
1091    if (err != OK) {
1092        ALOGE("failed to release output buffer for %s (err=%d)",
1093                mComponentName.c_str(), err);
1094        handleError(err);
1095    }
1096    if (msg->findInt32("eos", &eos) && eos
1097            && isDiscontinuityPending()) {
1098        finishHandleDiscontinuity(true /* flushOnTimeChange */);
1099    }
1100}
1101
1102bool NuPlayer::Decoder::isDiscontinuityPending() const {
1103    return mFormatChangePending || mTimeChangePending;
1104}
1105
1106void NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) {
1107    ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d",
1108            mFormatChangePending, mTimeChangePending, flushOnTimeChange);
1109
1110    // If we have format change, pause and wait to be killed;
1111    // If we have time change only, flush and restart fetching.
1112
1113    if (mFormatChangePending) {
1114        mPaused = true;
1115    } else if (mTimeChangePending) {
1116        if (flushOnTimeChange) {
1117            doFlush(false /* notifyComplete */);
1118            signalResume(false /* notifyComplete */);
1119        }
1120    }
1121
1122    // Notify NuPlayer to either shutdown decoder, or rescan sources
1123    sp<AMessage> msg = mNotify->dup();
1124    msg->setInt32("what", kWhatInputDiscontinuity);
1125    msg->setInt32("formatChange", mFormatChangePending);
1126    msg->post();
1127
1128    mFormatChangePending = false;
1129    mTimeChangePending = false;
1130}
1131
1132bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(
1133        const sp<AMessage> &targetFormat) const {
1134    if (targetFormat == NULL) {
1135        return true;
1136    }
1137
1138    AString mime;
1139    if (!targetFormat->findString("mime", &mime)) {
1140        return false;
1141    }
1142
1143    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
1144        // field-by-field comparison
1145        const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
1146        for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
1147            int32_t oldVal, newVal;
1148            if (!mInputFormat->findInt32(keys[i], &oldVal) ||
1149                    !targetFormat->findInt32(keys[i], &newVal) ||
1150                    oldVal != newVal) {
1151                return false;
1152            }
1153        }
1154
1155        sp<ABuffer> oldBuf, newBuf;
1156        if (mInputFormat->findBuffer("csd-0", &oldBuf) &&
1157                targetFormat->findBuffer("csd-0", &newBuf)) {
1158            if (oldBuf->size() != newBuf->size()) {
1159                return false;
1160            }
1161            return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size());
1162        }
1163    }
1164    return false;
1165}
1166
1167bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
1168    if (mInputFormat == NULL) {
1169        return false;
1170    }
1171
1172    if (targetFormat == NULL) {
1173        return true;
1174    }
1175
1176    AString oldMime, newMime;
1177    if (!mInputFormat->findString("mime", &oldMime)
1178            || !targetFormat->findString("mime", &newMime)
1179            || !(oldMime == newMime)) {
1180        return false;
1181    }
1182
1183    bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
1184    bool seamless;
1185    if (audio) {
1186        seamless = supportsSeamlessAudioFormatChange(targetFormat);
1187    } else {
1188        int32_t isAdaptive;
1189        seamless = (mCodec != NULL &&
1190                mInputFormat->findInt32("adaptive-playback", &isAdaptive) &&
1191                isAdaptive);
1192    }
1193
1194    ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
1195    return seamless;
1196}
1197
1198void NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
1199    if (format == NULL) {
1200        return;
1201    }
1202    mCSDsForCurrentFormat.clear();
1203    for (int32_t i = 0; ; ++i) {
1204        AString tag = "csd-";
1205        tag.append(i);
1206        sp<ABuffer> buffer;
1207        if (!format->findBuffer(tag.c_str(), &buffer)) {
1208            break;
1209        }
1210        mCSDsForCurrentFormat.push(buffer);
1211    }
1212}
1213
1214void NuPlayer::Decoder::notifyResumeCompleteIfNecessary() {
1215    if (mResumePending) {
1216        mResumePending = false;
1217
1218        sp<AMessage> notify = mNotify->dup();
1219        notify->setInt32("what", kWhatResumeCompleted);
1220        notify->post();
1221    }
1222}
1223
1224}  // namespace android
1225
1226