void
MediaEngineGonkVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight) {
  layers::GrallocImage *nativeImage = static_cast<layers::GrallocImage*>(aImage);
  android::sp<GraphicBuffer> graphicBuffer = nativeImage->GetGraphicBuffer();
  void *pMem = nullptr;
  // Bug 1109957 size will be wrong if width or height are odd
  uint32_t size = aWidth * aHeight * 3 / 2;
  MOZ_ASSERT(!(aWidth & 1) && !(aHeight & 1));

  graphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_MASK, &pMem);

  uint8_t* srcPtr = static_cast<uint8_t*>(pMem);

  // Create a video frame and append it to the track.
  RefPtr<layers::PlanarYCbCrImage> image = new GonkCameraImage();

  uint32_t dstWidth;
  uint32_t dstHeight;

  if (mRotation == 90 || mRotation == 270) {
    dstWidth = aHeight;
    dstHeight = aWidth;
  } else {
    dstWidth = aWidth;
    dstHeight = aHeight;
  }

  uint32_t half_width = dstWidth / 2;

  MOZ_ASSERT(mTextureClientAllocator);
  RefPtr<layers::TextureClient> textureClient
    = mTextureClientAllocator->CreateOrRecycle(gfx::SurfaceFormat::YUV,
                                               gfx::IntSize(dstWidth, dstHeight),
                                               layers::BackendSelector::Content,
                                               layers::TextureFlags::DEFAULT,
                                               layers::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
  if (textureClient) {
    android::sp<android::GraphicBuffer> destBuffer =
      static_cast<layers::GrallocTextureData*>(textureClient->GetInternalData())->GetGraphicBuffer();

    void* destMem = nullptr;
    destBuffer->lock(android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, &destMem);
    uint8_t* dstPtr = static_cast<uint8_t*>(destMem);

    int32_t yStride = destBuffer->getStride();
    // Align to 16 bytes boundary
    int32_t uvStride = ((yStride / 2) + 15) & ~0x0F;

    libyuv::ConvertToI420(srcPtr, size,
                          dstPtr, yStride,
                          dstPtr + (yStride * dstHeight + (uvStride * dstHeight / 2)), uvStride,
                          dstPtr + (yStride * dstHeight), uvStride,
                          0, 0,
                          graphicBuffer->getStride(), aHeight,
                          aWidth, aHeight,
                          static_cast<libyuv::RotationMode>(mRotation),
                          libyuv::FOURCC_NV21);
    destBuffer->unlock();

    image->AsGrallocImage()->AdoptData(textureClient, gfx::IntSize(dstWidth, dstHeight));
  } else {
    // Handle out of gralloc case.
    image = mImageContainer->CreatePlanarYCbCrImage();
    uint8_t* dstPtr = image->AsPlanarYCbCrImage()->AllocateAndGetNewBuffer(size);

    libyuv::ConvertToI420(srcPtr, size,
                          dstPtr, dstWidth,
                          dstPtr + (dstWidth * dstHeight), half_width,
                          dstPtr + (dstWidth * dstHeight * 5 / 4), half_width,
                          0, 0,
                          graphicBuffer->getStride(), aHeight,
                          aWidth, aHeight,
                          static_cast<libyuv::RotationMode>(mRotation),
                          ConvertPixelFormatToFOURCC(graphicBuffer->getPixelFormat()));

    const uint8_t lumaBpp = 8;
    const uint8_t chromaBpp = 4;

    layers::PlanarYCbCrData data;
    data.mYChannel = dstPtr;
    data.mYSize = IntSize(dstWidth, dstHeight);
    data.mYStride = dstWidth * lumaBpp / 8;
    data.mCbCrStride = dstWidth * chromaBpp / 8;
    data.mCbChannel = dstPtr + dstHeight * data.mYStride;
    data.mCrChannel = data.mCbChannel + data.mCbCrStride * (dstHeight / 2);
    data.mCbCrSize = IntSize(dstWidth / 2, dstHeight / 2);
    data.mPicX = 0;
    data.mPicY = 0;
    data.mPicSize = IntSize(dstWidth, dstHeight);
    data.mStereoMode = StereoMode::MONO;

    image->AsPlanarYCbCrImage()->AdoptData(data);
  }
  graphicBuffer->unlock();

  // Implicitly releases last preview image.
  mImage = image.forget();
}
Example #2
0
already_AddRefed<IDBRequest>
IDBCursor::Update(JSContext* aCx, JS::Handle<JS::Value> aValue,
                  ErrorResult& aRv)
{
  AssertIsOnOwningThread();

  if (!mTransaction->IsOpen()) {
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
    return nullptr;
  }

  if (!mTransaction->IsWriteAllowed()) {
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
    return nullptr;
  }

  if (mTransaction->GetMode() == IDBTransaction::CLEANUP ||
      IsSourceDeleted() ||
      !mHaveValue ||
      mType == Type_ObjectStoreKey ||
      mType == Type_IndexKey ||
      mContinueCalled) {
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
    return nullptr;
  }

  MOZ_ASSERT(mType == Type_ObjectStore || mType == Type_Index);
  MOZ_ASSERT(!mKey.IsUnset());
  MOZ_ASSERT_IF(mType == Type_Index, !mPrimaryKey.IsUnset());

  IDBObjectStore* objectStore;
  if (mType == Type_ObjectStore) {
    objectStore = mSourceObjectStore;
  } else {
    objectStore = mSourceIndex->ObjectStore();
  }

  MOZ_ASSERT(objectStore);

  IDBObjectStore::ValueWrapper valueWrapper(aCx, aValue);

  const Key& primaryKey = (mType == Type_ObjectStore) ? mKey : mPrimaryKey;

  RefPtr<IDBRequest> request;

  if (objectStore->HasValidKeyPath()) {
    if (!valueWrapper.Clone(aCx)) {
      aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
      return nullptr;
    }

    // Make sure the object given has the correct keyPath value set on it.
    const KeyPath& keyPath = objectStore->GetKeyPath();
    Key key;

    aRv = keyPath.ExtractKey(aCx, valueWrapper.Value(), key);
    if (aRv.Failed()) {
      return nullptr;
    }

    if (key != primaryKey) {
      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
      return nullptr;
    }

    request = objectStore->AddOrPut(aCx,
                                    valueWrapper,
                                    /* aKey */ JS::UndefinedHandleValue,
                                    /* aOverwrite */ true,
                                    /* aFromCursor */ true,
                                    aRv);
    if (aRv.Failed()) {
      return nullptr;
    }
  }
  else {
    JS::Rooted<JS::Value> keyVal(aCx);
    aRv = primaryKey.ToJSVal(aCx, &keyVal);
    if (aRv.Failed()) {
      return nullptr;
    }

    request = objectStore->AddOrPut(aCx,
                                    valueWrapper,
                                    keyVal,
                                    /* aOverwrite */ true,
                                    /* aFromCursor */ true,
                                    aRv);
    if (aRv.Failed()) {
      return nullptr;
    }
  }

  request->SetSource(this);

  if (mType == Type_ObjectStore) {
    IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
                   "database(%s).transaction(%s).objectStore(%s)."
                   "cursor(%s).update(%s)",
                 "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.update()",
                 IDB_LOG_ID_STRING(),
                 mTransaction->LoggingSerialNumber(),
                 request->LoggingSerialNumber(),
                 IDB_LOG_STRINGIFY(mTransaction->Database()),
                 IDB_LOG_STRINGIFY(mTransaction),
                 IDB_LOG_STRINGIFY(objectStore),
                 IDB_LOG_STRINGIFY(mDirection),
                 IDB_LOG_STRINGIFY(objectStore, primaryKey));
  } else {
    IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
                   "database(%s).transaction(%s).objectStore(%s)."
                   "index(%s).cursor(%s).update(%s)",
                 "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.update()",
                 IDB_LOG_ID_STRING(),
                 mTransaction->LoggingSerialNumber(),
                 request->LoggingSerialNumber(),
                 IDB_LOG_STRINGIFY(mTransaction->Database()),
                 IDB_LOG_STRINGIFY(mTransaction),
                 IDB_LOG_STRINGIFY(objectStore),
                 IDB_LOG_STRINGIFY(mSourceIndex),
                 IDB_LOG_STRINGIFY(mDirection),
                 IDB_LOG_STRINGIFY(objectStore, primaryKey));
  }

  return request.forget();
}
already_AddRefed<GLContextEGL>
GLContextEGL::CreateGLContext(CreateContextFlags flags,
                const SurfaceCaps& caps,
                bool isOffscreen,
                EGLConfig config,
                EGLSurface surface,
                nsACString* const out_failureId)
{
    if (sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API) == LOCAL_EGL_FALSE) {
        *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_ES");
        NS_WARNING("Failed to bind API to GLES!");
        return nullptr;
    }

    std::vector<EGLint> required_attribs;
    required_attribs.push_back(LOCAL_EGL_CONTEXT_CLIENT_VERSION);
    if (flags & CreateContextFlags::PREFER_ES3) {
        required_attribs.push_back(3);
    } else {
        required_attribs.push_back(2);
    }

    std::vector<EGLint> robustness_attribs;
    std::vector<EGLint> rbab_attribs; // RBAB: Robust Buffer Access Behavior
    if (flags & CreateContextFlags::PREFER_ROBUSTNESS) {
        if (sEGLLibrary.IsExtensionSupported(GLLibraryEGL::EXT_create_context_robustness)) {
            robustness_attribs = required_attribs;
            robustness_attribs.push_back(LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT);
            robustness_attribs.push_back(LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT);
            // Skip EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, since it doesn't help us.
        }

        if (sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_create_context)) {
            rbab_attribs = required_attribs;
            rbab_attribs.push_back(LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR);
            rbab_attribs.push_back(LOCAL_EGL_LOSE_CONTEXT_ON_RESET_KHR);
            rbab_attribs.push_back(LOCAL_EGL_CONTEXT_FLAGS_KHR);
            rbab_attribs.push_back(LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR);
        }
    }

    const auto fnCreate = [&](const std::vector<EGLint>& attribs) {
        auto terminated_attribs = attribs;

        for (const auto& cur : kTerminationAttribs) {
            terminated_attribs.push_back(cur);
        }

        return sEGLLibrary.fCreateContext(EGL_DISPLAY(), config, EGL_NO_CONTEXT,
                                          terminated_attribs.data());
    };

    EGLContext context;
    do {
        if (rbab_attribs.size()) {
            context = fnCreate(rbab_attribs);
            if (context)
                break;
            NS_WARNING("Failed to create EGLContext with rbab_attribs");
        }

        if (robustness_attribs.size()) {
            context = fnCreate(robustness_attribs);
            if (context)
                break;
            NS_WARNING("Failed to create EGLContext with robustness_attribs");
        }

        context = fnCreate(required_attribs);
        if (context)
            break;
        NS_WARNING("Failed to create EGLContext with required_attribs");

        *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_CREATE");
        return nullptr;
    } while (false);
    MOZ_ASSERT(context);

    RefPtr<GLContextEGL> glContext = new GLContextEGL(flags, caps, isOffscreen, config,
                                                      surface, context);
    if (!glContext->Init()) {
        *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_INIT");
        return nullptr;
    }

    return glContext.forget();
}
ServiceWorkerCloneData::~ServiceWorkerCloneData() {
  RefPtr<ipc::SharedJSAllocatedData> sharedData = TakeSharedData();
  if (sharedData) {
    NS_ProxyRelease(__func__, mEventTarget, sharedData.forget());
  }
}
Example #5
0
already_AddRefed<Promise>
PresentationRequest::StartWithDevice(const nsAString& aDeviceId,
                                     ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
  if (NS_WARN_IF(!global)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }

  // Get the origin.
  nsAutoString origin;
  nsresult rv = nsContentUtils::GetUTFOrigin(global->PrincipalOrNull(), origin);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    aRv.Throw(rv);
    return nullptr;
  }

  nsCOMPtr<nsIDocument> doc = GetOwner()->GetExtantDoc();
  if (NS_WARN_IF(!doc)) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  if (IsProhibitMixedSecurityContexts(doc) &&
      !IsAllURLAuthenticated()) {
    promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
    return promise.forget();
  }

  if (doc->GetSandboxFlags() & SANDBOXED_PRESENTATION) {
    promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
    return promise.forget();
  }

  // Generate a session ID.
  nsCOMPtr<nsIUUIDGenerator> uuidgen =
    do_GetService("@mozilla.org/uuid-generator;1");
  if(NS_WARN_IF(!uuidgen)) {
    promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
    return promise.forget();
  }

  nsID uuid;
  uuidgen->GenerateUUIDInPlace(&uuid);
  char buffer[NSID_LENGTH];
  uuid.ToProvidedString(buffer);
  nsAutoString id;
  CopyASCIItoUTF16(buffer, id);

  nsCOMPtr<nsIPresentationService> service =
    do_GetService(PRESENTATION_SERVICE_CONTRACTID);
  if(NS_WARN_IF(!service)) {
    promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
    return promise.forget();
  }

  nsCOMPtr<nsIPresentationServiceCallback> callback =
    new PresentationRequesterCallback(this, id, promise);
  rv = service->StartSession(mUrls, id, origin, aDeviceId, GetOwner()->WindowID(), callback);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
  }

  return promise.forget();
}
already_AddRefed<PlatformDecoderModule> CreateBlankDecoderModule()
{
  RefPtr<PlatformDecoderModule> pdm = new BlankDecoderModule();
  return pdm.forget();
}
already_AddRefed<AbstractThread>
CreateXPCOMAbstractThreadWrapper(nsIThread* aThread, bool aRequireTailDispatch)
{
  RefPtr<XPCOMThreadWrapper> wrapper = new XPCOMThreadWrapper(aThread, aRequireTailDispatch);
  return wrapper.forget();
}
Example #8
0
already_AddRefed<Layer> CreateLayerTree(
    const char* aLayerTreeDescription,
    nsIntRegion* aVisibleRegions,
    const Matrix4x4* aTransforms,
    RefPtr<LayerManager>& manager,
    nsTArray<RefPtr<Layer> >& aLayersOut) {

  aLayersOut.Clear();

  if (!manager) {
    manager = new TestLayerManager();
  }

  RefPtr<Layer> rootLayer = nullptr;
  RefPtr<ContainerLayer> parentContainerLayer = nullptr;
  RefPtr<Layer> lastLayer = nullptr;
  int layerNumber = 0;
  for (size_t i = 0; i < strlen(aLayerTreeDescription); i++) {
    if (aLayerTreeDescription[i] == '(') {
      if (!lastLayer) {
        printf("Syntax error, likely '(' character isn't preceded by a container.\n");
        MOZ_CRASH();
      }
      parentContainerLayer = lastLayer->AsContainerLayer();
      if (!parentContainerLayer) {
        printf("Layer before '(' must be a container.\n");
        MOZ_CRASH();
      }
    } else if (aLayerTreeDescription[i] == ')') {
      parentContainerLayer = parentContainerLayer->GetParent();
      lastLayer = nullptr;
    } else {
      RefPtr<Layer> layer = CreateLayer(aLayerTreeDescription[i], manager.get());
      if (aVisibleRegions) {
        layer->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(aVisibleRegions[layerNumber]));
        layer->SetEventRegions(EventRegions(aVisibleRegions[layerNumber]));
      }
      if (aTransforms) {
        layer->SetBaseTransform(aTransforms[layerNumber]);
      }
      aLayersOut.AppendElement(layer);
      layerNumber++;
      if (rootLayer && !parentContainerLayer) {
        MOZ_CRASH();
      }
      if (!rootLayer) {
        rootLayer = layer;
      }
      if (parentContainerLayer) {
        parentContainerLayer->InsertAfter(layer, parentContainerLayer->GetLastChild());
        layer->SetParent(parentContainerLayer);
      }
      lastLayer = layer;
    }
  }
  if (rootLayer) {
    rootLayer->ComputeEffectiveTransforms(Matrix4x4());
    manager->SetRoot(rootLayer);
    if (rootLayer->AsLayerComposite()) {
      // Only perform this for LayerManagerComposite
      CompositorBridgeParent::SetShadowProperties(rootLayer);
    }
  }
  return rootLayer.forget();
}
Example #9
0
 virtual already_AddRefed<ContainerLayer> CreateContainerLayer() {
   RefPtr<ContainerLayer> layer = new TestContainerLayer(this);
   return layer.forget();
 }
