FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
resman.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2025 - softworkz
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * output writers for filtergraph details
24  */
25 
26 #include "config.h"
27 
28 #include <string.h>
29 
30 #if CONFIG_RESOURCE_COMPRESSION
31 #include <zlib.h>
32 #endif
33 
34 #include "resman.h"
35 #include "libavutil/avassert.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/dict.h"
38 #include "libavutil/common.h"
39 
40 extern const unsigned char ff_graph_html_data[];
41 extern const unsigned int ff_graph_html_len;
42 
43 extern const unsigned char ff_graph_css_data[];
44 extern const unsigned ff_graph_css_len;
45 
49 };
50 
51 
52 static const AVClass resman_class = {
53  .class_name = "ResourceManager",
54 };
55 
56 typedef struct ResourceManagerContext {
57  const AVClass *class;
60 
62 
64 
65 
66 #if CONFIG_RESOURCE_COMPRESSION
67 
68 static int decompress_gzip(ResourceManagerContext *ctx, uint8_t *in, unsigned in_len, char **out, size_t *out_len)
69 {
70  z_stream strm;
71  unsigned chunk = 65534;
72  int ret;
73  uint8_t *buf;
74 
75  *out = NULL;
76  memset(&strm, 0, sizeof(strm));
77 
78  // Allocate output buffer with extra byte for null termination
79  buf = (uint8_t *)av_mallocz(chunk + 1);
80  if (!buf) {
81  av_log(ctx, AV_LOG_ERROR, "Failed to allocate decompression buffer\n");
82  return AVERROR(ENOMEM);
83  }
84 
85  // 15 + 16 tells zlib to detect GZIP or zlib automatically
86  ret = inflateInit2(&strm, 15 + 16);
87  if (ret != Z_OK) {
88  av_log(ctx, AV_LOG_ERROR, "Error during zlib initialization: %s\n", strm.msg);
89  av_free(buf);
90  return AVERROR(ENOSYS);
91  }
92 
93  strm.avail_in = in_len;
94  strm.next_in = in;
95  strm.avail_out = chunk;
96  strm.next_out = buf;
97 
98  ret = inflate(&strm, Z_FINISH);
99  if (ret != Z_OK && ret != Z_STREAM_END) {
100  av_log(ctx, AV_LOG_ERROR, "Inflate failed: %d, %s\n", ret, strm.msg);
101  inflateEnd(&strm);
102  av_free(buf);
103  return (ret == Z_STREAM_END) ? Z_OK : ((ret == Z_OK) ? Z_BUF_ERROR : ret);
104  }
105 
106  if (strm.avail_out == 0) {
107  // TODO: Error or loop decoding?
108  av_log(ctx, AV_LOG_WARNING, "Decompression buffer may be too small\n");
109  }
110 
111  *out_len = chunk - strm.avail_out;
112  buf[*out_len] = 0; // Ensure null termination
113 
114  inflateEnd(&strm);
115  *out = (char *)buf;
116  return Z_OK;
117 }
118 #endif
119 
121 {
123 
125 
127 }
128 
129 
131 {
133  FFResourceDefinition resource_definition = { 0 };
134  AVDictionaryEntry *dic_entry;
135  char *res = NULL;
136 
137  for (unsigned i = 0; i < FF_ARRAY_ELEMS(resource_definitions); ++i) {
139  if (def.resource_id == resource_id) {
140  resource_definition = def;
141  break;
142  }
143  }
144 
145  av_assert1(resource_definition.name);
146 
148 
149  dic_entry = av_dict_get(ctx->resource_dic, resource_definition.name, NULL, 0);
150 
151  if (!dic_entry) {
152  int dict_ret;
153 
154 #if CONFIG_RESOURCE_COMPRESSION
155 
156  char *out = NULL;
157  size_t out_len;
158 
159  int ret = decompress_gzip(ctx, (uint8_t *)resource_definition.data, *resource_definition.data_len, &out, &out_len);
160 
161  if (ret) {
162  av_log(ctx, AV_LOG_ERROR, "Unable to decompress the resource with ID %d\n", resource_id);
163  goto end;
164  }
165 
166  dict_ret = av_dict_set(&ctx->resource_dic, resource_definition.name, out, 0);
167  if (dict_ret < 0) {
168  av_log(ctx, AV_LOG_ERROR, "Failed to store decompressed resource in dictionary: %d\n", dict_ret);
169  av_freep(&out);
170  goto end;
171  }
172 
173  av_freep(&out);
174 #else
175 
176  dict_ret = av_dict_set(&ctx->resource_dic, resource_definition.name, (const char *)resource_definition.data, 0);
177  if (dict_ret < 0) {
178  av_log(ctx, AV_LOG_ERROR, "Failed to store resource in dictionary: %d\n", dict_ret);
179  goto end;
180  }
181 
182 #endif
183  dic_entry = av_dict_get(ctx->resource_dic, resource_definition.name, NULL, 0);
184 
185  if (!dic_entry) {
186  av_log(ctx, AV_LOG_ERROR, "Failed to retrieve resource from dictionary after storing it\n");
187  goto end;
188  }
189  }
190 
191  res = dic_entry->value;
192 
193 end:
195  return res;
196 }
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
FFResourceDefinition::data
const unsigned char * data
Definition: resman.h:41
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
out
FILE * out
Definition: movenc.c:55
FF_RESOURCE_GRAPH_CSS
@ FF_RESOURCE_GRAPH_CSS
Definition: resman.h:33
pixdesc.h
ff_resman_uninit
void ff_resman_uninit(void)
Definition: resman.c:120
AVDictionary
Definition: dict.c:32
resman.h
ff_mutex_unlock
static int ff_mutex_unlock(AVMutex *mutex)
Definition: thread.h:189
inflate
static void inflate(uint8_t *dst, const uint8_t *p1, int width, int threshold, const uint8_t *coordinates[], int coord, int maxc)
Definition: vf_neighbor.c:194
ff_graph_css_len
const unsigned ff_graph_css_len
ff_resman_get_string
char * ff_resman_get_string(FFResourceId resource_id)
Definition: resman.c:130
mutex
static AVMutex mutex
Definition: resman.c:61
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AVMutex
#define AVMutex
Definition: thread.h:184
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
ResourceManagerContext
Definition: resman.c:56
FFResourceDefinition::name
const char * name
Definition: resman.h:39
resource_definitions
static const FFResourceDefinition resource_definitions[]
Definition: resman.c:46
ctx
AVFormatContext * ctx
Definition: movenc.c:49
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
ff_graph_html_data
const unsigned char ff_graph_html_data[]
AV_MUTEX_INITIALIZER
#define AV_MUTEX_INITIALIZER
Definition: thread.h:185
ResourceManagerContext::class
const AVClass * class
Definition: resman.c:57
ff_mutex_lock
static int ff_mutex_lock(AVMutex *mutex)
Definition: thread.h:188
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
ff_graph_html_len
const unsigned int ff_graph_html_len
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_graph_css_data
const unsigned char ff_graph_css_data[]
common.h
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:57
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
FFResourceId
FFResourceId
Definition: resman.h:32
FFResourceDefinition::data_len
const unsigned * data_len
Definition: resman.h:42
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
dict.h
FFResourceDefinition::resource_id
FFResourceId resource_id
Definition: resman.h:38
FFResourceDefinition
Definition: resman.h:37
FF_RESOURCE_GRAPH_HTML
@ FF_RESOURCE_GRAPH_HTML
Definition: resman.h:34
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:86
resman_class
static const AVClass resman_class
Definition: resman.c:52
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVDictionaryEntry::value
char * value
Definition: dict.h:92
ResourceManagerContext::resource_dic
AVDictionary * resource_dic
Definition: resman.c:58
resman_ctx
static ResourceManagerContext resman_ctx
Definition: resman.c:63