Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Linux audio play and grab interface
  3.  * Copyright (c) 2000, 2001 Fabrice Bellard
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. #include "config.h"
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <stdint.h>
  26. #include <string.h>
  27. #include <errno.h>
  28. #if HAVE_SOUNDCARD_H
  29. #include <soundcard.h>
  30. #else
  31. #include <sys/soundcard.h>
  32. #endif
  33. #include <unistd.h>
  34. #include <fcntl.h>
  35. #include <sys/ioctl.h>
  36.  
  37. #include "libavutil/internal.h"
  38. #include "libavutil/log.h"
  39. #include "libavutil/opt.h"
  40. #include "libavutil/time.h"
  41. #include "libavcodec/avcodec.h"
  42. #include "avdevice.h"
  43. #include "libavformat/internal.h"
  44.  
  45. #define AUDIO_BLOCK_SIZE 4096
  46.  
  47. typedef struct {
  48.     AVClass *class;
  49.     int fd;
  50.     int sample_rate;
  51.     int channels;
  52.     int frame_size; /* in bytes ! */
  53.     enum AVCodecID codec_id;
  54.     unsigned int flip_left : 1;
  55.     uint8_t buffer[AUDIO_BLOCK_SIZE];
  56.     int buffer_ptr;
  57. } AudioData;
  58.  
  59. static int audio_open(AVFormatContext *s1, int is_output, const char *audio_device)
  60. {
  61.     AudioData *s = s1->priv_data;
  62.     int audio_fd;
  63.     int tmp, err;
  64.     char *flip = getenv("AUDIO_FLIP_LEFT");
  65.  
  66.     if (is_output)
  67.         audio_fd = avpriv_open(audio_device, O_WRONLY);
  68.     else
  69.         audio_fd = avpriv_open(audio_device, O_RDONLY);
  70.     if (audio_fd < 0) {
  71.         av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno));
  72.         return AVERROR(EIO);
  73.     }
  74.  
  75.     if (flip && *flip == '1') {
  76.         s->flip_left = 1;
  77.     }
  78.  
  79.     /* non blocking mode */
  80.     if (!is_output) {
  81.         if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) {
  82.             av_log(s1, AV_LOG_WARNING, "%s: Could not enable non block mode (%s)\n", audio_device, strerror(errno));
  83.         }
  84.     }
  85.  
  86.     s->frame_size = AUDIO_BLOCK_SIZE;
  87.  
  88.     /* select format : favour native format */
  89.     err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp);
  90.  
  91. #if HAVE_BIGENDIAN
  92.     if (tmp & AFMT_S16_BE) {
  93.         tmp = AFMT_S16_BE;
  94.     } else if (tmp & AFMT_S16_LE) {
  95.         tmp = AFMT_S16_LE;
  96.     } else {
  97.         tmp = 0;
  98.     }
  99. #else
  100.     if (tmp & AFMT_S16_LE) {
  101.         tmp = AFMT_S16_LE;
  102.     } else if (tmp & AFMT_S16_BE) {
  103.         tmp = AFMT_S16_BE;
  104.     } else {
  105.         tmp = 0;
  106.     }
  107. #endif
  108.  
  109.     switch(tmp) {
  110.     case AFMT_S16_LE:
  111.         s->codec_id = AV_CODEC_ID_PCM_S16LE;
  112.         break;
  113.     case AFMT_S16_BE:
  114.         s->codec_id = AV_CODEC_ID_PCM_S16BE;
  115.         break;
  116.     default:
  117.         av_log(s1, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n");
  118.         close(audio_fd);
  119.         return AVERROR(EIO);
  120.     }
  121.     err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp);
  122.     if (err < 0) {
  123.         av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SETFMT: %s\n", strerror(errno));
  124.         goto fail;
  125.     }
  126.  
  127.     tmp = (s->channels == 2);
  128.     err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
  129.     if (err < 0) {
  130.         av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_STEREO: %s\n", strerror(errno));
  131.         goto fail;
  132.     }
  133.  
  134.     tmp = s->sample_rate;
  135.     err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp);
  136.     if (err < 0) {
  137.         av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SPEED: %s\n", strerror(errno));
  138.         goto fail;
  139.     }
  140.     s->sample_rate = tmp; /* store real sample rate */
  141.     s->fd = audio_fd;
  142.  
  143.     return 0;
  144.  fail:
  145.     close(audio_fd);
  146.     return AVERROR(EIO);
  147. }
  148.  
  149. static int audio_close(AudioData *s)
  150. {
  151.     close(s->fd);
  152.     return 0;
  153. }
  154.  
  155. /* sound output support */
  156. static int audio_write_header(AVFormatContext *s1)
  157. {
  158.     AudioData *s = s1->priv_data;
  159.     AVStream *st;
  160.     int ret;
  161.  
  162.     st = s1->streams[0];
  163.     s->sample_rate = st->codec->sample_rate;
  164.     s->channels = st->codec->channels;
  165.     ret = audio_open(s1, 1, s1->filename);
  166.     if (ret < 0) {
  167.         return AVERROR(EIO);
  168.     } else {
  169.         return 0;
  170.     }
  171. }
  172.  
  173. static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt)
  174. {
  175.     AudioData *s = s1->priv_data;
  176.     int len, ret;
  177.     int size= pkt->size;
  178.     uint8_t *buf= pkt->data;
  179.  
  180.     while (size > 0) {
  181.         len = FFMIN(AUDIO_BLOCK_SIZE - s->buffer_ptr, size);
  182.         memcpy(s->buffer + s->buffer_ptr, buf, len);
  183.         s->buffer_ptr += len;
  184.         if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) {
  185.             for(;;) {
  186.                 ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE);
  187.                 if (ret > 0)
  188.                     break;
  189.                 if (ret < 0 && (errno != EAGAIN && errno != EINTR))
  190.                     return AVERROR(EIO);
  191.             }
  192.             s->buffer_ptr = 0;
  193.         }
  194.         buf += len;
  195.         size -= len;
  196.     }
  197.     return 0;
  198. }
  199.  
  200. static int audio_write_trailer(AVFormatContext *s1)
  201. {
  202.     AudioData *s = s1->priv_data;
  203.  
  204.     audio_close(s);
  205.     return 0;
  206. }
  207.  
  208. /* grab support */
  209.  
  210. static int audio_read_header(AVFormatContext *s1)
  211. {
  212.     AudioData *s = s1->priv_data;
  213.     AVStream *st;
  214.     int ret;
  215.  
  216.     st = avformat_new_stream(s1, NULL);
  217.     if (!st) {
  218.         return AVERROR(ENOMEM);
  219.     }
  220.  
  221.     ret = audio_open(s1, 0, s1->filename);
  222.     if (ret < 0) {
  223.         return AVERROR(EIO);
  224.     }
  225.  
  226.     /* take real parameters */
  227.     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
  228.     st->codec->codec_id = s->codec_id;
  229.     st->codec->sample_rate = s->sample_rate;
  230.     st->codec->channels = s->channels;
  231.  
  232.     avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
  233.     return 0;
  234. }
  235.  
  236. static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
  237. {
  238.     AudioData *s = s1->priv_data;
  239.     int ret, bdelay;
  240.     int64_t cur_time;
  241.     struct audio_buf_info abufi;
  242.  
  243.     if ((ret=av_new_packet(pkt, s->frame_size)) < 0)
  244.         return ret;
  245.  
  246.     ret = read(s->fd, pkt->data, pkt->size);
  247.     if (ret <= 0){
  248.         av_free_packet(pkt);
  249.         pkt->size = 0;
  250.         if (ret<0)  return AVERROR(errno);
  251.         else        return AVERROR_EOF;
  252.     }
  253.     pkt->size = ret;
  254.  
  255.     /* compute pts of the start of the packet */
  256.     cur_time = av_gettime();
  257.     bdelay = ret;
  258.     if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) {
  259.         bdelay += abufi.bytes;
  260.     }
  261.     /* subtract time represented by the number of bytes in the audio fifo */
  262.     cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels);
  263.  
  264.     /* convert to wanted units */
  265.     pkt->pts = cur_time;
  266.  
  267.     if (s->flip_left && s->channels == 2) {
  268.         int i;
  269.         short *p = (short *) pkt->data;
  270.  
  271.         for (i = 0; i < ret; i += 4) {
  272.             *p = ~*p;
  273.             p += 2;
  274.         }
  275.     }
  276.     return 0;
  277. }
  278.  
  279. static int audio_read_close(AVFormatContext *s1)
  280. {
  281.     AudioData *s = s1->priv_data;
  282.  
  283.     audio_close(s);
  284.     return 0;
  285. }
  286.  
  287. #if CONFIG_OSS_INDEV
  288. static const AVOption options[] = {
  289.     { "sample_rate", "", offsetof(AudioData, sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
  290.     { "channels",    "", offsetof(AudioData, channels),    AV_OPT_TYPE_INT, {.i64 = 2},     1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
  291.     { NULL },
  292. };
  293.  
  294. static const AVClass oss_demuxer_class = {
  295.     .class_name     = "OSS demuxer",
  296.     .item_name      = av_default_item_name,
  297.     .option         = options,
  298.     .version        = LIBAVUTIL_VERSION_INT,
  299. };
  300.  
  301. AVInputFormat ff_oss_demuxer = {
  302.     .name           = "oss",
  303.     .long_name      = NULL_IF_CONFIG_SMALL("OSS (Open Sound System) capture"),
  304.     .priv_data_size = sizeof(AudioData),
  305.     .read_header    = audio_read_header,
  306.     .read_packet    = audio_read_packet,
  307.     .read_close     = audio_read_close,
  308.     .flags          = AVFMT_NOFILE,
  309.     .priv_class     = &oss_demuxer_class,
  310. };
  311. #endif
  312.  
  313. #if CONFIG_OSS_OUTDEV
  314. AVOutputFormat ff_oss_muxer = {
  315.     .name           = "oss",
  316.     .long_name      = NULL_IF_CONFIG_SMALL("OSS (Open Sound System) playback"),
  317.     .priv_data_size = sizeof(AudioData),
  318.     /* XXX: we make the assumption that the soundcard accepts this format */
  319.     /* XXX: find better solution with "preinit" method, needed also in
  320.        other formats */
  321.     .audio_codec    = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE),
  322.     .video_codec    = AV_CODEC_ID_NONE,
  323.     .write_header   = audio_write_header,
  324.     .write_packet   = audio_write_packet,
  325.     .write_trailer  = audio_write_trailer,
  326.     .flags          = AVFMT_NOFILE,
  327. };
  328. #endif
  329.