blob: 27a94fd2736c3b167a2d6f349eab524d122a9f97 [file] [log] [blame]
Andreas Hubercda17c62010-06-07 13:05:37 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Robert Shih309aa8b2014-07-29 18:34:36 -070017//#define LOG_NDEBUG 0
18#define LOG_TAG "AnotherPacketSource"
19
Andreas Hubercda17c62010-06-07 13:05:37 -070020#include "AnotherPacketSource.h"
21
22#include <media/stagefright/foundation/ABuffer.h>
23#include <media/stagefright/foundation/ADebug.h>
24#include <media/stagefright/foundation/AMessage.h>
25#include <media/stagefright/foundation/AString.h>
26#include <media/stagefright/foundation/hexdump.h>
Dongwon Kangd91dc5a2017-10-10 00:07:09 -070027#include <media/stagefright/foundation/avc_utils.h>
Andreas Hubercda17c62010-06-07 13:05:37 -070028#include <media/stagefright/MediaBuffer.h>
29#include <media/stagefright/MediaDefs.h>
30#include <media/stagefright/MetaData.h>
Chong Zhangd47dfcb2015-03-27 15:53:45 -070031#include <media/stagefright/Utils.h>
Andreas Hubercda17c62010-06-07 13:05:37 -070032#include <utils/Vector.h>
33
Colin Crossb4a7a2d2014-03-19 16:59:00 -070034#include <inttypes.h>
35
Andreas Hubercda17c62010-06-07 13:05:37 -070036namespace android {
37
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -080038const int64_t kNearEOSMarkUs = 2000000LL; // 2 secs
Roger Jönssonb50e83e2013-01-21 16:26:41 +010039
Andreas Hubercda17c62010-06-07 13:05:37 -070040AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta)
Andreas Huber6e3d3112011-11-28 12:36:11 -080041 : mIsAudio(false),
Robert Shih3423bbd2014-07-16 15:47:09 -070042 mIsVideo(false),
Chong Zhang7c870802015-03-17 16:27:56 -070043 mEnabled(true),
Andreas Huber14f76722013-01-15 09:04:18 -080044 mFormat(NULL),
Roger Jönssonb50e83e2013-01-21 16:26:41 +010045 mLastQueuedTimeUs(0),
Robert Shih82e14702016-11-17 11:24:29 -080046 mEstimatedBufferDurationUs(-1),
Robert Shih69634502014-01-23 14:25:32 -080047 mEOSResult(OK),
Robert Shih309aa8b2014-07-29 18:34:36 -070048 mLatestEnqueuedMeta(NULL),
Robert Shih0dd229b2015-03-06 16:45:59 -080049 mLatestDequeuedMeta(NULL) {
Andreas Huber14f76722013-01-15 09:04:18 -080050 setFormat(meta);
Robert Shih0dd229b2015-03-06 16:45:59 -080051
52 mDiscontinuitySegments.push_back(DiscontinuitySegment());
Andreas Huber14f76722013-01-15 09:04:18 -080053}
54
55void AnotherPacketSource::setFormat(const sp<MetaData> &meta) {
Chong Zhangc4547ba2015-03-06 14:00:54 -080056 if (mFormat != NULL) {
57 // Only allowed to be set once. Requires explicit clear to reset.
58 return;
59 }
Andreas Huber14f76722013-01-15 09:04:18 -080060
61 mIsAudio = false;
Robert Shih3423bbd2014-07-16 15:47:09 -070062 mIsVideo = false;
Chong Zhang25cb3ca2020-12-21 11:01:13 -080063 const char *mime;
Andreas Huber14f76722013-01-15 09:04:18 -080064
Chong Zhang25cb3ca2020-12-21 11:01:13 -080065 // Do not use meta if no mime.
66 if (meta == NULL || !meta->findCString(kKeyMIMEType, &mime)) {
Andreas Huber14f76722013-01-15 09:04:18 -080067 return;
68 }
69
70 mFormat = meta;
Andreas Huber6e3d3112011-11-28 12:36:11 -080071
72 if (!strncasecmp("audio/", mime, 6)) {
73 mIsAudio = true;
Chong Zhang25cb3ca2020-12-21 11:01:13 -080074 } else if (!strncasecmp("video/", mime, 6)) {
Robert Shih3423bbd2014-07-16 15:47:09 -070075 mIsVideo = true;
Chong Zhang25cb3ca2020-12-21 11:01:13 -080076 } else if (!strncasecmp("text/", mime, 5) || !strncasecmp("application/", mime, 12)) {
77 return;
Andreas Huber6e3d3112011-11-28 12:36:11 -080078 } else {
Chong Zhang25cb3ca2020-12-21 11:01:13 -080079 ALOGW("Unsupported mime type: %s", mime);
Andreas Huber6e3d3112011-11-28 12:36:11 -080080 }
Andreas Hubercda17c62010-06-07 13:05:37 -070081}
82
83AnotherPacketSource::~AnotherPacketSource() {
84}
85
Andreas Huber84333e02014-02-07 15:36:10 -080086status_t AnotherPacketSource::start(MetaData * /* params */) {
Andreas Hubercda17c62010-06-07 13:05:37 -070087 return OK;
88}
89
90status_t AnotherPacketSource::stop() {
91 return OK;
92}
93
94sp<MetaData> AnotherPacketSource::getFormat() {
Lajos Molnarfd9b01b2013-12-17 14:10:46 -080095 Mutex::Autolock autoLock(mLock);
96 if (mFormat != NULL) {
97 return mFormat;
98 }
99
100 List<sp<ABuffer> >::iterator it = mBuffers.begin();
101 while (it != mBuffers.end()) {
102 sp<ABuffer> buffer = *it;
103 int32_t discontinuity;
Chong Zhang5bb7e182015-03-08 16:03:10 -0700104 if (!buffer->meta()->findInt32("discontinuity", &discontinuity)) {
105 sp<RefBase> object;
106 if (buffer->meta()->findObject("format", &object)) {
Chong Zhangc4547ba2015-03-06 14:00:54 -0800107 setFormat(static_cast<MetaData*>(object.get()));
108 return mFormat;
Chong Zhang5bb7e182015-03-08 16:03:10 -0700109 }
Lajos Molnarfd9b01b2013-12-17 14:10:46 -0800110 }
111
112 ++it;
113 }
114 return NULL;
Andreas Hubercda17c62010-06-07 13:05:37 -0700115}
116
Andreas Huberf9334412010-12-15 15:17:42 -0800117status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) {
118 buffer->clear();
119
120 Mutex::Autolock autoLock(mLock);
121 while (mEOSResult == OK && mBuffers.empty()) {
122 mCondition.wait(mLock);
123 }
124
125 if (!mBuffers.empty()) {
126 *buffer = *mBuffers.begin();
127 mBuffers.erase(mBuffers.begin());
128
129 int32_t discontinuity;
Andreas Huber5bc087c2010-12-23 10:27:40 -0800130 if ((*buffer)->meta()->findInt32("discontinuity", &discontinuity)) {
Andreas Huber6e3d3112011-11-28 12:36:11 -0800131 if (wasFormatChange(discontinuity)) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800132 mFormat.clear();
133 }
134
Robert Shih0dd229b2015-03-06 16:45:59 -0800135 mDiscontinuitySegments.erase(mDiscontinuitySegments.begin());
136 // CHECK(!mDiscontinuitySegments.empty());
Andreas Huberf9334412010-12-15 15:17:42 -0800137 return INFO_DISCONTINUITY;
138 }
139
Robert Shih0dd229b2015-03-06 16:45:59 -0800140 // CHECK(!mDiscontinuitySegments.empty());
141 DiscontinuitySegment &seg = *mDiscontinuitySegments.begin();
142
143 int64_t timeUs;
Robert Shih309aa8b2014-07-29 18:34:36 -0700144 mLatestDequeuedMeta = (*buffer)->meta()->dup();
Robert Shih0dd229b2015-03-06 16:45:59 -0800145 CHECK(mLatestDequeuedMeta->findInt64("timeUs", &timeUs));
146 if (timeUs > seg.mMaxDequeTimeUs) {
147 seg.mMaxDequeTimeUs = timeUs;
148 }
Robert Shih309aa8b2014-07-29 18:34:36 -0700149
Lajos Molnarfd9b01b2013-12-17 14:10:46 -0800150 sp<RefBase> object;
151 if ((*buffer)->meta()->findObject("format", &object)) {
Chong Zhangc4547ba2015-03-06 14:00:54 -0800152 setFormat(static_cast<MetaData*>(object.get()));
Lajos Molnarfd9b01b2013-12-17 14:10:46 -0800153 }
154
Andreas Huberf9334412010-12-15 15:17:42 -0800155 return OK;
156 }
157
158 return mEOSResult;
159}
160
Robert Shih08528432015-04-08 09:06:54 -0700161void AnotherPacketSource::requeueAccessUnit(const sp<ABuffer> &buffer) {
162 // TODO: update corresponding book keeping info.
163 Mutex::Autolock autoLock(mLock);
164 mBuffers.push_front(buffer);
165}
166
Andreas Hubercda17c62010-06-07 13:05:37 -0700167status_t AnotherPacketSource::read(
Dongwon Kang1889c3e2018-02-01 13:44:57 -0800168 MediaBufferBase **out, const ReadOptions *) {
Andreas Hubercda17c62010-06-07 13:05:37 -0700169 *out = NULL;
170
171 Mutex::Autolock autoLock(mLock);
172 while (mEOSResult == OK && mBuffers.empty()) {
173 mCondition.wait(mLock);
174 }
175
176 if (!mBuffers.empty()) {
Robert Shih309aa8b2014-07-29 18:34:36 -0700177
Andreas Hubercda17c62010-06-07 13:05:37 -0700178 const sp<ABuffer> buffer = *mBuffers.begin();
Andreas Hubercda17c62010-06-07 13:05:37 -0700179 mBuffers.erase(mBuffers.begin());
Andreas Huber2a4d22d2010-09-08 14:32:20 -0700180
181 int32_t discontinuity;
Andreas Huber5bc087c2010-12-23 10:27:40 -0800182 if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
Andreas Huber6e3d3112011-11-28 12:36:11 -0800183 if (wasFormatChange(discontinuity)) {
Andreas Huber5bc087c2010-12-23 10:27:40 -0800184 mFormat.clear();
185 }
186
Robert Shih0dd229b2015-03-06 16:45:59 -0800187 mDiscontinuitySegments.erase(mDiscontinuitySegments.begin());
188 // CHECK(!mDiscontinuitySegments.empty());
Andreas Huber2a4d22d2010-09-08 14:32:20 -0700189 return INFO_DISCONTINUITY;
Andreas Huber2a4d22d2010-09-08 14:32:20 -0700190 }
Lajos Molnarfd9b01b2013-12-17 14:10:46 -0800191
Chong Zhang7c870802015-03-17 16:27:56 -0700192 mLatestDequeuedMeta = buffer->meta()->dup();
193
Lajos Molnarfd9b01b2013-12-17 14:10:46 -0800194 sp<RefBase> object;
195 if (buffer->meta()->findObject("format", &object)) {
Chong Zhangc4547ba2015-03-06 14:00:54 -0800196 setFormat(static_cast<MetaData*>(object.get()));
Lajos Molnarfd9b01b2013-12-17 14:10:46 -0800197 }
198
199 int64_t timeUs;
200 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
Robert Shih0dd229b2015-03-06 16:45:59 -0800201 // CHECK(!mDiscontinuitySegments.empty());
202 DiscontinuitySegment &seg = *mDiscontinuitySegments.begin();
203 if (timeUs > seg.mMaxDequeTimeUs) {
204 seg.mMaxDequeTimeUs = timeUs;
205 }
Lajos Molnarfd9b01b2013-12-17 14:10:46 -0800206
Dongwon Kang1889c3e2018-02-01 13:44:57 -0800207 MediaBufferBase *mediaBuffer = new MediaBuffer(buffer);
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800208 MetaDataBase &bufmeta = mediaBuffer->meta_data();
Lajos Molnarfd9b01b2013-12-17 14:10:46 -0800209
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800210 bufmeta.setInt64(kKeyTime, timeUs);
Lajos Molnarfd9b01b2013-12-17 14:10:46 -0800211
Terry Heo37746af2015-03-25 17:38:27 +0900212 int32_t isSync;
213 if (buffer->meta()->findInt32("isSync", &isSync)) {
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800214 bufmeta.setInt32(kKeyIsSyncFrame, isSync);
Terry Heo37746af2015-03-25 17:38:27 +0900215 }
216
Robert Shihf8bd8512015-04-23 16:39:18 -0700217 sp<ABuffer> sei;
218 if (buffer->meta()->findBuffer("sei", &sei) && sei != NULL) {
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800219 bufmeta.setData(kKeySEI, 0, sei->data(), sei->size());
Robert Shihf8bd8512015-04-23 16:39:18 -0700220 }
221
Jaesung Chung3694d7c2015-10-21 11:41:38 +0900222 sp<ABuffer> mpegUserData;
Robert Shihd83d4f42018-02-24 19:02:46 -0800223 if (buffer->meta()->findBuffer("mpeg-user-data", &mpegUserData) && mpegUserData != NULL) {
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800224 bufmeta.setData(
Jaesung Chung3694d7c2015-10-21 11:41:38 +0900225 kKeyMpegUserData, 0, mpegUserData->data(), mpegUserData->size());
226 }
227
Sampath Shettyc6148a62018-12-18 15:50:43 +1100228 sp<ABuffer> ap;
229 if (buffer->meta()->findBuffer("audio-presentation-info", &ap) && ap != NULL) {
230 bufmeta.setData(
231 kKeyAudioPresentationInfo, 0, ap->data(), ap->size());
232 }
233
Chong Zhang3b2847f2017-01-18 17:43:03 -0800234 int32_t cryptoMode;
235 if (buffer->meta()->findInt32("cryptoMode", &cryptoMode)) {
236 int32_t cryptoKey;
Chong Zhangb2451bb2018-07-12 12:19:12 -0700237 int32_t pesOffset;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800238 sp<ABuffer> clearBytesBuffer, encBytesBuffer;
239
240 CHECK(buffer->meta()->findInt32("cryptoKey", &cryptoKey));
241 CHECK(buffer->meta()->findBuffer("clearBytes", &clearBytesBuffer)
242 && clearBytesBuffer != NULL);
243 CHECK(buffer->meta()->findBuffer("encBytes", &encBytesBuffer)
244 && encBytesBuffer != NULL);
Chong Zhangb2451bb2018-07-12 12:19:12 -0700245 CHECK(buffer->meta()->findInt32("pesOffset", &pesOffset)
246 && (pesOffset >= 0) && (pesOffset < 65536));
Chong Zhang3b2847f2017-01-18 17:43:03 -0800247
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800248 bufmeta.setInt32(kKeyCryptoMode, cryptoMode);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800249
250 uint8_t array[16] = {0};
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800251 bufmeta.setData(kKeyCryptoIV, 0, array, 16);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800252
253 array[0] = (uint8_t) (cryptoKey & 0xff);
Chong Zhangb2451bb2018-07-12 12:19:12 -0700254 // array[1] contains PES header flag, which we don't use.
255 // array[2~3] contain the PES offset.
256 array[2] = (uint8_t) (pesOffset & 0xff);
257 array[3] = (uint8_t) ((pesOffset >> 8) & 0xff);
258
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800259 bufmeta.setData(kKeyCryptoKey, 0, array, 16);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800260
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800261 bufmeta.setData(kKeyPlainSizes, 0,
Chong Zhang3b2847f2017-01-18 17:43:03 -0800262 clearBytesBuffer->data(), clearBytesBuffer->size());
263
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800264 bufmeta.setData(kKeyEncryptedSizes, 0,
Chong Zhang3b2847f2017-01-18 17:43:03 -0800265 encBytesBuffer->data(), encBytesBuffer->size());
266 }
267
268
Lajos Molnarfd9b01b2013-12-17 14:10:46 -0800269 *out = mediaBuffer;
270 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -0700271 }
272
273 return mEOSResult;
274}
275
Andreas Huber6e3d3112011-11-28 12:36:11 -0800276bool AnotherPacketSource::wasFormatChange(
277 int32_t discontinuityType) const {
278 if (mIsAudio) {
279 return (discontinuityType & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0;
280 }
281
Robert Shih3423bbd2014-07-16 15:47:09 -0700282 if (mIsVideo) {
283 return (discontinuityType & ATSParser::DISCONTINUITY_VIDEO_FORMAT) != 0;
284 }
285
286 return false;
Andreas Huber6e3d3112011-11-28 12:36:11 -0800287}
288
Andreas Hubercda17c62010-06-07 13:05:37 -0700289void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
290 int32_t damaged;
291 if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
292 // LOG(VERBOSE) << "discarding damaged AU";
293 return;
294 }
295
296 Mutex::Autolock autoLock(mLock);
297 mBuffers.push_back(buffer);
298 mCondition.signal();
Robert Shih69634502014-01-23 14:25:32 -0800299
Robert Shih0ad776d2014-08-29 18:02:56 -0700300 int32_t discontinuity;
Robert Shih0dd229b2015-03-06 16:45:59 -0800301 if (buffer->meta()->findInt32("discontinuity", &discontinuity)){
302 ALOGV("queueing a discontinuity with queueAccessUnit");
303
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800304 mLastQueuedTimeUs = 0LL;
Chong Zhang7c870802015-03-17 16:27:56 -0700305 mEOSResult = OK;
306 mLatestEnqueuedMeta = NULL;
Robert Shih0dd229b2015-03-06 16:45:59 -0800307
308 mDiscontinuitySegments.push_back(DiscontinuitySegment());
Chong Zhang7c870802015-03-17 16:27:56 -0700309 return;
Robert Shih0ad776d2014-08-29 18:02:56 -0700310 }
311
Chong Zhang7c870802015-03-17 16:27:56 -0700312 int64_t lastQueuedTimeUs;
313 CHECK(buffer->meta()->findInt64("timeUs", &lastQueuedTimeUs));
314 mLastQueuedTimeUs = lastQueuedTimeUs;
315 ALOGV("queueAccessUnit timeUs=%" PRIi64 " us (%.2f secs)",
316 mLastQueuedTimeUs, mLastQueuedTimeUs / 1E6);
317
Robert Shih0dd229b2015-03-06 16:45:59 -0800318 // CHECK(!mDiscontinuitySegments.empty());
319 DiscontinuitySegment &tailSeg = *(--mDiscontinuitySegments.end());
320 if (lastQueuedTimeUs > tailSeg.mMaxEnqueTimeUs) {
321 tailSeg.mMaxEnqueTimeUs = lastQueuedTimeUs;
322 }
323 if (tailSeg.mMaxDequeTimeUs == -1) {
324 tailSeg.mMaxDequeTimeUs = lastQueuedTimeUs;
325 }
326
Robert Shih309aa8b2014-07-29 18:34:36 -0700327 if (mLatestEnqueuedMeta == NULL) {
Apurupa Pattapu2a662072014-12-04 16:33:55 -0800328 mLatestEnqueuedMeta = buffer->meta()->dup();
Robert Shih69634502014-01-23 14:25:32 -0800329 } else {
330 int64_t latestTimeUs = 0;
Apurupa Pattapu79971c72014-10-14 15:05:50 -0700331 int64_t frameDeltaUs = 0;
Robert Shih69634502014-01-23 14:25:32 -0800332 CHECK(mLatestEnqueuedMeta->findInt64("timeUs", &latestTimeUs));
333 if (lastQueuedTimeUs > latestTimeUs) {
Apurupa Pattapu2a662072014-12-04 16:33:55 -0800334 mLatestEnqueuedMeta = buffer->meta()->dup();
Apurupa Pattapu79971c72014-10-14 15:05:50 -0700335 frameDeltaUs = lastQueuedTimeUs - latestTimeUs;
336 mLatestEnqueuedMeta->setInt64("durationUs", frameDeltaUs);
337 } else if (!mLatestEnqueuedMeta->findInt64("durationUs", &frameDeltaUs)) {
338 // For B frames
339 frameDeltaUs = latestTimeUs - lastQueuedTimeUs;
340 mLatestEnqueuedMeta->setInt64("durationUs", frameDeltaUs);
Robert Shih69634502014-01-23 14:25:32 -0800341 }
342 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700343}
344
Andreas Huber14f76722013-01-15 09:04:18 -0800345void AnotherPacketSource::clear() {
346 Mutex::Autolock autoLock(mLock);
347
348 mBuffers.clear();
349 mEOSResult = OK;
Robert Shih0dd229b2015-03-06 16:45:59 -0800350
351 mDiscontinuitySegments.clear();
352 mDiscontinuitySegments.push_back(DiscontinuitySegment());
Andreas Huber14f76722013-01-15 09:04:18 -0800353
354 mFormat = NULL;
Robert Shih69634502014-01-23 14:25:32 -0800355 mLatestEnqueuedMeta = NULL;
Robert Shih82e14702016-11-17 11:24:29 -0800356
357 mEstimatedBufferDurationUs = -1;
Andreas Huber14f76722013-01-15 09:04:18 -0800358}
359
Andreas Huber5bc087c2010-12-23 10:27:40 -0800360void AnotherPacketSource::queueDiscontinuity(
Andreas Huber32f3cef2011-03-02 15:34:46 -0800361 ATSParser::DiscontinuityType type,
Chong Zhang632740c2014-06-26 13:03:47 -0700362 const sp<AMessage> &extra,
363 bool discard) {
Andreas Huber9a442c12011-08-25 12:21:26 -0700364 Mutex::Autolock autoLock(mLock);
365
Chong Zhang632740c2014-06-26 13:03:47 -0700366 if (discard) {
367 // Leave only discontinuities in the queue.
368 List<sp<ABuffer> >::iterator it = mBuffers.begin();
369 while (it != mBuffers.end()) {
370 sp<ABuffer> oldBuffer = *it;
Andreas Huber9a442c12011-08-25 12:21:26 -0700371
Chong Zhang632740c2014-06-26 13:03:47 -0700372 int32_t oldDiscontinuityType;
373 if (!oldBuffer->meta()->findInt32(
374 "discontinuity", &oldDiscontinuityType)) {
375 it = mBuffers.erase(it);
376 continue;
377 }
378
379 ++it;
Andreas Huber9a442c12011-08-25 12:21:26 -0700380 }
Robert Shih0dd229b2015-03-06 16:45:59 -0800381
382 for (List<DiscontinuitySegment>::iterator it2 = mDiscontinuitySegments.begin();
383 it2 != mDiscontinuitySegments.end();
384 ++it2) {
385 DiscontinuitySegment &seg = *it2;
386 seg.clear();
387 }
388
Andreas Huber9a442c12011-08-25 12:21:26 -0700389 }
390
Wei Jia87e81232014-11-12 15:37:07 -0800391 mEOSResult = OK;
392 mLastQueuedTimeUs = 0;
393 mLatestEnqueuedMeta = NULL;
394
Wei Jiafef808d2014-10-31 17:57:05 -0700395 if (type == ATSParser::DISCONTINUITY_NONE) {
396 return;
397 }
398
Robert Shih0dd229b2015-03-06 16:45:59 -0800399 mDiscontinuitySegments.push_back(DiscontinuitySegment());
400
Andreas Huber2a4d22d2010-09-08 14:32:20 -0700401 sp<ABuffer> buffer = new ABuffer(0);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800402 buffer->meta()->setInt32("discontinuity", static_cast<int32_t>(type));
Andreas Huber32f3cef2011-03-02 15:34:46 -0800403 buffer->meta()->setMessage("extra", extra);
Andreas Huber53df1a42010-12-22 10:03:04 -0800404
Andreas Huber2a4d22d2010-09-08 14:32:20 -0700405 mBuffers.push_back(buffer);
406 mCondition.signal();
407}
408
Andreas Hubercda17c62010-06-07 13:05:37 -0700409void AnotherPacketSource::signalEOS(status_t result) {
410 CHECK(result != OK);
411
412 Mutex::Autolock autoLock(mLock);
413 mEOSResult = result;
414 mCondition.signal();
415}
416
417bool AnotherPacketSource::hasBufferAvailable(status_t *finalResult) {
418 Mutex::Autolock autoLock(mLock);
Chong Zhanga48d3722015-03-18 10:31:13 -0700419 *finalResult = OK;
Chong Zhang7c870802015-03-17 16:27:56 -0700420 if (!mEnabled) {
421 return false;
422 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700423 if (!mBuffers.empty()) {
424 return true;
425 }
426
427 *finalResult = mEOSResult;
428 return false;
429}
430
Chong Zhanga48d3722015-03-18 10:31:13 -0700431bool AnotherPacketSource::hasDataBufferAvailable(status_t *finalResult) {
432 Mutex::Autolock autoLock(mLock);
433 *finalResult = OK;
Chong Zhang7c870802015-03-17 16:27:56 -0700434 if (!mEnabled) {
435 return false;
436 }
Chong Zhanga48d3722015-03-18 10:31:13 -0700437 List<sp<ABuffer> >::iterator it;
438 for (it = mBuffers.begin(); it != mBuffers.end(); it++) {
439 int32_t discontinuity;
440 if (!(*it)->meta()->findInt32("discontinuity", &discontinuity)) {
441 return true;
442 }
443 }
444
445 *finalResult = mEOSResult;
446 return false;
447}
448
Chong Zhangfcf044a2015-07-14 15:58:51 -0700449size_t AnotherPacketSource::getAvailableBufferCount(status_t *finalResult) {
450 Mutex::Autolock autoLock(mLock);
451
452 *finalResult = OK;
453 if (!mEnabled) {
454 return 0;
455 }
456 if (!mBuffers.empty()) {
457 return mBuffers.size();
458 }
459 *finalResult = mEOSResult;
460 return 0;
461}
462
Andreas Huberbfd4d0d2012-05-17 14:18:50 -0700463int64_t AnotherPacketSource::getBufferedDurationUs(status_t *finalResult) {
464 Mutex::Autolock autoLock(mLock);
Andreas Huberbfd4d0d2012-05-17 14:18:50 -0700465 *finalResult = mEOSResult;
466
Robert Shih0ad776d2014-08-29 18:02:56 -0700467 int64_t durationUs = 0;
Robert Shih0dd229b2015-03-06 16:45:59 -0800468 for (List<DiscontinuitySegment>::iterator it = mDiscontinuitySegments.begin();
469 it != mDiscontinuitySegments.end();
470 ++it) {
471 const DiscontinuitySegment &seg = *it;
472 // dequeued access units should be a subset of enqueued access units
473 // CHECK(seg.maxEnqueTimeUs >= seg.mMaxDequeTimeUs);
474 durationUs += (seg.mMaxEnqueTimeUs - seg.mMaxDequeTimeUs);
Andreas Huberbfd4d0d2012-05-17 14:18:50 -0700475 }
476
Robert Shih0dd229b2015-03-06 16:45:59 -0800477 return durationUs;
Andreas Huberbfd4d0d2012-05-17 14:18:50 -0700478}
479
Robert Shih82e14702016-11-17 11:24:29 -0800480int64_t AnotherPacketSource::getEstimatedBufferDurationUs() {
481 Mutex::Autolock autoLock(mLock);
482 if (mEstimatedBufferDurationUs >= 0) {
483 return mEstimatedBufferDurationUs;
484 }
485
486 SortedVector<int64_t> maxTimesUs;
487 List<sp<ABuffer> >::iterator it;
488 int64_t t1 = 0, t2 = 0;
489 for (it = mBuffers.begin(); it != mBuffers.end(); ++it) {
490 int64_t timeUs = 0;
491 const sp<ABuffer> &buffer = *it;
492 if (!buffer->meta()->findInt64("timeUs", &timeUs)) {
493 continue;
494 }
495 maxTimesUs.add(timeUs);
496 while (maxTimesUs.size() > 2) {
497 maxTimesUs.removeAt(0);
498 t1 = maxTimesUs.itemAt(0);
499 t2 = maxTimesUs.itemAt(1);
500 }
501 }
502 return mEstimatedBufferDurationUs = t2 - t1;
503}
504
Andreas Huberf9334412010-12-15 15:17:42 -0800505status_t AnotherPacketSource::nextBufferTime(int64_t *timeUs) {
506 *timeUs = 0;
507
508 Mutex::Autolock autoLock(mLock);
509
510 if (mBuffers.empty()) {
511 return mEOSResult != OK ? mEOSResult : -EWOULDBLOCK;
512 }
513
514 sp<ABuffer> buffer = *mBuffers.begin();
515 CHECK(buffer->meta()->findInt64("timeUs", timeUs));
516
517 return OK;
518}
519
Roger Jönssonb50e83e2013-01-21 16:26:41 +0100520bool AnotherPacketSource::isFinished(int64_t duration) const {
521 if (duration > 0) {
522 int64_t diff = duration - mLastQueuedTimeUs;
523 if (diff < kNearEOSMarkUs && diff > -kNearEOSMarkUs) {
524 ALOGV("Detecting EOS due to near end");
525 return true;
526 }
527 }
528 return (mEOSResult != OK);
529}
530
Robert Shih309aa8b2014-07-29 18:34:36 -0700531sp<AMessage> AnotherPacketSource::getLatestEnqueuedMeta() {
Robert Shih69634502014-01-23 14:25:32 -0800532 Mutex::Autolock autoLock(mLock);
533 return mLatestEnqueuedMeta;
534}
535
Robert Shih309aa8b2014-07-29 18:34:36 -0700536sp<AMessage> AnotherPacketSource::getLatestDequeuedMeta() {
537 Mutex::Autolock autoLock(mLock);
538 return mLatestDequeuedMeta;
539}
540
Chong Zhang7c870802015-03-17 16:27:56 -0700541void AnotherPacketSource::enable(bool enable) {
542 Mutex::Autolock autoLock(mLock);
543 mEnabled = enable;
544}
545
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700546/*
547 * returns the sample meta that's delayUs after queue head
548 * (NULL if such sample is unavailable)
549 */
Chong Zhang7c870802015-03-17 16:27:56 -0700550sp<AMessage> AnotherPacketSource::getMetaAfterLastDequeued(int64_t delayUs) {
551 Mutex::Autolock autoLock(mLock);
552 int64_t firstUs = -1;
553 int64_t lastUs = -1;
554 int64_t durationUs = 0;
555
556 List<sp<ABuffer> >::iterator it;
557 for (it = mBuffers.begin(); it != mBuffers.end(); ++it) {
558 const sp<ABuffer> &buffer = *it;
559 int32_t discontinuity;
560 if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
561 durationUs += lastUs - firstUs;
562 firstUs = -1;
563 lastUs = -1;
564 continue;
565 }
566 int64_t timeUs;
567 if (buffer->meta()->findInt64("timeUs", &timeUs)) {
568 if (firstUs < 0) {
569 firstUs = timeUs;
570 }
571 if (lastUs < 0 || timeUs > lastUs) {
572 lastUs = timeUs;
573 }
574 if (durationUs + (lastUs - firstUs) >= delayUs) {
575 return buffer->meta();
576 }
577 }
578 }
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700579 return NULL;
Chong Zhang7c870802015-03-17 16:27:56 -0700580}
581
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700582/*
583 * removes samples with time equal or after meta
584 */
585void AnotherPacketSource::trimBuffersAfterMeta(
586 const sp<AMessage> &meta) {
587 if (meta == NULL) {
588 ALOGW("trimming with NULL meta, ignoring");
589 return;
590 }
Chong Zhang7c870802015-03-17 16:27:56 -0700591
592 Mutex::Autolock autoLock(mLock);
593 if (mBuffers.empty()) {
594 return;
595 }
596
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700597 HLSTime stopTime(meta);
Chong Zhang25f82752015-04-08 10:57:04 -0700598 ALOGV("trimBuffersAfterMeta: discontinuitySeq %d, timeUs %lld",
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700599 stopTime.mSeq, (long long)stopTime.mTimeUs);
600
Chong Zhang7c870802015-03-17 16:27:56 -0700601 List<sp<ABuffer> >::iterator it;
Robert Shih0dd229b2015-03-06 16:45:59 -0800602 List<DiscontinuitySegment >::iterator it2;
Chong Zhang7c870802015-03-17 16:27:56 -0700603 sp<AMessage> newLatestEnqueuedMeta = NULL;
604 int64_t newLastQueuedTimeUs = 0;
Robert Shih0dd229b2015-03-06 16:45:59 -0800605 for (it = mBuffers.begin(), it2 = mDiscontinuitySegments.begin(); it != mBuffers.end(); ++it) {
Chong Zhang7c870802015-03-17 16:27:56 -0700606 const sp<ABuffer> &buffer = *it;
607 int32_t discontinuity;
608 if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
Robert Shih0dd229b2015-03-06 16:45:59 -0800609 // CHECK(it2 != mDiscontinuitySegments.end());
610 ++it2;
Chong Zhang7c870802015-03-17 16:27:56 -0700611 continue;
612 }
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700613
614 HLSTime curTime(buffer->meta());
615 if (!(curTime < stopTime)) {
616 ALOGV("trimming from %lld (inclusive) to end",
617 (long long)curTime.mTimeUs);
Chong Zhang7c870802015-03-17 16:27:56 -0700618 break;
619 }
620 newLatestEnqueuedMeta = buffer->meta();
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700621 newLastQueuedTimeUs = curTime.mTimeUs;
Chong Zhang7c870802015-03-17 16:27:56 -0700622 }
Robert Shih0dd229b2015-03-06 16:45:59 -0800623
Chong Zhang7c870802015-03-17 16:27:56 -0700624 mBuffers.erase(it, mBuffers.end());
625 mLatestEnqueuedMeta = newLatestEnqueuedMeta;
626 mLastQueuedTimeUs = newLastQueuedTimeUs;
Robert Shih0dd229b2015-03-06 16:45:59 -0800627
628 DiscontinuitySegment &seg = *it2;
629 if (newLatestEnqueuedMeta != NULL) {
630 seg.mMaxEnqueTimeUs = newLastQueuedTimeUs;
631 } else {
632 seg.clear();
633 }
634 mDiscontinuitySegments.erase(++it2, mDiscontinuitySegments.end());
Chong Zhang7c870802015-03-17 16:27:56 -0700635}
636
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700637/*
638 * removes samples with time equal or before meta;
639 * returns first sample left in the queue.
640 *
641 * (for AVC, if trim happens, the samples left will always start
642 * at next IDR.)
643 */
644sp<AMessage> AnotherPacketSource::trimBuffersBeforeMeta(
645 const sp<AMessage> &meta) {
646 HLSTime startTime(meta);
Chong Zhang25f82752015-04-08 10:57:04 -0700647 ALOGV("trimBuffersBeforeMeta: discontinuitySeq %d, timeUs %lld",
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700648 startTime.mSeq, (long long)startTime.mTimeUs);
649
650 sp<AMessage> firstMeta;
Robert Shih0dd229b2015-03-06 16:45:59 -0800651 int64_t firstTimeUs = -1;
Chong Zhang7c870802015-03-17 16:27:56 -0700652 Mutex::Autolock autoLock(mLock);
653 if (mBuffers.empty()) {
654 return NULL;
655 }
656
657 sp<MetaData> format;
658 bool isAvc = false;
659
660 List<sp<ABuffer> >::iterator it;
Chong Zhang7c870802015-03-17 16:27:56 -0700661 for (it = mBuffers.begin(); it != mBuffers.end(); ++it) {
662 const sp<ABuffer> &buffer = *it;
663 int32_t discontinuity;
664 if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
Robert Shih0dd229b2015-03-06 16:45:59 -0800665 mDiscontinuitySegments.erase(mDiscontinuitySegments.begin());
666 // CHECK(!mDiscontinuitySegments.empty());
Chong Zhang7c870802015-03-17 16:27:56 -0700667 format = NULL;
668 isAvc = false;
Chong Zhang7c870802015-03-17 16:27:56 -0700669 continue;
670 }
671 if (format == NULL) {
672 sp<RefBase> object;
673 if (buffer->meta()->findObject("format", &object)) {
674 const char* mime;
675 format = static_cast<MetaData*>(object.get());
676 isAvc = format != NULL
677 && format->findCString(kKeyMIMEType, &mime)
678 && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
679 }
680 }
Dongwon Kangd91dc5a2017-10-10 00:07:09 -0700681 if (isAvc && !IsIDR(buffer->data(), buffer->size())) {
Chong Zhang7c870802015-03-17 16:27:56 -0700682 continue;
683 }
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700684
685 HLSTime curTime(buffer->meta());
686 if (startTime < curTime) {
687 ALOGV("trimming from beginning to %lld (not inclusive)",
688 (long long)curTime.mTimeUs);
689 firstMeta = buffer->meta();
Robert Shih0dd229b2015-03-06 16:45:59 -0800690 firstTimeUs = curTime.mTimeUs;
Chong Zhang7c870802015-03-17 16:27:56 -0700691 break;
692 }
693 }
694 mBuffers.erase(mBuffers.begin(), it);
Chong Zhang7c870802015-03-17 16:27:56 -0700695 mLatestDequeuedMeta = NULL;
Robert Shih0dd229b2015-03-06 16:45:59 -0800696
697 // CHECK(!mDiscontinuitySegments.empty());
698 DiscontinuitySegment &seg = *mDiscontinuitySegments.begin();
699 if (firstTimeUs >= 0) {
700 seg.mMaxDequeTimeUs = firstTimeUs;
701 } else {
702 seg.clear();
703 }
704
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700705 return firstMeta;
Chong Zhang7c870802015-03-17 16:27:56 -0700706}
707
Andreas Hubercda17c62010-06-07 13:05:37 -0700708} // namespace android