Commit 3552761e authored by romansh's avatar romansh

patch for DV capturing by Dan Dennedy <dan at dennedy dot org>


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@2105 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent c919adaf
...@@ -47,8 +47,15 @@ struct dv1394_data { ...@@ -47,8 +47,15 @@ struct dv1394_data {
int stream; /* Current stream. 0 - video, 1 - audio */ int stream; /* Current stream. 0 - video, 1 - audio */
int64_t pts; /* Current timestamp */ int64_t pts; /* Current timestamp */
AVStream *vst, *ast;
}; };
/*
* The trick here is to kludge around well known problem with kernel Ooopsing
* when you try to capture PAL on a device node configure for NTSC. That's
* why we have to configure the device node for PAL, and then read only NTSC
* amount of data.
*/
static int dv1394_reset(struct dv1394_data *dv) static int dv1394_reset(struct dv1394_data *dv)
{ {
struct dv1394_init init; struct dv1394_init init;
...@@ -56,7 +63,7 @@ static int dv1394_reset(struct dv1394_data *dv) ...@@ -56,7 +63,7 @@ static int dv1394_reset(struct dv1394_data *dv)
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 = dv->format; init.format = DV1394_PAL;
if (ioctl(dv->fd, DV1394_INIT, &init) < 0) if (ioctl(dv->fd, DV1394_INIT, &init) < 0)
return -1; return -1;
...@@ -79,15 +86,14 @@ static int dv1394_start(struct dv1394_data *dv) ...@@ -79,15 +86,14 @@ 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 *vst, *ast;
const char *video_device; const char *video_device;
vst = av_new_stream(context, 0); dv->vst = av_new_stream(context, 0);
if (!vst) if (!dv->vst)
return -ENOMEM; return -ENOMEM;
ast = av_new_stream(context, 1); dv->ast = av_new_stream(context, 1);
if (!ast) { if (!dv->ast) {
av_free(vst); av_free(dv->vst);
return -ENOMEM; return -ENOMEM;
} }
...@@ -127,27 +133,27 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap ...@@ -127,27 +133,27 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
goto failed; goto failed;
} }
dv->ring = mmap(NULL, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES, dv->ring = mmap(NULL, DV1394_PAL_FRAME_SIZE * DV1394_RING_FRAMES,
PROT_READ, MAP_PRIVATE, dv->fd, 0); PROT_READ, MAP_PRIVATE, dv->fd, 0);
if (!dv->ring) { if (dv->ring == MAP_FAILED) {
perror("Failed to mmap DV ring buffer"); perror("Failed to mmap DV ring buffer");
goto failed; goto failed;
} }
dv->stream = 0; dv->stream = 0;
vst->codec.codec_type = CODEC_TYPE_VIDEO; dv->vst->codec.codec_type = CODEC_TYPE_VIDEO;
vst->codec.codec_id = CODEC_ID_DVVIDEO; dv->vst->codec.codec_id = CODEC_ID_DVVIDEO;
vst->codec.width = dv->width; dv->vst->codec.width = dv->width;
vst->codec.height = dv->height; dv->vst->codec.height = dv->height;
vst->codec.frame_rate = dv->frame_rate; dv->vst->codec.frame_rate = dv->frame_rate;
vst->codec.frame_rate_base = 1; dv->vst->codec.frame_rate_base = 1;
vst->codec.bit_rate = 25000000; /* Consumer DV is 25Mbps */ dv->vst->codec.bit_rate = 25000000; /* Consumer DV is 25Mbps */
ast->codec.codec_type = CODEC_TYPE_AUDIO; dv->ast->codec.codec_type = CODEC_TYPE_AUDIO;
ast->codec.codec_id = CODEC_ID_DVAUDIO; dv->ast->codec.codec_id = CODEC_ID_DVAUDIO;
ast->codec.channels = 2; dv->ast->codec.channels = 2;
ast->codec.sample_rate= 48000; dv->ast->codec.sample_rate= 48000;
av_set_pts_info(context, 48, 1, 1000000); av_set_pts_info(context, 48, 1, 1000000);
...@@ -158,8 +164,8 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap ...@@ -158,8 +164,8 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
failed: failed:
close(dv->fd); close(dv->fd);
av_free(vst); av_free(dv->vst);
av_free(ast); av_free(dv->ast);
return -EIO; return -EIO;
} }
...@@ -171,7 +177,7 @@ static void __destruct_pkt(struct AVPacket *pkt) ...@@ -171,7 +177,7 @@ static void __destruct_pkt(struct AVPacket *pkt)
static inline int __get_frame(struct dv1394_data *dv, AVPacket *pkt) static inline int __get_frame(struct dv1394_data *dv, AVPacket *pkt)
{ {
char *ptr = dv->ring + (dv->index * dv->frame_size); char *ptr = dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE);
if (dv->stream) { if (dv->stream) {
dv->index = (dv->index + 1) % DV1394_RING_FRAMES; dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
...@@ -180,6 +186,17 @@ static inline int __get_frame(struct dv1394_data *dv, AVPacket *pkt) ...@@ -180,6 +186,17 @@ static inline int __get_frame(struct dv1394_data *dv, AVPacket *pkt)
dv->pts = av_gettime() & ((1LL << 48) - 1); dv->pts = av_gettime() & ((1LL << 48) - 1);
} }
dv->format = ((ptr[3] & 0x80) == 0) ? DV1394_NTSC : DV1394_PAL;
if (dv->format == DV1394_NTSC) {
dv->frame_size = DV1394_NTSC_FRAME_SIZE;
dv->vst->codec.height = dv->height = DV1394_NTSC_HEIGHT;
dv->vst->codec.frame_rate = dv->frame_rate = 30;
} else {
dv->frame_size = DV1394_PAL_FRAME_SIZE;
dv->vst->codec.height = dv->height = DV1394_PAL_HEIGHT;
dv->vst->codec.frame_rate = dv->frame_rate = 25;
}
av_init_packet(pkt); av_init_packet(pkt);
pkt->destruct = __destruct_pkt; pkt->destruct = __destruct_pkt;
pkt->data = ptr; pkt->data = ptr;
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#ifndef _DV_1394_H #ifndef _DV_1394_H
#define _DV_1394_H #define _DV_1394_H
#define DV1394_DEFAULT_CHANNEL 0x63 #define DV1394_DEFAULT_CHANNEL 63
#define DV1394_DEFAULT_CARD 0 #define DV1394_DEFAULT_CARD 0
#define DV1394_RING_FRAMES 20 #define DV1394_RING_FRAMES 20
...@@ -199,12 +199,12 @@ ...@@ -199,12 +199,12 @@
#define DV1394_MAX_FRAMES 32 #define DV1394_MAX_FRAMES 32
/* number of *full* isochronous packets per DV frame */ /* number of *full* isochronous packets per DV frame */
#define DV1394_NTSC_PACKETS_PER_FRAME 300 #define DV1394_NTSC_PACKETS_PER_FRAME 250
#define DV1394_PAL_PACKETS_PER_FRAME 250 #define DV1394_PAL_PACKETS_PER_FRAME 300
/* size of one frame's worth of DV data, in bytes */ /* size of one frame's worth of DV data, in bytes */
#define DV1394_NTSC_FRAME_SIZE (480 * DV1394_NTSC_PACKETS_PER_FRAME) #define DV1394_NTSC_FRAME_SIZE (480 * DV1394_NTSC_PACKETS_PER_FRAME)
#define DV1394_PAL_FRAME_SIZE (576 * DV1394_PAL_PACKETS_PER_FRAME) #define DV1394_PAL_FRAME_SIZE (480 * DV1394_PAL_PACKETS_PER_FRAME)
/* ioctl() commands */ /* ioctl() commands */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment