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> ¬ify,
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