2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
15 #include "vpx/vpx_encoder.h"
16 #include "vpx/vp8cx.h"
18 #include "../tools_common.h"
19 #include "../video_writer.h"
21 static const char *exec_name
;
23 void usage_exit(void) {
24 fprintf(stderr
, "vp9_lossless_encoder: Example demonstrating VP9 lossless "
25 "encoding feature. Supports raw input only.\n");
26 fprintf(stderr
, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name
);
30 static int encode_frame(vpx_codec_ctx_t
*codec
,
34 VpxVideoWriter
*writer
) {
36 vpx_codec_iter_t iter
= NULL
;
37 const vpx_codec_cx_pkt_t
*pkt
= NULL
;
38 const vpx_codec_err_t res
= vpx_codec_encode(codec
, img
, frame_index
, 1,
39 flags
, VPX_DL_GOOD_QUALITY
);
40 if (res
!= VPX_CODEC_OK
)
41 die_codec(codec
, "Failed to encode frame");
43 while ((pkt
= vpx_codec_get_cx_data(codec
, &iter
)) != NULL
) {
46 if (pkt
->kind
== VPX_CODEC_CX_FRAME_PKT
) {
47 const int keyframe
= (pkt
->data
.frame
.flags
& VPX_FRAME_IS_KEY
) != 0;
48 if (!vpx_video_writer_write_frame(writer
,
51 pkt
->data
.frame
.pts
)) {
52 die_codec(codec
, "Failed to write compressed frame");
54 printf(keyframe
? "K" : ".");
62 int main(int argc
, char **argv
) {
64 vpx_codec_ctx_t codec
;
65 vpx_codec_enc_cfg_t cfg
;
69 VpxVideoInfo info
= {0};
70 VpxVideoWriter
*writer
= NULL
;
71 const VpxInterface
*encoder
= NULL
;
77 die("Invalid number of arguments");
79 encoder
= get_vpx_encoder_by_name("vp9");
81 die("Unsupported codec.");
83 info
.codec_fourcc
= encoder
->fourcc
;
84 info
.frame_width
= strtol(argv
[1], NULL
, 0);
85 info
.frame_height
= strtol(argv
[2], NULL
, 0);
86 info
.time_base
.numerator
= 1;
87 info
.time_base
.denominator
= fps
;
89 if (info
.frame_width
<= 0 ||
90 info
.frame_height
<= 0 ||
91 (info
.frame_width
% 2) != 0 ||
92 (info
.frame_height
% 2) != 0) {
93 die("Invalid frame size: %dx%d", info
.frame_width
, info
.frame_height
);
96 if (!vpx_img_alloc(&raw
, VPX_IMG_FMT_I420
, info
.frame_width
,
97 info
.frame_height
, 1)) {
98 die("Failed to allocate image.");
101 printf("Using %s\n", vpx_codec_iface_name(encoder
->codec_interface()));
103 res
= vpx_codec_enc_config_default(encoder
->codec_interface(), &cfg
, 0);
105 die_codec(&codec
, "Failed to get default codec config.");
107 cfg
.g_w
= info
.frame_width
;
108 cfg
.g_h
= info
.frame_height
;
109 cfg
.g_timebase
.num
= info
.time_base
.numerator
;
110 cfg
.g_timebase
.den
= info
.time_base
.denominator
;
112 writer
= vpx_video_writer_open(argv
[4], kContainerIVF
, &info
);
114 die("Failed to open %s for writing.", argv
[4]);
116 if (!(infile
= fopen(argv
[3], "rb")))
117 die("Failed to open %s for reading.", argv
[3]);
119 if (vpx_codec_enc_init(&codec
, encoder
->codec_interface(), &cfg
, 0))
120 die_codec(&codec
, "Failed to initialize encoder");
122 if (vpx_codec_control_(&codec
, VP9E_SET_LOSSLESS
, 1))
123 die_codec(&codec
, "Failed to use lossless mode");
126 while (vpx_img_read(&raw
, infile
)) {
127 encode_frame(&codec
, &raw
, frame_count
++, 0, writer
);
131 while (encode_frame(&codec
, NULL
, -1, 0, writer
)) {}
135 printf("Processed %d frames.\n", frame_count
);
138 if (vpx_codec_destroy(&codec
))
139 die_codec(&codec
, "Failed to destroy codec.");
141 vpx_video_writer_close(writer
);