summaryrefslogtreecommitdiff
path: root/chromium/third_party/libvpx
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/third_party/libvpx
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/libvpx')
-rw-r--r--chromium/third_party/libvpx/README.chromium6
-rw-r--r--chromium/third_party/libvpx/source/config/vpx_version.h6
-rw-r--r--chromium/third_party/libvpx/source/libvpx/examples/decode_with_drops.c2
-rw-r--r--chromium/third_party/libvpx/source/libvpx/examples/postproc.c4
-rw-r--r--chromium/third_party/libvpx/source/libvpx/examples/set_maps.c2
-rw-r--r--chromium/third_party/libvpx/source/libvpx/examples/simple_decoder.c2
-rw-r--r--chromium/third_party/libvpx/source/libvpx/examples/simple_encoder.c2
-rw-r--r--chromium/third_party/libvpx/source/libvpx/examples/twopass_encoder.c4
-rw-r--r--chromium/third_party/libvpx/source/libvpx/examples/vp8cx_set_ref.c2
-rw-r--r--chromium/third_party/libvpx/source/libvpx/examples/vp9_lossless_encoder.c2
-rw-r--r--chromium/third_party/libvpx/source/libvpx/examples/vp9cx_set_ref.c2
-rw-r--r--chromium/third_party/libvpx/source/libvpx/examples/vpx_temporal_svc_encoder.c2
-rw-r--r--chromium/third_party/libvpx/source/libvpx/tools_common.c7
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp8/common/extend.c53
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c2
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp8/encoder/treewriter.h6
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp8/vp8_cx_iface.c7
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c5
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.h40
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_extend.c32
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.c129
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.h17
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.c10
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.c7
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/simple_encode.cc120
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/simple_encode.h66
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c6
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c9
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vpx/src/vpx_image.c13
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vpx/vpx_image.h1
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vpxenc.c8
-rw-r--r--chromium/third_party/libvpx/source/libvpx/vpxenc.h1
32 files changed, 438 insertions, 137 deletions
diff --git a/chromium/third_party/libvpx/README.chromium b/chromium/third_party/libvpx/README.chromium
index da2a7519f1f..770461309b8 100644
--- a/chromium/third_party/libvpx/README.chromium
+++ b/chromium/third_party/libvpx/README.chromium
@@ -6,9 +6,9 @@ License: BSD
License File: source/libvpx/LICENSE
Security Critical: yes
-Date: Monday June 22 2020
-Branch: m84-4147
-Commit: b30184a6821e1d36db8294574022ff9c207acacc
+Date: Thursday June 18 2020
+Branch: master
+Commit: 769129fb29fc66720be2b01276a472c334757d2d
Description:
Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/chromium/third_party/libvpx/source/config/vpx_version.h b/chromium/third_party/libvpx/source/config/vpx_version.h
index 9bb16668ece..8c003eaf7da 100644
--- a/chromium/third_party/libvpx/source/config/vpx_version.h
+++ b/chromium/third_party/libvpx/source/config/vpx_version.h
@@ -2,8 +2,8 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 8
#define VERSION_PATCH 2
-#define VERSION_EXTRA "175-gb30184a68"
+#define VERSION_EXTRA "202-g769129fb2"
#define VERSION_PACKED \
((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH))
-#define VERSION_STRING_NOSP "v1.8.2-175-gb30184a68"
-#define VERSION_STRING " v1.8.2-175-gb30184a68"
+#define VERSION_STRING_NOSP "v1.8.2-202-g769129fb2"
+#define VERSION_STRING " v1.8.2-202-g769129fb2"
diff --git a/chromium/third_party/libvpx/source/libvpx/examples/decode_with_drops.c b/chromium/third_party/libvpx/source/libvpx/examples/decode_with_drops.c
index e69e2a9f9b3..03c79a45616 100644
--- a/chromium/third_party/libvpx/source/libvpx/examples/decode_with_drops.c
+++ b/chromium/third_party/libvpx/source/libvpx/examples/decode_with_drops.c
@@ -106,7 +106,7 @@ int main(int argc, char **argv) {
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
if (vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
- die_codec(&codec, "Failed to initialize decoder.");
+ die("Failed to initialize decoder.");
while (vpx_video_reader_read_frame(reader)) {
vpx_codec_iter_t iter = NULL;
diff --git a/chromium/third_party/libvpx/source/libvpx/examples/postproc.c b/chromium/third_party/libvpx/source/libvpx/examples/postproc.c
index 15713b946a9..be999b429e7 100644
--- a/chromium/third_party/libvpx/source/libvpx/examples/postproc.c
+++ b/chromium/third_party/libvpx/source/libvpx/examples/postproc.c
@@ -86,9 +86,9 @@ int main(int argc, char **argv) {
res = vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL,
VPX_CODEC_USE_POSTPROC);
if (res == VPX_CODEC_INCAPABLE)
- die_codec(&codec, "Postproc not supported by this decoder.");
+ die("Postproc not supported by this decoder.");
- if (res) die_codec(&codec, "Failed to initialize decoder.");
+ if (res) die("Failed to initialize decoder.");
while (vpx_video_reader_read_frame(reader)) {
vpx_codec_iter_t iter = NULL;
diff --git a/chromium/third_party/libvpx/source/libvpx/examples/set_maps.c b/chromium/third_party/libvpx/source/libvpx/examples/set_maps.c
index c0c7d10e72a..867e473aea4 100644
--- a/chromium/third_party/libvpx/source/libvpx/examples/set_maps.c
+++ b/chromium/third_party/libvpx/source/libvpx/examples/set_maps.c
@@ -209,7 +209,7 @@ int main(int argc, char **argv) {
die("Failed to open %s for reading.", argv[4]);
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
- die_codec(&codec, "Failed to initialize encoder");
+ die("Failed to initialize encoder");
// Encode frames.
while (vpx_img_read(&raw, infile)) {
diff --git a/chromium/third_party/libvpx/source/libvpx/examples/simple_decoder.c b/chromium/third_party/libvpx/source/libvpx/examples/simple_decoder.c
index 2bb1a05245b..d089e826d5b 100644
--- a/chromium/third_party/libvpx/source/libvpx/examples/simple_decoder.c
+++ b/chromium/third_party/libvpx/source/libvpx/examples/simple_decoder.c
@@ -118,7 +118,7 @@ int main(int argc, char **argv) {
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
if (vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
- die_codec(&codec, "Failed to initialize decoder.");
+ die("Failed to initialize decoder.");
while (vpx_video_reader_read_frame(reader)) {
vpx_codec_iter_t iter = NULL;
diff --git a/chromium/third_party/libvpx/source/libvpx/examples/simple_encoder.c b/chromium/third_party/libvpx/source/libvpx/examples/simple_encoder.c
index dde6344f8d6..dffdd6d7da3 100644
--- a/chromium/third_party/libvpx/source/libvpx/examples/simple_encoder.c
+++ b/chromium/third_party/libvpx/source/libvpx/examples/simple_encoder.c
@@ -218,7 +218,7 @@ int main(int argc, char **argv) {
die("Failed to open %s for reading.", infile_arg);
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
- die_codec(&codec, "Failed to initialize encoder");
+ die("Failed to initialize encoder");
// Encode frames.
while (vpx_img_read(&raw, infile)) {
diff --git a/chromium/third_party/libvpx/source/libvpx/examples/twopass_encoder.c b/chromium/third_party/libvpx/source/libvpx/examples/twopass_encoder.c
index 4e63a7a6c97..3d950b2c4b9 100644
--- a/chromium/third_party/libvpx/source/libvpx/examples/twopass_encoder.c
+++ b/chromium/third_party/libvpx/source/libvpx/examples/twopass_encoder.c
@@ -128,7 +128,7 @@ static vpx_fixed_buf_t pass0(vpx_image_t *raw, FILE *infile,
vpx_fixed_buf_t stats = { NULL, 0 };
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
- die_codec(&codec, "Failed to initialize encoder");
+ die("Failed to initialize encoder");
// Calculate frame statistics.
while (vpx_img_read(raw, infile)) {
@@ -164,7 +164,7 @@ static void pass1(vpx_image_t *raw, FILE *infile, const char *outfile_name,
if (!writer) die("Failed to open %s for writing", outfile_name);
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
- die_codec(&codec, "Failed to initialize encoder");
+ die("Failed to initialize encoder");
// Encode frames.
while (vpx_img_read(raw, infile)) {
diff --git a/chromium/third_party/libvpx/source/libvpx/examples/vp8cx_set_ref.c b/chromium/third_party/libvpx/source/libvpx/examples/vp8cx_set_ref.c
index 846477c61ef..ca528f9e90a 100644
--- a/chromium/third_party/libvpx/source/libvpx/examples/vp8cx_set_ref.c
+++ b/chromium/third_party/libvpx/source/libvpx/examples/vp8cx_set_ref.c
@@ -155,7 +155,7 @@ int main(int argc, char **argv) {
die("Failed to open %s for reading.", argv[3]);
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
- die_codec(&codec, "Failed to initialize encoder");
+ die("Failed to initialize encoder");
// Encode frames.
while (vpx_img_read(&raw, infile)) {
diff --git a/chromium/third_party/libvpx/source/libvpx/examples/vp9_lossless_encoder.c b/chromium/third_party/libvpx/source/libvpx/examples/vp9_lossless_encoder.c
index cb5ca6bfe0b..c4eb3a8b171 100644
--- a/chromium/third_party/libvpx/source/libvpx/examples/vp9_lossless_encoder.c
+++ b/chromium/third_party/libvpx/source/libvpx/examples/vp9_lossless_encoder.c
@@ -110,7 +110,7 @@ int main(int argc, char **argv) {
die("Failed to open %s for reading.", argv[3]);
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
- die_codec(&codec, "Failed to initialize encoder");
+ die("Failed to initialize encoder");
if (vpx_codec_control_(&codec, VP9E_SET_LOSSLESS, 1))
die_codec(&codec, "Failed to use lossless mode");
diff --git a/chromium/third_party/libvpx/source/libvpx/examples/vp9cx_set_ref.c b/chromium/third_party/libvpx/source/libvpx/examples/vp9cx_set_ref.c
index 911ad38630c..1a0823153bd 100644
--- a/chromium/third_party/libvpx/source/libvpx/examples/vp9cx_set_ref.c
+++ b/chromium/third_party/libvpx/source/libvpx/examples/vp9cx_set_ref.c
@@ -251,7 +251,7 @@ int main(int argc, char **argv) {
die("Failed to open %s for reading.", infile_arg);
if (vpx_codec_enc_init(&ecodec, encoder->codec_interface(), &cfg, 0))
- die_codec(&ecodec, "Failed to initialize encoder");
+ die("Failed to initialize encoder");
// Disable alt_ref.
if (vpx_codec_control(&ecodec, VP8E_SET_ENABLEAUTOALTREF, 0))
diff --git a/chromium/third_party/libvpx/source/libvpx/examples/vpx_temporal_svc_encoder.c b/chromium/third_party/libvpx/source/libvpx/examples/vpx_temporal_svc_encoder.c
index 925043d1066..872751cefee 100644
--- a/chromium/third_party/libvpx/source/libvpx/examples/vpx_temporal_svc_encoder.c
+++ b/chromium/third_party/libvpx/source/libvpx/examples/vpx_temporal_svc_encoder.c
@@ -815,7 +815,7 @@ int main(int argc, char **argv) {
#else
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
#endif // CONFIG_VP9_HIGHBITDEPTH
- die_codec(&codec, "Failed to initialize encoder");
+ die("Failed to initialize encoder");
if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
diff --git a/chromium/third_party/libvpx/source/libvpx/tools_common.c b/chromium/third_party/libvpx/source/libvpx/tools_common.c
index 59978b7f93a..cbecfbb4193 100644
--- a/chromium/third_party/libvpx/source/libvpx/tools_common.c
+++ b/chromium/third_party/libvpx/source/libvpx/tools_common.c
@@ -91,10 +91,13 @@ int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) {
for (plane = 0; plane < 3; ++plane) {
uint8_t *ptr;
- const int w = vpx_img_plane_width(yuv_frame, plane);
+ int w = vpx_img_plane_width(yuv_frame, plane);
const int h = vpx_img_plane_height(yuv_frame, plane);
int r;
-
+ // Assuming that for nv12 we read all chroma data at one time
+ if (yuv_frame->fmt == VPX_IMG_FMT_NV12 && plane > 1) break;
+ // Fixing NV12 chroma width it is odd
+ if (yuv_frame->fmt == VPX_IMG_FMT_NV12 && plane == 1) w = (w + 1) & ~1;
/* Determine the correct plane based on the image format. The for-loop
* always counts in Y,U,V order, but this may not match the order of
* the data on disk.
diff --git a/chromium/third_party/libvpx/source/libvpx/vp8/common/extend.c b/chromium/third_party/libvpx/source/libvpx/vp8/common/extend.c
index f4dbce2cd53..b52e9fe93c7 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp8/common/extend.c
+++ b/chromium/third_party/libvpx/source/libvpx/vp8/common/extend.c
@@ -11,30 +11,40 @@
#include "extend.h"
#include "vpx_mem/vpx_mem.h"
-static void copy_and_extend_plane(unsigned char *s, /* source */
- int sp, /* source pitch */
- unsigned char *d, /* destination */
- int dp, /* destination pitch */
- int h, /* height */
- int w, /* width */
- int et, /* extend top border */
- int el, /* extend left border */
- int eb, /* extend bottom border */
- int er) { /* extend right border */
- int i;
+static void copy_and_extend_plane(
+ unsigned char *s, /* source */
+ int sp, /* source pitch */
+ unsigned char *d, /* destination */
+ int dp, /* destination pitch */
+ int h, /* height */
+ int w, /* width */
+ int et, /* extend top border */
+ int el, /* extend left border */
+ int eb, /* extend bottom border */
+ int er, /* extend right border */
+ int interleave_step) { /* step between pixels of the current plane */
+ int i, j;
unsigned char *src_ptr1, *src_ptr2;
unsigned char *dest_ptr1, *dest_ptr2;
int linesize;
+ if (interleave_step < 1) interleave_step = 1;
+
/* copy the left and right most columns out */
src_ptr1 = s;
- src_ptr2 = s + w - 1;
+ src_ptr2 = s + (w - 1) * interleave_step;
dest_ptr1 = d - el;
dest_ptr2 = d + w;
for (i = 0; i < h; ++i) {
memset(dest_ptr1, src_ptr1[0], el);
- memcpy(dest_ptr1 + el, src_ptr1, w);
+ if (interleave_step == 1) {
+ memcpy(dest_ptr1 + el, src_ptr1, w);
+ } else {
+ for (j = 0; j < w; j++) {
+ dest_ptr1[el + j] = src_ptr1[interleave_step * j];
+ }
+ }
memset(dest_ptr2, src_ptr2[0], er);
src_ptr1 += sp;
src_ptr2 += sp;
@@ -69,9 +79,12 @@ void vp8_copy_and_extend_frame(YV12_BUFFER_CONFIG *src,
int eb = dst->border + dst->y_height - src->y_height;
int er = dst->border + dst->y_width - src->y_width;
+ // detect nv12 colorspace
+ int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1;
+
copy_and_extend_plane(src->y_buffer, src->y_stride, dst->y_buffer,
dst->y_stride, src->y_height, src->y_width, et, el, eb,
- er);
+ er, 1);
et = dst->border >> 1;
el = dst->border >> 1;
@@ -80,11 +93,11 @@ void vp8_copy_and_extend_frame(YV12_BUFFER_CONFIG *src,
copy_and_extend_plane(src->u_buffer, src->uv_stride, dst->u_buffer,
dst->uv_stride, src->uv_height, src->uv_width, et, el,
- eb, er);
+ eb, er, chroma_step);
copy_and_extend_plane(src->v_buffer, src->uv_stride, dst->v_buffer,
dst->uv_stride, src->uv_height, src->uv_width, et, el,
- eb, er);
+ eb, er, chroma_step);
}
void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src,
@@ -98,6 +111,8 @@ void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src,
int dst_y_offset = srcy * dst->y_stride + srcx;
int src_uv_offset = ((srcy * src->uv_stride) >> 1) + (srcx >> 1);
int dst_uv_offset = ((srcy * dst->uv_stride) >> 1) + (srcx >> 1);
+ // detect nv12 colorspace
+ int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1;
/* If the side is not touching the bounder then don't extend. */
if (srcy) et = 0;
@@ -107,7 +122,7 @@ void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src,
copy_and_extend_plane(src->y_buffer + src_y_offset, src->y_stride,
dst->y_buffer + dst_y_offset, dst->y_stride, srch, srcw,
- et, el, eb, er);
+ et, el, eb, er, 1);
et = (et + 1) >> 1;
el = (el + 1) >> 1;
@@ -118,11 +133,11 @@ void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src,
copy_and_extend_plane(src->u_buffer + src_uv_offset, src->uv_stride,
dst->u_buffer + dst_uv_offset, dst->uv_stride, srch,
- srcw, et, el, eb, er);
+ srcw, et, el, eb, er, chroma_step);
copy_and_extend_plane(src->v_buffer + src_uv_offset, src->uv_stride,
dst->v_buffer + dst_uv_offset, dst->uv_stride, srch,
- srcw, et, el, eb, er);
+ srcw, et, el, eb, er, chroma_step);
}
/* note the extension is only for the last row, for intra prediction purpose */
diff --git a/chromium/third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c b/chromium/third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c
index 3f5b9816d5d..dccc6ebb1ab 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c
+++ b/chromium/third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c
@@ -4533,9 +4533,11 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size,
/* Actual bits spent */
cpi->total_actual_bits += cpi->projected_frame_size;
+#if 0 && CONFIG_INTERNAL_STATS
/* Debug stats */
cpi->total_target_vs_actual +=
(cpi->this_frame_target - cpi->projected_frame_size);
+#endif
cpi->buffer_level = cpi->bits_off_target;
diff --git a/chromium/third_party/libvpx/source/libvpx/vp8/encoder/treewriter.h b/chromium/third_party/libvpx/source/libvpx/vp8/encoder/treewriter.h
index c02683a58b7..4e9ed6af17c 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp8/encoder/treewriter.h
+++ b/chromium/third_party/libvpx/source/libvpx/vp8/encoder/treewriter.h
@@ -14,6 +14,8 @@
/* Trees map alphabets into huffman-like codes suitable for an arithmetic
bit coder. Timothy S Murphy 11 October 2004 */
+#include <stdint.h>
+
#include "./vpx_config.h"
#include "vp8/common/treecoder.h"
@@ -48,7 +50,9 @@ static INLINE unsigned int vp8_cost_branch(const unsigned int ct[2],
vp8_prob p) {
/* Imitate existing calculation */
- return ((ct[0] * vp8_cost_zero(p)) + (ct[1] * vp8_cost_one(p))) >> 8;
+ return (unsigned int)(((((uint64_t)ct[0]) * vp8_cost_zero(p)) +
+ (((uint64_t)ct[1]) * vp8_cost_one(p))) >>
+ 8);
}
/* Small functions to write explicit values and tokens, as well as
diff --git a/chromium/third_party/libvpx/source/libvpx/vp8/vp8_cx_iface.c b/chromium/third_party/libvpx/source/libvpx/vp8/vp8_cx_iface.c
index 8f7617abf9c..1160f51d64a 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp8/vp8_cx_iface.c
+++ b/chromium/third_party/libvpx/source/libvpx/vp8/vp8_cx_iface.c
@@ -264,9 +264,12 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
const vpx_image_t *img) {
switch (img->fmt) {
case VPX_IMG_FMT_YV12:
- case VPX_IMG_FMT_I420: break;
+ case VPX_IMG_FMT_I420:
+ case VPX_IMG_FMT_NV12: break;
default:
- ERROR("Invalid image format. Only YV12 and I420 images are supported");
+ ERROR(
+ "Invalid image format. Only YV12, I420 and NV12 images are "
+ "supported");
}
if ((img->d_w != ctx->cfg.g_w) || (img->d_h != ctx->cfg.g_h))
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c b/chromium/third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c
index bcade52c4e4..7db8ed72d51 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c
@@ -153,6 +153,11 @@ static int vp9_dec_alloc_mi(VP9_COMMON *cm, int mi_size) {
}
static void vp9_dec_free_mi(VP9_COMMON *cm) {
+#if CONFIG_VP9_POSTPROC
+ // MFQE allocates an additional mip and swaps it with cm->mip.
+ vpx_free(cm->postproc_state.prev_mip);
+ cm->postproc_state.prev_mip = NULL;
+#endif
vpx_free(cm->mip);
cm->mip = NULL;
vpx_free(cm->mi_grid_base);
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.h b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.h
index 1a25a496edc..7aa4bf7dcaf 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.h
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.h
@@ -532,24 +532,50 @@ typedef struct MOTION_VECTOR_INFO {
int_mv mv[2];
} MOTION_VECTOR_INFO;
+typedef struct GOP_COMMAND {
+ int use; // use this command to set gop or not. If not, use vp9's decision.
+ int show_frame_count;
+ int use_alt_ref;
+} GOP_COMMAND;
+
+static INLINE void gop_command_on(GOP_COMMAND *gop_command,
+ int show_frame_count, int use_alt_ref) {
+ gop_command->use = 1;
+ gop_command->show_frame_count = show_frame_count;
+ gop_command->use_alt_ref = use_alt_ref;
+}
+
+static INLINE void gop_command_off(GOP_COMMAND *gop_command) {
+ gop_command->use = 0;
+ gop_command->show_frame_count = 0;
+ gop_command->use_alt_ref = 0;
+}
+
+static INLINE int gop_command_coding_frame_count(
+ const GOP_COMMAND *gop_command) {
+ if (gop_command->use == 0) {
+ assert(0);
+ return -1;
+ }
+ return gop_command->show_frame_count + gop_command->use_alt_ref;
+}
+
typedef struct ENCODE_COMMAND {
int use_external_quantize_index;
int external_quantize_index;
- // A list of binary flags set from the external controller.
- // Each binary flag indicates whether the frame is an arf or not.
- const int *external_arf_indexes;
+ GOP_COMMAND gop_command;
} ENCODE_COMMAND;
static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) {
vp9_zero(*encode_command);
encode_command->use_external_quantize_index = 0;
encode_command->external_quantize_index = -1;
- encode_command->external_arf_indexes = NULL;
+ gop_command_off(&encode_command->gop_command);
}
-static INLINE void encode_command_set_external_arf_indexes(
- ENCODE_COMMAND *encode_command, const int *external_arf_indexes) {
- encode_command->external_arf_indexes = external_arf_indexes;
+static INLINE void encode_command_set_gop_command(
+ ENCODE_COMMAND *encode_command, GOP_COMMAND gop_command) {
+ encode_command->gop_command = gop_command;
}
static INLINE void encode_command_set_external_quantize_index(
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_extend.c b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_extend.c
index f8e24610aed..dcb62e8768a 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_extend.c
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_extend.c
@@ -18,18 +18,26 @@
static void copy_and_extend_plane(const uint8_t *src, int src_pitch,
uint8_t *dst, int dst_pitch, int w, int h,
int extend_top, int extend_left,
- int extend_bottom, int extend_right) {
- int i, linesize;
+ int extend_bottom, int extend_right,
+ int interleave_step) {
+ int i, j, linesize;
+ const int step = interleave_step < 1 ? 1 : interleave_step;
// copy the left and right most columns out
const uint8_t *src_ptr1 = src;
- const uint8_t *src_ptr2 = src + w - 1;
+ const uint8_t *src_ptr2 = src + (w - 1) * step;
uint8_t *dst_ptr1 = dst - extend_left;
uint8_t *dst_ptr2 = dst + w;
for (i = 0; i < h; i++) {
memset(dst_ptr1, src_ptr1[0], extend_left);
- memcpy(dst_ptr1 + extend_left, src_ptr1, w);
+ if (step == 1) {
+ memcpy(dst_ptr1 + extend_left, src_ptr1, w);
+ } else {
+ for (j = 0; j < w; j++) {
+ dst_ptr1[extend_left + j] = src_ptr1[step * j];
+ }
+ }
memset(dst_ptr2, src_ptr2[0], extend_right);
src_ptr1 += src_pitch;
src_ptr2 += src_pitch;
@@ -122,6 +130,8 @@ void vp9_copy_and_extend_frame(const YV12_BUFFER_CONFIG *src,
const int el_uv = el_y >> uv_width_subsampling;
const int eb_uv = eb_y >> uv_height_subsampling;
const int er_uv = er_y >> uv_width_subsampling;
+ // detect nv12 colorspace
+ const int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1;
#if CONFIG_VP9_HIGHBITDEPTH
if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
@@ -142,15 +152,15 @@ void vp9_copy_and_extend_frame(const YV12_BUFFER_CONFIG *src,
copy_and_extend_plane(src->y_buffer, src->y_stride, dst->y_buffer,
dst->y_stride, src->y_crop_width, src->y_crop_height,
- et_y, el_y, eb_y, er_y);
+ et_y, el_y, eb_y, er_y, 1);
copy_and_extend_plane(src->u_buffer, src->uv_stride, dst->u_buffer,
dst->uv_stride, src->uv_crop_width, src->uv_crop_height,
- et_uv, el_uv, eb_uv, er_uv);
+ et_uv, el_uv, eb_uv, er_uv, chroma_step);
copy_and_extend_plane(src->v_buffer, src->uv_stride, dst->v_buffer,
dst->uv_stride, src->uv_crop_width, src->uv_crop_height,
- et_uv, el_uv, eb_uv, er_uv);
+ et_uv, el_uv, eb_uv, er_uv, chroma_step);
}
void vp9_copy_and_extend_frame_with_rect(const YV12_BUFFER_CONFIG *src,
@@ -176,16 +186,18 @@ void vp9_copy_and_extend_frame_with_rect(const YV12_BUFFER_CONFIG *src,
const int dst_uv_offset = ((srcy * dst->uv_stride) >> 1) + (srcx >> 1);
const int srch_uv = ROUND_POWER_OF_TWO(srch, 1);
const int srcw_uv = ROUND_POWER_OF_TWO(srcw, 1);
+ // detect nv12 colorspace
+ const int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1;
copy_and_extend_plane(src->y_buffer + src_y_offset, src->y_stride,
dst->y_buffer + dst_y_offset, dst->y_stride, srcw, srch,
- et_y, el_y, eb_y, er_y);
+ et_y, el_y, eb_y, er_y, 1);
copy_and_extend_plane(src->u_buffer + src_uv_offset, src->uv_stride,
dst->u_buffer + dst_uv_offset, dst->uv_stride, srcw_uv,
- srch_uv, et_uv, el_uv, eb_uv, er_uv);
+ srch_uv, et_uv, el_uv, eb_uv, er_uv, chroma_step);
copy_and_extend_plane(src->v_buffer + src_uv_offset, src->uv_stride,
dst->v_buffer + dst_uv_offset, dst->uv_stride, srcw_uv,
- srch_uv, et_uv, el_uv, eb_uv, er_uv);
+ srch_uv, et_uv, el_uv, eb_uv, er_uv, chroma_step);
}
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.c b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.c
index 0bda4b7d66c..45b003e1e80 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.c
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.c
@@ -389,6 +389,29 @@ static int get_search_range(const VP9_COMP *cpi) {
return sr;
}
+// Reduce limits to keep the motion search within MV_MAX of ref_mv. Not doing
+// this can be problematic for big videos (8K) and may cause assert failure
+// (or memory violation) in mv_cost. Limits are only modified if they would
+// be non-empty. Returns 1 if limits are non-empty.
+static int intersect_limits_with_mv_max(MvLimits *mv_limits, const MV *ref_mv) {
+ const int row_min =
+ VPXMAX(mv_limits->row_min, (ref_mv->row + 7 - MV_MAX) >> 3);
+ const int row_max =
+ VPXMIN(mv_limits->row_max, (ref_mv->row - 1 + MV_MAX) >> 3);
+ const int col_min =
+ VPXMAX(mv_limits->col_min, (ref_mv->col + 7 - MV_MAX) >> 3);
+ const int col_max =
+ VPXMIN(mv_limits->col_max, (ref_mv->col - 1 + MV_MAX) >> 3);
+ if (row_min > row_max || col_min > col_max) {
+ return 0;
+ }
+ mv_limits->row_min = row_min;
+ mv_limits->row_max = row_max;
+ mv_limits->col_min = col_min;
+ mv_limits->col_max = col_max;
+ return 1;
+}
+
static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
const MV *ref_mv, MV *best_mv,
int *best_motion_err) {
@@ -403,9 +426,14 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
int step_param = 3;
int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
const int sr = get_search_range(cpi);
+ const MvLimits tmp_mv_limits = x->mv_limits;
step_param += sr;
further_steps -= sr;
+ if (!intersect_limits_with_mv_max(&x->mv_limits, ref_mv)) {
+ return;
+ }
+
// Override the default variance function to use MSE.
v_fn_ptr.vf = get_block_variance_fn(bsize);
#if CONFIG_VP9_HIGHBITDEPTH
@@ -451,6 +479,7 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
}
}
}
+ x->mv_limits = tmp_mv_limits;
}
static BLOCK_SIZE get_bsize(const VP9_COMMON *cm, int mb_row, int mb_col) {
@@ -2479,9 +2508,6 @@ typedef struct RANGE {
* structs.
*/
static int get_gop_coding_frame_num(
-#if CONFIG_RATE_CTRL
- const int *external_arf_indexes,
-#endif
int *use_alt_ref, const FRAME_INFO *frame_info,
const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc,
int gf_start_show_idx, const RANGE *active_gf_interval,
@@ -2497,24 +2523,6 @@ static int get_gop_coding_frame_num(
(frame_info->frame_height + frame_info->frame_width) / 4.0;
double zero_motion_accumulator = 1.0;
int gop_coding_frames;
-#if CONFIG_RATE_CTRL
- (void)mv_ratio_accumulator_thresh;
- (void)active_gf_interval;
- (void)gop_intra_factor;
-
- if (external_arf_indexes != NULL && rc->frames_to_key > 1) {
- // gop_coding_frames = 1 is necessary to filter out the overlay frame,
- // since the arf is in this group of picture and its overlay is in the next.
- gop_coding_frames = 1;
- *use_alt_ref = 1;
- while (gop_coding_frames < rc->frames_to_key) {
- const int frame_index = gf_start_show_idx + gop_coding_frames;
- ++gop_coding_frames;
- if (external_arf_indexes[frame_index] == 1) break;
- }
- return gop_coding_frames;
- }
-#endif // CONFIG_RATE_CTRL
*use_alt_ref = 1;
gop_coding_frames = 0;
@@ -2741,15 +2749,26 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) {
gop_intra_factor = 1.0;
}
- {
- gop_coding_frames = get_gop_coding_frame_num(
#if CONFIG_RATE_CTRL
- cpi->encode_command.external_arf_indexes,
-#endif
- &use_alt_ref, frame_info, first_pass_info, rc, gf_start_show_idx,
- &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames);
- use_alt_ref &= allow_alt_ref;
+ {
+ const GOP_COMMAND *gop_command = &cpi->encode_command.gop_command;
+ assert(allow_alt_ref == 1);
+ if (gop_command->use) {
+ gop_coding_frames = gop_command_coding_frame_count(gop_command);
+ use_alt_ref = gop_command->use_alt_ref;
+ } else {
+ gop_coding_frames = get_gop_coding_frame_num(
+ &use_alt_ref, frame_info, first_pass_info, rc, gf_start_show_idx,
+ &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames);
+ use_alt_ref &= allow_alt_ref;
+ }
}
+#else
+ gop_coding_frames = get_gop_coding_frame_num(
+ &use_alt_ref, frame_info, first_pass_info, rc, gf_start_show_idx,
+ &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames);
+ use_alt_ref &= allow_alt_ref;
+#endif
// Was the group length constrained by the requirement for a new KF?
rc->constrained_gf_group = (gop_coding_frames >= rc->frames_to_key) ? 1 : 0;
@@ -3675,6 +3694,7 @@ void vp9_get_next_group_of_picture(const VP9_COMP *cpi, int *first_is_key_frame,
int *use_alt_ref, int *coding_frame_count,
int *first_show_idx,
int *last_gop_use_alt_ref) {
+ const GOP_COMMAND *gop_command = &cpi->encode_command.gop_command;
// We make a copy of rc here because we want to get information from the
// encoder without changing its state.
// TODO(angiebird): Avoid copying rc here.
@@ -3697,14 +3717,19 @@ void vp9_get_next_group_of_picture(const VP9_COMP *cpi, int *first_is_key_frame,
*first_is_key_frame = 1;
}
- *coding_frame_count = vp9_get_gop_coding_frame_count(
- cpi->encode_command.external_arf_indexes, &cpi->oxcf, &cpi->frame_info,
- &cpi->twopass.first_pass_info, &rc, *first_show_idx, multi_layer_arf,
- allow_alt_ref, *first_is_key_frame, *last_gop_use_alt_ref, use_alt_ref);
+ if (gop_command->use) {
+ *coding_frame_count = gop_command_coding_frame_count(gop_command);
+ *use_alt_ref = gop_command->use_alt_ref;
+ assert(*coding_frame_count < rc.frames_to_key);
+ } else {
+ *coding_frame_count = vp9_get_gop_coding_frame_count(
+ &cpi->oxcf, &cpi->frame_info, &cpi->twopass.first_pass_info, &rc,
+ *first_show_idx, multi_layer_arf, allow_alt_ref, *first_is_key_frame,
+ *last_gop_use_alt_ref, use_alt_ref);
+ }
}
-int vp9_get_gop_coding_frame_count(const int *external_arf_indexes,
- const VP9EncoderConfig *oxcf,
+int vp9_get_gop_coding_frame_count(const VP9EncoderConfig *oxcf,
const FRAME_INFO *frame_info,
const FIRST_PASS_INFO *first_pass_info,
const RATE_CONTROL *rc, int show_idx,
@@ -3727,9 +3752,6 @@ int vp9_get_gop_coding_frame_count(const int *external_arf_indexes,
}
frame_count = get_gop_coding_frame_num(
-#if CONFIG_RATE_CTRL
- external_arf_indexes,
-#endif
use_alt_ref, frame_info, first_pass_info, rc, show_idx,
&active_gf_interval, gop_intra_factor, oxcf->lag_in_frames);
*use_alt_ref &= allow_alt_ref;
@@ -3738,8 +3760,7 @@ int vp9_get_gop_coding_frame_count(const int *external_arf_indexes,
// Under CONFIG_RATE_CTRL, once the first_pass_info is ready, the number of
// coding frames (including show frame and alt ref) can be determined.
-int vp9_get_coding_frame_num(const int *external_arf_indexes,
- const VP9EncoderConfig *oxcf,
+int vp9_get_coding_frame_num(const VP9EncoderConfig *oxcf,
const FRAME_INFO *frame_info,
const FIRST_PASS_INFO *first_pass_info,
int multi_layer_arf, int allow_alt_ref) {
@@ -3750,7 +3771,6 @@ int vp9_get_coding_frame_num(const int *external_arf_indexes,
int show_idx = 0;
int last_gop_use_alt_ref = 0;
vp9_rc_init(oxcf, 1, &rc);
- rc.static_scene_max_gf_interval = 250;
while (show_idx < first_pass_info->num_frames) {
int use_alt_ref;
@@ -3763,9 +3783,8 @@ int vp9_get_coding_frame_num(const int *external_arf_indexes,
}
gop_coding_frame_count = vp9_get_gop_coding_frame_count(
- external_arf_indexes, oxcf, frame_info, first_pass_info, &rc, show_idx,
- multi_layer_arf, allow_alt_ref, first_is_key_frame,
- last_gop_use_alt_ref, &use_alt_ref);
+ oxcf, frame_info, first_pass_info, &rc, show_idx, multi_layer_arf,
+ allow_alt_ref, first_is_key_frame, last_gop_use_alt_ref, &use_alt_ref);
rc.source_alt_ref_active = use_alt_ref;
last_gop_use_alt_ref = use_alt_ref;
@@ -3777,6 +3796,30 @@ int vp9_get_coding_frame_num(const int *external_arf_indexes,
}
return coding_frame_num;
}
+
+void vp9_get_key_frame_map(const VP9EncoderConfig *oxcf,
+ const FRAME_INFO *frame_info,
+ const FIRST_PASS_INFO *first_pass_info,
+ int *key_frame_map) {
+ int show_idx = 0;
+ RATE_CONTROL rc;
+ vp9_rc_init(oxcf, 1, &rc);
+
+ // key_frame_map points to an int array with size equal to
+ // first_pass_info->num_frames, which is also the number of show frames in the
+ // video.
+ memset(key_frame_map, 0,
+ sizeof(*key_frame_map) * first_pass_info->num_frames);
+ while (show_idx < first_pass_info->num_frames) {
+ int key_frame_group_size;
+ key_frame_map[show_idx] = 1;
+ key_frame_group_size = vp9_get_frames_to_next_key(
+ oxcf, frame_info, first_pass_info, show_idx, rc.min_gf_interval);
+ assert(key_frame_group_size > 0);
+ show_idx += key_frame_group_size;
+ }
+ assert(show_idx == first_pass_info->num_frames);
+}
#endif // CONFIG_RATE_CTRL
FIRSTPASS_STATS vp9_get_frame_stats(const TWO_PASS *twopass) {
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.h b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.h
index dcaf2eec676..b1047eab226 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.h
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.h
@@ -264,7 +264,6 @@ void vp9_get_next_group_of_picture(const struct VP9_COMP *cpi,
/*!\brief Call this function before coding a new group of pictures to get
* information about it.
- * \param[in] external_arf_indexes External arf indexs passed in
* \param[in] oxcf Encoder config
* \param[in] frame_info Frame info
* \param[in] first_pass_info First pass stats
@@ -279,8 +278,7 @@ void vp9_get_next_group_of_picture(const struct VP9_COMP *cpi,
*
* \return Returns coding frame count
*/
-int vp9_get_gop_coding_frame_count(const int *external_arf_indexes,
- const struct VP9EncoderConfig *oxcf,
+int vp9_get_gop_coding_frame_count(const struct VP9EncoderConfig *oxcf,
const FRAME_INFO *frame_info,
const FIRST_PASS_INFO *first_pass_info,
const RATE_CONTROL *rc, int show_idx,
@@ -288,11 +286,20 @@ int vp9_get_gop_coding_frame_count(const int *external_arf_indexes,
int first_is_key_frame,
int last_gop_use_alt_ref, int *use_alt_ref);
-int vp9_get_coding_frame_num(const int *external_arf_indexes,
- const struct VP9EncoderConfig *oxcf,
+int vp9_get_coding_frame_num(const struct VP9EncoderConfig *oxcf,
const FRAME_INFO *frame_info,
const FIRST_PASS_INFO *first_pass_info,
int multi_layer_arf, int allow_alt_ref);
+
+/*!\brief Compute a key frame binary map indicates whether key frames appear
+ * in the corresponding positions. The passed in key_frame_map must point to an
+ * integer array with length equal to first_pass_info->num_frames, which is the
+ * number of show frames in the video.
+ */
+void vp9_get_key_frame_map(const struct VP9EncoderConfig *oxcf,
+ const FRAME_INFO *frame_info,
+ const FIRST_PASS_INFO *first_pass_info,
+ int *key_frame_map);
#endif // CONFIG_RATE_CTRL
FIRSTPASS_STATS vp9_get_frame_stats(const TWO_PASS *twopass);
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.c b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.c
index 9debc01efd2..34dd618acf6 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.c
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.c
@@ -431,6 +431,11 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) {
rc->max_gf_interval = vp9_rc_get_default_max_gf_interval(
oxcf->init_framerate, rc->min_gf_interval);
rc->baseline_gf_interval = (rc->min_gf_interval + rc->max_gf_interval) / 2;
+ if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) {
+ rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL;
+ } else {
+ rc->static_scene_max_gf_interval = MAX_STATIC_GF_GROUP_LENGTH;
+ }
rc->force_max_q = 0;
rc->last_post_encode_dropped_scene_change = 0;
@@ -2371,7 +2376,8 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) {
if (cm->show_frame) update_buffer_level_svc_preencode(cpi);
if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC && svc->single_layer_svc == 1 &&
- svc->spatial_layer_id == svc->first_spatial_layer_to_encode) {
+ svc->spatial_layer_id == svc->first_spatial_layer_to_encode &&
+ svc->temporal_layer_id == 0) {
LAYER_CONTEXT *lc = NULL;
cpi->resize_pending = vp9_resize_one_pass_cbr(cpi);
if (cpi->resize_pending) {
@@ -2987,7 +2993,7 @@ void vp9_scene_detection_onepass(VP9_COMP *cpi) {
int scene_cut_force_key_frame = 0;
int num_zero_temp_sad = 0;
uint64_t avg_sad_current = 0;
- uint32_t min_thresh = 10000;
+ uint32_t min_thresh = 20000; // ~5 * 64 * 64
float thresh = 8.0f;
uint32_t thresh_key = 140000;
if (cpi->oxcf.speed <= 5) thresh_key = 240000;
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.c b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.c
index cd77c08a808..27dc8ec50ff 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.c
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.c
@@ -864,8 +864,9 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
}
}
- // Reset the drop flags for all spatial layers, on the base layer.
- if (svc->spatial_layer_id == 0) {
+ // Reset the drop flags for all spatial layers, on the
+ // first_spatial_layer_to_encode.
+ if (svc->spatial_layer_id == svc->first_spatial_layer_to_encode) {
vp9_zero(svc->drop_spatial_layer);
// TODO(jianj/marpan): Investigate why setting svc->lst/gld/alt_fb_idx
// causes an issue with frame dropping and temporal layers, when the frame
@@ -1259,7 +1260,7 @@ static void vp9_svc_update_ref_frame_bypass_mode(VP9_COMP *const cpi) {
BufferPool *const pool = cm->buffer_pool;
int i;
for (i = 0; i < REF_FRAMES; i++) {
- if (cm->frame_type == KEY_FRAME ||
+ if ((cm->frame_type == KEY_FRAME && !svc->simulcast_mode) ||
svc->update_buffer_slot[svc->spatial_layer_id] & (1 << i)) {
ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[i], cm->new_fb_idx);
svc->fb_idx_spatial_layer_id[i] = svc->spatial_layer_id;
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/simple_encode.cc b/chromium/third_party/libvpx/source/libvpx/vp9/simple_encode.cc
index c417a25890f..7bce91f7f0e 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/simple_encode.cc
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/simple_encode.cc
@@ -612,6 +612,9 @@ static void SetGroupOfPicture(int first_is_key_frame, int use_alt_ref,
group_of_picture->show_frame_count = coding_frame_count - use_alt_ref;
group_of_picture->start_show_index = first_show_idx;
group_of_picture->start_coding_index = start_coding_index;
+ group_of_picture->first_is_key_frame = first_is_key_frame;
+ group_of_picture->use_alt_ref = use_alt_ref;
+ group_of_picture->last_gop_use_alt_ref = last_gop_use_alt_ref;
// We need to make a copy of start reference frame info because we
// use it to simulate the ref frame update.
@@ -776,6 +779,9 @@ void SimpleEncode::ComputeFirstPassStats() {
free_encoder(cpi);
rewind(in_file_);
vpx_img_free(&img);
+
+ // Generate key_frame_map based on impl_ptr_->first_pass_stats.
+ key_frame_map_ = ComputeKeyFrameMap();
}
std::vector<std::vector<double>> SimpleEncode::ObserveFirstPassStats() {
@@ -800,9 +806,39 @@ std::vector<std::vector<double>> SimpleEncode::ObserveFirstPassStats() {
return output_stats;
}
-void SimpleEncode::SetExternalGroupOfPicture(
- std::vector<int> external_arf_indexes) {
- external_arf_indexes_ = external_arf_indexes;
+void SimpleEncode::SetExternalGroupOfPicturesMap(int *gop_map,
+ int gop_map_size) {
+ for (int i = 0; i < gop_map_size; ++i) {
+ gop_map_.push_back(gop_map[i]);
+ }
+ // The following will check and modify gop_map_ to make sure the
+ // gop_map_ satisfies the constraints.
+ // 1) Each key frame position should be at the start of a gop.
+ // 2) The last gop should not use an alt ref.
+ assert(gop_map_.size() == key_frame_map_.size());
+ int last_gop_start = 0;
+ for (int i = 0; static_cast<size_t>(i) < gop_map_.size(); ++i) {
+ if (key_frame_map_[i] == 1 && gop_map_[i] == 0) {
+ fprintf(stderr, "Add an extra gop start at show_idx %d\n", i);
+ // Insert a gop start at key frame location.
+ gop_map_[i] |= kGopMapFlagStart;
+ gop_map_[i] |= kGopMapFlagUseAltRef;
+ }
+ if (gop_map_[i] & kGopMapFlagStart) {
+ last_gop_start = i;
+ }
+ }
+ if (gop_map_[last_gop_start] & kGopMapFlagUseAltRef) {
+ fprintf(stderr,
+ "Last group of pictures starting at show_idx %d shouldn't use alt "
+ "ref\n",
+ last_gop_start);
+ gop_map_[last_gop_start] &= ~kGopMapFlagUseAltRef;
+ }
+}
+
+std::vector<int> SimpleEncode::ObserveExternalGroupOfPicturesMap() {
+ return gop_map_;
}
template <typename T>
@@ -813,6 +849,32 @@ T *GetVectorData(const std::vector<T> &v) {
return const_cast<T *>(v.data());
}
+static GOP_COMMAND GetGopCommand(const std::vector<int> &gop_map,
+ int start_show_index) {
+ GOP_COMMAND gop_command;
+ if (gop_map.size() > 0) {
+ assert(static_cast<size_t>(start_show_index) < gop_map.size());
+ assert((gop_map[start_show_index] & kGopMapFlagStart) != 0);
+ int end_show_index = start_show_index + 1;
+ // gop_map[end_show_index] & kGopMapFlagStart == 0 means this is
+ // the start of a gop.
+ while (static_cast<size_t>(end_show_index) < gop_map.size() &&
+ (gop_map[end_show_index] & kGopMapFlagStart) == 0) {
+ ++end_show_index;
+ }
+ const int show_frame_count = end_show_index - start_show_index;
+ int use_alt_ref = (gop_map[start_show_index] & kGopMapFlagUseAltRef) != 0;
+ if (static_cast<size_t>(end_show_index) == gop_map.size()) {
+ // This is the last gop group, there must be no altref.
+ use_alt_ref = 0;
+ }
+ gop_command_on(&gop_command, show_frame_count, use_alt_ref);
+ } else {
+ gop_command_off(&gop_command);
+ }
+ return gop_command;
+}
+
void SimpleEncode::StartEncode() {
assert(impl_ptr_->first_pass_stats.size() > 0);
vpx_rational_t frame_rate =
@@ -834,11 +896,10 @@ void SimpleEncode::StartEncode() {
frame_coding_index_ = 0;
show_frame_count_ = 0;
- encode_command_set_external_arf_indexes(&impl_ptr_->cpi->encode_command,
- GetVectorData(external_arf_indexes_));
-
UpdateKeyFrameGroup(show_frame_count_);
+ const GOP_COMMAND gop_command = GetGopCommand(gop_map_, show_frame_count_);
+ encode_command_set_gop_command(&impl_ptr_->cpi->encode_command, gop_command);
UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_,
&group_of_picture_);
rewind(in_file_);
@@ -914,6 +975,9 @@ void SimpleEncode::PostUpdateState(
IncreaseGroupOfPictureIndex(&group_of_picture_);
if (IsGroupOfPictureFinished(group_of_picture_)) {
+ const GOP_COMMAND gop_command = GetGopCommand(gop_map_, show_frame_count_);
+ encode_command_set_gop_command(&impl_ptr_->cpi->encode_command,
+ gop_command);
// This function needs to be called after ref_frame_info_ is updated
// properly in PostUpdateRefFrameInfo() and UpdateKeyFrameGroup().
UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_,
@@ -1002,8 +1066,24 @@ void SimpleEncode::EncodeFrameWithQuantizeIndex(
encode_command_reset_external_quantize_index(&impl_ptr_->cpi->encode_command);
}
+static int GetCodingFrameNumFromGopMap(const std::vector<int> &gop_map) {
+ int start_show_index = 0;
+ int coding_frame_count = 0;
+ while (static_cast<size_t>(start_show_index) < gop_map.size()) {
+ const GOP_COMMAND gop_command = GetGopCommand(gop_map, start_show_index);
+ start_show_index += gop_command.show_frame_count;
+ coding_frame_count += gop_command_coding_frame_count(&gop_command);
+ }
+ assert(start_show_index == gop_map.size());
+ return coding_frame_count;
+}
+
int SimpleEncode::GetCodingFrameNum() const {
- assert(impl_ptr_->first_pass_stats.size() - 1 > 0);
+ assert(impl_ptr_->first_pass_stats.size() > 0);
+ if (gop_map_.size() > 0) {
+ return GetCodingFrameNumFromGopMap(gop_map_);
+ }
+
// These are the default settings for now.
const int multi_layer_arf = 0;
const int allow_alt_ref = 1;
@@ -1017,11 +1097,33 @@ int SimpleEncode::GetCodingFrameNum() const {
fps_init_first_pass_info(&first_pass_info,
GetVectorData(impl_ptr_->first_pass_stats),
num_frames_);
- return vp9_get_coding_frame_num(external_arf_indexes_.data(), &oxcf,
- &frame_info, &first_pass_info,
+ return vp9_get_coding_frame_num(&oxcf, &frame_info, &first_pass_info,
multi_layer_arf, allow_alt_ref);
}
+std::vector<int> SimpleEncode::ComputeKeyFrameMap() const {
+ // The last entry of first_pass_stats is the overall stats.
+ assert(impl_ptr_->first_pass_stats.size() == num_frames_ + 1);
+ vpx_rational_t frame_rate =
+ make_vpx_rational(frame_rate_num_, frame_rate_den_);
+ const VP9EncoderConfig oxcf =
+ vp9_get_encoder_config(frame_width_, frame_height_, frame_rate,
+ target_bitrate_, VPX_RC_LAST_PASS);
+ FRAME_INFO frame_info = vp9_get_frame_info(&oxcf);
+ FIRST_PASS_INFO first_pass_info;
+ fps_init_first_pass_info(&first_pass_info,
+ GetVectorData(impl_ptr_->first_pass_stats),
+ num_frames_);
+ std::vector<int> key_frame_map(num_frames_, 0);
+ vp9_get_key_frame_map(&oxcf, &frame_info, &first_pass_info,
+ GetVectorData(key_frame_map));
+ return key_frame_map;
+}
+
+std::vector<int> SimpleEncode::ObserveKeyFrameMap() const {
+ return key_frame_map_;
+}
+
uint64_t SimpleEncode::GetFramePixelCount() const {
assert(frame_width_ % 2 == 0);
assert(frame_height_ % 2 == 0);
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/simple_encode.h b/chromium/third_party/libvpx/source/libvpx/vp9/simple_encode.h
index 4221a70150c..b2173207016 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/simple_encode.h
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/simple_encode.h
@@ -39,6 +39,14 @@ enum RefFrameType {
kRefFrameTypeNone = -1,
};
+enum GopMapFlag {
+ kGopMapFlagStart =
+ 1 << 0, // Indicate this location is the start of a group of pictures.
+ kGopMapFlagUseAltRef =
+ 1 << 1, // Indicate this group of pictures will use an alt ref. Only set
+ // this flag when kGopMapFlagStart is set.
+};
+
// The frame is split to 4x4 blocks.
// This structure contains the information of each 4x4 block.
struct PartitionInfo {
@@ -255,6 +263,7 @@ struct GroupOfPicture {
// triggered when the coded frame is the last one in the previous group of
// pictures.
std::vector<EncodeFrameInfo> encode_frame_list;
+
// Indicates the index of the next coding frame in encode_frame_list.
// In other words, EncodeFrameInfo of the next coding frame can be
// obtained with encode_frame_list[next_encode_frame_index].
@@ -263,13 +272,25 @@ struct GroupOfPicture {
// will be increased after each EncodeFrame()/EncodeFrameWithQuantizeIndex()
// call.
int next_encode_frame_index;
+
// Number of show frames in this group of pictures.
int show_frame_count;
+
// The show index/timestamp of the earliest show frame in the group of
// pictures.
int start_show_index;
- // The coding index of the first coding frame in the group of picture.
+
+ // The coding index of the first coding frame in the group of pictures.
int start_coding_index;
+
+ // Indicates whether this group of pictures starts with a key frame.
+ int first_is_key_frame;
+
+ // Indicates whether this group of pictures uses an alt ref.
+ int use_alt_ref;
+
+ // Indicates whether previous group of pictures used an alt ref.
+ int last_gop_use_alt_ref;
};
class SimpleEncode {
@@ -283,8 +304,9 @@ class SimpleEncode {
SimpleEncode(SimpleEncode &) = delete;
SimpleEncode &operator=(const SimpleEncode &) = delete;
- // Makes encoder compute the first pass stats and store it internally for
- // future encode.
+ // Makes encoder compute the first pass stats and store it at
+ // impl_ptr_->first_pass_stats. key_frame_map_ is also computed based on the
+ // first pass stats.
void ComputeFirstPassStats();
// Outputs the first pass stats represented by a 2-D vector.
@@ -293,13 +315,32 @@ class SimpleEncode {
// values. For details, please check FIRSTPASS_STATS in vp9_firstpass.h
std::vector<std::vector<double>> ObserveFirstPassStats();
- // Sets arf indexes for the video from external input.
- // The arf index determines whether a frame is arf or not.
- // Therefore it also determines the group of picture size.
- // If set, VP9 will use the external arf index to make decision.
+ // Ouputs a copy of key_frame_map_, a binary vector with size equal to the
+ // number of show frames in the video. For each entry in the vector, 1
+ // indicates the position is a key frame and 0 indicates it's not a key frame.
+ // This function should be called after ComputeFirstPassStats()
+ std::vector<int> ObserveKeyFrameMap() const;
+
+ // Sets group of pictures map for coding the entire video.
+ // Each entry in the gop_map corresponds to a show frame in the video.
+ // Therefore, the size of gop_map should equal to the number of show frames in
+ // the entire video.
+ // If a given entry's kGopMapFlagStart is set, it means this is the start of a
+ // gop. Once kGopMapFlagStart is set, one can set kGopMapFlagUseAltRef to
+ // indicate whether this gop use altref.
+ // If a given entry is zero, it means it's in the middle of a gop.
// This function should be called only once after ComputeFirstPassStats(),
// before StartEncode().
- void SetExternalGroupOfPicture(std::vector<int> external_arf_indexes);
+ // This API will check and modify the gop_map to satisfy the following
+ // constraints.
+ // 1) Each key frame position should be at the start of a gop.
+ // 2) The last gop should not use an alt ref.
+ void SetExternalGroupOfPicturesMap(int *gop_map, int gop_map_size);
+
+ // Observe the group of pictures map set through
+ // SetExternalGroupOfPicturesMap(). This function should be called after
+ // SetExternalGroupOfPicturesMap().
+ std::vector<int> ObserveExternalGroupOfPicturesMap();
// Initializes the encoder for actual encoding.
// This function should be called after ComputeFirstPassStats().
@@ -341,6 +382,12 @@ class SimpleEncode {
uint64_t GetFramePixelCount() const;
private:
+ // Compute the key frame locations of the video based on first pass stats.
+ // The results are returned as a binary vector with 1s indicating keyframes
+ // and 0s indicating non keyframes.
+ // It has to be called after impl_ptr_->first_pass_stats is computed.
+ std::vector<int> ComputeKeyFrameMap() const;
+
// Updates key_frame_group_size_, reset key_frame_group_index_ and init
// ref_frame_info_.
void UpdateKeyFrameGroup(int key_frame_show_index);
@@ -363,7 +410,8 @@ class SimpleEncode {
std::FILE *out_file_;
std::unique_ptr<EncodeImpl> impl_ptr_;
- std::vector<int> external_arf_indexes_;
+ std::vector<int> key_frame_map_;
+ std::vector<int> gop_map_;
GroupOfPicture group_of_picture_;
// The key frame group size includes one key frame plus the number of
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c b/chromium/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c
index bd6b07a299d..15aa7e60f79 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c
@@ -355,13 +355,14 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
switch (img->fmt) {
case VPX_IMG_FMT_YV12:
case VPX_IMG_FMT_I420:
- case VPX_IMG_FMT_I42016: break;
+ case VPX_IMG_FMT_I42016:
+ case VPX_IMG_FMT_NV12: break;
case VPX_IMG_FMT_I422:
case VPX_IMG_FMT_I444:
case VPX_IMG_FMT_I440:
if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) {
ERROR(
- "Invalid image format. I422, I444, I440 images are "
+ "Invalid image format. I422, I444, I440, NV12 images are "
"not supported in profile.");
}
break;
@@ -391,6 +392,7 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
static int get_image_bps(const vpx_image_t *img) {
switch (img->fmt) {
case VPX_IMG_FMT_YV12:
+ case VPX_IMG_FMT_NV12:
case VPX_IMG_FMT_I420: return 12;
case VPX_IMG_FMT_I422: return 16;
case VPX_IMG_FMT_I444: return 24;
diff --git a/chromium/third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c b/chromium/third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c
index 74d08a5873a..8d031694d8d 100644
--- a/chromium/third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c
+++ b/chromium/third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c
@@ -88,8 +88,9 @@ vpx_codec_err_t image2yuvconfig(const vpx_image_t *img,
yv12->y_width = img->d_w;
yv12->y_height = img->d_h;
- yv12->uv_width =
- img->x_chroma_shift == 1 ? (1 + yv12->y_width) / 2 : yv12->y_width;
+ yv12->uv_width = img->x_chroma_shift == 1 || img->fmt == VPX_IMG_FMT_NV12
+ ? (1 + yv12->y_width) / 2
+ : yv12->y_width;
yv12->uv_height =
img->y_chroma_shift == 1 ? (1 + yv12->y_height) / 2 : yv12->y_height;
yv12->uv_crop_width = yv12->uv_width;
@@ -127,5 +128,9 @@ vpx_codec_err_t image2yuvconfig(const vpx_image_t *img,
#endif // CONFIG_VP9_HIGHBITDEPTH
yv12->subsampling_x = img->x_chroma_shift;
yv12->subsampling_y = img->y_chroma_shift;
+ // When reading the data, UV are in one plane for NV12 format, thus
+ // x_chroma_shift is 0. After converting, UV are in separate planes, and
+ // subsampling_x should be set to 1.
+ if (img->fmt == VPX_IMG_FMT_NV12) yv12->subsampling_x = 1;
return VPX_CODEC_OK;
}
diff --git a/chromium/third_party/libvpx/source/libvpx/vpx/src/vpx_image.c b/chromium/third_party/libvpx/source/libvpx/vpx/src/vpx_image.c
index a7c6ec0ceab..ff496b5d34f 100644
--- a/chromium/third_party/libvpx/source/libvpx/vpx/src/vpx_image.c
+++ b/chromium/third_party/libvpx/source/libvpx/vpx/src/vpx_image.c
@@ -39,7 +39,8 @@ static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt,
/* Get sample size for this format */
switch (fmt) {
case VPX_IMG_FMT_I420:
- case VPX_IMG_FMT_YV12: bps = 12; break;
+ case VPX_IMG_FMT_YV12:
+ case VPX_IMG_FMT_NV12: bps = 12; break;
case VPX_IMG_FMT_I422:
case VPX_IMG_FMT_I440: bps = 16; break;
case VPX_IMG_FMT_I444: bps = 24; break;
@@ -51,6 +52,8 @@ static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt,
}
/* Get chroma shift values for this format */
+ // For VPX_IMG_FMT_NV12, xcs needs to be 0 such that UV data is all read at
+ // one time.
switch (fmt) {
case VPX_IMG_FMT_I420:
case VPX_IMG_FMT_YV12:
@@ -62,6 +65,7 @@ static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt,
switch (fmt) {
case VPX_IMG_FMT_I420:
+ case VPX_IMG_FMT_NV12:
case VPX_IMG_FMT_I440:
case VPX_IMG_FMT_YV12:
case VPX_IMG_FMT_I42016:
@@ -173,7 +177,12 @@ int vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y,
data + x * bytes_per_sample + y * img->stride[VPX_PLANE_Y];
data += img->h * img->stride[VPX_PLANE_Y];
- if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) {
+ if (img->fmt == VPX_IMG_FMT_NV12) {
+ img->planes[VPX_PLANE_U] =
+ data + (x >> img->x_chroma_shift) +
+ (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
+ img->planes[VPX_PLANE_V] = img->planes[VPX_PLANE_U] + 1;
+ } else if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) {
img->planes[VPX_PLANE_U] =
data + (x >> img->x_chroma_shift) * bytes_per_sample +
(y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
diff --git a/chromium/third_party/libvpx/source/libvpx/vpx/vpx_image.h b/chromium/third_party/libvpx/source/libvpx/vpx/vpx_image.h
index 98be5966a24..bc23be50c58 100644
--- a/chromium/third_party/libvpx/source/libvpx/vpx/vpx_image.h
+++ b/chromium/third_party/libvpx/source/libvpx/vpx/vpx_image.h
@@ -43,6 +43,7 @@ typedef enum vpx_img_fmt {
VPX_IMG_FMT_I422 = VPX_IMG_FMT_PLANAR | 5,
VPX_IMG_FMT_I444 = VPX_IMG_FMT_PLANAR | 6,
VPX_IMG_FMT_I440 = VPX_IMG_FMT_PLANAR | 7,
+ VPX_IMG_FMT_NV12 = VPX_IMG_FMT_PLANAR | 9,
VPX_IMG_FMT_I42016 = VPX_IMG_FMT_I420 | VPX_IMG_FMT_HIGHBITDEPTH,
VPX_IMG_FMT_I42216 = VPX_IMG_FMT_I422 | VPX_IMG_FMT_HIGHBITDEPTH,
VPX_IMG_FMT_I44416 = VPX_IMG_FMT_I444 | VPX_IMG_FMT_HIGHBITDEPTH,
diff --git a/chromium/third_party/libvpx/source/libvpx/vpxenc.c b/chromium/third_party/libvpx/source/libvpx/vpxenc.c
index 50c36bedd54..64288e83d28 100644
--- a/chromium/third_party/libvpx/source/libvpx/vpxenc.c
+++ b/chromium/third_party/libvpx/source/libvpx/vpxenc.c
@@ -95,6 +95,8 @@ static const arg_def_t debugmode =
ARG_DEF("D", "debug", 0, "Debug mode (makes output deterministic)");
static const arg_def_t outputfile =
ARG_DEF("o", "output", 1, "Output filename");
+static const arg_def_t use_nv12 =
+ ARG_DEF(NULL, "nv12", 0, "Input file is NV12 ");
static const arg_def_t use_yv12 =
ARG_DEF(NULL, "yv12", 0, "Input file is YV12 ");
static const arg_def_t use_i420 =
@@ -220,7 +222,8 @@ static const arg_def_t error_resilient =
static const arg_def_t lag_in_frames =
ARG_DEF(NULL, "lag-in-frames", 1, "Max number of frames to lag");
-static const arg_def_t *global_args[] = { &use_yv12,
+static const arg_def_t *global_args[] = { &use_nv12,
+ &use_yv12,
&use_i420,
&use_i422,
&use_i444,
@@ -696,6 +699,8 @@ static void parse_global_config(struct VpxEncoderConfig *global, char **argv) {
global->deadline = VPX_DL_REALTIME;
else if (arg_match(&arg, &use_yv12, argi))
global->color_type = YV12;
+ else if (arg_match(&arg, &use_nv12, argi))
+ global->color_type = NV12;
else if (arg_match(&arg, &use_i420, argi))
global->color_type = I420;
else if (arg_match(&arg, &use_i422, argi))
@@ -1642,6 +1647,7 @@ int main(int argc, const char **argv_) {
case I444: input.fmt = VPX_IMG_FMT_I444; break;
case I440: input.fmt = VPX_IMG_FMT_I440; break;
case YV12: input.fmt = VPX_IMG_FMT_YV12; break;
+ case NV12: input.fmt = VPX_IMG_FMT_NV12; break;
}
{
diff --git a/chromium/third_party/libvpx/source/libvpx/vpxenc.h b/chromium/third_party/libvpx/source/libvpx/vpxenc.h
index b780aedca69..be54840f7dd 100644
--- a/chromium/third_party/libvpx/source/libvpx/vpxenc.h
+++ b/chromium/third_party/libvpx/source/libvpx/vpxenc.h
@@ -28,6 +28,7 @@ typedef enum {
I444, // 4:4:4 8+ bit-depth
I440, // 4:4:0 8+ bit-depth
YV12, // 4:2:0 with uv flipped, only 8-bit depth
+ NV12, // 4:2:0 with uv interleaved
} ColorInputType;
struct VpxInterface;