Revision 7458ccbb libavformat/dv1394.c

View differences:

libavformat/dv1394.c
31 31
#undef DV1394_DEBUG
32 32

  
33 33
#include "dv1394.h"
34
#include "dv.h"
34 35

  
35 36
struct dv1394_data {
36 37
    int fd;
37 38
    int channel;
38
    int width, height;
39
    int frame_rate;
40
    int frame_size;
41 39
    int format;
42 40

  
43 41
    void *ring; /* Ring buffer */
......
45 43
    int avail;  /* Number of frames available for reading */
46 44
    int done;   /* Number of completed frames */
47 45

  
48
    int stream; /* Current stream. 0 - video, 1 - audio */
49 46
    int64_t pts;  /* Current timestamp */
50
    AVStream *vst, *ast;
47

  
48
    void* dv_demux; /* Generic DV muxing/demuxing context */
51 49
};
52 50

  
53 51
/* 
......
69 67
        return -1;
70 68

  
71 69
    dv->avail  = dv->done = 0;
72
    dv->stream = 0;
73 70
    return 0;
74 71
}
75 72

  
......
88 85
    struct dv1394_data *dv = context->priv_data;
89 86
    const char *video_device;
90 87

  
91
    dv->vst = av_new_stream(context, 0);
92
    if (!dv->vst)
93
        return -ENOMEM;
94
    dv->ast = av_new_stream(context, 1);
95
    if (!dv->ast) {
96
        av_free(dv->vst);
97
        return -ENOMEM;
98
    }
88
    dv->dv_demux = dv_init_demux(context, 0, 1);
89
    if (!dv->dv_demux)
90
        goto failed;
99 91

  
100 92
    if (ap->standard && !strcasecmp(ap->standard, "pal"))
101 93
	dv->format = DV1394_PAL;
......
107 99
    else
108 100
        dv->channel = DV1394_DEFAULT_CHANNEL;
109 101

  
110
    dv->width = DV1394_WIDTH;
111
    if (dv->format == DV1394_NTSC) {
112
	dv->height = DV1394_NTSC_HEIGHT;
113
        dv->frame_size = DV1394_NTSC_FRAME_SIZE;
114
        dv->frame_rate = 30;
115
    } else {
116
	dv->height = DV1394_PAL_HEIGHT;
117
        dv->frame_size = DV1394_PAL_FRAME_SIZE;
118
        dv->frame_rate = 25;
119
    }
120

  
121 102
    /* Open and initialize DV1394 device */
122 103
    video_device = ap->device;
123 104
    if (!video_device)
......
140 121
        goto failed;
141 122
    }
142 123

  
143
    dv->stream = 0;
144

  
145
    dv->vst->codec.codec_type = CODEC_TYPE_VIDEO;
146
    dv->vst->codec.codec_id   = CODEC_ID_DVVIDEO;
147
    dv->vst->codec.width      = dv->width;
148
    dv->vst->codec.height     = dv->height;
149
    dv->vst->codec.frame_rate = dv->frame_rate;
150
    dv->vst->codec.frame_rate_base = 1;
151
    dv->vst->codec.bit_rate   = 25000000;  /* Consumer DV is 25Mbps */
152

  
153
    dv->ast->codec.codec_type = CODEC_TYPE_AUDIO;
154
    dv->ast->codec.codec_id   = CODEC_ID_DVAUDIO;
155
    dv->ast->codec.channels   = 2;
156
    dv->ast->codec.sample_rate= 48000;
157

  
158 124
    av_set_pts_info(context, 48, 1, 1000000);
159 125

  
160 126
    if (dv1394_start(dv) < 0)
......
164 130

  
165 131
failed:
166 132
    close(dv->fd);
167
    av_free(dv->vst);
168
    av_free(dv->ast);
169 133
    return -EIO;
170 134
}
171 135

  
172
static void __destruct_pkt(struct AVPacket *pkt)
173
{
174
    pkt->data = NULL; pkt->size = 0;
175
    return;
176
}
177

  
178
static inline int __get_frame(struct dv1394_data *dv, AVPacket *pkt)
179
{
180
    char *ptr = dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE);
181

  
182
    if (dv->stream) {
183
        dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
184
        dv->done++; dv->avail--;
185
    } else {
186
        dv->pts = av_gettime() & ((1LL << 48) - 1);
187
    }
188

  
189
    dv->format = ((ptr[3] & 0x80) == 0) ? DV1394_NTSC : DV1394_PAL;
190
    if (dv->format == DV1394_NTSC) {
191
        dv->frame_size = DV1394_NTSC_FRAME_SIZE;
192
        dv->vst->codec.height = dv->height = DV1394_NTSC_HEIGHT;
193
        dv->vst->codec.frame_rate = dv->frame_rate = 30;
194
    } else {
195
        dv->frame_size = DV1394_PAL_FRAME_SIZE;
196
        dv->vst->codec.height = dv->height = DV1394_PAL_HEIGHT;
197
        dv->vst->codec.frame_rate = dv->frame_rate = 25;
198
    }
199
	
200
    av_init_packet(pkt);
201
    pkt->destruct = __destruct_pkt;
202
    pkt->data     = ptr;
203
    pkt->size     = dv->frame_size;
204
    pkt->pts      = dv->pts;
205
    pkt->stream_index = dv->stream;
206
    pkt->flags   |= PKT_FLAG_KEY;
207

  
208
    dv->stream ^= 1;
209

  
210
    return dv->frame_size;
211
}
212

  
213 136
static int dv1394_read_packet(AVFormatContext *context, AVPacket *pkt)
214 137
{
215 138
    struct dv1394_data *dv = context->priv_data;
139
    int size;
140

  
141
    size = dv_get_packet(dv->dv_demux, pkt);
142
    if (size > 0)
143
        goto out;
216 144

  
217 145
    if (!dv->avail) {
218 146
        struct dv1394_status s;
......
276 204
            dv->done);
277 205
#endif
278 206

  
279
    return __get_frame(dv, pkt);
207
    size = dv_produce_packet(dv->dv_demux, pkt, 
208
                             dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE), 
209
			     DV1394_PAL_FRAME_SIZE);
210
    dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
211
    dv->done++; dv->avail--;
212
    dv->pts = av_gettime() & ((1LL << 48) - 1);
213
    
214
out:
215
    pkt->pts = dv->pts;
216
    return size;
280 217
}
281 218

  
282 219
static int dv1394_close(AVFormatContext * context)
......
292 229
        perror("Failed to munmap DV1394 ring buffer");
293 230

  
294 231
    close(dv->fd);
232
    av_free(dv->dv_demux);
295 233

  
296 234
    return 0;
297 235
}

Also available in: Unified diff