status_t MatroskaSource::read( MediaBuffer **out, const ReadOptions *options) { *out = NULL; int64_t seekTimeUs; ReadOptions::SeekMode mode; if (options && options->getSeekTo(&seekTimeUs, &mode)) { mBlockIter.seek(seekTimeUs); } if (mBlockIter.eos()) { return ERROR_END_OF_STREAM; } const mkvparser::Block *block = mBlockIter.block(); size_t size = block->GetSize(); int64_t timeUs = mBlockIter.blockTimeUs(); MediaBuffer *buffer = new MediaBuffer(size + 2); buffer->meta_data()->setInt64(kKeyTime, timeUs); buffer->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey()); long res = block->Read( mExtractor->mReader, (unsigned char *)buffer->data() + 2); if (res != 0) { return ERROR_END_OF_STREAM; } buffer->set_range(2, size); if (mType == AVC) { CHECK(size >= 2); uint8_t *data = (uint8_t *)buffer->data(); unsigned NALsize = data[2] << 8 | data[3]; CHECK_EQ(size, NALsize + 2); memcpy(data, "\x00\x00\x00\x01", 4); buffer->set_range(0, size + 2); } else if (mType == AAC) { // There's strange junk at the beginning... const uint8_t *data = (const uint8_t *)buffer->data() + 2; size_t offset = 0; while (offset < size && data[offset] != 0x21) { ++offset; } buffer->set_range(2 + offset, size - offset); } *out = buffer; #if 0 hexdump((const uint8_t *)buffer->data() + buffer->range_offset(), buffer->range_length()); #endif mBlockIter.advance(); return OK; }