patch for DV capturing by Dan Dennedy <dan at dennedy dot org>
Originally committed as revision 2105 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
6e23091277
commit
1fbe1a61b1
@ -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)
|
|||||||
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)
|
|||||||
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
|
|||||||
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
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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 @@
|
|||||||
#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 @@
|
|||||||
#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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user