From 59d6bf505e6c5f801dd9e027fa0cd801df61228d Mon Sep 17 00:00:00 2001
From: philippegorley <philippe.gorley@savoirfairelinux.com>
Date: Tue, 17 Apr 2018 16:58:44 -0400
Subject: [PATCH] media: add function to get libav* error messages

FFmpeg has the convenient macro av_err2str, but it cannot compile using
g++ (https://ffmpeg.org/pipermail/libav-user/2013-January/003440.html).
Adds an equivalent function for C++.

Change-Id: Ie9eb2c0dfe68c58fd6a5ff82a3729ff63b736a69
---
 src/media/libav_utils.cpp   |  8 ++++++++
 src/media/libav_utils.h     |  4 +++-
 src/media/media_decoder.cpp | 21 +++++----------------
 src/media/media_encoder.cpp | 16 ++++------------
 4 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/src/media/libav_utils.cpp b/src/media/libav_utils.cpp
index 2ee286a905..5795567820 100644
--- a/src/media/libav_utils.cpp
+++ b/src/media/libav_utils.cpp
@@ -199,4 +199,12 @@ is_yuv_planar(const AVPixFmtDescriptor& desc)
     return not used_bit_mask;
 }
 
+std::string
+getError(int err)
+{
+    std::string ret(AV_ERROR_MAX_STRING_SIZE, '\0');
+    av_strerror(err, (char*)ret.data(), ret.size());
+    return ret;
+}
+
 }} // namespace ring::libav_utils
diff --git a/src/media/libav_utils.h b/src/media/libav_utils.h
index 8b12308e2d..c8f97d32f5 100644
--- a/src/media/libav_utils.h
+++ b/src/media/libav_utils.h
@@ -40,6 +40,8 @@ namespace ring { namespace libav_utils {
                       char *hostname, size_t hostname_size, int *port,
                       char *path, size_t path_size);
 
-bool is_yuv_planar(const AVPixFmtDescriptor& desc);
+    bool is_yuv_planar(const AVPixFmtDescriptor& desc);
+
+    std::string getError(int err);
 
 }} // namespace ring::libav_utils
diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp
index c29d612308..0fd2e7de20 100644
--- a/src/media/media_decoder.cpp
+++ b/src/media/media_decoder.cpp
@@ -123,9 +123,7 @@ int MediaDecoder::openInput(const DeviceParams& params)
         options_ ? &options_ : NULL);
 
     if (ret) {
-        char errbuf[64];
-        av_strerror(ret, errbuf, sizeof(errbuf));
-        RING_ERR("avformat_open_input failed: %s", errbuf);
+        RING_ERR("avformat_open_input failed: %s", libav_utils::getError(ret).c_str());
     } else {
         RING_DBG("Using format %s", params.format.c_str());
     }
@@ -170,11 +168,8 @@ MediaDecoder::setupStream(AVMediaType mediaType)
     if (!fallback_) {
         RING_DBG() << "Finding " << streamType << " stream info";
         if ((ret = avformat_find_stream_info(inputCtx_, nullptr)) < 0) {
-            char errBuf[64];
-            av_strerror(ret, errBuf, sizeof(errBuf));
-
             // Always fail here
-            RING_ERR() << "Could not find " << streamType << " stream info: " << errBuf;
+            RING_ERR() << "Could not find " << streamType << " stream info: " << libav_utils::getError(ret);
             return -1;
         }
     }
@@ -231,9 +226,7 @@ MediaDecoder::setupStream(AVMediaType mediaType)
 
     ret = avcodec_open2(decoderCtx_, inputDecoder_, nullptr);
     if (ret < 0) {
-        char errBuf[64];
-        av_strerror(ret, errBuf, sizeof(errBuf));
-        RING_ERR() << "Could not open codec: " << errBuf;
+        RING_ERR() << "Could not open codec: " << libav_utils::getError(ret);
         return -1;
     }
 
@@ -257,9 +250,7 @@ MediaDecoder::decode(VideoFrame& result)
     } else if (ret == AVERROR_EOF) {
         return Status::EOFError;
     } else if (ret < 0) {
-        char errbuf[64];
-        av_strerror(ret, errbuf, sizeof(errbuf));
-        RING_ERR("Couldn't read frame: %s\n", errbuf);
+        RING_ERR("Couldn't read frame: %s\n", libav_utils::getError(ret).c_str());
         return Status::ReadError;
     }
 
@@ -329,9 +320,7 @@ MediaDecoder::decode(const AudioFrame& decodedFrame)
     } else if (ret == AVERROR_EOF) {
         return Status::EOFError;
     } else if (ret < 0) {
-        char errbuf[64];
-        av_strerror(ret, errbuf, sizeof(errbuf));
-        RING_ERR("Couldn't read frame: %s\n", errbuf);
+        RING_ERR("Couldn't read frame: %s\n", libav_utils::getError(ret).c_str());
         return Status::ReadError;
     }
 
diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp
index ccbae447ef..38de69e4ff 100644
--- a/src/media/media_encoder.cpp
+++ b/src/media/media_encoder.cpp
@@ -320,9 +320,7 @@ MediaEncoder::encode(VideoFrame& input, bool is_keyframe,
             // write the compressed frame
             ret = av_write_frame(outputCtx_, &pkt);
             if (ret < 0) {
-                char errbuf[64];
-                av_strerror(ret, errbuf, sizeof(errbuf));
-                RING_ERR("av_write_frame failed: %s", errbuf);
+                RING_ERR("av_write_frame failed: %s", libav_utils::getError(ret).c_str());
             } else
                 break;
         }
@@ -387,9 +385,7 @@ int MediaEncoder::encode_audio(const AudioBuffer &buffer)
                                            reinterpret_cast<const uint8_t *>(offset_ptr),
                                            buffer_size, 0);
         if (err < 0) {
-            char errbuf[128];
-            av_strerror(err, errbuf, sizeof(errbuf));
-            RING_ERR("Couldn't fill audio frame: %s: %d %d", errbuf,
+            RING_ERR("Couldn't fill audio frame: %s: %d %d", libav_utils::getError(err).c_str(),
                      frame->nb_samples, buffer_size);
             av_frame_free(&frame);
             return -1;
@@ -428,9 +424,7 @@ int MediaEncoder::encode_audio(const AudioBuffer &buffer)
                 // write the compressed frame
                 ret = av_write_frame(outputCtx_, &pkt);
                 if (ret < 0) {
-                    char errbuf[64];
-                    av_strerror(ret, errbuf, sizeof(errbuf));
-                    RING_ERR("av_write_frame failed: %s", errbuf);
+                    RING_ERR("av_write_frame failed: %s", libav_utils::getError(ret).c_str());
                 } else
                     break;
             }
@@ -474,9 +468,7 @@ int MediaEncoder::flush()
             // write the compressed frame
             ret = av_write_frame(outputCtx_, &pkt);
             if (ret < 0) {
-                char errbuf[64];
-                av_strerror(ret, errbuf, sizeof(errbuf));
-                RING_ERR("av_write_frame failed: %s", errbuf);
+                RING_ERR("av_write_frame failed: %s", libav_utils::getError(ret).c_str());
             } else
                 break;
         }
-- 
GitLab