John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 1 | @TEMPLATE encoder_tmpl.c |
| 2 | Two Pass Encoder |
| 3 | ================ |
| 4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION |
| 5 | This is an example of a two pass encoder loop. It takes an input file in |
| 6 | YV12 format, passes it through the encoder twice, and writes the compressed |
| 7 | frames to disk in IVF format. It builds upon the simple_encoder example. |
| 8 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION |
| 9 | |
| 10 | |
| 11 | Twopass Variables |
| 12 | ----------------- |
| 13 | Twopass mode needs to track the current pass number and the buffer of |
| 14 | statistics packets. |
| 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS |
| 16 | int pass; |
| 17 | vpx_fixed_buf_t stats = {0}; |
| 18 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS |
| 19 | |
| 20 | |
| 21 | Updating The Configuration |
| 22 | --------------------------------- |
| 23 | In two pass mode, the configuration has to be updated on each pass. The |
| 24 | statistics buffer is passed on the last pass. |
| 25 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_BEGIN |
| 26 | for(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 | |
| 38 | Encoding A Frame |
| 39 | ---------------- |
| 40 | Encoding a frame in two pass mode is identical to the simple encoder |
| 41 | example, except the deadline is set to VPX_DL_BEST_QUALITY to get the |
| 42 | best quality possible. VPX_DL_GOOD_QUALITY could also be used. |
| 43 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME |
| 44 | frame_avail = read_frame(infile, &raw); |
| 45 | if(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 | |
| 51 | Processing Statistics Packets |
| 52 | ----------------------------- |
| 53 | Each packet of type `VPX_CODEC_CX_FRAME_PKT` contains the encoded data |
| 54 | for this frame. We write a IVF frame header, followed by the raw data. |
| 55 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_STATS |
| 56 | case 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 | |
| 69 | Pass Progress Reporting |
| 70 | ----------------------------- |
| 71 | It'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 |