annotate ffmpeg/libavdevice/libdc1394.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * IIDC1394 grab interface (uses libdc1394 and libraw1394)
yading@10 3 * Copyright (c) 2004 Roman Shaposhnik
yading@10 4 * Copyright (c) 2008 Alessandro Sappia
yading@10 5 *
yading@10 6 * This file is part of FFmpeg.
yading@10 7 *
yading@10 8 * FFmpeg is free software; you can redistribute it and/or
yading@10 9 * modify it under the terms of the GNU Lesser General Public
yading@10 10 * License as published by the Free Software Foundation; either
yading@10 11 * version 2.1 of the License, or (at your option) any later version.
yading@10 12 *
yading@10 13 * FFmpeg is distributed in the hope that it will be useful,
yading@10 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 16 * Lesser General Public License for more details.
yading@10 17 *
yading@10 18 * You should have received a copy of the GNU Lesser General Public
yading@10 19 * License along with FFmpeg; if not, write to the Free Software
yading@10 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 21 */
yading@10 22
yading@10 23 #include "config.h"
yading@10 24 #include "libavformat/avformat.h"
yading@10 25 #include "libavformat/internal.h"
yading@10 26 #include "libavutil/log.h"
yading@10 27 #include "libavutil/mathematics.h"
yading@10 28 #include "libavutil/opt.h"
yading@10 29 #include "libavutil/parseutils.h"
yading@10 30 #include "libavutil/pixdesc.h"
yading@10 31
yading@10 32 #if HAVE_LIBDC1394_2
yading@10 33 #include <dc1394/dc1394.h>
yading@10 34 #elif HAVE_LIBDC1394_1
yading@10 35 #include <libraw1394/raw1394.h>
yading@10 36 #include <libdc1394/dc1394_control.h>
yading@10 37
yading@10 38 #define DC1394_VIDEO_MODE_320x240_YUV422 MODE_320x240_YUV422
yading@10 39 #define DC1394_VIDEO_MODE_640x480_YUV411 MODE_640x480_YUV411
yading@10 40 #define DC1394_VIDEO_MODE_640x480_YUV422 MODE_640x480_YUV422
yading@10 41 #define DC1394_FRAMERATE_1_875 FRAMERATE_1_875
yading@10 42 #define DC1394_FRAMERATE_3_75 FRAMERATE_3_75
yading@10 43 #define DC1394_FRAMERATE_7_5 FRAMERATE_7_5
yading@10 44 #define DC1394_FRAMERATE_15 FRAMERATE_15
yading@10 45 #define DC1394_FRAMERATE_30 FRAMERATE_30
yading@10 46 #define DC1394_FRAMERATE_60 FRAMERATE_60
yading@10 47 #define DC1394_FRAMERATE_120 FRAMERATE_120
yading@10 48 #define DC1394_FRAMERATE_240 FRAMERATE_240
yading@10 49 #endif
yading@10 50
yading@10 51 typedef struct dc1394_data {
yading@10 52 AVClass *class;
yading@10 53 #if HAVE_LIBDC1394_1
yading@10 54 raw1394handle_t handle;
yading@10 55 dc1394_cameracapture camera;
yading@10 56 int channel;
yading@10 57 #elif HAVE_LIBDC1394_2
yading@10 58 dc1394_t *d;
yading@10 59 dc1394camera_t *camera;
yading@10 60 dc1394video_frame_t *frame;
yading@10 61 #endif
yading@10 62 int current_frame;
yading@10 63 int frame_rate; /**< frames per 1000 seconds (fps * 1000) */
yading@10 64 char *video_size; /**< String describing video size, set by a private option. */
yading@10 65 char *pixel_format; /**< Set by a private option. */
yading@10 66 char *framerate; /**< Set by a private option. */
yading@10 67
yading@10 68 AVPacket packet;
yading@10 69 } dc1394_data;
yading@10 70
yading@10 71 struct dc1394_frame_format {
yading@10 72 int width;
yading@10 73 int height;
yading@10 74 enum AVPixelFormat pix_fmt;
yading@10 75 int frame_size_id;
yading@10 76 } dc1394_frame_formats[] = {
yading@10 77 { 320, 240, AV_PIX_FMT_UYVY422, DC1394_VIDEO_MODE_320x240_YUV422 },
yading@10 78 { 640, 480, AV_PIX_FMT_UYYVYY411, DC1394_VIDEO_MODE_640x480_YUV411 },
yading@10 79 { 640, 480, AV_PIX_FMT_UYVY422, DC1394_VIDEO_MODE_640x480_YUV422 },
yading@10 80 { 0, 0, 0, 0 } /* gotta be the last one */
yading@10 81 };
yading@10 82
yading@10 83 struct dc1394_frame_rate {
yading@10 84 int frame_rate;
yading@10 85 int frame_rate_id;
yading@10 86 } dc1394_frame_rates[] = {
yading@10 87 { 1875, DC1394_FRAMERATE_1_875 },
yading@10 88 { 3750, DC1394_FRAMERATE_3_75 },
yading@10 89 { 7500, DC1394_FRAMERATE_7_5 },
yading@10 90 { 15000, DC1394_FRAMERATE_15 },
yading@10 91 { 30000, DC1394_FRAMERATE_30 },
yading@10 92 { 60000, DC1394_FRAMERATE_60 },
yading@10 93 {120000, DC1394_FRAMERATE_120 },
yading@10 94 {240000, DC1394_FRAMERATE_240 },
yading@10 95 { 0, 0 } /* gotta be the last one */
yading@10 96 };
yading@10 97
yading@10 98 #define OFFSET(x) offsetof(dc1394_data, x)
yading@10 99 #define DEC AV_OPT_FLAG_DECODING_PARAM
yading@10 100 static const AVOption options[] = {
yading@10 101 #if HAVE_LIBDC1394_1
yading@10 102 { "channel", "", offsetof(dc1394_data, channel), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
yading@10 103 #endif
yading@10 104 { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "qvga"}, 0, 0, DEC },
yading@10 105 { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "uyvy422"}, 0, 0, DEC },
yading@10 106 { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC },
yading@10 107 { NULL },
yading@10 108 };
yading@10 109
yading@10 110 static const AVClass libdc1394_class = {
yading@10 111 .class_name = "libdc1394 indev",
yading@10 112 .item_name = av_default_item_name,
yading@10 113 .option = options,
yading@10 114 .version = LIBAVUTIL_VERSION_INT,
yading@10 115 };
yading@10 116
yading@10 117
yading@10 118 static inline int dc1394_read_common(AVFormatContext *c,
yading@10 119 struct dc1394_frame_format **select_fmt, struct dc1394_frame_rate **select_fps)
yading@10 120 {
yading@10 121 dc1394_data* dc1394 = c->priv_data;
yading@10 122 AVStream* vst;
yading@10 123 struct dc1394_frame_format *fmt;
yading@10 124 struct dc1394_frame_rate *fps;
yading@10 125 enum AVPixelFormat pix_fmt;
yading@10 126 int width, height;
yading@10 127 AVRational framerate;
yading@10 128 int ret = 0;
yading@10 129
yading@10 130 if ((pix_fmt = av_get_pix_fmt(dc1394->pixel_format)) == AV_PIX_FMT_NONE) {
yading@10 131 av_log(c, AV_LOG_ERROR, "No such pixel format: %s.\n", dc1394->pixel_format);
yading@10 132 ret = AVERROR(EINVAL);
yading@10 133 goto out;
yading@10 134 }
yading@10 135
yading@10 136 if ((ret = av_parse_video_size(&width, &height, dc1394->video_size)) < 0) {
yading@10 137 av_log(c, AV_LOG_ERROR, "Could not parse video size '%s'.\n", dc1394->video_size);
yading@10 138 goto out;
yading@10 139 }
yading@10 140 if ((ret = av_parse_video_rate(&framerate, dc1394->framerate)) < 0) {
yading@10 141 av_log(c, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", dc1394->framerate);
yading@10 142 goto out;
yading@10 143 }
yading@10 144 dc1394->frame_rate = av_rescale(1000, framerate.num, framerate.den);
yading@10 145
yading@10 146 for (fmt = dc1394_frame_formats; fmt->width; fmt++)
yading@10 147 if (fmt->pix_fmt == pix_fmt && fmt->width == width && fmt->height == height)
yading@10 148 break;
yading@10 149
yading@10 150 for (fps = dc1394_frame_rates; fps->frame_rate; fps++)
yading@10 151 if (fps->frame_rate == dc1394->frame_rate)
yading@10 152 break;
yading@10 153
yading@10 154 if (!fps->frame_rate || !fmt->width) {
yading@10 155 av_log(c, AV_LOG_ERROR, "Can't find matching camera format for %s, %dx%d@%d:1000fps\n", av_get_pix_fmt_name(pix_fmt),
yading@10 156 width, height, dc1394->frame_rate);
yading@10 157 ret = AVERROR(EINVAL);
yading@10 158 goto out;
yading@10 159 }
yading@10 160
yading@10 161 /* create a video stream */
yading@10 162 vst = avformat_new_stream(c, NULL);
yading@10 163 if (!vst) {
yading@10 164 ret = AVERROR(ENOMEM);
yading@10 165 goto out;
yading@10 166 }
yading@10 167 avpriv_set_pts_info(vst, 64, 1, 1000);
yading@10 168 vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
yading@10 169 vst->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
yading@10 170 vst->codec->time_base.den = framerate.num;
yading@10 171 vst->codec->time_base.num = framerate.den;
yading@10 172 vst->codec->width = fmt->width;
yading@10 173 vst->codec->height = fmt->height;
yading@10 174 vst->codec->pix_fmt = fmt->pix_fmt;
yading@10 175
yading@10 176 /* packet init */
yading@10 177 av_init_packet(&dc1394->packet);
yading@10 178 dc1394->packet.size = avpicture_get_size(fmt->pix_fmt, fmt->width, fmt->height);
yading@10 179 dc1394->packet.stream_index = vst->index;
yading@10 180 dc1394->packet.flags |= AV_PKT_FLAG_KEY;
yading@10 181
yading@10 182 dc1394->current_frame = 0;
yading@10 183
yading@10 184 vst->codec->bit_rate = av_rescale(dc1394->packet.size * 8, fps->frame_rate, 1000);
yading@10 185 *select_fps = fps;
yading@10 186 *select_fmt = fmt;
yading@10 187 out:
yading@10 188 return ret;
yading@10 189 }
yading@10 190
yading@10 191 #if HAVE_LIBDC1394_1
yading@10 192 static int dc1394_v1_read_header(AVFormatContext *c)
yading@10 193 {
yading@10 194 dc1394_data* dc1394 = c->priv_data;
yading@10 195 AVStream* vst;
yading@10 196 nodeid_t* camera_nodes;
yading@10 197 int res;
yading@10 198 struct dc1394_frame_format *fmt = NULL;
yading@10 199 struct dc1394_frame_rate *fps = NULL;
yading@10 200
yading@10 201 if (dc1394_read_common(c, &fmt, &fps) != 0)
yading@10 202 return -1;
yading@10 203
yading@10 204 /* Now let us prep the hardware. */
yading@10 205 dc1394->handle = dc1394_create_handle(0); /* FIXME: gotta have ap->port */
yading@10 206 if (!dc1394->handle) {
yading@10 207 av_log(c, AV_LOG_ERROR, "Can't acquire dc1394 handle on port %d\n", 0 /* ap->port */);
yading@10 208 goto out;
yading@10 209 }
yading@10 210 camera_nodes = dc1394_get_camera_nodes(dc1394->handle, &res, 1);
yading@10 211 if (!camera_nodes || camera_nodes[dc1394->channel] == DC1394_NO_CAMERA) {
yading@10 212 av_log(c, AV_LOG_ERROR, "There's no IIDC camera on the channel %d\n", dc1394->channel);
yading@10 213 goto out_handle;
yading@10 214 }
yading@10 215 res = dc1394_dma_setup_capture(dc1394->handle, camera_nodes[dc1394->channel],
yading@10 216 0,
yading@10 217 FORMAT_VGA_NONCOMPRESSED,
yading@10 218 fmt->frame_size_id,
yading@10 219 SPEED_400,
yading@10 220 fps->frame_rate_id, 8, 1,
yading@10 221 c->filename,
yading@10 222 &dc1394->camera);
yading@10 223 dc1394_free_camera_nodes(camera_nodes);
yading@10 224 if (res != DC1394_SUCCESS) {
yading@10 225 av_log(c, AV_LOG_ERROR, "Can't prepare camera for the DMA capture\n");
yading@10 226 goto out_handle;
yading@10 227 }
yading@10 228
yading@10 229 res = dc1394_start_iso_transmission(dc1394->handle, dc1394->camera.node);
yading@10 230 if (res != DC1394_SUCCESS) {
yading@10 231 av_log(c, AV_LOG_ERROR, "Can't start isochronous transmission\n");
yading@10 232 goto out_handle_dma;
yading@10 233 }
yading@10 234
yading@10 235 return 0;
yading@10 236
yading@10 237 out_handle_dma:
yading@10 238 dc1394_dma_unlisten(dc1394->handle, &dc1394->camera);
yading@10 239 dc1394_dma_release_camera(dc1394->handle, &dc1394->camera);
yading@10 240 out_handle:
yading@10 241 dc1394_destroy_handle(dc1394->handle);
yading@10 242 out:
yading@10 243 return -1;
yading@10 244 }
yading@10 245
yading@10 246 static int dc1394_v1_read_packet(AVFormatContext *c, AVPacket *pkt)
yading@10 247 {
yading@10 248 struct dc1394_data *dc1394 = c->priv_data;
yading@10 249 int res;
yading@10 250
yading@10 251 /* discard stale frame */
yading@10 252 if (dc1394->current_frame++) {
yading@10 253 if (dc1394_dma_done_with_buffer(&dc1394->camera) != DC1394_SUCCESS)
yading@10 254 av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame);
yading@10 255 }
yading@10 256
yading@10 257 res = dc1394_dma_single_capture(&dc1394->camera);
yading@10 258
yading@10 259 if (res == DC1394_SUCCESS) {
yading@10 260 dc1394->packet.data = (uint8_t *)(dc1394->camera.capture_buffer);
yading@10 261 dc1394->packet.pts = (dc1394->current_frame * 1000000) / dc1394->frame_rate;
yading@10 262 res = dc1394->packet.size;
yading@10 263 } else {
yading@10 264 av_log(c, AV_LOG_ERROR, "DMA capture failed\n");
yading@10 265 dc1394->packet.data = NULL;
yading@10 266 res = -1;
yading@10 267 }
yading@10 268
yading@10 269 *pkt = dc1394->packet;
yading@10 270 return res;
yading@10 271 }
yading@10 272
yading@10 273 static int dc1394_v1_close(AVFormatContext * context)
yading@10 274 {
yading@10 275 struct dc1394_data *dc1394 = context->priv_data;
yading@10 276
yading@10 277 dc1394_stop_iso_transmission(dc1394->handle, dc1394->camera.node);
yading@10 278 dc1394_dma_unlisten(dc1394->handle, &dc1394->camera);
yading@10 279 dc1394_dma_release_camera(dc1394->handle, &dc1394->camera);
yading@10 280 dc1394_destroy_handle(dc1394->handle);
yading@10 281
yading@10 282 return 0;
yading@10 283 }
yading@10 284
yading@10 285 #elif HAVE_LIBDC1394_2
yading@10 286 static int dc1394_v2_read_header(AVFormatContext *c)
yading@10 287 {
yading@10 288 dc1394_data* dc1394 = c->priv_data;
yading@10 289 dc1394camera_list_t *list;
yading@10 290 int res, i;
yading@10 291 struct dc1394_frame_format *fmt = NULL;
yading@10 292 struct dc1394_frame_rate *fps = NULL;
yading@10 293
yading@10 294 if (dc1394_read_common(c, &fmt, &fps) != 0)
yading@10 295 return -1;
yading@10 296
yading@10 297 /* Now let us prep the hardware. */
yading@10 298 dc1394->d = dc1394_new();
yading@10 299 dc1394_camera_enumerate (dc1394->d, &list);
yading@10 300 if ( !list || list->num == 0) {
yading@10 301 av_log(c, AV_LOG_ERROR, "Unable to look for an IIDC camera\n\n");
yading@10 302 goto out;
yading@10 303 }
yading@10 304
yading@10 305 /* FIXME: To select a specific camera I need to search in list its guid */
yading@10 306 dc1394->camera = dc1394_camera_new (dc1394->d, list->ids[0].guid);
yading@10 307 if (list->num > 1) {
yading@10 308 av_log(c, AV_LOG_INFO, "Working with the first camera found\n");
yading@10 309 }
yading@10 310
yading@10 311 /* Freeing list of cameras */
yading@10 312 dc1394_camera_free_list (list);
yading@10 313
yading@10 314 /* Select MAX Speed possible from the cam */
yading@10 315 if (dc1394->camera->bmode_capable>0) {
yading@10 316 dc1394_video_set_operation_mode(dc1394->camera, DC1394_OPERATION_MODE_1394B);
yading@10 317 i = DC1394_ISO_SPEED_800;
yading@10 318 } else {
yading@10 319 i = DC1394_ISO_SPEED_400;
yading@10 320 }
yading@10 321
yading@10 322 for (res = DC1394_FAILURE; i >= DC1394_ISO_SPEED_MIN && res != DC1394_SUCCESS; i--) {
yading@10 323 res=dc1394_video_set_iso_speed(dc1394->camera, i);
yading@10 324 }
yading@10 325 if (res != DC1394_SUCCESS) {
yading@10 326 av_log(c, AV_LOG_ERROR, "Couldn't set ISO Speed\n");
yading@10 327 goto out_camera;
yading@10 328 }
yading@10 329
yading@10 330 if (dc1394_video_set_mode(dc1394->camera, fmt->frame_size_id) != DC1394_SUCCESS) {
yading@10 331 av_log(c, AV_LOG_ERROR, "Couldn't set video format\n");
yading@10 332 goto out_camera;
yading@10 333 }
yading@10 334
yading@10 335 if (dc1394_video_set_framerate(dc1394->camera,fps->frame_rate_id) != DC1394_SUCCESS) {
yading@10 336 av_log(c, AV_LOG_ERROR, "Couldn't set framerate %d \n",fps->frame_rate);
yading@10 337 goto out_camera;
yading@10 338 }
yading@10 339 if (dc1394_capture_setup(dc1394->camera, 10, DC1394_CAPTURE_FLAGS_DEFAULT)!=DC1394_SUCCESS) {
yading@10 340 av_log(c, AV_LOG_ERROR, "Cannot setup camera \n");
yading@10 341 goto out_camera;
yading@10 342 }
yading@10 343
yading@10 344 if (dc1394_video_set_transmission(dc1394->camera, DC1394_ON) !=DC1394_SUCCESS) {
yading@10 345 av_log(c, AV_LOG_ERROR, "Cannot start capture\n");
yading@10 346 goto out_camera;
yading@10 347 }
yading@10 348 return 0;
yading@10 349
yading@10 350 out_camera:
yading@10 351 dc1394_capture_stop(dc1394->camera);
yading@10 352 dc1394_video_set_transmission(dc1394->camera, DC1394_OFF);
yading@10 353 dc1394_camera_free (dc1394->camera);
yading@10 354 out:
yading@10 355 dc1394_free(dc1394->d);
yading@10 356 return -1;
yading@10 357 }
yading@10 358
yading@10 359 static int dc1394_v2_read_packet(AVFormatContext *c, AVPacket *pkt)
yading@10 360 {
yading@10 361 struct dc1394_data *dc1394 = c->priv_data;
yading@10 362 int res;
yading@10 363
yading@10 364 /* discard stale frame */
yading@10 365 if (dc1394->current_frame++) {
yading@10 366 if (dc1394_capture_enqueue(dc1394->camera, dc1394->frame) != DC1394_SUCCESS)
yading@10 367 av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame);
yading@10 368 }
yading@10 369
yading@10 370 res = dc1394_capture_dequeue(dc1394->camera, DC1394_CAPTURE_POLICY_WAIT, &dc1394->frame);
yading@10 371 if (res == DC1394_SUCCESS) {
yading@10 372 dc1394->packet.data = (uint8_t *) dc1394->frame->image;
yading@10 373 dc1394->packet.pts = dc1394->current_frame * 1000000 / dc1394->frame_rate;
yading@10 374 res = dc1394->frame->image_bytes;
yading@10 375 } else {
yading@10 376 av_log(c, AV_LOG_ERROR, "DMA capture failed\n");
yading@10 377 dc1394->packet.data = NULL;
yading@10 378 res = -1;
yading@10 379 }
yading@10 380
yading@10 381 *pkt = dc1394->packet;
yading@10 382 return res;
yading@10 383 }
yading@10 384
yading@10 385 static int dc1394_v2_close(AVFormatContext * context)
yading@10 386 {
yading@10 387 struct dc1394_data *dc1394 = context->priv_data;
yading@10 388
yading@10 389 dc1394_video_set_transmission(dc1394->camera, DC1394_OFF);
yading@10 390 dc1394_capture_stop(dc1394->camera);
yading@10 391 dc1394_camera_free(dc1394->camera);
yading@10 392 dc1394_free(dc1394->d);
yading@10 393
yading@10 394 return 0;
yading@10 395 }
yading@10 396
yading@10 397 AVInputFormat ff_libdc1394_demuxer = {
yading@10 398 .name = "libdc1394",
yading@10 399 .long_name = NULL_IF_CONFIG_SMALL("dc1394 v.2 A/V grab"),
yading@10 400 .priv_data_size = sizeof(struct dc1394_data),
yading@10 401 .read_header = dc1394_v2_read_header,
yading@10 402 .read_packet = dc1394_v2_read_packet,
yading@10 403 .read_close = dc1394_v2_close,
yading@10 404 .flags = AVFMT_NOFILE,
yading@10 405 .priv_class = &libdc1394_class,
yading@10 406 };
yading@10 407
yading@10 408 #endif
yading@10 409 #if HAVE_LIBDC1394_1
yading@10 410 AVInputFormat ff_libdc1394_demuxer = {
yading@10 411 .name = "libdc1394",
yading@10 412 .long_name = NULL_IF_CONFIG_SMALL("dc1394 v.1 A/V grab"),
yading@10 413 .priv_data_size = sizeof(struct dc1394_data),
yading@10 414 .read_header = dc1394_v1_read_header,
yading@10 415 .read_packet = dc1394_v1_read_packet,
yading@10 416 .read_close = dc1394_v1_close,
yading@10 417 .flags = AVFMT_NOFILE,
yading@10 418 .priv_class = &libdc1394_class,
yading@10 419 };
yading@10 420 #endif