12ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/* 22ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 32ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * 42ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * Use of this source code is governed by a BSD-style license 52ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * that can be found in the LICENSE file in the root of the source 62ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * tree. An additional intellectual property rights grant can be found 72ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * in the file PATENTS. All contributing project authors may 82ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * be found in the AUTHORS file in the root of the source tree. 92ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian */ 102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Two Pass Encoder 122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ================ 132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// This is an example of a two pass encoder loop. It takes an input file in 152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// YV12 format, passes it through the encoder twice, and writes the compressed 162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// frames to disk in IVF format. It builds upon the simple_encoder example. 172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Twopass Variables 192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ----------------- 202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Twopass mode needs to track the current pass number and the buffer of 212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// statistics packets. 222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Updating The Configuration 242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// --------------------------------- 252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// In two pass mode, the configuration has to be updated on each pass. The 262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// statistics buffer is passed on the last pass. 272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Encoding A Frame 292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ---------------- 302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Encoding a frame in two pass mode is identical to the simple encoder 312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// example, except the deadline is set to VPX_DL_BEST_QUALITY to get the 322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// best quality possible. VPX_DL_GOOD_QUALITY could also be used. 332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Processing Statistics Packets 362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ----------------------------- 372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Each packet of type `VPX_CODEC_CX_FRAME_PKT` contains the encoded data 382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// for this frame. We write a IVF frame header, followed by the raw data. 392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Pass Progress Reporting 422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ----------------------------- 432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// It's sometimes helpful to see when each pass completes. 442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Clean-up 472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ----------------------------- 482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Destruction of the encoder instance must be done on each pass. The 492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// raw image should be destroyed at the end as usual. 502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <stdio.h> 522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <stdlib.h> 532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <string.h> 542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#define VPX_CODEC_DISABLE_COMPAT 1 562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vpx/vpx_encoder.h" 572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "./tools_common.h" 592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "./video_writer.h" 602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic const char *exec_name; 622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid usage_exit() { 642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n", 652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian exec_name); 662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian exit(EXIT_FAILURE); 672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void get_frame_stats(vpx_codec_ctx_t *ctx, 702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const vpx_image_t *img, 712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_codec_pts_t pts, 722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian unsigned int duration, 732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_enc_frame_flags_t flags, 742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian unsigned int deadline, 752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_fixed_buf_t *stats) { 762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_codec_iter_t iter = NULL; 772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const vpx_codec_cx_pkt_t *pkt = NULL; 782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const vpx_codec_err_t res = vpx_codec_encode(ctx, img, pts, duration, flags, 792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian deadline); 802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (res != VPX_CODEC_OK) 812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(ctx, "Failed to get frame stats."); 822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) { 842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (pkt->kind == VPX_CODEC_STATS_PKT) { 852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint8_t *const pkt_buf = pkt->data.twopass_stats.buf; 862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t pkt_size = pkt->data.twopass_stats.sz; 872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stats->buf = realloc(stats->buf, stats->sz + pkt_size); 882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian memcpy((uint8_t *)stats->buf + stats->sz, pkt_buf, pkt_size); 892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stats->sz += pkt_size; 902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void encode_frame(vpx_codec_ctx_t *ctx, 952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const vpx_image_t *img, 962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_codec_pts_t pts, 972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian unsigned int duration, 982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_enc_frame_flags_t flags, 992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian unsigned int deadline, 1002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian VpxVideoWriter *writer) { 1012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_codec_iter_t iter = NULL; 1022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const vpx_codec_cx_pkt_t *pkt = NULL; 1032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const vpx_codec_err_t res = vpx_codec_encode(ctx, img, pts, duration, flags, 1042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian deadline); 1052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (res != VPX_CODEC_OK) 1062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(ctx, "Failed to encode frame."); 1072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) { 1092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { 1102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; 1112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf, 1132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian pkt->data.frame.sz, 1142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian pkt->data.frame.pts)) 1152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(ctx, "Failed to write compressed frame."); 1162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian printf(keyframe ? "K" : "."); 1172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian fflush(stdout); 1182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 1212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianint main(int argc, char **argv) { 1232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian FILE *infile = NULL; 1242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian VpxVideoWriter *writer = NULL; 1252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_codec_ctx_t codec; 1262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_codec_enc_cfg_t cfg; 1272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_image_t raw; 1282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_codec_err_t res; 1292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_fixed_buf_t stats = {0}; 1302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian VpxVideoInfo info = {0}; 1312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const VpxInterface *encoder = NULL; 1322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int pass; 1332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int fps = 30; // TODO(dkovalev) add command line argument 1342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument 1352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const char *const codec_arg = argv[1]; 1362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const char *const width_arg = argv[2]; 1372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const char *const height_arg = argv[3]; 1382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const char *const infile_arg = argv[4]; 1392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const char *const outfile_arg = argv[5]; 1402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian exec_name = argv[0]; 1412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (argc != 6) 1432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die("Invalid number of arguments."); 1442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoder = get_vpx_encoder_by_name(codec_arg); 1462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!encoder) 1472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die("Unsupported codec."); 1482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian info.codec_fourcc = encoder->fourcc; 1502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian info.time_base.numerator = 1; 1512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian info.time_base.denominator = fps; 1522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian info.frame_width = strtol(width_arg, NULL, 0); 1532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian info.frame_height = strtol(height_arg, NULL, 0); 1542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (info.frame_width <= 0 || 1562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian info.frame_height <= 0 || 1572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian (info.frame_width % 2) != 0 || 1582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian (info.frame_height % 2) != 0) { 1592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die("Invalid frame size: %dx%d", info.frame_width, info.frame_height); 1602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width, 1632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian info.frame_height, 1)) { 1642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die("Failed to allocate image", info.frame_width, info.frame_height); 1652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info); 1682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer) 1692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die("Failed to open %s for writing", outfile_arg); 1702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); 1722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); 1742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (res) 1752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(&codec, "Failed to get default codec config."); 1762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cfg.g_w = info.frame_width; 1782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cfg.g_h = info.frame_height; 1792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cfg.g_timebase.num = info.time_base.numerator; 1802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cfg.g_timebase.den = info.time_base.denominator; 1812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cfg.rc_target_bitrate = bitrate; 1822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (pass = 0; pass < 2; ++pass) { 1842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int frame_count = 0; 1852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (pass == 0) { 1872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cfg.g_pass = VPX_RC_FIRST_PASS; 1882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } else { 1892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cfg.g_pass = VPX_RC_LAST_PASS; 1902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cfg.rc_twopass_stats_in = stats; 1912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!(infile = fopen(infile_arg, "rb"))) 1942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die("Failed to open %s for reading", infile_arg); 1952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0)) 1972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(&codec, "Failed to initialize encoder"); 1982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (vpx_img_read(&raw, infile)) { 2002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ++frame_count; 2012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (pass == 0) { 2032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian get_frame_stats(&codec, &raw, frame_count, 1, 0, VPX_DL_BEST_QUALITY, 2042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian &stats); 2052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } else { 2062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encode_frame(&codec, &raw, frame_count, 1, 0, VPX_DL_BEST_QUALITY, 2072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer); 2082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 2092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 2102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (pass == 0) { 2122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian get_frame_stats(&codec, NULL, frame_count, 1, 0, VPX_DL_BEST_QUALITY, 2132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian &stats); 2142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } else { 2152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian printf("\n"); 2162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 2172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian fclose(infile); 2192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian printf("Pass %d complete. Processed %d frames.\n", pass + 1, frame_count); 2202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (vpx_codec_destroy(&codec)) 2212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(&codec, "Failed to destroy codec."); 2222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 2232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_img_free(&raw); 2252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian free(stats.buf); 2262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_video_writer_close(writer); 2282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return EXIT_SUCCESS; 2302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 231