コード例 #1
0
nsresult
sbWindowWatcher::RemoveWindow(nsIDOMWindow* aWindow)
{
  // Validate arguments.
  NS_ASSERTION(aWindow, "aWindow is null");

  // Function variables.
  bool success;
  nsresult rv;

  // Operate within the monitor.
  mozilla::ReentrantMonitorAutoEnter autoMonitor(mMonitor);

  // Get the removed window information.
  WindowInfo* windowInfo;
  success = mWindowInfoTable.Get(aWindow, &windowInfo);
  if (!success)
    windowInfo = nsnull;

  // Remove listener for the end of window overlay load events.
  if (windowInfo) {
    rv = windowInfo->eventListener->ClearEventListeners();
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Remove the closed window from the window information map.
  mWindowInfoTable.Remove(aWindow);

  // Remove the closed window from the window list.
  mWindowList.RemoveObject(aWindow);

  return NS_OK;
}
コード例 #2
0
void
sbWindowWatcher::Shutdown()
{
  // Validate state.
  NS_ASSERTION(SB_IsMainThread(mThreadManager), "not on main thread");

  // Operate within the monitor.
  {
    mozilla::ReentrantMonitorAutoEnter autoMonitor(mMonitor);

    // Do nothing if already shutting down.
    if (mIsShuttingDown)
      return;

    // Indicate that this instance is shutting down.
    mIsShuttingDown = PR_TRUE;
  }

  // Remove quit-application-granted observer.
  mObserverService->RemoveObserver(this, "quit-application-granted");

  // Invoke all call with window callbacks.
  InvokeCallWithWindowCallbacks(nsnull);

  // Remove window watcher observer.
  if (mWindowWatcher)
    mWindowWatcher->UnregisterNotification(this);
}
コード例 #3
0
NS_IMETHODIMP
sbWindowWatcher::WaitForWindow(const nsAString& aWindowType)
{
  nsresult rv;

  // This method may not be called on the main thread.
  NS_ENSURE_TRUE(!SB_IsMainThread(mThreadManager), NS_ERROR_UNEXPECTED);

  // Don't wait if this instance is shutting down.
  {
    // Check is shutting down within the monitor.
    mozilla::ReentrantMonitorAutoEnter autoMonitor(mMonitor);
    if (mIsShuttingDown)
      return NS_OK;
  }

  // Create a wait for window object.
  nsRefPtr<sbWindowWatcherWaitForWindow> waitForWindow;
  rv = sbWindowWatcherWaitForWindow::New(getter_AddRefs(waitForWindow));
  NS_ENSURE_SUCCESS(rv, rv);

  // Wait for the window.
  rv = waitForWindow->Wait(aWindowType);
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
コード例 #4
0
nsresult
sbWindowWatcher::AddWindow(nsIDOMWindow* aWindow)
{
  // Validate arguments and state.
  NS_ASSERTION(aWindow, "aWindow is null");

  // Function variables.
  bool success;
  nsresult rv;

  // Operate within the monitor.
  mozilla::ReentrantMonitorAutoEnter autoMonitor(mMonitor);

  // Create the window info object.
  nsAutoPtr<WindowInfo> windowInfo;
  windowInfo = new WindowInfo();
  NS_ENSURE_TRUE(windowInfo, NS_ERROR_OUT_OF_MEMORY);
  windowInfo->window = aWindow;

  // Get the window event target.
  nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(aWindow, &rv);
  NS_ENSURE_SUCCESS(rv, rv);
  nsCOMPtr<nsIDOMEventTarget> windowEventTarget;
  rv = window->GetWindowRoot(getter_AddRefs(windowEventTarget));
  NS_ENSURE_SUCCESS(rv, rv);
  windowInfo->eventTarget = windowEventTarget;

  // Create a window event listener.
  nsRefPtr<sbWindowWatcherEventListener> eventListener;
  rv = sbWindowWatcherEventListener::New(getter_AddRefs(eventListener),
                                         this,
                                         aWindow);
  NS_ENSURE_SUCCESS(rv, rv);
  windowInfo->eventListener = eventListener;

  // Add the window info to the window info table.
  mWindowInfoTable.Put(aWindow, windowInfo.forget());

  // Add the opened window to the window list.
  success = mWindowList.AppendObject(aWindow);
  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);

  // Listen for when the window has opened completely.
  // Due to annoying platform differences, we need to figure out when the
  // _last_ of a combination of events to occur (but the first instance of each)
  const char* DOM_WINDOW_READY_EVENT_TYPES[] = {  "resize", "sb-overlay-load" };

  for (unsigned int i = 0; i < NS_ARRAY_LENGTH(DOM_WINDOW_READY_EVENT_TYPES); ++i) {
    rv = eventListener->AddEventListener(DOM_WINDOW_READY_EVENT_TYPES[i]);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  return NS_OK;
}
コード例 #5
0
ファイル: nsRawReader.cpp プロジェクト: nikhilm/v8monkey
nsresult nsRawReader::Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime)
{
  mozilla::MonitorAutoEnter autoEnter(mMonitor);
  NS_ASSERTION(mDecoder->OnStateMachineThread(),
               "Should be on state machine thread.");

  nsMediaStream *stream = mDecoder->GetCurrentStream();
  NS_ASSERTION(stream, "Decoder has no media stream");

  PRUint32 frame = mCurrentFrame;
  if (aTime >= UINT_MAX)
    return NS_ERROR_FAILURE;
  mCurrentFrame = aTime * mFrameRate / USECS_PER_S;

  PRUint32 offset;
  if (!MulOverflow32(mCurrentFrame, mFrameSize, offset))
    return NS_ERROR_FAILURE;

  offset += sizeof(nsRawVideoHeader);

  nsresult rv = stream->Seek(nsISeekableStream::NS_SEEK_SET, offset);
  NS_ENSURE_SUCCESS(rv, rv);

  mVideoQueue.Erase();

  while(mVideoQueue.GetSize() == 0) {
    PRBool keyframeSkip = PR_FALSE;
    if (!DecodeVideoFrame(keyframeSkip, 0)) {
      mCurrentFrame = frame;
      return NS_ERROR_FAILURE;
    }

    {
      mozilla::MonitorAutoExit autoMonitorExit(mMonitor);
      mozilla::MonitorAutoEnter autoMonitor(mDecoder->GetMonitor());
      if (mDecoder->GetDecodeState() ==
          nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
        mCurrentFrame = frame;
        return NS_ERROR_FAILURE;
      }
    }

    nsAutoPtr<VideoData> video(mVideoQueue.PeekFront());
    if (video && video->mEndTime < aTime) {
      mVideoQueue.PopFront();
      video = nsnull;
    } else {
      video.forget();
    }
  }

  return NS_OK;
}
コード例 #6
0
void
sbWindowWatcher::RemoveAllWindows()
{
  // Operate within the monitor.
  mozilla::ReentrantMonitorAutoEnter autoMonitor(mMonitor);

  // Remove all of the windows.
  PRInt32 windowCount = mWindowList.Count();
  for (PRInt32 i = windowCount - 1; i >= 0; i--) {
    RemoveWindow(mWindowList[i]);
  }
}
コード例 #7
0
NS_IMETHODIMP
sbWindowWatcher::GetIsShuttingDown(bool* aIsShuttingDown)
{
  // Validate arguments.
  NS_ENSURE_ARG_POINTER(aIsShuttingDown);

  // Operate within the monitor.
  mozilla::ReentrantMonitorAutoEnter autoMonitor(mMonitor);

  // Return results.
  *aIsShuttingDown = mIsShuttingDown;

  return NS_OK;
}
コード例 #8
0
ファイル: nsRawReader.cpp プロジェクト: Ajunboys/mozilla-os2
nsresult nsRawReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
{
  NS_ASSERTION(mDecoder->OnDecodeThread(),
               "Should be on decode thread.");

  MediaResource *resource = mDecoder->GetResource();
  NS_ASSERTION(resource, "Decoder has no media resource");

  uint32_t frame = mCurrentFrame;
  if (aTime >= UINT_MAX)
    return NS_ERROR_FAILURE;
  mCurrentFrame = aTime * mFrameRate / USECS_PER_S;

  CheckedUint32 offset = CheckedUint32(mCurrentFrame) * mFrameSize;
  offset += sizeof(nsRawVideoHeader);
  NS_ENSURE_TRUE(offset.isValid(), NS_ERROR_FAILURE);

  nsresult rv = resource->Seek(nsISeekableStream::NS_SEEK_SET, offset.value());
  NS_ENSURE_SUCCESS(rv, rv);

  mVideoQueue.Erase();

  while(mVideoQueue.GetSize() == 0) {
    bool keyframeSkip = false;
    if (!DecodeVideoFrame(keyframeSkip, 0)) {
      mCurrentFrame = frame;
      return NS_ERROR_FAILURE;
    }

    {
      mozilla::ReentrantMonitorAutoEnter autoMonitor(mDecoder->GetReentrantMonitor());
      if (mDecoder->GetDecodeState() ==
          nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
        mCurrentFrame = frame;
        return NS_ERROR_FAILURE;
      }
    }

    nsAutoPtr<VideoData> video(mVideoQueue.PeekFront());
    if (video && video->mEndTime < aTime) {
      mVideoQueue.PopFront();
      video = nullptr;
    } else {
      video.forget();
    }
  }

  return NS_OK;
}
コード例 #9
0
ファイル: nsRawReader.cpp プロジェクト: ehsan/mozilla-history
nsresult nsRawReader::ReadMetadata(nsVideoInfo* aInfo)
{
  NS_ASSERTION(mDecoder->OnDecodeThread(),
               "Should be on decode thread.");

  nsMediaStream* stream = mDecoder->GetCurrentStream();
  NS_ASSERTION(stream, "Decoder has no media stream");

  if (!ReadFromStream(stream, reinterpret_cast<PRUint8*>(&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;

  PRUint32 dummy;
  if (!MulOverflow32(mMetadata.frameWidth, mMetadata.frameHeight, dummy))
    return 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);

  PRInt64 length = stream->GetLength();
  if (length != -1) {
    mozilla::ReentrantMonitorAutoEnter autoMonitor(mDecoder->GetReentrantMonitor());
    mDecoder->GetStateMachine()->SetDuration(USECS_PER_S *
                                           (length - sizeof(nsRawVideoHeader)) /
                                           (mFrameSize * mFrameRate));
  }

  *aInfo = mInfo;

  return NS_OK;
}
コード例 #10
0
ファイル: nsRawReader.cpp プロジェクト: nikhilm/v8monkey
nsresult nsRawReader::ReadMetadata(nsVideoInfo* aInfo)
{
  NS_ASSERTION(mDecoder->OnStateMachineThread(),
               "Should be on state machine thread.");
  mozilla::MonitorAutoEnter autoEnter(mMonitor);

  nsMediaStream* stream = mDecoder->GetCurrentStream();
  NS_ASSERTION(stream, "Decoder has no media stream");

  if (!ReadFromStream(stream, reinterpret_cast<PRUint8*>(&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;

  PRUint32 dummy;
  if (!MulOverflow32(mMetadata.frameWidth, mMetadata.frameHeight, dummy))
    return NS_ERROR_FAILURE;

  mInfo.mHasVideo = PR_TRUE;
  mInfo.mPicture.x = 0;
  mInfo.mPicture.y = 0;
  mInfo.mPicture.width = mMetadata.frameWidth;
  mInfo.mPicture.height = mMetadata.frameHeight;
  mInfo.mFrame.width = mMetadata.frameWidth;
  mInfo.mFrame.height = mMetadata.frameHeight;
  if (mMetadata.aspectDenominator == 0 ||
      mMetadata.framerateDenominator == 0)
    return NS_ERROR_FAILURE; // Invalid data
  mInfo.mPixelAspectRatio = static_cast<float>(mMetadata.aspectNumerator) / 
                            mMetadata.aspectDenominator;
  mInfo.mHasAudio = PR_FALSE;

  mFrameRate = static_cast<float>(mMetadata.framerateNumerator) /
               mMetadata.framerateDenominator;

  // Make some sanity checks
  if (mFrameRate > 45 ||
      mFrameRate == 0 ||
      mInfo.mPixelAspectRatio == 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);

  PRInt64 length = stream->GetLength();
  if (length != -1) {
    mozilla::MonitorAutoExit autoExitMonitor(mMonitor);
    mozilla::MonitorAutoEnter autoMonitor(mDecoder->GetMonitor());
    mDecoder->GetStateMachine()->SetDuration(USECS_PER_S *
                                           (length - sizeof(nsRawVideoHeader)) /
                                           (mFrameSize * mFrameRate));
  }

  *aInfo = mInfo;

  return NS_OK;
}
コード例 #11
0
NS_IMETHODIMP
sbWindowWatcher::GetWindow(const nsAString& aWindowType,
                           nsIDOMWindow**   _retval)
{
  // Validate arguments.
  NS_ENSURE_ARG_POINTER(_retval);

  // Function variables.
  nsCOMPtr<nsIDOMWindow> retWindow;
  bool                 success;
  nsresult               rv;

  // This method may only be called on the main thread.
  NS_ENSURE_TRUE(SB_IsMainThread(mThreadManager), NS_ERROR_UNEXPECTED);

  // Operate within the monitor.
  mozilla::ReentrantMonitorAutoEnter autoMonitor(mMonitor);

  // Get an enumerator of all windows of the specified type, sorted from oldest
  // to youngest.
  nsCOMPtr<nsISimpleEnumerator> enumerator;
  rv = mWindowMediator->GetEnumerator(aWindowType.BeginReading(),
                                      getter_AddRefs(enumerator));
  NS_ENSURE_SUCCESS(rv, rv);

  // Search for the most recently focused ready window of the specified type.
  // The enumerator enumerates from oldest to youngest (least recently focused
  // to most recently), so the last matching window is the most recently focused
  // one.
  bool hasMoreElements;
  rv = enumerator->HasMoreElements(&hasMoreElements);
  NS_ENSURE_SUCCESS(rv, rv);
  while (hasMoreElements) {
    // Get the window.  Skip if not ready.
    nsCOMPtr<nsISupports> _window;
    nsCOMPtr<nsIDOMWindow> window;
    rv = enumerator->GetNext(getter_AddRefs(_window));
    NS_ENSURE_SUCCESS(rv, rv);
    window = do_QueryInterface(_window, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
    rv = enumerator->HasMoreElements(&hasMoreElements);
    NS_ENSURE_SUCCESS(rv, rv);

    // Skip window if not ready.
    WindowInfo* windowInfo;
    success = mWindowInfoTable.Get(window, &windowInfo);
    if (!success || !(windowInfo->isReady))
      continue;

    // Get the window type.
    nsAutoString windowType;
    rv = GetWindowType(window, windowType);
    if (NS_FAILED(rv))
      continue;

    // Check for a match.
    if (aWindowType.Equals(windowType)) {
      retWindow = window;
    }
  }

  // Return results.
  NS_IF_ADDREF(*_retval = retWindow);

  return NS_OK;
}
コード例 #12
0
nsresult
sbWindowWatcher::CallWithWindow_Proxy(const nsAString&           aWindowType,
                                  sbICallWithWindowCallback* aCallback,
                                  bool                     aWait)
{
  // Validate arguments.
  NS_ENSURE_ARG_POINTER(aCallback);

  // Function variables.
  nsresult rv;

  // If not on main thread, call back through a proxy.
  if (!SB_IsMainThread(mThreadManager)) {
    nsRefPtr<sbRunnable_<nsresult>> job =
      new sbRunnableMethod3_<nsresult,sbWindowWatcher,
      const nsAString&,sbICallWithWindowCallback*,bool>(
          *this,&sbWindowWatcher::CallWithWindow_Proxy,
          aWindowType,aCallback,aWait);
    // Call back through the proxy.  Wait for window if specified to do so.
    rv = NS_OK;
    while (1) {
      // Call the proxied window watcher.  Exit loop on success or if not
      // waiting.
      NS_DispatchToMainThread(job);
      rv = job->Wait();
      if (NS_SUCCEEDED(rv) || !aWait)
        break;
      if (rv != NS_ERROR_NOT_AVAILABLE)
        NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

      // Wait for a window if none available.
      rv = WaitForWindow(aWindowType);
      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
    }
    NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

    return NS_OK;
  }

  // Operate within the monitor.
  mozilla::ReentrantMonitorAutoEnter autoMonitor(mMonitor);

  // Check if window is already available.
  nsCOMPtr<nsIDOMWindow> window;
  rv = GetWindow(aWindowType, getter_AddRefs(window));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  // If a window is available or this instance is shutting down, call the
  // callback.  Otherwise, place the call with window information on the call
  // with window list.
  if (window || mIsShuttingDown) {
    aCallback->HandleWindowCallback(window);
  } else {
    // If specified to wait and the window is not available, return a not
    // available error indication instead of enqueuing onto the call with window
    // list.
    if (aWait)
      return NS_ERROR_NOT_AVAILABLE;

    // Place the call with window information on the call with window list.
    CallWithWindowInfo callWithWindowInfo;
    callWithWindowInfo.windowType = aWindowType;
    callWithWindowInfo.callback = aCallback;
    mCallWithWindowList.AppendElement(callWithWindowInfo);
  }

  return NS_OK;
}