зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
1da8a6804f
Коммит
09b5578692
|
@ -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.
|
// UniquePtr dtor wrapper for aom_image_t.
|
||||||
struct AomImageFree {
|
struct AomImageFree {
|
||||||
void operator()(aom_image_t* img) { aom_img_free(img); }
|
void operator()(aom_image_t* img) { aom_img_free(img); }
|
||||||
|
@ -189,40 +141,6 @@ RefPtr<MediaDataDecoder::DecodePromise> AOMDecoder::ProcessDecode(
|
||||||
DecodedData results;
|
DecodedData results;
|
||||||
|
|
||||||
while ((img = aom_codec_get_frame(&mCodec, &iter))) {
|
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(
|
NS_ASSERTION(
|
||||||
img->fmt == AOM_IMG_FMT_I420 || img->fmt == AOM_IMG_FMT_I42016 ||
|
img->fmt == AOM_IMG_FMT_I420 || img->fmt == AOM_IMG_FMT_I42016 ||
|
||||||
img->fmt == AOM_IMG_FMT_I444 || img->fmt == AOM_IMG_FMT_I44416,
|
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].mHeight = img->d_h;
|
||||||
b.mPlanes[0].mWidth = img->d_w;
|
b.mPlanes[0].mWidth = img->d_w;
|
||||||
b.mPlanes[0].mOffset = 0;
|
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].mData = img->planes[1];
|
||||||
b.mPlanes[1].mStride = img->stride[1];
|
b.mPlanes[1].mStride = img->stride[1];
|
||||||
b.mPlanes[1].mOffset = 0;
|
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].mData = img->planes[2];
|
||||||
b.mPlanes[2].mStride = img->stride[2];
|
b.mPlanes[2].mStride = img->stride[2];
|
||||||
b.mPlanes[2].mOffset = 0;
|
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) {
|
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;
|
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].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
|
||||||
b.mPlanes[2].mWidth = (img->d_w + 1) >> img->x_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].mHeight = img->d_h;
|
||||||
b.mPlanes[1].mWidth = img->d_w;
|
b.mPlanes[1].mWidth = img->d_w;
|
||||||
|
|
||||||
|
@ -267,6 +185,27 @@ RefPtr<MediaDataDecoder::DecodePromise> AOMDecoder::ProcessDecode(
|
||||||
__func__);
|
__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;
|
RefPtr<VideoData> v;
|
||||||
v = VideoData::CreateAndCopyData(mInfo, mImageContainer, aSample->mOffset,
|
v = VideoData::CreateAndCopyData(mInfo, mImageContainer, aSample->mOffset,
|
||||||
aSample->mTime, aSample->mDuration, b,
|
aSample->mTime, aSample->mDuration, b,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче