1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
/* Spa FFmpeg support */
/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */
/* SPDX-License-Identifier: MIT */
#include <errno.h>
#include <stdio.h>
#include <spa/support/plugin.h>
#include <spa/support/log.h>
#include <spa/node/node.h>
#include <libavcodec/avcodec.h>
#include "ffmpeg.h"
static int
ffmpeg_dec_init(const struct spa_handle_factory *factory,
struct spa_handle *handle,
const struct spa_dict *info,
const struct spa_support *support,
uint32_t n_support)
{
if (factory == NULL || handle == NULL)
return -EINVAL;
return spa_ffmpeg_dec_init(handle, info, support, n_support);
}
static int
ffmpeg_enc_init(const struct spa_handle_factory *factory,
struct spa_handle *handle,
const struct spa_dict *info,
const struct spa_support *support,
uint32_t n_support)
{
if (factory == NULL || handle == NULL)
return -EINVAL;
return spa_ffmpeg_enc_init(handle, info, support, n_support);
}
static const struct spa_interface_info ffmpeg_interfaces[] = {
{SPA_TYPE_INTERFACE_Node, },
};
static int
ffmpeg_enum_interface_info(const struct spa_handle_factory *factory,
const struct spa_interface_info **info,
uint32_t *index)
{
if (factory == NULL || info == NULL || index == NULL)
return -EINVAL;
if (*index < SPA_N_ELEMENTS(ffmpeg_interfaces))
*info = &ffmpeg_interfaces[(*index)++];
else
return 0;
return 1;
}
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 10, 100)
static const AVCodec *find_codec_by_index(uint32_t index)
{
static void *av_iter_data;
static uint32_t next_index;
const AVCodec *c = NULL;
if (index == 0) {
av_iter_data = NULL;
next_index = 0;
}
while (next_index <= index) {
c = av_codec_iterate(&av_iter_data);
next_index += 1;
if (!c)
break;
}
return c;
}
#else
static const AVCodec *find_codec_by_index(uint32_t index)
{
static const AVCodec *last_codec;
static uint32_t next_index;
if (index == 0) {
last_codec = NULL;
next_index = 0;
}
while (next_index <= index) {
last_codec = av_codec_next(last_codec);
next_index += 1;
if (!last_codec)
break;
}
return last_codec;
}
#endif
SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED;
SPA_EXPORT
int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
{
static char name[128];
static struct spa_handle_factory f = {
SPA_VERSION_HANDLE_FACTORY,
.name = name,
.enum_interface_info = ffmpeg_enum_interface_info,
};
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)
avcodec_register_all();
#endif
const AVCodec *c = find_codec_by_index(*index);
if (c == NULL)
return 0;
if (av_codec_is_encoder(c)) {
snprintf(name, sizeof(name), "encoder.%s", c->name);
f.get_size = spa_ffmpeg_enc_get_size;
f.init = ffmpeg_enc_init;
} else {
snprintf(name, sizeof(name), "decoder.%s", c->name);
f.get_size = spa_ffmpeg_dec_get_size;
f.init = ffmpeg_dec_init;
}
*factory = &f;
(*index)++;
return 1;
}
|