/*! Constructs a DefaultCatalog with given signature and language and reads the catalog from disk. InitCheck() will be B_OK if catalog could be loaded successfully, it will give an appropriate error-code otherwise. */ DefaultCatalog::DefaultCatalog(const entry_ref &catalogOwner, const char *language, uint32 fingerprint) : HashMapCatalog("", language, fingerprint) { // We created the catalog with an invalid signature, but we fix that now. SetSignature(catalogOwner); status_t status; // search for catalog living in sub-folder of app's folder: node_ref nref; nref.device = catalogOwner.device; nref.node = catalogOwner.directory; BDirectory appDir(&nref); BString catalogName("locale/"); catalogName << kCatFolder << "/" << fSignature << "/" << fLanguageName << kCatExtension; BPath catalogPath(&appDir, catalogName.String()); status = ReadFromFile(catalogPath.Path()); if (status != B_OK) { // search in data folders directory_which which[] = { B_USER_DATA_DIRECTORY, B_COMMON_DATA_DIRECTORY, B_SYSTEM_DATA_DIRECTORY }; for (size_t i = 0; i < sizeof(which) / sizeof(which[0]); i++) { BPath path; if (find_directory(which[i], &path) == B_OK) { BString catalogName(path.Path()); catalogName << "/locale/" << kCatFolder << "/" << fSignature << "/" << fLanguageName << kCatExtension; status = ReadFromFile(catalogName.String()); if (status == B_OK) break; } } } if (status != B_OK) { // give lowest priority to catalog embedded as resource in application // executable, so they can be overridden easily. status = ReadFromResource(catalogOwner); } fInitCheck = status; }
nsresult nsRawReader::ReadMetadata(nsVideoInfo* aInfo, nsHTMLMediaElement::MetadataTags** aTags) { NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread."); MediaResource* resource = mDecoder->GetResource(); NS_ASSERTION(resource, "Decoder has no media resource"); if (!ReadFromResource(resource, reinterpret_cast<uint8_t*>(&mMetadata), sizeof(mMetadata))) return NS_ERROR_FAILURE; // Validate the header if (!(mMetadata.headerPacketID == 0 /* Packet ID of 0 for the header*/ && mMetadata.codecID == RAW_ID /* "YUV" */ && mMetadata.majorVersion == 0 && mMetadata.minorVersion == 1)) return NS_ERROR_FAILURE; CheckedUint32 dummy = CheckedUint32(static_cast<uint32_t>(mMetadata.frameWidth)) * static_cast<uint32_t>(mMetadata.frameHeight); NS_ENSURE_TRUE(dummy.isValid(), NS_ERROR_FAILURE); if (mMetadata.aspectDenominator == 0 || mMetadata.framerateDenominator == 0) return NS_ERROR_FAILURE; // Invalid data // Determine and verify frame display size. float pixelAspectRatio = static_cast<float>(mMetadata.aspectNumerator) / mMetadata.aspectDenominator; nsIntSize display(mMetadata.frameWidth, mMetadata.frameHeight); ScaleDisplayByAspectRatio(display, pixelAspectRatio); mPicture = nsIntRect(0, 0, mMetadata.frameWidth, mMetadata.frameHeight); nsIntSize frameSize(mMetadata.frameWidth, mMetadata.frameHeight); if (!nsVideoInfo::ValidateVideoRegion(frameSize, mPicture, display)) { // Video track's frame sizes will overflow. Fail. return NS_ERROR_FAILURE; } mInfo.mHasVideo = true; mInfo.mHasAudio = false; mInfo.mDisplay = display; mFrameRate = static_cast<float>(mMetadata.framerateNumerator) / mMetadata.framerateDenominator; // Make some sanity checks if (mFrameRate > 45 || mFrameRate == 0 || pixelAspectRatio == 0 || mMetadata.frameWidth > 2000 || mMetadata.frameHeight > 2000 || mMetadata.chromaChannelBpp != 4 || mMetadata.lumaChannelBpp != 8 || mMetadata.colorspace != 1 /* 4:2:0 */) return NS_ERROR_FAILURE; mFrameSize = mMetadata.frameWidth * mMetadata.frameHeight * (mMetadata.lumaChannelBpp + mMetadata.chromaChannelBpp) / 8.0 + sizeof(nsRawPacketHeader); int64_t length = resource->GetLength(); if (length != -1) { mozilla::ReentrantMonitorAutoEnter autoMonitor(mDecoder->GetReentrantMonitor()); mDecoder->GetStateMachine()->SetDuration(USECS_PER_S * (length - sizeof(nsRawVideoHeader)) / (mFrameSize * mFrameRate)); } *aInfo = mInfo; *aTags = nullptr; return NS_OK; }
/*! Constructs a DefaultCatalog and reads it from the resources of the given entry-ref (which usually is an app- or add-on-file). InitCheck() will be B_OK if catalog could be loaded successfully, it will give an appropriate error-code otherwise. */ DefaultCatalog::DefaultCatalog(entry_ref *appOrAddOnRef) : HashMapCatalog("", "", 0) { fInitCheck = ReadFromResource(*appOrAddOnRef); }
bool nsRawReader::DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) { NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread."); // Record number of frames decoded and parsed. Automatically update the // stats counters using the AutoNotifyDecoded stack-based class. uint32_t parsed = 0, decoded = 0; nsMediaDecoder::AutoNotifyDecoded autoNotify(mDecoder, parsed, decoded); if (!mFrameSize) return false; // Metadata read failed. We should refuse to play. int64_t currentFrameTime = USECS_PER_S * mCurrentFrame / mFrameRate; uint32_t length = mFrameSize - sizeof(nsRawPacketHeader); nsAutoArrayPtr<uint8_t> buffer(new uint8_t[length]); MediaResource* resource = mDecoder->GetResource(); NS_ASSERTION(resource, "Decoder has no media resource"); // We're always decoding one frame when called while(true) { nsRawPacketHeader header; // Read in a packet header and validate if (!(ReadFromResource(resource, reinterpret_cast<uint8_t*>(&header), sizeof(header))) || !(header.packetID == 0xFF && header.codecID == RAW_ID /* "YUV" */)) { return false; } if (!ReadFromResource(resource, buffer, length)) { return false; } parsed++; if (currentFrameTime >= aTimeThreshold) break; mCurrentFrame++; currentFrameTime += static_cast<double>(USECS_PER_S) / mFrameRate; } VideoData::YCbCrBuffer b; b.mPlanes[0].mData = buffer; b.mPlanes[0].mStride = mMetadata.frameWidth * mMetadata.lumaChannelBpp / 8.0; b.mPlanes[0].mHeight = mMetadata.frameHeight; b.mPlanes[0].mWidth = mMetadata.frameWidth; b.mPlanes[0].mOffset = b.mPlanes[0].mSkip = 0; uint32_t cbcrStride = mMetadata.frameWidth * mMetadata.chromaChannelBpp / 8.0; b.mPlanes[1].mData = buffer + mMetadata.frameHeight * b.mPlanes[0].mStride; b.mPlanes[1].mStride = cbcrStride; b.mPlanes[1].mHeight = mMetadata.frameHeight / 2; b.mPlanes[1].mWidth = mMetadata.frameWidth / 2; b.mPlanes[1].mOffset = b.mPlanes[1].mSkip = 0; b.mPlanes[2].mData = b.mPlanes[1].mData + mMetadata.frameHeight * cbcrStride / 2; b.mPlanes[2].mStride = cbcrStride; b.mPlanes[2].mHeight = mMetadata.frameHeight / 2; b.mPlanes[2].mWidth = mMetadata.frameWidth / 2; b.mPlanes[2].mOffset = b.mPlanes[2].mSkip = 0; VideoData *v = VideoData::Create(mInfo, mDecoder->GetImageContainer(), -1, currentFrameTime, currentFrameTime + (USECS_PER_S / mFrameRate), b, 1, // In raw video every frame is a keyframe -1, mPicture); if (!v) return false; mVideoQueue.Push(v); mCurrentFrame++; decoded++; currentFrameTime += USECS_PER_S / mFrameRate; return true; }