| OLD | NEW |
| (Empty) |
| 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 if(vpx_codec_destroy(&codec)) | |
| 75 die_codec(&codec, "Failed to destroy codec"); | |
| 76 } | |
| 77 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_END | |
| 78 | |
| 79 | |
| 80 Clean-up | |
| 81 ----------------------------- | |
| 82 Destruction of the encoder instance must be done on each pass. The | |
| 83 raw image should be destroyed at the end as usual. | |
| 84 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DESTROY | |
| 85 vpx_img_free(&raw); | |
| 86 free(stats.buf); | |
| 87 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DESTROY | |
| OLD | NEW |