1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "AnotherPacketSource"
19*ec779b8eSAndroid Build Coastguard Worker
20*ec779b8eSAndroid Build Coastguard Worker #include "AnotherPacketSource.h"
21*ec779b8eSAndroid Build Coastguard Worker
22*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ABuffer.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AMessage.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AString.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/hexdump.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/avc_utils.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaBuffer.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaDefs.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MetaData.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/Utils.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <utils/Vector.h>
33*ec779b8eSAndroid Build Coastguard Worker
34*ec779b8eSAndroid Build Coastguard Worker #include <inttypes.h>
35*ec779b8eSAndroid Build Coastguard Worker
36*ec779b8eSAndroid Build Coastguard Worker namespace android {
37*ec779b8eSAndroid Build Coastguard Worker
38*ec779b8eSAndroid Build Coastguard Worker const int64_t kNearEOSMarkUs = 2000000LL; // 2 secs
39*ec779b8eSAndroid Build Coastguard Worker
AnotherPacketSource(const sp<MetaData> & meta)40*ec779b8eSAndroid Build Coastguard Worker AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta)
41*ec779b8eSAndroid Build Coastguard Worker : mIsAudio(false),
42*ec779b8eSAndroid Build Coastguard Worker mIsVideo(false),
43*ec779b8eSAndroid Build Coastguard Worker mEnabled(true),
44*ec779b8eSAndroid Build Coastguard Worker mFormat(NULL),
45*ec779b8eSAndroid Build Coastguard Worker mLastQueuedTimeUs(0),
46*ec779b8eSAndroid Build Coastguard Worker mEstimatedBufferDurationUs(-1),
47*ec779b8eSAndroid Build Coastguard Worker mEOSResult(OK),
48*ec779b8eSAndroid Build Coastguard Worker mLatestEnqueuedMeta(NULL),
49*ec779b8eSAndroid Build Coastguard Worker mLatestDequeuedMeta(NULL) {
50*ec779b8eSAndroid Build Coastguard Worker setFormat(meta);
51*ec779b8eSAndroid Build Coastguard Worker
52*ec779b8eSAndroid Build Coastguard Worker mDiscontinuitySegments.push_back(DiscontinuitySegment());
53*ec779b8eSAndroid Build Coastguard Worker }
54*ec779b8eSAndroid Build Coastguard Worker
setFormat(const sp<MetaData> & meta)55*ec779b8eSAndroid Build Coastguard Worker void AnotherPacketSource::setFormat(const sp<MetaData> &meta) {
56*ec779b8eSAndroid Build Coastguard Worker if (mFormat != NULL) {
57*ec779b8eSAndroid Build Coastguard Worker // Only allowed to be set once. Requires explicit clear to reset.
58*ec779b8eSAndroid Build Coastguard Worker return;
59*ec779b8eSAndroid Build Coastguard Worker }
60*ec779b8eSAndroid Build Coastguard Worker
61*ec779b8eSAndroid Build Coastguard Worker mIsAudio = false;
62*ec779b8eSAndroid Build Coastguard Worker mIsVideo = false;
63*ec779b8eSAndroid Build Coastguard Worker const char *mime;
64*ec779b8eSAndroid Build Coastguard Worker
65*ec779b8eSAndroid Build Coastguard Worker // Do not use meta if no mime.
66*ec779b8eSAndroid Build Coastguard Worker if (meta == NULL || !meta->findCString(kKeyMIMEType, &mime)) {
67*ec779b8eSAndroid Build Coastguard Worker return;
68*ec779b8eSAndroid Build Coastguard Worker }
69*ec779b8eSAndroid Build Coastguard Worker
70*ec779b8eSAndroid Build Coastguard Worker mFormat = meta;
71*ec779b8eSAndroid Build Coastguard Worker
72*ec779b8eSAndroid Build Coastguard Worker if (!strncasecmp("audio/", mime, 6)) {
73*ec779b8eSAndroid Build Coastguard Worker mIsAudio = true;
74*ec779b8eSAndroid Build Coastguard Worker } else if (!strncasecmp("video/", mime, 6)) {
75*ec779b8eSAndroid Build Coastguard Worker mIsVideo = true;
76*ec779b8eSAndroid Build Coastguard Worker } else if (!strncasecmp("text/", mime, 5) || !strncasecmp("application/", mime, 12)) {
77*ec779b8eSAndroid Build Coastguard Worker return;
78*ec779b8eSAndroid Build Coastguard Worker } else {
79*ec779b8eSAndroid Build Coastguard Worker ALOGW("Unsupported mime type: %s", mime);
80*ec779b8eSAndroid Build Coastguard Worker }
81*ec779b8eSAndroid Build Coastguard Worker }
82*ec779b8eSAndroid Build Coastguard Worker
~AnotherPacketSource()83*ec779b8eSAndroid Build Coastguard Worker AnotherPacketSource::~AnotherPacketSource() {
84*ec779b8eSAndroid Build Coastguard Worker }
85*ec779b8eSAndroid Build Coastguard Worker
start(MetaData *)86*ec779b8eSAndroid Build Coastguard Worker status_t AnotherPacketSource::start(MetaData * /* params */) {
87*ec779b8eSAndroid Build Coastguard Worker return OK;
88*ec779b8eSAndroid Build Coastguard Worker }
89*ec779b8eSAndroid Build Coastguard Worker
stop()90*ec779b8eSAndroid Build Coastguard Worker status_t AnotherPacketSource::stop() {
91*ec779b8eSAndroid Build Coastguard Worker return OK;
92*ec779b8eSAndroid Build Coastguard Worker }
93*ec779b8eSAndroid Build Coastguard Worker
getFormat()94*ec779b8eSAndroid Build Coastguard Worker sp<MetaData> AnotherPacketSource::getFormat() {
95*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
96*ec779b8eSAndroid Build Coastguard Worker if (mFormat != NULL) {
97*ec779b8eSAndroid Build Coastguard Worker return mFormat;
98*ec779b8eSAndroid Build Coastguard Worker }
99*ec779b8eSAndroid Build Coastguard Worker
100*ec779b8eSAndroid Build Coastguard Worker List<sp<ABuffer> >::iterator it = mBuffers.begin();
101*ec779b8eSAndroid Build Coastguard Worker while (it != mBuffers.end()) {
102*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> buffer = *it;
103*ec779b8eSAndroid Build Coastguard Worker int32_t discontinuity;
104*ec779b8eSAndroid Build Coastguard Worker if (!buffer->meta()->findInt32("discontinuity", &discontinuity)) {
105*ec779b8eSAndroid Build Coastguard Worker sp<RefBase> object;
106*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findObject("format", &object)) {
107*ec779b8eSAndroid Build Coastguard Worker setFormat(static_cast<MetaData*>(object.get()));
108*ec779b8eSAndroid Build Coastguard Worker return mFormat;
109*ec779b8eSAndroid Build Coastguard Worker }
110*ec779b8eSAndroid Build Coastguard Worker }
111*ec779b8eSAndroid Build Coastguard Worker
112*ec779b8eSAndroid Build Coastguard Worker ++it;
113*ec779b8eSAndroid Build Coastguard Worker }
114*ec779b8eSAndroid Build Coastguard Worker return NULL;
115*ec779b8eSAndroid Build Coastguard Worker }
116*ec779b8eSAndroid Build Coastguard Worker
dequeueAccessUnit(sp<ABuffer> * buffer)117*ec779b8eSAndroid Build Coastguard Worker status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) {
118*ec779b8eSAndroid Build Coastguard Worker buffer->clear();
119*ec779b8eSAndroid Build Coastguard Worker
120*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
121*ec779b8eSAndroid Build Coastguard Worker while (mEOSResult == OK && mBuffers.empty()) {
122*ec779b8eSAndroid Build Coastguard Worker mCondition.wait(mLock);
123*ec779b8eSAndroid Build Coastguard Worker }
124*ec779b8eSAndroid Build Coastguard Worker
125*ec779b8eSAndroid Build Coastguard Worker if (!mBuffers.empty()) {
126*ec779b8eSAndroid Build Coastguard Worker *buffer = *mBuffers.begin();
127*ec779b8eSAndroid Build Coastguard Worker mBuffers.erase(mBuffers.begin());
128*ec779b8eSAndroid Build Coastguard Worker
129*ec779b8eSAndroid Build Coastguard Worker int32_t discontinuity;
130*ec779b8eSAndroid Build Coastguard Worker if ((*buffer)->meta()->findInt32("discontinuity", &discontinuity)) {
131*ec779b8eSAndroid Build Coastguard Worker if (wasFormatChange(discontinuity)) {
132*ec779b8eSAndroid Build Coastguard Worker mFormat.clear();
133*ec779b8eSAndroid Build Coastguard Worker }
134*ec779b8eSAndroid Build Coastguard Worker
135*ec779b8eSAndroid Build Coastguard Worker mDiscontinuitySegments.erase(mDiscontinuitySegments.begin());
136*ec779b8eSAndroid Build Coastguard Worker // CHECK(!mDiscontinuitySegments.empty());
137*ec779b8eSAndroid Build Coastguard Worker return INFO_DISCONTINUITY;
138*ec779b8eSAndroid Build Coastguard Worker }
139*ec779b8eSAndroid Build Coastguard Worker
140*ec779b8eSAndroid Build Coastguard Worker // CHECK(!mDiscontinuitySegments.empty());
141*ec779b8eSAndroid Build Coastguard Worker DiscontinuitySegment &seg = *mDiscontinuitySegments.begin();
142*ec779b8eSAndroid Build Coastguard Worker
143*ec779b8eSAndroid Build Coastguard Worker int64_t timeUs;
144*ec779b8eSAndroid Build Coastguard Worker mLatestDequeuedMeta = (*buffer)->meta()->dup();
145*ec779b8eSAndroid Build Coastguard Worker CHECK(mLatestDequeuedMeta->findInt64("timeUs", &timeUs));
146*ec779b8eSAndroid Build Coastguard Worker if (timeUs > seg.mMaxDequeTimeUs) {
147*ec779b8eSAndroid Build Coastguard Worker seg.mMaxDequeTimeUs = timeUs;
148*ec779b8eSAndroid Build Coastguard Worker }
149*ec779b8eSAndroid Build Coastguard Worker
150*ec779b8eSAndroid Build Coastguard Worker sp<RefBase> object;
151*ec779b8eSAndroid Build Coastguard Worker if ((*buffer)->meta()->findObject("format", &object)) {
152*ec779b8eSAndroid Build Coastguard Worker setFormat(static_cast<MetaData*>(object.get()));
153*ec779b8eSAndroid Build Coastguard Worker }
154*ec779b8eSAndroid Build Coastguard Worker
155*ec779b8eSAndroid Build Coastguard Worker return OK;
156*ec779b8eSAndroid Build Coastguard Worker }
157*ec779b8eSAndroid Build Coastguard Worker
158*ec779b8eSAndroid Build Coastguard Worker return mEOSResult;
159*ec779b8eSAndroid Build Coastguard Worker }
160*ec779b8eSAndroid Build Coastguard Worker
requeueAccessUnit(const sp<ABuffer> & buffer)161*ec779b8eSAndroid Build Coastguard Worker void AnotherPacketSource::requeueAccessUnit(const sp<ABuffer> &buffer) {
162*ec779b8eSAndroid Build Coastguard Worker // TODO: update corresponding book keeping info.
163*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
164*ec779b8eSAndroid Build Coastguard Worker mBuffers.push_front(buffer);
165*ec779b8eSAndroid Build Coastguard Worker }
166*ec779b8eSAndroid Build Coastguard Worker
read(MediaBufferBase ** out,const ReadOptions *)167*ec779b8eSAndroid Build Coastguard Worker status_t AnotherPacketSource::read(
168*ec779b8eSAndroid Build Coastguard Worker MediaBufferBase **out, const ReadOptions *) {
169*ec779b8eSAndroid Build Coastguard Worker *out = NULL;
170*ec779b8eSAndroid Build Coastguard Worker
171*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
172*ec779b8eSAndroid Build Coastguard Worker while (mEOSResult == OK && mBuffers.empty()) {
173*ec779b8eSAndroid Build Coastguard Worker mCondition.wait(mLock);
174*ec779b8eSAndroid Build Coastguard Worker }
175*ec779b8eSAndroid Build Coastguard Worker
176*ec779b8eSAndroid Build Coastguard Worker if (!mBuffers.empty()) {
177*ec779b8eSAndroid Build Coastguard Worker
178*ec779b8eSAndroid Build Coastguard Worker const sp<ABuffer> buffer = *mBuffers.begin();
179*ec779b8eSAndroid Build Coastguard Worker mBuffers.erase(mBuffers.begin());
180*ec779b8eSAndroid Build Coastguard Worker
181*ec779b8eSAndroid Build Coastguard Worker int32_t discontinuity;
182*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
183*ec779b8eSAndroid Build Coastguard Worker if (wasFormatChange(discontinuity)) {
184*ec779b8eSAndroid Build Coastguard Worker mFormat.clear();
185*ec779b8eSAndroid Build Coastguard Worker }
186*ec779b8eSAndroid Build Coastguard Worker
187*ec779b8eSAndroid Build Coastguard Worker mDiscontinuitySegments.erase(mDiscontinuitySegments.begin());
188*ec779b8eSAndroid Build Coastguard Worker // CHECK(!mDiscontinuitySegments.empty());
189*ec779b8eSAndroid Build Coastguard Worker return INFO_DISCONTINUITY;
190*ec779b8eSAndroid Build Coastguard Worker }
191*ec779b8eSAndroid Build Coastguard Worker
192*ec779b8eSAndroid Build Coastguard Worker mLatestDequeuedMeta = buffer->meta()->dup();
193*ec779b8eSAndroid Build Coastguard Worker
194*ec779b8eSAndroid Build Coastguard Worker sp<RefBase> object;
195*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findObject("format", &object)) {
196*ec779b8eSAndroid Build Coastguard Worker setFormat(static_cast<MetaData*>(object.get()));
197*ec779b8eSAndroid Build Coastguard Worker }
198*ec779b8eSAndroid Build Coastguard Worker
199*ec779b8eSAndroid Build Coastguard Worker int64_t timeUs;
200*ec779b8eSAndroid Build Coastguard Worker CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
201*ec779b8eSAndroid Build Coastguard Worker // CHECK(!mDiscontinuitySegments.empty());
202*ec779b8eSAndroid Build Coastguard Worker DiscontinuitySegment &seg = *mDiscontinuitySegments.begin();
203*ec779b8eSAndroid Build Coastguard Worker if (timeUs > seg.mMaxDequeTimeUs) {
204*ec779b8eSAndroid Build Coastguard Worker seg.mMaxDequeTimeUs = timeUs;
205*ec779b8eSAndroid Build Coastguard Worker }
206*ec779b8eSAndroid Build Coastguard Worker
207*ec779b8eSAndroid Build Coastguard Worker MediaBufferBase *mediaBuffer = new MediaBuffer(buffer);
208*ec779b8eSAndroid Build Coastguard Worker MetaDataBase &bufmeta = mediaBuffer->meta_data();
209*ec779b8eSAndroid Build Coastguard Worker
210*ec779b8eSAndroid Build Coastguard Worker bufmeta.setInt64(kKeyTime, timeUs);
211*ec779b8eSAndroid Build Coastguard Worker
212*ec779b8eSAndroid Build Coastguard Worker int32_t isSync;
213*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findInt32("isSync", &isSync)) {
214*ec779b8eSAndroid Build Coastguard Worker bufmeta.setInt32(kKeyIsSyncFrame, isSync);
215*ec779b8eSAndroid Build Coastguard Worker }
216*ec779b8eSAndroid Build Coastguard Worker
217*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> sei;
218*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findBuffer("sei", &sei) && sei != NULL) {
219*ec779b8eSAndroid Build Coastguard Worker bufmeta.setData(kKeySEI, 0, sei->data(), sei->size());
220*ec779b8eSAndroid Build Coastguard Worker }
221*ec779b8eSAndroid Build Coastguard Worker
222*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> mpegUserData;
223*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findBuffer("mpeg-user-data", &mpegUserData) && mpegUserData != NULL) {
224*ec779b8eSAndroid Build Coastguard Worker bufmeta.setData(
225*ec779b8eSAndroid Build Coastguard Worker kKeyMpegUserData, 0, mpegUserData->data(), mpegUserData->size());
226*ec779b8eSAndroid Build Coastguard Worker }
227*ec779b8eSAndroid Build Coastguard Worker
228*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> ap;
229*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findBuffer("audio-presentation-info", &ap) && ap != NULL) {
230*ec779b8eSAndroid Build Coastguard Worker bufmeta.setData(
231*ec779b8eSAndroid Build Coastguard Worker kKeyAudioPresentationInfo, 0, ap->data(), ap->size());
232*ec779b8eSAndroid Build Coastguard Worker }
233*ec779b8eSAndroid Build Coastguard Worker
234*ec779b8eSAndroid Build Coastguard Worker int32_t cryptoMode;
235*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findInt32("cryptoMode", &cryptoMode)) {
236*ec779b8eSAndroid Build Coastguard Worker int32_t cryptoKey;
237*ec779b8eSAndroid Build Coastguard Worker int32_t pesOffset;
238*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> clearBytesBuffer, encBytesBuffer;
239*ec779b8eSAndroid Build Coastguard Worker
240*ec779b8eSAndroid Build Coastguard Worker CHECK(buffer->meta()->findInt32("cryptoKey", &cryptoKey));
241*ec779b8eSAndroid Build Coastguard Worker CHECK(buffer->meta()->findBuffer("clearBytes", &clearBytesBuffer)
242*ec779b8eSAndroid Build Coastguard Worker && clearBytesBuffer != NULL);
243*ec779b8eSAndroid Build Coastguard Worker CHECK(buffer->meta()->findBuffer("encBytes", &encBytesBuffer)
244*ec779b8eSAndroid Build Coastguard Worker && encBytesBuffer != NULL);
245*ec779b8eSAndroid Build Coastguard Worker CHECK(buffer->meta()->findInt32("pesOffset", &pesOffset)
246*ec779b8eSAndroid Build Coastguard Worker && (pesOffset >= 0) && (pesOffset < 65536));
247*ec779b8eSAndroid Build Coastguard Worker
248*ec779b8eSAndroid Build Coastguard Worker bufmeta.setInt32(kKeyCryptoMode, cryptoMode);
249*ec779b8eSAndroid Build Coastguard Worker
250*ec779b8eSAndroid Build Coastguard Worker uint8_t array[16] = {0};
251*ec779b8eSAndroid Build Coastguard Worker bufmeta.setData(kKeyCryptoIV, 0, array, 16);
252*ec779b8eSAndroid Build Coastguard Worker
253*ec779b8eSAndroid Build Coastguard Worker array[0] = (uint8_t) (cryptoKey & 0xff);
254*ec779b8eSAndroid Build Coastguard Worker // array[1] contains PES header flag, which we don't use.
255*ec779b8eSAndroid Build Coastguard Worker // array[2~3] contain the PES offset.
256*ec779b8eSAndroid Build Coastguard Worker array[2] = (uint8_t) (pesOffset & 0xff);
257*ec779b8eSAndroid Build Coastguard Worker array[3] = (uint8_t) ((pesOffset >> 8) & 0xff);
258*ec779b8eSAndroid Build Coastguard Worker
259*ec779b8eSAndroid Build Coastguard Worker bufmeta.setData(kKeyCryptoKey, 0, array, 16);
260*ec779b8eSAndroid Build Coastguard Worker
261*ec779b8eSAndroid Build Coastguard Worker bufmeta.setData(kKeyPlainSizes, 0,
262*ec779b8eSAndroid Build Coastguard Worker clearBytesBuffer->data(), clearBytesBuffer->size());
263*ec779b8eSAndroid Build Coastguard Worker
264*ec779b8eSAndroid Build Coastguard Worker bufmeta.setData(kKeyEncryptedSizes, 0,
265*ec779b8eSAndroid Build Coastguard Worker encBytesBuffer->data(), encBytesBuffer->size());
266*ec779b8eSAndroid Build Coastguard Worker }
267*ec779b8eSAndroid Build Coastguard Worker
268*ec779b8eSAndroid Build Coastguard Worker
269*ec779b8eSAndroid Build Coastguard Worker *out = mediaBuffer;
270*ec779b8eSAndroid Build Coastguard Worker return OK;
271*ec779b8eSAndroid Build Coastguard Worker }
272*ec779b8eSAndroid Build Coastguard Worker
273*ec779b8eSAndroid Build Coastguard Worker return mEOSResult;
274*ec779b8eSAndroid Build Coastguard Worker }
275*ec779b8eSAndroid Build Coastguard Worker
wasFormatChange(int32_t discontinuityType) const276*ec779b8eSAndroid Build Coastguard Worker bool AnotherPacketSource::wasFormatChange(
277*ec779b8eSAndroid Build Coastguard Worker int32_t discontinuityType) const {
278*ec779b8eSAndroid Build Coastguard Worker if (mIsAudio) {
279*ec779b8eSAndroid Build Coastguard Worker return (discontinuityType & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0;
280*ec779b8eSAndroid Build Coastguard Worker }
281*ec779b8eSAndroid Build Coastguard Worker
282*ec779b8eSAndroid Build Coastguard Worker if (mIsVideo) {
283*ec779b8eSAndroid Build Coastguard Worker return (discontinuityType & ATSParser::DISCONTINUITY_VIDEO_FORMAT) != 0;
284*ec779b8eSAndroid Build Coastguard Worker }
285*ec779b8eSAndroid Build Coastguard Worker
286*ec779b8eSAndroid Build Coastguard Worker return false;
287*ec779b8eSAndroid Build Coastguard Worker }
288*ec779b8eSAndroid Build Coastguard Worker
queueAccessUnit(const sp<ABuffer> & buffer)289*ec779b8eSAndroid Build Coastguard Worker void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
290*ec779b8eSAndroid Build Coastguard Worker int32_t damaged;
291*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
292*ec779b8eSAndroid Build Coastguard Worker // LOG(VERBOSE) << "discarding damaged AU";
293*ec779b8eSAndroid Build Coastguard Worker return;
294*ec779b8eSAndroid Build Coastguard Worker }
295*ec779b8eSAndroid Build Coastguard Worker
296*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
297*ec779b8eSAndroid Build Coastguard Worker mBuffers.push_back(buffer);
298*ec779b8eSAndroid Build Coastguard Worker mCondition.signal();
299*ec779b8eSAndroid Build Coastguard Worker
300*ec779b8eSAndroid Build Coastguard Worker int32_t discontinuity;
301*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findInt32("discontinuity", &discontinuity)){
302*ec779b8eSAndroid Build Coastguard Worker ALOGV("queueing a discontinuity with queueAccessUnit");
303*ec779b8eSAndroid Build Coastguard Worker
304*ec779b8eSAndroid Build Coastguard Worker mLastQueuedTimeUs = 0LL;
305*ec779b8eSAndroid Build Coastguard Worker mEOSResult = OK;
306*ec779b8eSAndroid Build Coastguard Worker mLatestEnqueuedMeta = NULL;
307*ec779b8eSAndroid Build Coastguard Worker
308*ec779b8eSAndroid Build Coastguard Worker mDiscontinuitySegments.push_back(DiscontinuitySegment());
309*ec779b8eSAndroid Build Coastguard Worker return;
310*ec779b8eSAndroid Build Coastguard Worker }
311*ec779b8eSAndroid Build Coastguard Worker
312*ec779b8eSAndroid Build Coastguard Worker int64_t lastQueuedTimeUs;
313*ec779b8eSAndroid Build Coastguard Worker CHECK(buffer->meta()->findInt64("timeUs", &lastQueuedTimeUs));
314*ec779b8eSAndroid Build Coastguard Worker mLastQueuedTimeUs = lastQueuedTimeUs;
315*ec779b8eSAndroid Build Coastguard Worker ALOGV("queueAccessUnit timeUs=%" PRIi64 " us (%.2f secs)",
316*ec779b8eSAndroid Build Coastguard Worker mLastQueuedTimeUs, mLastQueuedTimeUs / 1E6);
317*ec779b8eSAndroid Build Coastguard Worker
318*ec779b8eSAndroid Build Coastguard Worker // CHECK(!mDiscontinuitySegments.empty());
319*ec779b8eSAndroid Build Coastguard Worker DiscontinuitySegment &tailSeg = *(--mDiscontinuitySegments.end());
320*ec779b8eSAndroid Build Coastguard Worker if (lastQueuedTimeUs > tailSeg.mMaxEnqueTimeUs) {
321*ec779b8eSAndroid Build Coastguard Worker tailSeg.mMaxEnqueTimeUs = lastQueuedTimeUs;
322*ec779b8eSAndroid Build Coastguard Worker }
323*ec779b8eSAndroid Build Coastguard Worker if (tailSeg.mMaxDequeTimeUs == -1) {
324*ec779b8eSAndroid Build Coastguard Worker tailSeg.mMaxDequeTimeUs = lastQueuedTimeUs;
325*ec779b8eSAndroid Build Coastguard Worker }
326*ec779b8eSAndroid Build Coastguard Worker
327*ec779b8eSAndroid Build Coastguard Worker if (mLatestEnqueuedMeta == NULL) {
328*ec779b8eSAndroid Build Coastguard Worker mLatestEnqueuedMeta = buffer->meta()->dup();
329*ec779b8eSAndroid Build Coastguard Worker } else {
330*ec779b8eSAndroid Build Coastguard Worker int64_t latestTimeUs = 0;
331*ec779b8eSAndroid Build Coastguard Worker int64_t frameDeltaUs = 0;
332*ec779b8eSAndroid Build Coastguard Worker CHECK(mLatestEnqueuedMeta->findInt64("timeUs", &latestTimeUs));
333*ec779b8eSAndroid Build Coastguard Worker if (lastQueuedTimeUs > latestTimeUs) {
334*ec779b8eSAndroid Build Coastguard Worker mLatestEnqueuedMeta = buffer->meta()->dup();
335*ec779b8eSAndroid Build Coastguard Worker frameDeltaUs = lastQueuedTimeUs - latestTimeUs;
336*ec779b8eSAndroid Build Coastguard Worker mLatestEnqueuedMeta->setInt64("durationUs", frameDeltaUs);
337*ec779b8eSAndroid Build Coastguard Worker } else if (!mLatestEnqueuedMeta->findInt64("durationUs", &frameDeltaUs)) {
338*ec779b8eSAndroid Build Coastguard Worker // For B frames
339*ec779b8eSAndroid Build Coastguard Worker frameDeltaUs = latestTimeUs - lastQueuedTimeUs;
340*ec779b8eSAndroid Build Coastguard Worker mLatestEnqueuedMeta->setInt64("durationUs", frameDeltaUs);
341*ec779b8eSAndroid Build Coastguard Worker }
342*ec779b8eSAndroid Build Coastguard Worker }
343*ec779b8eSAndroid Build Coastguard Worker }
344*ec779b8eSAndroid Build Coastguard Worker
clear()345*ec779b8eSAndroid Build Coastguard Worker void AnotherPacketSource::clear() {
346*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
347*ec779b8eSAndroid Build Coastguard Worker
348*ec779b8eSAndroid Build Coastguard Worker mBuffers.clear();
349*ec779b8eSAndroid Build Coastguard Worker mEOSResult = OK;
350*ec779b8eSAndroid Build Coastguard Worker
351*ec779b8eSAndroid Build Coastguard Worker mDiscontinuitySegments.clear();
352*ec779b8eSAndroid Build Coastguard Worker mDiscontinuitySegments.push_back(DiscontinuitySegment());
353*ec779b8eSAndroid Build Coastguard Worker
354*ec779b8eSAndroid Build Coastguard Worker mFormat = NULL;
355*ec779b8eSAndroid Build Coastguard Worker mLatestEnqueuedMeta = NULL;
356*ec779b8eSAndroid Build Coastguard Worker
357*ec779b8eSAndroid Build Coastguard Worker mEstimatedBufferDurationUs = -1;
358*ec779b8eSAndroid Build Coastguard Worker }
359*ec779b8eSAndroid Build Coastguard Worker
queueDiscontinuity(ATSParser::DiscontinuityType type,const sp<AMessage> & extra,bool discard)360*ec779b8eSAndroid Build Coastguard Worker void AnotherPacketSource::queueDiscontinuity(
361*ec779b8eSAndroid Build Coastguard Worker ATSParser::DiscontinuityType type,
362*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &extra,
363*ec779b8eSAndroid Build Coastguard Worker bool discard) {
364*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
365*ec779b8eSAndroid Build Coastguard Worker
366*ec779b8eSAndroid Build Coastguard Worker if (discard) {
367*ec779b8eSAndroid Build Coastguard Worker // Leave only discontinuities in the queue.
368*ec779b8eSAndroid Build Coastguard Worker List<sp<ABuffer> >::iterator it = mBuffers.begin();
369*ec779b8eSAndroid Build Coastguard Worker while (it != mBuffers.end()) {
370*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> oldBuffer = *it;
371*ec779b8eSAndroid Build Coastguard Worker
372*ec779b8eSAndroid Build Coastguard Worker int32_t oldDiscontinuityType;
373*ec779b8eSAndroid Build Coastguard Worker if (!oldBuffer->meta()->findInt32(
374*ec779b8eSAndroid Build Coastguard Worker "discontinuity", &oldDiscontinuityType)) {
375*ec779b8eSAndroid Build Coastguard Worker it = mBuffers.erase(it);
376*ec779b8eSAndroid Build Coastguard Worker continue;
377*ec779b8eSAndroid Build Coastguard Worker }
378*ec779b8eSAndroid Build Coastguard Worker
379*ec779b8eSAndroid Build Coastguard Worker ++it;
380*ec779b8eSAndroid Build Coastguard Worker }
381*ec779b8eSAndroid Build Coastguard Worker
382*ec779b8eSAndroid Build Coastguard Worker for (List<DiscontinuitySegment>::iterator it2 = mDiscontinuitySegments.begin();
383*ec779b8eSAndroid Build Coastguard Worker it2 != mDiscontinuitySegments.end();
384*ec779b8eSAndroid Build Coastguard Worker ++it2) {
385*ec779b8eSAndroid Build Coastguard Worker DiscontinuitySegment &seg = *it2;
386*ec779b8eSAndroid Build Coastguard Worker seg.clear();
387*ec779b8eSAndroid Build Coastguard Worker }
388*ec779b8eSAndroid Build Coastguard Worker
389*ec779b8eSAndroid Build Coastguard Worker }
390*ec779b8eSAndroid Build Coastguard Worker
391*ec779b8eSAndroid Build Coastguard Worker mEOSResult = OK;
392*ec779b8eSAndroid Build Coastguard Worker mLastQueuedTimeUs = 0;
393*ec779b8eSAndroid Build Coastguard Worker mLatestEnqueuedMeta = NULL;
394*ec779b8eSAndroid Build Coastguard Worker
395*ec779b8eSAndroid Build Coastguard Worker if (type == ATSParser::DISCONTINUITY_NONE) {
396*ec779b8eSAndroid Build Coastguard Worker return;
397*ec779b8eSAndroid Build Coastguard Worker }
398*ec779b8eSAndroid Build Coastguard Worker
399*ec779b8eSAndroid Build Coastguard Worker mDiscontinuitySegments.push_back(DiscontinuitySegment());
400*ec779b8eSAndroid Build Coastguard Worker
401*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> buffer = new ABuffer(0);
402*ec779b8eSAndroid Build Coastguard Worker buffer->meta()->setInt32("discontinuity", static_cast<int32_t>(type));
403*ec779b8eSAndroid Build Coastguard Worker buffer->meta()->setMessage("extra", extra);
404*ec779b8eSAndroid Build Coastguard Worker
405*ec779b8eSAndroid Build Coastguard Worker mBuffers.push_back(buffer);
406*ec779b8eSAndroid Build Coastguard Worker mCondition.signal();
407*ec779b8eSAndroid Build Coastguard Worker }
408*ec779b8eSAndroid Build Coastguard Worker
signalEOS(status_t result)409*ec779b8eSAndroid Build Coastguard Worker void AnotherPacketSource::signalEOS(status_t result) {
410*ec779b8eSAndroid Build Coastguard Worker CHECK(result != OK);
411*ec779b8eSAndroid Build Coastguard Worker
412*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
413*ec779b8eSAndroid Build Coastguard Worker mEOSResult = result;
414*ec779b8eSAndroid Build Coastguard Worker mCondition.signal();
415*ec779b8eSAndroid Build Coastguard Worker }
416*ec779b8eSAndroid Build Coastguard Worker
hasBufferAvailable(status_t * finalResult)417*ec779b8eSAndroid Build Coastguard Worker bool AnotherPacketSource::hasBufferAvailable(status_t *finalResult) {
418*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
419*ec779b8eSAndroid Build Coastguard Worker *finalResult = OK;
420*ec779b8eSAndroid Build Coastguard Worker if (!mEnabled) {
421*ec779b8eSAndroid Build Coastguard Worker return false;
422*ec779b8eSAndroid Build Coastguard Worker }
423*ec779b8eSAndroid Build Coastguard Worker if (!mBuffers.empty()) {
424*ec779b8eSAndroid Build Coastguard Worker return true;
425*ec779b8eSAndroid Build Coastguard Worker }
426*ec779b8eSAndroid Build Coastguard Worker
427*ec779b8eSAndroid Build Coastguard Worker *finalResult = mEOSResult;
428*ec779b8eSAndroid Build Coastguard Worker return false;
429*ec779b8eSAndroid Build Coastguard Worker }
430*ec779b8eSAndroid Build Coastguard Worker
hasDataBufferAvailable(status_t * finalResult)431*ec779b8eSAndroid Build Coastguard Worker bool AnotherPacketSource::hasDataBufferAvailable(status_t *finalResult) {
432*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
433*ec779b8eSAndroid Build Coastguard Worker *finalResult = OK;
434*ec779b8eSAndroid Build Coastguard Worker if (!mEnabled) {
435*ec779b8eSAndroid Build Coastguard Worker return false;
436*ec779b8eSAndroid Build Coastguard Worker }
437*ec779b8eSAndroid Build Coastguard Worker List<sp<ABuffer> >::iterator it;
438*ec779b8eSAndroid Build Coastguard Worker for (it = mBuffers.begin(); it != mBuffers.end(); it++) {
439*ec779b8eSAndroid Build Coastguard Worker int32_t discontinuity;
440*ec779b8eSAndroid Build Coastguard Worker if (!(*it)->meta()->findInt32("discontinuity", &discontinuity)) {
441*ec779b8eSAndroid Build Coastguard Worker return true;
442*ec779b8eSAndroid Build Coastguard Worker }
443*ec779b8eSAndroid Build Coastguard Worker }
444*ec779b8eSAndroid Build Coastguard Worker
445*ec779b8eSAndroid Build Coastguard Worker *finalResult = mEOSResult;
446*ec779b8eSAndroid Build Coastguard Worker return false;
447*ec779b8eSAndroid Build Coastguard Worker }
448*ec779b8eSAndroid Build Coastguard Worker
getAvailableBufferCount(status_t * finalResult)449*ec779b8eSAndroid Build Coastguard Worker size_t AnotherPacketSource::getAvailableBufferCount(status_t *finalResult) {
450*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
451*ec779b8eSAndroid Build Coastguard Worker
452*ec779b8eSAndroid Build Coastguard Worker *finalResult = OK;
453*ec779b8eSAndroid Build Coastguard Worker if (!mEnabled) {
454*ec779b8eSAndroid Build Coastguard Worker return 0;
455*ec779b8eSAndroid Build Coastguard Worker }
456*ec779b8eSAndroid Build Coastguard Worker if (!mBuffers.empty()) {
457*ec779b8eSAndroid Build Coastguard Worker return mBuffers.size();
458*ec779b8eSAndroid Build Coastguard Worker }
459*ec779b8eSAndroid Build Coastguard Worker *finalResult = mEOSResult;
460*ec779b8eSAndroid Build Coastguard Worker return 0;
461*ec779b8eSAndroid Build Coastguard Worker }
462*ec779b8eSAndroid Build Coastguard Worker
getBufferedDurationUs(status_t * finalResult)463*ec779b8eSAndroid Build Coastguard Worker int64_t AnotherPacketSource::getBufferedDurationUs(status_t *finalResult) {
464*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
465*ec779b8eSAndroid Build Coastguard Worker *finalResult = mEOSResult;
466*ec779b8eSAndroid Build Coastguard Worker
467*ec779b8eSAndroid Build Coastguard Worker int64_t durationUs = 0;
468*ec779b8eSAndroid Build Coastguard Worker for (List<DiscontinuitySegment>::iterator it = mDiscontinuitySegments.begin();
469*ec779b8eSAndroid Build Coastguard Worker it != mDiscontinuitySegments.end();
470*ec779b8eSAndroid Build Coastguard Worker ++it) {
471*ec779b8eSAndroid Build Coastguard Worker const DiscontinuitySegment &seg = *it;
472*ec779b8eSAndroid Build Coastguard Worker // dequeued access units should be a subset of enqueued access units
473*ec779b8eSAndroid Build Coastguard Worker // CHECK(seg.maxEnqueTimeUs >= seg.mMaxDequeTimeUs);
474*ec779b8eSAndroid Build Coastguard Worker durationUs += (seg.mMaxEnqueTimeUs - seg.mMaxDequeTimeUs);
475*ec779b8eSAndroid Build Coastguard Worker }
476*ec779b8eSAndroid Build Coastguard Worker
477*ec779b8eSAndroid Build Coastguard Worker return durationUs;
478*ec779b8eSAndroid Build Coastguard Worker }
479*ec779b8eSAndroid Build Coastguard Worker
getEstimatedBufferDurationUs()480*ec779b8eSAndroid Build Coastguard Worker int64_t AnotherPacketSource::getEstimatedBufferDurationUs() {
481*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
482*ec779b8eSAndroid Build Coastguard Worker if (mEstimatedBufferDurationUs >= 0) {
483*ec779b8eSAndroid Build Coastguard Worker return mEstimatedBufferDurationUs;
484*ec779b8eSAndroid Build Coastguard Worker }
485*ec779b8eSAndroid Build Coastguard Worker
486*ec779b8eSAndroid Build Coastguard Worker SortedVector<int64_t> maxTimesUs;
487*ec779b8eSAndroid Build Coastguard Worker List<sp<ABuffer> >::iterator it;
488*ec779b8eSAndroid Build Coastguard Worker int64_t t1 = 0, t2 = 0;
489*ec779b8eSAndroid Build Coastguard Worker for (it = mBuffers.begin(); it != mBuffers.end(); ++it) {
490*ec779b8eSAndroid Build Coastguard Worker int64_t timeUs = 0;
491*ec779b8eSAndroid Build Coastguard Worker const sp<ABuffer> &buffer = *it;
492*ec779b8eSAndroid Build Coastguard Worker if (!buffer->meta()->findInt64("timeUs", &timeUs)) {
493*ec779b8eSAndroid Build Coastguard Worker continue;
494*ec779b8eSAndroid Build Coastguard Worker }
495*ec779b8eSAndroid Build Coastguard Worker maxTimesUs.add(timeUs);
496*ec779b8eSAndroid Build Coastguard Worker while (maxTimesUs.size() > 2) {
497*ec779b8eSAndroid Build Coastguard Worker maxTimesUs.removeAt(0);
498*ec779b8eSAndroid Build Coastguard Worker t1 = maxTimesUs.itemAt(0);
499*ec779b8eSAndroid Build Coastguard Worker t2 = maxTimesUs.itemAt(1);
500*ec779b8eSAndroid Build Coastguard Worker }
501*ec779b8eSAndroid Build Coastguard Worker }
502*ec779b8eSAndroid Build Coastguard Worker return mEstimatedBufferDurationUs = t2 - t1;
503*ec779b8eSAndroid Build Coastguard Worker }
504*ec779b8eSAndroid Build Coastguard Worker
nextBufferTime(int64_t * timeUs)505*ec779b8eSAndroid Build Coastguard Worker status_t AnotherPacketSource::nextBufferTime(int64_t *timeUs) {
506*ec779b8eSAndroid Build Coastguard Worker *timeUs = 0;
507*ec779b8eSAndroid Build Coastguard Worker
508*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
509*ec779b8eSAndroid Build Coastguard Worker
510*ec779b8eSAndroid Build Coastguard Worker if (mBuffers.empty()) {
511*ec779b8eSAndroid Build Coastguard Worker return mEOSResult != OK ? mEOSResult : -EWOULDBLOCK;
512*ec779b8eSAndroid Build Coastguard Worker }
513*ec779b8eSAndroid Build Coastguard Worker
514*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> buffer = *mBuffers.begin();
515*ec779b8eSAndroid Build Coastguard Worker CHECK(buffer->meta()->findInt64("timeUs", timeUs));
516*ec779b8eSAndroid Build Coastguard Worker
517*ec779b8eSAndroid Build Coastguard Worker return OK;
518*ec779b8eSAndroid Build Coastguard Worker }
519*ec779b8eSAndroid Build Coastguard Worker
isFinished(int64_t duration) const520*ec779b8eSAndroid Build Coastguard Worker bool AnotherPacketSource::isFinished(int64_t duration) const {
521*ec779b8eSAndroid Build Coastguard Worker if (duration > 0) {
522*ec779b8eSAndroid Build Coastguard Worker int64_t diff = duration - mLastQueuedTimeUs;
523*ec779b8eSAndroid Build Coastguard Worker if (diff < kNearEOSMarkUs && diff > -kNearEOSMarkUs) {
524*ec779b8eSAndroid Build Coastguard Worker ALOGV("Detecting EOS due to near end");
525*ec779b8eSAndroid Build Coastguard Worker return true;
526*ec779b8eSAndroid Build Coastguard Worker }
527*ec779b8eSAndroid Build Coastguard Worker }
528*ec779b8eSAndroid Build Coastguard Worker return (mEOSResult != OK);
529*ec779b8eSAndroid Build Coastguard Worker }
530*ec779b8eSAndroid Build Coastguard Worker
getLatestEnqueuedMeta()531*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> AnotherPacketSource::getLatestEnqueuedMeta() {
532*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
533*ec779b8eSAndroid Build Coastguard Worker return mLatestEnqueuedMeta;
534*ec779b8eSAndroid Build Coastguard Worker }
535*ec779b8eSAndroid Build Coastguard Worker
getLatestDequeuedMeta()536*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> AnotherPacketSource::getLatestDequeuedMeta() {
537*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
538*ec779b8eSAndroid Build Coastguard Worker return mLatestDequeuedMeta;
539*ec779b8eSAndroid Build Coastguard Worker }
540*ec779b8eSAndroid Build Coastguard Worker
enable(bool enable)541*ec779b8eSAndroid Build Coastguard Worker void AnotherPacketSource::enable(bool enable) {
542*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
543*ec779b8eSAndroid Build Coastguard Worker mEnabled = enable;
544*ec779b8eSAndroid Build Coastguard Worker }
545*ec779b8eSAndroid Build Coastguard Worker
546*ec779b8eSAndroid Build Coastguard Worker /*
547*ec779b8eSAndroid Build Coastguard Worker * returns the sample meta that's delayUs after queue head
548*ec779b8eSAndroid Build Coastguard Worker * (NULL if such sample is unavailable)
549*ec779b8eSAndroid Build Coastguard Worker */
getMetaAfterLastDequeued(int64_t delayUs)550*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> AnotherPacketSource::getMetaAfterLastDequeued(int64_t delayUs) {
551*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
552*ec779b8eSAndroid Build Coastguard Worker int64_t firstUs = -1;
553*ec779b8eSAndroid Build Coastguard Worker int64_t lastUs = -1;
554*ec779b8eSAndroid Build Coastguard Worker int64_t durationUs = 0;
555*ec779b8eSAndroid Build Coastguard Worker
556*ec779b8eSAndroid Build Coastguard Worker List<sp<ABuffer> >::iterator it;
557*ec779b8eSAndroid Build Coastguard Worker for (it = mBuffers.begin(); it != mBuffers.end(); ++it) {
558*ec779b8eSAndroid Build Coastguard Worker const sp<ABuffer> &buffer = *it;
559*ec779b8eSAndroid Build Coastguard Worker int32_t discontinuity;
560*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
561*ec779b8eSAndroid Build Coastguard Worker durationUs += lastUs - firstUs;
562*ec779b8eSAndroid Build Coastguard Worker firstUs = -1;
563*ec779b8eSAndroid Build Coastguard Worker lastUs = -1;
564*ec779b8eSAndroid Build Coastguard Worker continue;
565*ec779b8eSAndroid Build Coastguard Worker }
566*ec779b8eSAndroid Build Coastguard Worker int64_t timeUs;
567*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findInt64("timeUs", &timeUs)) {
568*ec779b8eSAndroid Build Coastguard Worker if (firstUs < 0) {
569*ec779b8eSAndroid Build Coastguard Worker firstUs = timeUs;
570*ec779b8eSAndroid Build Coastguard Worker }
571*ec779b8eSAndroid Build Coastguard Worker if (lastUs < 0 || timeUs > lastUs) {
572*ec779b8eSAndroid Build Coastguard Worker lastUs = timeUs;
573*ec779b8eSAndroid Build Coastguard Worker }
574*ec779b8eSAndroid Build Coastguard Worker if (durationUs + (lastUs - firstUs) >= delayUs) {
575*ec779b8eSAndroid Build Coastguard Worker return buffer->meta();
576*ec779b8eSAndroid Build Coastguard Worker }
577*ec779b8eSAndroid Build Coastguard Worker }
578*ec779b8eSAndroid Build Coastguard Worker }
579*ec779b8eSAndroid Build Coastguard Worker return NULL;
580*ec779b8eSAndroid Build Coastguard Worker }
581*ec779b8eSAndroid Build Coastguard Worker
582*ec779b8eSAndroid Build Coastguard Worker /*
583*ec779b8eSAndroid Build Coastguard Worker * removes samples with time equal or after meta
584*ec779b8eSAndroid Build Coastguard Worker */
trimBuffersAfterMeta(const sp<AMessage> & meta)585*ec779b8eSAndroid Build Coastguard Worker void AnotherPacketSource::trimBuffersAfterMeta(
586*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &meta) {
587*ec779b8eSAndroid Build Coastguard Worker if (meta == NULL) {
588*ec779b8eSAndroid Build Coastguard Worker ALOGW("trimming with NULL meta, ignoring");
589*ec779b8eSAndroid Build Coastguard Worker return;
590*ec779b8eSAndroid Build Coastguard Worker }
591*ec779b8eSAndroid Build Coastguard Worker
592*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
593*ec779b8eSAndroid Build Coastguard Worker if (mBuffers.empty()) {
594*ec779b8eSAndroid Build Coastguard Worker return;
595*ec779b8eSAndroid Build Coastguard Worker }
596*ec779b8eSAndroid Build Coastguard Worker
597*ec779b8eSAndroid Build Coastguard Worker HLSTime stopTime(meta);
598*ec779b8eSAndroid Build Coastguard Worker ALOGV("trimBuffersAfterMeta: discontinuitySeq %d, timeUs %lld",
599*ec779b8eSAndroid Build Coastguard Worker stopTime.mSeq, (long long)stopTime.mTimeUs);
600*ec779b8eSAndroid Build Coastguard Worker
601*ec779b8eSAndroid Build Coastguard Worker List<sp<ABuffer> >::iterator it;
602*ec779b8eSAndroid Build Coastguard Worker List<DiscontinuitySegment >::iterator it2;
603*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> newLatestEnqueuedMeta = NULL;
604*ec779b8eSAndroid Build Coastguard Worker int64_t newLastQueuedTimeUs = 0;
605*ec779b8eSAndroid Build Coastguard Worker for (it = mBuffers.begin(), it2 = mDiscontinuitySegments.begin(); it != mBuffers.end(); ++it) {
606*ec779b8eSAndroid Build Coastguard Worker const sp<ABuffer> &buffer = *it;
607*ec779b8eSAndroid Build Coastguard Worker int32_t discontinuity;
608*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
609*ec779b8eSAndroid Build Coastguard Worker // CHECK(it2 != mDiscontinuitySegments.end());
610*ec779b8eSAndroid Build Coastguard Worker ++it2;
611*ec779b8eSAndroid Build Coastguard Worker continue;
612*ec779b8eSAndroid Build Coastguard Worker }
613*ec779b8eSAndroid Build Coastguard Worker
614*ec779b8eSAndroid Build Coastguard Worker HLSTime curTime(buffer->meta());
615*ec779b8eSAndroid Build Coastguard Worker if (!(curTime < stopTime)) {
616*ec779b8eSAndroid Build Coastguard Worker ALOGV("trimming from %lld (inclusive) to end",
617*ec779b8eSAndroid Build Coastguard Worker (long long)curTime.mTimeUs);
618*ec779b8eSAndroid Build Coastguard Worker break;
619*ec779b8eSAndroid Build Coastguard Worker }
620*ec779b8eSAndroid Build Coastguard Worker newLatestEnqueuedMeta = buffer->meta();
621*ec779b8eSAndroid Build Coastguard Worker newLastQueuedTimeUs = curTime.mTimeUs;
622*ec779b8eSAndroid Build Coastguard Worker }
623*ec779b8eSAndroid Build Coastguard Worker
624*ec779b8eSAndroid Build Coastguard Worker mBuffers.erase(it, mBuffers.end());
625*ec779b8eSAndroid Build Coastguard Worker mLatestEnqueuedMeta = newLatestEnqueuedMeta;
626*ec779b8eSAndroid Build Coastguard Worker mLastQueuedTimeUs = newLastQueuedTimeUs;
627*ec779b8eSAndroid Build Coastguard Worker
628*ec779b8eSAndroid Build Coastguard Worker DiscontinuitySegment &seg = *it2;
629*ec779b8eSAndroid Build Coastguard Worker if (newLatestEnqueuedMeta != NULL) {
630*ec779b8eSAndroid Build Coastguard Worker seg.mMaxEnqueTimeUs = newLastQueuedTimeUs;
631*ec779b8eSAndroid Build Coastguard Worker } else {
632*ec779b8eSAndroid Build Coastguard Worker seg.clear();
633*ec779b8eSAndroid Build Coastguard Worker }
634*ec779b8eSAndroid Build Coastguard Worker mDiscontinuitySegments.erase(++it2, mDiscontinuitySegments.end());
635*ec779b8eSAndroid Build Coastguard Worker }
636*ec779b8eSAndroid Build Coastguard Worker
637*ec779b8eSAndroid Build Coastguard Worker /*
638*ec779b8eSAndroid Build Coastguard Worker * removes samples with time equal or before meta;
639*ec779b8eSAndroid Build Coastguard Worker * returns first sample left in the queue.
640*ec779b8eSAndroid Build Coastguard Worker *
641*ec779b8eSAndroid Build Coastguard Worker * (for AVC, if trim happens, the samples left will always start
642*ec779b8eSAndroid Build Coastguard Worker * at next IDR.)
643*ec779b8eSAndroid Build Coastguard Worker */
trimBuffersBeforeMeta(const sp<AMessage> & meta)644*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> AnotherPacketSource::trimBuffersBeforeMeta(
645*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &meta) {
646*ec779b8eSAndroid Build Coastguard Worker HLSTime startTime(meta);
647*ec779b8eSAndroid Build Coastguard Worker ALOGV("trimBuffersBeforeMeta: discontinuitySeq %d, timeUs %lld",
648*ec779b8eSAndroid Build Coastguard Worker startTime.mSeq, (long long)startTime.mTimeUs);
649*ec779b8eSAndroid Build Coastguard Worker
650*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> firstMeta;
651*ec779b8eSAndroid Build Coastguard Worker int64_t firstTimeUs = -1;
652*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock autoLock(mLock);
653*ec779b8eSAndroid Build Coastguard Worker if (mBuffers.empty()) {
654*ec779b8eSAndroid Build Coastguard Worker return NULL;
655*ec779b8eSAndroid Build Coastguard Worker }
656*ec779b8eSAndroid Build Coastguard Worker
657*ec779b8eSAndroid Build Coastguard Worker sp<MetaData> format;
658*ec779b8eSAndroid Build Coastguard Worker bool isAvc = false;
659*ec779b8eSAndroid Build Coastguard Worker
660*ec779b8eSAndroid Build Coastguard Worker List<sp<ABuffer> >::iterator it;
661*ec779b8eSAndroid Build Coastguard Worker for (it = mBuffers.begin(); it != mBuffers.end(); ++it) {
662*ec779b8eSAndroid Build Coastguard Worker const sp<ABuffer> &buffer = *it;
663*ec779b8eSAndroid Build Coastguard Worker int32_t discontinuity;
664*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
665*ec779b8eSAndroid Build Coastguard Worker mDiscontinuitySegments.erase(mDiscontinuitySegments.begin());
666*ec779b8eSAndroid Build Coastguard Worker // CHECK(!mDiscontinuitySegments.empty());
667*ec779b8eSAndroid Build Coastguard Worker format = NULL;
668*ec779b8eSAndroid Build Coastguard Worker isAvc = false;
669*ec779b8eSAndroid Build Coastguard Worker continue;
670*ec779b8eSAndroid Build Coastguard Worker }
671*ec779b8eSAndroid Build Coastguard Worker if (format == NULL) {
672*ec779b8eSAndroid Build Coastguard Worker sp<RefBase> object;
673*ec779b8eSAndroid Build Coastguard Worker if (buffer->meta()->findObject("format", &object)) {
674*ec779b8eSAndroid Build Coastguard Worker const char* mime;
675*ec779b8eSAndroid Build Coastguard Worker format = static_cast<MetaData*>(object.get());
676*ec779b8eSAndroid Build Coastguard Worker isAvc = format != NULL
677*ec779b8eSAndroid Build Coastguard Worker && format->findCString(kKeyMIMEType, &mime)
678*ec779b8eSAndroid Build Coastguard Worker && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
679*ec779b8eSAndroid Build Coastguard Worker }
680*ec779b8eSAndroid Build Coastguard Worker }
681*ec779b8eSAndroid Build Coastguard Worker if (isAvc && !IsIDR(buffer->data(), buffer->size())) {
682*ec779b8eSAndroid Build Coastguard Worker continue;
683*ec779b8eSAndroid Build Coastguard Worker }
684*ec779b8eSAndroid Build Coastguard Worker
685*ec779b8eSAndroid Build Coastguard Worker HLSTime curTime(buffer->meta());
686*ec779b8eSAndroid Build Coastguard Worker if (startTime < curTime) {
687*ec779b8eSAndroid Build Coastguard Worker ALOGV("trimming from beginning to %lld (not inclusive)",
688*ec779b8eSAndroid Build Coastguard Worker (long long)curTime.mTimeUs);
689*ec779b8eSAndroid Build Coastguard Worker firstMeta = buffer->meta();
690*ec779b8eSAndroid Build Coastguard Worker firstTimeUs = curTime.mTimeUs;
691*ec779b8eSAndroid Build Coastguard Worker break;
692*ec779b8eSAndroid Build Coastguard Worker }
693*ec779b8eSAndroid Build Coastguard Worker }
694*ec779b8eSAndroid Build Coastguard Worker mBuffers.erase(mBuffers.begin(), it);
695*ec779b8eSAndroid Build Coastguard Worker mLatestDequeuedMeta = NULL;
696*ec779b8eSAndroid Build Coastguard Worker
697*ec779b8eSAndroid Build Coastguard Worker // CHECK(!mDiscontinuitySegments.empty());
698*ec779b8eSAndroid Build Coastguard Worker DiscontinuitySegment &seg = *mDiscontinuitySegments.begin();
699*ec779b8eSAndroid Build Coastguard Worker if (firstTimeUs >= 0) {
700*ec779b8eSAndroid Build Coastguard Worker seg.mMaxDequeTimeUs = firstTimeUs;
701*ec779b8eSAndroid Build Coastguard Worker } else {
702*ec779b8eSAndroid Build Coastguard Worker seg.clear();
703*ec779b8eSAndroid Build Coastguard Worker }
704*ec779b8eSAndroid Build Coastguard Worker
705*ec779b8eSAndroid Build Coastguard Worker return firstMeta;
706*ec779b8eSAndroid Build Coastguard Worker }
707*ec779b8eSAndroid Build Coastguard Worker
708*ec779b8eSAndroid Build Coastguard Worker } // namespace android
709