Home | History | Annotate | Download | only in examples
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      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.
      9  */
     10 
     11 
     12 /*
     13 @*INTRODUCTION
     14  */
     15 #include <stdio.h>
     16 #include <stdlib.h>
     17 #include <stdarg.h>
     18 #include <string.h>
     19 #define VPX_CODEC_DISABLE_COMPAT 1
     20 #include "vpx/vpx_encoder.h"
     21 #include "vpx/vp8cx.h"
     22 #define interface (&vpx_codec_vp8_cx_algo)
     23 #define fourcc    0x30385056
     24 @EXTRA_INCLUDES
     25 
     26 #define IVF_FILE_HDR_SZ  (32)
     27 #define IVF_FRAME_HDR_SZ (12)
     28 
     29 static void mem_put_le16(char *mem, unsigned int val) {
     30     mem[0] = val;
     31     mem[1] = val>>8;
     32 }
     33 
     34 static void mem_put_le32(char *mem, unsigned int val) {
     35     mem[0] = val;
     36     mem[1] = val>>8;
     37     mem[2] = val>>16;
     38     mem[3] = val>>24;
     39 }
     40 
     41 static void die(const char *fmt, ...) {
     42     va_list ap;
     43 
     44     va_start(ap, fmt);
     45     vprintf(fmt, ap);
     46     if(fmt[strlen(fmt)-1] != '\n')
     47         printf("\n");
     48     exit(EXIT_FAILURE);
     49 }
     50 
     51 @DIE_CODEC
     52 
     53 static int read_frame(FILE *f, vpx_image_t *img) {
     54     size_t nbytes, to_read;
     55     int    res = 1;
     56 
     57     to_read = img->w*img->h*3/2;
     58     nbytes = fread(img->planes[0], 1, to_read, f);
     59     if(nbytes != to_read) {
     60         res = 0;
     61         if(nbytes > 0)
     62             printf("Warning: Read partial frame. Check your width & height!\n");
     63     }
     64     return res;
     65 }
     66 
     67 static void write_ivf_file_header(FILE *outfile,
     68                                   const vpx_codec_enc_cfg_t *cfg,
     69                                   int frame_cnt) {
     70     char header[32];
     71 
     72     if(cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS)
     73         return;
     74     header[0] = 'D';
     75     header[1] = 'K';
     76     header[2] = 'I';
     77     header[3] = 'F';
     78     mem_put_le16(header+4,  0);                   /* version */
     79     mem_put_le16(header+6,  32);                  /* headersize */
     80     mem_put_le32(header+8,  fourcc);              /* headersize */
     81     mem_put_le16(header+12, cfg->g_w);            /* width */
     82     mem_put_le16(header+14, cfg->g_h);            /* height */
     83     mem_put_le32(header+16, cfg->g_timebase.den); /* rate */
     84     mem_put_le32(header+20, cfg->g_timebase.num); /* scale */
     85     mem_put_le32(header+24, frame_cnt);           /* length */
     86     mem_put_le32(header+28, 0);                   /* unused */
     87 
     88     fwrite(header, 1, 32, outfile);
     89 }
     90 
     91 
     92 static void write_ivf_frame_header(FILE *outfile,
     93                                    const vpx_codec_cx_pkt_t *pkt)
     94 {
     95     char             header[12];
     96     vpx_codec_pts_t  pts;
     97 
     98     if(pkt->kind != VPX_CODEC_CX_FRAME_PKT)
     99         return;
    100 
    101     pts = pkt->data.frame.pts;
    102     mem_put_le32(header, pkt->data.frame.sz);
    103     mem_put_le32(header+4, pts&0xFFFFFFFF);
    104     mem_put_le32(header+8, pts >> 32);
    105 
    106     fwrite(header, 1, 12, outfile);
    107 }
    108 
    109 int main(int argc, char **argv) {
    110     FILE                *infile, *outfile;
    111     vpx_codec_ctx_t      codec;
    112     vpx_codec_enc_cfg_t  cfg;
    113     int                  frame_cnt = 0;
    114     unsigned char        file_hdr[IVF_FILE_HDR_SZ];
    115     unsigned char        frame_hdr[IVF_FRAME_HDR_SZ];
    116     vpx_image_t          raw;
    117     vpx_codec_err_t      res;
    118     long                 width;
    119     long                 height;
    120     int                  frame_avail;
    121     int                  got_data;
    122     int                  flags = 0;
    123 @@@@TWOPASS_VARS
    124 
    125     /* Open files */
    126 @@@@USAGE
    127     width = strtol(argv[1], NULL, 0);
    128     height = strtol(argv[2], NULL, 0);
    129     if(width < 16 || width%2 || height <16 || height%2)
    130         die("Invalid resolution: %ldx%ld", width, height);
    131     if(!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 1))
    132         die("Faile to allocate image", width, height);
    133     if(!(outfile = fopen(argv[4], "wb")))
    134         die("Failed to open %s for writing", argv[4]);
    135 
    136     printf("Using %s\n",vpx_codec_iface_name(interface));
    137 
    138 @@@@ENC_DEF_CFG
    139 
    140 @@@@ENC_SET_CFG
    141 @@@@ENC_SET_CFG2
    142 
    143     write_ivf_file_header(outfile, &cfg, 0);
    144 
    145 @@@@TWOPASS_LOOP_BEGIN
    146 
    147         /* Open input file for this encoding pass */
    148         if(!(infile = fopen(argv[3], "rb")))
    149             die("Failed to open %s for reading", argv[3]);
    150 
    151 @@@@@@@@ENC_INIT
    152 
    153         frame_avail = 1;
    154         got_data = 0;
    155         while(frame_avail || got_data) {
    156             vpx_codec_iter_t iter = NULL;
    157             const vpx_codec_cx_pkt_t *pkt;
    158 
    159 @@@@@@@@@@@@PER_FRAME_CFG
    160 @@@@@@@@@@@@ENCODE_FRAME
    161             got_data = 0;
    162             while( (pkt = vpx_codec_get_cx_data(&codec, &iter)) ) {
    163                 got_data = 1;
    164                 switch(pkt->kind) {
    165 @@@@@@@@@@@@@@@@PROCESS_FRAME
    166 @@@@@@@@@@@@@@@@PROCESS_STATS
    167                 default:
    168                     break;
    169                 }
    170                 printf(pkt->kind == VPX_CODEC_CX_FRAME_PKT
    171                        && (pkt->data.frame.flags & VPX_FRAME_IS_KEY)? "K":".");
    172                 fflush(stdout);
    173             }
    174             frame_cnt++;
    175         }
    176         printf("\n");
    177         fclose(infile);
    178 @@@@TWOPASS_LOOP_END
    179 
    180     printf("Processed %d frames.\n",frame_cnt-1);
    181 @@@@DESTROY
    182 
    183     /* Try to rewrite the file header with the actual frame count */
    184     if(!fseek(outfile, 0, SEEK_SET))
    185         write_ivf_file_header(outfile, &cfg, frame_cnt-1);
    186     fclose(outfile);
    187     return EXIT_SUCCESS;
    188 }
    189