76 строки
2.8 KiB
Plaintext
76 строки
2.8 KiB
Plaintext
@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
|