Bug 1210286 - Fall back to converting SourceSurfaces (RGB) to NV12 in OMXCodecWrapper. r=jolin

--HG--
extra : commitid : HafpaHoj6i
extra : rebase_source : a975b625410158b345121f51b1839ac49d4a3883
This commit is contained in:
Andreas Pehrson 2015-10-12 10:33:58 +08:00
Родитель 80fca20565
Коммит 7fb8d88099
2 изменённых файлов: 76 добавлений и 3 удалений

Просмотреть файл

@ -17,7 +17,10 @@
#include "AudioChannelFormat.h"
#include "GrallocImages.h"
#include "LayersLogging.h"
#include "libyuv.h"
#include "mozilla/Monitor.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/GrallocTextureClient.h"
using namespace mozilla;
@ -380,6 +383,67 @@ ConvertGrallocImageToNV12(GrallocImage* aSource, uint8_t* aDestination)
graphicBuffer->unlock();
}
static nsresult
ConvertSourceSurfaceToNV12(const nsRefPtr<SourceSurface>& aSurface, uint8_t* aDestination)
{
uint32_t width = aSurface->GetSize().width;
uint32_t height = aSurface->GetSize().height;
uint8_t* y = aDestination;
int yStride = width;
uint8_t* uv = y + (yStride * height);
int uvStride = width / 2;
SurfaceFormat format = aSurface->GetFormat();
if (!aSurface) {
CODEC_ERROR("Getting surface %s from image failed", Stringify(format).c_str());
return NS_ERROR_FAILURE;
}
RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();
if (!data) {
CODEC_ERROR("Getting data surface from %s image with %s (%s) surface failed",
Stringify(format).c_str(), Stringify(aSurface->GetType()).c_str(),
Stringify(aSurface->GetFormat()).c_str());
return NS_ERROR_FAILURE;
}
DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ);
if (!map.IsMapped()) {
CODEC_ERROR("Reading DataSourceSurface from %s image with %s (%s) surface failed",
Stringify(format).c_str(), Stringify(aSurface->GetType()).c_str(),
Stringify(aSurface->GetFormat()).c_str());
return NS_ERROR_FAILURE;
}
int rv;
switch (aSurface->GetFormat()) {
case SurfaceFormat::B8G8R8A8:
case SurfaceFormat::B8G8R8X8:
rv = libyuv::ARGBToNV12(static_cast<uint8*>(map.GetData()),
map.GetStride(),
y, yStride,
uv, uvStride,
width, height);
break;
default:
CODEC_ERROR("Unsupported SourceSurface format %s",
Stringify(aSurface->GetFormat()).c_str());
NS_ASSERTION(false, "Unsupported SourceSurface format");
return NS_ERROR_NOT_IMPLEMENTED;
}
if (rv != 0) {
CODEC_ERROR("%s to I420 conversion failed",
Stringify(aSurface->GetFormat()).c_str());
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
int64_t aTimestamp, int aInputFlags, bool* aSendEOS)
@ -410,9 +474,10 @@ OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
halFormat == GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS,
NS_ERROR_INVALID_ARG);
} else {
// TODO: support RGB to YUV color conversion.
NS_ERROR("Unsupported input image type.");
return NS_ERROR_INVALID_ARG;
nsRefPtr<SourceSurface> surface = img->GetAsSourceSurface();
NS_ENSURE_TRUE(surface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
surface->GetFormat() == SurfaceFormat::B8G8R8X8,
NS_ERROR_INVALID_ARG);
}
}
@ -450,6 +515,13 @@ OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
} else if (format == ImageFormat::PLANAR_YCBCR) {
ConvertPlanarYCbCrToNV12(static_cast<PlanarYCbCrImage*>(img)->GetData(),
dst);
} else {
nsRefPtr<SourceSurface> surface = img->GetAsSourceSurface();
nsresult rv = ConvertSourceSurfaceToNV12(surface, dst);
if (rv != NS_OK) {
return NS_ERROR_FAILURE;
}
}
}

Просмотреть файл

@ -41,6 +41,7 @@ if CONFIG['MOZ_OMX_ENCODER']:
'OMXCodecDescriptorUtil.cpp',
'OMXCodecWrapper.cpp',
]
LOCAL_INCLUDES += ['/media/libyuv/include']
if 'rtsp' in CONFIG['NECKO_PROTOCOLS']:
EXPORTS += [