From 0b4a18218ef83dce94e64aac06f6cc1262fbed60 Mon Sep 17 00:00:00 2001 From: Alessandro Sappia Date: Fri, 11 Jan 2008 01:59:05 +0000 Subject: Adding support for libdc1394 v.2, patch by Alessandro Sappia a dot sappia at ngi dot it Originally committed as revision 11501 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavdevice/libdc1394.c | 203 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 184 insertions(+), 19 deletions(-) (limited to 'libavdevice') diff --git a/libavdevice/libdc1394.c b/libavdevice/libdc1394.c index a0f04817b8..bea2af2818 100644 --- a/libavdevice/libdc1394.c +++ b/libavdevice/libdc1394.c @@ -1,6 +1,7 @@ /* * IIDC1394 grab interface (uses libdc1394 and libraw1394) * Copyright (c) 2004 Roman Shaposhnik + * Copyright (c) 2008 Alessandro Sappia * * This file is part of FFmpeg. * @@ -20,15 +21,36 @@ */ #include "avformat.h" +#include "config.h" +#if ENABLE_LIBDC1394_2 +#include +#elif ENABLE_LIBDC1394_1 #include #include +#define DC1394_VIDEO_MODE_320x240_YUV422 MODE_320x240_YUV422 +#define DC1394_VIDEO_MODE_640x480_YUV411 MODE_640x480_YUV411 +#define DC1394_VIDEO_MODE_640x480_YUV422 MODE_640x480_YUV422 +#define DC1394_FRAMERATE_1_875 FRAMERATE_1_875 +#define DC1394_FRAMERATE_3_75 FRAMERATE_3_75 +#define DC1394_FRAMERATE_7_5 FRAMERATE_7_5 +#define DC1394_FRAMERATE_15 FRAMERATE_15 +#define DC1394_FRAMERATE_30 FRAMERATE_30 +#define DC1394_FRAMERATE_60 FRAMERATE_60 +#endif + #undef free typedef struct dc1394_data { +#if ENABLE_LIBDC1394_1 raw1394handle_t handle; dc1394_cameracapture camera; +#elif ENABLE_LIBDC1394_2 + dc1394_t *d; + dc1394camera_t *camera; + dc1394video_frame_t *frame; +#endif int current_frame; int fps; @@ -41,9 +63,9 @@ struct dc1394_frame_format { enum PixelFormat pix_fmt; int frame_size_id; } dc1394_frame_formats[] = { - { 320, 240, PIX_FMT_UYVY422, MODE_320x240_YUV422 }, - { 640, 480, PIX_FMT_UYYVYY411, MODE_640x480_YUV411 }, - { 640, 480, PIX_FMT_UYVY422, MODE_640x480_YUV422 }, + { 320, 240, PIX_FMT_UYVY422, DC1394_VIDEO_MODE_320x240_YUV422 }, + { 640, 480, PIX_FMT_UYYVYY411, DC1394_VIDEO_MODE_640x480_YUV411 }, + { 640, 480, PIX_FMT_UYVY422, DC1394_VIDEO_MODE_640x480_YUV422 }, { 0, 0, 0, 0 } /* gotta be the last one */ }; @@ -51,21 +73,20 @@ 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 }, + { 1875, DC1394_FRAMERATE_1_875 }, + { 3750, DC1394_FRAMERATE_3_75 }, + { 7500, DC1394_FRAMERATE_7_5 }, + { 15000, DC1394_FRAMERATE_15 }, + { 30000, DC1394_FRAMERATE_30 }, + { 60000, DC1394_FRAMERATE_60 }, { 0, 0 } /* gotta be the last one */ }; -static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap) +static inline int dc1394_read_common(AVFormatContext *c, AVFormatParameters *ap, + struct dc1394_frame_format **select_fmt, struct dc1394_frame_rate **select_fps) { dc1394_data* dc1394 = c->priv_data; AVStream* vst; - nodeid_t* camera_nodes; - int res; struct dc1394_frame_format *fmt; struct dc1394_frame_rate *fps; enum PixelFormat pix_fmt = ap->pix_fmt == PIX_FMT_NONE ? PIX_FMT_UYVY422 : ap->pix_fmt; /* defaults */ @@ -90,7 +111,7 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap) /* create a video stream */ vst = av_new_stream(c, 0); if (!vst) - return -1; + goto out; av_set_pts_info(vst, 64, 1, 1000); vst->codec->codec_type = CODEC_TYPE_VIDEO; vst->codec->codec_id = CODEC_ID_RAWVIDEO; @@ -110,6 +131,25 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap) dc1394->fps = fps->frame_rate; vst->codec->bit_rate = av_rescale(dc1394->packet.size * 8, fps->frame_rate, 1000); + *select_fps = fps; + *select_fmt = fmt; + return 0; +out: + return -1; +} + +#if ENABLE_LIBDC1394_1 +static int dc1394_v1_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 = NULL; + struct dc1394_frame_rate *fps = NULL; + + if (dc1394_read_common(c,ap,&fmt,&fps) != 0) + return -1; /* Now lets prep the hardware */ dc1394->handle = dc1394_create_handle(0); /* FIXME: gotta have ap->port */ @@ -153,7 +193,7 @@ out: return -1; } -static int dc1394_read_packet(AVFormatContext *c, AVPacket *pkt) +static int dc1394_v1_read_packet(AVFormatContext *c, AVPacket *pkt) { struct dc1394_data *dc1394 = c->priv_data; int res; @@ -180,7 +220,7 @@ static int dc1394_read_packet(AVFormatContext *c, AVPacket *pkt) return res; } -static int dc1394_close(AVFormatContext * context) +static int dc1394_v1_close(AVFormatContext * context) { struct dc1394_data *dc1394 = context->priv_data; @@ -192,12 +232,137 @@ static int dc1394_close(AVFormatContext * context) return 0; } +#elif ENABLE_LIBDC1394_2 +static int dc1394_v2_read_header(AVFormatContext *c, AVFormatParameters * ap) +{ + dc1394_data* dc1394 = c->priv_data; + dc1394camera_list_t *list; + int res, i; + struct dc1394_frame_format *fmt = NULL; + struct dc1394_frame_rate *fps = NULL; + + if (dc1394_read_common(c,ap,&fmt,&fps) != 0) + return -1; + + /* Now lets prep the hardware */ + dc1394->d = dc1394_new(); + dc1394_camera_enumerate (dc1394->d, &list); + if ( !list || list->num == 0) { + av_log(c, AV_LOG_ERROR, "Unable to look for an IIDC camera\n\n"); + goto out; + } + + /* FIXME: To select a specific camera I need to search in list its guid */ + dc1394->camera = dc1394_camera_new (dc1394->d, list->ids[0].guid); + if (list->num > 1) { + av_log(c, AV_LOG_INFO, "Working with the first camera found\n"); + } + + /* Freeing list of cameras */ + dc1394_camera_free_list (list); + + /* Select MAX Speed possible from the cam */ + if (dc1394->camera->bmode_capable>0) { + dc1394_video_set_operation_mode(dc1394->camera, DC1394_OPERATION_MODE_1394B); + i = DC1394_ISO_SPEED_800; + } else { + i = DC1394_ISO_SPEED_400; + } + + for (res = DC1394_FAILURE; i >= DC1394_ISO_SPEED_MIN && res != DC1394_SUCCESS; i--) { + res=dc1394_video_set_iso_speed(dc1394->camera, i); + } + if (res != DC1394_SUCCESS) { + av_log(c, AV_LOG_ERROR, "Couldn't set ISO Speed\n"); + goto out_camera; + } + + if (dc1394_video_set_mode(dc1394->camera, fmt->frame_size_id) != DC1394_SUCCESS) { + av_log(c, AV_LOG_ERROR, "Couldn't set video format\n"); + goto out_camera; + } + + if (dc1394_video_set_framerate(dc1394->camera,fps->frame_rate_id) != DC1394_SUCCESS) { + av_log(c, AV_LOG_ERROR, "Couldn't set framerate %d \n",fps->frame_rate); + goto out_camera; + } + if (dc1394_capture_setup(dc1394->camera, 10, DC1394_CAPTURE_FLAGS_DEFAULT)!=DC1394_SUCCESS) { + av_log(c, AV_LOG_ERROR, "Cannot setup camera \n"); + goto out_camera; + } + + if (dc1394_video_set_transmission(dc1394->camera, DC1394_ON) !=DC1394_SUCCESS) { + av_log(c, AV_LOG_ERROR, "Cannot start capture\n"); + goto out_camera; + } + return 0; + +out_camera: + dc1394_capture_stop(dc1394->camera); + dc1394_video_set_transmission(dc1394->camera, DC1394_OFF); + dc1394_camera_free (dc1394->camera); +out: + dc1394_free(dc1394->d); + return -1; +} + +static int dc1394_v2_read_packet(AVFormatContext *c, AVPacket *pkt) +{ + struct dc1394_data *dc1394 = c->priv_data; + int res; + + /* discard stale frame */ + if (dc1394->current_frame++) { + if (dc1394_capture_enqueue(dc1394->camera, dc1394->frame) != DC1394_SUCCESS) + av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame); + } + + res = dc1394_capture_dequeue(dc1394->camera, DC1394_CAPTURE_POLICY_WAIT, &dc1394->frame); + if (res == DC1394_SUCCESS) { + dc1394->packet.data = (uint8_t *)(dc1394->frame->image); + dc1394->packet.pts = (dc1394->current_frame * 1000000) / (dc1394->fps); + res = dc1394->frame->image_bytes; + } 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_v2_close(AVFormatContext * context) +{ + struct dc1394_data *dc1394 = context->priv_data; + + dc1394_video_set_transmission(dc1394->camera, DC1394_OFF); + dc1394_capture_stop(dc1394->camera); + dc1394_camera_free(dc1394->camera); + dc1394_free(dc1394->d); + + return 0; +} + +AVInputFormat libdc1394_demuxer = { + .name = "libdc1394", + .long_name = "dc1394 v.2 A/V grab", + .priv_data_size = sizeof(struct dc1394_data), + .read_header = dc1394_v2_read_header, + .read_packet = dc1394_v2_read_packet, + .read_close = dc1394_v2_close, + .flags = AVFMT_NOFILE +}; + +#endif +#if ENABLE_LIBDC1394_1 AVInputFormat libdc1394_demuxer = { .name = "libdc1394", - .long_name = "dc1394 A/V grab", + .long_name = "dc1394 v.1 A/V grab", .priv_data_size = sizeof(struct dc1394_data), - .read_header = dc1394_read_header, - .read_packet = dc1394_read_packet, - .read_close = dc1394_close, + .read_header = dc1394_v1_read_header, + .read_packet = dc1394_v1_read_packet, + .read_close = dc1394_v1_close, .flags = AVFMT_NOFILE }; +#endif -- cgit v1.2.3