From 1501987b465de317c0e65e5fb5063ee0ea83f95a Mon Sep 17 00:00:00 2001 From: Fabrice Bellard Date: Mon, 27 Jan 2003 22:59:42 +0000 Subject: [PATCH] Audio support for DV1394 by Max Krasnyansky Originally committed as revision 1516 to svn://svn.ffmpeg.org/ffmpeg/trunk --- ffmpeg.c | 4 +-- libavformat/dv1394.c | 77 ++++++++++++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 8fb82e6e0f..7288fc99e6 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -1886,7 +1886,7 @@ void opt_audio_device(const char *arg) void opt_dv1394(const char *arg) { video_grab_format = "dv1394"; - audio_grab_format = "none"; + audio_grab_format = NULL; } void opt_audio_codec(const char *arg) @@ -2482,7 +2482,7 @@ void prepare_grab(void) dump_format(ic, nb_input_files, "", 0); nb_input_files++; } - if (has_audio) { + if (has_audio && audio_grab_format) { AVInputFormat *fmt1; fmt1 = av_find_input_format(audio_grab_format); ap->device = audio_device; diff --git a/libavformat/dv1394.c b/libavformat/dv1394.c index 2c70827007..7208277a1d 100644 --- a/libavformat/dv1394.c +++ b/libavformat/dv1394.c @@ -31,29 +31,31 @@ #include "dv1394.h" -int dv1394_channel = DV1394_DEFAULT_CHANNEL; - struct dv1394_data { int fd; int channel; int width, height; int frame_rate; int frame_size; + int format; void *ring; /* Ring buffer */ int index; /* Current frame index */ int avail; /* Number of frames available for reading */ 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) { struct dv1394_init init; - init.channel = dv->channel; + init.channel = dv->channel; init.api_version = DV1394_API_VERSION; - init.n_frames = DV1394_RING_FRAMES; - init.format = DV1394_NTSC; + init.n_frames = DV1394_RING_FRAMES; + init.format = dv->format; if (ioctl(dv->fd, DV1394_INIT, &init) < 0) return -1; @@ -75,12 +77,17 @@ static int dv1394_start(struct dv1394_data *dv) static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap) { struct dv1394_data *dv = context->priv_data; - AVStream *st; + AVStream *vst, *ast; const char *video_device; - st = av_new_stream(context, 0); - if (!st) + vst = av_new_stream(context, 0); + if (!vst) return -ENOMEM; + ast = av_new_stream(context, 1); + if (!ast) { + av_free(vst); + return -ENOMEM; + } dv->width = DV1394_WIDTH; dv->height = DV1394_HEIGHT; @@ -90,9 +97,16 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap else 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 */ video_device = ap->device; @@ -116,13 +130,19 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap goto failed; } - st->codec.codec_type = CODEC_TYPE_VIDEO; - 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; + dv->stream = 0; - 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); @@ -133,24 +153,32 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap failed: close(dv->fd); - av_free(st); + av_free(vst); + av_free(ast); 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); - 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; - dv->avail--; - dv->done++; + memcpy(pkt->data, ptr, dv->frame_size); + pkt->stream_index = dv->stream; + pkt->pts = dv->pts; + + dv->stream ^= 1; 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; int len; @@ -202,8 +230,7 @@ static int dv1394_read_packet(AVFormatContext * context, AVPacket * pkt) dv->done); #endif - len = __copy_frame(dv, pkt->data); - pkt->pts = av_gettime() & ((1LL << 48) - 1); + len = __copy_frame(dv, pkt); if (!dv->avail && dv->done) { /* Request more frames */