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