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