From 8c56fd7952f9b7c8c89a273467227c16691c015f Mon Sep 17 00:00:00 2001
From: Eloi BAIL <eloi.bail@savoirfairelinux.com>
Date: Tue, 28 Apr 2015 17:35:55 -0400
Subject: [PATCH] daemon: enable H263 encoder

H263 version 1 allows a limited range of resolutions outdated compared
to recent camera capabilities. It was thus nearly impossible
to use it on Ring.

This patchset forces encoding of H263+ which supports all resolutions
multiple of 4 from 4x4 to 2048x1152.
On Libav we see video artifacts if multithread is enabled
on encoder side. A workaround deals with forcing h263 encoder
to monothread.

See https://bugzilla.libav.org/show_bug.cgi?id=912

Tuleap: #138
Change-Id: I7121e182fa13139d28db010e2ed0de573c616de7
---
 contrib/src/ffmpeg/rules.mak         |  1 +
 contrib/src/libav/rules.mak          |  1 +
 src/media/media_codec.cpp            |  2 ++
 src/media/media_encoder.cpp          | 16 +++++++++++++++-
 src/media/system_codec_container.cpp |  2 +-
 5 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/contrib/src/ffmpeg/rules.mak b/contrib/src/ffmpeg/rules.mak
index fc8edde375..d5b61f8074 100644
--- a/contrib/src/ffmpeg/rules.mak
+++ b/contrib/src/ffmpeg/rules.mak
@@ -54,6 +54,7 @@ FFMPEGCONF += \
 		--enable-encoder=libvpx_vp8 \
 		--enable-decoder=vp8 \
 		--enable-encoder=h263 \
+		--enable-encoder=h263p \
 		--enable-decoder=h263 \
 		--enable-encoder=mjpeg \
 		--enable-decoder=mjpeg \
diff --git a/contrib/src/libav/rules.mak b/contrib/src/libav/rules.mak
index e0287ed549..38580cb686 100644
--- a/contrib/src/libav/rules.mak
+++ b/contrib/src/libav/rules.mak
@@ -52,6 +52,7 @@ LIBAVCONF += \
 		--enable-decoder=mpeg4 \
 		--enable-encoder=h263 \
 		--enable-decoder=h263 \
+		--enable-encoder=h263p \
 		--enable-encoder=libspeex \
 		--enable-decoder=libspeex
 
diff --git a/src/media/media_codec.cpp b/src/media/media_codec.cpp
index b1939b204c..5e98b1c997 100644
--- a/src/media/media_codec.cpp
+++ b/src/media/media_codec.cpp
@@ -134,6 +134,8 @@ AccountCodecInfo::AccountCodecInfo(const SystemCodecInfo& sysCodecInfo)
 {
     if (sysCodecInfo.minQuality != SystemCodecInfo::DEFAULT_NO_QUALITY)
         quality = SystemCodecInfo::DEFAULT_CODEC_QUALITY;
+    else
+        quality = SystemCodecInfo::DEFAULT_NO_QUALITY;
 }
 
 AccountCodecInfo::~AccountCodecInfo()
diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp
index ea93b19bf9..7819d74528 100644
--- a/src/media/media_encoder.cpp
+++ b/src/media/media_encoder.cpp
@@ -134,7 +134,13 @@ MediaEncoder::openOutput(const char *filename,
     outputCtx_->filename[sizeof(outputCtx_->filename) - 1] = '\0';
 
     /* find the video encoder */
-    outputEncoder_ = avcodec_find_encoder((AVCodecID)args.codec->systemCodecInfo.avcodecId);
+    if (args.codec->systemCodecInfo.avcodecId == AV_CODEC_ID_H263)
+        // For H263 encoding, we force the use of AV_CODEC_ID_H263P (H263-1998)
+        // H263-1998 can manage all frame sizes while H263 don't
+        // AV_CODEC_ID_H263 decoder will be used for decoding
+        outputEncoder_ = avcodec_find_encoder(AV_CODEC_ID_H263P);
+    else
+        outputEncoder_ = avcodec_find_encoder((AVCodecID)args.codec->systemCodecInfo.avcodecId);
     if (!outputEncoder_) {
         RING_ERR("Encoder \"%s\" not found!", args.codec->systemCodecInfo.name.c_str());
         throw MediaEncoderException("No output encoder");
@@ -192,6 +198,14 @@ MediaEncoder::openOutput(const char *filename,
         encoderCtx_->rc_buffer_size = maxBitrate;
         encoderCtx_->bit_rate = encoderCtx_->rc_min_rate = encoderCtx_->rc_max_rate =  maxBitrate;
         RING_DBG("Using Max bitrate %d", maxBitrate);
+    } else if (args.codec->systemCodecInfo.avcodecId == AV_CODEC_ID_H263) {
+        encoderCtx_->bit_rate = encoderCtx_->rc_max_rate =  maxBitrate;
+        encoderCtx_->rc_buffer_size = maxBitrate;
+        // on libav there are video artifcats if multithreading is enabled
+        // see https://bugzilla.libav.org/show_bug.cgi?id=912
+        // TODO: this is a workaround !
+        encoderCtx_->thread_count = 1;
+        RING_DBG("Using Max bitrate %d", maxBitrate);
     }
 
     int ret;
diff --git a/src/media/system_codec_container.cpp b/src/media/system_codec_container.cpp
index ec23e5d92b..30b52ed5d8 100644
--- a/src/media/system_codec_container.cpp
+++ b/src/media/system_codec_container.cpp
@@ -75,7 +75,7 @@ SystemCodecContainer::initCodecConfig()
                                                DEFAULT_VIDEO_BITRATE),
 
         std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_H263,
-                                               "H263", "h263",
+                                               "H263-1998", "h263",
                                                CODEC_ENCODER_DECODER,
                                                DEFAULT_VIDEO_BITRATE),
 #endif
-- 
GitLab