예제 #1
0
/* static */ already_AddRefed<IDecodingTask>
DecoderFactory::CreateMetadataDecoder(DecoderType aType,
                                      NotNull<RasterImage*> aImage,
                                      NotNull<SourceBuffer*> aSourceBuffer,
                                      int aSampleSize)
{
  if (aType == DecoderType::UNKNOWN) {
    return nullptr;
  }

  RefPtr<Decoder> decoder =
    GetDecoder(aType, aImage, /* aIsRedecode = */ false);
  MOZ_ASSERT(decoder, "Should have a decoder now");

  // Initialize the decoder.
  decoder->SetMetadataDecode(true);
  decoder->SetIterator(aSourceBuffer->Iterator());
  decoder->SetSampleSize(aSampleSize);

  decoder->Init();
  if (NS_FAILED(decoder->GetDecoderError())) {
    return nullptr;
  }

  RefPtr<IDecodingTask> task = new MetadataDecodingTask(WrapNotNull(decoder));
  return task.forget();
}
예제 #2
0
/* static */ already_AddRefed<IDecodingTask>
DecoderFactory::CreateAnimationDecoder(DecoderType aType,
                                       NotNull<RasterImage*> aImage,
                                       NotNull<SourceBuffer*> aSourceBuffer,
                                       DecoderFlags aDecoderFlags,
                                       SurfaceFlags aSurfaceFlags)
{
  if (aType == DecoderType::UNKNOWN) {
    return nullptr;
  }

  MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG,
             "Calling CreateAnimationDecoder for non-animating DecoderType");

  RefPtr<Decoder> decoder =
    GetDecoder(aType, aImage, /* aIsRedecode = */ true);
  MOZ_ASSERT(decoder, "Should have a decoder now");

  // Initialize the decoder.
  decoder->SetMetadataDecode(false);
  decoder->SetIterator(aSourceBuffer->Iterator());
  decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::IS_REDECODE);
  decoder->SetSurfaceFlags(aSurfaceFlags);

  decoder->Init();
  if (NS_FAILED(decoder->GetDecoderError())) {
    return nullptr;
  }

  RefPtr<IDecodingTask> task = new DecodingTask(WrapNotNull(decoder));
  return task.forget();
}
예제 #3
0
/* static */ already_AddRefed<IDecodingTask>
DecoderFactory::CreateDecoder(DecoderType aType,
                              NotNull<RasterImage*> aImage,
                              NotNull<SourceBuffer*> aSourceBuffer,
                              const IntSize& aIntrinsicSize,
                              const IntSize& aOutputSize,
                              DecoderFlags aDecoderFlags,
                              SurfaceFlags aSurfaceFlags)
{
  if (aType == DecoderType::UNKNOWN) {
    return nullptr;
  }

  // Create an anonymous decoder. Interaction with the SurfaceCache and the
  // owning RasterImage will be mediated by DecodedSurfaceProvider.
  RefPtr<Decoder> decoder =
    GetDecoder(aType, nullptr, bool(aDecoderFlags & DecoderFlags::IS_REDECODE));
  MOZ_ASSERT(decoder, "Should have a decoder now");

  // Initialize the decoder.
  decoder->SetMetadataDecode(false);
  decoder->SetIterator(aSourceBuffer->Iterator());
  decoder->SetOutputSize(aOutputSize);
  decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::FIRST_FRAME_ONLY);
  decoder->SetSurfaceFlags(aSurfaceFlags);

  if (NS_FAILED(decoder->Init())) {
    return nullptr;
  }

  // Create a DecodedSurfaceProvider which will manage the decoding process and
  // make this decoder's output available in the surface cache.
  SurfaceKey surfaceKey =
    RasterSurfaceKey(aOutputSize, aSurfaceFlags, PlaybackType::eStatic);
  auto provider = MakeNotNull<RefPtr<DecodedSurfaceProvider>>(
    aImage, surfaceKey, WrapNotNull(decoder));
  if (aDecoderFlags & DecoderFlags::CANNOT_SUBSTITUTE) {
    provider->Availability().SetCannotSubstitute();
  }

  // Attempt to insert the surface provider into the surface cache right away so
  // we won't trigger any more decoders with the same parameters.
  if (SurfaceCache::Insert(provider) != InsertOutcome::SUCCESS) {
    return nullptr;
  }

  // Return the surface provider in its IDecodingTask guise.
  RefPtr<IDecodingTask> task = provider.get();
  return task.forget();
}
예제 #4
0
/* static */ already_AddRefed<IDecodingTask>
DecoderFactory::CreateAnimationDecoder(DecoderType aType,
                                       NotNull<RasterImage*> aImage,
                                       NotNull<SourceBuffer*> aSourceBuffer,
                                       const IntSize& aIntrinsicSize,
                                       DecoderFlags aDecoderFlags,
                                       SurfaceFlags aSurfaceFlags)
{
  if (aType == DecoderType::UNKNOWN) {
    return nullptr;
  }

  MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG,
             "Calling CreateAnimationDecoder for non-animating DecoderType");

  // Create an anonymous decoder. Interaction with the SurfaceCache and the
  // owning RasterImage will be mediated by AnimationSurfaceProvider.
  RefPtr<Decoder> decoder = GetDecoder(aType, nullptr, /* aIsRedecode = */ true);
  MOZ_ASSERT(decoder, "Should have a decoder now");

  // Initialize the decoder.
  decoder->SetMetadataDecode(false);
  decoder->SetIterator(aSourceBuffer->Iterator());
  decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::IS_REDECODE);
  decoder->SetSurfaceFlags(aSurfaceFlags);

  if (NS_FAILED(decoder->Init())) {
    return nullptr;
  }

  // Create an AnimationSurfaceProvider which will manage the decoding process
  // and make this decoder's output available in the surface cache.
  SurfaceKey surfaceKey =
    RasterSurfaceKey(aIntrinsicSize, aSurfaceFlags, PlaybackType::eAnimated);
  auto provider = MakeNotNull<RefPtr<AnimationSurfaceProvider>>(
    aImage, surfaceKey, WrapNotNull(decoder));

  // Attempt to insert the surface provider into the surface cache right away so
  // we won't trigger any more decoders with the same parameters.
  if (SurfaceCache::Insert(provider) != InsertOutcome::SUCCESS) {
    return nullptr;
  }

  // Return the surface provider in its IDecodingTask guise.
  RefPtr<IDecodingTask> task = provider.get();
  return task.forget();
}
예제 #5
0
/* static */ already_AddRefed<Decoder>
DecoderFactory::CreateAnonymousDecoder(DecoderType aType,
                                       NotNull<SourceBuffer*> aSourceBuffer,
                                       const Maybe<IntSize>& aTargetSize,
                                       SurfaceFlags aSurfaceFlags)
{
  if (aType == DecoderType::UNKNOWN) {
    return nullptr;
  }

  RefPtr<Decoder> decoder =
    GetDecoder(aType, /* aImage = */ nullptr, /* aIsRedecode = */ false);
  MOZ_ASSERT(decoder, "Should have a decoder now");

  // Initialize the decoder.
  decoder->SetMetadataDecode(false);
  decoder->SetIterator(aSourceBuffer->Iterator());

  // Anonymous decoders are always transient; we don't want to optimize surfaces
  // or do any other expensive work that might be wasted.
  DecoderFlags decoderFlags = DecoderFlags::IMAGE_IS_TRANSIENT;

  // Without an image, the decoder can't store anything in the SurfaceCache, so
  // callers will only be able to retrieve the most recent frame via
  // Decoder::GetCurrentFrame(). That means that anonymous decoders should
  // always be first-frame-only decoders, because nobody ever wants the *last*
  // frame.
  decoderFlags |= DecoderFlags::FIRST_FRAME_ONLY;

  decoder->SetDecoderFlags(decoderFlags);
  decoder->SetSurfaceFlags(aSurfaceFlags);

  // Set a target size for downscale-during-decode if applicable.
  if (aTargetSize) {
    DebugOnly<nsresult> rv = decoder->SetTargetSize(*aTargetSize);
    MOZ_ASSERT(NS_SUCCEEDED(rv), "Bad downscale-during-decode target size?");
  }

  decoder->Init();
  if (NS_FAILED(decoder->GetDecoderError())) {
    return nullptr;
  }

  return decoder.forget();
}
예제 #6
0
/* static */ already_AddRefed<IDecodingTask>
DecoderFactory::CreateDecoder(DecoderType aType,
                              NotNull<RasterImage*> aImage,
                              NotNull<SourceBuffer*> aSourceBuffer,
                              const Maybe<IntSize>& aTargetSize,
                              DecoderFlags aDecoderFlags,
                              SurfaceFlags aSurfaceFlags,
                              int aSampleSize)
{
  if (aType == DecoderType::UNKNOWN) {
    return nullptr;
  }

  RefPtr<Decoder> decoder =
    GetDecoder(aType, aImage, bool(aDecoderFlags & DecoderFlags::IS_REDECODE));
  MOZ_ASSERT(decoder, "Should have a decoder now");

  // Initialize the decoder.
  decoder->SetMetadataDecode(false);
  decoder->SetIterator(aSourceBuffer->Iterator());
  decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::FIRST_FRAME_ONLY);
  decoder->SetSurfaceFlags(aSurfaceFlags);
  decoder->SetSampleSize(aSampleSize);

  // Set a target size for downscale-during-decode if applicable.
  if (aTargetSize) {
    DebugOnly<nsresult> rv = decoder->SetTargetSize(*aTargetSize);
    MOZ_ASSERT(NS_SUCCEEDED(rv), "Bad downscale-during-decode target size?");
  }

  decoder->Init();
  if (NS_FAILED(decoder->GetDecoderError())) {
    return nullptr;
  }

  RefPtr<IDecodingTask> task = new DecodingTask(WrapNotNull(decoder));
  return task.forget();
}
예제 #7
0
/* static */ already_AddRefed<Decoder>
DecoderFactory::CreateAnonymousMetadataDecoder(DecoderType aType,
                                               NotNull<SourceBuffer*> aSourceBuffer)
{
  if (aType == DecoderType::UNKNOWN) {
    return nullptr;
  }

  RefPtr<Decoder> decoder =
    GetDecoder(aType, /* aImage = */ nullptr, /* aIsRedecode = */ false);
  MOZ_ASSERT(decoder, "Should have a decoder now");

  // Initialize the decoder.
  decoder->SetMetadataDecode(true);
  decoder->SetIterator(aSourceBuffer->Iterator());
  decoder->SetDecoderFlags(DecoderFlags::FIRST_FRAME_ONLY);

  if (NS_FAILED(decoder->Init())) {
    return nullptr;
  }

  return decoder.forget();
}