nsresult
GonkVideoDecoderManager::CreateVideoData(int64_t aStreamOffset, VideoData **v)
{
  *v = nullptr;
  RefPtr<VideoData> data;
  int64_t timeUs;
  int32_t keyFrame;

  if (mVideoBuffer == nullptr) {
    GVDM_LOG("Video Buffer is not valid!");
    return NS_ERROR_UNEXPECTED;
  }

  if (!mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
    ReleaseVideoBuffer();
    GVDM_LOG("Decoder did not return frame time");
    return NS_ERROR_UNEXPECTED;
  }

  if (mLastTime > timeUs) {
    ReleaseVideoBuffer();
    GVDM_LOG("Output decoded sample time is revert. time=%lld", timeUs);
    return NS_ERROR_NOT_AVAILABLE;
  }
  mLastTime = timeUs;

  if (mVideoBuffer->range_length() == 0) {
    // Some decoders may return spurious empty buffers that we just want to ignore
    // quoted from Android's AwesomePlayer.cpp
    ReleaseVideoBuffer();
    return NS_ERROR_NOT_AVAILABLE;
  }

  if (!mVideoBuffer->meta_data()->findInt32(kKeyIsSyncFrame, &keyFrame)) {
    keyFrame = 0;
  }

  gfx::IntRect picture = mPicture;
  if (mFrameInfo.mWidth != mInitialFrame.width ||
      mFrameInfo.mHeight != mInitialFrame.height) {

    // Frame size is different from what the container reports. This is legal,
    // and we will preserve the ratio of the crop rectangle as it
    // was reported relative to the picture size reported by the container.
    picture.x = (mPicture.x * mFrameInfo.mWidth) / mInitialFrame.width;
    picture.y = (mPicture.y * mFrameInfo.mHeight) / mInitialFrame.height;
    picture.width = (mFrameInfo.mWidth * mPicture.width) / mInitialFrame.width;
    picture.height = (mFrameInfo.mHeight * mPicture.height) / mInitialFrame.height;
  }

  RefPtr<mozilla::layers::TextureClient> textureClient;

  if ((mVideoBuffer->graphicBuffer().get())) {
    textureClient = mNativeWindow->getTextureClientFromBuffer(mVideoBuffer->graphicBuffer().get());
  }

  if (textureClient) {
    GrallocTextureClientOGL* grallocClient = static_cast<GrallocTextureClientOGL*>(textureClient.get());
    grallocClient->SetMediaBuffer(mVideoBuffer);
    textureClient->SetRecycleCallback(GonkVideoDecoderManager::RecycleCallback, this);

    data = VideoData::Create(mInfo.mVideo,
                             mImageContainer,
                             aStreamOffset,
                             timeUs,
                             1, // No way to pass sample duration from muxer to
                                // OMX codec, so we hardcode the duration here.
                             textureClient,
                             keyFrame,
                             -1,
                             picture);
  } else {
    if (!mVideoBuffer->data()) {
      GVDM_LOG("No data in Video Buffer!");
      return NS_ERROR_UNEXPECTED;
    }
    uint8_t *yuv420p_buffer = (uint8_t *)mVideoBuffer->data();
    int32_t stride = mFrameInfo.mStride;
    int32_t slice_height = mFrameInfo.mSliceHeight;

    // Converts to OMX_COLOR_FormatYUV420Planar
    if (mFrameInfo.mColorFormat != OMX_COLOR_FormatYUV420Planar) {
      ARect crop;
      crop.top = 0;
      crop.bottom = mFrameInfo.mHeight;
      crop.left = 0;
      crop.right = mFrameInfo.mWidth;
      yuv420p_buffer = GetColorConverterBuffer(mFrameInfo.mWidth, mFrameInfo.mHeight);
      if (mColorConverter.convertDecoderOutputToI420(mVideoBuffer->data(),
          mFrameInfo.mWidth, mFrameInfo.mHeight, crop, yuv420p_buffer) != OK) {
          ReleaseVideoBuffer();
          GVDM_LOG("Color conversion failed!");
          return NS_ERROR_UNEXPECTED;
      }
        stride = mFrameInfo.mWidth;
        slice_height = mFrameInfo.mHeight;
    }

    size_t yuv420p_y_size = stride * slice_height;
    size_t yuv420p_u_size = ((stride + 1) / 2) * ((slice_height + 1) / 2);
    uint8_t *yuv420p_y = yuv420p_buffer;
    uint8_t *yuv420p_u = yuv420p_y + yuv420p_y_size;
    uint8_t *yuv420p_v = yuv420p_u + yuv420p_u_size;

    // This is the approximate byte position in the stream.
    int64_t pos = aStreamOffset;

    VideoData::YCbCrBuffer b;
    b.mPlanes[0].mData = yuv420p_y;
    b.mPlanes[0].mWidth = mFrameInfo.mWidth;
    b.mPlanes[0].mHeight = mFrameInfo.mHeight;
    b.mPlanes[0].mStride = stride;
    b.mPlanes[0].mOffset = 0;
    b.mPlanes[0].mSkip = 0;

    b.mPlanes[1].mData = yuv420p_u;
    b.mPlanes[1].mWidth = (mFrameInfo.mWidth + 1) / 2;
    b.mPlanes[1].mHeight = (mFrameInfo.mHeight + 1) / 2;
    b.mPlanes[1].mStride = (stride + 1) / 2;
    b.mPlanes[1].mOffset = 0;
    b.mPlanes[1].mSkip = 0;

    b.mPlanes[2].mData = yuv420p_v;
    b.mPlanes[2].mWidth =(mFrameInfo.mWidth + 1) / 2;
    b.mPlanes[2].mHeight = (mFrameInfo.mHeight + 1) / 2;
    b.mPlanes[2].mStride = (stride + 1) / 2;
    b.mPlanes[2].mOffset = 0;
    b.mPlanes[2].mSkip = 0;

    data = VideoData::Create(
        mInfo.mVideo,
        mImageContainer,
        pos,
        timeUs,
        1, // We don't know the duration.
        b,
        keyFrame,
        -1,
        picture);
    ReleaseVideoBuffer();
  }

  data.forget(v);
  return NS_OK;
}
already_AddRefed<Promise>
ServiceWorkerRegistrationMainThread::Unregister(ErrorResult& aRv)
{
  AssertIsOnMainThread();
  nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(GetOwner());
  if (!go) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  // Although the spec says that the same-origin checks should also be done
  // asynchronously, we do them in sync because the Promise created by the
  // WebIDL infrastructure due to a returned error will be resolved
  // asynchronously. We aren't making any internal state changes in these
  // checks, so ordering of multiple calls is not affected.
  nsCOMPtr<nsIDocument> document = GetOwner()->GetExtantDoc();
  if (!document) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  nsCOMPtr<nsIURI> scopeURI;
  nsCOMPtr<nsIURI> baseURI = document->GetBaseURI();
  // "If the origin of scope is not client's origin..."
  nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), mScope, nullptr, baseURI);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
    return nullptr;
  }

  nsCOMPtr<nsIPrincipal> documentPrincipal = document->NodePrincipal();
  rv = documentPrincipal->CheckMayLoad(scopeURI, true /* report */,
                                       false /* allowIfInheritsPrinciple */);
  if (NS_FAILED(rv)) {
    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
    return nullptr;
  }

  nsAutoCString uriSpec;
  aRv = scopeURI->GetSpecIgnoringRef(uriSpec);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  nsCOMPtr<nsIServiceWorkerManager> swm =
    mozilla::services::GetServiceWorkerManager();

  RefPtr<Promise> promise = Promise::Create(go, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  RefPtr<UnregisterCallback> cb = new UnregisterCallback(promise);

  NS_ConvertUTF8toUTF16 scope(uriSpec);
  aRv = swm->Unregister(documentPrincipal, cb, scope);
  if (aRv.Failed()) {
    return nullptr;
  }

  return promise.forget();
}
Example #12
0
void
nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
                                      nsRenderingContext* aCtx)
{
  nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
  nsPoint offset = ToReferenceFrame();
  nsRect bgClipRect = frame->CanvasArea() + offset;

  nsRenderingContext context;
  nsRefPtr<gfxContext> dest = aCtx->ThebesContext();
  nsRefPtr<gfxASurface> surf;
  RefPtr<DrawTarget> dt;
  nsRefPtr<gfxContext> ctx;
  gfxRect destRect;
#ifndef MOZ_GFX_OPTIMIZE_MOBILE
  if (IsSingleFixedPositionImage(aBuilder, bgClipRect, &destRect) &&
      aBuilder->IsPaintingToWindow() && !aBuilder->IsCompositingCheap() &&
      !dest->CurrentMatrix().HasNonIntegerTranslation()) {
    // Snap image rectangle to nearest pixel boundaries. This is the right way
    // to snap for this context, because we checked HasNonIntegerTranslation above.
    destRect.Round();
    if (dest->IsCairo()) {
      surf = static_cast<gfxASurface*>(Frame()->Properties().Get(nsIFrame::CachedBackgroundImage()));
      nsRefPtr<gfxASurface> destSurf = dest->CurrentSurface();
      if (surf && surf->GetType() == destSurf->GetType()) {
        BlitSurface(dest, destRect, surf);
        return;
      }
      surf = destSurf->CreateSimilarSurface(
          gfxContentType::COLOR_ALPHA,
          gfxIntSize(ceil(destRect.width), ceil(destRect.height)));
    } else {
      dt = static_cast<DrawTarget*>(Frame()->Properties().Get(nsIFrame::CachedBackgroundImageDT()));
      DrawTarget* destDT = dest->GetDrawTarget();
      if (dt) {
        BlitSurface(destDT, destRect, dt);
        return;
      }
      dt = destDT->CreateSimilarDrawTarget(IntSize(ceil(destRect.width), ceil(destRect.height)), SurfaceFormat::B8G8R8A8);
    }
    if (surf || dt) {
      if (surf) {
        ctx = new gfxContext(surf);
      } else {
        ctx = new gfxContext(dt);
      }
      ctx->Translate(-gfxPoint(destRect.x, destRect.y));
      context.Init(aCtx->DeviceContext(), ctx);
    }
  }
#endif

  PaintInternal(aBuilder,
                (surf || dt) ? &context : aCtx,
                (surf || dt) ? bgClipRect: mVisibleRect,
                &bgClipRect);

  if (surf) {
    BlitSurface(dest, destRect, surf);
    frame->Properties().Set(nsIFrame::CachedBackgroundImage(), surf.forget().get());
  }
  if (dt) {
    BlitSurface(dest->GetDrawTarget(), destRect, dt);
    frame->Properties().Set(nsIFrame::CachedBackgroundImageDT(), dt.forget().drop());
  }
}
Example #13
0
already_AddRefed<TaskQueue> CreateMediaDecodeTaskQueue(const char* aName) {
  RefPtr<TaskQueue> queue = new TaskQueue(
      GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER), aName);
  return queue.forget();
}
Example #14
0
// Instantiates but does not initialize decoder.
static
already_AddRefed<MediaDecoder>
InstantiateDecoder(const nsACString& aType, MediaDecoderOwner* aOwner)
{
  MOZ_ASSERT(NS_IsMainThread());
  RefPtr<MediaDecoder> decoder;

#ifdef MOZ_FMP4
  if (IsMP4SupportedType(aType)) {
    decoder = new MP4Decoder(aOwner);
    return decoder.forget();
  }
#endif
  if (IsMP3SupportedType(aType)) {
    decoder = new MP3Decoder(aOwner);
    return decoder.forget();
  }
#ifdef MOZ_GSTREAMER
  if (IsGStreamerSupportedType(aType)) {
    decoder = new GStreamerDecoder(aOwner);
    return decoder.forget();
  }
#endif
#ifdef MOZ_RAW
  if (IsRawType(aType)) {
    decoder = new RawDecoder(aOwner);
    return decoder.forget();
  }
#endif
  if (IsOggType(aType)) {
    decoder = new OggDecoder(aOwner);
    return decoder.forget();
  }
#ifdef MOZ_WAVE
  if (IsWaveType(aType)) {
    decoder = new WaveDecoder(aOwner);
    return decoder.forget();
  }
#endif
#ifdef MOZ_OMX_DECODER
  if (IsOmxSupportedType(aType)) {
    // we are discouraging Web and App developers from using those formats in
    // gB2GOnlyTypes, thus we only allow them to be played on WebApps.
    if (IsB2GSupportOnlyType(aType)) {
      dom::HTMLMediaElement* element = aOwner->GetMediaElement();
      if (!element) {
        return nullptr;
      }
      nsIPrincipal* principal = element->NodePrincipal();
      if (!principal) {
        return nullptr;
      }
      if (principal->GetAppStatus() < nsIPrincipal::APP_STATUS_PRIVILEGED) {
        return nullptr;
      }
    }
    decoder = new MediaOmxDecoder(aOwner);
    return decoder.forget();
  }
#endif
#ifdef NECKO_PROTOCOL_rtsp
  if (IsRtspSupportedType(aType)) {
    decoder = new RtspOmxDecoder(aOwner);
    return decoder.forget();
  }
#endif
#ifdef MOZ_ANDROID_OMX
  if (MediaDecoder::IsAndroidMediaEnabled() &&
      EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
    decoder = new AndroidMediaDecoder(aOwner, aType);
    return decoder.forget();
  }
#endif
  if (DecoderTraits::IsWebMTypeAndEnabled(aType)) {
    decoder = new WebMDecoder(aOwner);
    return decoder.forget();
  }
#ifdef MOZ_DIRECTSHOW
  // Note: DirectShow should come before WMF, so that we prefer DirectShow's
  // MP3 support over WMF's.
  if (IsDirectShowSupportedType(aType)) {
    decoder = new DirectShowDecoder(aOwner);
    return decoder.forget();
  }
#endif

  return nullptr;
}
Example #15
0
NS_IMETHODIMP
PicoCallbackRunnable::Run()
{
  MOZ_ASSERT(!NS_IsMainThread());
  PicoApi::pico_Status status = 0;

  if (mService->CurrentVoice() != mVoice) {
    mService->LoadEngine(mVoice);
  } else {
    status = sPicoApi.pico_resetEngine(mService->mPicoEngine, PICO_RESET_SOFT);
    PICO_ENSURE_SUCCESS("pico_unloadResource", status, NS_ERROR_FAILURE);
  }

  // Add SSML markup for pitch and rate. Pico uses a minimal parser,
  // so no namespace is needed.
  nsPrintfCString markedUpText(
    "<pitch level=\"%0.0f\"><speed level=\"%0.0f\">%s</speed></pitch>",
    std::min(std::max(50.0f, mPitch * 100), 200.0f),
    std::min(std::max(20.0f, mRate * 100), 500.0f),
    mText.get());

  const char* text = markedUpText.get();
  size_t buffer_size = 512, buffer_offset = 0;
  RefPtr<SharedBuffer> buffer = SharedBuffer::Create(buffer_size);
  int16_t text_offset = 0, bytes_recv = 0, bytes_sent = 0, out_data_type = 0;
  int16_t text_remaining = markedUpText.Length() + 1;

  // Run this loop while this is the current task
  while (IsCurrentTask()) {
    if (text_remaining) {
      status = sPicoApi.pico_putTextUtf8(mService->mPicoEngine,
                                         text + text_offset, text_remaining,
                                         &bytes_sent);
      PICO_ENSURE_SUCCESS("pico_putTextUtf8", status, NS_ERROR_FAILURE);
      // XXX: End speech task on error
      text_remaining -= bytes_sent;
      text_offset += bytes_sent;
    } else {
      // If we already fed all the text to the engine, send a zero length buffer
      // and quit.
      DispatchSynthDataRunnable(already_AddRefed<SharedBuffer>(), 0);
      break;
    }

    do {
      // Run this loop while the result of getData is STEP_BUSY, when it finishes
      // synthesizing audio for the given text, it returns STEP_IDLE. We then
      // break to the outer loop and feed more text, if there is any left.
      if (!IsCurrentTask()) {
        // If the task has changed, quit.
        break;
      }

      if (buffer_size - buffer_offset < PICO_MAX_CHUNK_SIZE) {
        // The next audio chunk retrieved may be bigger than our buffer,
        // so send the data and flush the buffer.
        DispatchSynthDataRunnable(buffer.forget(), buffer_offset);
        buffer_offset = 0;
        buffer = SharedBuffer::Create(buffer_size);
      }

      status = sPicoApi.pico_getData(mService->mPicoEngine,
                                     (uint8_t*)buffer->Data() + buffer_offset,
                                     PICO_MAX_CHUNK_SIZE,
                                     &bytes_recv, &out_data_type);
      PICO_ENSURE_SUCCESS("pico_getData", status, NS_ERROR_FAILURE);
      buffer_offset += bytes_recv;
    } while (status == PICO_STEP_BUSY);
  }

  return NS_OK;
}
Example #16
0
 virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() {
   RefPtr<PaintedLayer> layer = new TestPaintedLayer(this);
   return layer.forget();
 }
