blob: 72281cdeaf9060b63d67b92bcc2eca045b82dffc [file] [log] [blame]
/*
* 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 FrameType {
kKeyFrame = 0,
kInterFrame,
kAlternateReference,
};
struct EncodeFrameInfo {
int show_idx;
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;
};
// This structure is a copy of vp9 |tx_counts|.
struct TransformSizeCounts {
std::vector<std::vector<unsigned int>> p32x32;
std::vector<std::vector<unsigned int>> p16x16;
std::vector<std::vector<unsigned int>> p8x8;
std::vector<unsigned int> tx_totals;
};
// This structure is a copy of vp9 |FRAME_COUNTS|.
struct FrameCounts {
std::vector<std::vector<unsigned int>> y_mode;
std::vector<std::vector<unsigned int>> uv_mode;
std::vector<std::vector<unsigned int>> partition;
std::vector<std::vector<
std::vector<std::vector<std::vector<std::vector<unsigned int>>>>>>
coef;
std::vector<std::vector<std::vector<std::vector<std::vector<unsigned int>>>>>
eob_branch;
std::vector<std::vector<unsigned int>> switchable_interp;
std::vector<std::vector<unsigned int>> inter_mode;
std::vector<std::vector<unsigned int>> intra_inter;
std::vector<std::vector<unsigned int>> comp_inter;
std::vector<std::vector<std::vector<unsigned int>>> single_ref;
std::vector<std::vector<unsigned int>> comp_ref;
std::vector<std::vector<unsigned int>> skip;
TransformSizeCounts tx;
NewMotionVectorContextCounts mv;
};
struct EncodeFrameResult {
int show_idx;
FrameType frame_type;
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;
double psnr;
uint64_t sse;
int quantize_index;
FrameCounts frame_counts;
};
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;
};
class SimpleEncode {
public:
SimpleEncode(int frame_width, int frame_height, int frame_rate_num,
int frame_rate_den, int target_bitrate, int num_frames,
const char *infile_path);
~SimpleEncode();
SimpleEncode(SimpleEncode &) = delete;
SimpleEncode &operator=(const SimpleEncode &) = delete;
// Makes encoder compute the first pass stats and store it internally for
// future encode.
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();
// 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();
// Given a key_frame_index, computes this key frame group's size.
// 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(int key_frame_index) 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);
// 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:
class EncodeImpl;
int frame_width_;
int frame_height_;
int frame_rate_num_;
int frame_rate_den_;
int target_bitrate_;
int num_frames_;
std::FILE *file_;
std::unique_ptr<EncodeImpl> impl_ptr_;
GroupOfPicture group_of_picture_;
};
} // namespace vp9
#endif // VPX_VP9_SIMPLE_ENCODE_H_