1@TEMPLATE encoder_tmpl.c 2Two Pass Encoder 3================ 4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION 5This is an example of a two pass encoder loop. It takes an input file in 6YV12 format, passes it through the encoder twice, and writes the compressed 7frames to disk in IVF format. It builds upon the simple_encoder example. 8~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION 9 10 11Twopass Variables 12----------------- 13Twopass mode needs to track the current pass number and the buffer of 14statistics packets. 15~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS 16int pass; 17vpx_fixed_buf_t stats = {0}; 18~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS 19 20 21Updating The Configuration 22--------------------------------- 23In two pass mode, the configuration has to be updated on each pass. The 24statistics buffer is passed on the last pass. 25~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_BEGIN 26for(pass=0; pass<2; pass++) { 27 frame_cnt = 0; 28 29 if(pass == 0) 30 cfg.g_pass = VPX_RC_FIRST_PASS; 31 else { 32 cfg.g_pass = VPX_RC_LAST_PASS; 33 cfg.rc_twopass_stats_in = stats; 34 } 35~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_BEGIN 36 37 38Encoding A Frame 39---------------- 40Encoding a frame in two pass mode is identical to the simple encoder 41example, except the deadline is set to VPX_DL_BEST_QUALITY to get the 42best quality possible. VPX_DL_GOOD_QUALITY could also be used. 43~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME 44frame_avail = read_frame(infile, &raw); 45if(vpx_codec_encode(&codec, frame_avail? &raw : NULL, frame_cnt, 46 1, flags, VPX_DL_BEST_QUALITY)) 47 die_codec(&codec, "Failed to encode frame"); 48~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME 49 50 51Processing Statistics Packets 52----------------------------- 53Each packet of type `VPX_CODEC_CX_FRAME_PKT` contains the encoded data 54for this frame. We write a IVF frame header, followed by the raw data. 55~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_STATS 56case VPX_CODEC_STATS_PKT: 57 stats.buf = realloc(stats.buf, stats.sz 58 + pkt->data.twopass_stats.sz); 59 if(!stats.buf) 60 die("Memory reallocation failed.\n"); 61 memcpy((char*)stats.buf + stats.sz, 62 pkt->data.twopass_stats.buf, 63 pkt->data.twopass_stats.sz); 64 stats.sz += pkt->data.twopass_stats.sz; 65 break; 66~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_STATS 67 68 69Pass Progress Reporting 70----------------------------- 71It's sometimes helpful to see when each pass completes. 72~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_END 73 printf("Pass %d complete.\n", pass+1); 74} 75~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_END 76