23 #include "./vpx_config.h"
33 #include <sys/types.h>
39 #include "vpx_ports/vpx_timer.h"
40 #define VPX_CODEC_DISABLE_COMPAT 1
43 #include "vpx_ports/mem_ops.h"
44 #include "./tools_common.h"
45 #define interface (vpx_codec_vp8_cx())
46 #define fourcc 0x30385056
62 #define NUM_ENCODERS 3
65 #define MAX_NUM_TEMPORAL_LAYERS 3
68 #include "third_party/libyuv/include/libyuv/basic_types.h"
69 #include "third_party/libyuv/include/libyuv/scale.h"
70 #include "third_party/libyuv/include/libyuv/cpu_id.h"
75 size_t nbytes, to_read;
78 to_read = img->
w*img->
h*3/2;
79 nbytes = fread(img->
planes[0], 1, to_read, f);
80 if(nbytes != to_read) {
83 printf(
"Warning: Read partial frame. Check your width & height!\n");
88 static int read_frame_by_row(FILE *f,
vpx_image_t *img) {
89 size_t nbytes, to_read;
93 for (plane = 0; plane < 3; plane++)
96 int w = (plane ? (1 + img->
d_w) / 2 : img->
d_w);
97 int h = (plane ? (1 + img->
d_h) / 2 : img->
d_h);
116 for (r = 0; r < h; r++)
120 nbytes = fread(ptr, 1, to_read, f);
121 if(nbytes != to_read) {
124 printf(
"Warning: Read partial frame. Check your width & height!\n");
128 ptr += img->
stride[plane];
137 static void write_ivf_file_header(FILE *outfile,
148 mem_put_le16(header+4, 0);
149 mem_put_le16(header+6, 32);
150 mem_put_le32(header+8, fourcc);
151 mem_put_le16(header+12, cfg->
g_w);
152 mem_put_le16(header+14, cfg->
g_h);
155 mem_put_le32(header+24, frame_cnt);
156 mem_put_le32(header+28, 0);
158 (void) fwrite(header, 1, 32, outfile);
161 static void write_ivf_frame_header(FILE *outfile,
171 mem_put_le32(header, pkt->
data.
frame.sz);
172 mem_put_le32(header+4, pts&0xFFFFFFFF);
173 mem_put_le32(header+8, pts >> 32);
175 (void) fwrite(header, 1, 12, outfile);
183 static void set_temporal_layer_pattern(
int num_temporal_layers,
188 assert(num_temporal_layers <= MAX_NUM_TEMPORAL_LAYERS);
189 switch (num_temporal_layers)
242 layer_flags[4] = layer_flags[2];
245 layer_flags[5] = layer_flags[3];
248 layer_flags[6] = layer_flags[4];
251 layer_flags[7] = layer_flags[5];
305 layer_flags[5] = layer_flags[3];
312 layer_flags[7] = layer_flags[3];
319 static int periodicity_to_num_layers[MAX_NUM_TEMPORAL_LAYERS] = {1, 8, 8};
321 int main(
int argc,
char **argv)
323 FILE *infile, *outfile[NUM_ENCODERS];
324 FILE *downsampled_input[NUM_ENCODERS - 1];
343 int flag_periodicity;
352 int key_frame_insert = 0;
353 uint64_t psnr_sse_total[NUM_ENCODERS] = {0};
354 uint64_t psnr_samples_total[NUM_ENCODERS] = {0};
355 double psnr_totals[NUM_ENCODERS][4] = {{0,0}};
356 int psnr_count[NUM_ENCODERS] = {0};
359 struct timeval tv1, tv2, difftv;
365 unsigned int target_bitrate[NUM_ENCODERS]={1000, 500, 100};
378 unsigned int num_temporal_layers[NUM_ENCODERS] = {3, 3, 3};
380 if(argc!= (7 + 3 * NUM_ENCODERS))
381 die(
"Usage: %s <width> <height> <frame_rate> <infile> <outfile(s)> "
382 "<rate_encoder(s)> <temporal_layer(s)> <key_frame_insert> <output psnr?> \n",
387 width = strtol(argv[1], NULL, 0);
388 height = strtol(argv[2], NULL, 0);
389 framerate = strtol(argv[3], NULL, 0);
391 if(width < 16 || width%2 || height <16 || height%2)
392 die(
"Invalid resolution: %ldx%ld", width, height);
395 if(!(infile = fopen(argv[4],
"rb")))
396 die(
"Failed to open %s for reading", argv[4]);
399 for (i=0; i< NUM_ENCODERS; i++)
401 if(!target_bitrate[i])
407 if(!(outfile[i] = fopen(argv[i+5],
"wb")))
408 die(
"Failed to open %s for writing", argv[i+4]);
412 for (i=0; i< NUM_ENCODERS; i++)
414 target_bitrate[i] = strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
418 for (i=0; i< NUM_ENCODERS; i++)
420 num_temporal_layers[i] = strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
421 if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
422 die(
"Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
423 num_temporal_layers);
427 for (i=0; i< NUM_ENCODERS - 1; i++)
430 if (sprintf(filename,
"ds%d.yuv",NUM_ENCODERS - i) < 0)
434 downsampled_input[i] = fopen(filename,
"wb");
437 key_frame_insert = strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0);
439 show_psnr = strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
443 for (i=0; i< NUM_ENCODERS; i++)
484 for (i=1; i< NUM_ENCODERS; i++)
495 unsigned int iw = cfg[i-1].
g_w*dsf[i-1].
den + dsf[i-1].
num - 1;
496 unsigned int ih = cfg[i-1].
g_h*dsf[i-1].
den + dsf[i-1].
num - 1;
497 cfg[i].
g_w = iw/dsf[i-1].
num;
498 cfg[i].
g_h = ih/dsf[i-1].
num;
503 if((cfg[i].g_w)%2)cfg[i].
g_w++;
504 if((cfg[i].g_h)%2)cfg[i].
g_h++;
515 for (i=0; i< NUM_ENCODERS; i++)
517 die(
"Failed to allocate image", cfg[i].g_w, cfg[i].g_h);
519 if (raw[0].stride[VPX_PLANE_Y] == raw[0].d_w)
520 read_frame_p = read_frame;
522 read_frame_p = read_frame_by_row;
524 for (i=0; i< NUM_ENCODERS; i++)
526 write_ivf_file_header(outfile[i], &cfg[i], 0);
529 for ( i=0; i<NUM_ENCODERS; i++)
531 set_temporal_layer_pattern(num_temporal_layers[i],
533 cfg[i].rc_target_bitrate,
539 (show_psnr ? VPX_CODEC_USE_PSNR : 0), &dsf[0]))
540 die_codec(&codec[0],
"Failed to initialize encoder");
544 for ( i=0; i<NUM_ENCODERS; i++)
548 if (i == NUM_ENCODERS - 1) speed = -4;
550 die_codec(&codec[i],
"Failed to set cpu_used");
554 for ( i=0; i<NUM_ENCODERS; i++)
557 die_codec(&codec[i],
"Failed to set static threshold");
563 die_codec(&codec[0],
"Failed to set noise_sensitivity");
564 for ( i=1; i< NUM_ENCODERS; i++)
567 die_codec(&codec[i],
"Failed to set noise_sensitivity");
571 for ( i=0; i<NUM_ENCODERS; i++)
574 die_codec(&codec[i],
"Failed to set static threshold");
578 for ( i=0; i<NUM_ENCODERS; i++)
580 unsigned int max_intra_size_pct =
581 (int)(((
double)cfg[0].rc_buf_optimal_sz * 0.5) * framerate / 10);
584 die_codec(&codec[i],
"Failed to set static threshold");
591 while(frame_avail || got_data)
597 frame_avail = read_frame_p(infile, &raw[0]);
601 for ( i=1; i<NUM_ENCODERS; i++)
605 I420Scale(raw[i-1].planes[VPX_PLANE_Y], raw[i-1].stride[VPX_PLANE_Y],
606 raw[i-1].planes[VPX_PLANE_U], raw[i-1].stride[VPX_PLANE_U],
607 raw[i-1].planes[
VPX_PLANE_V], raw[i-1].stride[VPX_PLANE_V],
608 raw[i-1].d_w, raw[i-1].d_h,
609 raw[i].planes[VPX_PLANE_Y], raw[i].stride[VPX_PLANE_Y],
610 raw[i].planes[VPX_PLANE_U], raw[i].stride[VPX_PLANE_U],
611 raw[i].planes[VPX_PLANE_V], raw[i].stride[VPX_PLANE_V],
612 raw[i].d_w, raw[i].d_h, 1);
614 length_frame = cfg[i].
g_w * cfg[i].
g_h *3/2;
615 if (fwrite(raw[i].planes[0], 1, length_frame,
616 downsampled_input[NUM_ENCODERS - i - 1]) !=
625 for ( i=0; i<NUM_ENCODERS; i++)
629 flag_periodicity = periodicity_to_num_layers
630 [num_temporal_layers[i] - 1];
632 frame_cnt % flag_periodicity];
638 if (frame_cnt > 0 && frame_cnt == key_frame_insert)
647 gettimeofday(&tv1, NULL);
652 frame_cnt, 1, 0, arg_deadline))
654 die_codec(&codec[0],
"Failed to encode frame");
656 gettimeofday(&tv2, NULL);
657 timersub(&tv2, &tv1, &difftv);
658 cx_time += (double)(difftv.tv_sec * 1000000 + difftv.tv_usec);
659 for (i=NUM_ENCODERS-1; i>=0 ; i--)
665 switch(pkt[i]->kind) {
667 write_ivf_frame_header(outfile[i], pkt[i]);
668 (void) fwrite(pkt[i]->data.
frame.buf, 1,
676 psnr_sse_total[i] += pkt[i]->
data.
psnr.sse[0];
677 psnr_samples_total[i] += pkt[i]->
data.
psnr.samples[0];
678 for (j = 0; j < 4; j++)
680 psnr_totals[i][j] += pkt[i]->
data.
psnr.psnr[j];
697 printf(
"FPS for encoding %d %f %f \n", frame_cnt, (
float)cx_time / 1000000,
698 1000000 * (
double)frame_cnt / (
double)cx_time);
702 printf(
"Processed %ld frames.\n",(
long int)frame_cnt-1);
703 for (i=0; i< NUM_ENCODERS; i++)
706 if ( (show_psnr) && (psnr_count[i]>0) )
709 double ovpsnr = sse_to_psnr(psnr_samples_total[i], 255.0,
712 fprintf(stderr,
"\n ENC%d PSNR (Overall/Avg/Y/U/V)", i);
714 fprintf(stderr,
" %.3lf", ovpsnr);
715 for (j = 0; j < 4; j++)
717 fprintf(stderr,
" %.3lf", psnr_totals[i][j]/psnr_count[i]);
722 die_codec(&codec[i],
"Failed to destroy codec");
730 if(!fseek(outfile[i], 0, SEEK_SET))
731 write_ivf_file_header(outfile[i], &cfg[i], frame_cnt-1);
Rational Number.
Definition: vpx_encoder.h:256
unsigned int rc_buf_initial_sz
Decoder Buffer Initial Size.
Definition: vpx_encoder.h:607
unsigned int ts_number_layers
Number of temporal coding layers.
Definition: vpx_encoder.h:712
Codec control function to set encoder internal speed settings.
Definition: vp8cx.h:183
#define VP8_EFLAG_NO_UPD_GF
Don't update the golden frame.
Definition: vp8cx.h:93
Image Descriptor.
Definition: vpx_image.h:82
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.
Definition: vpx_image.h:55
const char * vpx_codec_err_to_string(vpx_codec_err_t err)
Convert error number to printable string.
struct vpx_rational g_timebase
Stream timebase units.
Definition: vpx_encoder.h:394
Definition: vpx_encoder.h:273
unsigned int rc_buf_sz
Decoder Buffer Size.
Definition: vpx_encoder.h:597
#define VP8_EFLAG_NO_REF_GF
Don't reference the golden frame.
Definition: vp8cx.h:68
Codec control function to set reference and update frame flags.
Definition: vp8cx.h:285
enum vpx_kf_mode kf_mode
Keyframe placement mode.
Definition: vpx_encoder.h:662
int den
Definition: vpx_encoder.h:258
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 rc_max_quantizer
Maximum (Worst Quality) Quantizer.
Definition: vpx_encoder.h:549
unsigned int rc_min_quantizer
Minimum (Best Quality) Quantizer.
Definition: vpx_encoder.h:538
unsigned int kf_max_dist
Keyframe maximum interval.
Definition: vpx_encoder.h:682
unsigned int g_lag_in_frames
Allow lagged encoding.
Definition: vpx_encoder.h:426
Encoder configuration structure.
Definition: vpx_encoder.h:311
Definition: vpx_encoder.h:176
Definition: vpx_encoder.h:289
Codec control function to set Max data rate for Intra frames.
Definition: vp8cx.h:279
Encoder output packet.
Definition: vpx_encoder.h:192
unsigned int rc_overshoot_pct
Rate control adaptation overshoot control.
Definition: vpx_encoder.h:580
unsigned int ts_rate_decimator[5]
Frame rate decimation factor for each temporal layer.
Definition: vpx_encoder.h:726
unsigned int rc_buf_optimal_sz
Decoder Buffer Optimal Size.
Definition: vpx_encoder.h:617
#define VPX_PLANE_V
Definition: vpx_image.h:103
unsigned int kf_min_dist
Keyframe minimum interval.
Definition: vpx_encoder.h:672
Definition: vpx_encoder.h:266
unsigned int ts_layer_id[16]
Template defining the membership of frames to temporal layers.
Definition: vpx_encoder.h:744
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:56
unsigned int d_w
Definition: vpx_image.h:92
unsigned int g_w
Width of the frame.
Definition: vpx_encoder.h:354
unsigned int ts_target_bitrate[5]
Target bitrate for each temporal layer.
Definition: vpx_encoder.h:719
unsigned int rc_undershoot_pct
Rate control adaptation undershoot control.
Definition: vpx_encoder.h:567
unsigned int g_h
Height of the frame.
Definition: vpx_encoder.h:364
int stride[4]
Definition: vpx_image.h:106
enum vpx_codec_cx_pkt_kind kind
Definition: vpx_encoder.h:193
unsigned int rc_dropframe_thresh
Temporal resampling configuration, if supported by the codec.
Definition: vpx_encoder.h:449
Codec control function to set the temporal layer id.
Definition: vp8cx.h:326
#define VP8_EFLAG_NO_UPD_LAST
Don't update the last frame.
Definition: vp8cx.h:85
void vpx_img_free(vpx_image_t *img)
Close an image descriptor.
vpx_img_fmt_t fmt
Definition: vpx_image.h:83
unsigned char * planes[4]
Definition: vpx_image.h:105
Codec control function to set the number of token partitions.
Definition: vp8cx.h:216
unsigned int rc_target_bitrate
Target data rate.
Definition: vpx_encoder.h:522
#define VPX_DL_REALTIME
Definition: vpx_encoder.h:891
int num
Definition: vpx_encoder.h:257
control function to set noise sensitivity
Definition: vp8cx.h:198
enum vpx_enc_pass g_pass
Multi-pass Encoding Mode.
Definition: vpx_encoder.h:411
double psnr[4]
Definition: vpx_encoder.h:216
unsigned int g_threads
Maximum number of threads to use.
Definition: vpx_encoder.h:332
Provides definitions for using VP8 or VP9 encoder algorithm within the vpx Codec Interface.
#define VPX_PLANE_U
Definition: vpx_image.h:102
unsigned int rc_resize_allowed
Enable/disable spatial resampling, if supported by the codec.
Definition: vpx_encoder.h:459
unsigned int h
Definition: vpx_image.h:88
vpx_codec_err_t
Algorithm return codes.
Definition: vpx_codec.h:89
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
#define vpx_codec_enc_init_multi(ctx, iface, cfg, num_enc, flags, dsf)
Convenience macro for vpx_codec_enc_init_multi_ver()
Definition: vpx_encoder.h:830
int64_t vpx_codec_pts_t
Time Stamp Type.
Definition: vpx_encoder.h:116
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.
#define VPX_TS_MAX_PERIODICITY
Definition: vpx_encoder.h:37
#define vpx_codec_control(ctx, id, data)
vpx_codec_control wrapper macro
Definition: vpx_codec.h:407
unsigned int ts_periodicity
Length of the sequence defining frame temporal layer membership.
Definition: vpx_encoder.h:735
vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx)
Destroy a codec instance.
unsigned int d_h
Definition: vpx_image.h:93
unsigned int w
Definition: vpx_image.h:87
Codec control function to set the threshold for MBs treated static.
Definition: vp8cx.h:210
#define VPX_FRAME_IS_KEY
Definition: vpx_encoder.h:127
#define VPX_EFLAG_FORCE_KF
Definition: vpx_encoder.h:302
const void * vpx_codec_iter_t
Iterator.
Definition: vpx_codec.h:188
Definition: vpx_encoder.h:173
vpx_codec_er_flags_t g_error_resilient
Enable error resilient modes.
Definition: vpx_encoder.h:403
#define VP8_EFLAG_NO_UPD_ARF
Don't update the alternate reference frame.
Definition: vp8cx.h:101
#define VP8_EFLAG_NO_UPD_ENTROPY
Disable entropy update.
Definition: vp8cx.h:125
enum vpx_rc_mode rc_end_usage
Rate control algorithm to use.
Definition: vpx_encoder.h:501
Definition: vpx_encoder.h:264
Codec context structure.
Definition: vpx_codec.h:199