1 /*
2 * Copyright (C) 2011 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 "HTTPBase"
19 #include <utils/Log.h>
20
21 #include <datasource/HTTPBase.h>
22
23 #include <media/stagefright/foundation/ADebug.h>
24 #include <media/stagefright/foundation/ALooper.h>
25
26 #include <cutils/properties.h>
27 #include <cutils/qtaguid.h>
28
29 namespace android {
30
HTTPBase()31 HTTPBase::HTTPBase()
32 : mNumBandwidthHistoryItems(0),
33 mTotalTransferTimeUs(0),
34 mTotalTransferBytes(0),
35 mMaxBandwidthHistoryItems(100),
36 mPrevBandwidthMeasureTimeUs(0),
37 mPrevEstimatedBandWidthKbps(0),
38 mBandWidthCollectFreqMs(5000) {
39 mName = String8("HTTPBase(<disconnected>)");
40 }
41
addBandwidthMeasurement(size_t numBytes,int64_t delayUs)42 void HTTPBase::addBandwidthMeasurement(
43 size_t numBytes, int64_t delayUs) {
44 Mutex::Autolock autoLock(mLock);
45
46 BandwidthEntry entry;
47 entry.mDelayUs = delayUs;
48 entry.mNumBytes = numBytes;
49 mTotalTransferTimeUs += delayUs;
50 mTotalTransferBytes += numBytes;
51
52 mBandwidthHistory.push_back(entry);
53 if (++mNumBandwidthHistoryItems > mMaxBandwidthHistoryItems) {
54 BandwidthEntry *entry = &*mBandwidthHistory.begin();
55 mTotalTransferTimeUs -= entry->mDelayUs;
56 mTotalTransferBytes -= entry->mNumBytes;
57 mBandwidthHistory.erase(mBandwidthHistory.begin());
58 --mNumBandwidthHistoryItems;
59
60 int64_t timeNowUs = ALooper::GetNowUs();
61 if (timeNowUs - mPrevBandwidthMeasureTimeUs >=
62 mBandWidthCollectFreqMs * 1000LL) {
63
64 if (mPrevBandwidthMeasureTimeUs != 0) {
65 mPrevEstimatedBandWidthKbps =
66 (mTotalTransferBytes * 8E3 / mTotalTransferTimeUs);
67 }
68 mPrevBandwidthMeasureTimeUs = timeNowUs;
69 }
70 }
71
72 }
73
estimateBandwidth(int32_t * bandwidth_bps)74 bool HTTPBase::estimateBandwidth(int32_t *bandwidth_bps) {
75 Mutex::Autolock autoLock(mLock);
76
77 // Do not do bandwidth estimation if we don't have enough samples, or
78 // total bytes download are too small (<64K).
79 // Bandwidth estimation from these samples can often shoot up and cause
80 // unwanted bw adaption behaviors.
81 if (mNumBandwidthHistoryItems < 2 || mTotalTransferBytes < 65536) {
82 return false;
83 }
84
85 *bandwidth_bps = ((double)mTotalTransferBytes * 8E6 / mTotalTransferTimeUs);
86
87 return true;
88 }
89
getEstimatedBandwidthKbps(int32_t * kbps)90 status_t HTTPBase::getEstimatedBandwidthKbps(int32_t *kbps) {
91 Mutex::Autolock autoLock(mLock);
92 *kbps = mPrevEstimatedBandWidthKbps;
93 return OK;
94 }
95
setBandwidthStatCollectFreq(int32_t freqMs)96 status_t HTTPBase::setBandwidthStatCollectFreq(int32_t freqMs) {
97 Mutex::Autolock autoLock(mLock);
98
99 if (freqMs < kMinBandwidthCollectFreqMs
100 || freqMs > kMaxBandwidthCollectFreqMs) {
101
102 ALOGE("frequency (%d ms) is out of range [1000, 60000]", freqMs);
103 return BAD_VALUE;
104 }
105
106 ALOGI("frequency set to %d ms", freqMs);
107 mBandWidthCollectFreqMs = freqMs;
108 return OK;
109 }
110
setBandwidthHistorySize(size_t numHistoryItems)111 void HTTPBase::setBandwidthHistorySize(size_t numHistoryItems) {
112 mMaxBandwidthHistoryItems = numHistoryItems;
113 }
114
115 } // namespace android
116