You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by mj...@apache.org on 2016/03/20 03:25:04 UTC

[34/50] incubator-guacamole-server git commit: GUAC-236: Provide support for much older versions of libavcodec.

GUAC-236: Provide support for much older versions of libavcodec.


Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/89f6bd4f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/89f6bd4f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/89f6bd4f

Branch: refs/heads/master
Commit: 89f6bd4fae30a5a520e88f577ac9748123acb42b
Parents: 1fedb71
Author: Michael Jumper <mi...@guac-dev.org>
Authored: Wed Mar 16 18:48:00 2016 -0700
Committer: Michael Jumper <mi...@guac-dev.org>
Committed: Wed Mar 16 18:51:15 2016 -0700

----------------------------------------------------------------------
 src/guacenc/Makefile.am     |   1 +
 src/guacenc/ffmpeg-compat.c | 123 +++++++++++++++++++++++++++++++++++++++
 src/guacenc/ffmpeg-compat.h |  32 ++++++++++
 src/guacenc/video.c         |  37 +-----------
 4 files changed, 158 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/89f6bd4f/src/guacenc/Makefile.am
----------------------------------------------------------------------
diff --git a/src/guacenc/Makefile.am b/src/guacenc/Makefile.am
index 1230992..45b9f37 100644
--- a/src/guacenc/Makefile.am
+++ b/src/guacenc/Makefile.am
@@ -51,6 +51,7 @@ guacenc_SOURCES =           \
     display-layers.c        \
     display-sync.c          \
     encode.c                \
+    ffmpeg-compat.c         \
     guacenc.c               \
     image-stream.c          \
     instructions.c          \

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/89f6bd4f/src/guacenc/ffmpeg-compat.c
----------------------------------------------------------------------
diff --git a/src/guacenc/ffmpeg-compat.c b/src/guacenc/ffmpeg-compat.c
new file mode 100644
index 0000000..9cd6820
--- /dev/null
+++ b/src/guacenc/ffmpeg-compat.c
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "ffmpeg-compat.h"
+#include "log.h"
+#include "video.h"
+
+#include <libavcodec/avcodec.h>
+#include <libavutil/common.h>
+#include <libavutil/imgutils.h>
+#include <guacamole/client.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+int guacenc_avcodec_encode_video(guacenc_video* video, AVFrame* frame) {
+
+/* For libavcodec < 54.1.0: avcodec_encode_video2() did not exist */
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,1,0)
+
+    AVCodecContext* context = video->context;
+
+    /* Calculate appropriate buffer size */
+    int length = FF_MIN_BUFFER_SIZE + 12 * context->width * context->height;
+
+    /* Allocate space for output */
+    uint8_t* data = malloc(length);
+    if (data == NULL)
+        return -1;
+
+    /* Encode packet of video data */
+    int used = avcodec_encode_video(context, data, length, frame);
+    if (used < 0) {
+        guacenc_log(GUAC_LOG_WARNING, "Error encoding frame #%" PRId64,
+                video->next_pts);
+        free(data);
+        return -1;
+    }
+
+    /* Report if no data needs to be written */
+    if (used == 0) {
+        free(data);
+        return 0;
+    }
+
+    /* Write data, logging any errors */
+    if (fwrite(data, 1, used, video->output) == 0) {
+        guacenc_log(GUAC_LOG_ERROR, "Unable to write frame "
+                "#%" PRId64 ": %s", video->next_pts, strerror(errno));
+        free(data);
+        return -1;
+    }
+
+    /* Data was written successfully */
+    free(data);
+    return 1;
+
+#else
+
+    /* Init video packet */
+    AVPacket packet;
+    av_init_packet(&packet);
+
+    /* Request that encoder allocate data for packet */
+    packet.data = NULL;
+    packet.size = 0;
+
+    /* Write frame to video */
+    int got_data;
+    if (avcodec_encode_video2(video->context, &packet, frame, &got_data) < 0) {
+        guacenc_log(GUAC_LOG_WARNING, "Error encoding frame #%" PRId64,
+                video->next_pts);
+        return -1;
+    }
+
+    /* Write corresponding data to file */
+    if (got_data) {
+
+        /* Write data, logging any errors */
+        if (fwrite(packet.data, 1, packet.size, video->output) == 0) {
+            guacenc_log(GUAC_LOG_ERROR, "Unable to write frame "
+                    "#%" PRId64 ": %s", video->next_pts, strerror(errno));
+            return -1;
+        }
+
+        /* Data was written successfully */
+        guacenc_log(GUAC_LOG_DEBUG, "Frame #%08" PRId64 ": wrote %i bytes",
+                video->next_pts, packet.size);
+        av_packet_unref(&packet);
+
+    }
+
+    /* Frame may have been queued for later writing / reordering */
+    else
+        guacenc_log(GUAC_LOG_DEBUG, "Frame #%08" PRId64 ": queued for later",
+                video->next_pts);
+
+    return got_data;
+
+#endif
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/89f6bd4f/src/guacenc/ffmpeg-compat.h
----------------------------------------------------------------------
diff --git a/src/guacenc/ffmpeg-compat.h b/src/guacenc/ffmpeg-compat.h
index ba3213a..3e5255c 100644
--- a/src/guacenc/ffmpeg-compat.h
+++ b/src/guacenc/ffmpeg-compat.h
@@ -24,6 +24,7 @@
 #define GUACENC_FFMPEG_COMPAT_H
 
 #include "config.h"
