--- a/dom/media/encoder/VP8TrackEncoder.cpp
+++ b/dom/media/encoder/VP8TrackEncoder.cpp
@@ -10,29 +10,32 @@
#include "mozilla/gfx/2D.h"
#include "prsystem.h"
#include "VideoSegment.h"
#include "VideoUtils.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "WebMWriter.h"
#include "mozilla/media/MediaUtils.h"
+#include "mozilla/dom/ImageUtils.h"
+#include "mozilla/dom/ImageBitmapBinding.h"
namespace mozilla {
LazyLogModule gVP8TrackEncoderLog("VP8TrackEncoder");
#define VP8LOG(level, msg, ...) MOZ_LOG(gVP8TrackEncoderLog, \
level, \
(msg, ##__VA_ARGS__))
#define DEFAULT_BITRATE_BPS 2500000
using namespace mozilla::gfx;
using namespace mozilla::layers;
using namespace mozilla::media;
+using namespace mozilla::dom;
static already_AddRefed<SourceSurface>
GetSourceSurface(already_AddRefed<Image> aImg)
{
RefPtr<Image> img = aImg;
if (!img) {
return nullptr;
}
@@ -310,41 +313,16 @@ VP8TrackEncoder::GetEncodedPartitions(En
videoData->GetTimeStamp(), videoData->GetDuration(),
videoData->GetFrameType());
aData.AppendEncodedFrame(videoData);
}
return pkt ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
-static bool isYUV420(const PlanarYCbCrImage::Data *aData)
-{
- if (aData->mYSize == aData->mCbCrSize * 2) {
- return true;
- }
- return false;
-}
-
-static bool isYUV422(const PlanarYCbCrImage::Data *aData)
-{
- if ((aData->mYSize.width == aData->mCbCrSize.width * 2) &&
- (aData->mYSize.height == aData->mCbCrSize.height)) {
- return true;
- }
- return false;
-}
-
-static bool isYUV444(const PlanarYCbCrImage::Data *aData)
-{
- if (aData->mYSize == aData->mCbCrSize) {
- return true;
- }
- return false;
-}
-
nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk)
{
RefPtr<Image> img;
if (aChunk.mFrame.GetForceBlack() || aChunk.IsNull()) {
if (!mMuteFrame) {
mMuteFrame = VideoFrame::CreateBlackImage(gfx::IntSize(mFrameWidth, mFrameHeight));
}
if (!mMuteFrame) {
@@ -389,20 +367,26 @@ nsresult VP8TrackEncoder::PrepareRawFram
if (format == ImageFormat::PLANAR_YCBCR) {
PlanarYCbCrImage* yuv = static_cast<PlanarYCbCrImage *>(img.get());
MOZ_RELEASE_ASSERT(yuv);
if (!yuv->IsValid()) {
NS_WARNING("PlanarYCbCrImage is not valid");
return NS_ERROR_FAILURE;
}
- const PlanarYCbCrImage::Data *data = yuv->GetData();
- if (isYUV420(data) && !data->mCbSkip) {
+ // The ImageUtils API may change depending on our support for ImageBitmap
+ // extensions. Should this happen in a breaking way we should abstract out
+ // the format detection for use here.
+ const ImageUtils imageUtils(img);
+ const ImageBitmapFormat imageBitmapFormat = imageUtils.GetFormat();
+
+ if (imageBitmapFormat == ImageBitmapFormat::YUV420P) {
// 420 planar, no need for conversions
+ const PlanarYCbCrImage::Data* data = yuv->GetData();
mVPXImageWrapper->planes[VPX_PLANE_Y] = data->mYChannel;
mVPXImageWrapper->planes[VPX_PLANE_U] = data->mCbChannel;
mVPXImageWrapper->planes[VPX_PLANE_V] = data->mCrChannel;
mVPXImageWrapper->stride[VPX_PLANE_Y] = data->mYStride;
mVPXImageWrapper->stride[VPX_PLANE_U] = data->mCbCrStride;
mVPXImageWrapper->stride[VPX_PLANE_V] = data->mCbCrStride;
return NS_OK;
@@ -426,56 +410,82 @@ nsresult VP8TrackEncoder::PrepareRawFram
if (format == ImageFormat::PLANAR_YCBCR) {
PlanarYCbCrImage* yuv = static_cast<PlanarYCbCrImage *>(img.get());
MOZ_RELEASE_ASSERT(yuv);
if (!yuv->IsValid()) {
NS_WARNING("PlanarYCbCrImage is not valid");
return NS_ERROR_FAILURE;
}
+
+ const ImageUtils imageUtils(img);
+ const ImageBitmapFormat imageBitmapFormat = imageUtils.GetFormat();
const PlanarYCbCrImage::Data *data = yuv->GetData();
int rv;
std::string yuvFormat;
- if (isYUV420(data) && data->mCbSkip) {
- // If mCbSkip is set, we assume it's nv12 or nv21.
- if (data->mCbChannel < data->mCrChannel) { // nv12
- rv = libyuv::NV12ToI420(data->mYChannel, data->mYStride,
- data->mCbChannel, data->mCbCrStride,
- y, mFrameWidth,
- cb, halfWidth,
- cr, halfWidth,
- mFrameWidth, mFrameHeight);
- yuvFormat = "NV12";
- } else { // nv21
- rv = libyuv::NV21ToI420(data->mYChannel, data->mYStride,
- data->mCrChannel, data->mCbCrStride,
- y, mFrameWidth,
- cb, halfWidth,
- cr, halfWidth,
- mFrameWidth, mFrameHeight);
- yuvFormat = "NV21";
- }
- } else if (isYUV444(data) && !data->mCbSkip) {
- rv = libyuv::I444ToI420(data->mYChannel, data->mYStride,
- data->mCbChannel, data->mCbCrStride,
- data->mCrChannel, data->mCbCrStride,
- y, mFrameWidth,
- cb, halfWidth,
- cr, halfWidth,
- mFrameWidth, mFrameHeight);
+ if (imageBitmapFormat == ImageBitmapFormat::YUV420SP_NV12) {
+ rv = libyuv::NV12ToI420(data->mYChannel,
+ data->mYStride,
+ data->mCbChannel,
+ data->mCbCrStride,
+ y,
+ mFrameWidth,
+ cb,
+ halfWidth,
+ cr,
+ halfWidth,
+ mFrameWidth,
+ mFrameHeight);
+ yuvFormat = "NV12";
+ } else if (imageBitmapFormat == ImageBitmapFormat::YUV420SP_NV21) {
+ rv = libyuv::NV21ToI420(data->mYChannel,
+ data->mYStride,
+ data->mCrChannel,
+ data->mCbCrStride,
+ y,
+ mFrameWidth,
+ cb,
+ halfWidth,
+ cr,
+ halfWidth,
+ mFrameWidth,
+ mFrameHeight);
+ yuvFormat = "NV21";
+ } else if (imageBitmapFormat == ImageBitmapFormat::YUV444P) {
+ rv = libyuv::I444ToI420(data->mYChannel,
+ data->mYStride,
+ data->mCbChannel,
+ data->mCbCrStride,
+ data->mCrChannel,
+ data->mCbCrStride,
+ y,
+ mFrameWidth,
+ cb,
+ halfWidth,
+ cr,
+ halfWidth,
+ mFrameWidth,
+ mFrameHeight);
yuvFormat = "I444";
- } else if (isYUV422(data) && !data->mCbSkip) {
- rv = libyuv::I422ToI420(data->mYChannel, data->mYStride,
- data->mCbChannel, data->mCbCrStride,
- data->mCrChannel, data->mCbCrStride,
- y, mFrameWidth,
- cb, halfWidth,
- cr, halfWidth,
- mFrameWidth, mFrameHeight);
+ } else if (imageBitmapFormat == ImageBitmapFormat::YUV422P) {
+ rv = libyuv::I422ToI420(data->mYChannel,
+ data->mYStride,
+ data->mCbChannel,
+ data->mCbCrStride,
+ data->mCrChannel,
+ data->mCbCrStride,
+ y,
+ mFrameWidth,
+ cb,
+ halfWidth,
+ cr,
+ halfWidth,
+ mFrameWidth,
+ mFrameHeight);
yuvFormat = "I422";
} else {
VP8LOG(LogLevel::Error, "Unsupported planar format");
NS_ASSERTION(false, "Unsupported planar format");
return NS_ERROR_NOT_IMPLEMENTED;
}
if (rv != 0) {