]> git.sesse.net Git - ffmpeg/blob - libavdevice/libdc1394.c
* fixing a bug preventing default values to be set correctly
[ffmpeg] / libavdevice / libdc1394.c
1 /*
2  * IIDC1394 grab interface (uses libdc1394 and libraw1394)
3  * Copyright (c) 2004 Roman Shaposhnik
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "avformat.h"
23
24 #include <libraw1394/raw1394.h>
25 #include <libdc1394/dc1394_control.h>
26
27 #undef free
28
29 typedef struct dc1394_data {
30     raw1394handle_t handle;
31     dc1394_cameracapture camera;
32     int current_frame;
33     int fps;
34
35     AVPacket packet;
36 } dc1394_data;
37
38 struct dc1394_frame_format {
39     int width;
40     int height;
41     enum PixelFormat pix_fmt;
42     int frame_size_id;
43 } dc1394_frame_formats[] = {
44     { 320, 240, PIX_FMT_UYVY422, MODE_320x240_YUV422 },
45     { 640, 480, PIX_FMT_UYYVYY411, MODE_640x480_YUV411 },
46     { 640, 480, PIX_FMT_UYVY422, MODE_640x480_YUV422 },
47     { 0, 0, 0, 0 } /* gotta be the last one */
48 };
49
50 struct dc1394_frame_rate {
51     int frame_rate;
52     int frame_rate_id;
53 } dc1394_frame_rates[] = {
54     {  1875, FRAMERATE_1_875 },
55     {  3750, FRAMERATE_3_75  },
56     {  7500, FRAMERATE_7_5   },
57     { 15000, FRAMERATE_15    },
58     { 30000, FRAMERATE_30    },
59     { 60000, FRAMERATE_60    },
60     { 0, 0 } /* gotta be the last one */
61 };
62
63 static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap)
64 {
65     dc1394_data* dc1394 = c->priv_data;
66     AVStream* vst;
67     nodeid_t* camera_nodes;
68     int res;
69     struct dc1394_frame_format *fmt;
70     struct dc1394_frame_rate *fps;
71     enum PixelFormat pix_fmt = ap->pix_fmt == PIX_FMT_NONE ? PIX_FMT_UYVY422 : ap->pix_fmt; /* defaults */
72     int width                = !ap->width ? 320 : ap->width;
73     int height               = !ap->height ? 240 : ap->height;
74     int frame_rate           = !ap->time_base.num ? 30000 : av_rescale(1000, ap->time_base.den, ap->time_base.num);
75
76     for (fmt = dc1394_frame_formats; fmt->width; fmt++)
77          if (fmt->pix_fmt == pix_fmt && fmt->width == width && fmt->height == height)
78              break;
79
80     for (fps = dc1394_frame_rates; fps->frame_rate; fps++)
81          if (fps->frame_rate == frame_rate)
82              break;
83
84     if (!fps->frame_rate || !fmt->width) {
85         av_log(c, AV_LOG_ERROR, "Can't find matching camera format for %s, %dx%d@%d:1000fps\n", avcodec_get_pix_fmt_name(pix_fmt),
86                                                                                                 width, height, frame_rate);
87         goto out;
88     }
89
90     /* create a video stream */
91     vst = av_new_stream(c, 0);
92     if (!vst)
93         return -1;
94     av_set_pts_info(vst, 64, 1, 1000);
95     vst->codec->codec_type = CODEC_TYPE_VIDEO;
96     vst->codec->codec_id = CODEC_ID_RAWVIDEO;
97     vst->codec->time_base.den = fps->frame_rate;
98     vst->codec->time_base.num = 1000;
99     vst->codec->width = fmt->width;
100     vst->codec->height = fmt->height;
101     vst->codec->pix_fmt = fmt->pix_fmt;
102
103     /* packet init */
104     av_init_packet(&dc1394->packet);
105     dc1394->packet.size = avpicture_get_size(fmt->pix_fmt, fmt->width, fmt->height);
106     dc1394->packet.stream_index = vst->index;
107     dc1394->packet.flags |= PKT_FLAG_KEY;
108
109     dc1394->current_frame = 0;
110     dc1394->fps = fps->frame_rate;
111
112     vst->codec->bit_rate = av_rescale(dc1394->packet.size * 8, fps->frame_rate, 1000);
113
114     /* Now lets prep the hardware */
115     dc1394->handle = dc1394_create_handle(0); /* FIXME: gotta have ap->port */
116     if (!dc1394->handle) {
117         av_log(c, AV_LOG_ERROR, "Can't acquire dc1394 handle on port %d\n", 0 /* ap->port */);
118         goto out;
119     }
120     camera_nodes = dc1394_get_camera_nodes(dc1394->handle, &res, 1);
121     if (!camera_nodes || camera_nodes[ap->channel] == DC1394_NO_CAMERA) {
122         av_log(c, AV_LOG_ERROR, "There's no IIDC camera on the channel %d\n", ap->channel);
123         goto out_handle;
124     }
125     res = dc1394_dma_setup_capture(dc1394->handle, camera_nodes[ap->channel],
126                                    0,
127                                    FORMAT_VGA_NONCOMPRESSED,
128                                    fmt->frame_size_id,
129                                    SPEED_400,
130                                    fps->frame_rate_id, 8, 1,
131                                    c->filename,
132                                    &dc1394->camera);
133     dc1394_free_camera_nodes(camera_nodes);
134     if (res != DC1394_SUCCESS) {
135         av_log(c, AV_LOG_ERROR, "Can't prepare camera for the DMA capture\n");
136         goto out_handle;
137     }
138
139     res = dc1394_start_iso_transmission(dc1394->handle, dc1394->camera.node);
140     if (res != DC1394_SUCCESS) {
141         av_log(c, AV_LOG_ERROR, "Can't start isochronous transmission\n");
142         goto out_handle_dma;
143     }
144
145     return 0;
146
147 out_handle_dma:
148     dc1394_dma_unlisten(dc1394->handle, &dc1394->camera);
149     dc1394_dma_release_camera(dc1394->handle, &dc1394->camera);
150 out_handle:
151     dc1394_destroy_handle(dc1394->handle);
152 out:
153     return -1;
154 }
155
156 static int dc1394_read_packet(AVFormatContext *c, AVPacket *pkt)
157 {
158     struct dc1394_data *dc1394 = c->priv_data;
159     int res;
160
161     /* discard stale frame */
162     if (dc1394->current_frame++) {
163         if (dc1394_dma_done_with_buffer(&dc1394->camera) != DC1394_SUCCESS)
164             av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame);
165     }
166
167     res = dc1394_dma_single_capture(&dc1394->camera);
168
169     if (res == DC1394_SUCCESS) {
170         dc1394->packet.data = (uint8_t *)(dc1394->camera.capture_buffer);
171         dc1394->packet.pts = (dc1394->current_frame * 1000000) / dc1394->fps;
172         res = dc1394->packet.size;
173     } else {
174         av_log(c, AV_LOG_ERROR, "DMA capture failed\n");
175         dc1394->packet.data = NULL;
176         res = -1;
177     }
178
179     *pkt = dc1394->packet;
180     return res;
181 }
182
183 static int dc1394_close(AVFormatContext * context)
184 {
185     struct dc1394_data *dc1394 = context->priv_data;
186
187     dc1394_stop_iso_transmission(dc1394->handle, dc1394->camera.node);
188     dc1394_dma_unlisten(dc1394->handle, &dc1394->camera);
189     dc1394_dma_release_camera(dc1394->handle, &dc1394->camera);
190     dc1394_destroy_handle(dc1394->handle);
191
192     return 0;
193 }
194
195 AVInputFormat libdc1394_demuxer = {
196     .name           = "libdc1394",
197     .long_name      = "dc1394 A/V grab",
198     .priv_data_size = sizeof(struct dc1394_data),
199     .read_header    = dc1394_read_header,
200     .read_packet    = dc1394_read_packet,
201     .read_close     = dc1394_close,
202     .flags          = AVFMT_NOFILE
203 };