Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * This file is part of FFmpeg. | |
3 | * | |
4 | * FFmpeg is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU Lesser General Public | |
6 | * License as published by the Free Software Foundation; either | |
7 | * version 2.1 of the License, or (at your option) any later version. | |
8 | * | |
9 | * FFmpeg is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | * Lesser General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU Lesser General Public | |
15 | * License along with FFmpeg; if not, write to the Free Software | |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
17 | */ | |
18 | ||
19 | #include "libavutil/avassert.h" | |
20 | #include "libavutil/samplefmt.h" | |
21 | #include "libavutil/pixfmt.h" | |
22 | #include "libavcodec/avcodec.h" | |
23 | #include "avdevice.h" | |
24 | #include "config.h" | |
25 | ||
092a9121 DM |
26 | #include "libavutil/ffversion.h" |
27 | const char av_device_ffversion[] = "FFmpeg version " FFMPEG_VERSION; | |
28 | ||
2ba45a60 DM |
29 | #define E AV_OPT_FLAG_ENCODING_PARAM |
30 | #define D AV_OPT_FLAG_DECODING_PARAM | |
31 | #define A AV_OPT_FLAG_AUDIO_PARAM | |
32 | #define V AV_OPT_FLAG_VIDEO_PARAM | |
33 | #define OFFSET(x) offsetof(AVDeviceCapabilitiesQuery, x) | |
34 | ||
35 | const AVOption av_device_capabilities[] = { | |
36 | { "codec", "codec", OFFSET(codec), AV_OPT_TYPE_INT, | |
37 | {.i64 = AV_CODEC_ID_NONE}, AV_CODEC_ID_NONE, INT_MAX, E|D|A|V }, | |
38 | { "sample_format", "sample format", OFFSET(sample_format), AV_OPT_TYPE_INT, | |
39 | {.i64 = AV_SAMPLE_FMT_NONE}, -1, INT_MAX, E|D|A }, | |
40 | { "sample_rate", "sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, | |
41 | {.i64 = -1}, -1, INT_MAX, E|D|A }, | |
42 | { "channels", "channels", OFFSET(channels), AV_OPT_TYPE_INT, | |
43 | {.i64 = -1}, -1, INT_MAX, E|D|A }, | |
44 | { "channel_layout", "channel layout", OFFSET(channel_layout), AV_OPT_TYPE_INT64, | |
45 | {.i64 = -1}, -1, INT_MAX, E|D|A }, | |
46 | { "pixel_format", "pixel format", OFFSET(pixel_format), AV_OPT_TYPE_INT, | |
47 | {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, E|D|V }, | |
48 | { "window_size", "window size", OFFSET(window_width), AV_OPT_TYPE_IMAGE_SIZE, | |
49 | {.str = NULL}, -1, INT_MAX, E|D|V }, | |
50 | { "frame_size", "frame size", OFFSET(frame_width), AV_OPT_TYPE_IMAGE_SIZE, | |
51 | {.str = NULL}, -1, INT_MAX, E|D|V }, | |
52 | { "fps", "fps", OFFSET(fps), AV_OPT_TYPE_RATIONAL, | |
53 | {.dbl = -1}, -1, INT_MAX, E|D|V }, | |
54 | { NULL } | |
55 | }; | |
56 | ||
57 | #undef E | |
58 | #undef D | |
59 | #undef A | |
60 | #undef V | |
61 | #undef OFFSET | |
62 | ||
63 | unsigned avdevice_version(void) | |
64 | { | |
65 | av_assert0(LIBAVDEVICE_VERSION_MICRO >= 100); | |
66 | return LIBAVDEVICE_VERSION_INT; | |
67 | } | |
68 | ||
69 | const char * avdevice_configuration(void) | |
70 | { | |
71 | return FFMPEG_CONFIGURATION; | |
72 | } | |
73 | ||
74 | const char * avdevice_license(void) | |
75 | { | |
76 | #define LICENSE_PREFIX "libavdevice license: " | |
77 | return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; | |
78 | } | |
79 | ||
80 | static void *av_device_next(void *prev, int output, | |
81 | AVClassCategory c1, AVClassCategory c2) | |
82 | { | |
83 | const AVClass *pc; | |
84 | AVClassCategory category = AV_CLASS_CATEGORY_NA; | |
85 | do { | |
86 | if (output) { | |
87 | if (!(prev = av_oformat_next(prev))) | |
88 | break; | |
89 | pc = ((AVOutputFormat *)prev)->priv_class; | |
90 | } else { | |
91 | if (!(prev = av_iformat_next(prev))) | |
92 | break; | |
93 | pc = ((AVInputFormat *)prev)->priv_class; | |
94 | } | |
95 | if (!pc) | |
96 | continue; | |
97 | category = pc->category; | |
98 | } while (category != c1 && category != c2); | |
99 | return prev; | |
100 | } | |
101 | ||
102 | AVInputFormat *av_input_audio_device_next(AVInputFormat *d) | |
103 | { | |
104 | return av_device_next(d, 0, AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, | |
105 | AV_CLASS_CATEGORY_DEVICE_INPUT); | |
106 | } | |
107 | ||
108 | AVInputFormat *av_input_video_device_next(AVInputFormat *d) | |
109 | { | |
110 | return av_device_next(d, 0, AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, | |
111 | AV_CLASS_CATEGORY_DEVICE_INPUT); | |
112 | } | |
113 | ||
114 | AVOutputFormat *av_output_audio_device_next(AVOutputFormat *d) | |
115 | { | |
116 | return av_device_next(d, 1, AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, | |
117 | AV_CLASS_CATEGORY_DEVICE_OUTPUT); | |
118 | } | |
119 | ||
120 | AVOutputFormat *av_output_video_device_next(AVOutputFormat *d) | |
121 | { | |
122 | return av_device_next(d, 1, AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT, | |
123 | AV_CLASS_CATEGORY_DEVICE_OUTPUT); | |
124 | } | |
125 | ||
126 | int avdevice_app_to_dev_control_message(struct AVFormatContext *s, enum AVAppToDevMessageType type, | |
127 | void *data, size_t data_size) | |
128 | { | |
129 | if (!s->oformat || !s->oformat->control_message) | |
130 | return AVERROR(ENOSYS); | |
131 | return s->oformat->control_message(s, type, data, data_size); | |
132 | } | |
133 | ||
134 | int avdevice_dev_to_app_control_message(struct AVFormatContext *s, enum AVDevToAppMessageType type, | |
135 | void *data, size_t data_size) | |
136 | { | |
137 | if (!s->control_message_cb) | |
138 | return AVERROR(ENOSYS); | |
139 | return s->control_message_cb(s, type, data, data_size); | |
140 | } | |
141 | ||
142 | int avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s, | |
143 | AVDictionary **device_options) | |
144 | { | |
145 | int ret; | |
146 | av_assert0(s && caps); | |
147 | av_assert0(s->iformat || s->oformat); | |
148 | if ((s->oformat && !s->oformat->create_device_capabilities) || | |
149 | (s->iformat && !s->iformat->create_device_capabilities)) | |
150 | return AVERROR(ENOSYS); | |
151 | *caps = av_mallocz(sizeof(**caps)); | |
152 | if (!(*caps)) | |
153 | return AVERROR(ENOMEM); | |
154 | (*caps)->device_context = s; | |
155 | if (((ret = av_opt_set_dict(s->priv_data, device_options)) < 0)) | |
156 | goto fail; | |
157 | if (s->iformat) { | |
158 | if ((ret = s->iformat->create_device_capabilities(s, *caps)) < 0) | |
159 | goto fail; | |
160 | } else { | |
161 | if ((ret = s->oformat->create_device_capabilities(s, *caps)) < 0) | |
162 | goto fail; | |
163 | } | |
164 | av_opt_set_defaults(*caps); | |
165 | return 0; | |
166 | fail: | |
167 | av_freep(caps); | |
168 | return ret; | |
169 | } | |
170 | ||
171 | void avdevice_capabilities_free(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s) | |
172 | { | |
173 | if (!s || !caps || !(*caps)) | |
174 | return; | |
175 | av_assert0(s->iformat || s->oformat); | |
176 | if (s->iformat) { | |
177 | if (s->iformat->free_device_capabilities) | |
178 | s->iformat->free_device_capabilities(s, *caps); | |
179 | } else { | |
180 | if (s->oformat->free_device_capabilities) | |
181 | s->oformat->free_device_capabilities(s, *caps); | |
182 | } | |
183 | av_freep(caps); | |
184 | } | |
185 | ||
186 | int avdevice_list_devices(AVFormatContext *s, AVDeviceInfoList **device_list) | |
187 | { | |
188 | int ret; | |
189 | av_assert0(s); | |
190 | av_assert0(device_list); | |
191 | av_assert0(s->oformat || s->iformat); | |
192 | if ((s->oformat && !s->oformat->get_device_list) || | |
193 | (s->iformat && !s->iformat->get_device_list)) { | |
194 | *device_list = NULL; | |
195 | return AVERROR(ENOSYS); | |
196 | } | |
197 | *device_list = av_mallocz(sizeof(AVDeviceInfoList)); | |
198 | if (!(*device_list)) | |
199 | return AVERROR(ENOMEM); | |
200 | /* no default device by default */ | |
201 | (*device_list)->default_device = -1; | |
202 | if (s->oformat) | |
203 | ret = s->oformat->get_device_list(s, *device_list); | |
204 | else | |
205 | ret = s->iformat->get_device_list(s, *device_list); | |
206 | if (ret < 0) | |
207 | avdevice_free_list_devices(device_list); | |
208 | return ret; | |
209 | } | |
210 | ||
211 | void avdevice_free_list_devices(AVDeviceInfoList **device_list) | |
212 | { | |
213 | AVDeviceInfoList *list; | |
214 | AVDeviceInfo *dev; | |
215 | int i; | |
216 | ||
217 | av_assert0(device_list); | |
218 | list = *device_list; | |
219 | if (!list) | |
220 | return; | |
221 | ||
222 | for (i = 0; i < list->nb_devices; i++) { | |
223 | dev = list->devices[i]; | |
224 | if (dev) { | |
f6fa7814 DM |
225 | av_freep(&dev->device_name); |
226 | av_freep(&dev->device_description); | |
2ba45a60 DM |
227 | av_free(dev); |
228 | } | |
229 | } | |
f6fa7814 | 230 | av_freep(&list->devices); |
2ba45a60 DM |
231 | av_freep(device_list); |
232 | } |