Loading browser/base/content/nsContextMenu.js +6 −36 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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. Loading browser/base/content/test/general/browser_selectpopup.js +23 −12 Original line number Original line Diff line number Diff line Loading @@ -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) Loading Loading @@ -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); Loading Loading @@ -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"); }); dom/media/platforms/apple/AppleVDADecoder.cpp +107 −32 Original line number Original line Diff line number Diff line Loading @@ -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. Loading Loading @@ -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(), Loading @@ -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); Loading @@ -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(), Loading @@ -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"); Loading Loading @@ -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 }; Loading @@ -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 }; Loading dom/media/platforms/apple/AppleVDADecoder.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -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); Loading dom/media/platforms/apple/AppleVTDecoder.cpp +3 −8 Original line number Original line Diff line number Diff line Loading @@ -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" Loading Loading @@ -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 Loading
browser/base/content/nsContextMenu.js +6 −36 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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. Loading
browser/base/content/test/general/browser_selectpopup.js +23 −12 Original line number Original line Diff line number Diff line Loading @@ -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) Loading Loading @@ -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); Loading Loading @@ -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"); });
dom/media/platforms/apple/AppleVDADecoder.cpp +107 −32 Original line number Original line Diff line number Diff line Loading @@ -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. Loading Loading @@ -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(), Loading @@ -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); Loading @@ -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(), Loading @@ -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"); Loading Loading @@ -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 }; Loading @@ -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 }; Loading
dom/media/platforms/apple/AppleVDADecoder.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -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); Loading
dom/media/platforms/apple/AppleVTDecoder.cpp +3 −8 Original line number Original line Diff line number Diff line Loading @@ -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" Loading Loading @@ -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