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 26#define E AV_OPT_FLAG_ENCODING_PARAM 27#define D AV_OPT_FLAG_DECODING_PARAM 28#define A AV_OPT_FLAG_AUDIO_PARAM 29#define V AV_OPT_FLAG_VIDEO_PARAM 30#define OFFSET(x) offsetof(AVDeviceCapabilitiesQuery, x) 31 32const AVOption av_device_capabilities[] = { 33 { "codec", "codec", OFFSET(codec), AV_OPT_TYPE_INT, 34 {.i64 = AV_CODEC_ID_NONE}, AV_CODEC_ID_NONE, INT_MAX, E|D|A|V }, 35 { "sample_format", "sample format", OFFSET(sample_format), AV_OPT_TYPE_INT, 36 {.i64 = AV_SAMPLE_FMT_NONE}, -1, INT_MAX, E|D|A }, 37 { "sample_rate", "sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, 38 {.i64 = -1}, -1, INT_MAX, E|D|A }, 39 { "channels", "channels", OFFSET(channels), AV_OPT_TYPE_INT, 40 {.i64 = -1}, -1, INT_MAX, E|D|A }, 41 { "channel_layout", "channel layout", OFFSET(channel_layout), AV_OPT_TYPE_INT64, 42 {.i64 = -1}, -1, INT_MAX, E|D|A }, 43 { "pixel_format", "pixel format", OFFSET(pixel_format), AV_OPT_TYPE_INT, 44 {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, E|D|V }, 45 { "window_size", "window size", OFFSET(window_width), AV_OPT_TYPE_IMAGE_SIZE, 46 {.str = NULL}, -1, INT_MAX, E|D|V }, 47 { "frame_size", "frame size", OFFSET(frame_width), AV_OPT_TYPE_IMAGE_SIZE, 48 {.str = NULL}, -1, INT_MAX, E|D|V }, 49 { "fps", "fps", OFFSET(fps), AV_OPT_TYPE_RATIONAL, 50 {.dbl = -1}, -1, INT_MAX, E|D|V }, 51 { NULL } 52}; 53 54#undef E 55#undef D 56#undef A 57#undef V 58#undef OFFSET 59 60unsigned avdevice_version(void) 61{ 62 av_assert0(LIBAVDEVICE_VERSION_MICRO >= 100); 63 return LIBAVDEVICE_VERSION_INT; 64} 65 66const char * avdevice_configuration(void) 67{ 68 return FFMPEG_CONFIGURATION; 69} 70 71const char * avdevice_license(void) 72{ 73#define LICENSE_PREFIX "libavdevice license: " 74 return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; 75} 76 77static void *av_device_next(void *prev, int output, 78 AVClassCategory c1, AVClassCategory c2) 79{ 80 const AVClass *pc; 81 AVClassCategory category = AV_CLASS_CATEGORY_NA; 82 do { 83 if (output) { 84 if (!(prev = av_oformat_next(prev))) 85 break; 86 pc = ((AVOutputFormat *)prev)->priv_class; 87 } else { 88 if (!(prev = av_iformat_next(prev))) 89 break; 90 pc = ((AVInputFormat *)prev)->priv_class; 91 } 92 if (!pc) 93 continue; 94 category = pc->category; 95 } while (category != c1 && category != c2); 96 return prev; 97} 98 99AVInputFormat *av_input_audio_device_next(AVInputFormat *d) 100{ 101 return av_device_next(d, 0, AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, 102 AV_CLASS_CATEGORY_DEVICE_INPUT); 103} 104 105AVInputFormat *av_input_video_device_next(AVInputFormat *d) 106{ 107 return av_device_next(d, 0, AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, 108 AV_CLASS_CATEGORY_DEVICE_INPUT); 109} 110 111AVOutputFormat *av_output_audio_device_next(AVOutputFormat *d) 112{ 113 return av_device_next(d, 1, AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, 114 AV_CLASS_CATEGORY_DEVICE_OUTPUT); 115} 116 117AVOutputFormat *av_output_video_device_next(AVOutputFormat *d) 118{ 119 return av_device_next(d, 1, AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT, 120 AV_CLASS_CATEGORY_DEVICE_OUTPUT); 121} 122 123int avdevice_app_to_dev_control_message(struct AVFormatContext *s, enum AVAppToDevMessageType type, 124 void *data, size_t data_size) 125{ 126 if (!s->oformat || !s->oformat->control_message) 127 return AVERROR(ENOSYS); 128 return s->oformat->control_message(s, type, data, data_size); 129} 130 131int avdevice_dev_to_app_control_message(struct AVFormatContext *s, enum AVDevToAppMessageType type, 132 void *data, size_t data_size) 133{ 134 if (!s->control_message_cb) 135 return AVERROR(ENOSYS); 136 return s->control_message_cb(s, type, data, data_size); 137} 138 139int avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s, 140 AVDictionary **device_options) 141{ 142 int ret; 143 av_assert0(s && caps); 144 av_assert0(s->iformat || s->oformat); 145 if ((s->oformat && !s->oformat->create_device_capabilities) || 146 (s->iformat && !s->iformat->create_device_capabilities)) 147 return AVERROR(ENOSYS); 148 *caps = av_mallocz(sizeof(**caps)); 149 if (!(*caps)) 150 return AVERROR(ENOMEM); 151 (*caps)->device_context = s; 152 if (((ret = av_opt_set_dict(s->priv_data, device_options)) < 0)) 153 goto fail; 154 if (s->iformat) { 155 if ((ret = s->iformat->create_device_capabilities(s, *caps)) < 0) 156 goto fail; 157 } else { 158 if ((ret = s->oformat->create_device_capabilities(s, *caps)) < 0) 159 goto fail; 160 } 161 av_opt_set_defaults(*caps); 162 return 0; 163 fail: 164 av_freep(caps); 165 return ret; 166} 167 168void avdevice_capabilities_free(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s) 169{ 170 if (!s || !caps || !(*caps)) 171 return; 172 av_assert0(s->iformat || s->oformat); 173 if (s->iformat) { 174 if (s->iformat->free_device_capabilities) 175 s->iformat->free_device_capabilities(s, *caps); 176 } else { 177 if (s->oformat->free_device_capabilities) 178 s->oformat->free_device_capabilities(s, *caps); 179 } 180 av_freep(caps); 181} 182 183int avdevice_list_devices(AVFormatContext *s, AVDeviceInfoList **device_list) 184{ 185 int ret; 186 av_assert0(s); 187 av_assert0(device_list); 188 av_assert0(s->oformat || s->iformat); 189 if ((s->oformat && !s->oformat->get_device_list) || 190 (s->iformat && !s->iformat->get_device_list)) { 191 *device_list = NULL; 192 return AVERROR(ENOSYS); 193 } 194 *device_list = av_mallocz(sizeof(AVDeviceInfoList)); 195 if (!(*device_list)) 196 return AVERROR(ENOMEM); 197 /* no default device by default */ 198 (*device_list)->default_device = -1; 199 if (s->oformat) 200 ret = s->oformat->get_device_list(s, *device_list); 201 else 202 ret = s->iformat->get_device_list(s, *device_list); 203 if (ret < 0) 204 avdevice_free_list_devices(device_list); 205 return ret; 206} 207 208void avdevice_free_list_devices(AVDeviceInfoList **device_list) 209{ 210 AVDeviceInfoList *list; 211 AVDeviceInfo *dev; 212 int i; 213 214 av_assert0(device_list); 215 list = *device_list; 216 if (!list) 217 return; 218 219 for (i = 0; i < list->nb_devices; i++) { 220 dev = list->devices[i]; 221 if (dev) { 222 av_free(dev->device_name); 223 av_free(dev->device_description); 224 av_free(dev); 225 } 226 } 227 av_free(list->devices); 228 av_freep(device_list); 229} 230