1 /* 2 * Copyright (C) 2009 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_TAG "SampleTable" 18 //#define LOG_NDEBUG 0 19 #include <utils/Log.h> 20 21 #include "include/SampleTable.h" 22 #include "include/SampleIterator.h" 23 24 #include <arpa/inet.h> 25 26 #include <media/stagefright/DataSource.h> 27 #include <media/stagefright/MediaDebug.h> 28 #include <media/stagefright/Utils.h> 29 30 namespace android { 31 32 // static 33 const uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o'); 34 // static 35 const uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4'); 36 // static 37 const uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z'); 38 // static 39 const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); 40 41 //////////////////////////////////////////////////////////////////////////////// 42 43 SampleTable::SampleTable(const sp<DataSource> &source) 44 : mDataSource(source), 45 mChunkOffsetOffset(-1), 46 mChunkOffsetType(0), 47 mNumChunkOffsets(0), 48 mSampleToChunkOffset(-1), 49 mNumSampleToChunkOffsets(0), 50 mSampleSizeOffset(-1), 51 mSampleSizeFieldSize(0), 52 mDefaultSampleSize(0), 53 mNumSampleSizes(0), 54 mTimeToSampleCount(0), 55 mTimeToSample(NULL), 56 mSyncSampleOffset(-1), 57 mNumSyncSamples(0), 58 mSyncSamples(NULL), 59 mLastSyncSampleIndex(0), 60 mSampleToChunkEntries(NULL) { 61 mSampleIterator = new SampleIterator(this); 62 } 63 64 SampleTable::~SampleTable() { 65 delete[] mSampleToChunkEntries; 66 mSampleToChunkEntries = NULL; 67 68 delete[] mSyncSamples; 69 mSyncSamples = NULL; 70 71 delete[] mTimeToSample; 72 mTimeToSample = NULL; 73 74 delete mSampleIterator; 75 mSampleIterator = NULL; 76 } 77 78 status_t SampleTable::setChunkOffsetParams( 79 uint32_t type, off_t data_offset, size_t data_size) { 80 if (mChunkOffsetOffset >= 0) { 81 return ERROR_MALFORMED; 82 } 83 84 CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 85 86 mChunkOffsetOffset = data_offset; 87 mChunkOffsetType = type; 88 89 if (data_size < 8) { 90 return ERROR_MALFORMED; 91 } 92 93 uint8_t header[8]; 94 if (mDataSource->readAt( 95 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 96 return ERROR_IO; 97 } 98 99 if (U32_AT(header) != 0) { 100 // Expected version = 0, flags = 0. 101 return ERROR_MALFORMED; 102 } 103 104 mNumChunkOffsets = U32_AT(&header[4]); 105 106 if (mChunkOffsetType == kChunkOffsetType32) { 107 if (data_size < 8 + mNumChunkOffsets * 4) { 108 return ERROR_MALFORMED; 109 } 110 } else { 111 if (data_size < 8 + mNumChunkOffsets * 8) { 112 return ERROR_MALFORMED; 113 } 114 } 115 116 return OK; 117 } 118 119 status_t SampleTable::setSampleToChunkParams( 120 off_t data_offset, size_t data_size) { 121 if (mSampleToChunkOffset >= 0) { 122 return ERROR_MALFORMED; 123 } 124 125 mSampleToChunkOffset = data_offset; 126 127 if (data_size < 8) { 128 return ERROR_MALFORMED; 129 } 130 131 uint8_t header[8]; 132 if (mDataSource->readAt( 133 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 134 return ERROR_IO; 135 } 136 137 if (U32_AT(header) != 0) { 138 // Expected version = 0, flags = 0. 139 return ERROR_MALFORMED; 140 } 141 142 mNumSampleToChunkOffsets = U32_AT(&header[4]); 143 144 if (data_size < 8 + mNumSampleToChunkOffsets * 12) { 145 return ERROR_MALFORMED; 146 } 147 148 mSampleToChunkEntries = 149 new SampleToChunkEntry[mNumSampleToChunkOffsets]; 150 151 for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { 152 uint8_t buffer[12]; 153 if (mDataSource->readAt( 154 mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) 155 != (ssize_t)sizeof(buffer)) { 156 return ERROR_IO; 157 } 158 159 CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. 160 161 // We want the chunk index to be 0-based. 162 mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; 163 mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]); 164 mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]); 165 } 166 167 return OK; 168 } 169 170 status_t SampleTable::setSampleSizeParams( 171 uint32_t type, off_t data_offset, size_t data_size) { 172 if (mSampleSizeOffset >= 0) { 173 return ERROR_MALFORMED; 174 } 175 176 CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 177 178 mSampleSizeOffset = data_offset; 179 180 if (data_size < 12) { 181 return ERROR_MALFORMED; 182 } 183 184 uint8_t header[12]; 185 if (mDataSource->readAt( 186 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 187 return ERROR_IO; 188 } 189 190 if (U32_AT(header) != 0) { 191 // Expected version = 0, flags = 0. 192 return ERROR_MALFORMED; 193 } 194 195 mDefaultSampleSize = U32_AT(&header[4]); 196 mNumSampleSizes = U32_AT(&header[8]); 197 198 if (type == kSampleSizeType32) { 199 mSampleSizeFieldSize = 32; 200 201 if (mDefaultSampleSize != 0) { 202 return OK; 203 } 204 205 if (data_size < 12 + mNumSampleSizes * 4) { 206 return ERROR_MALFORMED; 207 } 208 } else { 209 if ((mDefaultSampleSize & 0xffffff00) != 0) { 210 // The high 24 bits are reserved and must be 0. 211 return ERROR_MALFORMED; 212 } 213 214 mSampleSizeFieldSize = mDefaultSampleSize & 0xf; 215 mDefaultSampleSize = 0; 216 217 if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 218 && mSampleSizeFieldSize != 16) { 219 return ERROR_MALFORMED; 220 } 221 222 if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 223 return ERROR_MALFORMED; 224 } 225 } 226 227 return OK; 228 } 229 230 status_t SampleTable::setTimeToSampleParams( 231 off_t data_offset, size_t data_size) { 232 if (mTimeToSample != NULL || data_size < 8) { 233 return ERROR_MALFORMED; 234 } 235 236 uint8_t header[8]; 237 if (mDataSource->readAt( 238 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 239 return ERROR_IO; 240 } 241 242 if (U32_AT(header) != 0) { 243 // Expected version = 0, flags = 0. 244 return ERROR_MALFORMED; 245 } 246 247 mTimeToSampleCount = U32_AT(&header[4]); 248 mTimeToSample = new uint32_t[mTimeToSampleCount * 2]; 249 250 size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2; 251 if (mDataSource->readAt( 252 data_offset + 8, mTimeToSample, size) < (ssize_t)size) { 253 return ERROR_IO; 254 } 255 256 for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) { 257 mTimeToSample[i] = ntohl(mTimeToSample[i]); 258 } 259 260 return OK; 261 } 262 263 status_t SampleTable::setSyncSampleParams(off_t data_offset, size_t data_size) { 264 if (mSyncSampleOffset >= 0 || data_size < 8) { 265 return ERROR_MALFORMED; 266 } 267 268 mSyncSampleOffset = data_offset; 269 270 uint8_t header[8]; 271 if (mDataSource->readAt( 272 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 273 return ERROR_IO; 274 } 275 276 if (U32_AT(header) != 0) { 277 // Expected version = 0, flags = 0. 278 return ERROR_MALFORMED; 279 } 280 281 mNumSyncSamples = U32_AT(&header[4]); 282 283 if (mNumSyncSamples < 2) { 284 LOGW("Table of sync samples is empty or has only a single entry!"); 285 } 286 287 mSyncSamples = new uint32_t[mNumSyncSamples]; 288 size_t size = mNumSyncSamples * sizeof(uint32_t); 289 if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) 290 != (ssize_t)size) { 291 return ERROR_IO; 292 } 293 294 for (size_t i = 0; i < mNumSyncSamples; ++i) { 295 mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; 296 } 297 298 return OK; 299 } 300 301 uint32_t SampleTable::countChunkOffsets() const { 302 return mNumChunkOffsets; 303 } 304 305 uint32_t SampleTable::countSamples() const { 306 return mNumSampleSizes; 307 } 308 309 status_t SampleTable::getMaxSampleSize(size_t *max_size) { 310 Mutex::Autolock autoLock(mLock); 311 312 *max_size = 0; 313 314 for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 315 size_t sample_size; 316 status_t err = getSampleSize_l(i, &sample_size); 317 318 if (err != OK) { 319 return err; 320 } 321 322 if (sample_size > *max_size) { 323 *max_size = sample_size; 324 } 325 } 326 327 return OK; 328 } 329 330 uint32_t abs_difference(uint32_t time1, uint32_t time2) { 331 return time1 > time2 ? time1 - time2 : time2 - time1; 332 } 333 334 status_t SampleTable::findSampleAtTime( 335 uint32_t req_time, uint32_t *sample_index, uint32_t flags) { 336 *sample_index = 0; 337 338 Mutex::Autolock autoLock(mLock); 339 340 uint32_t cur_sample = 0; 341 uint32_t time = 0; 342 for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 343 uint32_t n = mTimeToSample[2 * i]; 344 uint32_t delta = mTimeToSample[2 * i + 1]; 345 346 if (req_time < time + n * delta) { 347 int j = (req_time - time) / delta; 348 349 uint32_t time1 = time + j * delta; 350 uint32_t time2 = time1 + delta; 351 352 uint32_t sampleTime; 353 if (i+1 == mTimeToSampleCount 354 || (abs_difference(req_time, time1) 355 < abs_difference(req_time, time2))) { 356 *sample_index = cur_sample + j; 357 sampleTime = time1; 358 } else { 359 *sample_index = cur_sample + j + 1; 360 sampleTime = time2; 361 } 362 363 switch (flags) { 364 case kFlagBefore: 365 { 366 if (sampleTime > req_time && *sample_index > 0) { 367 --*sample_index; 368 } 369 break; 370 } 371 372 case kFlagAfter: 373 { 374 if (sampleTime < req_time 375 && *sample_index + 1 < mNumSampleSizes) { 376 ++*sample_index; 377 } 378 break; 379 } 380 381 default: 382 break; 383 } 384 385 return OK; 386 } 387 388 time += delta * n; 389 cur_sample += n; 390 } 391 392 return ERROR_OUT_OF_RANGE; 393 } 394 395 status_t SampleTable::findSyncSampleNear( 396 uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 397 Mutex::Autolock autoLock(mLock); 398 399 *sample_index = 0; 400 401 if (mSyncSampleOffset < 0) { 402 // All samples are sync-samples. 403 *sample_index = start_sample_index; 404 return OK; 405 } 406 407 if (mNumSyncSamples == 0) { 408 *sample_index = 0; 409 return OK; 410 } 411 412 uint32_t left = 0; 413 while (left < mNumSyncSamples) { 414 uint32_t x = mSyncSamples[left]; 415 416 if (x >= start_sample_index) { 417 break; 418 } 419 420 ++left; 421 } 422 423 --left; 424 uint32_t x; 425 if (mDataSource->readAt( 426 mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) { 427 return ERROR_IO; 428 } 429 430 x = ntohl(x); 431 --x; 432 433 if (left + 1 < mNumSyncSamples) { 434 uint32_t y = mSyncSamples[left + 1]; 435 436 // our sample lies between sync samples x and y. 437 438 status_t err = mSampleIterator->seekTo(start_sample_index); 439 if (err != OK) { 440 return err; 441 } 442 443 uint32_t sample_time = mSampleIterator->getSampleTime(); 444 445 err = mSampleIterator->seekTo(x); 446 if (err != OK) { 447 return err; 448 } 449 uint32_t x_time = mSampleIterator->getSampleTime(); 450 451 err = mSampleIterator->seekTo(y); 452 if (err != OK) { 453 return err; 454 } 455 456 uint32_t y_time = mSampleIterator->getSampleTime(); 457 458 if (abs_difference(x_time, sample_time) 459 > abs_difference(y_time, sample_time)) { 460 // Pick the sync sample closest (timewise) to the start-sample. 461 x = y; 462 ++left; 463 } 464 } 465 466 switch (flags) { 467 case kFlagBefore: 468 { 469 if (x > start_sample_index) { 470 CHECK(left > 0); 471 472 if (mDataSource->readAt( 473 mSyncSampleOffset + 8 + (left - 1) * 4, &x, 4) != 4) { 474 return ERROR_IO; 475 } 476 477 x = ntohl(x); 478 --x; 479 480 CHECK(x <= start_sample_index); 481 } 482 break; 483 } 484 485 case kFlagAfter: 486 { 487 if (x < start_sample_index) { 488 if (left + 1 >= mNumSyncSamples) { 489 return ERROR_OUT_OF_RANGE; 490 } 491 492 x = mSyncSamples[left + 1]; 493 494 CHECK(x >= start_sample_index); 495 } 496 497 break; 498 } 499 500 default: 501 break; 502 } 503 504 *sample_index = x; 505 506 return OK; 507 } 508 509 status_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 510 Mutex::Autolock autoLock(mLock); 511 512 if (mSyncSampleOffset < 0) { 513 // All samples are sync-samples. 514 *sample_index = 0; 515 return OK; 516 } 517 518 uint32_t bestSampleIndex = 0; 519 size_t maxSampleSize = 0; 520 521 static const size_t kMaxNumSyncSamplesToScan = 20; 522 523 // Consider the first kMaxNumSyncSamplesToScan sync samples and 524 // pick the one with the largest (compressed) size as the thumbnail. 525 526 size_t numSamplesToScan = mNumSyncSamples; 527 if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 528 numSamplesToScan = kMaxNumSyncSamplesToScan; 529 } 530 531 for (size_t i = 0; i < numSamplesToScan; ++i) { 532 uint32_t x = mSyncSamples[i]; 533 534 // Now x is a sample index. 535 size_t sampleSize; 536 status_t err = getSampleSize_l(x, &sampleSize); 537 if (err != OK) { 538 return err; 539 } 540 541 if (i == 0 || sampleSize > maxSampleSize) { 542 bestSampleIndex = x; 543 maxSampleSize = sampleSize; 544 } 545 } 546 547 *sample_index = bestSampleIndex; 548 549 return OK; 550 } 551 552 status_t SampleTable::getSampleSize_l( 553 uint32_t sampleIndex, size_t *sampleSize) { 554 return mSampleIterator->getSampleSizeDirect( 555 sampleIndex, sampleSize); 556 } 557 558 status_t SampleTable::getMetaDataForSample( 559 uint32_t sampleIndex, 560 off_t *offset, 561 size_t *size, 562 uint32_t *decodingTime, 563 bool *isSyncSample) { 564 Mutex::Autolock autoLock(mLock); 565 566 status_t err; 567 if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 568 return err; 569 } 570 571 if (offset) { 572 *offset = mSampleIterator->getSampleOffset(); 573 } 574 575 if (size) { 576 *size = mSampleIterator->getSampleSize(); 577 } 578 579 if (decodingTime) { 580 *decodingTime = mSampleIterator->getSampleTime(); 581 } 582 583 if (isSyncSample) { 584 *isSyncSample = false; 585 if (mSyncSampleOffset < 0) { 586 // Every sample is a sync sample. 587 *isSyncSample = true; 588 } else { 589 size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 590 && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 591 ? mLastSyncSampleIndex : 0; 592 593 while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 594 ++i; 595 } 596 597 if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 598 *isSyncSample = true; 599 } 600 601 mLastSyncSampleIndex = i; 602 } 603 } 604 605 return OK; 606 } 607 608 } // namespace android 609 610