You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
8.5KB

  1. /*
  2. * Copyright (c) 2011 Jonathan Baldwin
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. /**
  25. * @file
  26. * OpenAL 1.1 capture device for libavdevice
  27. **/
  28. #include <AL/al.h>
  29. #include <AL/alc.h>
  30. #include "libavutil/opt.h"
  31. #include "avdevice.h"
  32. typedef struct {
  33. AVClass *class;
  34. /** OpenAL capture device context. **/
  35. ALCdevice *device;
  36. /** The number of channels in the captured audio. **/
  37. int channels;
  38. /** The sample rate (in Hz) of the captured audio. **/
  39. int sample_rate;
  40. /** The sample size (in bits) of the captured audio. **/
  41. int sample_size;
  42. /** The OpenAL sample format of the captured audio. **/
  43. ALCenum sample_format;
  44. /** The number of bytes between two consecutive samples of the same channel/component. **/
  45. ALCint sample_step;
  46. /** If true, print a list of capture devices on this system and exit. **/
  47. int list_devices;
  48. } al_data;
  49. typedef struct {
  50. ALCenum al_fmt;
  51. enum CodecID codec_id;
  52. int channels;
  53. } al_format_info;
  54. #define LOWEST_AL_FORMAT FFMIN(FFMIN(AL_FORMAT_MONO8,AL_FORMAT_MONO16),FFMIN(AL_FORMAT_STEREO8,AL_FORMAT_STEREO16))
  55. /**
  56. * Get information about an AL_FORMAT value.
  57. * @param al_fmt the AL_FORMAT value to find information about.
  58. * @return A pointer to a structure containing information about the AL_FORMAT value.
  59. */
  60. static inline al_format_info* get_al_format_info(ALCenum al_fmt)
  61. {
  62. static al_format_info info_table[] = {
  63. [AL_FORMAT_MONO8-LOWEST_AL_FORMAT] = {AL_FORMAT_MONO8, CODEC_ID_PCM_U8, 1},
  64. [AL_FORMAT_MONO16-LOWEST_AL_FORMAT] = {AL_FORMAT_MONO16, AV_NE (CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE), 1},
  65. [AL_FORMAT_STEREO8-LOWEST_AL_FORMAT] = {AL_FORMAT_STEREO8, CODEC_ID_PCM_U8, 2},
  66. [AL_FORMAT_STEREO16-LOWEST_AL_FORMAT] = {AL_FORMAT_STEREO16, AV_NE (CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE), 2},
  67. };
  68. return &info_table[al_fmt-LOWEST_AL_FORMAT];
  69. }
  70. /**
  71. * Get the OpenAL error code, translated into an av/errno error code.
  72. * @param device The ALC device to check for errors.
  73. * @param error_msg_ret A pointer to a char* in which to return the error message, or NULL if desired.
  74. * @return The error code, or 0 if there is no error.
  75. */
  76. static inline int al_get_error(ALCdevice *device, const char** error_msg_ret)
  77. {
  78. ALCenum error = alcGetError(device);
  79. if (error_msg_ret)
  80. *error_msg_ret = (const char*) alcGetString(device, error);
  81. switch (error) {
  82. case ALC_NO_ERROR:
  83. return 0;
  84. case ALC_INVALID_DEVICE:
  85. return AVERROR(ENODEV);
  86. break;
  87. case ALC_INVALID_CONTEXT:
  88. case ALC_INVALID_ENUM:
  89. case ALC_INVALID_VALUE:
  90. return AVERROR(EINVAL);
  91. break;
  92. case ALC_OUT_OF_MEMORY:
  93. return AVERROR(ENOMEM);
  94. break;
  95. default:
  96. return AVERROR(EIO);
  97. }
  98. }
  99. /**
  100. * Print out a list of OpenAL capture devices on this system.
  101. */
  102. static inline void print_al_capture_devices(void *log_ctx)
  103. {
  104. const char *devices;
  105. if (!(devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER)))
  106. return;
  107. av_log(log_ctx, AV_LOG_INFO, "List of OpenAL capture devices on this system:\n");
  108. for (; *devices != '\0'; devices += strlen(devices) + 1)
  109. av_log(log_ctx, AV_LOG_INFO, " %s\n", devices);
  110. }
  111. static int read_header(AVFormatContext *ctx, AVFormatParameters *ap)
  112. {
  113. al_data *ad = ctx->priv_data;
  114. static const ALCenum sample_formats[2][2] = {
  115. { AL_FORMAT_MONO8, AL_FORMAT_STEREO8 },
  116. { AL_FORMAT_MONO16, AL_FORMAT_STEREO16 }
  117. };
  118. int error = 0;
  119. const char *error_msg;
  120. AVStream *st = NULL;
  121. AVCodecContext *codec = NULL;
  122. if (ad->list_devices) {
  123. print_al_capture_devices(ctx);
  124. return AVERROR_EXIT;
  125. }
  126. ad->sample_format = sample_formats[ad->sample_size/8-1][ad->channels-1];
  127. /* Open device for capture */
  128. ad->device =
  129. alcCaptureOpenDevice(ctx->filename[0] ? ctx->filename : NULL,
  130. ad->sample_rate,
  131. ad->sample_format,
  132. ad->sample_rate); /* Maximum 1 second of sample data to be read at once */
  133. if (error = al_get_error(ad->device, &error_msg)) goto fail;
  134. /* Create stream */
  135. if (!(st = av_new_stream(ctx, 0))) {
  136. error = AVERROR(ENOMEM);
  137. goto fail;
  138. }
  139. /* We work in microseconds */
  140. av_set_pts_info(st, 64, 1, 1000000);
  141. /* Set codec parameters */
  142. codec = st->codec;
  143. codec->codec_type = AVMEDIA_TYPE_AUDIO;
  144. codec->sample_rate = ad->sample_rate;
  145. codec->channels = get_al_format_info(ad->sample_format)->channels;
  146. codec->codec_id = get_al_format_info(ad->sample_format)->codec_id;
  147. /* This is needed to read the audio data */
  148. ad->sample_step = (av_get_bits_per_sample(get_al_format_info(ad->sample_format)->codec_id) *
  149. get_al_format_info(ad->sample_format)->channels) / 8;
  150. /* Finally, start the capture process */
  151. alcCaptureStart(ad->device);
  152. return 0;
  153. fail:
  154. /* Handle failure */
  155. if (ad->device)
  156. alcCaptureCloseDevice(ad->device);
  157. if (error_msg)
  158. av_log(ctx, AV_LOG_ERROR, "Cannot open device: %s\n", error_msg);
  159. return error;
  160. }
  161. static int read_packet(AVFormatContext* ctx, AVPacket *pkt)
  162. {
  163. al_data *ad = ctx->priv_data;
  164. int error=0;
  165. const char *error_msg;
  166. ALCint nb_samples;
  167. /* Get number of samples available */
  168. alcGetIntegerv(ad->device, ALC_CAPTURE_SAMPLES, (ALCsizei) sizeof(ALCint), &nb_samples);
  169. if (error = al_get_error(ad->device, &error_msg)) goto fail;
  170. /* Create a packet of appropriate size */
  171. av_new_packet(pkt, nb_samples*ad->sample_step);
  172. pkt->pts = av_gettime();
  173. /* Fill the packet with the available samples */
  174. alcCaptureSamples(ad->device, pkt->data, nb_samples);
  175. if (error = al_get_error(ad->device, &error_msg)) goto fail;
  176. return pkt->size;
  177. fail:
  178. /* Handle failure */
  179. if (pkt->data)
  180. av_destruct_packet(pkt);
  181. if (error_msg)
  182. av_log(ctx, AV_LOG_ERROR, "Error: %s\n", error_msg);
  183. return error;
  184. }
  185. static int read_close(AVFormatContext* ctx)
  186. {
  187. al_data *ad = ctx->priv_data;
  188. if (ad->device) {
  189. alcCaptureStop(ad->device);
  190. alcCaptureCloseDevice(ad->device);
  191. }
  192. return 0;
  193. }
  194. #define OFFSET(x) offsetof(al_data, x)
  195. static const AVOption options[] = {
  196. {"channels", "set number of channels", OFFSET(channels), FF_OPT_TYPE_INT, {.dbl=2}, 1, 2, AV_OPT_FLAG_DECODING_PARAM },
  197. {"sample_rate", "set sample rate", OFFSET(sample_rate), FF_OPT_TYPE_INT, {.dbl=44100}, 1, 192000, AV_OPT_FLAG_DECODING_PARAM },
  198. {"sample_size", "set sample size", OFFSET(sample_size), FF_OPT_TYPE_INT, {.dbl=16}, 8, 16, AV_OPT_FLAG_DECODING_PARAM },
  199. {"list_devices", "list available devices", OFFSET(list_devices), FF_OPT_TYPE_INT, {.dbl=0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
  200. {"true", "", 0, FF_OPT_TYPE_CONST, {.dbl=1}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
  201. {"false", "", 0, FF_OPT_TYPE_CONST, {.dbl=0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
  202. {NULL},
  203. };
  204. static const AVClass class = {
  205. .class_name = "openal",
  206. .item_name = av_default_item_name,
  207. .option = options,
  208. .version = LIBAVUTIL_VERSION_INT
  209. };
  210. AVInputFormat ff_openal_demuxer = {
  211. .name = "openal",
  212. .long_name = NULL_IF_CONFIG_SMALL("OpenAL audio capture device"),
  213. .priv_data_size = sizeof(al_data),
  214. .read_probe = NULL,
  215. .read_header = read_header,
  216. .read_packet = read_packet,
  217. .read_close = read_close,
  218. .flags = AVFMT_NOFILE,
  219. .priv_class = &class
  220. };