1 /*
2  * Copyright (C) 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 "SimplePlayer"
19 #include <utils/Log.h>
20 
21 #include "SimplePlayer.h"
22 
23 #include <gui/Surface.h>
24 
25 #include <media/AudioTrack.h>
26 #include <media/ICrypto.h>
27 #include <media/IMediaHTTPService.h>
28 #include <media/stagefright/foundation/ABuffer.h>
29 #include <media/stagefright/foundation/ADebug.h>
30 #include <media/stagefright/foundation/AMessage.h>
31 #include <media/stagefright/MediaCodec.h>
32 #include <media/stagefright/MediaErrors.h>
33 #include <media/stagefright/NuMediaExtractor.h>
34 
35 namespace android {
36 
SimplePlayer()37 SimplePlayer::SimplePlayer()
38     : mState(UNINITIALIZED),
39       mDoMoreStuffGeneration(0),
40       mStartTimeRealUs(-1ll) {
41 }
42 
~SimplePlayer()43 SimplePlayer::~SimplePlayer() {
44 }
45 
46 // static
PostAndAwaitResponse(const sp<AMessage> & msg,sp<AMessage> * response)47 status_t PostAndAwaitResponse(
48         const sp<AMessage> &msg, sp<AMessage> *response) {
49     status_t err = msg->postAndAwaitResponse(response);
50 
51     if (err != OK) {
52         return err;
53     }
54 
55     if (!(*response)->findInt32("err", &err)) {
56         err = OK;
57     }
58 
59     return err;
60 }
setDataSource(const char * path)61 status_t SimplePlayer::setDataSource(const char *path) {
62     sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
63     msg->setString("path", path);
64     sp<AMessage> response;
65     return PostAndAwaitResponse(msg, &response);
66 }
67 
setSurface(const sp<IGraphicBufferProducer> & bufferProducer)68 status_t SimplePlayer::setSurface(const sp<IGraphicBufferProducer> &bufferProducer) {
69     sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
70 
71     sp<Surface> surface;
72     if (bufferProducer != NULL) {
73         surface = new Surface(bufferProducer);
74     }
75 
76     msg->setObject("surface", surface);
77 
78     sp<AMessage> response;
79     return PostAndAwaitResponse(msg, &response);
80 }
81 
prepare()82 status_t SimplePlayer::prepare() {
83     sp<AMessage> msg = new AMessage(kWhatPrepare, this);
84     sp<AMessage> response;
85     return PostAndAwaitResponse(msg, &response);
86 }
87 
start()88 status_t SimplePlayer::start() {
89     sp<AMessage> msg = new AMessage(kWhatStart, this);
90     sp<AMessage> response;
91     return PostAndAwaitResponse(msg, &response);
92 }
93 
stop()94 status_t SimplePlayer::stop() {
95     sp<AMessage> msg = new AMessage(kWhatStop, this);
96     sp<AMessage> response;
97     return PostAndAwaitResponse(msg, &response);
98 }
99 
reset()100 status_t SimplePlayer::reset() {
101     sp<AMessage> msg = new AMessage(kWhatReset, this);
102     sp<AMessage> response;
103     return PostAndAwaitResponse(msg, &response);
104 }
105 
onMessageReceived(const sp<AMessage> & msg)106 void SimplePlayer::onMessageReceived(const sp<AMessage> &msg) {
107     switch (msg->what()) {
108         case kWhatSetDataSource:
109         {
110             status_t err;
111             if (mState != UNINITIALIZED) {
112                 err = INVALID_OPERATION;
113             } else {
114                 CHECK(msg->findString("path", &mPath));
115                 mState = UNPREPARED;
116             }
117 
118             sp<AReplyToken> replyID;
119             CHECK(msg->senderAwaitsResponse(&replyID));
120 
121             sp<AMessage> response = new AMessage;
122             response->setInt32("err", err);
123             response->postReply(replyID);
124             break;
125         }
126 
127         case kWhatSetSurface:
128         {
129             status_t err;
130             if (mState != UNPREPARED) {
131                 err = INVALID_OPERATION;
132             } else {
133                 sp<RefBase> obj;
134                 CHECK(msg->findObject("surface", &obj));
135                 mSurface = static_cast<Surface *>(obj.get());
136                 err = OK;
137             }
138 
139             sp<AReplyToken> replyID;
140             CHECK(msg->senderAwaitsResponse(&replyID));
141 
142             sp<AMessage> response = new AMessage;
143             response->setInt32("err", err);
144             response->postReply(replyID);
145             break;
146         }
147 
148         case kWhatPrepare:
149         {
150             status_t err;
151             if (mState != UNPREPARED) {
152                 err = INVALID_OPERATION;
153             } else {
154                 err = onPrepare();
155 
156                 if (err == OK) {
157                     mState = STOPPED;
158                 }
159             }
160 
161             sp<AReplyToken> replyID;
162             CHECK(msg->senderAwaitsResponse(&replyID));
163 
164             sp<AMessage> response = new AMessage;
165             response->setInt32("err", err);
166             response->postReply(replyID);
167             break;
168         }
169 
170         case kWhatStart:
171         {
172             status_t err = OK;
173 
174             if (mState == UNPREPARED) {
175                 err = onPrepare();
176 
177                 if (err == OK) {
178                     mState = STOPPED;
179                 }
180             }
181 
182             if (err == OK) {
183                 if (mState != STOPPED) {
184                     err = INVALID_OPERATION;
185                 } else {
186                     err = onStart();
187 
188                     if (err == OK) {
189                         mState = STARTED;
190                     }
191                 }
192             }
193 
194             sp<AReplyToken> replyID;
195             CHECK(msg->senderAwaitsResponse(&replyID));
196 
197             sp<AMessage> response = new AMessage;
198             response->setInt32("err", err);
199             response->postReply(replyID);
200             break;
201         }
202 
203         case kWhatStop:
204         {
205             status_t err;
206 
207             if (mState != STARTED) {
208                 err = INVALID_OPERATION;
209             } else {
210                 err = onStop();
211 
212                 if (err == OK) {
213                     mState = STOPPED;
214                 }
215             }
216 
217             sp<AReplyToken> replyID;
218             CHECK(msg->senderAwaitsResponse(&replyID));
219 
220             sp<AMessage> response = new AMessage;
221             response->setInt32("err", err);
222             response->postReply(replyID);
223             break;
224         }
225 
226         case kWhatReset:
227         {
228             status_t err = OK;
229 
230             if (mState == STARTED) {
231                 CHECK_EQ(onStop(), (status_t)OK);
232                 mState = STOPPED;
233             }
234 
235             if (mState == STOPPED) {
236                 err = onReset();
237                 mState = UNINITIALIZED;
238             }
239 
240             sp<AReplyToken> replyID;
241             CHECK(msg->senderAwaitsResponse(&replyID));
242 
243             sp<AMessage> response = new AMessage;
244             response->setInt32("err", err);
245             response->postReply(replyID);
246             break;
247         }
248 
249         case kWhatDoMoreStuff:
250         {
251             int32_t generation;
252             CHECK(msg->findInt32("generation", &generation));
253 
254             if (generation != mDoMoreStuffGeneration) {
255                 break;
256             }
257 
258             status_t err = onDoMoreStuff();
259 
260             if (err == OK) {
261                 msg->post(10000ll);
262             }
263             break;
264         }
265 
266         default:
267             TRESPASS();
268     }
269 }
270 
onPrepare()271 status_t SimplePlayer::onPrepare() {
272     CHECK_EQ(mState, UNPREPARED);
273 
274     mExtractor = new NuMediaExtractor;
275 
276     status_t err = mExtractor->setDataSource(
277             NULL /* httpService */, mPath.c_str());
278 
279     if (err != OK) {
280         mExtractor.clear();
281         return err;
282     }
283 
284     if (mCodecLooper == NULL) {
285         mCodecLooper = new ALooper;
286         mCodecLooper->start();
287     }
288 
289     bool haveAudio = false;
290     bool haveVideo = false;
291     for (size_t i = 0; i < mExtractor->countTracks(); ++i) {
292         sp<AMessage> format;
293         status_t err = mExtractor->getTrackFormat(i, &format);
294         CHECK_EQ(err, (status_t)OK);
295 
296         AString mime;
297         CHECK(format->findString("mime", &mime));
298 
299         bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
300 
301         if (!haveAudio && !strncasecmp(mime.c_str(), "audio/", 6)) {
302             haveAudio = true;
303         } else if (!haveVideo && isVideo) {
304             haveVideo = true;
305         } else {
306             continue;
307         }
308 
309         err = mExtractor->selectTrack(i);
310         CHECK_EQ(err, (status_t)OK);
311 
312         CodecState *state =
313             &mStateByTrackIndex.editValueAt(
314                     mStateByTrackIndex.add(i, CodecState()));
315 
316         state->mNumFramesWritten = 0;
317         state->mCodec = MediaCodec::CreateByType(
318                 mCodecLooper, mime.c_str(), false /* encoder */);
319 
320         CHECK(state->mCodec != NULL);
321 
322         err = state->mCodec->configure(
323                 format,
324                 isVideo ? mSurface : NULL,
325                 NULL /* crypto */,
326                 0 /* flags */);
327 
328         CHECK_EQ(err, (status_t)OK);
329 
330         size_t j = 0;
331         sp<ABuffer> buffer;
332         while (format->findBuffer(AStringPrintf("csd-%d", j).c_str(), &buffer)) {
333             state->mCSD.push_back(buffer);
334 
335             ++j;
336         }
337     }
338 
339     for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
340         CodecState *state = &mStateByTrackIndex.editValueAt(i);
341 
342         status_t err = state->mCodec->start();
343         CHECK_EQ(err, (status_t)OK);
344 
345         err = state->mCodec->getInputBuffers(&state->mBuffers[0]);
346         CHECK_EQ(err, (status_t)OK);
347 
348         err = state->mCodec->getOutputBuffers(&state->mBuffers[1]);
349         CHECK_EQ(err, (status_t)OK);
350 
351         for (size_t j = 0; j < state->mCSD.size(); ++j) {
352             const sp<ABuffer> &srcBuffer = state->mCSD.itemAt(j);
353 
354             size_t index;
355             err = state->mCodec->dequeueInputBuffer(&index, -1ll);
356             CHECK_EQ(err, (status_t)OK);
357 
358             const sp<ABuffer> &dstBuffer = state->mBuffers[0].itemAt(index);
359 
360             CHECK_LE(srcBuffer->size(), dstBuffer->capacity());
361             dstBuffer->setRange(0, srcBuffer->size());
362             memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size());
363 
364             err = state->mCodec->queueInputBuffer(
365                     index,
366                     0,
367                     dstBuffer->size(),
368                     0ll,
369                     MediaCodec::BUFFER_FLAG_CODECCONFIG);
370             CHECK_EQ(err, (status_t)OK);
371         }
372     }
373 
374     return OK;
375 }
376 
onStart()377 status_t SimplePlayer::onStart() {
378     CHECK_EQ(mState, STOPPED);
379 
380     mStartTimeRealUs = -1ll;
381 
382     sp<AMessage> msg = new AMessage(kWhatDoMoreStuff, this);
383     msg->setInt32("generation", ++mDoMoreStuffGeneration);
384     msg->post();
385 
386     return OK;
387 }
388 
onStop()389 status_t SimplePlayer::onStop() {
390     CHECK_EQ(mState, STARTED);
391 
392     ++mDoMoreStuffGeneration;
393 
394     return OK;
395 }
396 
onReset()397 status_t SimplePlayer::onReset() {
398     CHECK_EQ(mState, STOPPED);
399 
400     for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
401         CodecState *state = &mStateByTrackIndex.editValueAt(i);
402 
403         CHECK_EQ(state->mCodec->release(), (status_t)OK);
404     }
405 
406     mStartTimeRealUs = -1ll;
407 
408     mStateByTrackIndex.clear();
409     mCodecLooper.clear();
410     mExtractor.clear();
411     mSurface.clear();
412     mPath.clear();
413 
414     return OK;
415 }
416 
onDoMoreStuff()417 status_t SimplePlayer::onDoMoreStuff() {
418     ALOGV("onDoMoreStuff");
419     for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
420         CodecState *state = &mStateByTrackIndex.editValueAt(i);
421 
422         status_t err;
423         do {
424             size_t index;
425             err = state->mCodec->dequeueInputBuffer(&index);
426 
427             if (err == OK) {
428                 ALOGV("dequeued input buffer on track %zu",
429                       mStateByTrackIndex.keyAt(i));
430 
431                 state->mAvailInputBufferIndices.push_back(index);
432             } else {
433                 ALOGV("dequeueInputBuffer on track %zu returned %d",
434                       mStateByTrackIndex.keyAt(i), err);
435             }
436         } while (err == OK);
437 
438         do {
439             BufferInfo info;
440             err = state->mCodec->dequeueOutputBuffer(
441                     &info.mIndex,
442                     &info.mOffset,
443                     &info.mSize,
444                     &info.mPresentationTimeUs,
445                     &info.mFlags);
446 
447             if (err == OK) {
448                 ALOGV("dequeued output buffer on track %zu",
449                       mStateByTrackIndex.keyAt(i));
450 
451                 state->mAvailOutputBufferInfos.push_back(info);
452             } else if (err == INFO_FORMAT_CHANGED) {
453                 err = onOutputFormatChanged(mStateByTrackIndex.keyAt(i), state);
454                 CHECK_EQ(err, (status_t)OK);
455             } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
456                 err = state->mCodec->getOutputBuffers(&state->mBuffers[1]);
457                 CHECK_EQ(err, (status_t)OK);
458             } else {
459                 ALOGV("dequeueOutputBuffer on track %zu returned %d",
460                       mStateByTrackIndex.keyAt(i), err);
461             }
462         } while (err == OK
463                 || err == INFO_FORMAT_CHANGED
464                 || err == INFO_OUTPUT_BUFFERS_CHANGED);
465     }
466 
467     for (;;) {
468         size_t trackIndex;
469         status_t err = mExtractor->getSampleTrackIndex(&trackIndex);
470 
471         if (err != OK) {
472             ALOGI("encountered input EOS.");
473             break;
474         } else {
475             CodecState *state = &mStateByTrackIndex.editValueFor(trackIndex);
476 
477             if (state->mAvailInputBufferIndices.empty()) {
478                 break;
479             }
480 
481             size_t index = *state->mAvailInputBufferIndices.begin();
482             state->mAvailInputBufferIndices.erase(
483                     state->mAvailInputBufferIndices.begin());
484 
485             const sp<ABuffer> &dstBuffer =
486                 state->mBuffers[0].itemAt(index);
487 
488             err = mExtractor->readSampleData(dstBuffer);
489             CHECK_EQ(err, (status_t)OK);
490 
491             int64_t timeUs;
492             CHECK_EQ(mExtractor->getSampleTime(&timeUs), (status_t)OK);
493 
494             err = state->mCodec->queueInputBuffer(
495                     index,
496                     dstBuffer->offset(),
497                     dstBuffer->size(),
498                     timeUs,
499                     0);
500             CHECK_EQ(err, (status_t)OK);
501 
502             ALOGV("enqueued input data on track %zu", trackIndex);
503 
504             err = mExtractor->advance();
505             CHECK_EQ(err, (status_t)OK);
506         }
507     }
508 
509     int64_t nowUs = ALooper::GetNowUs();
510 
511     if (mStartTimeRealUs < 0ll) {
512         mStartTimeRealUs = nowUs + 1000000ll;
513     }
514 
515     for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
516         CodecState *state = &mStateByTrackIndex.editValueAt(i);
517 
518         while (!state->mAvailOutputBufferInfos.empty()) {
519             BufferInfo *info = &*state->mAvailOutputBufferInfos.begin();
520 
521             int64_t whenRealUs = info->mPresentationTimeUs + mStartTimeRealUs;
522             int64_t lateByUs = nowUs - whenRealUs;
523 
524             if (lateByUs > -10000ll) {
525                 bool release = true;
526 
527                 if (lateByUs > 30000ll) {
528                     ALOGI("track %zu buffer late by %lld us, dropping.",
529                           mStateByTrackIndex.keyAt(i), (long long)lateByUs);
530                     state->mCodec->releaseOutputBuffer(info->mIndex);
531                 } else {
532                     if (state->mAudioTrack != NULL) {
533                         const sp<ABuffer> &srcBuffer =
534                             state->mBuffers[1].itemAt(info->mIndex);
535 
536                         renderAudio(state, info, srcBuffer);
537 
538                         if (info->mSize > 0) {
539                             release = false;
540                         }
541                     }
542 
543                     if (release) {
544                         state->mCodec->renderOutputBufferAndRelease(
545                                 info->mIndex);
546                     }
547                 }
548 
549                 if (release) {
550                     state->mAvailOutputBufferInfos.erase(
551                             state->mAvailOutputBufferInfos.begin());
552 
553                     info = NULL;
554                 } else {
555                     break;
556                 }
557             } else {
558                 ALOGV("track %zu buffer early by %lld us.",
559                       mStateByTrackIndex.keyAt(i), (long long)-lateByUs);
560                 break;
561             }
562         }
563     }
564 
565     return OK;
566 }
567 
onOutputFormatChanged(size_t trackIndex __unused,CodecState * state)568 status_t SimplePlayer::onOutputFormatChanged(
569         size_t trackIndex __unused, CodecState *state) {
570     sp<AMessage> format;
571     status_t err = state->mCodec->getOutputFormat(&format);
572 
573     if (err != OK) {
574         return err;
575     }
576 
577     AString mime;
578     CHECK(format->findString("mime", &mime));
579 
580     if (!strncasecmp(mime.c_str(), "audio/", 6)) {
581         int32_t channelCount;
582         int32_t sampleRate;
583         CHECK(format->findInt32("channel-count", &channelCount));
584         CHECK(format->findInt32("sample-rate", &sampleRate));
585 
586         state->mAudioTrack = new AudioTrack(
587                 AUDIO_STREAM_MUSIC,
588                 sampleRate,
589                 AUDIO_FORMAT_PCM_16_BIT,
590                 audio_channel_out_mask_from_count(channelCount),
591                 0);
592 
593         state->mNumFramesWritten = 0;
594     }
595 
596     return OK;
597 }
598 
renderAudio(CodecState * state,BufferInfo * info,const sp<ABuffer> & buffer)599 void SimplePlayer::renderAudio(
600         CodecState *state, BufferInfo *info, const sp<ABuffer> &buffer) {
601     CHECK(state->mAudioTrack != NULL);
602 
603     if (state->mAudioTrack->stopped()) {
604         state->mAudioTrack->start();
605     }
606 
607     uint32_t numFramesPlayed;
608     CHECK_EQ(state->mAudioTrack->getPosition(&numFramesPlayed), (status_t)OK);
609 
610     uint32_t numFramesAvailableToWrite =
611         state->mAudioTrack->frameCount()
612             - (state->mNumFramesWritten - numFramesPlayed);
613 
614     size_t numBytesAvailableToWrite =
615         numFramesAvailableToWrite * state->mAudioTrack->frameSize();
616 
617     size_t copy = info->mSize;
618     if (copy > numBytesAvailableToWrite) {
619         copy = numBytesAvailableToWrite;
620     }
621 
622     if (copy == 0) {
623         return;
624     }
625 
626     int64_t startTimeUs = ALooper::GetNowUs();
627 
628     ssize_t nbytes = state->mAudioTrack->write(
629             buffer->base() + info->mOffset, copy);
630 
631     CHECK_EQ(nbytes, (ssize_t)copy);
632 
633     int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
634 
635     uint32_t numFramesWritten = nbytes / state->mAudioTrack->frameSize();
636 
637     if (delayUs > 2000ll) {
638         ALOGW("AudioTrack::write took %lld us, numFramesAvailableToWrite=%u, "
639               "numFramesWritten=%u",
640               (long long)delayUs, numFramesAvailableToWrite, numFramesWritten);
641     }
642 
643     info->mOffset += nbytes;
644     info->mSize -= nbytes;
645 
646     state->mNumFramesWritten += numFramesWritten;
647 }
648 
649 }  // namespace android
650