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