Commit 8aa3ee32 authored by Max Krasnyansky's avatar Max Krasnyansky Committed by Fabrice Bellard

dv patch by Max Krasnyansky (maxk at qualcomm dot com)

Originally committed as revision 1493 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 4b8b2edb
......@@ -53,6 +53,7 @@ gprof="no"
v4l="yes"
audio_oss="yes"
audio_beos="no"
dv1394="yes"
network="yes"
zlib="yes"
mp3lame="no"
......@@ -103,6 +104,7 @@ SHFLAGS=-nostart
# disable linux things
audio_oss="no"
v4l="no"
dv1394="no"
# enable beos things
audio_beos="yes"
# no need for libm, but the inet stuff
......@@ -117,6 +119,7 @@ fi ;;
SunOS)
v4l="no"
audio_oss="no"
dv1394="no"
make="gmake"
LDFLAGS=""
FFSLDFLAGS=""
......@@ -126,12 +129,14 @@ extralibs="$extralibs -lsocket -lnsl"
FreeBSD)
v4l="no"
audio_oss="yes"
dv1394="no"
make="gmake"
LDFLAGS="$LDFLAGS -export-dynamic"
;;
BSD/OS)
v4l="no"
audio_oss="yes"
dv1394="no"
extralibs="-lpoll -lgnugetopt -lm"
make="gmake"
;;
......@@ -139,6 +144,7 @@ Darwin)
cc="cc"
v4l="no"
audio_oss="no"
dv1394="no"
SHFLAGS="-dynamiclib"
extralibs=""
darwin="yes"
......@@ -158,6 +164,7 @@ esac
MINGW32*)
v4l="no"
audio_oss="no"
dv1394="no"
ffserver="no"
network="no"
mingw32="yes"
......@@ -165,6 +172,7 @@ mingw32="yes"
CYGWIN*)
v4l="no"
audio_oss="yes"
dv1394="no"
extralibs=""
cygwin="yes"
test -f /usr/include/inttypes.h || \
......@@ -190,6 +198,7 @@ SLIBSUF=".dll"
extralibs=""
v4l="no"
audio_oss="no"
dv1394="no"
network="no"
ffserver="no"
os2="yes"
......@@ -287,6 +296,8 @@ for opt do
;;
--disable-audio-beos) audio_beos="no"
;;
--disable-dv1394) dv1394="no"
;;
--disable-network) network="no"
;;
--disable-zlib) zlib="no"
......@@ -375,6 +386,7 @@ if test "$win32" = "yes" ; then
cross_prefix="i386-mingw32msvc-"
v4l="no"
audio_oss="no"
dv1394="no"
network="no"
fi
......@@ -382,6 +394,7 @@ if test "$mingw32" = "yes" ; then
cross_prefix=""
v4l="no"
audio_oss="no"
dv1394="no"
network="no"
fi
......@@ -543,6 +556,7 @@ echo " --disable-altivec disable AltiVec usage"
echo " --disable-audio-oss disable OSS audio support [default=no]"
echo " --disable-audio-beos disable BeOS audio support [default=no]"
echo " --disable-v4l disable video4linux grabbing [default=no]"
echo " --disable-dv1394 disable DV1394 grabbing [default=no]"
echo " --disable-network disable network support [default=no]"
echo " --disable-zlib disable zlib [default=no]"
echo " --disable-simple_idct disable simple IDCT routines [default=no]"
......@@ -705,6 +719,11 @@ if test "$v4l" = "yes" ; then
echo "CONFIG_VIDEO4LINUX=yes" >> config.mak
fi
if test "$dv1394" = "yes" ; then
echo "#define CONFIG_DV1394 1" >> $TMPH
echo "CONFIG_DV1394=yes" >> config.mak
fi
if test "$dlopen" = "yes" ; then
echo "#define CONFIG_HAVE_DLOPEN 1" >> $TMPH
fi
......
......@@ -158,14 +158,14 @@ static char *pass_logfilename = NULL;
static int audio_stream_copy = 0;
static int video_stream_copy = 0;
static char *video_grab_format = "video4linux";
static char *audio_grab_format = "audio_device";
#define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
#if !defined(CONFIG_AUDIO_OSS) && !defined(CONFIG_AUDIO_BEOS)
const char *audio_device = "none";
#endif
#ifndef CONFIG_VIDEO4LINUX
const char *v4l_device = "none";
#endif
typedef struct AVOutputStream {
int file_index; /* file index */
......@@ -1870,7 +1870,7 @@ void opt_audio_channels(const char *arg)
void opt_video_device(const char *arg)
{
v4l_device = strdup(arg);
video_device = strdup(arg);
}
void opt_audio_device(const char *arg)
......@@ -1878,6 +1878,12 @@ void opt_audio_device(const char *arg)
audio_device = strdup(arg);
}
void opt_dv1394(const char *arg)
{
video_grab_format = "dv1394";
audio_grab_format = "none";
}
void opt_audio_codec(const char *arg)
{
AVCodec *p;
......@@ -2455,7 +2461,7 @@ void prepare_grab(void)
if (has_video) {
AVInputFormat *fmt1;
fmt1 = av_find_input_format("video_grab_device");
fmt1 = av_find_input_format(video_grab_format);
if (av_open_input_file(&ic, "", fmt1, 0, ap) < 0) {
fprintf(stderr, "Could not find video grab device\n");
exit(1);
......@@ -2463,12 +2469,12 @@ void prepare_grab(void)
/* by now video grab has one stream */
ic->streams[0]->r_frame_rate = ap->frame_rate;
input_files[nb_input_files] = ic;
dump_format(ic, nb_input_files, v4l_device, 0);
dump_format(ic, nb_input_files, video_device, 0);
nb_input_files++;
}
if (has_audio) {
AVInputFormat *fmt1;
fmt1 = av_find_input_format("audio_device");
fmt1 = av_find_input_format(audio_grab_format);
if (av_open_input_file(&ic, "", fmt1, 0, ap) < 0) {
fprintf(stderr, "Could not find audio grab device\n");
exit(1);
......@@ -2692,6 +2698,7 @@ const OptionDef options[] = {
{ "minrate", HAS_ARG, {(void*)opt_video_bitrate_min}, "set min video bitrate tolerance (in kbit/s)", "bitrate" },
{ "bufsize", HAS_ARG, {(void*)opt_video_buffer_size}, "set ratecontrol buffere size (in kbit)", "size" },
{ "vd", HAS_ARG | OPT_EXPERT, {(void*)opt_video_device}, "set video grab device", "device" },
{ "dv1394", OPT_EXPERT, {(void*)opt_dv1394}, "set DV1394 options", "[channel]" },
{ "vcodec", HAS_ARG | OPT_EXPERT, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" },
{ "me", HAS_ARG | OPT_EXPERT, {(void*)opt_motion_estimation}, "set motion estimation method",
"method" },
......
......@@ -28,6 +28,10 @@ ifeq ($(CONFIG_VIDEO4LINUX),yes)
OBJS+= grab.o
endif
ifeq ($(CONFIG_DV1394),yes)
OBJS+= dv1394.o
endif
ifeq ($(CONFIG_AUDIO_OSS),yes)
OBJS+= audio.o
endif
......
......@@ -21,6 +21,8 @@
/* If you do not call this function, then you can select exactly which
formats you want to support */
char *video_device = "none";
/**
* Initialize libavcodec and register all the codecs and formats.
*/
......@@ -62,6 +64,10 @@ void av_register_all(void)
audio_init();
#endif
#ifdef CONFIG_DV1394
dv1394_init();
#endif
/* image formats */
av_register_image_format(&pnm_image_format);
av_register_image_format(&pbm_image_format);
......
/*
* Linux DV1394 interface
* Copyright (c) 2003 Max Krasnyansky <maxk@qualcomm.com>
*
* This library 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 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <sys/time.h>
#include <time.h>
#include "avformat.h"
#undef DV1394_DEBUG
#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;
void *ring; /* Ring buffer */
int index; /* Current frame index */
int avail; /* Number of frames available for reading */
int done; /* Number of completed frames */
};
static int dv1394_reset(struct dv1394_data *dv)
{
struct dv1394_init init;
init.channel = dv->channel;
init.api_version = DV1394_API_VERSION;
init.n_frames = DV1394_RING_FRAMES;
init.format = DV1394_NTSC;
if (ioctl(dv->fd, DV1394_INIT, &init) < 0)
return -1;
dv->avail = 0;
return 0;
}
static int dv1394_start(struct dv1394_data *dv)
{
/* Tell DV1394 driver to enable receiver */
if (ioctl(dv->fd, DV1394_START_RECEIVE, 0) < 0) {
perror("Failed to start receiver");
return -1;
}
return 0;
}
static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap)
{
struct dv1394_data *dv = context->priv_data;
AVStream *st;
st = av_new_stream(context, 0);
if (!st)
return -ENOMEM;
dv->width = DV1394_WIDTH;
dv->height = DV1394_HEIGHT;
dv->channel = dv1394_channel;
dv->frame_rate = 30;
dv->frame_size = DV1394_NTSC_FRAME_SIZE;
/* Open and initialize DV1394 device */
dv->fd = open(video_device, O_RDONLY);
if (dv->fd < 0) {
perror("Failed to open DV interface");
goto failed;
}
if (dv1394_reset(dv) < 0) {
perror("Failed to initialize DV interface");
goto failed;
}
dv->ring = mmap(NULL, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES,
PROT_READ, MAP_PRIVATE, dv->fd, 0);
if (!dv->ring) {
perror("Failed to mmap DV ring buffer");
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;
st->codec.bit_rate = 25000000; /* Consumer DV is 25Mbps */
av_set_pts_info(context, 48, 1, 1000000);
if (dv1394_start(dv) < 0)
goto failed;
return 0;
failed:
close(dv->fd);
av_free(st);
return -EIO;
}
static inline int __copy_frame(struct dv1394_data *dv, void *buf)
{
char *ptr = dv->ring + (dv->index * dv->frame_size);
memcpy(buf, ptr, dv->frame_size);
dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
dv->avail--;
dv->done++;
return dv->frame_size;
}
static int dv1394_read_packet(AVFormatContext * context, AVPacket * pkt)
{
struct dv1394_data *dv = context->priv_data;
int len;
if (!dv->avail) {
struct dv1394_status s;
struct pollfd p;
p.fd = dv->fd;
p.events = POLLIN | POLLERR | POLLHUP;
/* Wait until more frames are available */
if (poll(&p, 1, -1) < 0) {
perror("Poll failed");
return -EIO;
}
if (ioctl(dv->fd, DV1394_GET_STATUS, &s) < 0) {
perror("Failed to get status");
return -EIO;
}
#ifdef DV1394_DEBUG
fprintf(stderr, "DV1394: status\n"
"\tactive_frame\t%d\n"
"\tfirst_clear_frame\t%d\n"
"\tn_clear_frames\t%d\n"
"\tdropped_frames\t%d\n",
s.active_frame, s.first_clear_frame,
s.n_clear_frames, s.dropped_frames);
#endif
dv->avail = s.n_clear_frames;
dv->index = s.first_clear_frame;
dv->done = 0;
if (s.dropped_frames) {
fprintf(stderr, "DV1394: Frame drop detected (%d). Reseting ..\n",
s.dropped_frames);
dv1394_reset(dv);
dv1394_start(dv);
}
}
if (av_new_packet(pkt, dv->frame_size) < 0)
return -EIO;
#ifdef DV1394_DEBUG
fprintf(stderr, "index %d, avail %d, done %d\n", dv->index, dv->avail,
dv->done);
#endif
len = __copy_frame(dv, pkt->data);
pkt->pts = av_gettime() & ((1LL << 48) - 1);
if (!dv->avail && dv->done) {
/* Request more frames */
if (ioctl(dv->fd, DV1394_RECEIVE_FRAMES, dv->done) < 0) {
/* This usually means that ring buffer overflowed.
* We have to reset :(.
*/
fprintf(stderr, "DV1394: Ring buffer overflow. Reseting ..\n");
dv1394_reset(dv);
dv1394_start(dv);
}
}
return len;
}
static int dv1394_close(AVFormatContext * context)
{
struct dv1394_data *dv = context->priv_data;
/* Shutdown DV1394 receiver */
if (ioctl(dv->fd, DV1394_SHUTDOWN, 0) < 0)
perror("Failed to shutdown DV1394");
/* Unmap ring buffer */
if (munmap(dv->ring, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES) < 0)
perror("Failed to munmap DV1394 ring buffer");
close(dv->fd);
return 0;
}
static AVInputFormat dv1394_format = {
.name = "dv1394",
.long_name = "dv1394 A/V grab",
.priv_data_size = sizeof(struct dv1394_data),
.read_header = dv1394_read_header,
.read_packet = dv1394_read_packet,
.read_close = dv1394_close,
.flags = AVFMT_NOFILE
};
int dv1394_init(void)
{
av_register_input_format(&dv1394_format);
return 0;
}
This diff is collapsed.
......@@ -53,8 +53,6 @@ static int aiw_init(VideoData *s);
static int aiw_read_picture(VideoData *s, uint8_t *data);
static int aiw_close(VideoData *s);
const char *v4l_device = "/dev/video";
static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
{
VideoData *s = s1->priv_data;
......@@ -80,9 +78,9 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
s->height = height;
s->frame_rate = frame_rate;
video_fd = open(v4l_device, O_RDWR);
video_fd = open(video_device, O_RDWR);
if (video_fd < 0) {
perror(v4l_device);
perror(video_device);
goto fail;
}
......@@ -339,7 +337,7 @@ static int grab_read_close(AVFormatContext *s1)
}
static AVInputFormat video_grab_device_format = {
"video_grab_device",
"video4linux",
"video grab",
sizeof(VideoData),
NULL,
......
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