[Ffmpeg-devel] [patch] *BSD bktr support

Jacob Meuser jakemsr
Mon May 16 05:29:48 CEST 2005


the FreeBSD, OpenBSD and NetBSD FFmpeg "ports" all use this code (or a
slight variation of it, anyway) originally written by Steve O'Hara-Smith.

-- 
<jakemsr at jakemsr.com>
-------------- next part --------------
Index: configure
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/configure,v
retrieving revision 1.180
diff -u -r1.180 configure
--- configure	13 May 2005 20:57:27 -0000	1.180
+++ configure	16 May 2005 01:00:40 -0000
@@ -56,6 +56,7 @@
 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-bktr           disable bktr video 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]"
@@ -152,6 +153,7 @@
 esac
 gprof="no"
 v4l="yes"
+bktr="no"
 audio_oss="yes"
 audio_beos="no"
 dv1394="yes"
@@ -255,6 +257,7 @@
 ;;
 NetBSD)
 v4l="no"
+bktr="yes"
 audio_oss="yes"
 dv1394="no"
 make="gmake"
@@ -266,6 +269,7 @@
 ;;
 OpenBSD)
 v4l="no"
+bktr="yes"
 audio_oss="yes"
 dv1394="no"
 make="gmake"
@@ -275,6 +279,7 @@
 ;;
 FreeBSD)
 v4l="no"
+bktr="yes"
 audio_oss="yes"
 dv1394="no"
 make="gmake"
@@ -283,6 +288,7 @@
 ;;
 BSD/OS)
 v4l="no"
+bktr="yes"
 audio_oss="yes"
 dv1394="no"
 extralibs="-lpoll -lgnugetopt -lm"
@@ -431,6 +437,8 @@
   ;;
   --disable-v4l) v4l="no"
   ;;
+  --disable-bktr) bktr="no"
+  ;;
   --disable-audio-oss) audio_oss="no"
   ;;
   --disable-audio-beos) audio_beos="no"
@@ -767,6 +775,7 @@
 
 if test "$mingw32" = "yes" ; then
     v4l="no"
+    bktr="no"
     audio_oss="no"
     dv1394="no"
     dc1394="no"
@@ -1382,6 +1391,11 @@
   echo "CONFIG_VIDEO4LINUX=yes" >> config.mak
 fi
 
+if test "$bktr" = "yes" ; then
+  echo "#define CONFIG_BKTR 1" >> $TMPH
+  echo "CONFIG_BKTR=yes" >> config.mak
+fi
+
 if test "$dv1394" = "yes" ; then
   echo "#define CONFIG_DV1394 1" >> $TMPH
   echo "CONFIG_DV1394=yes" >> config.mak
Index: ffmpeg.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/ffmpeg.c,v
retrieving revision 1.328
diff -u -r1.328 ffmpeg.c
--- ffmpeg.c	12 May 2005 16:28:24 -0000	1.328
+++ ffmpeg.c	16 May 2005 01:00:43 -0000
@@ -247,7 +247,7 @@
 
 static int rate_emu = 0;
 
-static char *video_grab_format = "video4linux";
+static char *video_grab_format = "video_device";
 static char *video_device = NULL;
 static char *grab_device = NULL;
 static int  video_channel = 0;
Index: libavformat/Makefile
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavformat/Makefile,v
retrieving revision 1.89
diff -u -r1.89 Makefile
--- libavformat/Makefile	11 May 2005 22:47:26 -0000	1.89
+++ libavformat/Makefile	16 May 2005 01:00:44 -0000
@@ -40,6 +40,10 @@
 OBJS+= grab.o
 endif
 
+ifeq ($(CONFIG_BKTR),yes)
+OBJS+= grab_bktr.o
+endif
+
 ifeq ($(CONFIG_DV1394),yes)
 OBJS+= dv1394.o
 endif
Index: libavformat/allformats.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavformat/allformats.c,v
retrieving revision 1.46
diff -u -r1.46 allformats.c
--- libavformat/allformats.c	9 Apr 2005 15:32:58 -0000	1.46
+++ libavformat/allformats.c	16 May 2005 01:00:44 -0000
@@ -88,7 +88,7 @@
 #endif
 
     ffm_init();
