]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavdevice/libdc1394.c
095a35af15de47e3e57e5d1d99910f16d0b9fcfc
[frescor/ffmpeg.git] / 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, MODE_320x240_YUV422 } /* default -- 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, FRAMERATE_30    } /* default -- 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
72     for (fmt = dc1394_frame_formats; fmt->width; fmt++)
73          if (fmt->pix_fmt == ap->pix_fmt && fmt->width == ap->width && fmt->height == ap->height)
74              break;
75
76     for (fps = dc1394_frame_rates; fps->frame_rate; fps++)
77          if (fps->frame_rate == av_rescale(1000, ap->time_base.den, ap->time_base.num))
78              break;
79
80     /* create a video stream */
81     vst = av_new_stream(c, 0);
82     if (!vst)
83         return -1;
84     av_set_pts_info(vst, 64, 1, 1000);
85     vst->codec->codec_type = CODEC_TYPE_VIDEO;
86     vst->codec->codec_id = CODEC_ID_RAWVIDEO;
87     vst->codec->time_base.den = fps->frame_rate;
88     vst->codec->time_base.num = 1000;
89     vst->codec->width = fmt->width;
90     vst->codec->height = fmt->height;
91     vst->codec->pix_fmt = fmt->pix_fmt;
92
93     /* packet init */
94     av_init_packet(&dc1394->packet);
95     dc1394->packet.size = avpicture_get_size(fmt->pix_fmt, fmt->width, fmt->height);
96     dc1394->packet.stream_index = vst->index;
97     dc1394->packet.flags |= PKT_FLAG_KEY;
98
99     dc1394->current_frame = 0;
100     dc1394->fps = fps->frame_rate;
101
102     vst->codec->bit_rate = av_rescale(dc1394->packet.size * 8, fps->frame_rate, 1000);
103
104     /* Now lets prep the hardware */
105     dc1394->handle = dc1394_create_handle(0); /* FIXME: gotta have ap->port */
106     if (!dc1394->handle) {
107         av_log(c, AV_LOG_ERROR, "Can't acquire dc1394 handle on port %d\n", 0 /* ap->port */);
108         goto out;
109     }
110     camera_nodes = dc1394_get_camera_nodes(dc1394->handle, &res, 1);
111     if (!camera_nodes || camera_nodes[ap->channel] == DC1394_NO_CAMERA) {
112         av_log(c, AV_LOG_ERROR, "There's no IIDC camera on the channel %d\n", ap->channel);
113         goto out_handle;
114     }
115     res = dc1394_dma_setup_capture(dc1394->handle, camera_nodes[ap->channel],
116                                    0,
117                                    FORMAT_VGA_NONCOMPRESSED,
118                                    fmt->frame_size_id,
119                                    SPEED_400,
120                                    fps->frame_rate_id, 8, 1,
121                                    c->filename,
122                                    &dc1394->camera);
123     dc1394_free_camera_nodes(camera_nodes);
124     if (res != DC1394_SUCCESS) {
125         av_log(c, AV_LOG_ERROR, "Can't prepare camera for the DMA capture\n");
126         goto out_handle;
127     }
128
129     res = dc1394_start_iso_transmission(dc1394->handle, dc1394->camera.node);
130     if (res != DC1394_SUCCESS) {
131         av_log(c, AV_LOG_ERROR, "Can't start isochronous transmission\n");
132         goto out_handle_dma;
133     }
134
135     return 0;
136
137 out_handle_dma:
138     dc1394_dma_unlisten(dc1394->handle, &dc1394->camera);
139     dc1394_dma_release_camera(dc1394->handle, &dc1394->camera);
140 out_handle:
141     dc1394_destroy_handle(dc1394->handle);
142 out:
143     return -1;
144 }
145
146 static int dc1394_read_packet(AVFormatContext *c, AVPacket *pkt)
147 {
148     struct dc1394_data *dc1394 = c->priv_data;
149     int res;
150
151     /* discard stale frame */
152     if (dc1394->current_frame++) {
153         if (dc1394_dma_done_with_buffer(&dc1394->camera) != DC1394_SUCCESS)
154             av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame);
155     }
156
157     res = dc1394_dma_single_capture(&dc1394->camera);
158
159     if (res == DC1394_SUCCESS) {
160         dc1394->packet.data = (uint8_t *)(dc1394->camera.capture_buffer);
161         dc1394->packet.pts = (dc1394->current_frame * 1000000) / dc1394->fps;
162         res = dc1394->packet.size;
163     } else {
164         av_log(c, AV_LOG_ERROR, "DMA capture failed\n");
165         dc1394->packet.data = NULL;
166         res = -1;
167     }
168
169     *pkt = dc1394->packet;
170     return res;
171 }
172
173 static int dc1394_close(AVFormatContext * context)
174 {
175     struct dc1394_data *dc1394 = context->priv_data;
176
177     dc1394_stop_iso_transmission(dc1394->handle, dc1394->camera.node);
178     dc1394_dma_unlisten(dc1394->handle, &dc1394->camera);
179     dc1394_dma_release_camera(dc1394->handle, &dc1394->camera);
180     dc1394_destroy_handle(dc1394->handle);
181
182     return 0;
183 }
184
185 AVInputFormat libdc1394_demuxer = {
186     .name           = "libdc1394",
187     .long_name      = "dc1394 A/V grab",
188     .priv_data_size = sizeof(struct dc1394_data),
189     .read_header    = dc1394_read_header,
190     .read_packet    = dc1394_read_packet,
191     .read_close     = dc1394_close,
192     .flags          = AVFMT_NOFILE
193 };