23 #include "./vpx_config.h" 32 #include "vpx_ports/vpx_timer.h" 35 #include "vpx_ports/mem_ops.h" 36 #include "../tools_common.h" 37 #define interface (vpx_codec_vp8_cx()) 38 #define fourcc 0x30385056 40 void usage_exit(
void) { exit(EXIT_FAILURE); }
52 #define NUM_ENCODERS 3 55 #define MAX_NUM_TEMPORAL_LAYERS 3 58 #include "third_party/libyuv/include/libyuv/basic_types.h" 59 #include "third_party/libyuv/include/libyuv/scale.h" 60 #include "third_party/libyuv/include/libyuv/cpu_id.h" 65 size_t nbytes, to_read;
68 to_read = img->
w * img->
h * 3 / 2;
69 nbytes = fread(img->
planes[0], 1, to_read, f);
70 if (nbytes != to_read) {
73 printf(
"Warning: Read partial frame. Check your width & height!\n");
78 static int read_frame_by_row(FILE *f,
vpx_image_t *img) {
79 size_t nbytes, to_read;
83 for (plane = 0; plane < 3; plane++) {
85 int w = (plane ? (1 + img->
d_w) / 2 : img->
d_w);
86 int h = (plane ? (1 + img->
d_h) / 2 : img->
d_h);
102 default: ptr = img->
planes[plane];
105 for (r = 0; r < h; r++) {
108 nbytes = fread(ptr, 1, to_read, f);
109 if (nbytes != to_read) {
112 printf(
"Warning: Read partial frame. Check your width & height!\n");
116 ptr += img->
stride[plane];
133 mem_put_le16(header + 4, 0);
134 mem_put_le16(header + 6, 32);
135 mem_put_le32(header + 8, fourcc);
136 mem_put_le16(header + 12, cfg->
g_w);
137 mem_put_le16(header + 14, cfg->
g_h);
140 mem_put_le32(header + 24, frame_cnt);
141 mem_put_le32(header + 28, 0);
143 (void)fwrite(header, 1, 32, outfile);
146 static void write_ivf_frame_header(FILE *outfile,
154 mem_put_le32(header, pkt->
data.
frame.sz);
155 mem_put_le32(header + 4, pts & 0xFFFFFFFF);
156 mem_put_le32(header + 8, pts >> 32);
158 (void)fwrite(header, 1, 12, outfile);
166 static void set_temporal_layer_pattern(
int num_temporal_layers,
169 assert(num_temporal_layers <= MAX_NUM_TEMPORAL_LAYERS);
170 switch (num_temporal_layers) {
216 layer_flags[4] = layer_flags[2];
219 layer_flags[5] = layer_flags[3];
222 layer_flags[6] = layer_flags[4];
225 layer_flags[7] = layer_flags[5];
271 layer_flags[5] = layer_flags[3];
277 layer_flags[7] = layer_flags[3];
284 static int periodicity_to_num_layers[MAX_NUM_TEMPORAL_LAYERS] = { 1, 8, 8 };
286 int main(
int argc,
char **argv) {
287 FILE *infile, *outfile[NUM_ENCODERS];
288 FILE *downsampled_input[NUM_ENCODERS - 1];
306 int flag_periodicity;
315 int key_frame_insert = 0;
316 uint64_t psnr_sse_total[NUM_ENCODERS] = { 0 };
317 uint64_t psnr_samples_total[NUM_ENCODERS] = { 0 };
318 double psnr_totals[NUM_ENCODERS][4] = { { 0, 0 } };
319 int psnr_count[NUM_ENCODERS] = { 0 };
327 unsigned int target_bitrate[NUM_ENCODERS] = { 1000, 500, 100 };
336 vpx_rational_t dsf[NUM_ENCODERS] = { { 2, 1 }, { 2, 1 }, { 1, 1 } };
340 unsigned int num_temporal_layers[NUM_ENCODERS] = { 3, 3, 3 };
342 if (argc != (7 + 3 * NUM_ENCODERS))
343 die(
"Usage: %s <width> <height> <frame_rate> <infile> <outfile(s)> " 344 "<rate_encoder(s)> <temporal_layer(s)> <key_frame_insert> <output " 350 width = strtol(argv[1], NULL, 0);
351 height = strtol(argv[2], NULL, 0);
352 framerate = strtol(argv[3], NULL, 0);
354 if (width < 16 || width % 2 || height < 16 || height % 2)
355 die(
"Invalid resolution: %ldx%ld", width, height);
358 if (!(infile = fopen(argv[4],
"rb")))
359 die(
"Failed to open %s for reading", argv[4]);
362 for (i = 0; i < NUM_ENCODERS; i++) {
363 if (!target_bitrate[i]) {
368 if (!(outfile[i] = fopen(argv[i + 5],
"wb")))
369 die(
"Failed to open %s for writing", argv[i + 4]);
373 for (i = 0; i < NUM_ENCODERS; i++) {
374 target_bitrate[i] = strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
378 for (i = 0; i < NUM_ENCODERS; i++) {
379 num_temporal_layers[i] = strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
380 if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
381 die(
"Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
382 num_temporal_layers);
386 for (i = 0; i < NUM_ENCODERS - 1; i++) {
388 if (sprintf(filename,
"ds%d.yuv", NUM_ENCODERS - i) < 0) {
391 downsampled_input[i] = fopen(filename,
"wb");
394 key_frame_insert = strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0);
396 show_psnr = strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
399 for (i = 0; i < NUM_ENCODERS; i++) {
439 for (i = 1; i < NUM_ENCODERS; i++) {
449 unsigned int iw = cfg[i - 1].
g_w * dsf[i - 1].
den + dsf[i - 1].
num - 1;
450 unsigned int ih = cfg[i - 1].
g_h * dsf[i - 1].
den + dsf[i - 1].
num - 1;
451 cfg[i].
g_w = iw / dsf[i - 1].
num;
452 cfg[i].
g_h = ih / dsf[i - 1].
num;
457 if ((cfg[i].g_w) % 2) cfg[i].
g_w++;
458 if ((cfg[i].g_h) % 2) cfg[i].
g_h++;
468 for (i = 0; i < NUM_ENCODERS; i++)
470 die(
"Failed to allocate image", cfg[i].g_w, cfg[i].g_h);
472 if (raw[0].stride[VPX_PLANE_Y] == raw[0].d_w)
473 read_frame_p = read_frame;
475 read_frame_p = read_frame_by_row;
477 for (i = 0; i < NUM_ENCODERS; i++)
478 if (outfile[i]) write_ivf_file_header(outfile[i], &cfg[i], 0);
481 for (i = 0; i < NUM_ENCODERS; i++) {
482 set_temporal_layer_pattern(num_temporal_layers[i], &cfg[i],
483 cfg[i].rc_target_bitrate,
489 (show_psnr ? VPX_CODEC_USE_PSNR : 0), &dsf[0]))
490 die_codec(&codec[0],
"Failed to initialize encoder");
494 for (i = 0; i < NUM_ENCODERS; i++) {
497 if (i == NUM_ENCODERS - 1) speed = -4;
499 die_codec(&codec[i],
"Failed to set cpu_used");
503 for (i = 0; i < NUM_ENCODERS; i++) {
505 die_codec(&codec[i],
"Failed to set static threshold");
511 die_codec(&codec[0],
"Failed to set noise_sensitivity");
513 die_codec(&codec[1],
"Failed to set noise_sensitivity");
514 for (i = 2; i < NUM_ENCODERS; i++) {
516 die_codec(&codec[i],
"Failed to set noise_sensitivity");
520 for (i = 0; i < NUM_ENCODERS; i++) {
522 die_codec(&codec[i],
"Failed to set static threshold");
526 for (i = 0; i < NUM_ENCODERS; i++) {
527 unsigned int max_intra_size_pct =
528 (int)(((
double)cfg[0].rc_buf_optimal_sz * 0.5) * framerate / 10);
531 die_codec(&codec[i],
"Failed to set static threshold");
538 while (frame_avail || got_data) {
539 struct vpx_usec_timer timer;
544 frame_avail = read_frame_p(infile, &raw[0]);
547 for (i = 1; i < NUM_ENCODERS; i++) {
551 raw[i - 1].planes[VPX_PLANE_Y], raw[i - 1].stride[VPX_PLANE_Y],
552 raw[i - 1].planes[VPX_PLANE_U], raw[i - 1].stride[VPX_PLANE_U],
553 raw[i - 1].planes[VPX_PLANE_V], raw[i - 1].stride[VPX_PLANE_V],
554 raw[i - 1].d_w, raw[i - 1].d_h, raw[i].planes[VPX_PLANE_Y],
555 raw[i].stride[VPX_PLANE_Y], raw[i].planes[VPX_PLANE_U],
556 raw[i].stride[VPX_PLANE_U], raw[i].planes[VPX_PLANE_V],
557 raw[i].stride[VPX_PLANE_V], raw[i].d_w, raw[i].d_h, 1);
559 length_frame = cfg[i].
g_w * cfg[i].
g_h * 3 / 2;
560 if (fwrite(raw[i].planes[0], 1, length_frame,
561 downsampled_input[NUM_ENCODERS - i - 1]) != length_frame) {
568 for (i = 0; i < NUM_ENCODERS; i++) {
571 flag_periodicity = periodicity_to_num_layers[num_temporal_layers[i] - 1];
573 frame_cnt % flag_periodicity];
575 if (frame_cnt == 0) {
578 if (frame_cnt > 0 && frame_cnt == key_frame_insert) {
589 vpx_usec_timer_start(&timer);
592 die_codec(&codec[0],
"Failed to encode frame");
594 vpx_usec_timer_mark(&timer);
595 cx_time += vpx_usec_timer_elapsed(&timer);
597 for (i = NUM_ENCODERS - 1; i >= 0; i--) {
601 switch (pkt[i]->kind) {
603 write_ivf_frame_header(outfile[i], pkt[i]);
611 psnr_sse_total[i] += pkt[i]->
data.
psnr.sse[0];
612 psnr_samples_total[i] += pkt[i]->
data.
psnr.samples[0];
613 for (j = 0; j < 4; j++) {
614 psnr_totals[i][j] += pkt[i]->
data.
psnr.psnr[j];
632 printf(
"Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
633 frame_cnt, 1000 * (
float)cx_time / (
double)(frame_cnt * 1000000),
634 1000000 * (
double)frame_cnt / (
double)cx_time);
638 printf(
"Processed %ld frames.\n", (
long int)frame_cnt - 1);
639 for (i = 0; i < NUM_ENCODERS; i++) {
641 if ((show_psnr) && (psnr_count[i] > 0)) {
644 sse_to_psnr(psnr_samples_total[i], 255.0, psnr_sse_total[i]);
646 fprintf(stderr,
"\n ENC%d PSNR (Overall/Avg/Y/U/V)", i);
648 fprintf(stderr,
" %.3lf", ovpsnr);
649 for (j = 0; j < 4; j++) {
650 fprintf(stderr,
" %.3lf", psnr_totals[i][j] / psnr_count[i]);
655 die_codec(&codec[i],
"Failed to destroy codec");
659 if (!outfile[i])
continue;
662 if (!fseek(outfile[i], 0, SEEK_SET))
663 write_ivf_file_header(outfile[i], &cfg[i], frame_cnt - 1);
Rational Number.
Definition: vpx_encoder.h:235
unsigned int rc_buf_initial_sz
Decoder Buffer Initial Size.
Definition: vpx_encoder.h:559
unsigned int ts_number_layers
Number of temporal coding layers.
Definition: vpx_encoder.h:656
Codec control function to set encoder internal speed settings.
Definition: vp8cx.h:155
#define VP8_EFLAG_NO_UPD_GF
Don't update the golden frame.
Definition: vp8cx.h:88
Image Descriptor.
Definition: vpx_image.h:88
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:53
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:363
Definition: vpx_encoder.h:250
unsigned int rc_buf_sz
Decoder Buffer Size.
Definition: vpx_encoder.h:550
#define VP8_EFLAG_NO_REF_GF
Don't reference the golden frame.
Definition: vp8cx.h:66
Codec control function to set reference and update frame flags.
Definition: vp8cx.h:257
enum vpx_kf_mode kf_mode
Keyframe placement mode.
Definition: vpx_encoder.h:608
int den
Definition: vpx_encoder.h:237
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:507
unsigned int rc_min_quantizer
Minimum (Best Quality) Quantizer.
Definition: vpx_encoder.h:497
unsigned int kf_max_dist
Keyframe maximum interval.
Definition: vpx_encoder.h:626
unsigned int g_lag_in_frames
Allow lagged encoding.
Definition: vpx_encoder.h:392
Encoder configuration structure.
Definition: vpx_encoder.h:285
Definition: vpx_encoder.h:160
Definition: vpx_encoder.h:265
Codec control function to set Max data rate for Intra frames.
Definition: vp8cx.h:251
Encoder output packet.
Definition: vpx_encoder.h:175
unsigned int rc_overshoot_pct
Rate control adaptation overshoot control.
Definition: vpx_encoder.h:535
unsigned int ts_rate_decimator[5]
Frame rate decimation factor for each temporal layer.
Definition: vpx_encoder.h:670
unsigned int rc_buf_optimal_sz
Decoder Buffer Optimal Size.
Definition: vpx_encoder.h:568
#define VPX_PLANE_V
Definition: vpx_image.h:114
unsigned int kf_min_dist
Keyframe minimum interval.
Definition: vpx_encoder.h:617
Definition: vpx_encoder.h:244
unsigned int ts_layer_id[16]
Template defining the membership of frames to temporal layers.
Definition: vpx_encoder.h:688
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
vpx_image_t img
Definition: vp8.h:121
unsigned int g_w
Width of the frame.
Definition: vpx_encoder.h:324
unsigned int ts_target_bitrate[5]
Target bitrate for each temporal layer.
Definition: vpx_encoder.h:663
unsigned int rc_undershoot_pct
Rate control adaptation undershoot control.
Definition: vpx_encoder.h:523
unsigned int g_h
Height of the frame.
Definition: vpx_encoder.h:333
int stride[4]
Definition: vpx_image.h:117
enum vpx_codec_cx_pkt_kind kind
Definition: vpx_encoder.h:176
unsigned int rc_dropframe_thresh
Temporal resampling configuration, if supported by the codec.
Definition: vpx_encoder.h:414
Codec control function to set the temporal layer id.
Definition: vp8cx.h:298
#define VP8_EFLAG_NO_UPD_LAST
Don't update the last frame.
Definition: vp8cx.h:81
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
Codec control function to set the number of token partitions.
Definition: vp8cx.h:188
unsigned int rc_target_bitrate
Target data rate.
Definition: vpx_encoder.h:483
#define VPX_DL_REALTIME
deadline parameter analogous to VPx REALTIME mode.
Definition: vpx_encoder.h:842
int num
Definition: vpx_encoder.h:236
control function to set noise sensitivity
Definition: vp8cx.h:170
enum vpx_enc_pass g_pass
Multi-pass Encoding Mode.
Definition: vpx_encoder.h:378
double psnr[4]
Definition: vpx_encoder.h:196
unsigned int g_threads
Maximum number of threads to use.
Definition: vpx_encoder.h:305
Provides definitions for using VP8 or VP9 encoder algorithm within the vpx Codec Interface.
#define VPX_PLANE_U
Definition: vpx_image.h:113
unsigned int rc_resize_allowed
Enable/disable spatial resampling, if supported by the codec.
Definition: vpx_encoder.h:423
unsigned int h
Definition: vpx_image.h:95
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:784
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:399
unsigned int ts_periodicity
Length of the sequence defining frame temporal layer membership.
Definition: vpx_encoder.h:679
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
unsigned int w
Definition: vpx_image.h:94
Codec control function to set the threshold for MBs treated static.
Definition: vp8cx.h:182
#define VPX_FRAME_IS_KEY
Definition: vpx_encoder.h:126
#define VPX_EFLAG_FORCE_KF
Definition: vpx_encoder.h:277
const void * vpx_codec_iter_t
Iterator.
Definition: vpx_codec.h:182
Definition: vpx_encoder.h:157
vpx_codec_er_flags_t g_error_resilient
Enable error resilient modes.
Definition: vpx_encoder.h:371
#define VP8_EFLAG_NO_UPD_ARF
Don't update the alternate reference frame.
Definition: vp8cx.h:95
#define VP8_EFLAG_NO_UPD_ENTROPY
Disable entropy update.
Definition: vp8cx.h:116
enum vpx_rc_mode rc_end_usage
Rate control algorithm to use.
Definition: vpx_encoder.h:463
Definition: vpx_encoder.h:242
Codec context structure.
Definition: vpx_codec.h:192