GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavdevice/oss.c Lines: 0 51 0.0 %
Date: 2020-09-25 23:16:12 Branches: 0 27 0.0 %

Line Branch Exec Source
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
24
#include <string.h>
25
26
#if HAVE_UNISTD_H
27
#include <unistd.h>
28
#endif
29
#include <fcntl.h>
30
#include <sys/ioctl.h>
31
#include <sys/soundcard.h>
32
33
#include "libavutil/log.h"
34
35
#include "libavcodec/avcodec.h"
36
#include "avdevice.h"
37
38
#include "oss.h"
39
40
int ff_oss_audio_open(AVFormatContext *s1, int is_output,
41
                      const char *audio_device)
42
{
43
    OSSAudioData *s = s1->priv_data;
44
    int audio_fd;
45
    int tmp, err;
46
    char *flip = getenv("AUDIO_FLIP_LEFT");
47
48
    if (is_output)
49
        audio_fd = avpriv_open(audio_device, O_WRONLY);
50
    else
51
        audio_fd = avpriv_open(audio_device, O_RDONLY);
52
    if (audio_fd < 0) {
53
        av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, av_err2str(AVERROR(errno)));
54
        return AVERROR(EIO);
55
    }
56
57
    if (flip && *flip == '1') {
58
        s->flip_left = 1;
59
    }
60
61
    /* non blocking mode */
62
    if (!is_output) {
63
        if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) {
64
            av_log(s1, AV_LOG_WARNING, "%s: Could not enable non block mode (%s)\n", audio_device, av_err2str(AVERROR(errno)));
65
        }
66
    }
67
68
    s->frame_size = OSS_AUDIO_BLOCK_SIZE;
69
70
#define CHECK_IOCTL_ERROR(event)                                              \
71
    if (err < 0) {                                                            \
72
        av_log(s1, AV_LOG_ERROR, #event ": %s\n", av_err2str(AVERROR(errno)));\
73
        goto fail;                                                            \
74
    }
75
76
    /* select format : favour native format
77
     * We don't CHECK_IOCTL_ERROR here because even if failed OSS still may be
78
     * usable. If OSS is not usable the SNDCTL_DSP_SETFMTS later is going to
79
     * fail anyway. */
80
    err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp);
81
    if (err < 0) {
82
        av_log(s1, AV_LOG_WARNING, "SNDCTL_DSP_GETFMTS: %s\n", av_err2str(AVERROR(errno)));
83
    }
84
85
#if HAVE_BIGENDIAN
86
    if (tmp & AFMT_S16_BE) {
87
        tmp = AFMT_S16_BE;
88
    } else if (tmp & AFMT_S16_LE) {
89
        tmp = AFMT_S16_LE;
90
    } else {
91
        tmp = 0;
92
    }
93
#else
94
    if (tmp & AFMT_S16_LE) {
95
        tmp = AFMT_S16_LE;
96
    } else if (tmp & AFMT_S16_BE) {
97
        tmp = AFMT_S16_BE;
98
    } else {
99
        tmp = 0;
100
    }
101
#endif
102
103
    switch(tmp) {
104
    case AFMT_S16_LE:
105
        s->codec_id = AV_CODEC_ID_PCM_S16LE;
106
        break;
107
    case AFMT_S16_BE:
108
        s->codec_id = AV_CODEC_ID_PCM_S16BE;
109
        break;
110
    default:
111
        av_log(s1, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n");
112
        close(audio_fd);
113
        return AVERROR(EIO);
114
    }
115
    err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp);
116
    CHECK_IOCTL_ERROR(SNDCTL_DSP_SETFMTS)
117
118
    tmp = (s->channels == 2);
119
    err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
120
    CHECK_IOCTL_ERROR(SNDCTL_DSP_STEREO)
121
122
    tmp = s->sample_rate;
123
    err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp);
124
    CHECK_IOCTL_ERROR(SNDCTL_DSP_SPEED)
125
    s->sample_rate = tmp; /* store real sample rate */
126
    s->fd = audio_fd;
127
128
    return 0;
129
 fail:
130
    close(audio_fd);
131
    return AVERROR(EIO);
132
#undef CHECK_IOCTL_ERROR
133
}
134
135
int ff_oss_audio_close(OSSAudioData *s)
136
{
137
    close(s->fd);
138
    return 0;
139
}