+#include "video.h"
 
 #include <libavcodec/avcodec.h>
 
@@ -39,6 +40,11 @@
 #define av_frame_free avcodec_free_frame
 #endif
 
+/* For libavcodec < 54.28.0: old avcodec_free_frame() did not exist. */
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,28,0)
+#define avcodec_free_frame av_freep
+#endif
+
 /* For libavcodec < 55.52.0: avcodec_free_context did not exist */
 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,52,0)
 #define avcodec_free_context av_freep
@@ -49,5 +55,31 @@
 #define av_packet_unref av_free_packet
 #endif
 
+/* For libavutil < 51.42.0: AV_PIX_FMT_* was PIX_FMT_* */
+#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,42,0)
+#define AV_PIX_FMT_RGB32 PIX_FMT_RGB32
+#define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
+#endif
+
+/**
+ * Writes the specied frame as a new frame of video. If pending frames of the
+ * video are being flushed, the given frame may be NULL (as required by
+ * avcodec_encode_video2()). If avcodec_encode_video2() does not exist, this
+ * function will transparently use avcodec_encode_video().
+ *
+ * @param video
+ *     The video to write the given frame to.
+ *
+ * @param frame
+ *     The frame to write to the video, or NULL if previously-written frames
+ *     are being flushed.
+ *
+ * @return
+ *     A positive value if the frame was successfully written, zero if the
+ *     frame has been saved for later writing / reordering, negative if an
+ *     error occurs.
+ */
+int guacenc_avcodec_encode_video(guacenc_video* video, AVFrame* frame);
+
 #endif
 

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/89f6bd4f/src/guacenc/video.c
----------------------------------------------------------------------
diff --git a/src/guacenc/video.c b/src/guacenc/video.c
index 8c13844..60a9477 100644
--- a/src/guacenc/video.c
+++ b/src/guacenc/video.c
@@ -174,47 +174,14 @@ fail_codec:
  */
 static int guacenc_video_write_frame(guacenc_video* video, AVFrame* frame) {
 
-    /* Init video packet */
-    AVPacket packet;
-    av_init_packet(&packet);
-
-    /* Request that encoder allocate data for packet */
-    packet.data = NULL;
-    packet.size = 0;
-
     /* Set timestamp of frame, if frame given */
     if (frame != NULL)
         frame->pts = video->next_pts;
 
     /* Write frame to video */
-    int got_data;
-    if (avcodec_encode_video2(video->context, &packet, frame, &got_data) < 0) {
-        guacenc_log(GUAC_LOG_WARNING, "Error encoding frame #%" PRId64,
-                video->next_pts);
+    int got_data = guacenc_avcodec_encode_video(video, frame);
+    if (got_data < 0)
         return -1;
-    }
-
-    /* Write corresponding data to file */
-    if (got_data) {
-
-        /* Write data, logging any errors */
-        if (fwrite(packet.data, 1, packet.size, video->output) == 0) {
-            guacenc_log(GUAC_LOG_ERROR, "Unable to write frame "
-                    "#%" PRId64 ": %s", video->next_pts, strerror(errno));
-            return -1;
-        }
-
-        /* Data was written successfully */
-        guacenc_log(GUAC_LOG_DEBUG, "Frame #%08" PRId64 ": wrote %i bytes",
-                video->next_pts, packet.size);
-        av_packet_unref(&packet);
-
-    }
-
-    /* Frame may have been queued for later writing / reordering */
-    else
-        guacenc_log(GUAC_LOG_DEBUG, "Frame #%08" PRId64 ": queued for later",
-                video->next_pts);
 
     /* Update presentation timestamp for next frame */
     video->next_pts++;