-#ifdef CONFIG_VIDEO4LINUX
+#if defined(CONFIG_VIDEO4LINUX) || defined(CONFIG_BKTR)
     video_grab_init();
 #endif
 #if defined(CONFIG_AUDIO_OSS) || defined(CONFIG_AUDIO_BEOS)
Index: libavformat/avformat.h
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavformat/avformat.h,v
retrieving revision 1.119
diff -u -r1.119 avformat.h
--- libavformat/avformat.h	30 Apr 2005 21:43:58 -0000	1.119
+++ libavformat/avformat.h	16 May 2005 01:00:44 -0000
@@ -106,7 +106,7 @@
     enum PixelFormat pix_fmt;
     struct AVImageFormat *image_format;
     int channel; /* used to select dv channel */
-    const char *device; /* video4linux, audio or DV device */
+    const char *device; /* video, audio or DV device */
     const char *standard; /* tv standard, NTSC, PAL, SECAM */
     int mpeg2ts_raw:1;  /* force raw MPEG2 transport stream output, if possible */
     int mpeg2ts_compute_pcr:1; /* compute exact PCR for each transport
Index: libavformat/grab.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavformat/grab.c,v
retrieving revision 1.34
diff -u -r1.34 grab.c
--- libavformat/grab.c	30 Apr 2005 21:43:58 -0000	1.34
+++ libavformat/grab.c	16 May 2005 01:00:45 -0000
@@ -364,7 +364,7 @@
 }
 
 static AVInputFormat video_grab_device_format = {
-    "video4linux",
+    "video_device",
     "video grab",
     sizeof(VideoData),
     NULL,
--- /dev/null	Sun May 15 18:04:42 2005
+++ libavformat/grab_bktr.c	Sun May 15 17:52:42 2005
@@ -0,0 +1,337 @@
+/* $OpenBSD: grab_bsdbktr.c,v 1.5 2005/04/20 16:46:54 naddy Exp $
+ *
+ * FreeBSD video grab interface
+ * Copyright (c) 2002 Steve O'Hara-Smith
+ * based on
+ *           Linux video grab interface
+ *           Copyright (c) 2000,2001 Gerard Lantau.
+ * and
+ *           simple_grab.c Copyright (c) 1999 Roger Hardiman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "avformat.h"
+#ifdef __FreeBSD__
+# if __FreeBSD__ >= 502100
+#  include <dev/bktr/ioctl_meteor.h>
+#  include <dev/bktr/ioctl_bt848.h>
+# else
+#  include <machine/ioctl_meteor.h>
+#  include <machine/ioctl_bt848.h>
+# endif
+#else
+# include <dev/ic/bt8xx.h>
+#endif
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <signal.h>
+
+typedef struct {
+	int video_fd;
+	int tuner_fd;
+	int frame_format; /* see VIDEO_PALETTE_xxx */
+	int width, height;
+	int frame_rate;
+	int frame_rate_base;
+	int64_t per_frame;
+} VideoData;
+
+const char *video_device = "/dev/bktr0";
+
+#define PAL 1
+#define PALBDGHI 1
+#define NTSC 2
+#define NTSCM 2
+#define SECAM 3
+#define PALN 4
+#define PALM 5
+#define NTSCJ 6
+
+/* PAL is 768 x 576. NTSC is 640 x 480 */
+#define PAL_HEIGHT 576
+#define SECAM_HEIGHT 576
+#define NTSC_HEIGHT 480
+
+#ifndef VIDEO_FORMAT
+#define VIDEO_FORMAT NTSC
+#endif
+
+static int bktr_dev[] = { METEOR_DEV0, METEOR_DEV1, METEOR_DEV2,
+                   METEOR_DEV3, METEOR_DEV_SVIDEO };
+
+uint8_t *video_buf;
+volatile sig_atomic_t nsignals = 0;
+
+static void catchsignal(int signal)
+{
+	nsignals++;
+	return;
+}
+
+static int bktr_init (const char *video_device, int width, int height,
+	int format, int *video_fd, int *tuner_fd, int idev, double frequency)
+{
+	struct meteor_geomet geo;
+	int h_max;
+	long ioctl_frequency;
+	char *arg;
+	int c;
+	struct sigaction act,old;
+
+	if (idev < 0 || idev > 4)
+	{
+		arg = getenv ("BKTR_DEV");
+		if (arg)
+			idev = atoi (arg);
+		if (idev < 0 || idev > 4)
+			idev = 1;
+	}
+
+	if (format < 1 || format > 6)
+	{
+		arg = getenv ("BKTR_FORMAT");
+		if (arg)
+			format = atoi (arg);
+		if (format < 1 || format > 6)
+			format = VIDEO_FORMAT;
+	}
+
+	if (frequency <= 0)
+	{
+		arg = getenv ("BKTR_FREQUENCY");
+		if (arg)
+			frequency = atof (arg);
+		if (frequency <= 0)
+			frequency = 0.0;
+	}
+
+	memset(&act,0,sizeof(act));
+	sigemptyset(&act.sa_mask);
+	act.sa_handler  = catchsignal;
+	sigaction(SIGUSR1,&act,&old);
+
+	*tuner_fd = open ("/dev/tuner0", O_RDONLY);
+	if (*tuner_fd < 0) {
+		perror("Warning: Tuner not opened continuing");
+	}
+
+	*video_fd = open (video_device, O_RDONLY);
+	if (*video_fd < 0) {
+		perror (video_device);
+		return -1;
+	}
+
+	geo.rows = height;
+	geo.columns = width;
+	geo.frames = 1;
+//	geo.oformat = METEOR_GEO_YUV_422 | METEOR_GEO_YUV_12;
+	geo.oformat = METEOR_GEO_YUV_PACKED;
+
+	switch (format) {
+	case PAL:   h_max = PAL_HEIGHT;   c = BT848_IFORM_F_PALBDGHI; break;
+	case PALN:  h_max = PAL_HEIGHT;   c = BT848_IFORM_F_PALN;     break;
+	case PALM:  h_max = PAL_HEIGHT;   c = BT848_IFORM_F_PALM;     break;
+	case SECAM: h_max = SECAM_HEIGHT; c = BT848_IFORM_F_SECAM;    break;
+	case NTSC:  h_max = NTSC_HEIGHT;  c = BT848_IFORM_F_NTSCM;    break;
+	case NTSCJ: h_max = NTSC_HEIGHT;  c = BT848_IFORM_F_NTSCJ;    break;
+	default:    h_max = PAL_HEIGHT;   c = BT848_IFORM_F_PALBDGHI; break;
+	}
+	if (height <= h_max/2) {
+		geo.oformat |= METEOR_GEO_EVEN_ONLY;
+	}
+
+	if (ioctl(*video_fd, METEORSETGEO, &geo) < 0) {
+		perror ("METEORSETGEO");
+		return -1;
+	}
+
+	if (ioctl(*video_fd, BT848SFMT, &c) < 0) {
+		perror ("BT848SFMT");
+		return -1;
+	}
+
+	c = bktr_dev[idev];
+	if (ioctl(*video_fd, METEORSINPUT, &c) < 0) {
+		perror ("METEORSINPUT");
+		return -1;
+	}
+	video_buf = (uint8_t *) mmap((caddr_t)0, width*height*2,
+		PROT_READ, MAP_SHARED, *video_fd, (off_t) 0);
+	if (video_buf == MAP_FAILED) {
+		perror ("mmap");
+		return -1;
+	}
+	if (frequency != 0.0) {
+		ioctl_frequency  = (unsigned long)(frequency*16); 
+		if (ioctl(*tuner_fd, TVTUNER_SETFREQ, &ioctl_frequency)<0)
+			perror("TVTUNER_SETFREQ");
+	}
+
+	c = AUDIO_UNMUTE;
+	if (ioctl(*tuner_fd, BT848_SAUDIO, &c) < 0)
+		perror("TVTUNER_SAUDIO");
+
+	c = METEOR_CAP_CONTINOUS;
+	ioctl(*video_fd, METEORCAPTUR, &c);
+	c = SIGUSR1;
+	ioctl (*video_fd, METEORSSIGNAL, &c);
+	return 0;
+}
+
+static void bktr_getframe(u_int64_t per_frame)
+{
+	u_int64_t curtime;
+	static u_int64_t last_frame_time = 0;
+
+	curtime = av_gettime();
+	if (!last_frame_time
+	    || ((last_frame_time + per_frame) > curtime)) {
+		usleep (last_frame_time + per_frame + per_frame/8 - curtime);
+#if 0
+		if (!usleep (last_frame_time + per_frame + per_frame/8 - curtime)) {
+			if (!nsignals)
+				printf ("\nSLEPT NO signals - %d microseconds late\n",
+				        (int) (av_gettime() - last_frame_time - per_frame));
+		}
+#endif
+	}
+	nsignals = 0;
+
+	last_frame_time = curtime;
+}
+
+void bf_memcpy (char *dest, char *src, int size)
+{
+	while (size -= 2)
+	{
+		dest[0] = src[1];
+		dest[1] = src[0];
+		dest += 2;
+		src += 2;
+	}
+}
+
+/* note: we support only one picture read at a time */
+static int grab_read_packet(AVFormatContext *s1, AVPacket *pkt)
+{
+	VideoData *s = s1->priv_data;
+	int size, halfsize;
+
+	size = s->width * s->height;
+	halfsize = size << 1;
+
+//	if (av_new_packet(pkt, size + halfsize) < 0)
+	if (av_new_packet(pkt, size + size) < 0)
+		return -EIO;
+
+	bktr_getframe (s->per_frame);
+	pkt->pts = av_gettime() & ((1LL << 48) - 1);
+	bf_memcpy (pkt->data, video_buf, size + size);
+//	bf_memcpy (pkt->data, video_buf, size + halfsize);
+
+//	return size + halfsize;
+	return size + size;
+}
+
+static int grab_read_header (AVFormatContext *s1,  AVFormatParameters *ap)
+{
+	VideoData *s = s1->priv_data;
+	AVStream *st;
+	int width, height;
+	int frame_rate;
+	int frame_rate_base;
+	int format = -1;
+
+	if (!ap || ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0)
+		return -1;
+
+	width = ap->width;
+	height = ap->height;
+	frame_rate = ap->time_base.den;
+	frame_rate_base = ap->time_base.num;
+
+	st = av_new_stream(s1, 0);
+	if (!st)
+		return -ENOMEM;
+	av_set_pts_info(st, 48, 1, 1000000); /* 48 bits pts in use */
+
+	s->width = width;
+	s->height = height;
+	s->frame_rate = frame_rate;
+	s->frame_rate_base = frame_rate_base;
+	s->per_frame = ((int64_t)1000000 * s->frame_rate_base) / s->frame_rate;
+
+	st->codec.codec_type = CODEC_TYPE_VIDEO;
+//	st->codec.pix_fmt = PIX_FMT_YUV420P;
+	st->codec.pix_fmt = PIX_FMT_YUV422;
+	st->codec.codec_id = CODEC_ID_RAWVIDEO;
+	st->codec.width = width;
+	st->codec.height = height;
+	st->codec.time_base.den = frame_rate;
+	st->codec.time_base.num = frame_rate_base;
+
+
+   if (ap->standard) {
+		if (!strcasecmp(ap->standard, "pal"))
+		    format = PAL;
+		if (!strcasecmp(ap->standard, "secam"))
+		    format = SECAM;
+		if (!strcasecmp(ap->standard, "ntsc"))
+		    format = NTSC;
+	}
+
+	if (bktr_init (video_device, width, height, format,
+			&(s->video_fd), &(s->tuner_fd), -1, 0.0) < 0)
+		return -EIO;
+	return 0;
+}
+
+static int grab_read_close (AVFormatContext *s1)
+{
+	VideoData *s = s1->priv_data;
+	int c;
+
+	c = METEOR_CAP_STOP_CONT;
+	ioctl(s->video_fd, METEORCAPTUR, &c);
+	close(s->video_fd);
+
+	c = AUDIO_MUTE;
+	ioctl(s->tuner_fd, BT848_SAUDIO, &c);
+	close(s->tuner_fd);
+
+	munmap((caddr_t)video_buf, sizeof(video_buf));
+
+	return 0;
+}
+
+AVInputFormat video_grab_device_format = {
+	"video_device",
+	"video grab",
+	 sizeof(VideoData),
+	 NULL,
+	grab_read_header,
+	grab_read_packet,
+	grab_read_close,
+	.flags = AVFMT_NOFILE,
+};
+
+int video_grab_init(void)
+{
+	av_register_input_format(&video_grab_device_format);
+	return 0;
+}



More information about the ffmpeg-devel mailing list