Bug 1493898 - P3. Don't downsample 10/12 bits AOM images. r=bryce

All compositors support 10/12 bits images now.
Additionally, add BT2020 support to AOM decoder.

Differential Revision: https://phabricator.services.mozilla.com/D25344

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jean-Yves Avenard 2019-04-11 12:40:59 +00:00
Родитель 1da8a6804f
Коммит 09b5578692
1 изменённых файлов: 25 добавлений и 86 удалений

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

@ -110,54 +110,6 @@ RefPtr<MediaDataDecoder::FlushPromise> AOMDecoder::Flush() {
});
}
// Ported from third_party/aom/tools_common.c.
static aom_codec_err_t highbd_img_downshift(aom_image_t* dst, aom_image_t* src,
int down_shift) {
int plane;
if (dst->d_w != src->d_w || dst->d_h != src->d_h)
return AOM_CODEC_INVALID_PARAM;
if (dst->x_chroma_shift != src->x_chroma_shift)
return AOM_CODEC_INVALID_PARAM;
if (dst->y_chroma_shift != src->y_chroma_shift)
return AOM_CODEC_INVALID_PARAM;
if (dst->fmt != (src->fmt & ~AOM_IMG_FMT_HIGHBITDEPTH))
return AOM_CODEC_INVALID_PARAM;
if (down_shift < 0) return AOM_CODEC_INVALID_PARAM;
switch (dst->fmt) {
case AOM_IMG_FMT_I420:
case AOM_IMG_FMT_I422:
case AOM_IMG_FMT_I444:
break;
default:
return AOM_CODEC_INVALID_PARAM;
}
switch (src->fmt) {
case AOM_IMG_FMT_I42016:
case AOM_IMG_FMT_I42216:
case AOM_IMG_FMT_I44416:
break;
default:
// We don't support anything that's not 16 bit
return AOM_CODEC_UNSUP_BITSTREAM;
}
for (plane = 0; plane < 3; plane++) {
int w = src->d_w;
int h = src->d_h;
int x, y;
if (plane) {
w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
}
for (y = 0; y < h; y++) {
uint16_t* p_src =
(uint16_t*)(src->planes[plane] + y * src->stride[plane]);
uint8_t* p_dst = dst->planes[plane] + y * dst->stride[plane];
for (x = 0; x < w; x++) *p_dst++ = (*p_src++ >> down_shift) & 0xFF;
}
}
return AOM_CODEC_OK;
}
// UniquePtr dtor wrapper for aom_image_t.
struct AomImageFree {
void operator()(aom_image_t* img) { aom_img_free(img); }
@ -189,40 +141,6 @@ RefPtr<MediaDataDecoder::DecodePromise> AOMDecoder::ProcessDecode(
DecodedData results;
while ((img = aom_codec_get_frame(&mCodec, &iter))) {
// Track whether the underlying buffer is 8 or 16 bits per channel.
bool highbd = bool(img->fmt & AOM_IMG_FMT_HIGHBITDEPTH);
if (highbd) {
// Downsample images with more than 8 bits per channel.
aom_img_fmt_t fmt8 =
static_cast<aom_img_fmt_t>(img->fmt ^ AOM_IMG_FMT_HIGHBITDEPTH);
img8.reset(aom_img_alloc(NULL, fmt8, img->d_w, img->d_h, 16));
if (img8 == nullptr) {
LOG("Couldn't allocate bitdepth reduction target!");
return DecodePromise::CreateAndReject(
MediaResult(
NS_ERROR_OUT_OF_MEMORY,
RESULT_DETAIL(
"Couldn't allocate conversion buffer for AV1 frame")),
__func__);
}
if (aom_codec_err_t r =
highbd_img_downshift(img8.get(), img, img->bit_depth - 8)) {
LOG_RESULT(r, "Image downconversion failed");
return DecodePromise::CreateAndReject(
MediaResult(
NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("Error converting AV1 frame to 8 bits: %s",
aom_codec_err_to_string(r))),
__func__);
}
// img normally points to storage owned by mCodec, so it is not freed.
// To copy out the contents of img8 we can overwrite img with an alias.
// Since img is assigned at the start of the while loop and img8 is held
// outside that loop, the alias won't outlive the storage it points to.
img = img8.get();
highbd = false;
}
NS_ASSERTION(
img->fmt == AOM_IMG_FMT_I420 || img->fmt == AOM_IMG_FMT_I42016 ||
img->fmt == AOM_IMG_FMT_I444 || img->fmt == AOM_IMG_FMT_I44416,
@ -235,17 +153,17 @@ RefPtr<MediaDataDecoder::DecodePromise> AOMDecoder::ProcessDecode(
b.mPlanes[0].mHeight = img->d_h;
b.mPlanes[0].mWidth = img->d_w;
b.mPlanes[0].mOffset = 0;
b.mPlanes[0].mSkip = highbd ? 1 : 0;
b.mPlanes[0].mSkip = 0;
b.mPlanes[1].mData = img->planes[1];
b.mPlanes[1].mStride = img->stride[1];
b.mPlanes[1].mOffset = 0;
b.mPlanes[1].mSkip = highbd ? 1 : 0;
b.mPlanes[1].mSkip = 0;
b.mPlanes[2].mData = img->planes[2];
b.mPlanes[2].mStride = img->stride[2];
b.mPlanes[2].mOffset = 0;
b.mPlanes[2].mSkip = highbd ? 1 : 0;
b.mPlanes[2].mSkip = 0;
if (img->fmt == AOM_IMG_FMT_I420 || img->fmt == AOM_IMG_FMT_I42016) {
b.mPlanes[1].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
@ -253,7 +171,7 @@ RefPtr<MediaDataDecoder::DecodePromise> AOMDecoder::ProcessDecode(
b.mPlanes[2].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
b.mPlanes[2].mWidth = (img->d_w + 1) >> img->x_chroma_shift;
} else if (img->fmt == AOM_IMG_FMT_I444) {
} else if (img->fmt == AOM_IMG_FMT_I444 || img->fmt == AOM_IMG_FMT_I44416) {
b.mPlanes[1].mHeight = img->d_h;
b.mPlanes[1].mWidth = img->d_w;
@ -267,6 +185,27 @@ RefPtr<MediaDataDecoder::DecodePromise> AOMDecoder::ProcessDecode(
__func__);
}
if (img->bit_depth == 10) {
b.mColorDepth = ColorDepth::COLOR_10;
} else if (img->bit_depth == 12) {
b.mColorDepth = ColorDepth::COLOR_12;
}
switch (img->mc) {
case AOM_CICP_MC_BT_601:
b.mYUVColorSpace = YUVColorSpace::BT601;
break;
case AOM_CICP_MC_BT_2020_NCL:
case AOM_CICP_MC_BT_2020_CL:
b.mYUVColorSpace = YUVColorSpace::BT2020;
break;
case AOM_CICP_MC_BT_709:
default:
// Set 709 as default, as it's the most sane default.
b.mYUVColorSpace = YUVColorSpace::BT709;
break;
}
RefPtr<VideoData> v;
v = VideoData::CreateAndCopyData(mInfo, mImageContainer, aSample->mOffset,
aSample->mTime, aSample->mDuration, b,