* Introducing IIDC1394 grabbing interface.
Use it with -grab dc1394 * Introducing yet another packed pix_fmt in order to support some of the IIDC1394 modes: uyvy411 (Cb Y0 Y1 Cr Y2 Y3). Originally committed as revision 3621 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
5ba7c3d7c9
commit
f02be79d61
4
Makefile
4
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
|
||||
|
10
configure
vendored
10
configure
vendored
@ -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
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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 &&
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -102,6 +102,10 @@ void av_register_all(void)
|
||||
dv1394_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DC1394
|
||||
dc1394_init();
|
||||
#endif
|
||||
|
||||
nut_init();
|
||||
matroska_init();
|
||||
sol_init();
|
||||
|
@ -616,6 +616,7 @@ int audio_init(void);
|
||||
|
||||
/* DV1394 */
|
||||
int dv1394_init(void);
|
||||
int dc1394_init(void);
|
||||
|
||||
#ifdef HAVE_AV_CONFIG_H
|
||||
|
||||
|
197
libavformat/dc1394.c
Normal file
197
libavformat/dc1394.c
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user