11b362b15af34006e6a11974088a46d42b903418eJohann/* 21b362b15af34006e6a11974088a46d42b903418eJohann * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 31b362b15af34006e6a11974088a46d42b903418eJohann * 41b362b15af34006e6a11974088a46d42b903418eJohann * Use of this source code is governed by a BSD-style license 51b362b15af34006e6a11974088a46d42b903418eJohann * that can be found in the LICENSE file in the root of the source 61b362b15af34006e6a11974088a46d42b903418eJohann * tree. An additional intellectual property rights grant can be found 71b362b15af34006e6a11974088a46d42b903418eJohann * in the file PATENTS. All contributing project authors may 81b362b15af34006e6a11974088a46d42b903418eJohann * be found in the AUTHORS file in the root of the source tree. 91b362b15af34006e6a11974088a46d42b903418eJohann */ 101b362b15af34006e6a11974088a46d42b903418eJohann 111b362b15af34006e6a11974088a46d42b903418eJohann/* 121b362b15af34006e6a11974088a46d42b903418eJohann * This is an example demonstrating multi-resolution encoding in VP8. 131b362b15af34006e6a11974088a46d42b903418eJohann * High-resolution input video is down-sampled to lower-resolutions. The 141b362b15af34006e6a11974088a46d42b903418eJohann * encoder then encodes the video and outputs multiple bitstreams with 151b362b15af34006e6a11974088a46d42b903418eJohann * different resolutions. 161b362b15af34006e6a11974088a46d42b903418eJohann */ 171b362b15af34006e6a11974088a46d42b903418eJohann#include <stdio.h> 181b362b15af34006e6a11974088a46d42b903418eJohann#include <stdlib.h> 191b362b15af34006e6a11974088a46d42b903418eJohann#include <stdarg.h> 201b362b15af34006e6a11974088a46d42b903418eJohann#include <string.h> 21b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <math.h> 221b362b15af34006e6a11974088a46d42b903418eJohann#define VPX_CODEC_DISABLE_COMPAT 1 231b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx/vpx_encoder.h" 241b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx/vp8cx.h" 251b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_ports/mem_ops.h" 26b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./tools_common.h" 271b362b15af34006e6a11974088a46d42b903418eJohann#define interface (vpx_codec_vp8_cx()) 281b362b15af34006e6a11974088a46d42b903418eJohann#define fourcc 0x30385056 291b362b15af34006e6a11974088a46d42b903418eJohann 301b362b15af34006e6a11974088a46d42b903418eJohann#define IVF_FILE_HDR_SZ (32) 311b362b15af34006e6a11974088a46d42b903418eJohann#define IVF_FRAME_HDR_SZ (12) 321b362b15af34006e6a11974088a46d42b903418eJohann 331b362b15af34006e6a11974088a46d42b903418eJohann/* 341b362b15af34006e6a11974088a46d42b903418eJohann * The input video frame is downsampled several times to generate a multi-level 351b362b15af34006e6a11974088a46d42b903418eJohann * hierarchical structure. NUM_ENCODERS is defined as the number of encoding 361b362b15af34006e6a11974088a46d42b903418eJohann * levels required. For example, if the size of input video is 1280x720, 371b362b15af34006e6a11974088a46d42b903418eJohann * NUM_ENCODERS is 3, and down-sampling factor is 2, the encoder outputs 3 381b362b15af34006e6a11974088a46d42b903418eJohann * bitstreams with resolution of 1280x720(level 0), 640x360(level 1), and 391b362b15af34006e6a11974088a46d42b903418eJohann * 320x180(level 2) respectively. 401b362b15af34006e6a11974088a46d42b903418eJohann */ 411b362b15af34006e6a11974088a46d42b903418eJohann#define NUM_ENCODERS 3 421b362b15af34006e6a11974088a46d42b903418eJohann 431b362b15af34006e6a11974088a46d42b903418eJohann/* This example uses the scaler function in libyuv. */ 441b362b15af34006e6a11974088a46d42b903418eJohann#include "third_party/libyuv/include/libyuv/basic_types.h" 451b362b15af34006e6a11974088a46d42b903418eJohann#include "third_party/libyuv/include/libyuv/scale.h" 461b362b15af34006e6a11974088a46d42b903418eJohann#include "third_party/libyuv/include/libyuv/cpu_id.h" 471b362b15af34006e6a11974088a46d42b903418eJohann 481b362b15af34006e6a11974088a46d42b903418eJohannstatic void die(const char *fmt, ...) { 491b362b15af34006e6a11974088a46d42b903418eJohann va_list ap; 501b362b15af34006e6a11974088a46d42b903418eJohann 511b362b15af34006e6a11974088a46d42b903418eJohann va_start(ap, fmt); 521b362b15af34006e6a11974088a46d42b903418eJohann vprintf(fmt, ap); 531b362b15af34006e6a11974088a46d42b903418eJohann if(fmt[strlen(fmt)-1] != '\n') 541b362b15af34006e6a11974088a46d42b903418eJohann printf("\n"); 551b362b15af34006e6a11974088a46d42b903418eJohann exit(EXIT_FAILURE); 561b362b15af34006e6a11974088a46d42b903418eJohann} 571b362b15af34006e6a11974088a46d42b903418eJohann 581b362b15af34006e6a11974088a46d42b903418eJohannstatic void die_codec(vpx_codec_ctx_t *ctx, const char *s) { 591b362b15af34006e6a11974088a46d42b903418eJohann const char *detail = vpx_codec_error_detail(ctx); 601b362b15af34006e6a11974088a46d42b903418eJohann 611b362b15af34006e6a11974088a46d42b903418eJohann printf("%s: %s\n", s, vpx_codec_error(ctx)); 621b362b15af34006e6a11974088a46d42b903418eJohann if(detail) 631b362b15af34006e6a11974088a46d42b903418eJohann printf(" %s\n",detail); 641b362b15af34006e6a11974088a46d42b903418eJohann exit(EXIT_FAILURE); 651b362b15af34006e6a11974088a46d42b903418eJohann} 661b362b15af34006e6a11974088a46d42b903418eJohann 671b362b15af34006e6a11974088a46d42b903418eJohannint (*read_frame_p)(FILE *f, vpx_image_t *img); 681b362b15af34006e6a11974088a46d42b903418eJohann 691b362b15af34006e6a11974088a46d42b903418eJohannstatic int read_frame(FILE *f, vpx_image_t *img) { 701b362b15af34006e6a11974088a46d42b903418eJohann size_t nbytes, to_read; 711b362b15af34006e6a11974088a46d42b903418eJohann int res = 1; 721b362b15af34006e6a11974088a46d42b903418eJohann 731b362b15af34006e6a11974088a46d42b903418eJohann to_read = img->w*img->h*3/2; 741b362b15af34006e6a11974088a46d42b903418eJohann nbytes = fread(img->planes[0], 1, to_read, f); 751b362b15af34006e6a11974088a46d42b903418eJohann if(nbytes != to_read) { 761b362b15af34006e6a11974088a46d42b903418eJohann res = 0; 771b362b15af34006e6a11974088a46d42b903418eJohann if(nbytes > 0) 781b362b15af34006e6a11974088a46d42b903418eJohann printf("Warning: Read partial frame. Check your width & height!\n"); 791b362b15af34006e6a11974088a46d42b903418eJohann } 801b362b15af34006e6a11974088a46d42b903418eJohann return res; 811b362b15af34006e6a11974088a46d42b903418eJohann} 821b362b15af34006e6a11974088a46d42b903418eJohann 831b362b15af34006e6a11974088a46d42b903418eJohannstatic int read_frame_by_row(FILE *f, vpx_image_t *img) { 841b362b15af34006e6a11974088a46d42b903418eJohann size_t nbytes, to_read; 851b362b15af34006e6a11974088a46d42b903418eJohann int res = 1; 861b362b15af34006e6a11974088a46d42b903418eJohann int plane; 871b362b15af34006e6a11974088a46d42b903418eJohann 881b362b15af34006e6a11974088a46d42b903418eJohann for (plane = 0; plane < 3; plane++) 891b362b15af34006e6a11974088a46d42b903418eJohann { 901b362b15af34006e6a11974088a46d42b903418eJohann unsigned char *ptr; 911b362b15af34006e6a11974088a46d42b903418eJohann int w = (plane ? (1 + img->d_w) / 2 : img->d_w); 921b362b15af34006e6a11974088a46d42b903418eJohann int h = (plane ? (1 + img->d_h) / 2 : img->d_h); 931b362b15af34006e6a11974088a46d42b903418eJohann int r; 941b362b15af34006e6a11974088a46d42b903418eJohann 951b362b15af34006e6a11974088a46d42b903418eJohann /* Determine the correct plane based on the image format. The for-loop 961b362b15af34006e6a11974088a46d42b903418eJohann * always counts in Y,U,V order, but this may not match the order of 971b362b15af34006e6a11974088a46d42b903418eJohann * the data on disk. 981b362b15af34006e6a11974088a46d42b903418eJohann */ 991b362b15af34006e6a11974088a46d42b903418eJohann switch (plane) 1001b362b15af34006e6a11974088a46d42b903418eJohann { 1011b362b15af34006e6a11974088a46d42b903418eJohann case 1: 1021b362b15af34006e6a11974088a46d42b903418eJohann ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12? VPX_PLANE_V : VPX_PLANE_U]; 1031b362b15af34006e6a11974088a46d42b903418eJohann break; 1041b362b15af34006e6a11974088a46d42b903418eJohann case 2: 1051b362b15af34006e6a11974088a46d42b903418eJohann ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12?VPX_PLANE_U : VPX_PLANE_V]; 1061b362b15af34006e6a11974088a46d42b903418eJohann break; 1071b362b15af34006e6a11974088a46d42b903418eJohann default: 1081b362b15af34006e6a11974088a46d42b903418eJohann ptr = img->planes[plane]; 1091b362b15af34006e6a11974088a46d42b903418eJohann } 1101b362b15af34006e6a11974088a46d42b903418eJohann 1111b362b15af34006e6a11974088a46d42b903418eJohann for (r = 0; r < h; r++) 1121b362b15af34006e6a11974088a46d42b903418eJohann { 1131b362b15af34006e6a11974088a46d42b903418eJohann to_read = w; 1141b362b15af34006e6a11974088a46d42b903418eJohann 1151b362b15af34006e6a11974088a46d42b903418eJohann nbytes = fread(ptr, 1, to_read, f); 1161b362b15af34006e6a11974088a46d42b903418eJohann if(nbytes != to_read) { 1171b362b15af34006e6a11974088a46d42b903418eJohann res = 0; 1181b362b15af34006e6a11974088a46d42b903418eJohann if(nbytes > 0) 1191b362b15af34006e6a11974088a46d42b903418eJohann printf("Warning: Read partial frame. Check your width & height!\n"); 1201b362b15af34006e6a11974088a46d42b903418eJohann break; 1211b362b15af34006e6a11974088a46d42b903418eJohann } 1221b362b15af34006e6a11974088a46d42b903418eJohann 1231b362b15af34006e6a11974088a46d42b903418eJohann ptr += img->stride[plane]; 1241b362b15af34006e6a11974088a46d42b903418eJohann } 1251b362b15af34006e6a11974088a46d42b903418eJohann if (!res) 1261b362b15af34006e6a11974088a46d42b903418eJohann break; 1271b362b15af34006e6a11974088a46d42b903418eJohann } 1281b362b15af34006e6a11974088a46d42b903418eJohann 1291b362b15af34006e6a11974088a46d42b903418eJohann return res; 1301b362b15af34006e6a11974088a46d42b903418eJohann} 1311b362b15af34006e6a11974088a46d42b903418eJohann 1321b362b15af34006e6a11974088a46d42b903418eJohannstatic void write_ivf_file_header(FILE *outfile, 1331b362b15af34006e6a11974088a46d42b903418eJohann const vpx_codec_enc_cfg_t *cfg, 1341b362b15af34006e6a11974088a46d42b903418eJohann int frame_cnt) { 1351b362b15af34006e6a11974088a46d42b903418eJohann char header[32]; 1361b362b15af34006e6a11974088a46d42b903418eJohann 1371b362b15af34006e6a11974088a46d42b903418eJohann if(cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS) 1381b362b15af34006e6a11974088a46d42b903418eJohann return; 1391b362b15af34006e6a11974088a46d42b903418eJohann header[0] = 'D'; 1401b362b15af34006e6a11974088a46d42b903418eJohann header[1] = 'K'; 1411b362b15af34006e6a11974088a46d42b903418eJohann header[2] = 'I'; 1421b362b15af34006e6a11974088a46d42b903418eJohann header[3] = 'F'; 1431b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le16(header+4, 0); /* version */ 1441b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le16(header+6, 32); /* headersize */ 1451b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le32(header+8, fourcc); /* headersize */ 1461b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le16(header+12, cfg->g_w); /* width */ 1471b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le16(header+14, cfg->g_h); /* height */ 1481b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le32(header+16, cfg->g_timebase.den); /* rate */ 1491b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le32(header+20, cfg->g_timebase.num); /* scale */ 1501b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le32(header+24, frame_cnt); /* length */ 1511b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le32(header+28, 0); /* unused */ 1521b362b15af34006e6a11974088a46d42b903418eJohann 1531b362b15af34006e6a11974088a46d42b903418eJohann (void) fwrite(header, 1, 32, outfile); 1541b362b15af34006e6a11974088a46d42b903418eJohann} 1551b362b15af34006e6a11974088a46d42b903418eJohann 1561b362b15af34006e6a11974088a46d42b903418eJohannstatic void write_ivf_frame_header(FILE *outfile, 1571b362b15af34006e6a11974088a46d42b903418eJohann const vpx_codec_cx_pkt_t *pkt) 1581b362b15af34006e6a11974088a46d42b903418eJohann{ 1591b362b15af34006e6a11974088a46d42b903418eJohann char header[12]; 1601b362b15af34006e6a11974088a46d42b903418eJohann vpx_codec_pts_t pts; 1611b362b15af34006e6a11974088a46d42b903418eJohann 1621b362b15af34006e6a11974088a46d42b903418eJohann if(pkt->kind != VPX_CODEC_CX_FRAME_PKT) 1631b362b15af34006e6a11974088a46d42b903418eJohann return; 1641b362b15af34006e6a11974088a46d42b903418eJohann 1651b362b15af34006e6a11974088a46d42b903418eJohann pts = pkt->data.frame.pts; 1661b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le32(header, pkt->data.frame.sz); 1671b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le32(header+4, pts&0xFFFFFFFF); 1681b362b15af34006e6a11974088a46d42b903418eJohann mem_put_le32(header+8, pts >> 32); 1691b362b15af34006e6a11974088a46d42b903418eJohann 1701b362b15af34006e6a11974088a46d42b903418eJohann (void) fwrite(header, 1, 12, outfile); 1711b362b15af34006e6a11974088a46d42b903418eJohann} 1721b362b15af34006e6a11974088a46d42b903418eJohann 1731b362b15af34006e6a11974088a46d42b903418eJohannint main(int argc, char **argv) 1741b362b15af34006e6a11974088a46d42b903418eJohann{ 1751b362b15af34006e6a11974088a46d42b903418eJohann FILE *infile, *outfile[NUM_ENCODERS]; 1761b362b15af34006e6a11974088a46d42b903418eJohann vpx_codec_ctx_t codec[NUM_ENCODERS]; 1771b362b15af34006e6a11974088a46d42b903418eJohann vpx_codec_enc_cfg_t cfg[NUM_ENCODERS]; 1781b362b15af34006e6a11974088a46d42b903418eJohann vpx_codec_pts_t frame_cnt = 0; 1791b362b15af34006e6a11974088a46d42b903418eJohann vpx_image_t raw[NUM_ENCODERS]; 1801b362b15af34006e6a11974088a46d42b903418eJohann vpx_codec_err_t res[NUM_ENCODERS]; 1811b362b15af34006e6a11974088a46d42b903418eJohann 1821b362b15af34006e6a11974088a46d42b903418eJohann int i; 1831b362b15af34006e6a11974088a46d42b903418eJohann long width; 1841b362b15af34006e6a11974088a46d42b903418eJohann long height; 1851b362b15af34006e6a11974088a46d42b903418eJohann int frame_avail; 1861b362b15af34006e6a11974088a46d42b903418eJohann int got_data; 1871b362b15af34006e6a11974088a46d42b903418eJohann int flags = 0; 1881b362b15af34006e6a11974088a46d42b903418eJohann 1891b362b15af34006e6a11974088a46d42b903418eJohann /*Currently, only realtime mode is supported in multi-resolution encoding.*/ 1901b362b15af34006e6a11974088a46d42b903418eJohann int arg_deadline = VPX_DL_REALTIME; 1911b362b15af34006e6a11974088a46d42b903418eJohann 1921b362b15af34006e6a11974088a46d42b903418eJohann /* Set show_psnr to 1/0 to show/not show PSNR. Choose show_psnr=0 if you 1931b362b15af34006e6a11974088a46d42b903418eJohann don't need to know PSNR, which will skip PSNR calculation and save 1941b362b15af34006e6a11974088a46d42b903418eJohann encoding time. */ 1951b362b15af34006e6a11974088a46d42b903418eJohann int show_psnr = 0; 1961b362b15af34006e6a11974088a46d42b903418eJohann uint64_t psnr_sse_total[NUM_ENCODERS] = {0}; 1971b362b15af34006e6a11974088a46d42b903418eJohann uint64_t psnr_samples_total[NUM_ENCODERS] = {0}; 1981b362b15af34006e6a11974088a46d42b903418eJohann double psnr_totals[NUM_ENCODERS][4] = {{0,0}}; 1991b362b15af34006e6a11974088a46d42b903418eJohann int psnr_count[NUM_ENCODERS] = {0}; 2001b362b15af34006e6a11974088a46d42b903418eJohann 2011b362b15af34006e6a11974088a46d42b903418eJohann /* Set the required target bitrates for each resolution level. 2021b362b15af34006e6a11974088a46d42b903418eJohann * If target bitrate for highest-resolution level is set to 0, 2031b362b15af34006e6a11974088a46d42b903418eJohann * (i.e. target_bitrate[0]=0), we skip encoding at that level. 2041b362b15af34006e6a11974088a46d42b903418eJohann */ 205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int target_bitrate[NUM_ENCODERS]={1000, 500, 100}; 2061b362b15af34006e6a11974088a46d42b903418eJohann /* Enter the frame rate of the input video */ 2071b362b15af34006e6a11974088a46d42b903418eJohann int framerate = 30; 2081b362b15af34006e6a11974088a46d42b903418eJohann /* Set down-sampling factor for each resolution level. 2091b362b15af34006e6a11974088a46d42b903418eJohann dsf[0] controls down sampling from level 0 to level 1; 2101b362b15af34006e6a11974088a46d42b903418eJohann dsf[1] controls down sampling from level 1 to level 2; 2111b362b15af34006e6a11974088a46d42b903418eJohann dsf[2] is not used. */ 2121b362b15af34006e6a11974088a46d42b903418eJohann vpx_rational_t dsf[NUM_ENCODERS] = {{2, 1}, {2, 1}, {1, 1}}; 2131b362b15af34006e6a11974088a46d42b903418eJohann 2141b362b15af34006e6a11974088a46d42b903418eJohann if(argc!= (5+NUM_ENCODERS)) 2151b362b15af34006e6a11974088a46d42b903418eJohann die("Usage: %s <width> <height> <infile> <outfile(s)> <output psnr?>\n", 2161b362b15af34006e6a11974088a46d42b903418eJohann argv[0]); 2171b362b15af34006e6a11974088a46d42b903418eJohann 2181b362b15af34006e6a11974088a46d42b903418eJohann printf("Using %s\n",vpx_codec_iface_name(interface)); 2191b362b15af34006e6a11974088a46d42b903418eJohann 2201b362b15af34006e6a11974088a46d42b903418eJohann width = strtol(argv[1], NULL, 0); 2211b362b15af34006e6a11974088a46d42b903418eJohann height = strtol(argv[2], NULL, 0); 2221b362b15af34006e6a11974088a46d42b903418eJohann 2231b362b15af34006e6a11974088a46d42b903418eJohann if(width < 16 || width%2 || height <16 || height%2) 2241b362b15af34006e6a11974088a46d42b903418eJohann die("Invalid resolution: %ldx%ld", width, height); 2251b362b15af34006e6a11974088a46d42b903418eJohann 2261b362b15af34006e6a11974088a46d42b903418eJohann /* Open input video file for encoding */ 2271b362b15af34006e6a11974088a46d42b903418eJohann if(!(infile = fopen(argv[3], "rb"))) 2281b362b15af34006e6a11974088a46d42b903418eJohann die("Failed to open %s for reading", argv[3]); 2291b362b15af34006e6a11974088a46d42b903418eJohann 2301b362b15af34006e6a11974088a46d42b903418eJohann /* Open output file for each encoder to output bitstreams */ 2311b362b15af34006e6a11974088a46d42b903418eJohann for (i=0; i< NUM_ENCODERS; i++) 2321b362b15af34006e6a11974088a46d42b903418eJohann { 2331b362b15af34006e6a11974088a46d42b903418eJohann if(!target_bitrate[i]) 2341b362b15af34006e6a11974088a46d42b903418eJohann { 2351b362b15af34006e6a11974088a46d42b903418eJohann outfile[i] = NULL; 2361b362b15af34006e6a11974088a46d42b903418eJohann continue; 2371b362b15af34006e6a11974088a46d42b903418eJohann } 2381b362b15af34006e6a11974088a46d42b903418eJohann 2391b362b15af34006e6a11974088a46d42b903418eJohann if(!(outfile[i] = fopen(argv[i+4], "wb"))) 2401b362b15af34006e6a11974088a46d42b903418eJohann die("Failed to open %s for writing", argv[i+4]); 2411b362b15af34006e6a11974088a46d42b903418eJohann } 2421b362b15af34006e6a11974088a46d42b903418eJohann 2431b362b15af34006e6a11974088a46d42b903418eJohann show_psnr = strtol(argv[NUM_ENCODERS + 4], NULL, 0); 2441b362b15af34006e6a11974088a46d42b903418eJohann 2451b362b15af34006e6a11974088a46d42b903418eJohann /* Populate default encoder configuration */ 2461b362b15af34006e6a11974088a46d42b903418eJohann for (i=0; i< NUM_ENCODERS; i++) 2471b362b15af34006e6a11974088a46d42b903418eJohann { 2481b362b15af34006e6a11974088a46d42b903418eJohann res[i] = vpx_codec_enc_config_default(interface, &cfg[i], 0); 2491b362b15af34006e6a11974088a46d42b903418eJohann if(res[i]) { 2501b362b15af34006e6a11974088a46d42b903418eJohann printf("Failed to get config: %s\n", vpx_codec_err_to_string(res[i])); 2511b362b15af34006e6a11974088a46d42b903418eJohann return EXIT_FAILURE; 2521b362b15af34006e6a11974088a46d42b903418eJohann } 2531b362b15af34006e6a11974088a46d42b903418eJohann } 2541b362b15af34006e6a11974088a46d42b903418eJohann 2551b362b15af34006e6a11974088a46d42b903418eJohann /* 2561b362b15af34006e6a11974088a46d42b903418eJohann * Update the default configuration according to needs of the application. 2571b362b15af34006e6a11974088a46d42b903418eJohann */ 2581b362b15af34006e6a11974088a46d42b903418eJohann /* Highest-resolution encoder settings */ 2591b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].g_w = width; 2601b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].g_h = height; 2611b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].g_threads = 1; /* number of threads used */ 2621b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_dropframe_thresh = 30; 2631b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_end_usage = VPX_CBR; 2641b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_resize_allowed = 0; 2651b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_min_quantizer = 4; 2661b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_max_quantizer = 56; 2671b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_undershoot_pct = 98; 2681b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_overshoot_pct = 100; 2691b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_buf_initial_sz = 500; 2701b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_buf_optimal_sz = 600; 2711b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_buf_sz = 1000; 2721b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].g_error_resilient = 1; /* Enable error resilient mode */ 2731b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].g_lag_in_frames = 0; 2741b362b15af34006e6a11974088a46d42b903418eJohann 2751b362b15af34006e6a11974088a46d42b903418eJohann /* Disable automatic keyframe placement */ 2761b362b15af34006e6a11974088a46d42b903418eJohann /* Note: These 3 settings are copied to all levels. But, except the lowest 2771b362b15af34006e6a11974088a46d42b903418eJohann * resolution level, all other levels are set to VPX_KF_DISABLED internally. 2781b362b15af34006e6a11974088a46d42b903418eJohann */ 2791b362b15af34006e6a11974088a46d42b903418eJohann //cfg[0].kf_mode = VPX_KF_DISABLED; 2801b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].kf_mode = VPX_KF_AUTO; 2811b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].kf_min_dist = 3000; 2821b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].kf_max_dist = 3000; 2831b362b15af34006e6a11974088a46d42b903418eJohann 2841b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].rc_target_bitrate = target_bitrate[0]; /* Set target bitrate */ 2851b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].g_timebase.num = 1; /* Set fps */ 2861b362b15af34006e6a11974088a46d42b903418eJohann cfg[0].g_timebase.den = framerate; 2871b362b15af34006e6a11974088a46d42b903418eJohann 2881b362b15af34006e6a11974088a46d42b903418eJohann /* Other-resolution encoder settings */ 2891b362b15af34006e6a11974088a46d42b903418eJohann for (i=1; i< NUM_ENCODERS; i++) 2901b362b15af34006e6a11974088a46d42b903418eJohann { 2911b362b15af34006e6a11974088a46d42b903418eJohann memcpy(&cfg[i], &cfg[0], sizeof(vpx_codec_enc_cfg_t)); 2921b362b15af34006e6a11974088a46d42b903418eJohann 2931b362b15af34006e6a11974088a46d42b903418eJohann cfg[i].g_threads = 1; /* number of threads used */ 2941b362b15af34006e6a11974088a46d42b903418eJohann cfg[i].rc_target_bitrate = target_bitrate[i]; 2951b362b15af34006e6a11974088a46d42b903418eJohann 2961b362b15af34006e6a11974088a46d42b903418eJohann /* Note: Width & height of other-resolution encoders are calculated 2971b362b15af34006e6a11974088a46d42b903418eJohann * from the highest-resolution encoder's size and the corresponding 2981b362b15af34006e6a11974088a46d42b903418eJohann * down_sampling_factor. 2991b362b15af34006e6a11974088a46d42b903418eJohann */ 3001b362b15af34006e6a11974088a46d42b903418eJohann { 3011b362b15af34006e6a11974088a46d42b903418eJohann unsigned int iw = cfg[i-1].g_w*dsf[i-1].den + dsf[i-1].num - 1; 3021b362b15af34006e6a11974088a46d42b903418eJohann unsigned int ih = cfg[i-1].g_h*dsf[i-1].den + dsf[i-1].num - 1; 3031b362b15af34006e6a11974088a46d42b903418eJohann cfg[i].g_w = iw/dsf[i-1].num; 3041b362b15af34006e6a11974088a46d42b903418eJohann cfg[i].g_h = ih/dsf[i-1].num; 3051b362b15af34006e6a11974088a46d42b903418eJohann } 3061b362b15af34006e6a11974088a46d42b903418eJohann 3071b362b15af34006e6a11974088a46d42b903418eJohann /* Make width & height to be multiplier of 2. */ 3081b362b15af34006e6a11974088a46d42b903418eJohann // Should support odd size ??? 3091b362b15af34006e6a11974088a46d42b903418eJohann if((cfg[i].g_w)%2)cfg[i].g_w++; 3101b362b15af34006e6a11974088a46d42b903418eJohann if((cfg[i].g_h)%2)cfg[i].g_h++; 3111b362b15af34006e6a11974088a46d42b903418eJohann } 3121b362b15af34006e6a11974088a46d42b903418eJohann 3131b362b15af34006e6a11974088a46d42b903418eJohann /* Allocate image for each encoder */ 3141b362b15af34006e6a11974088a46d42b903418eJohann for (i=0; i< NUM_ENCODERS; i++) 3151b362b15af34006e6a11974088a46d42b903418eJohann if(!vpx_img_alloc(&raw[i], VPX_IMG_FMT_I420, cfg[i].g_w, cfg[i].g_h, 32)) 3161b362b15af34006e6a11974088a46d42b903418eJohann die("Failed to allocate image", cfg[i].g_w, cfg[i].g_h); 3171b362b15af34006e6a11974088a46d42b903418eJohann 3181b362b15af34006e6a11974088a46d42b903418eJohann if (raw[0].stride[VPX_PLANE_Y] == raw[0].d_w) 3191b362b15af34006e6a11974088a46d42b903418eJohann read_frame_p = read_frame; 3201b362b15af34006e6a11974088a46d42b903418eJohann else 3211b362b15af34006e6a11974088a46d42b903418eJohann read_frame_p = read_frame_by_row; 3221b362b15af34006e6a11974088a46d42b903418eJohann 3231b362b15af34006e6a11974088a46d42b903418eJohann for (i=0; i< NUM_ENCODERS; i++) 3241b362b15af34006e6a11974088a46d42b903418eJohann if(outfile[i]) 3251b362b15af34006e6a11974088a46d42b903418eJohann write_ivf_file_header(outfile[i], &cfg[i], 0); 3261b362b15af34006e6a11974088a46d42b903418eJohann 3271b362b15af34006e6a11974088a46d42b903418eJohann /* Initialize multi-encoder */ 3281b362b15af34006e6a11974088a46d42b903418eJohann if(vpx_codec_enc_init_multi(&codec[0], interface, &cfg[0], NUM_ENCODERS, 3291b362b15af34006e6a11974088a46d42b903418eJohann (show_psnr ? VPX_CODEC_USE_PSNR : 0), &dsf[0])) 3301b362b15af34006e6a11974088a46d42b903418eJohann die_codec(&codec[0], "Failed to initialize encoder"); 3311b362b15af34006e6a11974088a46d42b903418eJohann 3321b362b15af34006e6a11974088a46d42b903418eJohann /* The extra encoding configuration parameters can be set as follows. */ 3331b362b15af34006e6a11974088a46d42b903418eJohann /* Set encoding speed */ 3341b362b15af34006e6a11974088a46d42b903418eJohann for ( i=0; i<NUM_ENCODERS; i++) 3351b362b15af34006e6a11974088a46d42b903418eJohann { 3361b362b15af34006e6a11974088a46d42b903418eJohann int speed = -6; 3371b362b15af34006e6a11974088a46d42b903418eJohann if(vpx_codec_control(&codec[i], VP8E_SET_CPUUSED, speed)) 3381b362b15af34006e6a11974088a46d42b903418eJohann die_codec(&codec[i], "Failed to set cpu_used"); 3391b362b15af34006e6a11974088a46d42b903418eJohann } 340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Set static threshold. */ 342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for ( i=0; i<NUM_ENCODERS; i++) 3431b362b15af34006e6a11974088a46d42b903418eJohann { 344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int static_thresh = 1; 3451b362b15af34006e6a11974088a46d42b903418eJohann if(vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, static_thresh)) 3461b362b15af34006e6a11974088a46d42b903418eJohann die_codec(&codec[i], "Failed to set static threshold"); 3471b362b15af34006e6a11974088a46d42b903418eJohann } 348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3491b362b15af34006e6a11974088a46d42b903418eJohann /* Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING */ 350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Enable denoising for the highest-resolution encoder. */ 351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if(vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 1)) 352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang die_codec(&codec[0], "Failed to set noise_sensitivity"); 353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for ( i=1; i< NUM_ENCODERS; i++) 3541b362b15af34006e6a11974088a46d42b903418eJohann { 3551b362b15af34006e6a11974088a46d42b903418eJohann if(vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0)) 3561b362b15af34006e6a11974088a46d42b903418eJohann die_codec(&codec[i], "Failed to set noise_sensitivity"); 3571b362b15af34006e6a11974088a46d42b903418eJohann } 3581b362b15af34006e6a11974088a46d42b903418eJohann 359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3601b362b15af34006e6a11974088a46d42b903418eJohann frame_avail = 1; 3611b362b15af34006e6a11974088a46d42b903418eJohann got_data = 0; 3621b362b15af34006e6a11974088a46d42b903418eJohann 3631b362b15af34006e6a11974088a46d42b903418eJohann while(frame_avail || got_data) 3641b362b15af34006e6a11974088a46d42b903418eJohann { 3651b362b15af34006e6a11974088a46d42b903418eJohann vpx_codec_iter_t iter[NUM_ENCODERS]={NULL}; 3661b362b15af34006e6a11974088a46d42b903418eJohann const vpx_codec_cx_pkt_t *pkt[NUM_ENCODERS]; 3671b362b15af34006e6a11974088a46d42b903418eJohann 3681b362b15af34006e6a11974088a46d42b903418eJohann flags = 0; 3691b362b15af34006e6a11974088a46d42b903418eJohann frame_avail = read_frame_p(infile, &raw[0]); 3701b362b15af34006e6a11974088a46d42b903418eJohann 3711b362b15af34006e6a11974088a46d42b903418eJohann if(frame_avail) 3721b362b15af34006e6a11974088a46d42b903418eJohann { 3731b362b15af34006e6a11974088a46d42b903418eJohann for ( i=1; i<NUM_ENCODERS; i++) 3741b362b15af34006e6a11974088a46d42b903418eJohann { 3751b362b15af34006e6a11974088a46d42b903418eJohann /*Scale the image down a number of times by downsampling factor*/ 3761b362b15af34006e6a11974088a46d42b903418eJohann /* FilterMode 1 or 2 give better psnr than FilterMode 0. */ 3771b362b15af34006e6a11974088a46d42b903418eJohann I420Scale(raw[i-1].planes[VPX_PLANE_Y], raw[i-1].stride[VPX_PLANE_Y], 3781b362b15af34006e6a11974088a46d42b903418eJohann raw[i-1].planes[VPX_PLANE_U], raw[i-1].stride[VPX_PLANE_U], 3791b362b15af34006e6a11974088a46d42b903418eJohann raw[i-1].planes[VPX_PLANE_V], raw[i-1].stride[VPX_PLANE_V], 3801b362b15af34006e6a11974088a46d42b903418eJohann raw[i-1].d_w, raw[i-1].d_h, 3811b362b15af34006e6a11974088a46d42b903418eJohann raw[i].planes[VPX_PLANE_Y], raw[i].stride[VPX_PLANE_Y], 3821b362b15af34006e6a11974088a46d42b903418eJohann raw[i].planes[VPX_PLANE_U], raw[i].stride[VPX_PLANE_U], 3831b362b15af34006e6a11974088a46d42b903418eJohann raw[i].planes[VPX_PLANE_V], raw[i].stride[VPX_PLANE_V], 3841b362b15af34006e6a11974088a46d42b903418eJohann raw[i].d_w, raw[i].d_h, 1); 3851b362b15af34006e6a11974088a46d42b903418eJohann } 3861b362b15af34006e6a11974088a46d42b903418eJohann } 3871b362b15af34006e6a11974088a46d42b903418eJohann 3881b362b15af34006e6a11974088a46d42b903418eJohann /* Encode each frame at multi-levels */ 3891b362b15af34006e6a11974088a46d42b903418eJohann if(vpx_codec_encode(&codec[0], frame_avail? &raw[0] : NULL, 3901b362b15af34006e6a11974088a46d42b903418eJohann frame_cnt, 1, flags, arg_deadline)) 3911b362b15af34006e6a11974088a46d42b903418eJohann die_codec(&codec[0], "Failed to encode frame"); 3921b362b15af34006e6a11974088a46d42b903418eJohann 3931b362b15af34006e6a11974088a46d42b903418eJohann for (i=NUM_ENCODERS-1; i>=0 ; i--) 3941b362b15af34006e6a11974088a46d42b903418eJohann { 3951b362b15af34006e6a11974088a46d42b903418eJohann got_data = 0; 3961b362b15af34006e6a11974088a46d42b903418eJohann 3971b362b15af34006e6a11974088a46d42b903418eJohann while( (pkt[i] = vpx_codec_get_cx_data(&codec[i], &iter[i])) ) 3981b362b15af34006e6a11974088a46d42b903418eJohann { 3991b362b15af34006e6a11974088a46d42b903418eJohann got_data = 1; 4001b362b15af34006e6a11974088a46d42b903418eJohann switch(pkt[i]->kind) { 4011b362b15af34006e6a11974088a46d42b903418eJohann case VPX_CODEC_CX_FRAME_PKT: 4021b362b15af34006e6a11974088a46d42b903418eJohann write_ivf_frame_header(outfile[i], pkt[i]); 4031b362b15af34006e6a11974088a46d42b903418eJohann (void) fwrite(pkt[i]->data.frame.buf, 1, 4041b362b15af34006e6a11974088a46d42b903418eJohann pkt[i]->data.frame.sz, outfile[i]); 4051b362b15af34006e6a11974088a46d42b903418eJohann break; 4061b362b15af34006e6a11974088a46d42b903418eJohann case VPX_CODEC_PSNR_PKT: 4071b362b15af34006e6a11974088a46d42b903418eJohann if (show_psnr) 4081b362b15af34006e6a11974088a46d42b903418eJohann { 4091b362b15af34006e6a11974088a46d42b903418eJohann int j; 4101b362b15af34006e6a11974088a46d42b903418eJohann 4111b362b15af34006e6a11974088a46d42b903418eJohann psnr_sse_total[i] += pkt[i]->data.psnr.sse[0]; 4121b362b15af34006e6a11974088a46d42b903418eJohann psnr_samples_total[i] += pkt[i]->data.psnr.samples[0]; 4131b362b15af34006e6a11974088a46d42b903418eJohann for (j = 0; j < 4; j++) 4141b362b15af34006e6a11974088a46d42b903418eJohann { 4151b362b15af34006e6a11974088a46d42b903418eJohann //fprintf(stderr, "%.3lf ", pkt[i]->data.psnr.psnr[j]); 4161b362b15af34006e6a11974088a46d42b903418eJohann psnr_totals[i][j] += pkt[i]->data.psnr.psnr[j]; 4171b362b15af34006e6a11974088a46d42b903418eJohann } 4181b362b15af34006e6a11974088a46d42b903418eJohann psnr_count[i]++; 4191b362b15af34006e6a11974088a46d42b903418eJohann } 4201b362b15af34006e6a11974088a46d42b903418eJohann 4211b362b15af34006e6a11974088a46d42b903418eJohann break; 4221b362b15af34006e6a11974088a46d42b903418eJohann default: 4231b362b15af34006e6a11974088a46d42b903418eJohann break; 4241b362b15af34006e6a11974088a46d42b903418eJohann } 4251b362b15af34006e6a11974088a46d42b903418eJohann printf(pkt[i]->kind == VPX_CODEC_CX_FRAME_PKT 4261b362b15af34006e6a11974088a46d42b903418eJohann && (pkt[i]->data.frame.flags & VPX_FRAME_IS_KEY)? "K":"."); 4271b362b15af34006e6a11974088a46d42b903418eJohann fflush(stdout); 4281b362b15af34006e6a11974088a46d42b903418eJohann } 4291b362b15af34006e6a11974088a46d42b903418eJohann } 4301b362b15af34006e6a11974088a46d42b903418eJohann frame_cnt++; 4311b362b15af34006e6a11974088a46d42b903418eJohann } 4321b362b15af34006e6a11974088a46d42b903418eJohann printf("\n"); 4331b362b15af34006e6a11974088a46d42b903418eJohann 4341b362b15af34006e6a11974088a46d42b903418eJohann fclose(infile); 4351b362b15af34006e6a11974088a46d42b903418eJohann 4361b362b15af34006e6a11974088a46d42b903418eJohann printf("Processed %ld frames.\n",(long int)frame_cnt-1); 4371b362b15af34006e6a11974088a46d42b903418eJohann for (i=0; i< NUM_ENCODERS; i++) 4381b362b15af34006e6a11974088a46d42b903418eJohann { 4391b362b15af34006e6a11974088a46d42b903418eJohann /* Calculate PSNR and print it out */ 4401b362b15af34006e6a11974088a46d42b903418eJohann if ( (show_psnr) && (psnr_count[i]>0) ) 4411b362b15af34006e6a11974088a46d42b903418eJohann { 4421b362b15af34006e6a11974088a46d42b903418eJohann int j; 443b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian double ovpsnr = sse_to_psnr(psnr_samples_total[i], 255.0, 444b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian psnr_sse_total[i]); 4451b362b15af34006e6a11974088a46d42b903418eJohann 4461b362b15af34006e6a11974088a46d42b903418eJohann fprintf(stderr, "\n ENC%d PSNR (Overall/Avg/Y/U/V)", i); 4471b362b15af34006e6a11974088a46d42b903418eJohann 4481b362b15af34006e6a11974088a46d42b903418eJohann fprintf(stderr, " %.3lf", ovpsnr); 4491b362b15af34006e6a11974088a46d42b903418eJohann for (j = 0; j < 4; j++) 4501b362b15af34006e6a11974088a46d42b903418eJohann { 4511b362b15af34006e6a11974088a46d42b903418eJohann fprintf(stderr, " %.3lf", psnr_totals[i][j]/psnr_count[i]); 4521b362b15af34006e6a11974088a46d42b903418eJohann } 4531b362b15af34006e6a11974088a46d42b903418eJohann } 4541b362b15af34006e6a11974088a46d42b903418eJohann 4551b362b15af34006e6a11974088a46d42b903418eJohann if(vpx_codec_destroy(&codec[i])) 4561b362b15af34006e6a11974088a46d42b903418eJohann die_codec(&codec[i], "Failed to destroy codec"); 4571b362b15af34006e6a11974088a46d42b903418eJohann 4581b362b15af34006e6a11974088a46d42b903418eJohann vpx_img_free(&raw[i]); 4591b362b15af34006e6a11974088a46d42b903418eJohann 4601b362b15af34006e6a11974088a46d42b903418eJohann if(!outfile[i]) 4611b362b15af34006e6a11974088a46d42b903418eJohann continue; 4621b362b15af34006e6a11974088a46d42b903418eJohann 4631b362b15af34006e6a11974088a46d42b903418eJohann /* Try to rewrite the file header with the actual frame count */ 4641b362b15af34006e6a11974088a46d42b903418eJohann if(!fseek(outfile[i], 0, SEEK_SET)) 4651b362b15af34006e6a11974088a46d42b903418eJohann write_ivf_file_header(outfile[i], &cfg[i], frame_cnt-1); 4661b362b15af34006e6a11974088a46d42b903418eJohann fclose(outfile[i]); 4671b362b15af34006e6a11974088a46d42b903418eJohann } 4681b362b15af34006e6a11974088a46d42b903418eJohann printf("\n"); 4691b362b15af34006e6a11974088a46d42b903418eJohann 4701b362b15af34006e6a11974088a46d42b903418eJohann return EXIT_SUCCESS; 4711b362b15af34006e6a11974088a46d42b903418eJohann} 472