Bug 1169125 - Part 1: Allow sending any DataSourceSurface-backed image over WebRTC and fix failure cases. r=bwc

--HG--
extra : rebase_source : c4a9d4fb40d1ea2aefe3be7bfa864998dc2062fa
extra : histedit_source : d7909e28671d1b965798e7e040a8fdc51309585f
This commit is contained in:
Andreas Pehrson 2015-06-09 13:31:22 +08:00
Родитель 2d74879e56
Коммит f76298db5c
1 изменённых файлов: 50 добавлений и 32 удалений

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

@ -43,6 +43,7 @@
#endif
#include "mozilla/gfx/Point.h"
#include "mozilla/gfx/Types.h"
#include "mozilla/UniquePtr.h"
#include "logging.h"
@ -1157,12 +1158,20 @@ void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk(
MOZ_MTLOG(ML_DEBUG, "Sending a video frame");
// Not much for us to do with an error
conduit->SendVideoFrame(y, I420SIZE(width, height), width, height, mozilla::kVideoI420, 0);
} else if(format == ImageFormat::CAIRO_SURFACE) {
layers::CairoImage* rgb =
const_cast<layers::CairoImage *>(
static_cast<const layers::CairoImage *>(img));
} else {
RefPtr<gfx::SourceSurface> surf = img->GetAsSourceSurface();
if (!surf) {
MOZ_MTLOG(ML_ERROR, "Getting surface from image failed");
return;
}
gfx::IntSize size = rgb->GetSize();
RefPtr<gfx::DataSourceSurface> data = surf->GetDataSurface();
if (!data) {
MOZ_MTLOG(ML_ERROR, "Getting data surface from image failed");
return;
}
gfx::IntSize size = img->GetSize();
int half_width = (size.width + 1) >> 1;
int half_height = (size.height + 1) >> 1;
int c_size = half_width * half_height;
@ -1171,37 +1180,46 @@ void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk(
if (!yuv)
return;
int cb_offset = YSIZE(size.width, size.height);
int cr_offset = cb_offset + c_size;
RefPtr<gfx::SourceSurface> tempSurf = rgb->GetAsSourceSurface();
RefPtr<gfx::DataSourceSurface> surf = tempSurf->GetDataSurface();
{
DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ);
if (!map.IsMapped()) {
MOZ_MTLOG(ML_ERROR, "Reading DataSourceSurface failed");
return;
}
switch (surf->GetFormat()) {
case gfx::SurfaceFormat::B8G8R8A8:
case gfx::SurfaceFormat::B8G8R8X8:
libyuv::ARGBToI420(static_cast<uint8*>(surf->GetData()), surf->Stride(),
yuv, size.width,
yuv + cb_offset, half_width,
yuv + cr_offset, half_width,
size.width, size.height);
break;
case gfx::SurfaceFormat::R5G6B5:
libyuv::RGB565ToI420(static_cast<uint8*>(surf->GetData()), surf->Stride(),
yuv, size.width,
yuv + cb_offset, half_width,
yuv + cr_offset, half_width,
size.width, size.height);
break;
default:
MOZ_MTLOG(ML_ERROR, "Unsupported RGB video format");
MOZ_ASSERT(PR_FALSE);
int rv;
int cb_offset = YSIZE(size.width, size.height);
int cr_offset = cb_offset + c_size;
switch (surf->GetFormat()) {
case gfx::SurfaceFormat::B8G8R8A8:
case gfx::SurfaceFormat::B8G8R8X8:
rv = libyuv::ARGBToI420(static_cast<uint8*>(map.GetData()),
map.GetStride(),
yuv, size.width,
yuv + cb_offset, half_width,
yuv + cr_offset, half_width,
size.width, size.height);
break;
case gfx::SurfaceFormat::R5G6B5:
rv = libyuv::RGB565ToI420(static_cast<uint8*>(map.GetData()),
map.GetStride(),
yuv, size.width,
yuv + cb_offset, half_width,
yuv + cr_offset, half_width,
size.width, size.height);
break;
default:
MOZ_MTLOG(ML_ERROR, "Unsupported RGB video format");
MOZ_ASSERT(PR_FALSE);
return;
}
if (rv != 0) {
MOZ_MTLOG(ML_ERROR, "RGB to I420 conversion failed");
return;
}
}
conduit->SendVideoFrame(yuv, buffer_size, size.width, size.height, mozilla::kVideoI420, 0);
free(yuv);
} else {
MOZ_MTLOG(ML_ERROR, "Unsupported video format");
MOZ_ASSERT(PR_FALSE);
return;
}
}
#endif