Statistics
| Branch: | Revision:

ffmpeg / libavformat / dc1394.c @ 7be806f3

History | View | Annotate | Download (6.17 KB)

1
/*
2
 * IIDC1394 grab interface (uses libdc1394 and libraw1394)
3
 * Copyright (c) 2004 Roman Shaposhnik
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19

    
20
#include "avformat.h"
21

    
22
#include <libraw1394/raw1394.h>
23
#include <libdc1394/dc1394_control.h>
24

    
25
#undef free
26

    
27
typedef struct dc1394_data {
28
    raw1394handle_t handle;
29
    dc1394_cameracapture camera;
30
    int current_frame;
31
    int fps;
32

    
33
    AVPacket packet;
34
} dc1394_data;
35

    
36
struct dc1394_frame_format {
37
    int width;
38
    int height;
39
    enum PixelFormat pix_fmt;
40
    int frame_size_id;
41
} dc1394_frame_formats[] = {
42
    { 320, 240, PIX_FMT_UYVY422, MODE_320x240_YUV422 },
43
    { 640, 480, PIX_FMT_UYVY411, MODE_640x480_YUV411 },
44
    { 640, 480, PIX_FMT_UYVY422, MODE_640x480_YUV422 },
45
    {   0,   0, 0, MODE_320x240_YUV422 } /* default -- gotta be the last one */
46
};
47

    
48
struct dc1394_frame_rate {
49
    int frame_rate;
50
    int frame_rate_id;
51
} dc1394_frame_rates[] = {
52
    {  1875, FRAMERATE_1_875 },
53
    {  3750, FRAMERATE_3_75  },
54
    {  7500, FRAMERATE_7_5   },
55
    { 15000, FRAMERATE_15    },
56
    { 30000, FRAMERATE_30    },
57
    { 60000, FRAMERATE_60    },
58
    {     0, FRAMERATE_30    } /* default -- gotta be the last one */
59
};
60

    
61
static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap)
62
{
63
    dc1394_data* dc1394 = c->priv_data;
64
    AVStream* vst;
65
    nodeid_t* camera_nodes;
66
    int res;
67
    struct dc1394_frame_format *fmt;
68
    struct dc1394_frame_rate *fps;
69

    
70
    for (fmt = dc1394_frame_formats; fmt->width; fmt++)
71
         if (fmt->pix_fmt == ap->pix_fmt && fmt->width == ap->width && fmt->height == ap->height)
72
             break;
73
             
74
    for (fps = dc1394_frame_rates; fps->frame_rate; fps++)
75
         if (fps->frame_rate == av_rescale(1000, ap->frame_rate, ap->frame_rate_base))
76
             break;
77
    
78
    /* create a video stream */
79
    vst = av_new_stream(c, 0);
80
    if (!vst)
81
        return -1;
82
    av_set_pts_info(vst, 64, 1, 1000);
83
    vst->codec.codec_type = CODEC_TYPE_VIDEO;
84
    vst->codec.codec_id = CODEC_ID_RAWVIDEO;
85
    vst->codec.frame_rate = fps->frame_rate;
86
    vst->codec.frame_rate_base = 1000;
87
    vst->codec.width = fmt->width;
88
    vst->codec.height = fmt->height;
89
    vst->codec.pix_fmt = fmt->pix_fmt;
90

    
91
    /* packet init */
92
    av_init_packet(&dc1394->packet);
93
    dc1394->packet.size = avpicture_get_size(fmt->pix_fmt, fmt->width, fmt->height);
94
    dc1394->packet.stream_index = vst->index;
95
    dc1394->packet.flags |= PKT_FLAG_KEY;
96
    
97
    dc1394->current_frame = 0;
98
    dc1394->fps = fps->frame_rate;
99

    
100
    vst->codec.bit_rate = av_rescale(dc1394->packet.size * 8, fps->frame_rate, 1000);
101
    
102
    /* Now lets prep the hardware */
103
    dc1394->handle = dc1394_create_handle(0); /* FIXME: gotta have ap->port */
104
    if (!dc1394->handle) {
105
        av_log(c, AV_LOG_ERROR, "Can't aquire dc1394 handle on port %d\n", 0 /* ap->port */);
106
        goto out;
107
    }
108
    camera_nodes = dc1394_get_camera_nodes(dc1394->handle, &res, 1);
109
    if (!camera_nodes || camera_nodes[ap->channel] == DC1394_NO_CAMERA) {
110
        av_log(c, AV_LOG_ERROR, "There's no IIDC camera on the channel %d\n", ap->channel);
111
        goto out_handle; 
112
    }
113
    res = dc1394_dma_setup_capture(dc1394->handle, camera_nodes[ap->channel], 
114
                                   0,
115
                                   FORMAT_VGA_NONCOMPRESSED,
116
                                   fmt->frame_size_id,
117
                                   SPEED_400,
118
                                   fps->frame_rate_id, 8, 1, 
119
                                   ap->device, 
120
                                   &dc1394->camera);
121
    dc1394_free_camera_nodes(camera_nodes);
122
    if (res != DC1394_SUCCESS) {
123
        av_log(c, AV_LOG_ERROR, "Can't prepare camera for the DMA capture\n");
124
        goto out_handle;
125
    }
126

    
127
    res = dc1394_start_iso_transmission(dc1394->handle, dc1394->camera.node);
128
    if (res != DC1394_SUCCESS) {
129
        av_log(c, AV_LOG_ERROR, "Can't start isochronous transmission\n");
130
        goto out_handle_dma;
131
    }
132
    
133
    return 0;
134

    
135
out_handle_dma:
136
    dc1394_dma_unlisten(dc1394->handle, &dc1394->camera);
137
    dc1394_dma_release_camera(dc1394->handle, &dc1394->camera);
138
out_handle:
139
    dc1394_destroy_handle(dc1394->handle);
140
out:
141
    return -1;
142
}
143

    
144
static int dc1394_read_packet(AVFormatContext *c, AVPacket *pkt)
145
{
146
    struct dc1394_data *dc1394 = c->priv_data;
147
    int res;
148
    
149
    /* discard stale frame */
150
    if (dc1394->current_frame++) {
151
        if (dc1394_dma_done_with_buffer(&dc1394->camera) != DC1394_SUCCESS)
152
            av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame);
153
    }
