diff --git a/src/guacenc/Makefile.am b/src/guacenc/Makefile.am index 3f4ac424..e5588b06 100644 --- a/src/guacenc/Makefile.am +++ b/src/guacenc/Makefile.am @@ -28,6 +28,7 @@ noinst_HEADERS = \ buffer.h \ display.h \ encode.h \ + guacenc.h \ image-stream.h \ instructions.h \ jpeg.h \ diff --git a/src/guacenc/display.c b/src/guacenc/display.c index 6892d24a..d4bba518 100644 --- a/src/guacenc/display.c +++ b/src/guacenc/display.c @@ -85,11 +85,11 @@ cairo_operator_t guacenc_display_cairo_operator(guac_composite_mode mask) { } -guacenc_display* guacenc_display_alloc() { +guacenc_display* guacenc_display_alloc(const char* path, const char* codec, + int width, int height, int bitrate) { /* STUB: Prepare video encoding */ - guacenc_video* video = guacenc_video_alloc("/tmp/test.mpg", "mpeg4", - 640, 480, 400000); + guacenc_video* video = guacenc_video_alloc(path, codec, width, height, bitrate); if (video == NULL) return NULL; diff --git a/src/guacenc/display.h b/src/guacenc/display.h index 3ca51397..b8956d76 100644 --- a/src/guacenc/display.h +++ b/src/guacenc/display.h @@ -129,11 +129,29 @@ int guacenc_display_flatten(guacenc_display* display); * representation of encoding state, as well as the state of the Guacamole * display as instructions are read and handled. * + * @param path + * The full path to the file in which encoded video should be written. + * + * @param codec + * The name of the codec to use for the video encoding, as defined by + * ffmpeg / libavcodec. + * + * @param width + * The width of the desired video, in pixels. + * + * @param height + * The height of the desired video, in pixels. + * + * @param bitrate + * The desired overall bitrate of the resulting encoded video, in bits per + * second. + * * @return * The newly-allocated Guacamole video encoder display, or NULL if the * display could not be allocated. */ -guacenc_display* guacenc_display_alloc(); +guacenc_display* guacenc_display_alloc(const char* path, const char* codec, + int width, int height, int bitrate); /** * Frees all memory associated with the given Guacamole video encoder display, diff --git a/src/guacenc/encode.c b/src/guacenc/encode.c index 91cfc0df..680bb31d 100644 --- a/src/guacenc/encode.c +++ b/src/guacenc/encode.c @@ -83,10 +83,12 @@ static int guacenc_read_instructions(guacenc_display* display, } -int guacenc_encode(const char* path) { +int guacenc_encode(const char* path, const char* out_path, const char* codec, + int width, int height, int bitrate) { /* Allocate display for encoding process */ - guacenc_display* display = guacenc_display_alloc(); + guacenc_display* display = guacenc_display_alloc(out_path, codec, + width, height, bitrate); if (display == NULL) return 1; @@ -108,7 +110,7 @@ int guacenc_encode(const char* path) { return 1; } - guacenc_log(GUAC_LOG_INFO, "Encoding \"%s\" ...", path); + guacenc_log(GUAC_LOG_INFO, "Encoding \"%s\" to \"%s\" ...", path, out_path); /* Attempt to read all instructions in the file */ if (guacenc_read_instructions(display, path, socket)) { diff --git a/src/guacenc/encode.h b/src/guacenc/encode.h index 66f12573..ee6be9ab 100644 --- a/src/guacenc/encode.h +++ b/src/guacenc/encode.h @@ -31,11 +31,29 @@ * @param path * The path to the file containing the raw Guacamole protocol dump. * + * @param out_path + * The full path to the file in which encoded video should be written. + * + * @param codec + * The name of the codec to use for the video encoding, as defined by + * ffmpeg / libavcodec. + * + * @param width + * The width of the desired video, in pixels. + * + * @param height + * The height of the desired video, in pixels. + * + * @param bitrate + * The desired overall bitrate of the resulting encoded video, in bits per + * second. + * * @return * Zero on success, non-zero if an error prevented successful encoding of * the video. */ -int guacenc_encode(const char* path); +int guacenc_encode(const char* path, const char* out_path, const char* codec, + int width, int height, int bitrate); #endif diff --git a/src/guacenc/guacenc.c b/src/guacenc/guacenc.c index 79b7d61d..997e7497 100644 --- a/src/guacenc/guacenc.c +++ b/src/guacenc/guacenc.c @@ -23,6 +23,7 @@ #include "config.h" #include "encode.h" +#include "guacenc.h" #include "log.h" #include @@ -41,6 +42,15 @@ int main(int argc, char* argv[]) { return 0; } + /* Load defaults */ + const char* codec = GUACENC_DEFAULT_CODEC; + const char* suffix = GUACENC_DEFAULT_SUFFIX; + int width = GUACENC_DEFAULT_WIDTH; + int height = GUACENC_DEFAULT_HEIGHT; + int bitrate = GUACENC_DEFAULT_BITRATE; + + /* TODO: Override defaults via command-line arguments */ + /* Prepare libavcodec */ avcodec_register_all(); @@ -54,8 +64,19 @@ int main(int argc, char* argv[]) { /* Get current filename */ const char* path = argv[i]; + /* Generate output filename */ + char out_path[4096]; + int len = snprintf(out_path, sizeof(out_path), "%s.%s", path, suffix); + + /* Do not write if filename exceeds maximum length */ + if (len >= sizeof(out_path)) { + guacenc_log(GUAC_LOG_ERROR, "Cannot write output file \"%s.%s\": " + "Name too long", path, suffix); + continue; + } + /* Attempt encoding, log granular success/failure at debug level */ - if (guacenc_encode(path)) { + if (guacenc_encode(path, out_path, codec, width, height, bitrate)) { failures++; guacenc_log(GUAC_LOG_DEBUG, "%s was NOT successfully encoded.", path); diff --git a/src/guacenc/guacenc.h b/src/guacenc/guacenc.h new file mode 100644 index 00000000..68da005c --- /dev/null +++ b/src/guacenc/guacenc.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 Glyptodon, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef GUACENC_H +#define GUACENC_H + +#include "config.h" + +/** + * The name of the codec to use by default, if no other codec is specified on + * the command line. This name is dictated by ffmpeg / libavcodec. + */ +#define GUACENC_DEFAULT_CODEC "mpeg4" + +/** + * The extension to append to the end of the input file to produce the output + * file name, excluding the separating period, if no other suffix is specified + * on the command line. + */ +#define GUACENC_DEFAULT_SUFFIX "mpg" + +/** + * The width of the output video, in pixels, if no other width is given on the + * command line. Note that different codecs will have different restrictions + * regarding legal widths. + */ +#define GUACENC_DEFAULT_WIDTH 640 + +/** + * The height of the output video, in pixels, if no other height is given on the + * command line. Note that different codecs will have different restrictions + * regarding legal heights. + */ +#define GUACENC_DEFAULT_HEIGHT 480 + +/** + * The desired bitrate of the output video, in bits per second, if no other + * bitrate is given on the command line. + */ +#define GUACENC_DEFAULT_BITRATE 400000 + +#endif + diff --git a/src/guacenc/video.h b/src/guacenc/video.h index 398ce410..e72af3e8 100644 --- a/src/guacenc/video.h +++ b/src/guacenc/video.h @@ -113,8 +113,8 @@ typedef struct guacenc_video { * The height of the desired video, in pixels. * * @param bitrate - * The desired overall bitrate of the resulting encoded video, in kilobits - * per second. + * The desired overall bitrate of the resulting encoded video, in bits per + * second. */ guacenc_video* guacenc_video_alloc(const char* path, const char* codec_name, int width, int height, int bitrate);