xref: /aosp_15_r20/frameworks/av/media/module/mpeg2ts/AnotherPacketSource.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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