tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

set_maps.c (6899B)


      1 /*
      2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
      3 *
      4 * This source code is subject to the terms of the BSD 2 Clause License and
      5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      6 * was not distributed with this source code in the LICENSE file, you can
      7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      8 * Media Patent License 1.0 was not distributed with this source code in the
      9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
     10 */
     11 
     12 // AOM Set Active and ROI Maps
     13 // ===========================
     14 //
     15 // This is an example demonstrating how to control the AOM encoder's
     16 // ROI and Active maps.
     17 //
     18 // ROI (Region of Interest) maps are a way for the application to assign
     19 // each macroblock in the image to a region, and then set quantizer and
     20 // filtering parameters on that image.
     21 //
     22 // Active maps are a way for the application to specify on a
     23 // macroblock-by-macroblock basis whether there is any activity in that
     24 // macroblock.
     25 //
     26 //
     27 // Configuration
     28 // -------------
     29 // An ROI map is set on frame 22. If the width of the image in macroblocks
     30 // is evenly divisible by 4, then the output will appear to have distinct
     31 // columns, where the quantizer, loopfilter, and static threshold differ
     32 // from column to column.
     33 //
     34 // An active map is set on frame 33. If the width of the image in macroblocks
     35 // is evenly divisible by 4, then the output will appear to have distinct
     36 // columns, where one column will have motion and the next will not.
     37 //
     38 // The active map is cleared on frame 44.
     39 //
     40 // Observing The Effects
     41 // ---------------------
     42 // Use the `simple_decoder` example to decode this sample, and observe
     43 // the change in the image at frames 22, 33, and 44.
     44 
     45 #include <assert.h>
     46 #include <stdio.h>
     47 #include <stdlib.h>
     48 #include <string.h>
     49 
     50 #include "aom/aom_encoder.h"
     51 #include "aom/aomcx.h"
     52 #include "common/tools_common.h"
     53 #include "common/video_writer.h"
     54 
     55 static const char *exec_name;
     56 
     57 void usage_exit(void) {
     58  fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n",
     59          exec_name);
     60  exit(EXIT_FAILURE);
     61 }
     62 
     63 static void set_active_map(const aom_codec_enc_cfg_t *cfg,
     64                           aom_codec_ctx_t *codec) {
     65  unsigned int i;
     66  aom_active_map_t map = { 0, 0, 0 };
     67 
     68  map.rows = (cfg->g_h + 15) / 16;
     69  map.cols = (cfg->g_w + 15) / 16;
     70 
     71  map.active_map = (uint8_t *)malloc(map.rows * map.cols);
     72  if (!map.active_map) die("Failed to allocate active map");
     73  for (i = 0; i < map.rows * map.cols; ++i) map.active_map[i] = i % 2;
     74 
     75  if (aom_codec_control(codec, AOME_SET_ACTIVEMAP, &map))
     76    die_codec(codec, "Failed to set active map");
     77 
     78  free(map.active_map);
     79 }
     80 
     81 static void unset_active_map(const aom_codec_enc_cfg_t *cfg,
     82                             aom_codec_ctx_t *codec) {
     83  aom_active_map_t map = { 0, 0, 0 };
     84 
     85  map.rows = (cfg->g_h + 15) / 16;
     86  map.cols = (cfg->g_w + 15) / 16;
     87  map.active_map = NULL;
     88 
     89  if (aom_codec_control(codec, AOME_SET_ACTIVEMAP, &map))
     90    die_codec(codec, "Failed to set active map");
     91 }
     92 
     93 static int encode_frame(aom_codec_ctx_t *codec, aom_image_t *img,
     94                        int frame_index, AvxVideoWriter *writer) {
     95  int got_pkts = 0;
     96  aom_codec_iter_t iter = NULL;
     97  const aom_codec_cx_pkt_t *pkt = NULL;
     98  const aom_codec_err_t res = aom_codec_encode(codec, img, frame_index, 1, 0);
     99  if (res != AOM_CODEC_OK) die_codec(codec, "Failed to encode frame");
    100 
    101  while ((pkt = aom_codec_get_cx_data(codec, &iter)) != NULL) {
    102    got_pkts = 1;
    103 
    104    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
    105      const int keyframe = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
    106      if (!aom_video_writer_write_frame(writer, pkt->data.frame.buf,
    107                                        pkt->data.frame.sz,
    108                                        pkt->data.frame.pts)) {
    109        die_codec(codec, "Failed to write compressed frame");
    110      }
    111 
    112      printf(keyframe ? "K" : ".");
    113      fflush(stdout);
    114    }
    115  }
    116 
    117  return got_pkts;
    118 }
    119 
    120 int main(int argc, char **argv) {
    121  FILE *infile = NULL;
    122  aom_codec_ctx_t codec;
    123  aom_codec_enc_cfg_t cfg;
    124  int frame_count = 0;
    125  const int limit = 10;
    126  aom_image_t raw;
    127  aom_codec_err_t res;
    128  AvxVideoInfo info;
    129  AvxVideoWriter *writer = NULL;
    130  const int fps = 2;  // TODO(dkovalev) add command line argument
    131  const double bits_per_pixel_per_frame = 0.067;
    132 
    133 #if CONFIG_REALTIME_ONLY
    134  const int usage = 1;
    135  const int speed = 7;
    136 #else
    137  const int usage = 0;
    138  const int speed = 2;
    139 #endif
    140 
    141  exec_name = argv[0];
    142  if (argc != 6) die("Invalid number of arguments");
    143 
    144  memset(&info, 0, sizeof(info));
    145 
    146  aom_codec_iface_t *encoder = get_aom_encoder_by_short_name(argv[1]);
    147  if (encoder == NULL) {
    148    die("Unsupported codec.");
    149  }
    150  assert(encoder != NULL);
    151  info.codec_fourcc = get_fourcc_by_aom_encoder(encoder);
    152  info.frame_width = (int)strtol(argv[2], NULL, 0);
    153  info.frame_height = (int)strtol(argv[3], NULL, 0);
    154  info.time_base.numerator = 1;
    155  info.time_base.denominator = fps;
    156 
    157  if (info.frame_width <= 0 || info.frame_height <= 0 ||
    158      (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
    159    die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
    160  }
    161 
    162  if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, info.frame_width,
    163                     info.frame_height, 1)) {
    164    die("Failed to allocate image.");
    165  }
    166 
    167  printf("Using %s\n", aom_codec_iface_name(encoder));
    168 
    169  res = aom_codec_enc_config_default(encoder, &cfg, usage);
    170  if (res) die_codec(&codec, "Failed to get default codec config.");
    171 
    172  cfg.g_w = info.frame_width;
    173  cfg.g_h = info.frame_height;
    174  cfg.g_timebase.num = info.time_base.numerator;
    175  cfg.g_timebase.den = info.time_base.denominator;
    176  cfg.rc_target_bitrate =
    177      (unsigned int)(bits_per_pixel_per_frame * cfg.g_w * cfg.g_h * fps / 1000);
    178  cfg.g_lag_in_frames = 0;
    179 
    180  writer = aom_video_writer_open(argv[5], kContainerIVF, &info);
    181  if (!writer) die("Failed to open %s for writing.", argv[5]);
    182 
    183  if (!(infile = fopen(argv[4], "rb")))
    184    die("Failed to open %s for reading.", argv[4]);
    185 
    186  if (aom_codec_enc_init(&codec, encoder, &cfg, 0))
    187    die("Failed to initialize encoder");
    188 
    189  if (aom_codec_control(&codec, AOME_SET_CPUUSED, speed))
    190    die_codec(&codec, "Failed to set cpu-used");
    191 
    192  // Encode frames.
    193  while (aom_img_read(&raw, infile) && frame_count < limit) {
    194    ++frame_count;
    195 
    196    if (frame_count == 5) {
    197      set_active_map(&cfg, &codec);
    198    } else if (frame_count == 9) {
    199      unset_active_map(&cfg, &codec);
    200    }
    201 
    202    encode_frame(&codec, &raw, frame_count, writer);
    203  }
    204 
    205  // Flush encoder.
    206  while (encode_frame(&codec, NULL, -1, writer)) {
    207  }
    208 
    209  printf("\n");
    210  fclose(infile);
    211  printf("Processed %d frames.\n", frame_count);
    212 
    213  aom_img_free(&raw);
    214  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
    215 
    216  aom_video_writer_close(writer);
    217 
    218  return EXIT_SUCCESS;
    219 }