cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

guacenc.c (4407B)


      1/*
      2 * Licensed to the Apache Software Foundation (ASF) under one
      3 * or more contributor license agreements.  See the NOTICE file
      4 * distributed with this work for additional information
      5 * regarding copyright ownership.  The ASF licenses this file
      6 * to you under the Apache License, Version 2.0 (the
      7 * "License"); you may not use this file except in compliance
      8 * with the License.  You may obtain a copy of the License at
      9 *
     10 *   http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing,
     13 * software distributed under the License is distributed on an
     14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     15 * KIND, either express or implied.  See the License for the
     16 * specific language governing permissions and limitations
     17 * under the License.
     18 */
     19
     20#include "config.h"
     21
     22#include "encode.h"
     23#include "guacenc.h"
     24#include "log.h"
     25#include "parse.h"
     26
     27#include <libavcodec/avcodec.h>
     28#include <libavformat/avformat.h>
     29
     30#include <getopt.h>
     31#include <stdbool.h>
     32#include <stdio.h>
     33
     34int main(int argc, char* argv[]) {
     35
     36    int i;
     37
     38    /* Load defaults */
     39    bool force = false;
     40    int width = GUACENC_DEFAULT_WIDTH;
     41    int height = GUACENC_DEFAULT_HEIGHT;
     42    int bitrate = GUACENC_DEFAULT_BITRATE;
     43
     44    /* Parse arguments */
     45    int opt;
     46    while ((opt = getopt(argc, argv, "s:r:f")) != -1) {
     47
     48        /* -s: Dimensions (WIDTHxHEIGHT) */
     49        if (opt == 's') {
     50            if (guacenc_parse_dimensions(optarg, &width, &height)) {
     51                guacenc_log(GUAC_LOG_ERROR, "Invalid dimensions.");
     52                goto invalid_options;
     53            }
     54        }
     55
     56        /* -r: Bitrate (bits per second) */
     57        else if (opt == 'r') {
     58            if (guacenc_parse_int(optarg, &bitrate)) {
     59                guacenc_log(GUAC_LOG_ERROR, "Invalid bitrate.");
     60                goto invalid_options;
     61            }
     62        }
     63
     64        /* -f: Force */
     65        else if (opt == 'f')
     66            force = true;
     67
     68        /* Invalid option */
     69        else {
     70            goto invalid_options;
     71        }
     72
     73    }
     74
     75    /* Log start */
     76    guacenc_log(GUAC_LOG_INFO, "Guacamole video encoder (guacenc) "
     77            "version " VERSION);
     78
     79#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)
     80    /* Prepare libavcodec */
     81    avcodec_register_all();
     82#endif
     83
     84#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100)
     85    av_register_all();
     86#endif
     87
     88    /* Track number of overall failures */
     89    int total_files = argc - optind;
     90    int failures = 0;
     91
     92    /* Abort if no files given */
     93    if (total_files <= 0) {
     94        guacenc_log(GUAC_LOG_INFO, "No input files specified. Nothing to do.");
     95        return 0;
     96    }
     97
     98    guacenc_log(GUAC_LOG_INFO, "%i input file(s) provided.", total_files);
     99
    100    guacenc_log(GUAC_LOG_INFO, "Video will be encoded at %ix%i "
    101            "and %i bps.", width, height, bitrate);
    102
    103    /* Encode all input files */
    104    for (i = optind; i < argc; i++) {
    105
    106        /* Get current filename */
    107        const char* path = argv[i];
    108
    109        /* Generate output filename */
    110        char out_path[4096];
    111        int len = snprintf(out_path, sizeof(out_path), "%s.m4v", path);
    112
    113        /* Do not write if filename exceeds maximum length */
    114        if (len >= sizeof(out_path)) {
    115            guacenc_log(GUAC_LOG_ERROR, "Cannot write output file for \"%s\": "
    116                    "Name too long", path);
    117            continue;
    118        }
    119
    120        /* Attempt encoding, log granular success/failure at debug level */
    121        if (guacenc_encode(path, out_path, "mpeg4",
    122                    width, height, bitrate, force)) {
    123            failures++;
    124            guacenc_log(GUAC_LOG_DEBUG,
    125                    "%s was NOT successfully encoded.", path);
    126        }
    127        else
    128            guacenc_log(GUAC_LOG_DEBUG, "%s was successfully encoded.", path);
    129
    130    }
    131
    132    /* Warn if at least one file failed */
    133    if (failures != 0)
    134        guacenc_log(GUAC_LOG_WARNING, "Encoding failed for %i of %i file(s).",
    135                failures, total_files);
    136
    137    /* Notify of success */
    138    else
    139        guacenc_log(GUAC_LOG_INFO, "All files encoded successfully.");
    140
    141    /* Encoding complete */
    142    return 0;
    143
    144    /* Display usage and exit with error if options are invalid */
    145invalid_options:
    146
    147    fprintf(stderr, "USAGE: %s"
    148            " [-s WIDTHxHEIGHT]"
    149            " [-r BITRATE]"
    150            " [-f]"
    151            " [FILE]...\n", argv[0]);
    152
    153    return 1;
    154
    155}
    156