Converter.cpp revision 530fdbdc1b5491f3fbf172752834d1515701e142
1/*
2 * Copyright 2012, 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 "Converter"
19#include <utils/Log.h>
20
21#include "Converter.h"
22
23#include "MediaPuller.h"
24#include "include/avc_utils.h"
25
26#include <cutils/properties.h>
27#include <gui/Surface.h>
28#include <media/ICrypto.h>
29#include <media/stagefright/foundation/ABuffer.h>
30#include <media/stagefright/foundation/ADebug.h>
31#include <media/stagefright/foundation/AMessage.h>
32#include <media/stagefright/MediaBuffer.h>
33#include <media/stagefright/MediaCodec.h>
34#include <media/stagefright/MediaDefs.h>
35#include <media/stagefright/MediaErrors.h>
36
37#include <arpa/inet.h>
38
39#include <OMX_Video.h>
40
41namespace android {
42
43Converter::Converter(
44        const sp<AMessage> &notify,
45        const sp<ALooper> &codecLooper,
46        const sp<AMessage> &outputFormat,
47        uint32_t flags)
48    : mNotify(notify),
49      mCodecLooper(codecLooper),
50      mOutputFormat(outputFormat),
51      mFlags(flags),
52      mIsVideo(false),
53      mIsH264(false),
54      mIsPCMAudio(false),
55      mNeedToManuallyPrependSPSPPS(false),
56      mDoMoreWorkPending(false)
57#if ENABLE_SILENCE_DETECTION
58      ,mFirstSilentFrameUs(-1ll)
59      ,mInSilentMode(false)
60#endif
61      ,mPrevVideoBitrate(-1)
62      ,mNumFramesToDrop(0)
63      ,mEncodingSuspended(false)
64    {
65    AString mime;
66    CHECK(mOutputFormat->findString("mime", &mime));
67
68    if (!strncasecmp("video/", mime.c_str(), 6)) {
69        mIsVideo = true;
70
71        mIsH264 = !strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC);
72    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime.c_str())) {
73        mIsPCMAudio = true;
74    }
75}
76
77static void ReleaseMediaBufferReference(const sp<ABuffer> &accessUnit) {
78    void *mbuf;
79    if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
80            && mbuf != NULL) {
81        ALOGV("releasing mbuf %p", mbuf);
82
83        accessUnit->meta()->setPointer("mediaBuffer", NULL);
84
85        static_cast<MediaBuffer *>(mbuf)->release();
86        mbuf = NULL;
87    }
88}
89
90void Converter::releaseEncoder() {
91    if (mEncoder == NULL) {
92        return;
93    }
94
95    mEncoder->release();
96    mEncoder.clear();
97
98    while (!mInputBufferQueue.empty()) {
99        sp<ABuffer> accessUnit = *mInputBufferQueue.begin();
100        mInputBufferQueue.erase(mInputBufferQueue.begin());
101
102        ReleaseMediaBufferReference(accessUnit);
103    }
104
105    for (size_t i = 0; i < mEncoderInputBuffers.size(); ++i) {
106        sp<ABuffer> accessUnit = mEncoderInputBuffers.itemAt(i);
107        ReleaseMediaBufferReference(accessUnit);
108    }
109
110    mEncoderInputBuffers.clear();
111    mEncoderOutputBuffers.clear();
112}
113
114Converter::~Converter() {
115    CHECK(mEncoder == NULL);
116}
117
118void Converter::shutdownAsync() {
119    ALOGV("shutdown");
120    (new AMessage(kWhatShutdown, id()))->post();
121}
122
123status_t Converter::init() {
124    status_t err = initEncoder();
125
126    if (err != OK) {
127        releaseEncoder();
128    }
129
130    return err;
131}
132
133sp<IGraphicBufferProducer> Converter::getGraphicBufferProducer() {
134    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
135    return mGraphicBufferProducer;
136}
137
138size_t Converter::getInputBufferCount() const {
139    return mEncoderInputBuffers.size();
140}
141
142sp<AMessage> Converter::getOutputFormat() const {
143    return mOutputFormat;
144}
145
146bool Converter::needToManuallyPrependSPSPPS() const {
147    return mNeedToManuallyPrependSPSPPS;
148}
149
150// static
151int32_t Converter::GetInt32Property(
152        const char *propName, int32_t defaultValue) {
153    char val[PROPERTY_VALUE_MAX];
154    if (property_get(propName, val, NULL)) {
155        char *end;
156        unsigned long x = strtoul(val, &end, 10);
157
158        if (*end == '\0' && end > val && x > 0) {
159            return x;
160        }
161    }
162
163    return defaultValue;
164}
165
166status_t Converter::initEncoder() {
167    AString outputMIME;
168    CHECK(mOutputFormat->findString("mime", &outputMIME));
169
170    bool isAudio = !strncasecmp(outputMIME.c_str(), "audio/", 6);
171
172    if (!mIsPCMAudio) {
173        mEncoder = MediaCodec::CreateByType(
174                mCodecLooper, outputMIME.c_str(), true /* encoder */);
175
176        if (mEncoder == NULL) {
177            return ERROR_UNSUPPORTED;
178        }
179    }
180
181    if (mIsPCMAudio) {
182        return OK;
183    }
184
185    int32_t audioBitrate = GetInt32Property("media.wfd.audio-bitrate", 128000);
186    int32_t videoBitrate = GetInt32Property("media.wfd.video-bitrate", 5000000);
187    mPrevVideoBitrate = videoBitrate;
188
189    ALOGI("using audio bitrate of %d bps, video bitrate of %d bps",
190          audioBitrate, videoBitrate);
191
192    if (isAudio) {
193        mOutputFormat->setInt32("bitrate", audioBitrate);
194    } else {
195        mOutputFormat->setInt32("bitrate", videoBitrate);
196        mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant);
197        mOutputFormat->setInt32("frame-rate", 30);
198        mOutputFormat->setInt32("i-frame-interval", 15);  // Iframes every 15 secs
199
200        // Configure encoder to use intra macroblock refresh mode
201        mOutputFormat->setInt32("intra-refresh-mode", OMX_VIDEO_IntraRefreshCyclic);
202
203        int width, height, mbs;
204        if (!mOutputFormat->findInt32("width", &width)
205                || !mOutputFormat->findInt32("height", &height)) {
206            return ERROR_UNSUPPORTED;
207        }
208
209        // Update macroblocks in a cyclic fashion with 10% of all MBs within
210        // frame gets updated at one time. It takes about 10 frames to
211        // completely update a whole video frame. If the frame rate is 30,
212        // it takes about 333 ms in the best case (if next frame is not an IDR)
213        // to recover from a lost/corrupted packet.
214        mbs = (((width + 15) / 16) * ((height + 15) / 16) * 10) / 100;
215        mOutputFormat->setInt32("intra-refresh-CIR-mbs", mbs);
216    }
217
218    ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
219
220    mNeedToManuallyPrependSPSPPS = false;
221
222    status_t err = NO_INIT;
223
224    if (!isAudio) {
225        sp<AMessage> tmp = mOutputFormat->dup();
226        tmp->setInt32("prepend-sps-pps-to-idr-frames", 1);
227
228        err = mEncoder->configure(
229                tmp,
230                NULL /* nativeWindow */,
231                NULL /* crypto */,
232                MediaCodec::CONFIGURE_FLAG_ENCODE);
233
234        if (err == OK) {
235            // Encoder supported prepending SPS/PPS, we don't need to emulate
236            // it.
237            mOutputFormat = tmp;
238        } else {
239            mNeedToManuallyPrependSPSPPS = true;
240
241            ALOGI("We going to manually prepend SPS and PPS to IDR frames.");
242        }
243    }
244
245    if (err != OK) {
246        // We'll get here for audio or if we failed to configure the encoder
247        // to automatically prepend SPS/PPS in the case of video.
248
249        err = mEncoder->configure(
250                    mOutputFormat,
251                    NULL /* nativeWindow */,
252                    NULL /* crypto */,
253                    MediaCodec::CONFIGURE_FLAG_ENCODE);
254    }
255
256    if (err != OK) {
257        return err;
258    }
259
260    if (mFlags & FLAG_USE_SURFACE_INPUT) {
261        CHECK(mIsVideo);
262
263        err = mEncoder->createInputSurface(&mGraphicBufferProducer);
264
265        if (err != OK) {
266            return err;
267        }
268    }
269
270    err = mEncoder->start();
271
272    if (err != OK) {
273        return err;
274    }
275
276    err = mEncoder->getInputBuffers(&mEncoderInputBuffers);
277
278    if (err != OK) {
279        return err;
280    }
281
282    err = mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
283
284    if (err != OK) {
285        return err;
286    }
287
288    if (mFlags & FLAG_USE_SURFACE_INPUT) {
289        scheduleDoMoreWork();
290    }
291
292    return OK;
293}
294
295void Converter::notifyError(status_t err) {
296    sp<AMessage> notify = mNotify->dup();
297    notify->setInt32("what", kWhatError);
298    notify->setInt32("err", err);
299    notify->post();
300}
301
302// static
303bool Converter::IsSilence(const sp<ABuffer> &accessUnit) {
304    const uint8_t *ptr = accessUnit->data();
305    const uint8_t *end = ptr + accessUnit->size();
306    while (ptr < end) {
307        if (*ptr != 0) {
308            return false;
309        }
310        ++ptr;
311    }
312
313    return true;
314}
315
316void Converter::onMessageReceived(const sp<AMessage> &msg) {
317    switch (msg->what()) {
318        case kWhatMediaPullerNotify:
319        {
320            int32_t what;
321            CHECK(msg->findInt32("what", &what));
322
323            if (!mIsPCMAudio && mEncoder == NULL) {
324                ALOGV("got msg '%s' after encoder shutdown.",
325                      msg->debugString().c_str());
326
327                if (what == MediaPuller::kWhatAccessUnit) {
328                    sp<ABuffer> accessUnit;
329                    CHECK(msg->findBuffer("accessUnit", &accessUnit));
330
331                    ReleaseMediaBufferReference(accessUnit);
332                }
333                break;
334            }
335
336            if (what == MediaPuller::kWhatEOS) {
337                mInputBufferQueue.push_back(NULL);
338
339                feedEncoderInputBuffers();
340
341                scheduleDoMoreWork();
342            } else {
343                CHECK_EQ(what, MediaPuller::kWhatAccessUnit);
344
345                sp<ABuffer> accessUnit;
346                CHECK(msg->findBuffer("accessUnit", &accessUnit));
347
348                if (mNumFramesToDrop > 0 || mEncodingSuspended) {
349                    if (mNumFramesToDrop > 0) {
350                        --mNumFramesToDrop;
351                        ALOGI("dropping frame.");
352                    }
353
354                    ReleaseMediaBufferReference(accessUnit);
355                    break;
356                }
357
358#if 0
359                void *mbuf;
360                if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
361                        && mbuf != NULL) {
362                    ALOGI("queueing mbuf %p", mbuf);
363                }
364#endif
365
366#if ENABLE_SILENCE_DETECTION
367                if (!mIsVideo) {
368                    if (IsSilence(accessUnit)) {
369                        if (mInSilentMode) {
370                            break;
371                        }
372
373                        int64_t nowUs = ALooper::GetNowUs();
374
375                        if (mFirstSilentFrameUs < 0ll) {
376                            mFirstSilentFrameUs = nowUs;
377                        } else if (nowUs >= mFirstSilentFrameUs + 10000000ll) {
378                            mInSilentMode = true;
379                            ALOGI("audio in silent mode now.");
380                            break;
381                        }
382                    } else {
383                        if (mInSilentMode) {
384                            ALOGI("audio no longer in silent mode.");
385                        }
386                        mInSilentMode = false;
387                        mFirstSilentFrameUs = -1ll;
388                    }
389                }
390#endif
391
392                mInputBufferQueue.push_back(accessUnit);
393
394                feedEncoderInputBuffers();
395
396                scheduleDoMoreWork();
397            }
398            break;
399        }
400
401        case kWhatEncoderActivity:
402        {
403#if 0
404            int64_t whenUs;
405            if (msg->findInt64("whenUs", &whenUs)) {
406                int64_t nowUs = ALooper::GetNowUs();
407                ALOGI("[%s] kWhatEncoderActivity after %lld us",
408                      mIsVideo ? "video" : "audio", nowUs - whenUs);
409            }
410#endif
411
412            mDoMoreWorkPending = false;
413
414            if (mEncoder == NULL) {
415                break;
416            }
417
418            status_t err = doMoreWork();
419
420            if (err != OK) {
421                notifyError(err);
422            } else {
423                scheduleDoMoreWork();
424            }
425            break;
426        }
427
428        case kWhatRequestIDRFrame:
429        {
430            if (mEncoder == NULL) {
431                break;
432            }
433
434            if (mIsVideo) {
435                ALOGV("requesting IDR frame");
436                mEncoder->requestIDRFrame();
437            }
438            break;
439        }
440
441        case kWhatShutdown:
442        {
443            ALOGI("shutting down %s encoder", mIsVideo ? "video" : "audio");
444
445            releaseEncoder();
446
447            AString mime;
448            CHECK(mOutputFormat->findString("mime", &mime));
449            ALOGI("encoder (%s) shut down.", mime.c_str());
450
451            sp<AMessage> notify = mNotify->dup();
452            notify->setInt32("what", kWhatShutdownCompleted);
453            notify->post();
454            break;
455        }
456
457        case kWhatDropAFrame:
458        {
459            ++mNumFramesToDrop;
460            break;
461        }
462
463        case kWhatReleaseOutputBuffer:
464        {
465            if (mEncoder != NULL) {
466                size_t bufferIndex;
467                CHECK(msg->findInt32("bufferIndex", (int32_t*)&bufferIndex));
468                CHECK(bufferIndex < mEncoderOutputBuffers.size());
469                mEncoder->releaseOutputBuffer(bufferIndex);
470            }
471            break;
472        }
473
474        case kWhatSuspendEncoding:
475        {
476            int32_t suspend;
477            CHECK(msg->findInt32("suspend", &suspend));
478
479            mEncodingSuspended = suspend;
480
481            if (mFlags & FLAG_USE_SURFACE_INPUT) {
482                sp<AMessage> params = new AMessage;
483                params->setInt32("drop-input-frames",suspend);
484                mEncoder->setParameters(params);
485            }
486            break;
487        }
488
489        default:
490            TRESPASS();
491    }
492}
493
494void Converter::scheduleDoMoreWork() {
495    if (mIsPCMAudio) {
496        // There's no encoder involved in this case.
497        return;
498    }
499
500    if (mDoMoreWorkPending) {
501        return;
502    }
503
504    mDoMoreWorkPending = true;
505
506#if 1
507    if (mEncoderActivityNotify == NULL) {
508        mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, id());
509    }
510    mEncoder->requestActivityNotification(mEncoderActivityNotify->dup());
511#else
512    sp<AMessage> notify = new AMessage(kWhatEncoderActivity, id());
513    notify->setInt64("whenUs", ALooper::GetNowUs());
514    mEncoder->requestActivityNotification(notify);
515#endif
516}
517
518status_t Converter::feedRawAudioInputBuffers() {
519    // Split incoming PCM audio into buffers of 6 AUs of 80 audio frames each
520    // and add a 4 byte header according to the wifi display specs.
521
522    while (!mInputBufferQueue.empty()) {
523        sp<ABuffer> buffer = *mInputBufferQueue.begin();
524        mInputBufferQueue.erase(mInputBufferQueue.begin());
525
526        int16_t *ptr = (int16_t *)buffer->data();
527        int16_t *stop = (int16_t *)(buffer->data() + buffer->size());
528        while (ptr < stop) {
529            *ptr = htons(*ptr);
530            ++ptr;
531        }
532
533        static const size_t kFrameSize = 2 * sizeof(int16_t);  // stereo
534        static const size_t kFramesPerAU = 80;
535        static const size_t kNumAUsPerPESPacket = 6;
536
537        if (mPartialAudioAU != NULL) {
538            size_t bytesMissingForFullAU =
539                kNumAUsPerPESPacket * kFramesPerAU * kFrameSize
540                - mPartialAudioAU->size() + 4;
541
542            size_t copy = buffer->size();
543            if(copy > bytesMissingForFullAU) {
544                copy = bytesMissingForFullAU;
545            }
546
547            memcpy(mPartialAudioAU->data() + mPartialAudioAU->size(),
548                   buffer->data(),
549                   copy);
550
551            mPartialAudioAU->setRange(0, mPartialAudioAU->size() + copy);
552
553            buffer->setRange(buffer->offset() + copy, buffer->size() - copy);
554
555            int64_t timeUs;
556            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
557
558            int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0);
559            timeUs += copyUs;
560            buffer->meta()->setInt64("timeUs", timeUs);
561
562            if (bytesMissingForFullAU == copy) {
563                sp<AMessage> notify = mNotify->dup();
564                notify->setInt32("what", kWhatAccessUnit);
565                notify->setBuffer("accessUnit", mPartialAudioAU);
566                notify->post();
567
568                mPartialAudioAU.clear();
569            }
570        }
571
572        while (buffer->size() > 0) {
573            sp<ABuffer> partialAudioAU =
574                new ABuffer(
575                        4
576                        + kNumAUsPerPESPacket * kFrameSize * kFramesPerAU);
577
578            uint8_t *ptr = partialAudioAU->data();
579            ptr[0] = 0xa0;  // 10100000b
580            ptr[1] = kNumAUsPerPESPacket;
581            ptr[2] = 0;  // reserved, audio _emphasis_flag = 0
582
583            static const unsigned kQuantizationWordLength = 0;  // 16-bit
584            static const unsigned kAudioSamplingFrequency = 2;  // 48Khz
585            static const unsigned kNumberOfAudioChannels = 1;  // stereo
586
587            ptr[3] = (kQuantizationWordLength << 6)
588                    | (kAudioSamplingFrequency << 3)
589                    | kNumberOfAudioChannels;
590
591            size_t copy = buffer->size();
592            if (copy > partialAudioAU->size() - 4) {
593                copy = partialAudioAU->size() - 4;
594            }
595
596            memcpy(&ptr[4], buffer->data(), copy);
597
598            partialAudioAU->setRange(0, 4 + copy);
599            buffer->setRange(buffer->offset() + copy, buffer->size() - copy);
600
601            int64_t timeUs;
602            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
603
604            partialAudioAU->meta()->setInt64("timeUs", timeUs);
605
606            int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0);
607            timeUs += copyUs;
608            buffer->meta()->setInt64("timeUs", timeUs);
609
610            if (copy == partialAudioAU->capacity() - 4) {
611                sp<AMessage> notify = mNotify->dup();
612                notify->setInt32("what", kWhatAccessUnit);
613                notify->setBuffer("accessUnit", partialAudioAU);
614                notify->post();
615
616                partialAudioAU.clear();
617                continue;
618            }
619
620            mPartialAudioAU = partialAudioAU;
621        }
622    }
623
624    return OK;
625}
626
627status_t Converter::feedEncoderInputBuffers() {
628    if (mIsPCMAudio) {
629        return feedRawAudioInputBuffers();
630    }
631
632    while (!mInputBufferQueue.empty()
633            && !mAvailEncoderInputIndices.empty()) {
634        sp<ABuffer> buffer = *mInputBufferQueue.begin();
635        mInputBufferQueue.erase(mInputBufferQueue.begin());
636
637        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
638        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
639
640        int64_t timeUs = 0ll;
641        uint32_t flags = 0;
642
643        if (buffer != NULL) {
644            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
645
646            memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(),
647                   buffer->data(),
648                   buffer->size());
649
650            void *mediaBuffer;
651            if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer)
652                    && mediaBuffer != NULL) {
653                mEncoderInputBuffers.itemAt(bufferIndex)->meta()
654                    ->setPointer("mediaBuffer", mediaBuffer);
655
656                buffer->meta()->setPointer("mediaBuffer", NULL);
657            }
658        } else {
659            flags = MediaCodec::BUFFER_FLAG_EOS;
660        }
661
662        status_t err = mEncoder->queueInputBuffer(
663                bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(),
664                timeUs, flags);
665
666        if (err != OK) {
667            return err;
668        }
669    }
670
671    return OK;
672}
673
674sp<ABuffer> Converter::prependCSD(const sp<ABuffer> &accessUnit) const {
675    CHECK(mCSD0 != NULL);
676
677    sp<ABuffer> dup = new ABuffer(accessUnit->size() + mCSD0->size());
678    memcpy(dup->data(), mCSD0->data(), mCSD0->size());
679    memcpy(dup->data() + mCSD0->size(), accessUnit->data(), accessUnit->size());
680
681    int64_t timeUs;
682    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
683
684    dup->meta()->setInt64("timeUs", timeUs);
685
686    return dup;
687}
688
689status_t Converter::doMoreWork() {
690    status_t err;
691
692    if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
693        for (;;) {
694            size_t bufferIndex;
695            err = mEncoder->dequeueInputBuffer(&bufferIndex);
696
697            if (err != OK) {
698                break;
699            }
700
701            mAvailEncoderInputIndices.push_back(bufferIndex);
702        }
703
704        feedEncoderInputBuffers();
705    }
706
707    for (;;) {
708        size_t bufferIndex;
709        size_t offset;
710        size_t size;
711        int64_t timeUs;
712        uint32_t flags;
713        native_handle_t* handle = NULL;
714        err = mEncoder->dequeueOutputBuffer(
715                &bufferIndex, &offset, &size, &timeUs, &flags);
716
717        if (err != OK) {
718            if (err == INFO_FORMAT_CHANGED) {
719                continue;
720            } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
721                mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
722                continue;
723            }
724
725            if (err == -EAGAIN) {
726                err = OK;
727            }
728            break;
729        }
730
731        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
732            sp<AMessage> notify = mNotify->dup();
733            notify->setInt32("what", kWhatEOS);
734            notify->post();
735        } else {
736#if 0
737            if (mIsVideo) {
738                int32_t videoBitrate = GetInt32Property(
739                        "media.wfd.video-bitrate", 5000000);
740
741                setVideoBitrate(videoBitrate);
742            }
743#endif
744
745            sp<ABuffer> buffer;
746            sp<ABuffer> outbuf = mEncoderOutputBuffers.itemAt(bufferIndex);
747
748            if (outbuf->meta()->findPointer("handle", (void**)&handle) &&
749                    handle != NULL) {
750                int32_t rangeLength, rangeOffset;
751                CHECK(outbuf->meta()->findInt32("rangeOffset", &rangeOffset));
752                CHECK(outbuf->meta()->findInt32("rangeLength", &rangeLength));
753                outbuf->meta()->setPointer("handle", NULL);
754
755                // MediaSender will post the following message when HDCP
756                // is done, to release the output buffer back to encoder.
757                sp<AMessage> notify(new AMessage(
758                        kWhatReleaseOutputBuffer, id()));
759                notify->setInt32("bufferIndex", bufferIndex);
760
761                buffer = new ABuffer(
762                        rangeLength > (int32_t)size ? rangeLength : size);
763                buffer->meta()->setPointer("handle", handle);
764                buffer->meta()->setInt32("rangeOffset", rangeOffset);
765                buffer->meta()->setInt32("rangeLength", rangeLength);
766                buffer->meta()->setMessage("notify", notify);
767            } else {
768                buffer = new ABuffer(size);
769            }
770
771            buffer->meta()->setInt64("timeUs", timeUs);
772
773            ALOGV("[%s] time %lld us (%.2f secs)",
774                  mIsVideo ? "video" : "audio", timeUs, timeUs / 1E6);
775
776            memcpy(buffer->data(), outbuf->base() + offset, size);
777
778            if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) {
779                if (!handle) {
780                    if (mIsH264) {
781                        mCSD0 = buffer;
782                    }
783                    mOutputFormat->setBuffer("csd-0", buffer);
784                }
785            } else {
786                if (mNeedToManuallyPrependSPSPPS
787                        && mIsH264
788                        && (mFlags & FLAG_PREPEND_CSD_IF_NECESSARY)
789                        && IsIDR(buffer)) {
790                    buffer = prependCSD(buffer);
791                }
792
793                sp<AMessage> notify = mNotify->dup();
794                notify->setInt32("what", kWhatAccessUnit);
795                notify->setBuffer("accessUnit", buffer);
796                notify->post();
797            }
798        }
799
800        if (!handle) {
801            mEncoder->releaseOutputBuffer(bufferIndex);
802        }
803
804        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
805            break;
806        }
807    }
808
809    return err;
810}
811
812void Converter::requestIDRFrame() {
813    (new AMessage(kWhatRequestIDRFrame, id()))->post();
814}
815
816void Converter::dropAFrame() {
817    // Unsupported in surface input mode.
818    CHECK(!(mFlags & FLAG_USE_SURFACE_INPUT));
819
820    (new AMessage(kWhatDropAFrame, id()))->post();
821}
822
823void Converter::suspendEncoding(bool suspend) {
824    sp<AMessage> msg = new AMessage(kWhatSuspendEncoding, id());
825    msg->setInt32("suspend", suspend);
826    msg->post();
827}
828
829int32_t Converter::getVideoBitrate() const {
830    return mPrevVideoBitrate;
831}
832
833void Converter::setVideoBitrate(int32_t bitRate) {
834    if (mIsVideo && mEncoder != NULL && bitRate != mPrevVideoBitrate) {
835        sp<AMessage> params = new AMessage;
836        params->setInt32("video-bitrate", bitRate);
837
838        mEncoder->setParameters(params);
839
840        mPrevVideoBitrate = bitRate;
841    }
842}
843
844}  // namespace android
845