libav_utils.cpp 4.06 KB
Newer Older
1
/*
Adrien Béraud's avatar
Adrien Béraud committed
2
 *  Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
3
 *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
4
 *  Author: Luca Barbato <lu_zero@gentoo.org>
5
 *  Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
20 21 22 23 24 25 26 27 28 29 30 31 32
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
 */

33 34
#include "libav_deps.h" // MUST BE INCLUDED FIRST

Alexandre Lision's avatar
Alexandre Lision committed
35
#include "config.h"
36
#include "video/video_base.h"
37 38
#include "logger.h"

39
#include <vector>
40 41 42
#include <algorithm>
#include <string>
#include <iostream>
43 44 45
#include <thread>
#include <mutex>
#include <exception>
46

Guillaume Roguez's avatar
Guillaume Roguez committed
47 48
namespace ring { namespace libav_utils {

49
// protect libav/ffmpeg access
50 51
static int
avcodecManageMutex(void **data, enum AVLockOp op)
52
{
53
    auto mutex = reinterpret_cast<std::mutex**>(data);
54 55
    int ret = 0;
    switch (op) {
Tristan Matthews's avatar
Tristan Matthews committed
56
        case AV_LOCK_CREATE:
57 58 59
            try {
                *mutex = new std::mutex;
            } catch (const std::bad_alloc& e) {
60
                return AVERROR(ENOMEM);
61
            }
62
            break;
Tristan Matthews's avatar
Tristan Matthews committed
63
        case AV_LOCK_OBTAIN:
64
            (*mutex)->lock();
Tristan Matthews's avatar
Tristan Matthews committed
65 66
            break;
        case AV_LOCK_RELEASE:
67
            (*mutex)->unlock();
Tristan Matthews's avatar
Tristan Matthews committed
68
            break;
69
        case AV_LOCK_DESTROY:
70 71
            delete *mutex;
            *mutex = nullptr;
72 73
            break;
        default:
74
#ifdef AVERROR_BUG
75
            return AVERROR_BUG;
76 77
#else
            break;
78
#endif
79
    }
80
    return AVERROR(ret);
81 82
}

83
static constexpr const char* AVLOGLEVEL = "AVLOGLEVEL";
84

85 86 87 88
static void
setAvLogLevel()
{
    char* envvar = getenv(AVLOGLEVEL);
89
    signed level = AV_LOG_WARNING;
90 91 92 93 94 95 96 97 98 99 100 101

    if (envvar != nullptr) {
        if (not (std::istringstream(envvar) >> level))
            level = AV_LOG_ERROR;

        level = std::max(AV_LOG_QUIET, std::min(level, AV_LOG_DEBUG));
    }
    av_log_set_level(level);
}

static void
init_once()
102
{
103
    av_register_all();
104
    avdevice_register_all();
105
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 13, 0)
106
    avformat_network_init();
107
#endif
108

109
    av_lockmgr_register(avcodecManageMutex);
110

Vittorio Giovara's avatar
Vittorio Giovara committed
111
    if (getDebugMode())
112
        setAvLogLevel();
113 114
}

115
static std::once_flag already_called;
116

117
void ring_avcodec_init()
118
{
119
    std::call_once(already_called, init_once);
120 121
}

122

123 124 125
int libav_pixel_format(int fmt)
{
    switch (fmt) {
126
        case video::VIDEO_PIXFMT_BGRA: return PIXEL_FORMAT(BGRA);
127
        case video::VIDEO_PIXFMT_RGBA: return PIXEL_FORMAT(RGBA);
128
        case video::VIDEO_PIXFMT_YUV420P: return PIXEL_FORMAT(YUV420P);
129 130 131 132
    }
    return fmt;
}

133
int ring_pixel_format(int fmt)
134 135
{
    switch (fmt) {
136
        case PIXEL_FORMAT(YUV420P): return video::VIDEO_PIXFMT_YUV420P;
137 138 139 140
    }
    return fmt;
}

141
void ring_url_split(const char *url,
142 143 144 145 146 147 148
                   char *hostname, size_t hostname_size, int *port,
                   char *path, size_t path_size)
{
    av_url_split(NULL, 0, NULL, 0, hostname, hostname_size, port,
                 path, path_size, url);
}

Guillaume Roguez's avatar
Guillaume Roguez committed
149
}} // namespace ring::libav_utils