Blender V5.0
bpy_app_ffmpeg.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_utildefines.h"
10#include <Python.h>
11
12#include "../generic/python_compat.hh" /* IWYU pragma: keep. */
13
14#include "bpy_app_ffmpeg.hh"
15
17
18#ifdef WITH_FFMPEG
19extern "C" {
20# include <libavcodec/avcodec.h>
21# include <libavdevice/avdevice.h>
22# include <libavformat/avformat.h>
23# include <libavutil/avutil.h>
24# include <libswscale/swscale.h>
25}
26#endif
27
28static PyTypeObject BlenderAppFFmpegType;
29
30#define DEF_FFMPEG_LIB_VERSION(lib) \
31 {(#lib "_version"), ("The " #lib " version as a tuple of 3 numbers")}, \
32 { \
33 (#lib "_version_string"), ("The " #lib " version formatted as a string") \
34 }
35
36static PyStructSequence_Field app_ffmpeg_info_fields[] = {
37 {"supported", "Boolean, True when Blender is built with FFmpeg support"},
38
40 DEF_FFMPEG_LIB_VERSION(avdevice),
41 DEF_FFMPEG_LIB_VERSION(avformat),
44 {nullptr},
45};
46
47#undef DEF_FFMPEG_LIB_VERSION
48
49static PyStructSequence_Desc app_ffmpeg_info_desc = {
50 /*name*/ "bpy.app.ffmpeg",
51 /*doc*/ "This module contains information about FFmpeg blender is linked against",
52 /*fields*/ app_ffmpeg_info_fields,
53 /*n_in_sequence*/ ARRAY_SIZE(app_ffmpeg_info_fields) - 1,
54};
55
56static PyObject *make_ffmpeg_info()
57{
58 PyObject *ffmpeg_info;
59 int pos = 0;
60
61#ifdef WITH_FFMPEG
62 int curversion;
63#endif
64
65 ffmpeg_info = PyStructSequence_New(&BlenderAppFFmpegType);
66 if (ffmpeg_info == nullptr) {
67 return nullptr;
68 }
69
70#if 0 /* UNUSED */
71# define SetIntItem(flag) PyStructSequence_SET_ITEM(ffmpeg_info, pos++, PyLong_FromLong(flag))
72#endif
73#ifndef WITH_FFMPEG
74# define SetStrItem(str) PyStructSequence_SET_ITEM(ffmpeg_info, pos++, PyUnicode_FromString(str))
75#endif
76#define SetObjItem(obj) PyStructSequence_SET_ITEM(ffmpeg_info, pos++, obj)
77
78#ifdef WITH_FFMPEG
79# define FFMPEG_LIB_VERSION(lib) \
80 { \
81 curversion = lib##_version(); \
82 SetObjItem( \
83 PyC_Tuple_Pack_I32({curversion >> 16, (curversion >> 8) % 256, curversion % 256})); \
84 SetObjItem(PyUnicode_FromFormat( \
85 "%2d, %2d, %2d", curversion >> 16, (curversion >> 8) % 256, curversion % 256)); \
86 } \
87 (void)0
88#else
89# define FFMPEG_LIB_VERSION(lib) \
90 { \
91 SetStrItem("Unknown"); \
92 SetStrItem("Unknown"); \
93 } \
94 (void)0
95#endif
96
97#ifdef WITH_FFMPEG
98 SetObjItem(PyBool_FromLong(1));
99#else
100 SetObjItem(PyBool_FromLong(0));
101#endif
102
103 FFMPEG_LIB_VERSION(avcodec);
104 FFMPEG_LIB_VERSION(avdevice);
105 FFMPEG_LIB_VERSION(avformat);
106 FFMPEG_LIB_VERSION(avutil);
107 FFMPEG_LIB_VERSION(swscale);
108
109#undef FFMPEG_LIB_VERSION
110
111 if (UNLIKELY(PyErr_Occurred())) {
112 Py_DECREF(ffmpeg_info);
113 return nullptr;
114 }
115
116// #undef SetIntItem
117#undef SetStrItem
118#undef SetObjItem
119
120 return ffmpeg_info;
121}
122
124{
125 PyObject *ret;
126
127 PyStructSequence_InitType(&BlenderAppFFmpegType, &app_ffmpeg_info_desc);
128
130
131 /* prevent user from creating new instances */
132 BlenderAppFFmpegType.tp_init = nullptr;
133 BlenderAppFFmpegType.tp_new = nullptr;
134 /* Without this we can't do `set(sys.modules)` #29635. */
135 BlenderAppFFmpegType.tp_hash = (hashfunc)Py_HashPointer;
136
137 return ret;
138}
#define ARRAY_SIZE(arr)
#define UNLIKELY(x)
#define DEF_FFMPEG_LIB_VERSION(lib)
static PyTypeObject BlenderAppFFmpegType
static PyStructSequence_Desc app_ffmpeg_info_desc
PyObject * BPY_app_ffmpeg_struct()
static PyStructSequence_Field app_ffmpeg_info_fields[]
#define FFMPEG_LIB_VERSION(lib)
static PyObject * make_ffmpeg_info()
#define SetObjItem(obj)
uint pos
header-only compatibility defines.
#define Py_HashPointer
Py_DECREF(oname)
return ret