APacketSource.cpp revision 21a6f9ffee8b3c014abfe165b8f7fd2224f49e1f
1/* 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 17//#define LOG_NDEBUG 0 18#define LOG_TAG "APacketSource" 19#include <utils/Log.h> 20 21#include "APacketSource.h" 22 23#include "ASessionDescription.h" 24 25#include "avc_utils.h" 26 27#include <ctype.h> 28 29#include <media/stagefright/foundation/ABitReader.h> 30#include <media/stagefright/foundation/ABuffer.h> 31#include <media/stagefright/foundation/ADebug.h> 32#include <media/stagefright/foundation/AMessage.h> 33#include <media/stagefright/foundation/AString.h> 34#include <media/stagefright/foundation/base64.h> 35#include <media/stagefright/foundation/hexdump.h> 36#include <media/stagefright/MediaBuffer.h> 37#include <media/stagefright/MediaDefs.h> 38#include <media/stagefright/MetaData.h> 39#include <utils/Vector.h> 40 41namespace android { 42 43static bool GetAttribute(const char *s, const char *key, AString *value) { 44 value->clear(); 45 46 size_t keyLen = strlen(key); 47 48 for (;;) { 49 while (isspace(*s)) { 50 ++s; 51 } 52 53 const char *colonPos = strchr(s, ';'); 54 55 size_t len = 56 (colonPos == NULL) ? strlen(s) : colonPos - s; 57 58 if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) { 59 value->setTo(&s[keyLen + 1], len - keyLen - 1); 60 return true; 61 } 62 63 if (colonPos == NULL) { 64 return false; 65 } 66 67 s = colonPos + 1; 68 } 69} 70 71static sp<ABuffer> decodeHex(const AString &s) { 72 if ((s.size() % 2) != 0) { 73 return NULL; 74 } 75 76 size_t outLen = s.size() / 2; 77 sp<ABuffer> buffer = new ABuffer(outLen); 78 uint8_t *out = buffer->data(); 79 80 uint8_t accum = 0; 81 for (size_t i = 0; i < s.size(); ++i) { 82 char c = s.c_str()[i]; 83 unsigned value; 84 if (c >= '0' && c <= '9') { 85 value = c - '0'; 86 } else if (c >= 'a' && c <= 'f') { 87 value = c - 'a' + 10; 88 } else if (c >= 'A' && c <= 'F') { 89 value = c - 'A' + 10; 90 } else { 91 return NULL; 92 } 93 94 accum = (accum << 4) | value; 95 96 if (i & 1) { 97 *out++ = accum; 98 99 accum = 0; 100 } 101 } 102 103 return buffer; 104} 105 106static sp<ABuffer> MakeAVCCodecSpecificData( 107 const char *params, int32_t *width, int32_t *height) { 108 *width = 0; 109 *height = 0; 110 111 AString val; 112 if (!GetAttribute(params, "profile-level-id", &val)) { 113 return NULL; 114 } 115 116 sp<ABuffer> profileLevelID = decodeHex(val); 117 CHECK(profileLevelID != NULL); 118 CHECK_EQ(profileLevelID->size(), 3u); 119 120 Vector<sp<ABuffer> > paramSets; 121 122 size_t numSeqParameterSets = 0; 123 size_t totalSeqParameterSetSize = 0; 124 size_t numPicParameterSets = 0; 125 size_t totalPicParameterSetSize = 0; 126 127 if (!GetAttribute(params, "sprop-parameter-sets", &val)) { 128 return NULL; 129 } 130 131 size_t start = 0; 132 for (;;) { 133 ssize_t commaPos = val.find(",", start); 134 size_t end = (commaPos < 0) ? val.size() : commaPos; 135 136 AString nalString(val, start, end - start); 137 sp<ABuffer> nal = decodeBase64(nalString); 138 CHECK(nal != NULL); 139 CHECK_GT(nal->size(), 0u); 140 CHECK_LE(nal->size(), 65535u); 141 142 uint8_t nalType = nal->data()[0] & 0x1f; 143 if (numSeqParameterSets == 0) { 144 CHECK_EQ((unsigned)nalType, 7u); 145 } else if (numPicParameterSets > 0) { 146 CHECK_EQ((unsigned)nalType, 8u); 147 } 148 if (nalType == 7) { 149 ++numSeqParameterSets; 150 totalSeqParameterSetSize += nal->size(); 151 } else { 152 CHECK_EQ((unsigned)nalType, 8u); 153 ++numPicParameterSets; 154 totalPicParameterSetSize += nal->size(); 155 } 156 157 paramSets.push(nal); 158 159 if (commaPos < 0) { 160 break; 161 } 162 163 start = commaPos + 1; 164 } 165 166 CHECK_LT(numSeqParameterSets, 32u); 167 CHECK_LE(numPicParameterSets, 255u); 168 169 size_t csdSize = 170 1 + 3 + 1 + 1 171 + 2 * numSeqParameterSets + totalSeqParameterSetSize 172 + 1 + 2 * numPicParameterSets + totalPicParameterSetSize; 173 174 sp<ABuffer> csd = new ABuffer(csdSize); 175 uint8_t *out = csd->data(); 176 177 *out++ = 0x01; // configurationVersion 178 memcpy(out, profileLevelID->data(), 3); 179 out += 3; 180 *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes 181 *out++ = 0xe0 | numSeqParameterSets; 182 183 for (size_t i = 0; i < numSeqParameterSets; ++i) { 184 sp<ABuffer> nal = paramSets.editItemAt(i); 185 186 *out++ = nal->size() >> 8; 187 *out++ = nal->size() & 0xff; 188 189 memcpy(out, nal->data(), nal->size()); 190 191 out += nal->size(); 192 193 if (i == 0) { 194 FindAVCDimensions(nal, width, height); 195 LOGI("dimensions %dx%d", *width, *height); 196 } 197 } 198 199 *out++ = numPicParameterSets; 200 201 for (size_t i = 0; i < numPicParameterSets; ++i) { 202 sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets); 203 204 *out++ = nal->size() >> 8; 205 *out++ = nal->size() & 0xff; 206 207 memcpy(out, nal->data(), nal->size()); 208 209 out += nal->size(); 210 } 211 212 // hexdump(csd->data(), csd->size()); 213 214 return csd; 215} 216 217sp<ABuffer> MakeAACCodecSpecificData(const char *params) { 218 AString val; 219 CHECK(GetAttribute(params, "config", &val)); 220 221 sp<ABuffer> config = decodeHex(val); 222 CHECK(config != NULL); 223 CHECK_GE(config->size(), 4u); 224 225 const uint8_t *data = config->data(); 226 uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; 227 x = (x >> 1) & 0xffff; 228 229 static const uint8_t kStaticESDS[] = { 230 0x03, 22, 231 0x00, 0x00, // ES_ID 232 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 233 234 0x04, 17, 235 0x40, // Audio ISO/IEC 14496-3 236 0x00, 0x00, 0x00, 0x00, 237 0x00, 0x00, 0x00, 0x00, 238 0x00, 0x00, 0x00, 0x00, 239 240 0x05, 2, 241 // AudioSpecificInfo follows 242 }; 243 244 sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2); 245 memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS)); 246 csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff; 247 csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff; 248 249 // hexdump(csd->data(), csd->size()); 250 251 return csd; 252} 253 254// From mpeg4-generic configuration data. 255sp<ABuffer> MakeAACCodecSpecificData2(const char *params) { 256 AString val; 257 unsigned long objectType; 258 if (GetAttribute(params, "objectType", &val)) { 259 const char *s = val.c_str(); 260 char *end; 261 objectType = strtoul(s, &end, 10); 262 CHECK(end > s && *end == '\0'); 263 } else { 264 objectType = 0x40; // Audio ISO/IEC 14496-3 265 } 266 267 CHECK(GetAttribute(params, "config", &val)); 268 269 sp<ABuffer> config = decodeHex(val); 270 CHECK(config != NULL); 271 272 // Make sure size fits into a single byte and doesn't have to 273 // be encoded. 274 CHECK_LT(20 + config->size(), 128u); 275 276 const uint8_t *data = config->data(); 277 278 static const uint8_t kStaticESDS[] = { 279 0x03, 22, 280 0x00, 0x00, // ES_ID 281 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 282 283 0x04, 17, 284 0x40, // Audio ISO/IEC 14496-3 285 0x00, 0x00, 0x00, 0x00, 286 0x00, 0x00, 0x00, 0x00, 287 0x00, 0x00, 0x00, 0x00, 288 289 0x05, 2, 290 // AudioSpecificInfo follows 291 }; 292 293 sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size()); 294 uint8_t *dst = csd->data(); 295 *dst++ = 0x03; 296 *dst++ = 20 + config->size(); 297 *dst++ = 0x00; // ES_ID 298 *dst++ = 0x00; 299 *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 300 *dst++ = 0x04; 301 *dst++ = 15 + config->size(); 302 *dst++ = objectType; 303 for (int i = 0; i < 12; ++i) { *dst++ = 0x00; } 304 *dst++ = 0x05; 305 *dst++ = config->size(); 306 memcpy(dst, config->data(), config->size()); 307 308 // hexdump(csd->data(), csd->size()); 309 310 return csd; 311} 312 313static size_t GetSizeWidth(size_t x) { 314 size_t n = 1; 315 while (x > 127) { 316 ++n; 317 x >>= 7; 318 } 319 return n; 320} 321 322static uint8_t *EncodeSize(uint8_t *dst, size_t x) { 323 while (x > 127) { 324 *dst++ = (x & 0x7f) | 0x80; 325 x >>= 7; 326 } 327 *dst++ = x; 328 return dst; 329} 330 331static bool ExtractDimensionsFromVOLHeader( 332 const sp<ABuffer> &config, int32_t *width, int32_t *height) { 333 *width = 0; 334 *height = 0; 335 336 const uint8_t *ptr = config->data(); 337 size_t offset = 0; 338 bool foundVOL = false; 339 while (offset + 3 < config->size()) { 340 if (memcmp("\x00\x00\x01", &ptr[offset], 3) 341 || (ptr[offset + 3] & 0xf0) != 0x20) { 342 ++offset; 343 continue; 344 } 345 346 foundVOL = true; 347 break; 348 } 349 350 if (!foundVOL) { 351 return false; 352 } 353 354 ABitReader br(&ptr[offset + 4], config->size() - offset - 4); 355 br.skipBits(1); // random_accessible_vol 356 unsigned video_object_type_indication = br.getBits(8); 357 358 CHECK_NE(video_object_type_indication, 359 0x21u /* Fine Granularity Scalable */); 360 361 unsigned video_object_layer_verid; 362 unsigned video_object_layer_priority; 363 if (br.getBits(1)) { 364 video_object_layer_verid = br.getBits(4); 365 video_object_layer_priority = br.getBits(3); 366 } 367 unsigned aspect_ratio_info = br.getBits(4); 368 if (aspect_ratio_info == 0x0f /* extended PAR */) { 369 br.skipBits(8); // par_width 370 br.skipBits(8); // par_height 371 } 372 if (br.getBits(1)) { // vol_control_parameters 373 br.skipBits(2); // chroma_format 374 br.skipBits(1); // low_delay 375 if (br.getBits(1)) { // vbv_parameters 376 br.skipBits(15); // first_half_bit_rate 377 CHECK(br.getBits(1)); // marker_bit 378 br.skipBits(15); // latter_half_bit_rate 379 CHECK(br.getBits(1)); // marker_bit 380 br.skipBits(15); // first_half_vbv_buffer_size 381 CHECK(br.getBits(1)); // marker_bit 382 br.skipBits(3); // latter_half_vbv_buffer_size 383 br.skipBits(11); // first_half_vbv_occupancy 384 CHECK(br.getBits(1)); // marker_bit 385 br.skipBits(15); // latter_half_vbv_occupancy 386 CHECK(br.getBits(1)); // marker_bit 387 } 388 } 389 unsigned video_object_layer_shape = br.getBits(2); 390 CHECK_EQ(video_object_layer_shape, 0x00u /* rectangular */); 391 392 CHECK(br.getBits(1)); // marker_bit 393 unsigned vop_time_increment_resolution = br.getBits(16); 394 CHECK(br.getBits(1)); // marker_bit 395 396 if (br.getBits(1)) { // fixed_vop_rate 397 // range [0..vop_time_increment_resolution) 398 399 // vop_time_increment_resolution 400 // 2 => 0..1, 1 bit 401 // 3 => 0..2, 2 bits 402 // 4 => 0..3, 2 bits 403 // 5 => 0..4, 3 bits 404 // ... 405 406 CHECK_GT(vop_time_increment_resolution, 0u); 407 --vop_time_increment_resolution; 408 409 unsigned numBits = 0; 410 while (vop_time_increment_resolution > 0) { 411 ++numBits; 412 vop_time_increment_resolution >>= 1; 413 } 414 415 br.skipBits(numBits); // fixed_vop_time_increment 416 } 417 418 CHECK(br.getBits(1)); // marker_bit 419 unsigned video_object_layer_width = br.getBits(13); 420 CHECK(br.getBits(1)); // marker_bit 421 unsigned video_object_layer_height = br.getBits(13); 422 CHECK(br.getBits(1)); // marker_bit 423 424 unsigned interlaced = br.getBits(1); 425 426 *width = video_object_layer_width; 427 *height = video_object_layer_height; 428 429 LOGI("VOL dimensions = %dx%d", *width, *height); 430 431 return true; 432} 433 434sp<ABuffer> MakeMPEG4VideoCodecSpecificData( 435 const char *params, int32_t *width, int32_t *height) { 436 *width = 0; 437 *height = 0; 438 439 AString val; 440 CHECK(GetAttribute(params, "config", &val)); 441 442 sp<ABuffer> config = decodeHex(val); 443 CHECK(config != NULL); 444 445 if (!ExtractDimensionsFromVOLHeader(config, width, height)) { 446 return NULL; 447 } 448 449 size_t len1 = config->size() + GetSizeWidth(config->size()) + 1; 450 size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13; 451 size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3; 452 453 sp<ABuffer> csd = new ABuffer(len3); 454 uint8_t *dst = csd->data(); 455 *dst++ = 0x03; 456 dst = EncodeSize(dst, len2 + 3); 457 *dst++ = 0x00; // ES_ID 458 *dst++ = 0x00; 459 *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 460 461 *dst++ = 0x04; 462 dst = EncodeSize(dst, len1 + 13); 463 *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile 464 for (size_t i = 0; i < 12; ++i) { 465 *dst++ = 0x00; 466 } 467 468 *dst++ = 0x05; 469 dst = EncodeSize(dst, config->size()); 470 memcpy(dst, config->data(), config->size()); 471 dst += config->size(); 472 473 // hexdump(csd->data(), csd->size()); 474 475 return csd; 476} 477 478static bool GetClockRate(const AString &desc, uint32_t *clockRate) { 479 ssize_t slashPos = desc.find("/"); 480 if (slashPos < 0) { 481 return false; 482 } 483 484 const char *s = desc.c_str() + slashPos + 1; 485 486 char *end; 487 unsigned long x = strtoul(s, &end, 10); 488 489 if (end == s || (*end != '\0' && *end != '/')) { 490 return false; 491 } 492 493 *clockRate = x; 494 495 return true; 496} 497 498APacketSource::APacketSource( 499 const sp<ASessionDescription> &sessionDesc, size_t index) 500 : mInitCheck(NO_INIT), 501 mFormat(new MetaData), 502 mEOSResult(OK), 503 mIsAVC(false), 504 mScanForIDR(true), 505 mRTPTimeBase(0), 506 mNormalPlayTimeBaseUs(0), 507 mLastNormalPlayTimeUs(0) { 508 unsigned long PT; 509 AString desc; 510 AString params; 511 sessionDesc->getFormatType(index, &PT, &desc, ¶ms); 512 513 CHECK(GetClockRate(desc, &mClockRate)); 514 515 int64_t durationUs; 516 if (sessionDesc->getDurationUs(&durationUs)) { 517 mFormat->setInt64(kKeyDuration, durationUs); 518 } else { 519 mFormat->setInt64(kKeyDuration, 60 * 60 * 1000000ll); 520 } 521 522 mInitCheck = OK; 523 if (!strncmp(desc.c_str(), "H264/", 5)) { 524 mIsAVC = true; 525 526 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 527 528 int32_t width, height; 529 if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 530 width = -1; 531 height = -1; 532 } 533 534 int32_t encWidth, encHeight; 535 sp<ABuffer> codecSpecificData = 536 MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight); 537 538 if (codecSpecificData != NULL) { 539 if (width < 0) { 540 // If no explicit width/height given in the sdp, use the dimensions 541 // extracted from the first sequence parameter set. 542 width = encWidth; 543 height = encHeight; 544 } 545 546 mFormat->setData( 547 kKeyAVCC, 0, 548 codecSpecificData->data(), codecSpecificData->size()); 549 } else if (width < 0) { 550 mInitCheck = ERROR_UNSUPPORTED; 551 return; 552 } 553 554 mFormat->setInt32(kKeyWidth, width); 555 mFormat->setInt32(kKeyHeight, height); 556 } else if (!strncmp(desc.c_str(), "H263-2000/", 10) 557 || !strncmp(desc.c_str(), "H263-1998/", 10)) { 558 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 559 560 int32_t width, height; 561 if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 562 mInitCheck = ERROR_UNSUPPORTED; 563 return; 564 } 565 566 mFormat->setInt32(kKeyWidth, width); 567 mFormat->setInt32(kKeyHeight, height); 568 } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) { 569 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 570 571 int32_t sampleRate, numChannels; 572 ASessionDescription::ParseFormatDesc( 573 desc.c_str(), &sampleRate, &numChannels); 574 575 mFormat->setInt32(kKeySampleRate, sampleRate); 576 mFormat->setInt32(kKeyChannelCount, numChannels); 577 578 sp<ABuffer> codecSpecificData = 579 MakeAACCodecSpecificData(params.c_str()); 580 581 mFormat->setData( 582 kKeyESDS, 0, 583 codecSpecificData->data(), codecSpecificData->size()); 584 } else if (!strncmp(desc.c_str(), "AMR/", 4)) { 585 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 586 587 int32_t sampleRate, numChannels; 588 ASessionDescription::ParseFormatDesc( 589 desc.c_str(), &sampleRate, &numChannels); 590 591 mFormat->setInt32(kKeySampleRate, sampleRate); 592 mFormat->setInt32(kKeyChannelCount, numChannels); 593 594 if (sampleRate != 8000 || numChannels != 1) { 595 mInitCheck = ERROR_UNSUPPORTED; 596 } 597 } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { 598 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 599 600 int32_t sampleRate, numChannels; 601 ASessionDescription::ParseFormatDesc( 602 desc.c_str(), &sampleRate, &numChannels); 603 604 mFormat->setInt32(kKeySampleRate, sampleRate); 605 mFormat->setInt32(kKeyChannelCount, numChannels); 606 607 if (sampleRate != 16000 || numChannels != 1) { 608 mInitCheck = ERROR_UNSUPPORTED; 609 } 610 } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) { 611 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 612 613 int32_t width, height; 614 if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 615 width = -1; 616 height = -1; 617 } 618 619 int32_t encWidth, encHeight; 620 sp<ABuffer> codecSpecificData = 621 MakeMPEG4VideoCodecSpecificData( 622 params.c_str(), &encWidth, &encHeight); 623 624 if (codecSpecificData != NULL) { 625 mFormat->setData( 626 kKeyESDS, 0, 627 codecSpecificData->data(), codecSpecificData->size()); 628 629 if (width < 0) { 630 width = encWidth; 631 height = encHeight; 632 } 633 } else if (width < 0) { 634 mInitCheck = ERROR_UNSUPPORTED; 635 return; 636 } 637 638 mFormat->setInt32(kKeyWidth, width); 639 mFormat->setInt32(kKeyHeight, height); 640 } else if (!strncmp(desc.c_str(), "mpeg4-generic/", 14)) { 641 AString val; 642 if (!GetAttribute(params.c_str(), "mode", &val) 643 || (strcasecmp(val.c_str(), "AAC-lbr") 644 && strcasecmp(val.c_str(), "AAC-hbr"))) { 645 mInitCheck = ERROR_UNSUPPORTED; 646 return; 647 } 648 649 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 650 651 int32_t sampleRate, numChannels; 652 ASessionDescription::ParseFormatDesc( 653 desc.c_str(), &sampleRate, &numChannels); 654 655 mFormat->setInt32(kKeySampleRate, sampleRate); 656 mFormat->setInt32(kKeyChannelCount, numChannels); 657 658 sp<ABuffer> codecSpecificData = 659 MakeAACCodecSpecificData2(params.c_str()); 660 661 mFormat->setData( 662 kKeyESDS, 0, 663 codecSpecificData->data(), codecSpecificData->size()); 664 } else { 665 mInitCheck = ERROR_UNSUPPORTED; 666 } 667} 668 669APacketSource::~APacketSource() { 670} 671 672status_t APacketSource::initCheck() const { 673 return mInitCheck; 674} 675 676status_t APacketSource::start(MetaData *params) { 677 return OK; 678} 679 680status_t APacketSource::stop() { 681 return OK; 682} 683 684sp<MetaData> APacketSource::getFormat() { 685 return mFormat; 686} 687 688status_t APacketSource::read( 689 MediaBuffer **out, const ReadOptions *) { 690 *out = NULL; 691 692 Mutex::Autolock autoLock(mLock); 693 while (mEOSResult == OK && mBuffers.empty()) { 694 mCondition.wait(mLock); 695 } 696 697 if (!mBuffers.empty()) { 698 const sp<ABuffer> buffer = *mBuffers.begin(); 699 700 updateNormalPlayTime_l(buffer); 701 702 MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size()); 703 704 int64_t timeUs; 705 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 706 707 mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs); 708 709 memcpy(mediaBuffer->data(), buffer->data(), buffer->size()); 710 *out = mediaBuffer; 711 712 mBuffers.erase(mBuffers.begin()); 713 return OK; 714 } 715 716 return mEOSResult; 717} 718 719void APacketSource::updateNormalPlayTime_l(const sp<ABuffer> &buffer) { 720 uint32_t rtpTime; 721 CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)); 722 723 mLastNormalPlayTimeUs = 724 (((double)rtpTime - (double)mRTPTimeBase) / mClockRate) 725 * 1000000ll 726 + mNormalPlayTimeBaseUs; 727} 728 729void APacketSource::queueAccessUnit(const sp<ABuffer> &buffer) { 730 int32_t damaged; 731 if (buffer->meta()->findInt32("damaged", &damaged) && damaged) { 732 LOGV("discarding damaged AU"); 733 return; 734 } 735 736 if (mScanForIDR && mIsAVC) { 737 // This pretty piece of code ensures that the first access unit 738 // fed to the decoder after stream-start or seek is guaranteed to 739 // be an IDR frame. This is to workaround limitations of a certain 740 // hardware h.264 decoder that requires this to be the case. 741 742 if (!IsIDR(buffer)) { 743 LOGV("skipping AU while scanning for next IDR frame."); 744 return; 745 } 746 747 mScanForIDR = false; 748 } 749 750 Mutex::Autolock autoLock(mLock); 751 mBuffers.push_back(buffer); 752 mCondition.signal(); 753} 754 755void APacketSource::signalEOS(status_t result) { 756 CHECK(result != OK); 757 758 Mutex::Autolock autoLock(mLock); 759 mEOSResult = result; 760 mCondition.signal(); 761} 762 763void APacketSource::flushQueue() { 764 Mutex::Autolock autoLock(mLock); 765 mBuffers.clear(); 766 767 mScanForIDR = true; 768} 769 770int64_t APacketSource::getNormalPlayTimeUs() { 771 Mutex::Autolock autoLock(mLock); 772 return mLastNormalPlayTimeUs; 773} 774 775void APacketSource::setNormalPlayTimeMapping( 776 uint32_t rtpTime, int64_t normalPlayTimeUs) { 777 Mutex::Autolock autoLock(mLock); 778 779 mRTPTimeBase = rtpTime; 780 mNormalPlayTimeBaseUs = normalPlayTimeUs; 781} 782 783int64_t APacketSource::getQueueDurationUs(bool *eos) { 784 Mutex::Autolock autoLock(mLock); 785 786 *eos = (mEOSResult != OK); 787 788 if (mBuffers.size() < 2) { 789 return 0; 790 } 791 792 const sp<ABuffer> first = *mBuffers.begin(); 793 const sp<ABuffer> last = *--mBuffers.end(); 794 795 int64_t firstTimeUs; 796 CHECK(first->meta()->findInt64("timeUs", &firstTimeUs)); 797 798 int64_t lastTimeUs; 799 CHECK(last->meta()->findInt64("timeUs", &lastTimeUs)); 800 801 if (lastTimeUs < firstTimeUs) { 802 LOGE("Huh? Time moving backwards? %lld > %lld", 803 firstTimeUs, lastTimeUs); 804 805 return 0; 806 } 807 808 return lastTimeUs - firstTimeUs; 809} 810 811} // namespace android 812