56 #include "vp9/common/vp9_common.h" 58 #include "./tools_common.h" 59 #include "./video_writer.h" 61 static const char *exec_name;
65 "Usage: %s <width> <height> <infile> <outfile> " 66 "<frame> <limit(optional)>\n",
71 static int compare_img(
const vpx_image_t *
const img1,
73 uint32_t l_w = img1->
d_w;
80 match &= (img1->
fmt == img2->
fmt);
81 match &= (img1->
d_w == img2->
d_w);
82 match &= (img1->
d_h == img2->
d_h);
84 for (i = 0; i < img1->
d_h; ++i)
89 for (i = 0; i < c_h; ++i)
94 for (i = 0; i < c_h; ++i)
102 #define mmin(a, b) ((a) < (b) ? (a) : (b)) 103 static void find_mismatch(
const vpx_image_t *
const img1,
105 int uloc[4],
int vloc[4]) {
106 const uint32_t bsize = 64;
115 yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1;
116 for (i = 0, match = 1; match && i < img1->
d_h; i += bsize) {
117 for (j = 0; match && j < img1->
d_w; j += bsize) {
119 const int si = mmin(i + bsize, img1->
d_h) - i;
120 const int sj = mmin(j + bsize, img1->
d_w) - j;
121 for (k = 0; match && k < si; ++k) {
122 for (l = 0; match && l < sj; ++l) {
141 uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1;
142 for (i = 0, match = 1; match && i < c_h; i += bsizey) {
143 for (j = 0; match && j < c_w; j += bsizex) {
145 const int si = mmin(i + bsizey, c_h - i);
146 const int sj = mmin(j + bsizex, c_w - j);
147 for (k = 0; match && k < si; ++k) {
148 for (l = 0; match && l < sj; ++l) {
166 vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1;
167 for (i = 0, match = 1; match && i < c_h; i += bsizey) {
168 for (j = 0; match && j < c_w; j += bsizex) {
170 const int si = mmin(i + bsizey, c_h - i);
171 const int sj = mmin(j + bsizex, c_w - j);
172 for (k = 0; match && k < si; ++k) {
173 for (l = 0; match && l < sj; ++l) {
194 unsigned int frame_out,
int *mismatch_seen) {
198 if (*mismatch_seen)
return;
203 die_codec(encoder,
"Failed to get encoder reference frame");
204 enc_img = ref_enc.img;
206 die_codec(decoder,
"Failed to get decoder reference frame");
207 dec_img = ref_dec.img;
209 if (!compare_img(&enc_img, &dec_img)) {
210 int y[4], u[4], v[4];
214 find_mismatch(&enc_img, &dec_img, y, u, v);
216 "Encode/decode mismatch on frame %d at" 217 " Y[%d, %d] {%d/%d}," 218 " U[%d, %d] {%d/%d}," 219 " V[%d, %d] {%d/%d}",
220 frame_out, y[0], y[1], y[2], y[3], u[0], u[1], u[2], u[3], v[0], v[1],
229 unsigned int frame_in, VpxVideoWriter *writer,
231 unsigned int *frame_out,
int *mismatch_seen) {
238 if (res !=
VPX_CODEC_OK) die_codec(ecodec,
"Failed to encode frame");
252 if (!vpx_video_writer_write_frame(writer, pkt->
data.
frame.buf,
255 die_codec(ecodec,
"Failed to write compressed frame");
257 printf(keyframe ?
"K" :
".");
264 (
unsigned int)pkt->
data.
frame.sz, NULL, 0))
265 die_codec(dcodec,
"Failed to decode frame.");
271 if (got_data && test_decode) {
272 testing_decode(ecodec, dcodec, *frame_out, mismatch_seen);
278 int main(
int argc,
char **argv) {
283 unsigned int frame_in = 0;
287 VpxVideoWriter *writer = NULL;
288 const VpxInterface *encoder = NULL;
294 unsigned int frame_out = 0;
297 unsigned int update_frame_num = 0;
298 int mismatch_seen = 0;
301 const int bitrate = 500;
303 const char *width_arg = NULL;
304 const char *height_arg = NULL;
305 const char *infile_arg = NULL;
306 const char *outfile_arg = NULL;
307 const char *update_frame_num_arg = NULL;
308 unsigned int limit = 0;
316 if (argc < 6) die(
"Invalid number of arguments");
319 height_arg = argv[2];
320 infile_arg = argv[3];
321 outfile_arg = argv[4];
322 update_frame_num_arg = argv[5];
324 encoder = get_vpx_encoder_by_name(
"vp9");
325 if (!encoder) die(
"Unsupported codec.");
327 update_frame_num = (
unsigned int)strtoul(update_frame_num_arg, NULL, 0);
331 if (update_frame_num <= 1) {
332 die(
"Couldn't parse frame number '%s'\n", update_frame_num_arg);
336 limit = (
unsigned int)strtoul(argv[6], NULL, 0);
337 if (update_frame_num > limit)
338 die(
"Update frame number couldn't larger than limit\n");
341 info.codec_fourcc = encoder->fourcc;
342 info.frame_width = (int)strtol(width_arg, NULL, 0);
343 info.frame_height = (int)strtol(height_arg, NULL, 0);
344 info.time_base.numerator = 1;
345 info.time_base.denominator = fps;
347 if (info.frame_width <= 0 || info.frame_height <= 0 ||
348 (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
349 die(
"Invalid frame size: %dx%d", info.frame_width, info.frame_height);
353 info.frame_height, 1)) {
354 die(
"Failed to allocate image.");
360 if (res) die_codec(&ecodec,
"Failed to get default codec config.");
362 cfg.
g_w = info.frame_width;
363 cfg.
g_h = info.frame_height;
369 writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
370 if (!writer) die(
"Failed to open %s for writing.", outfile_arg);
372 if (!(infile = fopen(infile_arg,
"rb")))
373 die(
"Failed to open %s for reading.", infile_arg);
376 die_codec(&ecodec,
"Failed to initialize encoder");
380 die_codec(&ecodec,
"Failed to set enable auto alt ref");
383 const VpxInterface *decoder = get_vpx_decoder_by_name(
"vp9");
385 die_codec(&dcodec,
"Failed to initialize decoder.");
389 while (vpx_img_read(&raw, infile)) {
390 if (limit && frame_in >= limit)
break;
391 if (update_frame_num > 1 && frame_out + 1 == update_frame_num) {
397 die_codec(&ecodec,
"Failed to set reference frame");
398 printf(
" <SET_REF>");
404 die_codec(&dcodec,
"Failed to set reference frame");
408 encode_frame(&ecodec, &raw, frame_in, writer, test_decode, &dcodec,
409 &frame_out, &mismatch_seen);
411 if (mismatch_seen)
break;
416 while (encode_frame(&ecodec, NULL, frame_in, writer, test_decode, &dcodec,
417 &frame_out, &mismatch_seen)) {
422 printf(
"Processed %d frames.\n", frame_out);
426 printf(
"Encoder/decoder results are matching.\n");
428 printf(
"Encoder/decoder results are NOT matching.\n");
433 die_codec(&dcodec,
"Failed to destroy decoder");
437 die_codec(&ecodec,
"Failed to destroy encoder.");
439 vpx_video_writer_close(writer);
Image Descriptor.
Definition: vpx_image.h:88
Describes the decoder algorithm interface to applications.
Describes the encoder algorithm interface to applications.
const char * vpx_codec_iface_name(vpx_codec_iface_t *iface)
Return the name for a given interface.
struct vpx_rational g_timebase
Stream timebase units.
Definition: vpx_encoder.h:357
int den
Definition: vpx_encoder.h:231
vpx_codec_err_t vpx_codec_encode(vpx_codec_ctx_t *ctx, const vpx_image_t *img, vpx_codec_pts_t pts, unsigned long duration, vpx_enc_frame_flags_t flags, unsigned long deadline)
Encode a frame.
unsigned int g_lag_in_frames
Allow lagged encoding.
Definition: vpx_encoder.h:386
Encoder configuration structure.
Definition: vpx_encoder.h:279
#define VPX_PLANE_Y
Definition: vpx_image.h:112
Encoder output packet.
Definition: vpx_encoder.h:170
#define VPX_PLANE_V
Definition: vpx_image.h:114
unsigned int y_chroma_shift
Definition: vpx_image.h:108
unsigned int x_chroma_shift
Definition: vpx_image.h:107
struct vpx_codec_cx_pkt::@1::@2 frame
vpx_image_t * vpx_img_alloc(vpx_image_t *img, vpx_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align)
Open a descriptor, allocating storage for the underlying image.
Definition: vpx_image.h:55
unsigned int d_w
Definition: vpx_image.h:99
#define vpx_codec_dec_init(ctx, iface, cfg, flags)
Convenience macro for vpx_codec_dec_init_ver()
Definition: vpx_decoder.h:144
vpx_image_t img
Definition: vp8.h:121
unsigned int g_w
Width of the frame.
Definition: vpx_encoder.h:318
vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx, const uint8_t *data, unsigned int data_sz, void *user_priv, long deadline)
Decode data.
unsigned int g_h
Height of the frame.
Definition: vpx_encoder.h:327
int stride[4]
Definition: vpx_image.h:117
enum vpx_codec_cx_pkt_kind kind
Definition: vpx_encoder.h:171
Operation completed without error.
Definition: vpx_codec.h:92
void vpx_img_free(vpx_image_t *img)
Close an image descriptor.
vpx_img_fmt_t fmt
Definition: vpx_image.h:89
unsigned char * planes[4]
Definition: vpx_image.h:116
unsigned int rc_target_bitrate
Target data rate.
Definition: vpx_encoder.h:477
int num
Definition: vpx_encoder.h:230
#define VPX_DL_GOOD_QUALITY
deadline parameter analogous to VPx GOOD QUALITY mode.
Definition: vpx_encoder.h:851
vpx_image_t img
Definition: vp8.h:112
Provides definitions for using VP8 or VP9 encoder algorithm within the vpx Codec Interface.
#define VPX_PLANE_U
Definition: vpx_image.h:113
#define vpx_codec_enc_init(ctx, iface, cfg, flags)
Convenience macro for vpx_codec_enc_init_ver()
Definition: vpx_encoder.h:760
vpx_codec_err_t
Algorithm return codes.
Definition: vpx_codec.h:90
const vpx_codec_cx_pkt_t * vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx, vpx_codec_iter_t *iter)
Encoded data iterator.
union vpx_codec_cx_pkt::@1 data
VP9 specific reference frame data struct.
Definition: vp8.h:119
vpx_codec_err_t vpx_codec_enc_config_default(vpx_codec_iface_t *iface, vpx_codec_enc_cfg_t *cfg, unsigned int reserved)
Get a default configuration.
Codec control function to enable automatic set and use alf frames.
Definition: vp8cx.h:161
reference frame data struct
Definition: vp8.h:110
vpx_ref_frame_type_t frame_type
Definition: vp8.h:111
int idx
Definition: vp8.h:120
#define vpx_codec_control(ctx, id, data)
vpx_codec_control wrapper macro
Definition: vpx_codec.h:404
vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx)
Destroy a codec instance.
unsigned int d_h
Definition: vpx_image.h:100
#define VPX_FRAME_IS_KEY
Definition: vpx_encoder.h:122
const void * vpx_codec_iter_t
Iterator.
Definition: vpx_codec.h:187
Definition: vpx_encoder.h:153
#define VPX_FRAME_IS_FRAGMENT
this is a fragment of the encoded frame
Definition: vpx_encoder.h:129
pass in an external frame into decoder to be used as reference frame
Definition: vp8.h:47
Codec context structure.
Definition: vpx_codec.h:197