LCOV - code coverage report
Current view: top level - src/libavdevice - alsa_enc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 59 0.0 %
Date: 2017-01-19 23:52:33 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /*
       2             :  * ALSA input and output
       3             :  * Copyright (c) 2007 Luca Abeni ( lucabe72 email it )
       4             :  * Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr )
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : /**
      24             :  * @file
      25             :  * ALSA input and output: output
      26             :  * @author Luca Abeni ( lucabe72 email it )
      27             :  * @author Benoit Fouet ( benoit fouet free fr )
      28             :  *
      29             :  * This avdevice encoder can play audio to an ALSA (Advanced Linux
      30             :  * Sound Architecture) device.
      31             :  *
      32             :  * The filename parameter is the name of an ALSA PCM device capable of
      33             :  * capture, for example "default" or "plughw:1"; see the ALSA documentation
      34             :  * for naming conventions. The empty string is equivalent to "default".
      35             :  *
      36             :  * The playback period is set to the lower value available for the device,
      37             :  * which gives a low latency suitable for real-time playback.
      38             :  */
      39             : 
      40             : #include <alsa/asoundlib.h>
      41             : 
      42             : #include "libavutil/internal.h"
      43             : #include "libavutil/time.h"
      44             : 
      45             : 
      46             : #include "libavformat/internal.h"
      47             : #include "avdevice.h"
      48             : #include "alsa.h"
      49             : 
      50           0 : static av_cold int audio_write_header(AVFormatContext *s1)
      51             : {
      52           0 :     AlsaData *s = s1->priv_data;
      53           0 :     AVStream *st = NULL;
      54             :     unsigned int sample_rate;
      55             :     enum AVCodecID codec_id;
      56             :     int res;
      57             : 
      58           0 :     if (s1->nb_streams != 1 || s1->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
      59           0 :         av_log(s1, AV_LOG_ERROR, "Only a single audio stream is supported.\n");
      60           0 :         return AVERROR(EINVAL);
      61             :     }
      62           0 :     st = s1->streams[0];
      63             : 
      64           0 :     sample_rate = st->codecpar->sample_rate;
      65           0 :     codec_id    = st->codecpar->codec_id;
      66           0 :     res = ff_alsa_open(s1, SND_PCM_STREAM_PLAYBACK, &sample_rate,
      67           0 :         st->codecpar->channels, &codec_id);
      68           0 :     if (sample_rate != st->codecpar->sample_rate) {
      69           0 :         av_log(s1, AV_LOG_ERROR,
      70             :                "sample rate %d not available, nearest is %d\n",
      71           0 :                st->codecpar->sample_rate, sample_rate);
      72           0 :         goto fail;
      73             :     }
      74           0 :     avpriv_set_pts_info(st, 64, 1, sample_rate);
      75             : 
      76           0 :     return res;
      77             : 
      78             : fail:
      79           0 :     snd_pcm_close(s->h);
      80           0 :     return AVERROR(EIO);
      81             : }
      82             : 
      83           0 : static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt)
      84             : {
      85           0 :     AlsaData *s = s1->priv_data;
      86             :     int res;
      87           0 :     int size     = pkt->size;
      88           0 :     uint8_t *buf = pkt->data;
      89             : 
      90           0 :     size /= s->frame_size;
      91           0 :     if (pkt->dts != AV_NOPTS_VALUE)
      92           0 :         s->timestamp = pkt->dts;
      93           0 :     s->timestamp += pkt->duration ? pkt->duration : size;
      94             : 
      95           0 :     if (s->reorder_func) {
      96           0 :         if (size > s->reorder_buf_size)
      97           0 :             if (ff_alsa_extend_reorder_buf(s, size))
      98           0 :                 return AVERROR(ENOMEM);
      99           0 :         s->reorder_func(buf, s->reorder_buf, size);
     100           0 :         buf = s->reorder_buf;
     101             :     }
     102           0 :     while ((res = snd_pcm_writei(s->h, buf, size)) < 0) {
     103           0 :         if (res == -EAGAIN) {
     104             : 
     105           0 :             return AVERROR(EAGAIN);
     106             :         }
     107             : 
     108           0 :         if (ff_alsa_xrun_recover(s1, res) < 0) {
     109           0 :             av_log(s1, AV_LOG_ERROR, "ALSA write error: %s\n",
     110             :                    snd_strerror(res));
     111             : 
     112           0 :             return AVERROR(EIO);
     113             :         }
     114             :     }
     115             : 
     116           0 :     return 0;
     117             : }
     118             : 
     119           0 : static int audio_write_frame(AVFormatContext *s1, int stream_index,
     120             :                              AVFrame **frame, unsigned flags)
     121             : {
     122           0 :     AlsaData *s = s1->priv_data;
     123             :     AVPacket pkt;
     124             : 
     125             :     /* ff_alsa_open() should have accepted only supported formats */
     126           0 :     if ((flags & AV_WRITE_UNCODED_FRAME_QUERY))
     127           0 :         return av_sample_fmt_is_planar(s1->streams[stream_index]->codecpar->format) ?
     128           0 :                AVERROR(EINVAL) : 0;
     129             :     /* set only used fields */
     130           0 :     pkt.data     = (*frame)->data[0];
     131           0 :     pkt.size     = (*frame)->nb_samples * s->frame_size;
     132           0 :     pkt.dts      = (*frame)->pkt_dts;
     133           0 :     pkt.duration = av_frame_get_pkt_duration(*frame);
     134           0 :     return audio_write_packet(s1, &pkt);
     135             : }
     136             : 
     137             : static void
     138           0 : audio_get_output_timestamp(AVFormatContext *s1, int stream,
     139             :     int64_t *dts, int64_t *wall)
     140             : {
     141           0 :     AlsaData *s  = s1->priv_data;
     142           0 :     snd_pcm_sframes_t delay = 0;
     143           0 :     *wall = av_gettime();
     144           0 :     snd_pcm_delay(s->h, &delay);
     145           0 :     *dts = s->timestamp - delay;
     146           0 : }
     147             : 
     148           0 : static int audio_get_device_list(AVFormatContext *h, AVDeviceInfoList *device_list)
     149             : {
     150           0 :     return ff_alsa_get_device_list(device_list, SND_PCM_STREAM_PLAYBACK);
     151             : }
     152             : 
     153             : static const AVClass alsa_muxer_class = {
     154             :     .class_name     = "ALSA muxer",
     155             :     .item_name      = av_default_item_name,
     156             :     .version        = LIBAVUTIL_VERSION_INT,
     157             :     .category       = AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT,
     158             : };
     159             : 
     160             : AVOutputFormat ff_alsa_muxer = {
     161             :     .name           = "alsa",
     162             :     .long_name      = NULL_IF_CONFIG_SMALL("ALSA audio output"),
     163             :     .priv_data_size = sizeof(AlsaData),
     164             :     .audio_codec    = DEFAULT_CODEC_ID,
     165             :     .video_codec    = AV_CODEC_ID_NONE,
     166             :     .write_header   = audio_write_header,
     167             :     .write_packet   = audio_write_packet,
     168             :     .write_trailer  = ff_alsa_close,
     169             :     .write_uncoded_frame = audio_write_frame,
     170             :     .get_device_list = audio_get_device_list,
     171             :     .get_output_timestamp = audio_get_output_timestamp,
     172             :     .flags          = AVFMT_NOFILE,
     173             :     .priv_class     = &alsa_muxer_class,
     174             : };

Generated by: LCOV version 1.12