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++;