154
    
155
    res = dc1394_dma_single_capture(&dc1394->camera);
156

    
157
    if (res == DC1394_SUCCESS) {
158
        dc1394->packet.data = (uint8_t *)(dc1394->camera.capture_buffer); 
159
        dc1394->packet.pts = (dc1394->current_frame * 1000000) / dc1394->fps; 
160
        res = dc1394->packet.size;
161
    } else {
162
        av_log(c, AV_LOG_ERROR, "DMA capture failed\n");
163
        dc1394->packet.data = NULL;
164
        res = -1;        
165
    }
166
    
167
    *pkt = dc1394->packet;
168
    return res;
169
}
170

    
171
static int dc1394_close(AVFormatContext * context)
172
{
173
    struct dc1394_data *dc1394 = context->priv_data;
174

    
175
    dc1394_stop_iso_transmission(dc1394->handle, dc1394->camera.node);
176
    dc1394_dma_unlisten(dc1394->handle, &dc1394->camera);
177
    dc1394_dma_release_camera(dc1394->handle, &dc1394->camera);
178
    dc1394_destroy_handle(dc1394->handle);
179
    
180
    return 0;
181
}
182

    
183
static AVInputFormat dc1394_format = {
184
    .name           = "dc1394",
185
    .long_name      = "dc1394 A/V grab",
186
    .priv_data_size = sizeof(struct dc1394_data),
187
    .read_header    = dc1394_read_header,
188
    .read_packet    = dc1394_read_packet,
189
    .read_close     = dc1394_close,
190
    .flags          = AVFMT_NOFILE
191
};
192

    
193
int dc1394_init(void)
194
{
195
    av_register_input_format(&dc1394_format);
196
    return 0;
197
}