1b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian/* 2b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * 4b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * Use of this source code is governed by a BSD-style license 5b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * that can be found in the LICENSE file in the root of the source 6b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * tree. An additional intellectual property rights grant can be found 7b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * in the file PATENTS. All contributing project authors may 8b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * be found in the AUTHORS file in the root of the source tree. 9b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian */ 10b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 11b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Two Pass Encoder 12b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ================ 13b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 14b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// This is an example of a two pass encoder loop. It takes an input file in 15b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// YV12 format, passes it through the encoder twice, and writes the compressed 16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// frames to disk in IVF format. It builds upon the simple_encoder example. 17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 18b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Twopass Variables 19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ----------------- 20b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Twopass mode needs to track the current pass number and the buffer of 21b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// statistics packets. 22b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 23b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Updating The Configuration 24b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// --------------------------------- 25b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// In two pass mode, the configuration has to be updated on each pass. The 26b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// statistics buffer is passed on the last pass. 27b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 28b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Encoding A Frame 29b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ---------------- 30b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Encoding a frame in two pass mode is identical to the simple encoder 31b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// example, except the deadline is set to VPX_DL_BEST_QUALITY to get the 32b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// best quality possible. VPX_DL_GOOD_QUALITY could also be used. 33b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 34b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 35b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Processing Statistics Packets 36b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ----------------------------- 37b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Each packet of type `VPX_CODEC_CX_FRAME_PKT` contains the encoded data 38b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// for this frame. We write a IVF frame header, followed by the raw data. 39b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 40b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 41b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Pass Progress Reporting 42b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ----------------------------- 43b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// It's sometimes helpful to see when each pass completes. 44b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 45b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 46b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Clean-up 47b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ----------------------------- 48b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Destruction of the encoder instance must be done on each pass. The 49b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// raw image should be destroyed at the end as usual. 50b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 51b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdio.h> 52b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdlib.h> 53b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <string.h> 54b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 55b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define VPX_CODEC_DISABLE_COMPAT 1 56b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vpx_encoder.h" 57b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 58b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./tools_common.h" 59b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./video_writer.h" 60b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 61b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic const char *exec_name; 62b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 63b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid usage_exit() { 64b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n", 65b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exec_name); 66b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exit(EXIT_FAILURE); 67b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 68b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 69b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void get_frame_stats(vpx_codec_ctx_t *ctx, 70b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const vpx_image_t *img, 71b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_pts_t pts, 72b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int duration, 73b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_enc_frame_flags_t flags, 74b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int deadline, 75b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_fixed_buf_t *stats) { 76b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_iter_t iter = NULL; 77b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const vpx_codec_cx_pkt_t *pkt = NULL; 78b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const vpx_codec_err_t res = vpx_codec_encode(ctx, img, pts, duration, flags, 79b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian deadline); 80b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (res != VPX_CODEC_OK) 81b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(ctx, "Failed to get frame stats."); 82b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 83b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) { 84b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (pkt->kind == VPX_CODEC_STATS_PKT) { 85b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const uint8_t *const pkt_buf = pkt->data.twopass_stats.buf; 86b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const size_t pkt_size = pkt->data.twopass_stats.sz; 87b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian stats->buf = realloc(stats->buf, stats->sz + pkt_size); 88b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy((uint8_t *)stats->buf + stats->sz, pkt_buf, pkt_size); 89b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian stats->sz += pkt_size; 90b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 91b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 92b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 93b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 94b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void encode_frame(vpx_codec_ctx_t *ctx, 95b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const vpx_image_t *img, 96b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_pts_t pts, 97b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int duration, 98b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_enc_frame_flags_t flags, 99b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int deadline, 100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VpxVideoWriter *writer) { 101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_iter_t iter = NULL; 102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const vpx_codec_cx_pkt_t *pkt = NULL; 103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const vpx_codec_err_t res = vpx_codec_encode(ctx, img, pts, duration, flags, 104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian deadline); 105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (res != VPX_CODEC_OK) 106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(ctx, "Failed to encode frame."); 107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) { 109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { 110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; 111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf, 113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pkt->data.frame.sz, 114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pkt->data.frame.pts)) 115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(ctx, "Failed to write compressed frame."); 116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf(keyframe ? "K" : "."); 117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fflush(stdout); 118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint main(int argc, char **argv) { 123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian FILE *infile = NULL; 124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VpxVideoWriter *writer = NULL; 125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_ctx_t codec; 126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_enc_cfg_t cfg; 127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_image_t raw; 128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_err_t res; 129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_fixed_buf_t stats = {0}; 130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VpxVideoInfo info = {0}; 131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const VpxInterface *encoder = NULL; 132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int pass; 133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const int fps = 30; // TODO(dkovalev) add command line argument 134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument 135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const char *const codec_arg = argv[1]; 136b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const char *const width_arg = argv[2]; 137b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const char *const height_arg = argv[3]; 138b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const char *const infile_arg = argv[4]; 139b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const char *const outfile_arg = argv[5]; 140b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exec_name = argv[0]; 141b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 142b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (argc != 6) 143b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Invalid number of arguments."); 144b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 145b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian encoder = get_vpx_encoder_by_name(codec_arg); 146b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!encoder) 147b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Unsupported codec."); 148b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 149b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.codec_fourcc = encoder->fourcc; 150b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.time_base.numerator = 1; 151b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.time_base.denominator = fps; 152b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.frame_width = strtol(width_arg, NULL, 0); 153b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.frame_height = strtol(height_arg, NULL, 0); 154b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 155b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (info.frame_width <= 0 || 156b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.frame_height <= 0 || 157b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (info.frame_width % 2) != 0 || 158b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (info.frame_height % 2) != 0) { 159b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Invalid frame size: %dx%d", info.frame_width, info.frame_height); 160b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 161b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 162b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width, 163b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info.frame_height, 1)) { 164b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to allocate image", info.frame_width, info.frame_height); 165b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 166b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 167b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info); 168b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!writer) 169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to open %s for writing", outfile_arg); 170b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 171b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Using %s\n", vpx_codec_iface_name(encoder->interface())); 172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 173b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian res = vpx_codec_enc_config_default(encoder->interface(), &cfg, 0); 174b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (res) 175b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to get default codec config."); 176b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 177b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_w = info.frame_width; 178b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_h = info.frame_height; 179b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_timebase.num = info.time_base.numerator; 180b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_timebase.den = info.time_base.denominator; 181b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_target_bitrate = bitrate; 182b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 183b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (pass = 0; pass < 2; ++pass) { 184b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int frame_count = 0; 185b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 186b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (pass == 0) { 187b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_pass = VPX_RC_FIRST_PASS; 188b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } else { 189b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.g_pass = VPX_RC_LAST_PASS; 190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cfg.rc_twopass_stats_in = stats; 191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 192b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 193b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!(infile = fopen(infile_arg, "rb"))) 194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to open %s for reading", infile_arg); 195b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 196b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_enc_init(&codec, encoder->interface(), &cfg, 0)) 197b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to initialize encoder"); 198b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (vpx_img_read(&raw, infile)) { 200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ++frame_count; 201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 202b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (pass == 0) { 203b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian get_frame_stats(&codec, &raw, frame_count, 1, 0, VPX_DL_BEST_QUALITY, 204b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian &stats); 205b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } else { 206b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian encode_frame(&codec, &raw, frame_count, 1, 0, VPX_DL_BEST_QUALITY, 207b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian writer); 208b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 209b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 210b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 211b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (pass == 0) { 212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian get_frame_stats(&codec, NULL, frame_count, 1, 0, VPX_DL_BEST_QUALITY, 213b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian &stats); 214b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } else { 215b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("\n"); 216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 218b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fclose(infile); 219b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Pass %d complete. Processed %d frames.\n", pass + 1, frame_count); 220b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_destroy(&codec)) 221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to destroy codec."); 222b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 223b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 224b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_img_free(&raw); 225b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian free(stats.buf); 226b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 227b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_video_writer_close(writer); 228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 229b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return EXIT_SUCCESS; 230b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 231