1eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber/*
2eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber *
4eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber * you may not use this file except in compliance with the License.
6eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber * You may obtain a copy of the License at
7eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber *
8eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber *
10eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber * Unless required by applicable law or agreed to in writing, software
11eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber * See the License for the specific language governing permissions and
14eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber * limitations under the License.
15eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber */
16eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
17eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber#include "include/ThrottledSource.h"
18eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
19eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber#include <media/stagefright/MediaDebug.h>
20eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
21eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Hubernamespace android {
22eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
23eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huberstatic int64_t getNowUs() {
24eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    struct timeval tv;
25eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    gettimeofday(&tv, NULL);
26eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
27eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
28eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber}
29eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
30eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas HuberThrottledSource::ThrottledSource(
31eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber        const sp<DataSource> &source,
32eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber        int32_t bandwidthLimitBytesPerSecond)
33eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    : mSource(source),
34eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber      mBandwidthLimitBytesPerSecond(bandwidthLimitBytesPerSecond),
35eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber      mStartTimeUs(-1),
36eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber      mTotalTransferred(0) {
37eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    CHECK(mBandwidthLimitBytesPerSecond > 0);
38eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber}
39eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
40eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huberstatus_t ThrottledSource::initCheck() const {
41eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    return mSource->initCheck();
42eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber}
43eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
44b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dongssize_t ThrottledSource::readAt(off64_t offset, void *data, size_t size) {
45eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    Mutex::Autolock autoLock(mLock);
46eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
47eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    ssize_t n = mSource->readAt(offset, data, size);
48eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
49eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    if (n <= 0) {
50eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber        return n;
51eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    }
52eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
53eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    mTotalTransferred += n;
54eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
55eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    int64_t nowUs = getNowUs();
56eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
57eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    if (mStartTimeUs < 0) {
58eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber        mStartTimeUs = nowUs;
59eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    }
60eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
61eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    // How long would it have taken to transfer everything we ever
62eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    // transferred given the limited bandwidth.
63eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    int64_t durationUs =
64eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber        mTotalTransferred * 1000000ll / mBandwidthLimitBytesPerSecond;
65eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
66eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    int64_t whenUs = mStartTimeUs + durationUs;
67eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
68eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    if (whenUs > nowUs) {
69eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber        usleep(whenUs - nowUs);
70eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    }
71eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
72eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    return n;
73eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber}
74eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
75b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dongstatus_t ThrottledSource::getSize(off64_t *size) {
76eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    return mSource->getSize(size);
77eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber}
78eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
79eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huberuint32_t ThrottledSource::flags() {
80eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber    return mSource->flags();
81eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber}
82eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
83eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber}  // namespace android
84eaeae4ab60a9a48b93a74fd363ec23fb7e882a78Andreas Huber
85