Beispiel #1
0
SharedImage* ImageContainerChild::CreateSharedImageFromData(Image* image)
{
  NS_ABORT_IF_FALSE(InImageBridgeChildThread(),
                  "Should be in ImageBridgeChild thread.");
  
  ++mActiveImageCount;

  // TODO: I don't test for BasicManager()->IsCompositingCheap() here,
  // is this a problem? (the equvivalent code in PCompositor does that)
  if (image->GetFormat() == Image::PLANAR_YCBCR ) {
    PlanarYCbCrImage *YCbCrImage = static_cast<PlanarYCbCrImage*>(image);
    const PlanarYCbCrImage::Data *data = YCbCrImage->GetData();
    NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
    
    nsRefPtr<gfxSharedImageSurface> tempBufferY;
    nsRefPtr<gfxSharedImageSurface> tempBufferU;
    nsRefPtr<gfxSharedImageSurface> tempBufferV;
    
    if (!this->AllocBuffer(data->mYSize, gfxASurface::CONTENT_ALPHA,
                           getter_AddRefs(tempBufferY)) ||
        !this->AllocBuffer(data->mCbCrSize, gfxASurface::CONTENT_ALPHA,
                           getter_AddRefs(tempBufferU)) ||
        !this->AllocBuffer(data->mCbCrSize, gfxASurface::CONTENT_ALPHA,
                           getter_AddRefs(tempBufferV))) {
      NS_RUNTIMEABORT("creating SharedImage failed!");
    }

    for (int i = 0; i < data->mYSize.height; i++) {
      memcpy(tempBufferY->Data() + i * tempBufferY->Stride(),
             data->mYChannel + i * data->mYStride,
             data->mYSize.width);
    }
    for (int i = 0; i < data->mCbCrSize.height; i++) {
      memcpy(tempBufferU->Data() + i * tempBufferU->Stride(),
             data->mCbChannel + i * data->mCbCrStride,
             data->mCbCrSize.width);
      memcpy(tempBufferV->Data() + i * tempBufferV->Stride(),
             data->mCrChannel + i * data->mCbCrStride,
             data->mCbCrSize.width);
    }

    SharedImage* result = new SharedImage( 
              *(new YUVImage(tempBufferY->GetShmem(),
                                             tempBufferU->GetShmem(),
                                             tempBufferV->GetShmem(),
                                             data->GetPictureRect())));
    NS_ABORT_IF_FALSE(result->type() == SharedImage::TYUVImage,
                      "SharedImage type not set correctly");
    return result;
  } else if (image->GetFormat() == Image::GONK_IO_SURFACE) {
    GonkIOSurfaceImage* gonkImage = static_cast<GonkIOSurfaceImage*>(image);
    SharedImage* result = new SharedImage(gonkImage->GetSurfaceDescriptor());
    return result;
  } else {
    NS_RUNTIMEABORT("TODO: Only YUVImage is supported here right now.");
  }
  return nsnull;
}
SharedImage* ImageContainerChild::AsSharedImage(Image* aImage)
{
#ifdef MOZ_WIDGET_GONK
  if (aImage->GetFormat() == GONK_IO_SURFACE) {
    GonkIOSurfaceImage* gonkImage = static_cast<GonkIOSurfaceImage*>(aImage);
    SharedImage* result = new SharedImage(gonkImage->GetSurfaceDescriptor());
    return result;
  } else if (aImage->GetFormat() == GRALLOC_PLANAR_YCBCR) {
    GrallocPlanarYCbCrImage* GrallocImage = static_cast<GrallocPlanarYCbCrImage*>(aImage);
    SharedImage* result = new SharedImage(GrallocImage->GetSurfaceDescriptor());
    return result;
  }
#endif
  return nullptr; // XXX: bug 773440
}
SharedImage* ImageContainerChild::CreateSharedImageFromData(Image* image)
{
    NS_ABORT_IF_FALSE(InImageBridgeChildThread(),
                      "Should be in ImageBridgeChild thread.");

    if (!image) {
        return nullptr;
    }
    if (image->GetFormat() == PLANAR_YCBCR ) {
        PlanarYCbCrImage *planarYCbCrImage = static_cast<PlanarYCbCrImage*>(image);
        const PlanarYCbCrImage::Data *data = planarYCbCrImage->GetData();
        NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
        if (!data) {
            return nullptr;
        }

        SharedMemory::SharedMemoryType shmType = OptimalShmemType();
        size_t size = ShmemYCbCrImage::ComputeMinBufferSize(data->mYSize,
                      data->mCbCrSize);
        Shmem shmem;
        if (!AllocUnsafeShmem(size, shmType, &shmem)) {
            return nullptr;
        }

        ShmemYCbCrImage::InitializeBufferInfo(shmem.get<uint8_t>(),
                                              data->mYSize,
                                              data->mCbCrSize);
        ShmemYCbCrImage shmemImage(shmem);

        if (!shmemImage.IsValid() || shmem.Size<uint8_t>() < size) {
            DeallocShmem(shmem);
            return nullptr;
        }

        for (int i = 0; i < data->mYSize.height; i++) {
            memcpy(shmemImage.GetYData() + i * shmemImage.GetYStride(),
                   data->mYChannel + i * data->mYStride,
                   data->mYSize.width);
        }
        for (int i = 0; i < data->mCbCrSize.height; i++) {
            memcpy(shmemImage.GetCbData() + i * shmemImage.GetCbCrStride(),
                   data->mCbChannel + i * data->mCbCrStride,
                   data->mCbCrSize.width);
            memcpy(shmemImage.GetCrData() + i * shmemImage.GetCbCrStride(),
                   data->mCrChannel + i * data->mCbCrStride,
                   data->mCbCrSize.width);
        }

        ++mActiveImageCount;
        SharedImage* result = new SharedImage(YCbCrImage(shmem, 0, data->GetPictureRect()));
        return result;
#ifdef MOZ_WIDGET_GONK
    } else if (image->GetFormat() == GONK_IO_SURFACE) {
        GonkIOSurfaceImage* gonkImage = static_cast<GonkIOSurfaceImage*>(image);
        SharedImage* result = new SharedImage(gonkImage->GetSurfaceDescriptor());
        return result;
    } else if (image->GetFormat() == GRALLOC_PLANAR_YCBCR) {
        GrallocPlanarYCbCrImage* GrallocImage = static_cast<GrallocPlanarYCbCrImage*>(image);
        SharedImage* result = new SharedImage(GrallocImage->GetSurfaceDescriptor());
        return result;
#endif
    } else {
        NS_RUNTIMEABORT("TODO: Only YCbCrImage is supported here right now.");
    }
    return nullptr;
}