summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rwxr-xr-xconfigure10
-rw-r--r--libavcodec/avcodec.h1
-rw-r--r--libavcodec/imgconvert.c66
-rw-r--r--libavcodec/utils.c1
-rw-r--r--libavformat/Makefile4
-rw-r--r--libavformat/allformats.c4
-rw-r--r--libavformat/avformat.h1
-rw-r--r--libavformat/dc1394.c197
9 files changed, 288 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 8aaa51b70f..db8bcea5e4 100644
--- a/Makefile
+++ b/Makefile
@@ -63,6 +63,10 @@ ifeq ($(CONFIG_XVID),yes)
EXTRALIBS+=-lxvidcore
endif
+ifeq ($(CONFIG_DC1394),yes)
+EXTRALIBS+=-ldc1394_control -lraw1394
+endif
+
ifeq ($(BUILD_VHOOK),yes)
VHOOK=videohook
INSTALLVHOOK=install-vhook
diff --git a/configure b/configure
index c76695b39f..664825782f 100755
--- a/configure
+++ b/configure
@@ -32,6 +32,7 @@ echo " --enable-amr_nb-fixed use fixed point for amr-nb codec"
echo " --enable-amr_wb enable amr_wb float audio codec"
echo " --enable-sunmlib use Sun medialib [default=no]"
echo " --enable-pthreads use pthreads [default=no]"
+echo " --enable-dc1394 enable IIDC-1394 grabbing using libdc1394 and libraw1394 [default=no]"
echo " --enable-gpl allow use of gpl code, the resulting libav* and ffmpeg will be under gpl [default=no]"
echo ""
echo "Advanced options (experts only):"
@@ -145,6 +146,7 @@ v4l="yes"
audio_oss="yes"
audio_beos="no"
dv1394="yes"
+dc1394="no"
network="yes"
zlib="yes"
mp3lame="no"
@@ -418,6 +420,8 @@ for opt do
;;
--enable-xvid) xvid="yes"
;;
+ --enable-dc1394) dc1394="yes"
+ ;;
--disable-vhook) vhook="no"
;;
--disable-simple_idct) simpleidct="no"
@@ -686,6 +690,7 @@ if test "$mingw32" = "yes" ; then
v4l="no"
audio_oss="no"
dv1394="no"
+ dc1394="no"
ffserver="no"
network="no"
LIBPREF=""
@@ -1261,6 +1266,11 @@ if test "$dv1394" = "yes" ; then
echo "CONFIG_DV1394=yes" >> config.mak
fi
+if test "$dc1394" = "yes" ; then
+ echo "#define CONFIG_DC1394 1" >> $TMPH
+ echo "CONFIG_DC1394=yes" >> config.mak
+fi
+
if test "$dlopen" = "yes" ; then
echo "#define CONFIG_HAVE_DLOPEN 1" >> $TMPH
fi
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 4919e977ab..88f83b9b27 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -203,6 +203,7 @@ enum PixelFormat {
PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing(xvmc_render.h)
PIX_FMT_XVMC_MPEG2_IDCT,
PIX_FMT_UYVY422, ///< Packed pixel, Cb Y0 Cr Y1
+ PIX_FMT_UYVY411, ///< Packed pixel, Cb Y0 Y1 Cr Y2 Y3
PIX_FMT_NB,
};
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index 7bcb8ee23d..040b2c7939 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -227,6 +227,14 @@ static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
[PIX_FMT_XVMC_MPEG2_IDCT] = {
.name = "xvmcidct",
},
+ [PIX_FMT_UYVY411] = {
+ .name = "uyvy411",
+ .nb_channels = 1,
+ .color_type = FF_COLOR_YUV,
+ .pixel_type = FF_PIXEL_PACKED,
+ .depth = 8,
+ .x_chroma_shift = 2, .y_chroma_shift = 0,
+ },
};
void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
@@ -308,6 +316,12 @@ int avpicture_fill(AVPicture *picture, uint8_t *ptr,
picture->data[2] = NULL;
picture->linesize[0] = width * 2;
return size * 2;
+ case PIX_FMT_UYVY411:
+ picture->data[0] = ptr;
+ picture->data[1] = NULL;
+ picture->data[2] = NULL;
+ picture->linesize[0] = width + width/2;
+ return size + size/2;
case PIX_FMT_GRAY8:
picture->data[0] = ptr;
picture->data[1] = NULL;
@@ -355,6 +369,8 @@ int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
pix_fmt == PIX_FMT_RGB565 ||
pix_fmt == PIX_FMT_RGB555)
w = width * 2;
+ else if (pix_fmt == PIX_FMT_UYVY411)
+ w = width + width/2;
else if (pix_fmt == PIX_FMT_PAL8)
w = width;
else
@@ -466,6 +482,9 @@ static int avg_bits_per_pixel(int pix_fmt)
case PIX_FMT_RGB555:
bits = 16;
break;
+ case PIX_FMT_UYVY411:
+ bits = 12;
+ break;
default:
bits = pf->depth * pf->nb_channels;
break;
@@ -579,6 +598,9 @@ void img_copy(AVPicture *dst, const AVPicture *src,
case PIX_FMT_RGB555:
bits = 16;
break;
+ case PIX_FMT_UYVY411:
+ bits = 12;
+ break;
default:
bits = pf->depth * pf->nb_channels;
break;
@@ -864,6 +886,40 @@ static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
}
}
+static void uyvy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
+ int width, int height)
+{
+ const uint8_t *p, *p1;
+ uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
+ int w;
+
+ p1 = src->data[0];
+ lum1 = dst->data[0];
+ cb1 = dst->data[1];
+ cr1 = dst->data[2];
+ for(;height > 0; height--) {
+ p = p1;
+ lum = lum1;
+ cb = cb1;
+ cr = cr1;
+ for(w = width; w >= 4; w -= 4) {
+ cb[0] = p[0];
+ lum[0] = p[1];
+ lum[1] = p[2];
+ cr[0] = p[3];
+ lum[2] = p[4];
+ lum[3] = p[5];
+ p += 6;
+ lum += 4;
+ cb++;
+ cr++;
+ }
+ p1 += src->linesize[0];
+ lum1 += dst->linesize[0];
+ cb1 += dst->linesize[1];
+ cr1 += dst->linesize[2];
+ }
+}
#define SCALEBITS 10
@@ -1777,6 +1833,12 @@ static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
.convert = pal8_to_rgba32
},
},
+ [PIX_FMT_UYVY411] = {
+ [PIX_FMT_YUV411P] = {
+ .convert = uyvy411_to_yuv411p,
+ },
+ },
+
};
int avpicture_alloc(AVPicture *picture,
@@ -2003,6 +2065,10 @@ int img_convert(AVPicture *dst, int dst_pix_fmt,
dst_pix_fmt == PIX_FMT_UYVY422) {
/* specific case: convert to YUV422P first */
int_pix_fmt = PIX_FMT_YUV422P;
+ } else if (src_pix_fmt == PIX_FMT_UYVY411 ||
+ dst_pix_fmt == PIX_FMT_UYVY411) {
+ /* specific case: convert to YUV411P first */
+ int_pix_fmt = PIX_FMT_YUV411P;
} else if ((src_pix->color_type == FF_COLOR_GRAY &&
src_pix_fmt != PIX_FMT_GRAY8) ||
(dst_pix->color_type == FF_COLOR_GRAY &&
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 2d2fc14c0e..05e63ae7f2 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -159,6 +159,7 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){
h_align= 16;
break;
case PIX_FMT_YUV411P:
+ case PIX_FMT_UYVY411:
w_align=32;
h_align=8;
break;
diff --git a/libavformat/Makefile b/libavformat/Makefile
index f8d769f96a..944a5dd1c2 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -47,6 +47,10 @@ ifeq ($(CONFIG_DV1394),yes)
OBJS+= dv1394.o
endif
+ifeq ($(CONFIG_DC1394),yes)
+OBJS+= dc1394.o
+endif
+
ifeq ($(CONFIG_AUDIO_OSS),yes)
OBJS+= audio.o
endif
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index aae3eb5a89..d1fc72a949 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -102,6 +102,10 @@ void av_register_all(void)
dv1394_init();
#endif
+#ifdef CONFIG_DC1394
+ dc1394_init();
+#endif
+
nut_init();
matroska_init();
sol_init();
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index a17778ea51..7d51ac425e 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -616,6 +616,7 @@ int audio_init(void);
/* DV1394 */
int dv1394_init(void);
+int dc1394_init(void);
#ifdef HAVE_AV_CONFIG_H
diff --git a/libavformat/dc1394.c b/libavformat/dc1394.c
new file mode 100644
index 0000000000..2aba671da1
--- /dev/null
+++ b/libavformat/dc1394.c
@@ -0,0 +1,197 @@
+/*
+ * IIDC1394 grab interface (uses libdc1394 and libraw1394)
+ * Copyright (c) 2004 Roman Shaposhnik
+ *
+ * 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 "avformat.h"
+
+#include <libraw1394/raw1394.h>
+#include <libdc1394/dc1394_control.h>
+
+#undef free
+
+typedef struct dc1394_data {
+ raw1394handle_t handle;
+ dc1394_cameracapture camera;
+ int current_frame;
+ int fps;
+
+ AVPacket packet;
+} dc1394_data;
+
+struct dc1394_frame_format {
+ int width;
+ int height;
+ enum PixelFormat pix_fmt;
+ int frame_size_id;
+} dc1394_frame_formats[] = {
+ { 320, 240, PIX_FMT_UYVY422, MODE_320x240_YUV422 },
+ { 640, 480, PIX_FMT_UYVY411, MODE_640x480_YUV411 },
+ { 640, 480, PIX_FMT_UYVY422, MODE_640x480_YUV422 },
+ { 0, 0, 0, MODE_320x240_YUV422 } /* default -- gotta be the last one */
+};
+
+struct dc1394_frame_rate {
+ int frame_rate;
+ int frame_rate_id;
+} dc1394_frame_rates[] = {
+ { 1875, FRAMERATE_1_875 },
+ { 3750, FRAMERATE_3_75 },
+ { 7500, FRAMERATE_7_5 },
+ { 15000, FRAMERATE_15 },
+ { 30000, FRAMERATE_30 },
+ { 60000, FRAMERATE_60 },
+ { 0, FRAMERATE_30 } /* default -- gotta be the last one */
+};
+
+static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap)
+{
+ dc1394_data* dc1394 = c->priv_data;
+ AVStream* vst;
+ nodeid_t* camera_nodes;
+ int res;
+ struct dc1394_frame_format *fmt;
+ struct dc1394_frame_rate *fps;
+
+ for (fmt = dc1394_frame_formats; fmt->width; fmt++)
+ if (fmt->pix_fmt == ap->pix_fmt && fmt->width == ap->width && fmt->height == ap->height)
+ break;
+
+ for (fps = dc1394_frame_rates; fps->frame_rate; fps++)
+ if (fps->frame_rate == av_rescale(1000, ap->frame_rate, ap->frame_rate_base))
+ break;
+
+ /* create a video stream */
+ vst = av_new_stream(c, 0);
+ if (!vst)
+ return -1;
+ av_set_pts_info(vst, 64, 1, 1000);
+ vst->codec.codec_type = CODEC_TYPE_VIDEO;
+ vst->codec.codec_id = CODEC_ID_RAWVIDEO;
+ vst->codec.frame_rate = fps->frame_rate;
+ vst->codec.frame_rate_base = 1000;
+ vst->codec.width = fmt->width;
+ vst->codec.height = fmt->height;
+ vst->codec.pix_fmt = fmt->pix_fmt;
+
+ /* packet init */
+ av_init_packet(&dc1394->packet);
+ dc1394->packet.size = avpicture_get_size(fmt->pix_fmt, fmt->width, fmt->height);
+ dc1394->packet.stream_index = vst->index;
+ dc1394->packet.flags |= PKT_FLAG_KEY;
+
+ dc1394->current_frame = 0;
+ dc1394->fps = fps->frame_rate;
+
+ vst->codec.bit_rate = av_rescale(dc1394->packet.size * 8, fps->frame_rate, 1000);
+
+ /* Now lets prep the hardware */
+ dc1394->handle = dc1394_create_handle(0); /* FIXME: gotta have ap->port */
+ if (!dc1394->handle) {
+ av_log(c, AV_LOG_ERROR, "Can't aquire dc1394 handle on port %d\n", 0 /* ap->port */);
+ goto out;
+ }
+ camera_nodes = dc1394_get_camera_nodes(dc1394->handle, &res, 1);
+ if (!camera_nodes || camera_nodes[ap->channel] == DC1394_NO_CAMERA) {
+ av_log(c, AV_LOG_ERROR, "There's no IIDC camera on the channel %d\n", ap->channel);
+ goto out_handle;
+ }
+ res = dc1394_dma_setup_capture(dc1394->handle, camera_nodes[ap->channel],
+ 0,
+ FORMAT_VGA_NONCOMPRESSED,
+ fmt->frame_size_id,
+ SPEED_400,
+ fps->frame_rate_id, 8, 1,
+ ap->device,
+ &dc1394->camera);
+ dc1394_free_camera_nodes(camera_nodes);
+ if (res != DC1394_SUCCESS) {
+ av_log(c, AV_LOG_ERROR, "Can't prepare camera for the DMA capture\n");
+ goto out_handle;
+ }
+
+ res = dc1394_start_iso_transmission(dc1394->handle, dc1394->camera.node);
+ if (res != DC1394_SUCCESS) {
+ av_log(c, AV_LOG_ERROR, "Can't start isochronous transmission\n");
+ goto out_handle_dma;
+ }
+
+ return 0;
+
+out_handle_dma:
+ dc1394_dma_unlisten(dc1394->handle, &dc1394->camera);
+ dc1394_dma_release_camera(dc1394->handle, &dc1394->camera);
+out_handle:
+ dc1394_destroy_handle(dc1394->handle);
+out:
+ return -1;
+}
+
+static int dc1394_read_packet(AVFormatContext *c, AVPacket *pkt)
+{
+ struct dc1394_data *dc1394 = c->priv_data;
+ int res;
+
+ /* discard stale frame */
+ if (dc1394->current_frame++) {
+ if (dc1394_dma_done_with_buffer(&dc1394->camera) != DC1394_SUCCESS)
+ av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame);
+ }
+
+ res = dc1394_dma_single_capture(&dc1394->camera);
+
+ if (res == DC1394_SUCCESS) {
+ dc1394->packet.data = (uint8_t *)(dc1394->camera.capture_buffer);
+ dc1394->packet.pts = (dc1394->current_frame * 1000000) / dc1394->fps;
+ res = dc1394->packet.size;
+ } else {
+ av_log(c, AV_LOG_ERROR, "DMA capture failed\n");
+ dc1394->packet.data = NULL;
+ res = -1;
+ }
+
+ *pkt = dc1394->packet;
+ return res;
+}
+
+static int dc1394_close(AVFormatContext * context)
+{
+ struct dc1394_data *dc1394 = context->priv_data;
+
+ dc1394_stop_iso_transmission(dc1394->handle, dc1394->camera.node);
+ dc1394_dma_unlisten(dc1394->handle, &dc1394->camera);
+ dc1394_dma_release_camera(dc1394->handle, &dc1394->camera);
+ dc1394_destroy_handle(dc1394->handle);
+
+ return 0;
+}
+
+static AVInputFormat dc1394_format = {
+ .name = "dc1394",
+ .long_name = "dc1394 A/V grab",
+ .priv_data_size = sizeof(struct dc1394_data),
+ .read_header = dc1394_read_header,
+ .read_packet = dc1394_read_packet,
+ .read_close = dc1394_close,
+ .flags = AVFMT_NOFILE
+};
+
+int dc1394_init(void)
+{
+ av_register_input_format(&dc1394_format);
+ return 0;
+}