Audio support for DV1394 by Max Krasnyansky
Originally committed as revision 1516 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
4
ffmpeg.c
4
ffmpeg.c
@@ -1886,7 +1886,7 @@ void opt_audio_device(const char *arg)
|
|||||||
void opt_dv1394(const char *arg)
|
void opt_dv1394(const char *arg)
|
||||||
{
|
{
|
||||||
video_grab_format = "dv1394";
|
video_grab_format = "dv1394";
|
||||||
audio_grab_format = "none";
|
audio_grab_format = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_audio_codec(const char *arg)
|
void opt_audio_codec(const char *arg)
|
||||||
@@ -2482,7 +2482,7 @@ void prepare_grab(void)
|
|||||||
dump_format(ic, nb_input_files, "", 0);
|
dump_format(ic, nb_input_files, "", 0);
|
||||||
nb_input_files++;
|
nb_input_files++;
|
||||||
}
|
}
|
||||||
if (has_audio) {
|
if (has_audio && audio_grab_format) {
|
||||||
AVInputFormat *fmt1;
|
AVInputFormat *fmt1;
|
||||||
fmt1 = av_find_input_format(audio_grab_format);
|
fmt1 = av_find_input_format(audio_grab_format);
|
||||||
ap->device = audio_device;
|
ap->device = audio_device;
|
||||||
|
@@ -31,29 +31,31 @@
|
|||||||
|
|
||||||
#include "dv1394.h"
|
#include "dv1394.h"
|
||||||
|
|
||||||
int dv1394_channel = DV1394_DEFAULT_CHANNEL;
|
|
||||||
|
|
||||||
struct dv1394_data {
|
struct dv1394_data {
|
||||||
int fd;
|
int fd;
|
||||||
int channel;
|
int channel;
|
||||||
int width, height;
|
int width, height;
|
||||||
int frame_rate;
|
int frame_rate;
|
||||||
int frame_size;
|
int frame_size;
|
||||||
|
int format;
|
||||||
|
|
||||||
void *ring; /* Ring buffer */
|
void *ring; /* Ring buffer */
|
||||||
int index; /* Current frame index */
|
int index; /* Current frame index */
|
||||||
int avail; /* Number of frames available for reading */
|
int avail; /* Number of frames available for reading */
|
||||||
int done; /* Number of completed frames */
|
int done; /* Number of completed frames */
|
||||||
|
|
||||||
|
int stream; /* Current stream. 0 - video, 1 - audio */
|
||||||
|
INT64 pts; /* Current timestamp */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int dv1394_reset(struct dv1394_data *dv)
|
static int dv1394_reset(struct dv1394_data *dv)
|
||||||
{
|
{
|
||||||
struct dv1394_init init;
|
struct dv1394_init init;
|
||||||
|
|
||||||
init.channel = dv->channel;
|
init.channel = dv->channel;
|
||||||
init.api_version = DV1394_API_VERSION;
|
init.api_version = DV1394_API_VERSION;
|
||||||
init.n_frames = DV1394_RING_FRAMES;
|
init.n_frames = DV1394_RING_FRAMES;
|
||||||
init.format = DV1394_NTSC;
|
init.format = dv->format;
|
||||||
|
|
||||||
if (ioctl(dv->fd, DV1394_INIT, &init) < 0)
|
if (ioctl(dv->fd, DV1394_INIT, &init) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -75,12 +77,17 @@ static int dv1394_start(struct dv1394_data *dv)
|
|||||||
static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap)
|
static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap)
|
||||||
{
|
{
|
||||||
struct dv1394_data *dv = context->priv_data;
|
struct dv1394_data *dv = context->priv_data;
|
||||||
AVStream *st;
|
AVStream *vst, *ast;
|
||||||
const char *video_device;
|
const char *video_device;
|
||||||
|
|
||||||
st = av_new_stream(context, 0);
|
vst = av_new_stream(context, 0);
|
||||||
if (!st)
|
if (!vst)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
ast = av_new_stream(context, 1);
|
||||||
|
if (!ast) {
|
||||||
|
av_free(vst);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
dv->width = DV1394_WIDTH;
|
dv->width = DV1394_WIDTH;
|
||||||
dv->height = DV1394_HEIGHT;
|
dv->height = DV1394_HEIGHT;
|
||||||
@@ -90,9 +97,16 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
|
|||||||
else
|
else
|
||||||
dv->channel = DV1394_DEFAULT_CHANNEL;
|
dv->channel = DV1394_DEFAULT_CHANNEL;
|
||||||
|
|
||||||
dv->frame_rate = 30;
|
/* FIXME: Need a format change parameter */
|
||||||
|
dv->format = DV1394_NTSC;
|
||||||
|
|
||||||
dv->frame_size = DV1394_NTSC_FRAME_SIZE;
|
if (dv->format == DV1394_NTSC) {
|
||||||
|
dv->frame_size = DV1394_NTSC_FRAME_SIZE;
|
||||||
|
dv->frame_rate = 30;
|
||||||
|
} else {
|
||||||
|
dv->frame_size = DV1394_PAL_FRAME_SIZE;
|
||||||
|
dv->frame_rate = 25;
|
||||||
|
}
|
||||||
|
|
||||||
/* Open and initialize DV1394 device */
|
/* Open and initialize DV1394 device */
|
||||||
video_device = ap->device;
|
video_device = ap->device;
|
||||||
@@ -116,13 +130,19 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
st->codec.codec_type = CODEC_TYPE_VIDEO;
|
dv->stream = 0;
|
||||||
st->codec.codec_id = CODEC_ID_DVVIDEO;
|
|
||||||
st->codec.width = dv->width;
|
|
||||||
st->codec.height = dv->height;
|
|
||||||
st->codec.frame_rate = dv->frame_rate * FRAME_RATE_BASE;
|
|
||||||
|
|
||||||
st->codec.bit_rate = 25000000; /* Consumer DV is 25Mbps */
|
vst->codec.codec_type = CODEC_TYPE_VIDEO;
|
||||||
|
vst->codec.codec_id = CODEC_ID_DVVIDEO;
|
||||||
|
vst->codec.width = dv->width;
|
||||||
|
vst->codec.height = dv->height;
|
||||||
|
vst->codec.frame_rate = dv->frame_rate * FRAME_RATE_BASE;
|
||||||
|
vst->codec.bit_rate = 25000000; /* Consumer DV is 25Mbps */
|
||||||
|
|
||||||
|
ast->codec.codec_type = CODEC_TYPE_AUDIO;
|
||||||
|
ast->codec.codec_id = CODEC_ID_DVAUDIO;
|
||||||
|
ast->codec.channels = 2;
|
||||||
|
ast->codec.sample_rate= 48000;
|
||||||
|
|
||||||
av_set_pts_info(context, 48, 1, 1000000);
|
av_set_pts_info(context, 48, 1, 1000000);
|
||||||
|
|
||||||
@@ -133,24 +153,32 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
|
|||||||
|
|
||||||
failed:
|
failed:
|
||||||
close(dv->fd);
|
close(dv->fd);
|
||||||
av_free(st);
|
av_free(vst);
|
||||||
|
av_free(ast);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int __copy_frame(struct dv1394_data *dv, void *buf)
|
static inline int __copy_frame(struct dv1394_data *dv, AVPacket *pkt)
|
||||||
{
|
{
|
||||||
char *ptr = dv->ring + (dv->index * dv->frame_size);
|
char *ptr = dv->ring + (dv->index * dv->frame_size);
|
||||||
|
|
||||||
memcpy(buf, ptr, dv->frame_size);
|
if (dv->stream) {
|
||||||
|
dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
|
||||||
|
dv->done++; dv->avail--;
|
||||||
|
} else {
|
||||||
|
dv->pts = av_gettime() & ((1LL << 48) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
|
memcpy(pkt->data, ptr, dv->frame_size);
|
||||||
dv->avail--;
|
pkt->stream_index = dv->stream;
|
||||||
dv->done++;
|
pkt->pts = dv->pts;
|
||||||
|
|
||||||
|
dv->stream ^= 1;
|
||||||
|
|
||||||
return dv->frame_size;
|
return dv->frame_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dv1394_read_packet(AVFormatContext * context, AVPacket * pkt)
|
static int dv1394_read_packet(AVFormatContext *context, AVPacket *pkt)
|
||||||
{
|
{
|
||||||
struct dv1394_data *dv = context->priv_data;
|
struct dv1394_data *dv = context->priv_data;
|
||||||
int len;
|
int len;
|
||||||
@@ -202,8 +230,7 @@ static int dv1394_read_packet(AVFormatContext * context, AVPacket * pkt)
|
|||||||
dv->done);
|
dv->done);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
len = __copy_frame(dv, pkt->data);
|
len = __copy_frame(dv, pkt);
|
||||||
pkt->pts = av_gettime() & ((1LL << 48) - 1);
|
|
||||||
|
|
||||||
if (!dv->avail && dv->done) {
|
if (!dv->avail && dv->done) {
|
||||||
/* Request more frames */
|
/* Request more frames */
|
||||||
|
Reference in New Issue
Block a user