Example #17
0
already_AddRefed<nsPicoService>
nsPicoService::GetInstanceForService()
{
  RefPtr<nsPicoService> picoService = GetInstance();
  return picoService.forget();
}
static already_AddRefed<SourceSurface>
CreateSourceSurfaceFromLockedMacIOSurface(MacIOSurface* aSurface)
{
  size_t bytesPerRow = aSurface->GetBytesPerRow();
  size_t ioWidth = aSurface->GetDevicePixelWidth();
  size_t ioHeight = aSurface->GetDevicePixelHeight();
  SurfaceFormat ioFormat = aSurface->GetFormat();

  if ((ioFormat == SurfaceFormat::NV12 || ioFormat == SurfaceFormat::YUV422) &&
      (ioWidth > PlanarYCbCrImage::MAX_DIMENSION ||
       ioHeight > PlanarYCbCrImage::MAX_DIMENSION)) {
    return nullptr;
  }

  SurfaceFormat format =
    (ioFormat == SurfaceFormat::NV12 || ioFormat == SurfaceFormat::YUV422)
      ? SurfaceFormat::B8G8R8X8
      : SurfaceFormat::B8G8R8A8;

  RefPtr<DataSourceSurface> dataSurface =
    Factory::CreateDataSourceSurface(IntSize::Truncate(ioWidth, ioHeight), format);
  if (NS_WARN_IF(!dataSurface)) {
    return nullptr;
  }

  DataSourceSurface::MappedSurface mappedSurface;
  if (!dataSurface->Map(DataSourceSurface::WRITE, &mappedSurface)) {
    return nullptr;
  }

  if (ioFormat == SurfaceFormat::NV12) {
    /* Extract and separate the CbCr planes */
    size_t cbCrStride = aSurface->GetBytesPerRow(1);
    size_t cbCrWidth = aSurface->GetDevicePixelWidth(1);
    size_t cbCrHeight = aSurface->GetDevicePixelHeight(1);

    auto cbPlane = MakeUnique<uint8_t[]>(cbCrWidth * cbCrHeight);
    auto crPlane = MakeUnique<uint8_t[]>(cbCrWidth * cbCrHeight);

    uint8_t* src = (uint8_t*)aSurface->GetBaseAddressOfPlane(1);
    uint8_t* cbDest = cbPlane.get();
    uint8_t* crDest = crPlane.get();

    for (size_t i = 0; i < cbCrHeight; i++) {
      uint8_t* rowSrc = src + cbCrStride * i;
      for (size_t j = 0; j < cbCrWidth; j++) {
        *cbDest = *rowSrc;
        cbDest++;
        rowSrc++;
        *crDest = *rowSrc;
        crDest++;
        rowSrc++;
      }
    }

    /* Convert to RGB */
    PlanarYCbCrData data;
    data.mYChannel = (uint8_t*)aSurface->GetBaseAddressOfPlane(0);
    data.mYStride = aSurface->GetBytesPerRow(0);
    data.mYSize = IntSize::Truncate(ioWidth, ioHeight);
    data.mCbChannel = cbPlane.get();
    data.mCrChannel = crPlane.get();
    data.mCbCrStride = cbCrWidth;
    data.mCbCrSize = IntSize::Truncate(cbCrWidth, cbCrHeight);
    data.mPicSize = data.mYSize;

    ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize::Truncate(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
  } else if (ioFormat == SurfaceFormat::YUV422) {
    IntSize size = IntSize::Truncate(ioWidth, ioHeight);
    libyuv::ConvertToARGB((uint8_t*)aSurface->GetBaseAddress(), 0 /* not used */,
                          mappedSurface.mData, mappedSurface.mStride,
                          0, 0,
                          size.width, size.height,
                          size.width, size.height,
                          libyuv::kRotate0, libyuv::FOURCC_UYVY);
  } else {
    unsigned char* ioData = (unsigned char*)aSurface->GetBaseAddress();

    for (size_t i = 0; i < ioHeight; ++i) {
      memcpy(mappedSurface.mData + i * mappedSurface.mStride,
             ioData + i * bytesPerRow,
             ioWidth * 4);
    }
  }

  dataSurface->Unmap();

  return dataSurface.forget();
}
void
MediaEngineWebRTCMicrophoneSource::Process(int channel,
                                           webrtc::ProcessingTypes type,
                                           sample *audio10ms, int length,
                                           int samplingFreq, bool isStereo)
{
  // On initial capture, throw away all far-end data except the most recent sample
  // since it's already irrelevant and we want to keep avoid confusing the AEC far-end
  // input code with "old" audio.
  if (!mStarted) {
    mStarted  = true;
    while (gFarendObserver->Size() > 1) {
      free(gFarendObserver->Pop()); // only call if size() > 0
    }
  }

  while (gFarendObserver->Size() > 0) {
    FarEndAudioChunk *buffer = gFarendObserver->Pop(); // only call if size() > 0
    if (buffer) {
      int length = buffer->mSamples;
      int res = mVoERender->ExternalPlayoutData(buffer->mData,
                                                gFarendObserver->PlayoutFrequency(),
                                                gFarendObserver->PlayoutChannels(),
                                                mPlayoutDelay,
                                                length);
      free(buffer);
      if (res == -1) {
        return;
      }
    }
  }

  MonitorAutoLock lock(mMonitor);
  if (mState != kStarted)
    return;

  uint32_t len = mSources.Length();
  for (uint32_t i = 0; i < len; i++) {
    RefPtr<SharedBuffer> buffer = SharedBuffer::Create(length * sizeof(sample));

    sample* dest = static_cast<sample*>(buffer->Data());
    memcpy(dest, audio10ms, length * sizeof(sample));

    nsAutoPtr<AudioSegment> segment(new AudioSegment());
    nsAutoTArray<const sample*,1> channels;
    channels.AppendElement(dest);
    segment->AppendFrames(buffer.forget(), channels, length);
    TimeStamp insertTime;
    segment->GetStartTime(insertTime);

    if (mSources[i]) {
      // Make sure we include the stream and the track.
      // The 0:1 is a flag to note when we've done the final insert for a given input block.
      LogTime(AsyncLatencyLogger::AudioTrackInsertion, LATENCY_STREAM_ID(mSources[i].get(), mTrackID),
              (i+1 < len) ? 0 : 1, insertTime);

      // This is safe from any thread, and is safe if the track is Finished
      // or Destroyed.
      // Note: due to evil magic, the nsAutoPtr<AudioSegment>'s ownership transfers to
      // the Runnable (AutoPtr<> = AutoPtr<>)
      RUN_ON_THREAD(mThread, WrapRunnable(mSources[i], &SourceMediaStream::AppendToTrack,
                                          mTrackID, segment, (AudioSegment *) nullptr),
                    NS_DISPATCH_NORMAL);
    }
  }

  return;
}
Example #20
0
/* static */ already_AddRefed<File>
File::CreateFromFile(nsISupports* aParent, nsIFile* aFile, bool aTemporary)
{
  RefPtr<File> file = new File(aParent, new BlobImplFile(aFile, aTemporary));
  return file.forget();
}
Example #21
0
already_AddRefed<DataTextureSource>
BasicCompositor::CreateDataTextureSource(TextureFlags aFlags)
{
  RefPtr<DataTextureSource> result = new DataTextureSourceBasic();
  return result.forget();
}
Example #22
0
already_AddRefed<gfxFontFaceBufferSource>
FontFace::CreateBufferSource()
{
  RefPtr<FontFaceBufferSource> bufferSource = new FontFaceBufferSource(this);
  return bufferSource.forget();
}
already_AddRefed<Promise>
MobileMessageManager::SetSmscAddress(const SmscAddress& aSmscAddress,
                                     const Optional<uint32_t>& aServiceId,
                                     ErrorResult& aRv)
{
  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
  if (!smsService) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  // Use the default one unless |serviceId| is available.
  uint32_t serviceId;
  nsresult rv;
  if (aServiceId.WasPassed()) {
    serviceId = aServiceId.Value();
  } else {
    rv = smsService->GetSmsDefaultServiceId(&serviceId);
    if (NS_FAILED(rv)) {
      aRv.Throw(rv);
      return nullptr;
    }
  }

  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
  if (!window) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
  if (!global) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  if (!aSmscAddress.mAddress.WasPassed()) {
    NS_WARNING("SmscAddress.address is a mandatory field and can not be omitted.");
    promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
    return promise.forget();
  }

  nsString address = aSmscAddress.mAddress.Value();
  TypeOfNumber ton = aSmscAddress.mTypeOfAddress.mTypeOfNumber;
  NumberPlanIdentification npi =
    aSmscAddress.mTypeOfAddress.mNumberPlanIdentification;

  // If the address begins with +, set TON to international no matter what has
  // passed in.
  if (!address.IsEmpty() && address[0] == '+') {
    ton = TypeOfNumber::International;
  }

  nsCOMPtr<nsIMobileMessageCallback> msgCallback =
    new MobileMessageCallback(promise);

  rv = smsService->SetSmscAddress(serviceId, address,
    static_cast<uint32_t>(ton), static_cast<uint32_t>(npi), msgCallback);
  if (NS_FAILED(rv)) {
    promise->MaybeReject(rv);
    return promise.forget();
  }

  return promise.forget();
}
already_AddRefed<MediaDataDecoder> AppleDecoderModule::CreateAudioDecoder(
    const CreateDecoderParams& aParams) {
  RefPtr<MediaDataDecoder> decoder =
      new AppleATDecoder(aParams.AudioConfig(), aParams.mTaskQueue);
  return decoder.forget();
}
Example #25
0
already_AddRefed<DOMMatrix>
DOMMatrix::Constructor(const GlobalObject& aGlobal, const DOMMatrixReadOnly& aOther, ErrorResult& aRv)
{
  RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports(), aOther);
  return obj.forget();
}
already_AddRefed<gfx::SourceSurface>
D3D11ShareHandleImage::GetAsSourceSurface()
{
  RefPtr<ID3D11Texture2D> texture = GetTexture();
  if (!texture) {
    NS_WARNING("Cannot readback from shared texture because no texture is available.");
    return nullptr;
  }

  RefPtr<ID3D11Device> device;
  texture->GetDevice(byRef(device));

  RefPtr<IDXGIKeyedMutex> keyedMutex;
  if (FAILED(texture->QueryInterface(static_cast<IDXGIKeyedMutex**>(byRef(keyedMutex))))) {
    NS_WARNING("Failed to QueryInterface for IDXGIKeyedMutex, strange.");
    return nullptr;
  }

  if (FAILED(keyedMutex->AcquireSync(0, 0))) {
    NS_WARNING("Failed to acquire sync for keyedMutex, plugin failed to release?");
    return nullptr;
  }

  D3D11_TEXTURE2D_DESC desc;
  texture->GetDesc(&desc);

  CD3D11_TEXTURE2D_DESC softDesc(desc.Format, desc.Width, desc.Height);
  softDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
  softDesc.BindFlags = 0;
  softDesc.MiscFlags = 0;
  softDesc.MipLevels = 1;
  softDesc.Usage = D3D11_USAGE_STAGING;

  RefPtr<ID3D11Texture2D> softTexture;
  HRESULT hr = device->CreateTexture2D(&softDesc,
                                       NULL,
                                       static_cast<ID3D11Texture2D**>(byRef(softTexture)));

  if (FAILED(hr)) {
    NS_WARNING("Failed to create 2D staging texture.");
    keyedMutex->ReleaseSync(0);
    return nullptr;
  }

  RefPtr<ID3D11DeviceContext> context;
  device->GetImmediateContext(byRef(context));
  if (!context) {
    keyedMutex->ReleaseSync(0);
    return nullptr;
  }

  context->CopyResource(softTexture, texture);
  keyedMutex->ReleaseSync(0);

  RefPtr<gfx::DataSourceSurface> surface =
    gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8X8);
  if (NS_WARN_IF(!surface)) {
    return nullptr;
  }

  gfx::DataSourceSurface::MappedSurface mappedSurface;
  if (!surface->Map(gfx::DataSourceSurface::WRITE, &mappedSurface)) {
    return nullptr;
  }

  D3D11_MAPPED_SUBRESOURCE map;
  hr = context->Map(softTexture, 0, D3D11_MAP_READ, 0, &map);
  if (!SUCCEEDED(hr)) {
    surface->Unmap();
    return nullptr;
  }

  for (int y = 0; y < mSize.height; y++) {
    memcpy(mappedSurface.mData + mappedSurface.mStride * y,
           (unsigned char*)(map.pData) + map.RowPitch * y,
           mSize.width * 4);
  }

  context->Unmap(softTexture, 0);
  surface->Unmap();

  return surface.forget();
}
Example #27
0
already_AddRefed<IDBRequest>
IDBCursor::Delete(JSContext* aCx, ErrorResult& aRv)
{
  AssertIsOnOwningThread();

  if (!mTransaction->IsOpen()) {
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
    return nullptr;
  }

  if (!mTransaction->IsWriteAllowed()) {
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
    return nullptr;
  }

  if (IsSourceDeleted() ||
      !mHaveValue ||
      mType == Type_ObjectStoreKey ||
      mType == Type_IndexKey ||
      mContinueCalled) {
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
    return nullptr;
  }

  MOZ_ASSERT(mType == Type_ObjectStore || mType == Type_Index);
  MOZ_ASSERT(!mKey.IsUnset());

  IDBObjectStore* objectStore;
  if (mType == Type_ObjectStore) {
    objectStore = mSourceObjectStore;
  } else {
    objectStore = mSourceIndex->ObjectStore();
  }

  MOZ_ASSERT(objectStore);

  const Key& primaryKey = (mType == Type_ObjectStore) ? mKey : mPrimaryKey;

  JS::Rooted<JS::Value> key(aCx);
  aRv = primaryKey.ToJSVal(aCx, &key);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  RefPtr<IDBRequest> request =
    objectStore->DeleteInternal(aCx, key, /* aFromCursor */ true, aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  request->SetSource(this);

  if (mType == Type_ObjectStore) {
  IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
                 "database(%s).transaction(%s).objectStore(%s)."
                 "cursor(%s).delete(%s)",
               "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.delete()",
               IDB_LOG_ID_STRING(),
               mTransaction->LoggingSerialNumber(),
               request->LoggingSerialNumber(),
               IDB_LOG_STRINGIFY(mTransaction->Database()),
               IDB_LOG_STRINGIFY(mTransaction),
               IDB_LOG_STRINGIFY(objectStore),
               IDB_LOG_STRINGIFY(mDirection),
               IDB_LOG_STRINGIFY(objectStore, primaryKey));
  } else {
    IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
                   "database(%s).transaction(%s).objectStore(%s)."
                   "index(%s).cursor(%s).delete(%s)",
                 "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.delete()",
                 IDB_LOG_ID_STRING(),
                 mTransaction->LoggingSerialNumber(),
                 request->LoggingSerialNumber(),
                 IDB_LOG_STRINGIFY(mTransaction->Database()),
                 IDB_LOG_STRINGIFY(mTransaction),
                 IDB_LOG_STRINGIFY(objectStore),
                 IDB_LOG_STRINGIFY(mSourceIndex),
                 IDB_LOG_STRINGIFY(mDirection),
                 IDB_LOG_STRINGIFY(objectStore, primaryKey));
  }

  return request.forget();
}
Example #28
0
int
FFmpegH264Decoder<LIBAV_VER>::AllocateYUV420PVideoBuffer(
  AVCodecContext* aCodecContext, AVFrame* aFrame)
{
  bool needAlign = aCodecContext->codec->capabilities & CODEC_CAP_DR1;
  bool needEdge = !(aCodecContext->flags & CODEC_FLAG_EMU_EDGE);
  int edgeWidth = needEdge ? avcodec_get_edge_width() : 0;

  int decodeWidth = aCodecContext->width + edgeWidth * 2;
  int decodeHeight = aCodecContext->height + edgeWidth * 2;

  if (needAlign) {
    // Align width and height to account for CODEC_CAP_DR1.
    // Make sure the decodeWidth is a multiple of 64, so a UV plane stride will be
    // a multiple of 32. FFmpeg uses SSE3 accelerated code to copy a frame line by
    // line.
    // VP9 decoder uses MOVAPS/VEX.256 which requires 32-bytes aligned memory.
    decodeWidth = (decodeWidth + 63) & ~63;
    decodeHeight = (decodeHeight + 63) & ~63;
  }

  PodZero(&aFrame->data[0], AV_NUM_DATA_POINTERS);
  PodZero(&aFrame->linesize[0], AV_NUM_DATA_POINTERS);

  int pitch = decodeWidth;
  int chroma_pitch  = (pitch + 1) / 2;
  int chroma_height = (decodeHeight +1) / 2;

  // Get strides for each plane.
  aFrame->linesize[0] = pitch;
  aFrame->linesize[1] = aFrame->linesize[2] = chroma_pitch;

  size_t allocSize = pitch * decodeHeight + (chroma_pitch * chroma_height) * 2;

  RefPtr<Image> image =
    mImageContainer->CreateImage(ImageFormat::PLANAR_YCBCR);
  PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(image.get());
  uint8_t* buffer = ycbcr->AllocateAndGetNewBuffer(allocSize + 64);
  // FFmpeg requires a 16/32 bytes-aligned buffer, align it on 64 to be safe
  buffer = reinterpret_cast<uint8_t*>((reinterpret_cast<uintptr_t>(buffer) + 63) & ~63);

  if (!buffer) {
    NS_WARNING("Failed to allocate buffer for FFmpeg video decoding");
    return -1;
  }

  int offsets[3] = {
    0,
    pitch * decodeHeight,
    pitch * decodeHeight + chroma_pitch * chroma_height };

  // Add a horizontal bar |edgeWidth| pixels high at the
  // top of the frame, plus |edgeWidth| pixels from the left of the frame.
  int planesEdgeWidth[3] = {
    edgeWidth * aFrame->linesize[0] + edgeWidth,
    edgeWidth / 2 * aFrame->linesize[1] + edgeWidth / 2,
    edgeWidth / 2 * aFrame->linesize[2] + edgeWidth / 2 };

  for (uint32_t i = 0; i < 3; i++) {
    aFrame->data[i] = buffer + offsets[i] + planesEdgeWidth[i];
  }

  aFrame->extended_data = aFrame->data;
  aFrame->width = aCodecContext->width;
  aFrame->height = aCodecContext->height;

  aFrame->opaque = static_cast<void*>(image.forget().take());

  aFrame->type = FF_BUFFER_TYPE_USER;
  aFrame->reordered_opaque = aCodecContext->reordered_opaque;
#if LIBAVCODEC_VERSION_MAJOR == 53
  if (aCodecContext->pkt) {
    aFrame->pkt_pts = aCodecContext->pkt->pts;
  }
#endif
  return 0;
}
Example #29
0
static already_AddRefed<TextureClient>
TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
                      TextureFlags baseFlags, LayersBackend layersBackend)
{
  auto backendType = gfx::BackendType::CAIRO;
  TexClientFactory factory(allocator, src->mHasAlpha, src->mSize, backendType,
                           baseFlags, layersBackend);

  RefPtr<BufferTextureClient> texClient;

  {
    gl::ScopedReadbackFB autoReadback(src);

    // We have a source FB, now we need a format.
    GLenum destFormat = LOCAL_GL_BGRA;
    GLenum destType = LOCAL_GL_UNSIGNED_BYTE;
    GLenum readFormat;
    GLenum readType;

    // We actually don't care if they match, since we can handle
    // any read{Format,Type} we get.
    auto gl = src->mGL;
    GetActualReadFormats(gl, destFormat, destType, &readFormat, &readType);

    MOZ_ASSERT(readFormat == LOCAL_GL_RGBA ||
               readFormat == LOCAL_GL_BGRA);
    MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE);

    // With a format and type, we can create texClient.
    if (readFormat == LOCAL_GL_BGRA &&
        readType == LOCAL_GL_UNSIGNED_BYTE)
    {
      // 0xAARRGGBB
      // In Lendian: [BB, GG, RR, AA]
      texClient = factory.CreateB8G8R8AX8();

    } else if (readFormat == LOCAL_GL_RGBA &&
               readType == LOCAL_GL_UNSIGNED_BYTE)
    {
      // [RR, GG, BB, AA]
      texClient = factory.CreateR8G8B8AX8();
    } else {
      MOZ_CRASH("Bad `read{Format,Type}`.");
    }

    MOZ_ASSERT(texClient);
    if (!texClient)
        return nullptr;

    // With a texClient, we can lock for writing.
    MOZ_ALWAYS_TRUE( texClient->Lock(OpenMode::OPEN_WRITE) );

    uint8_t* lockedBytes = texClient->GetLockedData();

    // ReadPixels from the current FB into lockedBits.
    auto width = src->mSize.width;
    auto height = src->mSize.height;

    {
      ScopedPackAlignment autoAlign(gl, 4);

      gl->raw_fReadPixels(0, 0, width, height, readFormat, readType, lockedBytes);
    }

    // RB_SWAPPED doesn't work with D3D11. (bug 1051010)
    // RB_SWAPPED doesn't work with Basic. (bug ???????)
    // RB_SWAPPED doesn't work with D3D9. (bug ???????)
    bool layersNeedsManualSwap = layersBackend == LayersBackend::LAYERS_BASIC ||
                                 layersBackend == LayersBackend::LAYERS_D3D9 ||
                                 layersBackend == LayersBackend::LAYERS_D3D11;
    if (texClient->HasFlags(TextureFlags::RB_SWAPPED) &&
        layersNeedsManualSwap)
    {
      size_t pixels = width * height;
      uint8_t* itr = lockedBytes;
      for (size_t i = 0; i < pixels; i++) {
        SwapRB_R8G8B8A8(itr);
        itr += 4;
      }

      texClient->RemoveFlags(TextureFlags::RB_SWAPPED);
    }

    texClient->Unlock();
  }

  return texClient.forget();
}
Example #30
0
already_AddRefed<ReadbackLayer>
ClientLayerManager::CreateReadbackLayer()
{
  RefPtr<ReadbackLayer> layer = new ClientReadbackLayer(this);
  return layer.forget();
}