Mercurial > libavformat.hg
annotate dc1394.c @ 1960:c0289552590f libavformat
Change the vhook code to send real timestamps to the filters instead of the
current time of day, which is useless, and which the filters could just as
easily query for themselves.
patch by Bobby Bingham, uhmmmm gmail com
author | diego |
---|---|
date | Thu, 29 Mar 2007 05:24:35 +0000 |
parents | 62792a60f740 |
children | 491a751cc58c |
rev | line source |
---|---|
571 | 1 /* |
2 * IIDC1394 grab interface (uses libdc1394 and libraw1394) | |
3 * Copyright (c) 2004 Roman Shaposhnik | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
571 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
571 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
571 | 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 | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
887
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
571 | 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 }, | |
1760
8cba5672faa4
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
1358
diff
changeset
|
45 { 640, 480, PIX_FMT_UYYVYY411, MODE_640x480_YUV411 }, |
571 | 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) | |
887 | 74 break; |
885 | 75 |
571 | 76 for (fps = dc1394_frame_rates; fps->frame_rate; fps++) |
743 | 77 if (fps->frame_rate == av_rescale(1000, ap->time_base.den, ap->time_base.num)) |
887 | 78 break; |
885 | 79 |
571 | 80 /* create a video stream */ |
81 vst = av_new_stream(c, 0); | |
82 if (!vst) | |
887 | 83 return -1; |
571 | 84 av_set_pts_info(vst, 64, 1, 1000); |
833 | 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; | |
571 | 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; | |
885 | 98 |
571 | 99 dc1394->current_frame = 0; |
100 dc1394->fps = fps->frame_rate; | |
101 | |
833 | 102 vst->codec->bit_rate = av_rescale(dc1394->packet.size * 8, fps->frame_rate, 1000); |
885 | 103 |
571 | 104 /* Now lets prep the hardware */ |
105 dc1394->handle = dc1394_create_handle(0); /* FIXME: gotta have ap->port */ | |
106 if (!dc1394->handle) { | |
887 | 107 av_log(c, AV_LOG_ERROR, "Can't acquire dc1394 handle on port %d\n", 0 /* ap->port */); |
571 | 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); | |
885 | 113 goto out_handle; |
571 | 114 } |
885 | 115 res = dc1394_dma_setup_capture(dc1394->handle, camera_nodes[ap->channel], |
887 | 116 0, |
117 FORMAT_VGA_NONCOMPRESSED, | |
118 fmt->frame_size_id, | |
119 SPEED_400, | |
120 fps->frame_rate_id, 8, 1, | |
1795
62792a60f740
implement new grabbing interface, as described here:
gpoirier
parents:
1760
diff
changeset
|
121 c->filename, |
887 | 122 &dc1394->camera); |
571 | 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"); | |
887 | 126 goto out_handle; |
571 | 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"); | |
887 | 132 goto out_handle_dma; |
571 | 133 } |
885 | 134 |
571 | 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; | |
885 | 150 |
571 | 151 /* discard stale frame */ |
152 if (dc1394->current_frame++) { | |
887 | 153 if (dc1394_dma_done_with_buffer(&dc1394->camera) != DC1394_SUCCESS) |
571 | 154 av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame); |
155 } | |
885 | 156 |
571 | 157 res = dc1394_dma_single_capture(&dc1394->camera); |
158 | |
159 if (res == DC1394_SUCCESS) { | |
885 | 160 dc1394->packet.data = (uint8_t *)(dc1394->camera.capture_buffer); |
161 dc1394->packet.pts = (dc1394->current_frame * 1000000) / dc1394->fps; | |
887 | 162 res = dc1394->packet.size; |
571 | 163 } else { |
164 av_log(c, AV_LOG_ERROR, "DMA capture failed\n"); | |
165 dc1394->packet.data = NULL; | |
885 | 166 res = -1; |
571 | 167 } |
885 | 168 |
571 | 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); | |
885 | 181 |
571 | 182 return 0; |
183 } | |
184 | |
1169 | 185 AVInputFormat dc1394_demuxer = { |
571 | 186 .name = "dc1394", |
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 }; |