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
35namespace android {
36
37SimplePlayer::SimplePlayer()
38    : mState(UNINITIALIZED),
39      mDoMoreStuffGeneration(0),
40      mStartTimeRealUs(-1ll) {
41}
42
43SimplePlayer::~SimplePlayer() {
44}
45
46// static
47status_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}
61status_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
68status_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
82status_t SimplePlayer::prepare() {
83    sp<AMessage> msg = new AMessage(kWhatPrepare, this);
84    sp<AMessage> response;
85    return PostAndAwaitResponse(msg, &response);
86}
87
88status_t SimplePlayer::start() {
89    sp<AMessage> msg = new AMessage(kWhatStart, this);
90    sp<AMessage> response;
91    return PostAndAwaitResponse(msg, &response);
92}
93
94status_t SimplePlayer::stop() {
95    sp<AMessage> msg = new AMessage(kWhatStop, this);
96    sp<AMessage> response;
97    return PostAndAwaitResponse(msg, &response);
98}
99
100status_t SimplePlayer::reset() {
101    sp<AMessage> msg = new AMessage(kWhatReset, this);
102    sp<AMessage> response;
103    return PostAndAwaitResponse(msg, &response);
104}
105
106void 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
271status_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
377status_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
389status_t SimplePlayer::onStop() {
390    CHECK_EQ(mState, STARTED);
391
392    ++mDoMoreStuffGeneration;
393
394    return OK;
395}
396
397status_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
417status_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
568status_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
599void 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