1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
|
/*
* Copyright (c) 2019 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VPX_VP9_SIMPLE_ENCODE_H_
#define VPX_VP9_SIMPLE_ENCODE_H_
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <memory>
#include <vector>
namespace vp9 {
enum StatusCode {
StatusOk = 0,
StatusError,
};
// TODO(angiebird): Add description for each frame type.
enum FrameType {
kFrameTypeKey = 0,
kFrameTypeInter = 1,
kFrameTypeAltRef = 2,
kFrameTypeOverlay = 3,
kFrameTypeGolden = 4,
};
// TODO(angiebird): Add description for each reference frame type.
// This enum numbers have to be contiguous and start from zero except
// kNoneRefFrame.
enum RefFrameType {
kRefFrameTypeLast = 0,
kRefFrameTypePast = 1,
kRefFrameTypeFuture = 2,
kRefFrameTypeMax = 3,
kRefFrameTypeNone = -1,
};
enum VP9_LEVEL {
LEVEL_UNKNOWN = 0,
LEVEL_AUTO = 1,
LEVEL_1 = 10,
LEVEL_1_1 = 11,
LEVEL_2 = 20,
LEVEL_2_1 = 21,
LEVEL_3 = 30,
LEVEL_3_1 = 31,
LEVEL_4 = 40,
LEVEL_4_1 = 41,
LEVEL_5 = 50,
LEVEL_5_1 = 51,
LEVEL_5_2 = 52,
LEVEL_6 = 60,
LEVEL_6_1 = 61,
LEVEL_6_2 = 62,
LEVEL_MAX = 255
};
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 {
int row; // row pixel offset of current 4x4 block
int column; // column pixel offset of current 4x4 block
int row_start; // row pixel offset of the start of the prediction block
int column_start; // column pixel offset of the start of the prediction block
int width; // prediction block width
int height; // prediction block height
};
constexpr int kMotionVectorSubPixelPrecision = 8;
constexpr int kMotionVectorFullPixelPrecision = 1;
// In the first pass. The frame is split to 16x16 blocks.
// This structure contains the information of each 16x16 block.
// In the second pass. The frame is split to 4x4 blocks.
// This structure contains the information of each 4x4 block.
struct MotionVectorInfo {
// Number of valid motion vectors, always 0 if this block is in the key frame.
// For inter frames, it could be 1 or 2.
int mv_count;
// The reference frame for motion vectors. If the second motion vector does
// not exist (mv_count = 1), the reference frame is kNoneRefFrame.
// Otherwise, the reference frame is either kRefFrameTypeLast, or
// kRefFrameTypePast, or kRefFrameTypeFuture.
RefFrameType ref_frame[2];
// The row offset of motion vectors in the unit of pixel.
// If the second motion vector does not exist, the value is 0.
double mv_row[2];
// The column offset of motion vectors in the unit of pixel.
// If the second motion vector does not exist, the value is 0.
double mv_column[2];
};
// Accumulated tpl stats of all blocks in one frame.
// For each frame, the tpl stats are computed per 32x32 block.
struct TplStatsInfo {
// Intra complexity: the sum of absolute transform difference (SATD) of
// intra predicted residuals.
int64_t intra_cost;
// Inter complexity: the SATD of inter predicted residuals.
int64_t inter_cost;
// Motion compensated information flow. It measures how much information
// is propagated from the current frame to other frames.
int64_t mc_flow;
// Motion compensated dependency cost. It equals to its own intra_cost
// plus the mc_flow.
int64_t mc_dep_cost;
// Motion compensated reference cost.
int64_t mc_ref_cost;
};
struct RefFrameInfo {
int coding_indexes[kRefFrameTypeMax];
// Indicate whether the reference frames are available or not.
// When the reference frame type is not valid, it means either the to-be-coded
// frame is a key frame or the reference frame already appears in other
// reference frame type. vp9 always keeps three types of reference frame
// available. However, the duplicated reference frames will not be
// chosen by the encoder. The priorities of choosing reference frames are
// kRefFrameTypeLast > kRefFrameTypePast > kRefFrameTypeFuture.
// For example, if kRefFrameTypeLast and kRefFrameTypePast both point to the
// same frame, kRefFrameTypePast will be set to invalid.
// 1: the ref frame type is available 0: the ref frame type is not available
int valid_list[kRefFrameTypeMax];
};
bool operator==(const RefFrameInfo &a, const RefFrameInfo &b);
struct EncodeFrameInfo {
int show_idx;
// Each show or no show frame is assigned with a coding index based on its
// coding order (starting from zero) in the coding process of the entire
// video. The coding index for each frame is unique.
int coding_index;
RefFrameInfo ref_frame_info;
FrameType frame_type;
};
// This structure is a copy of vp9 |nmv_component_counts|.
struct NewMotionvectorComponentCounts {
std::vector<unsigned int> sign;
std::vector<unsigned int> classes;
std::vector<unsigned int> class0;
std::vector<std::vector<unsigned int>> bits;
std::vector<std::vector<unsigned int>> class0_fp;
std::vector<unsigned int> fp;
std::vector<unsigned int> class0_hp;
std::vector<unsigned int> hp;
};
// This structure is a copy of vp9 |nmv_context_counts|.
struct NewMotionVectorContextCounts {
std::vector<unsigned int> joints;
std::vector<NewMotionvectorComponentCounts> comps;
};
using UintArray2D = std::vector<std::vector<unsigned int>>;
using UintArray3D = std::vector<std::vector<std::vector<unsigned int>>>;
using UintArray5D = std::vector<
std::vector<std::vector<std::vector<std::vector<unsigned int>>>>>;
using UintArray6D = std::vector<std::vector<
std::vector<std::vector<std::vector<std::vector<unsigned int>>>>>>;
// This structure is a copy of vp9 |tx_counts|.
struct TransformSizeCounts {
// Transform size found in blocks of partition size 32x32.
// First dimension: transform size contexts (2).
// Second dimension: transform size type (3: 32x32, 16x16, 8x8)
UintArray2D p32x32;
// Transform size found in blocks of partition size 16x16.
// First dimension: transform size contexts (2).
// Second dimension: transform size type (2: 16x16, 8x8)
UintArray2D p16x16;
// Transform size found in blocks of partition size 8x8.
// First dimension: transform size contexts (2).
// Second dimension: transform size type (1: 8x8)
UintArray2D p8x8;
// Overall transform size count.
std::vector<unsigned int> tx_totals;
};
// This structure is a copy of vp9 |FRAME_COUNTS|.
struct FrameCounts {
// Intra prediction mode for luma plane. First dimension: block size (4).
// Second dimension: intra prediction mode (10).
UintArray2D y_mode;
// Intra prediction mode for chroma plane. First and second dimension:
// intra prediction mode (10).
UintArray2D uv_mode;
// Partition type. First dimension: partition contexts (16).
// Second dimension: partition type (4).
UintArray2D partition;
// Transform coefficient.
UintArray6D coef;
// End of block (the position of the last non-zero transform coefficient)
UintArray5D eob_branch;
// Interpolation filter type. First dimension: switchable filter contexts (4).
// Second dimension: filter types (3).
UintArray2D switchable_interp;
// Inter prediction mode (the motion vector type).
// First dimension: inter mode contexts (7).
// Second dimension: mode type (4).
UintArray2D inter_mode;
// Block is intra or inter predicted. First dimension: contexts (4).
// Second dimension: type (0 for intra, 1 for inter).
UintArray2D intra_inter;
// Block is compound predicted (predicted from average of two blocks).
// First dimension: contexts (5).
// Second dimension: type (0 for single, 1 for compound prediction).
UintArray2D comp_inter;
// Type of the reference frame. Only one reference frame.
// First dimension: context (5). Second dimension: context (2).
// Third dimension: count (2).
UintArray3D single_ref;
// Type of the two reference frames.
// First dimension: context (5). Second dimension: count (2).
UintArray2D comp_ref;
// Block skips transform and quantization, uses prediction as reconstruction.
// First dimension: contexts (3). Second dimension: type (0 not skip, 1 skip).
UintArray2D skip;
// Transform size.
TransformSizeCounts tx;
// New motion vector.
NewMotionVectorContextCounts mv;
};
struct ImageBuffer {
// The image data is stored in raster order,
// i.e. image[plane][r][c] =
// plane_buffer[plane][r * plane_width[plane] + plane_height[plane]].
std::unique_ptr<unsigned char[]> plane_buffer[3];
int plane_width[3];
int plane_height[3];
};
void output_image_buffer(const ImageBuffer &image_buffer, std::FILE *out_file);
struct EncodeFrameResult {
int show_idx;
FrameType frame_type;
int coding_idx;
RefFrameInfo ref_frame_info;
size_t coding_data_bit_size;
size_t coding_data_byte_size;
// The EncodeFrame will allocate a buffer, write the coding data into the
// buffer and give the ownership of the buffer to coding_data.
std::unique_ptr<unsigned char[]> coding_data;
size_t max_coding_data_byte_size;
double psnr;
uint64_t sse;
int quantize_index;
FrameCounts frame_counts;
int num_rows_4x4; // number of row units, in size of 4.
int num_cols_4x4; // number of column units, in size of 4.
// A vector of the partition information of the frame.
// The number of elements is |num_rows_4x4| * |num_cols_4x4|.
// The frame is divided 4x4 blocks of |num_rows_4x4| rows and
// |num_cols_4x4| columns.
// Each 4x4 block contains the current pixel position (|row|, |column|),
// the start pixel position of the partition (|row_start|, |column_start|),
// and the |width|, |height| of the partition.
// The current pixel position can be the same as the start pixel position
// if the 4x4 block is the top-left block in the partition. Otherwise, they
// are different.
// Within the same partition, all 4x4 blocks have the same |row_start|,
// |column_start|, |width| and |height|.
// For example, if the frame is partitioned to a 32x32 block,
// starting at (0, 0). Then, there're 64 4x4 blocks within this partition.
// They all have the same |row_start|, |column_start|, |width|, |height|,
// which can be used to figure out the start of the current partition and
// the start of the next partition block.
// Horizontal next: |column_start| + |width|,
// Vertical next: |row_start| + |height|.
std::vector<PartitionInfo> partition_info;
// A vector of the motion vector information of the frame.
// The number of elements is |num_rows_4x4| * |num_cols_4x4|.
// The frame is divided into 4x4 blocks of |num_rows_4x4| rows and
// |num_cols_4x4| columns.
// Each 4x4 block contains 0 motion vector if this is an intra predicted
// frame (for example, the key frame). If the frame is inter predicted,
// each 4x4 block contains either 1 or 2 motion vectors.
// Similar to partition info, all 4x4 blocks inside the same partition block
// share the same motion vector information.
std::vector<MotionVectorInfo> motion_vector_info;
// A vector of the tpl stats information.
// The tpl stats measure the complexity of a frame, as well as the
// information propagated along the motion trajectory between frames, in
// the reference frame structure.
// The tpl stats could be used as a more accurate spatial and temporal
// complexity measure in addition to the first pass stats.
// The vector contains tpl stats for all show frames in a GOP.
// The tpl stats stored in the vector is according to the encoding order.
// For example, suppose there are N show frames for the current GOP.
// Then tpl_stats_info[0] stores the information of the first frame to be
// encoded for this GOP, i.e., the AltRef frame.
std::vector<TplStatsInfo> tpl_stats_info;
ImageBuffer coded_frame;
// recode_count, q_index_history and rate_history are only available when
// EncodeFrameWithTargetFrameBits() is used.
int recode_count;
std::vector<int> q_index_history;
std::vector<int> rate_history;
};
struct GroupOfPicture {
// This list will be updated internally in StartEncode() and
// EncodeFrame()/EncodeFrameWithQuantizeIndex().
// In EncodeFrame()/EncodeFrameWithQuantizeIndex(), the update will only be
// 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].
// Internally, next_encode_frame_index will be set to zero after the last
// frame of the group of pictures is coded. Otherwise, next_encode_frame_index
// 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 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 {
public:
// When outfile_path is set, the encoder will output the bitstream in ivf
// format.
SimpleEncode(int frame_width, int frame_height, int frame_rate_num,
int frame_rate_den, int target_bitrate, int num_frames,
int target_level, const char *infile_path,
const char *outfile_path = nullptr);
~SimpleEncode();
SimpleEncode(SimpleEncode &) = delete;
SimpleEncode &operator=(const SimpleEncode &) = delete;
// Adjusts the encoder's coding speed.
// If this function is not called, the encoder will use default encode_speed
// 0. Call this function before ComputeFirstPassStats() if needed.
// The encode_speed is equivalent to --cpu-used of the vpxenc command.
// The encode_speed's range should be [0, 9].
// Setting the encode_speed to a higher level will yield faster coding
// at the cost of lower compression efficiency.
void SetEncodeSpeed(int encode_speed);
// Set encoder config
// The following configs in VP9EncoderConfig are allowed to change in this
// function. See https://ffmpeg.org/ffmpeg-codecs.html#libvpx for each
// config's meaning.
// Configs in VP9EncoderConfig: Equivalent configs in ffmpeg:
// 1 key_freq -g
// 2 two_pass_vbrmin_section -minrate * 100LL / bit_rate
// 3 two_pass_vbrmax_section -maxrate * 100LL / bit_rate
// 4 under_shoot_pct -undershoot-pct
// 5 over_shoot_pct -overshoot-pct
// 6 max_threads -threads
// 7 frame_parallel_decoding_mode -frame-parallel
// 8 tile_column -tile-columns
// 9 arnr_max_frames -arnr-maxframes
// 10 arnr_strength -arnr-strength
// 11 lag_in_frames -rc_lookahead
// 12 encode_breakout -static-thresh
// 13 enable_tpl_model -enable-tpl
// 14 enable_auto_arf -auto-alt-ref
// 15 rc_mode
// Possible Settings:
// 0 - Variable Bit Rate (VPX_VBR) -b:v <bit_rate>
// 1 - Constant Bit Rate (VPX_CBR) -b:v <bit_rate> -minrate <bit_rate>
// -maxrate <bit_rate>
// two_pass_vbrmin_section == 100 i.e. bit_rate == minrate == maxrate
// two_pass_vbrmax_section == 100
// 2 - Constrained Quality (VPX_CQ) -crf <cq_level> -b:v bit_rate
// 3 - Constant Quality (VPX_Q) -crf <cq_level> -b:v 0
// See https://trac.ffmpeg.org/wiki/Encode/VP9 for more details.
// 16 cq_level see rc_mode for details.
StatusCode SetEncodeConfig(const char *name, const char *value);
// A debug function that dumps configs from VP9EncoderConfig
// pass = 1: first pass, pass = 2: second pass
// fp: file pointer for dumping config
StatusCode DumpEncodeConfigs(int pass, FILE *fp);
// 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.
// One can use the frame index at first dimension to retrieve the stats for
// each video frame. The stats of each video frame is a vector of 25 double
// values. For details, please check FIRSTPASS_STATS in vp9_firstpass.h
std::vector<std::vector<double>> ObserveFirstPassStats();
// Outputs the first pass motion vectors represented by a 2-D vector.
// One can use the frame index at first dimension to retrieve the mvs for
// each video frame. The frame is divided into 16x16 blocks. The number of
// elements is round_up(|num_rows_4x4| / 4) * round_up(|num_cols_4x4| / 4).
std::vector<std::vector<MotionVectorInfo>> ObserveFirstPassMotionVectors();
// 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().
// 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().
void StartEncode();
// Frees the encoder.
// This function should be called after StartEncode() or EncodeFrame().
void EndEncode();
// The key frame group size includes one key frame plus the number of
// following inter frames. Note that the key frame group size only counts the
// show frames. The number of no show frames like alternate refereces are not
// counted.
int GetKeyFrameGroupSize() const;
// Provides the group of pictures that the next coding frame is in.
// Only call this function between StartEncode() and EndEncode()
GroupOfPicture ObserveGroupOfPicture() const;
// Gets encode_frame_info for the next coding frame.
// Only call this function between StartEncode() and EndEncode()
EncodeFrameInfo GetNextEncodeFrameInfo() const;
// Encodes a frame
// This function should be called after StartEncode() and before EndEncode().
void EncodeFrame(EncodeFrameResult *encode_frame_result);
// Encodes a frame with a specific quantize index.
// This function should be called after StartEncode() and before EndEncode().
void EncodeFrameWithQuantizeIndex(EncodeFrameResult *encode_frame_result,
int quantize_index);
// Encode a frame with target frame bits usage.
// The encoder will find a quantize index to make the actual frame bits usage
// match the target. EncodeFrameWithTargetFrameBits() will recode the frame
// up to 7 times to find a q_index to make the actual_frame_bits satisfy the
// following inequality. |actual_frame_bits - target_frame_bits| * 100 /
// target_frame_bits
// <= percent_diff.
void EncodeFrameWithTargetFrameBits(EncodeFrameResult *encode_frame_result,
int target_frame_bits,
double percent_diff);
// Gets the number of coding frames for the video. The coding frames include
// show frame and no show frame.
// This function should be called after ComputeFirstPassStats().
int GetCodingFrameNum() const;
// Gets the total number of pixels of YUV planes per frame.
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);
// Update key_frame_group_index_.
void PostUpdateKeyFrameGroupIndex(FrameType frame_type);
void PostUpdateState(const EncodeFrameResult &encode_frame_result);
class EncodeImpl;
int frame_width_; // frame width in pixels.
int frame_height_; // frame height in pixels.
int frame_rate_num_;
int frame_rate_den_;
int target_bitrate_;
int num_frames_;
int encode_speed_;
int target_level_;
std::FILE *in_file_;
std::FILE *out_file_;
std::unique_ptr<EncodeImpl> impl_ptr_;
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
// following inter frames. Note that the key frame group size only counts the
// show frames. The number of no show frames like alternate references are not
// counted.
int key_frame_group_size_;
// The index for the to-be-coded show frame in the key frame group.
int key_frame_group_index_;
// Each show or no show frame is assigned with a coding index based on its
// coding order (starting from zero) in the coding process of the entire
// video. The coding index of the to-be-coded frame.
int frame_coding_index_;
// Number of show frames we have coded so far.
int show_frame_count_;
// TODO(angiebird): Do we need to reset ref_frames_info_ when the next key
// frame appears?
// Reference frames info of the to-be-coded frame.
RefFrameInfo ref_frame_info_;
// A 2-D vector of motion vector information of the frame collected
// from the first pass. The first dimension is the frame index.
// Each frame is divided into 16x16 blocks. The number of elements is
// round_up(|num_rows_4x4| / 4) * round_up(|num_cols_4x4| / 4).
// Each 16x16 block contains 0 motion vector if this is an intra predicted
// frame (for example, the key frame). If the frame is inter predicted,
// each 16x16 block contains either 1 or 2 motion vectors.
// The first motion vector is always from the LAST_FRAME.
// The second motion vector is always from the GOLDEN_FRAME.
std::vector<std::vector<MotionVectorInfo>> fp_motion_vector_info_;
};
} // namespace vp9
#endif // VPX_VP9_SIMPLE_ENCODE_H_
|