2 * Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license and patent
5 * grant that can be found in the LICENSE file in the root of the source
6 * tree. All contributing project authors may be found in the AUTHORS
7 * file in the root of the source tree.
18 #define VPX_CODEC_DISABLE_COMPAT 1
19 #include "vpx_encoder.h"
21 #define interface (&vpx_codec_vp8_cx_algo)
22 #define fourcc 0x30385056
25 #define IVF_FILE_HDR_SZ (32)
26 #define IVF_FRAME_HDR_SZ (12)
28 static void mem_put_le16(char *mem, unsigned int val) {
33 static void mem_put_le32(char *mem, unsigned int val) {
40 static void die(const char *fmt, ...) {
45 if(fmt[strlen(fmt)-1] != '\n')
52 static int read_frame(FILE *f, vpx_image_t *img) {
53 size_t nbytes, to_read;
56 to_read = img->w*img->h*3/2;
57 nbytes = fread(img->planes[0], 1, to_read, f);
58 if(nbytes != to_read) {
61 printf("Warning: Read partial frame. Check your width & height!\n");
66 static void write_ivf_file_header(FILE *outfile,
67 const vpx_codec_enc_cfg_t *cfg,
71 if(cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS)
77 mem_put_le16(header+4, 0); /* version */
78 mem_put_le16(header+6, 32); /* headersize */
79 mem_put_le32(header+8, fourcc); /* headersize */
80 mem_put_le16(header+12, cfg->g_w); /* width */
81 mem_put_le16(header+14, cfg->g_h); /* height */
82 mem_put_le32(header+16, cfg->g_timebase.den); /* rate */
83 mem_put_le32(header+20, cfg->g_timebase.num); /* scale */
84 mem_put_le32(header+24, frame_cnt); /* length */
85 mem_put_le32(header+28, 0); /* unused */
87 fwrite(header, 1, 32, outfile);
91 static void write_ivf_frame_header(FILE *outfile,
92 const vpx_codec_cx_pkt_t *pkt)
97 if(pkt->kind != VPX_CODEC_CX_FRAME_PKT)
100 pts = pkt->data.frame.pts;
101 mem_put_le32(header, pkt->data.frame.sz);
102 mem_put_le32(header+4, pts&0xFFFFFFFF);
103 mem_put_le32(header+8, pts >> 32);
105 fwrite(header, 1, 12, outfile);
108 int main(int argc, char **argv) {
109 FILE *infile, *outfile;
110 vpx_codec_ctx_t codec;
111 vpx_codec_enc_cfg_t cfg;
113 unsigned char file_hdr[IVF_FILE_HDR_SZ];
114 unsigned char frame_hdr[IVF_FRAME_HDR_SZ];
126 width = strtol(argv[1], NULL, 0);
127 height = strtol(argv[2], NULL, 0);
128 if(width < 16 || width%2 || height <16 || height%2)
129 die("Invalid resolution: %ldx%ld", width, height);
130 if(!vpx_img_alloc(&raw, IMG_FMT_YV12, width, height, 1))
131 die("Faile to allocate image", width, height);
132 if(!(outfile = fopen(argv[4], "wb")))
133 die("Failed to open %s for writing", argv[4]);
135 printf("Using %s\n",vpx_codec_iface_name(interface));
142 write_ivf_file_header(outfile, &cfg, 0);
144 @@@@TWOPASS_LOOP_BEGIN
146 /* Open input file for this encoding pass */
147 if(!(infile = fopen(argv[3], "rb")))
148 die("Failed to open %s for reading", argv[3]);
154 while(frame_avail || got_data) {
155 vpx_codec_iter_t iter = NULL;
156 const vpx_codec_cx_pkt_t *pkt;
158 @@@@@@@@@@@@PER_FRAME_CFG
159 @@@@@@@@@@@@ENCODE_FRAME
161 while( (pkt = vpx_codec_get_cx_data(&codec, &iter)) ) {
164 @@@@@@@@@@@@@@@@PROCESS_FRAME
165 @@@@@@@@@@@@@@@@PROCESS_STATS
169 printf(pkt->kind == VPX_CODEC_CX_FRAME_PKT
170 && (pkt->data.frame.flags & VPX_FRAME_IS_KEY)? "K":".");
179 printf("Processed %d frames.\n",frame_cnt-1);
182 /* Try to rewrite the file header with the actual frame count */
183 if(!fseek(outfile, 0, SEEK_SET))
184 write_ivf_file_header(outfile, &cfg, frame_cnt-1);