| ... | ... |
@@ -188,6 +188,7 @@ External library support: |
| 188 | 188 |
--enable-libxavs enable AVS encoding via xavs [no] |
| 189 | 189 |
--enable-libxvid enable Xvid encoding via xvidcore, |
| 190 | 190 |
native MPEG-4/Xvid encoder exists [no] |
| 191 |
+ --enable-openal enable OpenAL 1.1 capture support [no] |
|
| 191 | 192 |
--enable-mlib enable Sun medialib [no] |
| 192 | 193 |
--enable-zlib enable zlib [autodetect] |
| 193 | 194 |
|
| ... | ... |
@@ -959,6 +960,7 @@ CONFIG_LIST=" |
| 959 | 959 |
mpegaudiodsp |
| 960 | 960 |
network |
| 961 | 961 |
nonfree |
| 962 |
+ openal |
|
| 962 | 963 |
pic |
| 963 | 964 |
postproc |
| 964 | 965 |
rdft |
| ... | ... |
@@ -1471,6 +1473,7 @@ dv1394_indev_deps="dv1394 dv_demuxer" |
| 1471 | 1471 |
fbdev_indev_deps="linux_fb_h" |
| 1472 | 1472 |
jack_indev_deps="jack_jack_h sem_timedwait" |
| 1473 | 1473 |
libdc1394_indev_deps="libdc1394" |
| 1474 |
+openal_indev_deps="openal" |
|
| 1474 | 1475 |
oss_indev_deps_any="soundcard_h sys_soundcard_h" |
| 1475 | 1476 |
oss_outdev_deps_any="soundcard_h sys_soundcard_h" |
| 1476 | 1477 |
sdl_outdev_deps="sdl" |
| ... | ... |
@@ -2948,6 +2951,11 @@ enabled libx264 && require libx264 x264.h x264_encoder_encode -lx264 && |
| 2948 | 2948 |
die "ERROR: libx264 version must be >= 0.115."; } |
| 2949 | 2949 |
enabled libxavs && require libxavs xavs.h xavs_encoder_encode -lxavs |
| 2950 | 2950 |
enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore |
| 2951 |
+enabled openal && { { for al_libs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do
|
|
| 2952 |
+ check_lib 'AL/al.h' alGetError "${al_libs}" && break; done } ||
|
|
| 2953 |
+ die "ERROR: openal not found"; } && |
|
| 2954 |
+ { check_cpp_condition "AL/al.h" "defined(AL_VERSION_1_1)" ||
|
|
| 2955 |
+ die "ERROR: openal version must be 1.1 or compatible"; } |
|
| 2951 | 2956 |
enabled mlib && require mediaLib mlib_types.h mlib_VectorSub_S16_U8_Mod -lmlib |
| 2952 | 2957 |
|
| 2953 | 2958 |
SDL_CONFIG="${cross_prefix}sdl-config"
|
| ... | ... |
@@ -3247,6 +3255,7 @@ echo "libvpx enabled ${libvpx-no}"
|
| 3247 | 3247 |
echo "libx264 enabled ${libx264-no}"
|
| 3248 | 3248 |
echo "libxavs enabled ${libxavs-no}"
|
| 3249 | 3249 |
echo "libxvid enabled ${libxvid-no}"
|
| 3250 |
+echo "openal enabled ${openal-no}"
|
|
| 3250 | 3251 |
echo "zlib enabled ${zlib-no}"
|
| 3251 | 3252 |
echo "bzlib enabled ${bzlib-no}"
|
| 3252 | 3253 |
echo |
| ... | ... |
@@ -137,6 +137,95 @@ For more information read: |
| 137 | 137 |
|
| 138 | 138 |
IIDC1394 input device, based on libdc1394 and libraw1394. |
| 139 | 139 |
|
| 140 |
+@section openal |
|
| 141 |
+ |
|
| 142 |
+The OpenAL input device provides audio capture on all systems with a |
|
| 143 |
+working OpenAL 1.1 implementation. |
|
| 144 |
+ |
|
| 145 |
+To enable this input device during configuration, you need OpenAL |
|
| 146 |
+headers and libraries installed on your system, and need to configure |
|
| 147 |
+FFmpeg with @code{--enable-openal}.
|
|
| 148 |
+ |
|
| 149 |
+OpenAL headers and libraries should be provided as part of your OpenAL |
|
| 150 |
+implementation, or as an additional download (an SDK). Depending on your |
|
| 151 |
+installation you may need to specify additional flags via the |
|
| 152 |
+@code{--extra-cflags} and @code{--extra-ldflags} for allowing the build
|
|
| 153 |
+system to locate the OpenAL headers and libraries. |
|
| 154 |
+ |
|
| 155 |
+An incomplete list of OpenAL implementations follows: |
|
| 156 |
+ |
|
| 157 |
+@table @strong |
|
| 158 |
+@item Creative |
|
| 159 |
+The official Windows implementation, providing hardware acceleration |
|
| 160 |
+with supported devices and software fallback. |
|
| 161 |
+See @url{http://openal.org/}.
|
|
| 162 |
+@item OpenAL Soft |
|
| 163 |
+Portable, open source (LGPL) software implementation. Includes |
|
| 164 |
+backends for the most common sound APIs on the Windows, Linux, |
|
| 165 |
+Solaris, and BSD operating systems. |
|
| 166 |
+See @url{http://kcat.strangesoft.net/openal.html}.
|
|
| 167 |
+@item Apple |
|
| 168 |
+OpenAL is part of Core Audio, the official Mac OS X Audio interface. |
|
| 169 |
+See @url{http://developer.apple.com/technologies/mac/audio-and-video.html}
|
|
| 170 |
+@end table |
|
| 171 |
+ |
|
| 172 |
+This device allows to capture from an audio input device handled |
|
| 173 |
+through OpenAL. |
|
| 174 |
+ |
|
| 175 |
+You need to specify the name of the device to capture in the provided |
|
| 176 |
+filename. If the empty string is provided, the device will |
|
| 177 |
+automatically select the default device. You can get the list of the |
|
| 178 |
+supported devices by using the option @var{list_devices}.
|
|
| 179 |
+ |
|
| 180 |
+@subsection Options |
|
| 181 |
+ |
|
| 182 |
+@table @option |
|
| 183 |
+ |
|
| 184 |
+@item channels |
|
| 185 |
+Set the number of channels in the captured audio. Only the values |
|
| 186 |
+@option{1} (monaural) and @option{2} (stereo) are currently supported.
|
|
| 187 |
+Defaults to @option{2}.
|
|
| 188 |
+ |
|
| 189 |
+@item sample_size |
|
| 190 |
+Set the sample size (in bits) of the captured audio. Only the values |
|
| 191 |
+@option{8} and @option{16} are currently supported. Defaults to
|
|
| 192 |
+@option{16}.
|
|
| 193 |
+ |
|
| 194 |
+@item sample_rate |
|
| 195 |
+Set the sample rate (in Hz) of the captured audio. |
|
| 196 |
+Defaults to @option{44.1k}.
|
|
| 197 |
+ |
|
| 198 |
+@item list_devices |
|
| 199 |
+If set to @option{true}, print a list of devices and exit.
|
|
| 200 |
+Defaults to @option{false}.
|
|
| 201 |
+ |
|
| 202 |
+@end table |
|
| 203 |
+ |
|
| 204 |
+@subsection Examples |
|
| 205 |
+ |
|
| 206 |
+Print the list of OpenAL supported devices and exit: |
|
| 207 |
+@example |
|
| 208 |
+$ ffmpeg -list_devices true -f openal -i dummy out.ogg |
|
| 209 |
+@end example |
|
| 210 |
+ |
|
| 211 |
+Capture from the OpenAL device @file{DR-BT101 via PulseAudio}:
|
|
| 212 |
+@example |
|
| 213 |
+$ ffmpeg -f openal -i 'DR-BT101 via PulseAudio' out.ogg |
|
| 214 |
+@end example |
|
| 215 |
+ |
|
| 216 |
+Capture from the default device (note the empty string '' as filename): |
|
| 217 |
+@example |
|
| 218 |
+$ ffmpeg -f openal -i '' out.ogg |
|
| 219 |
+@end example |
|
| 220 |
+ |
|
| 221 |
+Capture from two devices simultaneously, writing to two different files, |
|
| 222 |
+within the same @file{ffmpeg} command:
|
|
| 223 |
+@example |
|
| 224 |
+$ ffmpeg -f openal -i 'DR-BT101 via PulseAudio' out1.ogg -f openal -i 'ALSA Default' out2.ogg |
|
| 225 |
+@end example |
|
| 226 |
+Note: not all OpenAL implementations support multiple simultaneous capture - |
|
| 227 |
+try the latest OpenAL Soft if the above does not work. |
|
| 228 |
+ |
|
| 140 | 229 |
@section oss |
| 141 | 230 |
|
| 142 | 231 |
Open Sound System input device. |
| ... | ... |
@@ -19,6 +19,7 @@ OBJS-$(CONFIG_DSHOW_INDEV) += dshow.o dshow_enummediatypes.o \ |
| 19 | 19 |
OBJS-$(CONFIG_DV1394_INDEV) += dv1394.o |
| 20 | 20 |
OBJS-$(CONFIG_FBDEV_INDEV) += fbdev.o |
| 21 | 21 |
OBJS-$(CONFIG_JACK_INDEV) += jack_audio.o |
| 22 |
+OBJS-$(CONFIG_OPENAL_INDEV) += openal-dec.o |
|
| 22 | 23 |
OBJS-$(CONFIG_OSS_INDEV) += oss_audio.o |
| 23 | 24 |
OBJS-$(CONFIG_OSS_OUTDEV) += oss_audio.o |
| 24 | 25 |
OBJS-$(CONFIG_SDL_OUTDEV) += sdl.o |
| ... | ... |
@@ -44,6 +44,7 @@ void avdevice_register_all(void) |
| 44 | 44 |
REGISTER_INDEV (DV1394, dv1394); |
| 45 | 45 |
REGISTER_INDEV (FBDEV, fbdev); |
| 46 | 46 |
REGISTER_INDEV (JACK, jack); |
| 47 |
+ REGISTER_INDEV (OPENAL, openal); |
|
| 47 | 48 |
REGISTER_INOUTDEV (OSS, oss); |
| 48 | 49 |
REGISTER_OUTDEV (SDL, sdl); |
| 49 | 50 |
REGISTER_INOUTDEV (SNDIO, sndio); |
| ... | ... |
@@ -23,8 +23,8 @@ |
| 23 | 23 |
#include "libavformat/avformat.h" |
| 24 | 24 |
|
| 25 | 25 |
#define LIBAVDEVICE_VERSION_MAJOR 53 |
| 26 |
-#define LIBAVDEVICE_VERSION_MINOR 1 |
|
| 27 |
-#define LIBAVDEVICE_VERSION_MICRO 1 |
|
| 26 |
+#define LIBAVDEVICE_VERSION_MINOR 2 |
|
| 27 |
+#define LIBAVDEVICE_VERSION_MICRO 0 |
|
| 28 | 28 |
|
| 29 | 29 |
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ |
| 30 | 30 |
LIBAVDEVICE_VERSION_MINOR, \ |
| 31 | 31 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,256 @@ |
| 0 |
+/* |
|
| 1 |
+ * Copyright (c) 2011 Jonathan Baldwin |
|
| 2 |
+ * |
|
| 3 |
+ * This file is part of FFmpeg. |
|
| 4 |
+ * |
|
| 5 |
+ * Permission is hereby granted, free of charge, to any person obtaining a copy |
|
| 6 |
+ * of this software and associated documentation files (the "Software"), to deal |
|
| 7 |
+ * in the Software without restriction, including without limitation the rights |
|
| 8 |
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
| 9 |
+ * copies of the Software, and to permit persons to whom the Software is |
|
| 10 |
+ * furnished to do so, subject to the following conditions: |
|
| 11 |
+ * |
|
| 12 |
+ * The above copyright notice and this permission notice shall be included in |
|
| 13 |
+ * all copies or substantial portions of the Software. |
|
| 14 |
+ * |
|
| 15 |
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
| 16 |
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
| 17 |
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
| 18 |
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
| 19 |
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
| 20 |
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
| 21 |
+ * THE SOFTWARE. |
|
| 22 |
+ */ |
|
| 23 |
+ |
|
| 24 |
+/** |
|
| 25 |
+ * @file |
|
| 26 |
+ * OpenAL 1.1 capture device for libavdevice |
|
| 27 |
+ **/ |
|
| 28 |
+ |
|
| 29 |
+#include <AL/al.h> |
|
| 30 |
+#include <AL/alc.h> |
|
| 31 |
+ |
|
| 32 |
+#include "libavutil/opt.h" |
|
| 33 |
+#include "avdevice.h" |
|
| 34 |
+ |
|
| 35 |
+typedef struct {
|
|
| 36 |
+ AVClass *class; |
|
| 37 |
+ /** OpenAL capture device context. **/ |
|
| 38 |
+ ALCdevice *device; |
|
| 39 |
+ /** The number of channels in the captured audio. **/ |
|
| 40 |
+ int channels; |
|
| 41 |
+ /** The sample rate (in Hz) of the captured audio. **/ |
|
| 42 |
+ int sample_rate; |
|
| 43 |
+ /** The sample size (in bits) of the captured audio. **/ |
|
| 44 |
+ int sample_size; |
|
| 45 |
+ /** The OpenAL sample format of the captured audio. **/ |
|
| 46 |
+ ALCenum sample_format; |
|
| 47 |
+ /** The number of bytes between two consecutive samples of the same channel/component. **/ |
|
| 48 |
+ ALCint sample_step; |
|
| 49 |
+ /** If true, print a list of capture devices on this system and exit. **/ |
|
| 50 |
+ int list_devices; |
|
| 51 |
+} al_data; |
|
| 52 |
+ |
|
| 53 |
+typedef struct {
|
|
| 54 |
+ ALCenum al_fmt; |
|
| 55 |
+ enum CodecID codec_id; |
|
| 56 |
+ int channels; |
|
| 57 |
+} al_format_info; |
|
| 58 |
+ |
|
| 59 |
+#define LOWEST_AL_FORMAT FFMIN(FFMIN(AL_FORMAT_MONO8,AL_FORMAT_MONO16),FFMIN(AL_FORMAT_STEREO8,AL_FORMAT_STEREO16)) |
|
| 60 |
+ |
|
| 61 |
+/** |
|
| 62 |
+ * Get information about an AL_FORMAT value. |
|
| 63 |
+ * @param al_fmt the AL_FORMAT value to find information about. |
|
| 64 |
+ * @return A pointer to a structure containing information about the AL_FORMAT value. |
|
| 65 |
+ */ |
|
| 66 |
+static inline al_format_info* get_al_format_info(ALCenum al_fmt) |
|
| 67 |
+{
|
|
| 68 |
+ static al_format_info info_table[] = {
|
|
| 69 |
+ [AL_FORMAT_MONO8-LOWEST_AL_FORMAT] = {AL_FORMAT_MONO8, CODEC_ID_PCM_U8, 1},
|
|
| 70 |
+ [AL_FORMAT_MONO16-LOWEST_AL_FORMAT] = {AL_FORMAT_MONO16, AV_NE (CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE), 1},
|
|
| 71 |
+ [AL_FORMAT_STEREO8-LOWEST_AL_FORMAT] = {AL_FORMAT_STEREO8, CODEC_ID_PCM_U8, 2},
|
|
| 72 |
+ [AL_FORMAT_STEREO16-LOWEST_AL_FORMAT] = {AL_FORMAT_STEREO16, AV_NE (CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE), 2},
|
|
| 73 |
+ }; |
|
| 74 |
+ |
|
| 75 |
+ return &info_table[al_fmt-LOWEST_AL_FORMAT]; |
|
| 76 |
+} |
|
| 77 |
+ |
|
| 78 |
+/** |
|
| 79 |
+ * Get the OpenAL error code, translated into an av/errno error code. |
|
| 80 |
+ * @param device The ALC device to check for errors. |
|
| 81 |
+ * @param error_msg_ret A pointer to a char* in which to return the error message, or NULL if desired. |
|
| 82 |
+ * @return The error code, or 0 if there is no error. |
|
| 83 |
+ */ |
|
| 84 |
+static inline int al_get_error(ALCdevice *device, const char** error_msg_ret) |
|
| 85 |
+{
|
|
| 86 |
+ ALCenum error = alcGetError(device); |
|
| 87 |
+ if (error_msg_ret) |
|
| 88 |
+ *error_msg_ret = (const char*) alcGetString(device, error); |
|
| 89 |
+ switch (error) {
|
|
| 90 |
+ case ALC_NO_ERROR: |
|
| 91 |
+ return 0; |
|
| 92 |
+ case ALC_INVALID_DEVICE: |
|
| 93 |
+ return AVERROR(ENODEV); |
|
| 94 |
+ break; |
|
| 95 |
+ case ALC_INVALID_CONTEXT: |
|
| 96 |
+ case ALC_INVALID_ENUM: |
|
| 97 |
+ case ALC_INVALID_VALUE: |
|
| 98 |
+ return AVERROR(EINVAL); |
|
| 99 |
+ break; |
|
| 100 |
+ case ALC_OUT_OF_MEMORY: |
|
| 101 |
+ return AVERROR(ENOMEM); |
|
| 102 |
+ break; |
|
| 103 |
+ default: |
|
| 104 |
+ return AVERROR(EIO); |
|
| 105 |
+ } |
|
| 106 |
+} |
|
| 107 |
+ |
|
| 108 |
+/** |
|
| 109 |
+ * Print out a list of OpenAL capture devices on this system. |
|
| 110 |
+ */ |
|
| 111 |
+static inline void print_al_capture_devices(void *log_ctx) |
|
| 112 |
+{
|
|
| 113 |
+ const char *devices; |
|
| 114 |
+ |
|
| 115 |
+ if (!(devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER))) |
|
| 116 |
+ return; |
|
| 117 |
+ |
|
| 118 |
+ av_log(log_ctx, AV_LOG_INFO, "List of OpenAL capture devices on this system:\n"); |
|
| 119 |
+ |
|
| 120 |
+ for (; *devices != '\0'; devices += strlen(devices) + 1) |
|
| 121 |
+ av_log(log_ctx, AV_LOG_INFO, " %s\n", devices); |
|
| 122 |
+} |
|
| 123 |
+ |
|
| 124 |
+static int read_header(AVFormatContext *ctx, AVFormatParameters *ap) |
|
| 125 |
+{
|
|
| 126 |
+ al_data *ad = ctx->priv_data; |
|
| 127 |
+ static const ALCenum sample_formats[2][2] = {
|
|
| 128 |
+ { AL_FORMAT_MONO8, AL_FORMAT_STEREO8 },
|
|
| 129 |
+ { AL_FORMAT_MONO16, AL_FORMAT_STEREO16 }
|
|
| 130 |
+ }; |
|
| 131 |
+ int error = 0; |
|
| 132 |
+ const char *error_msg; |
|
| 133 |
+ AVStream *st = NULL; |
|
| 134 |
+ AVCodecContext *codec = NULL; |
|
| 135 |
+ |
|
| 136 |
+ if (ad->list_devices) {
|
|
| 137 |
+ print_al_capture_devices(ctx); |
|
| 138 |
+ return AVERROR_EXIT; |
|
| 139 |
+ } |
|
| 140 |
+ |
|
| 141 |
+ ad->sample_format = sample_formats[ad->sample_size/8-1][ad->channels-1]; |
|
| 142 |
+ |
|
| 143 |
+ /* Open device for capture */ |
|
| 144 |
+ ad->device = |
|
| 145 |
+ alcCaptureOpenDevice(ctx->filename[0] ? ctx->filename : NULL, |
|
| 146 |
+ ad->sample_rate, |
|
| 147 |
+ ad->sample_format, |
|
| 148 |
+ ad->sample_rate); /* Maximum 1 second of sample data to be read at once */ |
|
| 149 |
+ |
|
| 150 |
+ if (error = al_get_error(ad->device, &error_msg)) goto fail; |
|
| 151 |
+ |
|
| 152 |
+ /* Create stream */ |
|
| 153 |
+ if (!(st = av_new_stream(ctx, 0))) {
|
|
| 154 |
+ error = AVERROR(ENOMEM); |
|
| 155 |
+ goto fail; |
|
| 156 |
+ } |
|
| 157 |
+ |
|
| 158 |
+ /* We work in microseconds */ |
|
| 159 |
+ av_set_pts_info(st, 64, 1, 1000000); |
|
| 160 |
+ |
|
| 161 |
+ /* Set codec parameters */ |
|
| 162 |
+ codec = st->codec; |
|
| 163 |
+ codec->codec_type = AVMEDIA_TYPE_AUDIO; |
|
| 164 |
+ codec->sample_rate = ad->sample_rate; |
|
| 165 |
+ codec->channels = get_al_format_info(ad->sample_format)->channels; |
|
| 166 |
+ codec->codec_id = get_al_format_info(ad->sample_format)->codec_id; |
|
| 167 |
+ |
|
| 168 |
+ /* This is needed to read the audio data */ |
|
| 169 |
+ ad->sample_step = (av_get_bits_per_sample(get_al_format_info(ad->sample_format)->codec_id) * |
|
| 170 |
+ get_al_format_info(ad->sample_format)->channels) / 8; |
|
| 171 |
+ |
|
| 172 |
+ /* Finally, start the capture process */ |
|
| 173 |
+ alcCaptureStart(ad->device); |
|
| 174 |
+ |
|
| 175 |
+ return 0; |
|
| 176 |
+ |
|
| 177 |
+fail: |
|
| 178 |
+ /* Handle failure */ |
|
| 179 |
+ if (ad->device) |
|
| 180 |
+ alcCaptureCloseDevice(ad->device); |
|
| 181 |
+ if (error_msg) |
|
| 182 |
+ av_log(ctx, AV_LOG_ERROR, "Cannot open device: %s\n", error_msg); |
|
| 183 |
+ return error; |
|
| 184 |
+} |
|
| 185 |
+ |
|
| 186 |
+static int read_packet(AVFormatContext* ctx, AVPacket *pkt) |
|
| 187 |
+{
|
|
| 188 |
+ al_data *ad = ctx->priv_data; |
|
| 189 |
+ int error=0; |
|
| 190 |
+ const char *error_msg; |
|
| 191 |
+ ALCint nb_samples; |
|
| 192 |
+ |
|
| 193 |
+ /* Get number of samples available */ |
|
| 194 |
+ alcGetIntegerv(ad->device, ALC_CAPTURE_SAMPLES, (ALCsizei) sizeof(ALCint), &nb_samples); |
|
| 195 |
+ if (error = al_get_error(ad->device, &error_msg)) goto fail; |
|
| 196 |
+ |
|
| 197 |
+ /* Create a packet of appropriate size */ |
|
| 198 |
+ av_new_packet(pkt, nb_samples*ad->sample_step); |
|
| 199 |
+ pkt->pts = av_gettime(); |
|
| 200 |
+ |
|
| 201 |
+ /* Fill the packet with the available samples */ |
|
| 202 |
+ alcCaptureSamples(ad->device, pkt->data, nb_samples); |
|
| 203 |
+ if (error = al_get_error(ad->device, &error_msg)) goto fail; |
|
| 204 |
+ |
|
| 205 |
+ return pkt->size; |
|
| 206 |
+fail: |
|
| 207 |
+ /* Handle failure */ |
|
| 208 |
+ if (pkt->data) |
|
| 209 |
+ av_destruct_packet(pkt); |
|
| 210 |
+ if (error_msg) |
|
| 211 |
+ av_log(ctx, AV_LOG_ERROR, "Error: %s\n", error_msg); |
|
| 212 |
+ return error; |
|
| 213 |
+} |
|
| 214 |
+ |
|
| 215 |
+static int read_close(AVFormatContext* ctx) |
|
| 216 |
+{
|
|
| 217 |
+ al_data *ad = ctx->priv_data; |
|
| 218 |
+ |
|
| 219 |
+ if (ad->device) {
|
|
| 220 |
+ alcCaptureStop(ad->device); |
|
| 221 |
+ alcCaptureCloseDevice(ad->device); |
|
| 222 |
+ } |
|
| 223 |
+ return 0; |
|
| 224 |
+} |
|
| 225 |
+ |
|
| 226 |
+#define OFFSET(x) offsetof(al_data, x) |
|
| 227 |
+ |
|
| 228 |
+static const AVOption options[] = {
|
|
| 229 |
+ {"channels", "set number of channels", OFFSET(channels), FF_OPT_TYPE_INT, {.dbl=2}, 1, 2, AV_OPT_FLAG_DECODING_PARAM },
|
|
| 230 |
+ {"sample_rate", "set sample rate", OFFSET(sample_rate), FF_OPT_TYPE_INT, {.dbl=44100}, 1, 192000, AV_OPT_FLAG_DECODING_PARAM },
|
|
| 231 |
+ {"sample_size", "set sample size", OFFSET(sample_size), FF_OPT_TYPE_INT, {.dbl=16}, 8, 16, AV_OPT_FLAG_DECODING_PARAM },
|
|
| 232 |
+ {"list_devices", "list available devices", OFFSET(list_devices), FF_OPT_TYPE_INT, {.dbl=0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
|
|
| 233 |
+ {"true", "", 0, FF_OPT_TYPE_CONST, {.dbl=1}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
|
|
| 234 |
+ {"false", "", 0, FF_OPT_TYPE_CONST, {.dbl=0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
|
|
| 235 |
+ {NULL},
|
|
| 236 |
+}; |
|
| 237 |
+ |
|
| 238 |
+static const AVClass class = {
|
|
| 239 |
+ .class_name = "openal", |
|
| 240 |
+ .item_name = av_default_item_name, |
|
| 241 |
+ .option = options, |
|
| 242 |
+ .version = LIBAVUTIL_VERSION_INT |
|
| 243 |
+}; |
|
| 244 |
+ |
|
| 245 |
+AVInputFormat ff_openal_demuxer = {
|
|
| 246 |
+ .name = "openal", |
|
| 247 |
+ .long_name = NULL_IF_CONFIG_SMALL("OpenAL audio capture device"),
|
|
| 248 |
+ .priv_data_size = sizeof(al_data), |
|
| 249 |
+ .read_probe = NULL, |
|
| 250 |
+ .read_header = read_header, |
|
| 251 |
+ .read_packet = read_packet, |
|
| 252 |
+ .read_close = read_close, |
|
| 253 |
+ .flags = AVFMT_NOFILE, |
|
| 254 |
+ .priv_class = &class |
|
| 255 |
+}; |