Home | History | Annotate | Download | only in nuplayer
      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 "NuPlayerDecoder"
     19 #include <utils/Log.h>
     20 #include <inttypes.h>
     21 
     22 #include "NuPlayerDecoder.h"
     23 
     24 #include <media/ICrypto.h>
     25 #include <media/stagefright/foundation/ABitReader.h>
     26 #include <media/stagefright/foundation/ABuffer.h>
     27 #include <media/stagefright/foundation/ADebug.h>
     28 #include <media/stagefright/foundation/AMessage.h>
     29 #include <media/stagefright/MediaBuffer.h>
     30 #include <media/stagefright/MediaCodec.h>
     31 #include <media/stagefright/MediaDefs.h>
     32 #include <media/stagefright/MediaErrors.h>
     33 
     34 namespace android {
     35 
     36 NuPlayer::Decoder::Decoder(
     37         const sp<AMessage> &notify,
     38         const sp<NativeWindowWrapper> &nativeWindow)
     39     : mNotify(notify),
     40       mNativeWindow(nativeWindow),
     41       mBufferGeneration(0),
     42       mPaused(true),
     43       mComponentName("decoder") {
     44     // Every decoder has its own looper because MediaCodec operations
     45     // are blocking, but NuPlayer needs asynchronous operations.
     46     mDecoderLooper = new ALooper;
     47     mDecoderLooper->setName("NPDecoder");
     48     mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
     49 
     50     mCodecLooper = new ALooper;
     51     mCodecLooper->setName("NPDecoder-CL");
     52     mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
     53 }
     54 
     55 NuPlayer::Decoder::~Decoder() {
     56     mDecoderLooper->unregisterHandler(id());
     57     mDecoderLooper->stop();
     58 
     59     releaseAndResetMediaBuffers();
     60 }
     61 
     62 static
     63 status_t PostAndAwaitResponse(
     64         const sp<AMessage> &msg, sp<AMessage> *response) {
     65     status_t err = msg->postAndAwaitResponse(response);
     66 
     67     if (err != OK) {
     68         return err;
     69     }
     70 
     71     if (!(*response)->findInt32("err", &err)) {
     72         err = OK;
     73     }
     74 
     75     return err;
     76 }
     77 
     78 void NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
     79     mCSDsForCurrentFormat.clear();
     80     for (int32_t i = 0; ; ++i) {
     81         AString tag = "csd-";
     82         tag.append(i);
     83         sp<ABuffer> buffer;
     84         if (!format->findBuffer(tag.c_str(), &buffer)) {
     85             break;
     86         }
     87         mCSDsForCurrentFormat.push(buffer);
     88     }
     89 }
     90 
     91 void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
     92     CHECK(mCodec == NULL);
     93 
     94     ++mBufferGeneration;
     95 
     96     AString mime;
     97     CHECK(format->findString("mime", &mime));
     98 
     99     sp<Surface> surface = NULL;
    100     if (mNativeWindow != NULL) {
    101         surface = mNativeWindow->getSurfaceTextureClient();
    102     }
    103 
    104     mComponentName = mime;
    105     mComponentName.append(" decoder");
    106     ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), surface.get());
    107 
    108     mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */);
    109     int32_t secure = 0;
    110     if (format->findInt32("secure", &secure) && secure != 0) {
    111         if (mCodec != NULL) {
    112             mCodec->getName(&mComponentName);
    113             mComponentName.append(".secure");
    114             mCodec->release();
    115             ALOGI("[%s] creating", mComponentName.c_str());
    116             mCodec = MediaCodec::CreateByComponentName(
    117                     mCodecLooper, mComponentName.c_str());
    118         }
    119     }
    120     if (mCodec == NULL) {
    121         ALOGE("Failed to create %s%s decoder",
    122                 (secure ? "secure " : ""), mime.c_str());
    123         handleError(UNKNOWN_ERROR);
    124         return;
    125     }
    126 
    127     mCodec->getName(&mComponentName);
    128 
    129     status_t err;
    130     if (mNativeWindow != NULL) {
    131         // disconnect from surface as MediaCodec will reconnect
    132         err = native_window_api_disconnect(
    133                 surface.get(), NATIVE_WINDOW_API_MEDIA);
    134         // We treat this as a warning, as this is a preparatory step.
    135         // Codec will try to connect to the surface, which is where
    136         // any error signaling will occur.
    137         ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
    138     }
    139     err = mCodec->configure(
    140             format, surface, NULL /* crypto */, 0 /* flags */);
    141     if (err != OK) {
    142         ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
    143         mCodec->release();
    144         mCodec.clear();
    145         handleError(err);
    146         return;
    147     }
    148     rememberCodecSpecificData(format);
    149 
    150     // the following should work in configured state
    151     CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat));
    152     CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat));
    153 
    154     err = mCodec->start();
    155     if (err != OK) {
    156         ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
    157         mCodec->release();
    158         mCodec.clear();
    159         handleError(err);
    160         return;
    161     }
    162 
    163     // the following should work after start
    164     CHECK_EQ((status_t)OK, mCodec->getInputBuffers(&mInputBuffers));
    165     releaseAndResetMediaBuffers();
    166     CHECK_EQ((status_t)OK, mCodec->getOutputBuffers(&mOutputBuffers));
    167     ALOGV("[%s] got %zu input and %zu output buffers",
    168             mComponentName.c_str(),
    169             mInputBuffers.size(),
    170             mOutputBuffers.size());
    171 
    172     requestCodecNotification();
    173     mPaused = false;
    174 }
    175 
    176 void NuPlayer::Decoder::releaseAndResetMediaBuffers() {
    177     for (size_t i = 0; i < mMediaBuffers.size(); i++) {
    178         if (mMediaBuffers[i] != NULL) {
    179             mMediaBuffers[i]->release();
    180             mMediaBuffers.editItemAt(i) = NULL;
    181         }
    182     }
    183     mMediaBuffers.resize(mInputBuffers.size());
    184     for (size_t i = 0; i < mMediaBuffers.size(); i++) {
    185         mMediaBuffers.editItemAt(i) = NULL;
    186     }
    187     mInputBufferIsDequeued.clear();
    188     mInputBufferIsDequeued.resize(mInputBuffers.size());
    189     for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
    190         mInputBufferIsDequeued.editItemAt(i) = false;
    191     }
    192 
    193     mPendingInputMessages.clear();
    194 }
    195 
    196 void NuPlayer::Decoder::requestCodecNotification() {
    197     if (mCodec != NULL) {
    198         sp<AMessage> reply = new AMessage(kWhatCodecNotify, id());
    199         reply->setInt32("generation", mBufferGeneration);
    200         mCodec->requestActivityNotification(reply);
    201     }
    202 }
    203 
    204 bool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) {
    205     int32_t generation;
    206     CHECK(msg->findInt32("generation", &generation));
    207     return generation != mBufferGeneration;
    208 }
    209 
    210 void NuPlayer::Decoder::init() {
    211     mDecoderLooper->registerHandler(this);
    212 }
    213 
    214 void NuPlayer::Decoder::configure(const sp<AMessage> &format) {
    215     sp<AMessage> msg = new AMessage(kWhatConfigure, id());
    216     msg->setMessage("format", format);
    217     msg->post();
    218 }
    219 
    220 void NuPlayer::Decoder::signalUpdateFormat(const sp<AMessage> &format) {
    221     sp<AMessage> msg = new AMessage(kWhatUpdateFormat, id());
    222     msg->setMessage("format", format);
    223     msg->post();
    224 }
    225 
    226 status_t NuPlayer::Decoder::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
    227     sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id());
    228     msg->setPointer("buffers", buffers);
    229 
    230     sp<AMessage> response;
    231     return PostAndAwaitResponse(msg, &response);
    232 }
    233 
    234 void NuPlayer::Decoder::handleError(int32_t err)
    235 {
    236     // We cannot immediately release the codec due to buffers still outstanding
    237     // in the renderer.  We signal to the player the error so it can shutdown/release the
    238     // decoder after flushing and increment the generation to discard unnecessary messages.
    239 
    240     ++mBufferGeneration;
    241 
    242     sp<AMessage> notify = mNotify->dup();
    243     notify->setInt32("what", kWhatError);
    244     notify->setInt32("err", err);
    245     notify->post();
    246 }
    247 
    248 bool NuPlayer::Decoder::handleAnInputBuffer() {
    249     size_t bufferIx = -1;
    250     status_t res = mCodec->dequeueInputBuffer(&bufferIx);
    251     ALOGV("[%s] dequeued input: %d",
    252             mComponentName.c_str(), res == OK ? (int)bufferIx : res);
    253     if (res != OK) {
    254         if (res != -EAGAIN) {
    255             ALOGE("Failed to dequeue input buffer for %s (err=%d)",
    256                     mComponentName.c_str(), res);
    257             handleError(res);
    258         }
    259         return false;
    260     }
    261 
    262     CHECK_LT(bufferIx, mInputBuffers.size());
    263 
    264     if (mMediaBuffers[bufferIx] != NULL) {
    265         mMediaBuffers[bufferIx]->release();
    266         mMediaBuffers.editItemAt(bufferIx) = NULL;
    267     }
    268     mInputBufferIsDequeued.editItemAt(bufferIx) = true;
    269 
    270     sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id());
    271     reply->setSize("buffer-ix", bufferIx);
    272     reply->setInt32("generation", mBufferGeneration);
    273 
    274     if (!mCSDsToSubmit.isEmpty()) {
    275         sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
    276         ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
    277         reply->setBuffer("buffer", buffer);
    278         mCSDsToSubmit.removeAt(0);
    279         CHECK(onInputBufferFilled(reply));
    280         return true;
    281     }
    282 
    283     while (!mPendingInputMessages.empty()) {
    284         sp<AMessage> msg = *mPendingInputMessages.begin();
    285         if (!onInputBufferFilled(msg)) {
    286             break;
    287         }
    288         mPendingInputMessages.erase(mPendingInputMessages.begin());
    289     }
    290 
    291     if (!mInputBufferIsDequeued.editItemAt(bufferIx)) {
    292         return true;
    293     }
    294 
    295     sp<AMessage> notify = mNotify->dup();
    296     notify->setInt32("what", kWhatFillThisBuffer);
    297     notify->setBuffer("buffer", mInputBuffers[bufferIx]);
    298     notify->setMessage("reply", reply);
    299     notify->post();
    300     return true;
    301 }
    302 
    303 bool android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) {
    304     size_t bufferIx;
    305     CHECK(msg->findSize("buffer-ix", &bufferIx));
    306     CHECK_LT(bufferIx, mInputBuffers.size());
    307     sp<ABuffer> codecBuffer = mInputBuffers[bufferIx];
    308 
    309     sp<ABuffer> buffer;
    310     bool hasBuffer = msg->findBuffer("buffer", &buffer);
    311 
    312     // handle widevine classic source - that fills an arbitrary input buffer
    313     MediaBuffer *mediaBuffer = NULL;
    314     if (hasBuffer) {
    315         mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase());
    316         if (mediaBuffer != NULL) {
    317             // likely filled another buffer than we requested: adjust buffer index
    318             size_t ix;
    319             for (ix = 0; ix < mInputBuffers.size(); ix++) {
    320                 const sp<ABuffer> &buf = mInputBuffers[ix];
    321                 if (buf->data() == mediaBuffer->data()) {
    322                     // all input buffers are dequeued on start, hence the check
    323                     if (!mInputBufferIsDequeued[ix]) {
    324                         ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu",
    325                                 mComponentName.c_str(), ix, bufferIx);
    326                         mediaBuffer->release();
    327                         return false;
    328                     }
    329 
    330                     // TRICKY: need buffer for the metadata, so instead, set
    331                     // codecBuffer to the same (though incorrect) buffer to
    332                     // avoid a memcpy into the codecBuffer
    333                     codecBuffer = buffer;
    334                     codecBuffer->setRange(
    335                             mediaBuffer->range_offset(),
    336                             mediaBuffer->range_length());
    337                     bufferIx = ix;
    338                     break;
    339                 }
    340             }
    341             CHECK(ix < mInputBuffers.size());
    342         }
    343     }
    344 
    345 
    346 
    347     if (buffer == NULL /* includes !hasBuffer */) {
    348         int32_t streamErr = ERROR_END_OF_STREAM;
    349         CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
    350 
    351         if (streamErr == OK) {
    352             /* buffers are returned to hold on to */
    353             return true;
    354         }
    355 
    356         // attempt to queue EOS
    357         status_t err = mCodec->queueInputBuffer(
    358                 bufferIx,
    359                 0,
    360                 0,
    361                 0,
    362                 MediaCodec::BUFFER_FLAG_EOS);
    363         if (err == OK) {
    364             mInputBufferIsDequeued.editItemAt(bufferIx) = false;
    365         } else if (streamErr == ERROR_END_OF_STREAM) {
    366             streamErr = err;
    367             // err will not be ERROR_END_OF_STREAM
    368         }
    369 
    370         if (streamErr != ERROR_END_OF_STREAM) {
    371             ALOGE("Stream error for %s (err=%d), EOS %s queued",
    372                     mComponentName.c_str(),
    373                     streamErr,
    374                     err == OK ? "successfully" : "unsuccessfully");
    375             handleError(streamErr);
    376         }
    377     } else {
    378         int64_t timeUs = 0;
    379         uint32_t flags = 0;
    380         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
    381 
    382         int32_t eos, csd;
    383         // we do not expect SYNCFRAME for decoder
    384         if (buffer->meta()->findInt32("eos", &eos) && eos) {
    385             flags |= MediaCodec::BUFFER_FLAG_EOS;
    386         } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
    387             flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
    388         }
    389 
    390         // copy into codec buffer
    391         if (buffer != codecBuffer) {
    392             CHECK_LE(buffer->size(), codecBuffer->capacity());
    393             codecBuffer->setRange(0, buffer->size());
    394             memcpy(codecBuffer->data(), buffer->data(), buffer->size());
    395         }
    396 
    397         status_t err = mCodec->queueInputBuffer(
    398                         bufferIx,
    399                         codecBuffer->offset(),
    400                         codecBuffer->size(),
    401                         timeUs,
    402                         flags);
    403         if (err != OK) {
    404             if (mediaBuffer != NULL) {
    405                 mediaBuffer->release();
    406             }
    407             ALOGE("Failed to queue input buffer for %s (err=%d)",
    408                     mComponentName.c_str(), err);
    409             handleError(err);
    410         } else {
    411             mInputBufferIsDequeued.editItemAt(bufferIx) = false;
    412             if (mediaBuffer != NULL) {
    413                 CHECK(mMediaBuffers[bufferIx] == NULL);
    414                 mMediaBuffers.editItemAt(bufferIx) = mediaBuffer;
    415             }
    416         }
    417     }
    418     return true;
    419 }
    420 
    421 bool NuPlayer::Decoder::handleAnOutputBuffer() {
    422     size_t bufferIx = -1;
    423     size_t offset;
    424     size_t size;
    425     int64_t timeUs;
    426     uint32_t flags;
    427     status_t res = mCodec->dequeueOutputBuffer(
    428             &bufferIx, &offset, &size, &timeUs, &flags);
    429 
    430     if (res != OK) {
    431         ALOGV("[%s] dequeued output: %d", mComponentName.c_str(), res);
    432     } else {
    433         ALOGV("[%s] dequeued output: %d (time=%lld flags=%" PRIu32 ")",
    434                 mComponentName.c_str(), (int)bufferIx, timeUs, flags);
    435     }
    436 
    437     if (res == INFO_OUTPUT_BUFFERS_CHANGED) {
    438         res = mCodec->getOutputBuffers(&mOutputBuffers);
    439         if (res != OK) {
    440             ALOGE("Failed to get output buffers for %s after INFO event (err=%d)",
    441                     mComponentName.c_str(), res);
    442             handleError(res);
    443             return false;
    444         }
    445         // NuPlayer ignores this
    446         return true;
    447     } else if (res == INFO_FORMAT_CHANGED) {
    448         sp<AMessage> format = new AMessage();
    449         res = mCodec->getOutputFormat(&format);
    450         if (res != OK) {
    451             ALOGE("Failed to get output format for %s after INFO event (err=%d)",
    452                     mComponentName.c_str(), res);
    453             handleError(res);
    454             return false;
    455         }
    456 
    457         sp<AMessage> notify = mNotify->dup();
    458         notify->setInt32("what", kWhatOutputFormatChanged);
    459         notify->setMessage("format", format);
    460         notify->post();
    461         return true;
    462     } else if (res == INFO_DISCONTINUITY) {
    463         // nothing to do
    464         return true;
    465     } else if (res != OK) {
    466         if (res != -EAGAIN) {
    467             ALOGE("Failed to dequeue output buffer for %s (err=%d)",
    468                     mComponentName.c_str(), res);
    469             handleError(res);
    470         }
    471         return false;
    472     }
    473 
    474     CHECK_LT(bufferIx, mOutputBuffers.size());
    475     sp<ABuffer> buffer = mOutputBuffers[bufferIx];
    476     buffer->setRange(offset, size);
    477     buffer->meta()->clear();
    478     buffer->meta()->setInt64("timeUs", timeUs);
    479     if (flags & MediaCodec::BUFFER_FLAG_EOS) {
    480         buffer->meta()->setInt32("eos", true);
    481     }
    482     // we do not expect CODECCONFIG or SYNCFRAME for decoder
    483 
    484     sp<AMessage> reply = new AMessage(kWhatRenderBuffer, id());
    485     reply->setSize("buffer-ix", bufferIx);
    486     reply->setInt32("generation", mBufferGeneration);
    487 
    488     sp<AMessage> notify = mNotify->dup();
    489     notify->setInt32("what", kWhatDrainThisBuffer);
    490     notify->setBuffer("buffer", buffer);
    491     notify->setMessage("reply", reply);
    492     notify->post();
    493 
    494     // FIXME: This should be handled after rendering is complete,
    495     // but Renderer needs it now
    496     if (flags & MediaCodec::BUFFER_FLAG_EOS) {
    497         ALOGV("queueing eos [%s]", mComponentName.c_str());
    498         sp<AMessage> notify = mNotify->dup();
    499         notify->setInt32("what", kWhatEOS);
    500         notify->setInt32("err", ERROR_END_OF_STREAM);
    501         notify->post();
    502     }
    503     return true;
    504 }
    505 
    506 void NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
    507     status_t err;
    508     int32_t render;
    509     size_t bufferIx;
    510     CHECK(msg->findSize("buffer-ix", &bufferIx));
    511     if (msg->findInt32("render", &render) && render) {
    512         int64_t timestampNs;
    513         CHECK(msg->findInt64("timestampNs", &timestampNs));
    514         err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs);
    515     } else {
    516         err = mCodec->releaseOutputBuffer(bufferIx);
    517     }
    518     if (err != OK) {
    519         ALOGE("failed to release output buffer for %s (err=%d)",
    520                 mComponentName.c_str(), err);
    521         handleError(err);
    522     }
    523 }
    524 
    525 void NuPlayer::Decoder::onFlush() {
    526     status_t err = OK;
    527     if (mCodec != NULL) {
    528         err = mCodec->flush();
    529         mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator
    530         ++mBufferGeneration;
    531     }
    532 
    533     if (err != OK) {
    534         ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err);
    535         handleError(err);
    536         // finish with posting kWhatFlushCompleted.
    537         // we attempt to release the buffers even if flush fails.
    538     }
    539     releaseAndResetMediaBuffers();
    540 
    541     sp<AMessage> notify = mNotify->dup();
    542     notify->setInt32("what", kWhatFlushCompleted);
    543     notify->post();
    544     mPaused = true;
    545 }
    546 
    547 void NuPlayer::Decoder::onResume() {
    548     mPaused = false;
    549 }
    550 
    551 void NuPlayer::Decoder::onShutdown() {
    552     status_t err = OK;
    553     if (mCodec != NULL) {
    554         err = mCodec->release();
    555         mCodec = NULL;
    556         ++mBufferGeneration;
    557 
    558         if (mNativeWindow != NULL) {
    559             // reconnect to surface as MediaCodec disconnected from it
    560             status_t error =
    561                     native_window_api_connect(
    562                             mNativeWindow->getNativeWindow().get(),
    563                             NATIVE_WINDOW_API_MEDIA);
    564             ALOGW_IF(error != NO_ERROR,
    565                     "[%s] failed to connect to native window, error=%d",
    566                     mComponentName.c_str(), error);
    567         }
    568         mComponentName = "decoder";
    569     }
    570 
    571     releaseAndResetMediaBuffers();
    572 
    573     if (err != OK) {
    574         ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err);
    575         handleError(err);
    576         // finish with posting kWhatShutdownCompleted.
    577     }
    578 
    579     sp<AMessage> notify = mNotify->dup();
    580     notify->setInt32("what", kWhatShutdownCompleted);
    581     notify->post();
    582     mPaused = true;
    583 }
    584 
    585 void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
    586     ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
    587 
    588     switch (msg->what()) {
    589         case kWhatConfigure:
    590         {
    591             sp<AMessage> format;
    592             CHECK(msg->findMessage("format", &format));
    593             onConfigure(format);
    594             break;
    595         }
    596 
    597         case kWhatUpdateFormat:
    598         {
    599             sp<AMessage> format;
    600             CHECK(msg->findMessage("format", &format));
    601             rememberCodecSpecificData(format);
    602             break;
    603         }
    604 
    605         case kWhatGetInputBuffers:
    606         {
    607             uint32_t replyID;
    608             CHECK(msg->senderAwaitsResponse(&replyID));
    609 
    610             Vector<sp<ABuffer> > *dstBuffers;
    611             CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
    612 
    613             dstBuffers->clear();
    614             for (size_t i = 0; i < mInputBuffers.size(); i++) {
    615                 dstBuffers->push(mInputBuffers[i]);
    616             }
    617 
    618             (new AMessage)->postReply(replyID);
    619             break;
    620         }
    621 
    622         case kWhatCodecNotify:
    623         {
    624             if (!isStaleReply(msg)) {
    625                 int32_t numInput, numOutput;
    626 
    627                 if (!msg->findInt32("input-buffers", &numInput)) {
    628                     numInput = INT32_MAX;
    629                 }
    630 
    631                 if (!msg->findInt32("output-buffers", &numOutput)) {
    632                     numOutput = INT32_MAX;
    633                 }
    634 
    635                 if (!mPaused) {
    636                     while (numInput-- > 0 && handleAnInputBuffer()) {}
    637                 }
    638 
    639                 while (numOutput-- > 0 && handleAnOutputBuffer()) {}
    640             }
    641 
    642             requestCodecNotification();
    643             break;
    644         }
    645 
    646         case kWhatInputBufferFilled:
    647         {
    648             if (!isStaleReply(msg)) {
    649                 if (!mPendingInputMessages.empty()
    650                         || !onInputBufferFilled(msg)) {
    651                     mPendingInputMessages.push_back(msg);
    652                 }
    653             }
    654 
    655             break;
    656         }
    657 
    658         case kWhatRenderBuffer:
    659         {
    660             if (!isStaleReply(msg)) {
    661                 onRenderBuffer(msg);
    662             }
    663             break;
    664         }
    665 
    666         case kWhatFlush:
    667         {
    668             sp<AMessage> format;
    669             if (msg->findMessage("new-format", &format)) {
    670                 rememberCodecSpecificData(format);
    671             }
    672             onFlush();
    673             break;
    674         }
    675 
    676         case kWhatResume:
    677         {
    678             onResume();
    679             break;
    680         }
    681 
    682         case kWhatShutdown:
    683         {
    684             onShutdown();
    685             break;
    686         }
    687 
    688         default:
    689             TRESPASS();
    690             break;
    691     }
    692 }
    693 
    694 void NuPlayer::Decoder::signalFlush(const sp<AMessage> &format) {
    695     sp<AMessage> msg = new AMessage(kWhatFlush, id());
    696     if (format != NULL) {
    697         msg->setMessage("new-format", format);
    698     }
    699     msg->post();
    700 }
    701 
    702 void NuPlayer::Decoder::signalResume() {
    703     (new AMessage(kWhatResume, id()))->post();
    704 }
    705 
    706 void NuPlayer::Decoder::initiateShutdown() {
    707     (new AMessage(kWhatShutdown, id()))->post();
    708 }
    709 
    710 bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const {
    711     if (targetFormat == NULL) {
    712         return true;
    713     }
    714 
    715     AString mime;
    716     if (!targetFormat->findString("mime", &mime)) {
    717         return false;
    718     }
    719 
    720     if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
    721         // field-by-field comparison
    722         const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
    723         for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
    724             int32_t oldVal, newVal;
    725             if (!mOutputFormat->findInt32(keys[i], &oldVal) ||
    726                     !targetFormat->findInt32(keys[i], &newVal) ||
    727                     oldVal != newVal) {
    728                 return false;
    729             }
    730         }
    731 
    732         sp<ABuffer> oldBuf, newBuf;
    733         if (mOutputFormat->findBuffer("csd-0", &oldBuf) &&
    734                 targetFormat->findBuffer("csd-0", &newBuf)) {
    735             if (oldBuf->size() != newBuf->size()) {
    736                 return false;
    737             }
    738             return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size());
    739         }
    740     }
    741     return false;
    742 }
    743 
    744 bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
    745     if (mOutputFormat == NULL) {
    746         return false;
    747     }
    748 
    749     if (targetFormat == NULL) {
    750         return true;
    751     }
    752 
    753     AString oldMime, newMime;
    754     if (!mOutputFormat->findString("mime", &oldMime)
    755             || !targetFormat->findString("mime", &newMime)
    756             || !(oldMime == newMime)) {
    757         return false;
    758     }
    759 
    760     bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
    761     bool seamless;
    762     if (audio) {
    763         seamless = supportsSeamlessAudioFormatChange(targetFormat);
    764     } else {
    765         int32_t isAdaptive;
    766         seamless = (mCodec != NULL &&
    767                 mInputFormat->findInt32("adaptive-playback", &isAdaptive) &&
    768                 isAdaptive);
    769     }
    770 
    771     ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
    772     return seamless;
    773 }
    774 
    775 struct CCData {
    776     CCData(uint8_t type, uint8_t data1, uint8_t data2)
    777         : mType(type), mData1(data1), mData2(data2) {
    778     }
    779     bool getChannel(size_t *channel) const {
    780         if (mData1 >= 0x10 && mData1 <= 0x1f) {
    781             *channel = (mData1 >= 0x18 ? 1 : 0) + (mType ? 2 : 0);
    782             return true;
    783         }
    784         return false;
    785     }
    786 
    787     uint8_t mType;
    788     uint8_t mData1;
    789     uint8_t mData2;
    790 };
    791 
    792 static bool isNullPad(CCData *cc) {
    793     return cc->mData1 < 0x10 && cc->mData2 < 0x10;
    794 }
    795 
    796 static void dumpBytePair(const sp<ABuffer> &ccBuf) {
    797     size_t offset = 0;
    798     AString out;
    799 
    800     while (offset < ccBuf->size()) {
    801         char tmp[128];
    802 
    803         CCData *cc = (CCData *) (ccBuf->data() + offset);
    804 
    805         if (isNullPad(cc)) {
    806             // 1 null pad or XDS metadata, ignore
    807             offset += sizeof(CCData);
    808             continue;
    809         }
    810 
    811         if (cc->mData1 >= 0x20 && cc->mData1 <= 0x7f) {
    812             // 2 basic chars
    813             sprintf(tmp, "[%d]Basic: %c %c", cc->mType, cc->mData1, cc->mData2);
    814         } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19)
    815                  && cc->mData2 >= 0x30 && cc->mData2 <= 0x3f) {
    816             // 1 special char
    817             sprintf(tmp, "[%d]Special: %02x %02x", cc->mType, cc->mData1, cc->mData2);
    818         } else if ((cc->mData1 == 0x12 || cc->mData1 == 0x1A)
    819                  && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){
    820             // 1 Spanish/French char
    821             sprintf(tmp, "[%d]Spanish: %02x %02x", cc->mType, cc->mData1, cc->mData2);
    822         } else if ((cc->mData1 == 0x13 || cc->mData1 == 0x1B)
    823                  && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){
    824             // 1 Portuguese/German/Danish char
    825             sprintf(tmp, "[%d]German: %02x %02x", cc->mType, cc->mData1, cc->mData2);
    826         } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19)
    827                  && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f){
    828             // Mid-Row Codes (Table 69)
    829             sprintf(tmp, "[%d]Mid-row: %02x %02x", cc->mType, cc->mData1, cc->mData2);
    830         } else if (((cc->mData1 == 0x14 || cc->mData1 == 0x1c)
    831                   && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f)
    832                   ||
    833                    ((cc->mData1 == 0x17 || cc->mData1 == 0x1f)
    834                   && cc->mData2 >= 0x21 && cc->mData2 <= 0x23)){
    835             // Misc Control Codes (Table 70)
    836             sprintf(tmp, "[%d]Ctrl: %02x %02x", cc->mType, cc->mData1, cc->mData2);
    837         } else if ((cc->mData1 & 0x70) == 0x10
    838                 && (cc->mData2 & 0x40) == 0x40
    839                 && ((cc->mData1 & 0x07) || !(cc->mData2 & 0x20)) ) {
    840             // Preamble Address Codes (Table 71)
    841             sprintf(tmp, "[%d]PAC: %02x %02x", cc->mType, cc->mData1, cc->mData2);
    842         } else {
    843             sprintf(tmp, "[%d]Invalid: %02x %02x", cc->mType, cc->mData1, cc->mData2);
    844         }
    845 
    846         if (out.size() > 0) {
    847             out.append(", ");
    848         }
    849 
    850         out.append(tmp);
    851 
    852         offset += sizeof(CCData);
    853     }
    854 
    855     ALOGI("%s", out.c_str());
    856 }
    857 
    858 NuPlayer::CCDecoder::CCDecoder(const sp<AMessage> &notify)
    859     : mNotify(notify),
    860       mCurrentChannel(0),
    861       mSelectedTrack(-1) {
    862       for (size_t i = 0; i < sizeof(mTrackIndices)/sizeof(mTrackIndices[0]); ++i) {
    863           mTrackIndices[i] = -1;
    864       }
    865 }
    866 
    867 size_t NuPlayer::CCDecoder::getTrackCount() const {
    868     return mFoundChannels.size();
    869 }
    870 
    871 sp<AMessage> NuPlayer::CCDecoder::getTrackInfo(size_t index) const {
    872     if (!isTrackValid(index)) {
    873         return NULL;
    874     }
    875 
    876     sp<AMessage> format = new AMessage();
    877 
    878     format->setInt32("type", MEDIA_TRACK_TYPE_SUBTITLE);
    879     format->setString("language", "und");
    880     format->setString("mime", MEDIA_MIMETYPE_TEXT_CEA_608);
    881     //CC1, field 0 channel 0
    882     bool isDefaultAuto = (mFoundChannels[index] == 0);
    883     format->setInt32("auto", isDefaultAuto);
    884     format->setInt32("default", isDefaultAuto);
    885     format->setInt32("forced", 0);
    886 
    887     return format;
    888 }
    889 
    890 status_t NuPlayer::CCDecoder::selectTrack(size_t index, bool select) {
    891     if (!isTrackValid(index)) {
    892         return BAD_VALUE;
    893     }
    894 
    895     if (select) {
    896         if (mSelectedTrack == (ssize_t)index) {
    897             ALOGE("track %zu already selected", index);
    898             return BAD_VALUE;
    899         }
    900         ALOGV("selected track %zu", index);
    901         mSelectedTrack = index;
    902     } else {
    903         if (mSelectedTrack != (ssize_t)index) {
    904             ALOGE("track %zu is not selected", index);
    905             return BAD_VALUE;
    906         }
    907         ALOGV("unselected track %zu", index);
    908         mSelectedTrack = -1;
    909     }
    910 
    911     return OK;
    912 }
    913 
    914 bool NuPlayer::CCDecoder::isSelected() const {
    915     return mSelectedTrack >= 0 && mSelectedTrack < (int32_t) getTrackCount();
    916 }
    917 
    918 bool NuPlayer::CCDecoder::isTrackValid(size_t index) const {
    919     return index < getTrackCount();
    920 }
    921 
    922 int32_t NuPlayer::CCDecoder::getTrackIndex(size_t channel) const {
    923     if (channel < sizeof(mTrackIndices)/sizeof(mTrackIndices[0])) {
    924         return mTrackIndices[channel];
    925     }
    926     return -1;
    927 }
    928 
    929 // returns true if a new CC track is found
    930 bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) {
    931     int64_t timeUs;
    932     CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
    933 
    934     sp<ABuffer> sei;
    935     if (!accessUnit->meta()->findBuffer("sei", &sei) || sei == NULL) {
    936         return false;
    937     }
    938 
    939     bool trackAdded = false;
    940 
    941     NALBitReader br(sei->data() + 1, sei->size() - 1);
    942     // sei_message()
    943     while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message()
    944         uint32_t payload_type = 0;
    945         size_t payload_size = 0;
    946         uint8_t last_byte;
    947 
    948         do {
    949             last_byte = br.getBits(8);
    950             payload_type += last_byte;
    951         } while (last_byte == 0xFF);
    952 
    953         do {
    954             last_byte = br.getBits(8);
    955             payload_size += last_byte;
    956         } while (last_byte == 0xFF);
    957 
    958         // sei_payload()
    959         if (payload_type == 4) {
    960             // user_data_registered_itu_t_t35()
    961 
    962             // ATSC A/72: 6.4.2
    963             uint8_t itu_t_t35_country_code = br.getBits(8);
    964             uint16_t itu_t_t35_provider_code = br.getBits(16);
    965             uint32_t user_identifier = br.getBits(32);
    966             uint8_t user_data_type_code = br.getBits(8);
    967 
    968             payload_size -= 1 + 2 + 4 + 1;
    969 
    970             if (itu_t_t35_country_code == 0xB5
    971                     && itu_t_t35_provider_code == 0x0031
    972                     && user_identifier == 'GA94'
    973                     && user_data_type_code == 0x3) {
    974                 // MPEG_cc_data()
    975                 // ATSC A/53 Part 4: 6.2.3.1
    976                 br.skipBits(1); //process_em_data_flag
    977                 bool process_cc_data_flag = br.getBits(1);
    978                 br.skipBits(1); //additional_data_flag
    979                 size_t cc_count = br.getBits(5);
    980                 br.skipBits(8); // em_data;
    981                 payload_size -= 2;
    982 
    983                 if (process_cc_data_flag) {
    984                     AString out;
    985 
    986                     sp<ABuffer> ccBuf = new ABuffer(cc_count * sizeof(CCData));
    987                     ccBuf->setRange(0, 0);
    988 
    989                     for (size_t i = 0; i < cc_count; i++) {
    990                         uint8_t marker = br.getBits(5);
    991                         CHECK_EQ(marker, 0x1f);
    992 
    993                         bool cc_valid = br.getBits(1);
    994                         uint8_t cc_type = br.getBits(2);
    995                         // remove odd parity bit
    996                         uint8_t cc_data_1 = br.getBits(8) & 0x7f;
    997                         uint8_t cc_data_2 = br.getBits(8) & 0x7f;
    998 
    999                         if (cc_valid
   1000                                 && (cc_type == 0 || cc_type == 1)) {
   1001                             CCData cc(cc_type, cc_data_1, cc_data_2);
   1002                             if (!isNullPad(&cc)) {
   1003                                 size_t channel;
   1004                                 if (cc.getChannel(&channel) && getTrackIndex(channel) < 0) {
   1005                                     mTrackIndices[channel] = mFoundChannels.size();
   1006                                     mFoundChannels.push_back(channel);
   1007                                     trackAdded = true;
   1008                                 }
   1009                                 memcpy(ccBuf->data() + ccBuf->size(),
   1010                                         (void *)&cc, sizeof(cc));
   1011                                 ccBuf->setRange(0, ccBuf->size() + sizeof(CCData));
   1012                             }
   1013                         }
   1014                     }
   1015                     payload_size -= cc_count * 3;
   1016 
   1017                     mCCMap.add(timeUs, ccBuf);
   1018                     break;
   1019                 }
   1020             } else {
   1021                 ALOGV("Malformed SEI payload type 4");
   1022             }
   1023         } else {
   1024             ALOGV("Unsupported SEI payload type %d", payload_type);
   1025         }
   1026 
   1027         // skipping remaining bits of this payload
   1028         br.skipBits(payload_size * 8);
   1029     }
   1030 
   1031     return trackAdded;
   1032 }
   1033 
   1034 sp<ABuffer> NuPlayer::CCDecoder::filterCCBuf(
   1035         const sp<ABuffer> &ccBuf, size_t index) {
   1036     sp<ABuffer> filteredCCBuf = new ABuffer(ccBuf->size());
   1037     filteredCCBuf->setRange(0, 0);
   1038 
   1039     size_t cc_count = ccBuf->size() / sizeof(CCData);
   1040     const CCData* cc_data = (const CCData*)ccBuf->data();
   1041     for (size_t i = 0; i < cc_count; ++i) {
   1042         size_t channel;
   1043         if (cc_data[i].getChannel(&channel)) {
   1044             mCurrentChannel = channel;
   1045         }
   1046         if (mCurrentChannel == mFoundChannels[index]) {
   1047             memcpy(filteredCCBuf->data() + filteredCCBuf->size(),
   1048                     (void *)&cc_data[i], sizeof(CCData));
   1049             filteredCCBuf->setRange(0, filteredCCBuf->size() + sizeof(CCData));
   1050         }
   1051     }
   1052 
   1053     return filteredCCBuf;
   1054 }
   1055 
   1056 void NuPlayer::CCDecoder::decode(const sp<ABuffer> &accessUnit) {
   1057     if (extractFromSEI(accessUnit)) {
   1058         ALOGI("Found CEA-608 track");
   1059         sp<AMessage> msg = mNotify->dup();
   1060         msg->setInt32("what", kWhatTrackAdded);
   1061         msg->post();
   1062     }
   1063     // TODO: extract CC from other sources
   1064 }
   1065 
   1066 void NuPlayer::CCDecoder::display(int64_t timeUs) {
   1067     if (!isTrackValid(mSelectedTrack)) {
   1068         ALOGE("Could not find current track(index=%d)", mSelectedTrack);
   1069         return;
   1070     }
   1071 
   1072     ssize_t index = mCCMap.indexOfKey(timeUs);
   1073     if (index < 0) {
   1074         ALOGV("cc for timestamp %" PRId64 " not found", timeUs);
   1075         return;
   1076     }
   1077 
   1078     sp<ABuffer> ccBuf = filterCCBuf(mCCMap.valueAt(index), mSelectedTrack);
   1079 
   1080     if (ccBuf->size() > 0) {
   1081 #if 0
   1082         dumpBytePair(ccBuf);
   1083 #endif
   1084 
   1085         ccBuf->meta()->setInt32("trackIndex", mSelectedTrack);
   1086         ccBuf->meta()->setInt64("timeUs", timeUs);
   1087         ccBuf->meta()->setInt64("durationUs", 0ll);
   1088 
   1089         sp<AMessage> msg = mNotify->dup();
   1090         msg->setInt32("what", kWhatClosedCaptionData);
   1091         msg->setBuffer("buffer", ccBuf);
   1092         msg->post();
   1093     }
   1094 
   1095     // remove all entries before timeUs
   1096     mCCMap.removeItemsAt(0, index + 1);
   1097 }
   1098 
   1099 void NuPlayer::CCDecoder::flush() {
   1100     mCCMap.clear();
   1101 }
   1102 
   1103 }  // namespace android
   1104 
   1105