@TEMPLATE encoder_tmpl.c Two Pass Encoder ================ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION This is an example of a two pass encoder loop. It takes an input file in YV12 format, passes it through the encoder twice, and writes the compressed frames to disk in IVF format. It builds upon the simple_encoder example. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION Twopass Variables ----------------- Twopass mode needs to track the current pass number and the buffer of statistics packets. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS int pass; vpx_fixed_buf_t stats = {0}; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS Updating The Configuration --------------------------------- In two pass mode, the configuration has to be updated on each pass. The statistics buffer is passed on the last pass. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_BEGIN for(pass=0; pass<2; pass++) { frame_cnt = 0; if(pass == 0) cfg.g_pass = VPX_RC_FIRST_PASS; else { cfg.g_pass = VPX_RC_LAST_PASS; cfg.rc_twopass_stats_in = stats; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_BEGIN Encoding A Frame ---------------- Encoding a frame in two pass mode is identical to the simple encoder example, except the deadline is set to VPX_DL_BEST_QUALITY to get the best quality possible. VPX_DL_GOOD_QUALITY could also be used. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME frame_avail = read_frame(infile, &raw); if(vpx_codec_encode(&codec, frame_avail? &raw : NULL, frame_cnt, 1, flags, VPX_DL_BEST_QUALITY)) die_codec(&codec, "Failed to encode frame"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME Processing Statistics Packets ----------------------------- Each packet of type `VPX_CODEC_CX_FRAME_PKT` contains the encoded data for this frame. We write a IVF frame header, followed by the raw data. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_STATS case VPX_CODEC_STATS_PKT: stats.buf = realloc(stats.buf, stats.sz + pkt->data.twopass_stats.sz); if(!stats.buf) die("Memory reallocation failed.\n"); memcpy((char*)stats.buf + stats.sz, pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz); stats.sz += pkt->data.twopass_stats.sz; break; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_STATS Pass Progress Reporting ----------------------------- It's sometimes helpful to see when each pass completes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_END printf("Pass %d complete.\n", pass+1); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_END