Commit d9980044 authored by Wes Kocher's avatar Wes Kocher
Browse files

Merge inbound to central, a=merge CLOSED TREE

--HG--
extra : amend_source : fc9d33844a7172d62ec9d2184833a18cdaa28d5d
parents 3188a805 6cfdf70c
Loading
Loading
Loading
Loading
+6 −36
Original line number Original line Diff line number Diff line
@@ -1005,27 +1005,8 @@ nsContextMenu.prototype = {


  // View Partial Source
  // View Partial Source
  viewPartialSource: function(aContext) {
  viewPartialSource: function(aContext) {
    var focusedWindow = document.commandDispatcher.focusedWindow;
    let inWindow = !Services.prefs.getBoolPref("view_source.tab");
    if (focusedWindow == window)
    let openSelectionFn = inWindow ? null : function() {
      focusedWindow = gBrowser.selectedBrowser.contentWindowAsCPOW;

    var docCharset = null;
    if (focusedWindow)
      docCharset = "charset=" + focusedWindow.document.characterSet;

    // "View Selection Source" and others such as "View MathML Source"
    // are mutually exclusive, with the precedence given to the selection
    // when there is one
    var reference = null;
    if (aContext == "selection")
      reference = focusedWindow.getSelection();
    else if (aContext == "mathml")
      reference = this.target;
    else
      throw "not reached";

    let inTab = Services.prefs.getBoolPref("view_source.tab");
    if (inTab) {
      let tabBrowser = gBrowser;
      let tabBrowser = gBrowser;
      // In the case of sidebars and chat windows, gBrowser is defined but null,
      // In the case of sidebars and chat windows, gBrowser is defined but null,
      // because no #content element exists.  For these cases, we need to find
      // because no #content element exists.  For these cases, we need to find
@@ -1040,22 +1021,11 @@ nsContextMenu.prototype = {
        relatedToCurrent: true,
        relatedToCurrent: true,
        inBackground: false
        inBackground: false
      });
      });
      let viewSourceBrowser = tabBrowser.getBrowserForTab(tab);
      return tabBrowser.getBrowserForTab(tab);
      if (aContext == "selection") {
        top.gViewSourceUtils
           .viewSourceFromSelectionInBrowser(reference, viewSourceBrowser);
      } else {
        top.gViewSourceUtils
           .viewSourceFromFragmentInBrowser(reference, aContext,
                                            viewSourceBrowser);
      }
    } else {
      // unused (and play nice for fragments generated via XSLT too)
      var docUrl = null;
      window.openDialog("chrome://global/content/viewPartialSource.xul",
                        "_blank", "scrollbars,resizable,chrome,dialog=no",
                        docUrl, docCharset, reference, aContext);
    }
    }

    let target = aContext == "mathml" ? this.target : null;
    top.gViewSourceUtils.viewPartialSourceInBrowser(gBrowser.selectedBrowser, target, openSelectionFn);
  },
  },


  // Open new "view source" window with the frame's URL.
  // Open new "view source" window with the frame's URL.
+23 −12
Original line number Original line Diff line number Diff line
@@ -6,21 +6,22 @@
// to implement the dropdown list.
// to implement the dropdown list.


const PAGECONTENT =
const PAGECONTENT =
  "<html><body onload='gChangeEvents = 0; document.body.firstChild.focus()'><select onchange='gChangeEvents++'>" +
  "<html xmlns='http://www.w3.org/1999/xhtml'>" + 
  "<body onload='gChangeEvents = 0; document.body.firstChild.focus()'><select onchange='gChangeEvents++'>" +
  "  <optgroup label='First Group'>" +
  "  <optgroup label='First Group'>" +
  "    <option value=One>One" +
  "    <option value='One'>One</option>" +
  "    <option value=Two>Two" +
  "    <option value='Two'>Two</option>" +
  "  </optgroup>" +
  "  </optgroup>" +
  "  <option value=Three>Three" +
  "  <option value='Three'>Three</option>" +
  "  <optgroup label='Second Group' disabled='true'>" +
  "  <optgroup label='Second Group' disabled='true'>" +
  "    <option value=Four>Four" +
  "    <option value='Four'>Four</option>" +
  "    <option value=Five>Five" +
  "    <option value='Five'>Five</option>" +
  "  </optgroup>" +
  "  </optgroup>" +
  "  <option value=Six disabled='true'>Six" +
  "  <option value='Six' disabled='true'>Six</option>" +
  "  <optgroup label='Third Group'>" +
  "  <optgroup label='Third Group'>" +
  "    <option value=Seven>Seven" +
  "    <option value='Seven'>Seven</option>" +
  "    <option value=Eight>Eight" +
  "    <option value='Eight'>Eight</option>" +
  "  </optgroup></select><input>" +
  "  </optgroup></select><input />" +
  "</body></html>";
  "</body></html>";


