1
mirror of https://git.videolan.org/git/ffmpeg.git synced 2024-10-01 00:54:33 +02:00

sndio: Coalesce source files after outdev removal

This commit is contained in:
Diego Biurrun 2017-09-27 15:12:41 +02:00
parent 8e7e042d41
commit 8d3db95f20
4 changed files with 105 additions and 175 deletions

View File

@ -18,7 +18,7 @@ OBJS-$(CONFIG_FBDEV_INDEV) += fbdev.o
OBJS-$(CONFIG_JACK_INDEV) += jack.o timefilter.o
OBJS-$(CONFIG_OSS_INDEV) += oss_dec.o oss.o
OBJS-$(CONFIG_PULSE_INDEV) += pulse.o
OBJS-$(CONFIG_SNDIO_INDEV) += sndio_dec.o sndio.o
OBJS-$(CONFIG_SNDIO_INDEV) += sndio.o
OBJS-$(CONFIG_V4L2_INDEV) += v4l2.o
OBJS-$(CONFIG_VFWCAP_INDEV) += vfwcap.o
OBJS-$(CONFIG_XCBGRAB_INDEV) += xcbgrab.o

View File

@ -1,5 +1,5 @@
/*
* sndio play and grab interface
* sndio grab interface
* Copyright (c) 2010 Jacob Meuser
*
* This file is part of Libav.
@ -22,9 +22,26 @@
#include <stdint.h>
#include <sndio.h>
#include "libavformat/avformat.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"
#include "libavutil/time.h"
#include "libavdevice/sndio.h"
#include "libavformat/avformat.h"
#include "libavformat/internal.h"
typedef struct SndioData {
AVClass *class;
struct sio_hdl *hdl;
enum AVCodecID codec_id;
int64_t hwpos;
int64_t softpos;
uint8_t *buffer;
int bps;
int buffer_size;
int buffer_offset;
int channels;
int sample_rate;
} SndioData;
static inline void movecb(void *addr, int delta)
{
@ -33,8 +50,8 @@ static inline void movecb(void *addr, int delta)
s->hwpos += delta * s->channels * s->bps;
}
av_cold int ff_sndio_open(AVFormatContext *s1, int is_output,
const char *audio_device)
static av_cold int sndio_open(AVFormatContext *s1, int is_output,
const char *audio_device)
{
SndioData *s = s1->priv_data;
struct sio_hdl *hdl;
@ -109,8 +126,65 @@ fail:
return AVERROR(EIO);
}
int ff_sndio_close(SndioData *s)
static av_cold int audio_read_header(AVFormatContext *s1)
{
SndioData *s = s1->priv_data;
AVStream *st;
int ret;
st = avformat_new_stream(s1, NULL);
if (!st)
return AVERROR(ENOMEM);
ret = sndio_open(s1, 0, s1->filename);
if (ret < 0)
return ret;
/* take real parameters */
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
st->codecpar->codec_id = s->codec_id;
st->codecpar->sample_rate = s->sample_rate;
st->codecpar->channels = s->channels;
avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
return 0;
}
static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
{
SndioData *s = s1->priv_data;
int64_t bdelay, cur_time;
int ret;
if ((ret = av_new_packet(pkt, s->buffer_size)) < 0)
return ret;
ret = sio_read(s->hdl, pkt->data, pkt->size);
if (ret == 0 || sio_eof(s->hdl)) {
av_packet_unref(pkt);
return AVERROR_EOF;
}
pkt->size = ret;
s->softpos += ret;
/* compute pts of the start of the packet */
cur_time = av_gettime();
bdelay = ret + s->hwpos - s->softpos;
/* convert to pts */
pkt->pts = cur_time - ((bdelay * 1000000) /
(s->bps * s->channels * s->sample_rate));
return 0;
}
static av_cold int audio_read_close(AVFormatContext *s1)
{
SndioData *s = s1->priv_data;
av_freep(&s->buffer);
if (s->hdl)
@ -118,3 +192,27 @@ int ff_sndio_close(SndioData *s)
return 0;
}
static const AVOption options[] = {
{ "sample_rate", "", offsetof(SndioData, sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
{ "channels", "", offsetof(SndioData, channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
};
static const AVClass sndio_demuxer_class = {
.class_name = "sndio indev",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};
AVInputFormat ff_sndio_demuxer = {
.name = "sndio",
.long_name = NULL_IF_CONFIG_SMALL("sndio audio capture"),
.priv_data_size = sizeof(SndioData),
.read_header = audio_read_header,
.read_packet = audio_read_packet,
.read_close = audio_read_close,
.flags = AVFMT_NOFILE,
.priv_class = &sndio_demuxer_class,
};

View File

@ -1,48 +0,0 @@
/*
* sndio play and grab interface
* Copyright (c) 2010 Jacob Meuser
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVDEVICE_SNDIO_H
#define AVDEVICE_SNDIO_H
#include <stdint.h>
#include <sndio.h>
#include "libavformat/avformat.h"
#include "libavutil/log.h"
typedef struct SndioData {
AVClass *class;
struct sio_hdl *hdl;
enum AVCodecID codec_id;
int64_t hwpos;
int64_t softpos;
uint8_t *buffer;
int bps;
int buffer_size;
int buffer_offset;
int channels;
int sample_rate;
} SndioData;
int ff_sndio_open(AVFormatContext *s1, int is_output, const char *audio_device);
int ff_sndio_close(SndioData *s);
#endif /* AVDEVICE_SNDIO_H */

View File

@ -1,120 +0,0 @@
/*
* sndio play and grab interface
* Copyright (c) 2010 Jacob Meuser
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include <sndio.h>
#include "libavutil/internal.h"
#include "libavutil/opt.h"
#include "libavutil/time.h"
#include "libavformat/avformat.h"
#include "libavformat/internal.h"
#include "libavdevice/sndio.h"
static av_cold int audio_read_header(AVFormatContext *s1)
{
SndioData *s = s1->priv_data;
AVStream *st;
int ret;
st = avformat_new_stream(s1, NULL);
if (!st)
return AVERROR(ENOMEM);
ret = ff_sndio_open(s1, 0, s1->filename);
if (ret < 0)
return ret;
/* take real parameters */
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
st->codecpar->codec_id = s->codec_id;
st->codecpar->sample_rate = s->sample_rate;
st->codecpar->channels = s->channels;
avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
return 0;
}
static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
{
SndioData *s = s1->priv_data;
int64_t bdelay, cur_time;
int ret;
if ((ret = av_new_packet(pkt, s->buffer_size)) < 0)
return ret;
ret = sio_read(s->hdl, pkt->data, pkt->size);
if (ret == 0 || sio_eof(s->hdl)) {
av_packet_unref(pkt);
return AVERROR_EOF;
}
pkt->size = ret;
s->softpos += ret;
/* compute pts of the start of the packet */
cur_time = av_gettime();
bdelay = ret + s->hwpos - s->softpos;
/* convert to pts */
pkt->pts = cur_time - ((bdelay * 1000000) /
(s->bps * s->channels * s->sample_rate));
return 0;
}
static av_cold int audio_read_close(AVFormatContext *s1)
{
SndioData *s = s1->priv_data;
ff_sndio_close(s);
return 0;
}
static const AVOption options[] = {
{ "sample_rate", "", offsetof(SndioData, sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
{ "channels", "", offsetof(SndioData, channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
};
static const AVClass sndio_demuxer_class = {
.class_name = "sndio indev",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};
AVInputFormat ff_sndio_demuxer = {
.name = "sndio",
.long_name = NULL_IF_CONFIG_SMALL("sndio audio capture"),
.priv_data_size = sizeof(SndioData),
.read_header = audio_read_header,
.read_packet = audio_read_packet,
.read_close = audio_read_close,
.flags = AVFMT_NOFILE,
.priv_class = &sndio_demuxer_class,
};