function openSelectPopup(selectPopup, withMouse)
function openSelectPopup(selectPopup, withMouse)
@@ -57,10 +58,11 @@ function getChangeEvents()
  });
  });
}
}


add_task(function*() {
function doSelectTests(contentType)
{
  let tab = gBrowser.selectedTab = gBrowser.addTab();
  let tab = gBrowser.selectedTab = gBrowser.addTab();
  let browser = gBrowser.getBrowserForTab(tab);
  let browser = gBrowser.getBrowserForTab(tab);
  yield promiseTabLoadEvent(tab, "data:text/html," + escape(PAGECONTENT));
  yield promiseTabLoadEvent(tab, "data:" + contentType + "," + escape(PAGECONTENT));


  yield SimpleTest.promiseFocus(browser.contentWindow);
  yield SimpleTest.promiseFocus(browser.contentWindow);


@@ -126,5 +128,14 @@ add_task(function*() {
  is((yield getChangeEvents()), isWindows ? 2 : 1, "Tab away from select with change - number of change events");
  is((yield getChangeEvents()), isWindows ? 2 : 1, "Tab away from select with change - number of change events");


  gBrowser.removeCurrentTab();
  gBrowser.removeCurrentTab();
}

add_task(function*() {
  yield doSelectTests("text/html");
});
});


add_task(function*() {
  yield doSelectTests("application/xhtml+xml");
});

+107 −32
Original line number Original line Diff line number Diff line
@@ -40,8 +40,9 @@ AppleVDADecoder::AppleVDADecoder(const VideoInfo& aConfig,
  , mPictureHeight(aConfig.mImage.height)
  , mPictureHeight(aConfig.mImage.height)
  , mDisplayWidth(aConfig.mDisplay.width)
  , mDisplayWidth(aConfig.mDisplay.width)
  , mDisplayHeight(aConfig.mDisplay.height)
  , mDisplayHeight(aConfig.mDisplay.height)
  , mDecoder(nullptr)
  , mUseSoftwareImages(false)
  , mIs106(!nsCocoaFeatures::OnLionOrLater())
  , mIs106(!nsCocoaFeatures::OnLionOrLater())
  , mDecoder(nullptr)
{
{
  MOZ_COUNT_CTOR(AppleVDADecoder);
  MOZ_COUNT_CTOR(AppleVDADecoder);
  // TODO: Verify aConfig.mime_type.
  // TODO: Verify aConfig.mime_type.
@@ -248,9 +249,6 @@ nsresult
AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage,
AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage,
                             nsAutoPtr<AppleVDADecoder::AppleFrameRef> aFrameRef)
                             nsAutoPtr<AppleVDADecoder::AppleFrameRef> aFrameRef)
{
{
  IOSurfacePtr surface = MacIOSurfaceLib::CVPixelBufferGetIOSurface(aImage);
  MOZ_ASSERT(surface, "Decoder didn't return an IOSurface backed buffer");

  LOG("mp4 output frame %lld dts %lld pts %lld duration %lld us%s",
  LOG("mp4 output frame %lld dts %lld pts %lld duration %lld us%s",
      aFrameRef->byte_offset,
      aFrameRef->byte_offset,
      aFrameRef->decode_timestamp.ToMicroseconds(),
      aFrameRef->decode_timestamp.ToMicroseconds(),
@@ -259,7 +257,8 @@ AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage,
      aFrameRef->is_sync_point ? " keyframe" : ""
      aFrameRef->is_sync_point ? " keyframe" : ""
  );
  );


  nsRefPtr<MacIOSurface> macSurface = new MacIOSurface(surface);
  // Where our resulting image will end up.
  nsRefPtr<VideoData> data;
  // Bounds.
  // Bounds.
  VideoInfo info;
  VideoInfo info;
  info.mDisplay = nsIntSize(mDisplayWidth, mDisplayHeight);
  info.mDisplay = nsIntSize(mDisplayWidth, mDisplayHeight);
@@ -268,14 +267,74 @@ AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage,
                                      mPictureWidth,
                                      mPictureWidth,
                                      mPictureHeight);
                                      mPictureHeight);


  if (mUseSoftwareImages) {
    size_t width = CVPixelBufferGetWidth(aImage);
    size_t height = CVPixelBufferGetHeight(aImage);
    DebugOnly<size_t> planes = CVPixelBufferGetPlaneCount(aImage);
    MOZ_ASSERT(planes == 2, "Likely not NV12 format and it must be.");

    VideoData::YCbCrBuffer buffer;

    // Lock the returned image data.
    CVReturn rv = CVPixelBufferLockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
    if (rv != kCVReturnSuccess) {
      NS_ERROR("error locking pixel data");
      mCallback->Error();
      return NS_ERROR_FAILURE;
    }
    // Y plane.
    buffer.mPlanes[0].mData =
      static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 0));
    buffer.mPlanes[0].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 0);
    buffer.mPlanes[0].mWidth = width;
    buffer.mPlanes[0].mHeight = height;
    buffer.mPlanes[0].mOffset = 0;
    buffer.mPlanes[0].mSkip = 0;
    // Cb plane.
    buffer.mPlanes[1].mData =
      static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 1));
    buffer.mPlanes[1].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 1);
    buffer.mPlanes[1].mWidth = (width+1) / 2;
    buffer.mPlanes[1].mHeight = (height+1) / 2;
    buffer.mPlanes[1].mOffset = 0;
    buffer.mPlanes[1].mSkip = 1;
    // Cr plane.
    buffer.mPlanes[2].mData =
      static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 1));
    buffer.mPlanes[2].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 1);
    buffer.mPlanes[2].mWidth = (width+1) / 2;
    buffer.mPlanes[2].mHeight = (height+1) / 2;
    buffer.mPlanes[2].mOffset = 1;
    buffer.mPlanes[2].mSkip = 1;

    // Copy the image data into our own format.
    data =
      VideoData::Create(info,
                        mImageContainer,
                        nullptr,
                        aFrameRef->byte_offset,
                        aFrameRef->composition_timestamp.ToMicroseconds(),
                        aFrameRef->duration.ToMicroseconds(),
                        buffer,
                        aFrameRef->is_sync_point,
                        aFrameRef->decode_timestamp.ToMicroseconds(),
                        visible);
    // Unlock the returned image data.
    CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
  } else {
    IOSurfacePtr surface = MacIOSurfaceLib::CVPixelBufferGetIOSurface(aImage);
    MOZ_ASSERT(surface, "Decoder didn't return an IOSurface backed buffer");

    nsRefPtr<MacIOSurface> macSurface = new MacIOSurface(surface);

    nsRefPtr<layers::Image> image =
    nsRefPtr<layers::Image> image =
      mImageContainer->CreateImage(ImageFormat::MAC_IOSURFACE);
      mImageContainer->CreateImage(ImageFormat::MAC_IOSURFACE);
    layers::MacIOSurfaceImage* videoImage =
    layers::MacIOSurfaceImage* videoImage =
      static_cast<layers::MacIOSurfaceImage*>(image.get());
      static_cast<layers::MacIOSurfaceImage*>(image.get());
    videoImage->SetSurface(macSurface);
    videoImage->SetSurface(macSurface);


  nsRefPtr<VideoData> data;
    data =
  data = VideoData::CreateFromImage(info,
      VideoData::CreateFromImage(info,
                                 mImageContainer,
                                 mImageContainer,
                                 aFrameRef->byte_offset,
                                 aFrameRef->byte_offset,
                                 aFrameRef->composition_timestamp.ToMicroseconds(),
                                 aFrameRef->composition_timestamp.ToMicroseconds(),
@@ -284,6 +343,7 @@ AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage,
                                 aFrameRef->is_sync_point,
                                 aFrameRef->is_sync_point,
                                 aFrameRef->decode_timestamp.ToMicroseconds(),
                                 aFrameRef->decode_timestamp.ToMicroseconds(),
                                 visible);
                                 visible);
  }


  if (!data) {
  if (!data) {
    NS_ERROR("Couldn't create VideoData for frame");
    NS_ERROR("Couldn't create VideoData for frame");
@@ -459,6 +519,27 @@ AppleVDADecoder::CreateDecoderSpecification()
CFDictionaryRef
CFDictionaryRef
AppleVDADecoder::CreateOutputConfiguration()
AppleVDADecoder::CreateOutputConfiguration()
{
{
  // Output format type:
  SInt32 PixelFormatTypeValue = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
  AutoCFRelease<CFNumberRef> PixelFormatTypeNumber =
    CFNumberCreate(kCFAllocatorDefault,
                   kCFNumberSInt32Type,
                   &PixelFormatTypeValue);

  if (mUseSoftwareImages) {
    const void* outputKeys[] = { kCVPixelBufferPixelFormatTypeKey };
    const void* outputValues[] = { PixelFormatTypeNumber };
    static_assert(ArrayLength(outputKeys) == ArrayLength(outputValues),
                  "Non matching keys/values array size");

    return CFDictionaryCreate(kCFAllocatorDefault,
                              outputKeys,
                              outputValues,
                              ArrayLength(outputKeys),
                              &kCFTypeDictionaryKeyCallBacks,
                              &kCFTypeDictionaryValueCallBacks);
  }

  // Construct IOSurface Properties
  // Construct IOSurface Properties
  const void* IOSurfaceKeys[] = { MacIOSurfaceLib::kPropIsGlobal };
  const void* IOSurfaceKeys[] = { MacIOSurfaceLib::kPropIsGlobal };
  const void* IOSurfaceValues[] = { kCFBooleanTrue };
  const void* IOSurfaceValues[] = { kCFBooleanTrue };
@@ -474,12 +555,6 @@ AppleVDADecoder::CreateOutputConfiguration()
                       &kCFTypeDictionaryKeyCallBacks,
                       &kCFTypeDictionaryKeyCallBacks,
                       &kCFTypeDictionaryValueCallBacks);
                       &kCFTypeDictionaryValueCallBacks);


  SInt32 PixelFormatTypeValue = kCVPixelFormatType_32BGRA;
  AutoCFRelease<CFNumberRef> PixelFormatTypeNumber =
    CFNumberCreate(kCFAllocatorDefault,
                   kCFNumberSInt32Type,
                   &PixelFormatTypeValue);

  const void* outputKeys[] = { kCVPixelBufferIOSurfacePropertiesKey,
  const void* outputKeys[] = { kCVPixelBufferIOSurfacePropertiesKey,
                               kCVPixelBufferPixelFormatTypeKey,
                               kCVPixelBufferPixelFormatTypeKey,
                               kCVPixelBufferOpenGLCompatibilityKey };
                               kCVPixelBufferOpenGLCompatibilityKey };
+2 −1
Original line number Original line Diff line number Diff line
@@ -99,10 +99,11 @@ public:
  uint32_t mDisplayWidth;
  uint32_t mDisplayWidth;
  uint32_t mDisplayHeight;
  uint32_t mDisplayHeight;
  uint32_t mMaxRefFrames;
  uint32_t mMaxRefFrames;
  bool mUseSoftwareImages;
  bool mIs106;


private:
private:
  VDADecoder mDecoder;
  VDADecoder mDecoder;
  bool mIs106;


  // Method to pass a frame to VideoToolbox for decoding.
  // Method to pass a frame to VideoToolbox for decoding.
  nsresult SubmitFrame(MediaRawData* aSample);
  nsresult SubmitFrame(MediaRawData* aSample);
+3 −8
Original line number Original line Diff line number Diff line
@@ -12,7 +12,6 @@
#include "AppleVTLinker.h"
#include "AppleVTLinker.h"
#include "mp4_demuxer/H264.h"
#include "mp4_demuxer/H264.h"
#include "MediaData.h"
#include "MediaData.h"
#include "MacIOSurfaceImage.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/ArrayUtils.h"
#include "nsAutoPtr.h"
#include "nsAutoPtr.h"
#include "nsThreadUtils.h"
#include "nsThreadUtils.h"
@@ -350,23 +349,19 @@ AppleVTDecoder::CreateDecoderExtensions()
  const void* extensionKeys[] =
  const void* extensionKeys[] =
    { kCVImageBufferChromaLocationBottomFieldKey,
    { kCVImageBufferChromaLocationBottomFieldKey,
      kCVImageBufferChromaLocationTopFieldKey,
      kCVImageBufferChromaLocationTopFieldKey,
      AppleCMLinker::skPropExtensionAtoms,
      AppleCMLinker::skPropExtensionAtoms };
      AppleCMLinker::skPropFullRangeVideo /* Not defined in 10.6 */ };


  const void* extensionValues[] =
  const void* extensionValues[] =
    { kCVImageBufferChromaLocation_Left,
    { kCVImageBufferChromaLocation_Left,
      kCVImageBufferChromaLocation_Left,
      kCVImageBufferChromaLocation_Left,
      atoms,
      atoms };
      kCFBooleanTrue };
  static_assert(ArrayLength(extensionKeys) == ArrayLength(extensionValues),
  static_assert(ArrayLength(extensionKeys) == ArrayLength(extensionValues),
                "Non matching keys/values array size");
                "Non matching keys/values array size");


  return CFDictionaryCreate(kCFAllocatorDefault,
  return CFDictionaryCreate(kCFAllocatorDefault,
                            extensionKeys,
                            extensionKeys,
                            extensionValues,
                            extensionValues,
                            AppleCMLinker::skPropFullRangeVideo ?
                            ArrayLength(extensionKeys),
                              ArrayLength(extensionKeys) :
                              ArrayLength(extensionKeys) - 1,
                            &kCFTypeDictionaryKeyCallBacks,
                            &kCFTypeDictionaryKeyCallBacks,
                            &kCFTypeDictionaryValueCallBacks);
                            &kCFTypeDictionaryValueCallBacks);
}
}
Loading