Originally committed as revision 7946 to svn://svn.ffmpeg.org/ffmpeg/trunk
Luca Abeni authored on 2007/02/12 22:38:14... | ... |
@@ -109,7 +109,7 @@ static struct fmt_map fmt_conversion_table[] = { |
109 | 109 |
}, |
110 | 110 |
}; |
111 | 111 |
|
112 |
-static int device_open(const char *devname, uint32_t *capabilities) |
|
112 |
+static int device_open(AVFormatContext *ctx, const char *devname, uint32_t *capabilities) |
|
113 | 113 |
{ |
114 | 114 |
struct v4l2_capability cap; |
115 | 115 |
int fd; |
... | ... |
@@ -117,7 +117,7 @@ static int device_open(const char *devname, uint32_t *capabilities) |
117 | 117 |
|
118 | 118 |
fd = open(devname, O_RDWR /*| O_NONBLOCK*/, 0); |
119 | 119 |
if (fd < 0) { |
120 |
- av_log(NULL, AV_LOG_ERROR, "Cannot open video device %s : %s\n", |
|
120 |
+ av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n", |
|
121 | 121 |
devname, strerror(errno)); |
122 | 122 |
|
123 | 123 |
return -1; |
... | ... |
@@ -127,20 +127,20 @@ static int device_open(const char *devname, uint32_t *capabilities) |
127 | 127 |
// ENOIOCTLCMD definition only availble on __KERNEL__ |
128 | 128 |
if (res < 0 && errno == 515) |
129 | 129 |
{ |
130 |
- av_log(NULL, AV_LOG_ERROR, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n"); |
|
130 |
+ av_log(ctx, AV_LOG_ERROR, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n"); |
|
131 | 131 |
close(fd); |
132 | 132 |
|
133 | 133 |
return -1; |
134 | 134 |
} |
135 | 135 |
if (res < 0) { |
136 |
- av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n", |
|
136 |
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n", |
|
137 | 137 |
strerror(errno)); |
138 | 138 |
close(fd); |
139 | 139 |
|
140 | 140 |
return -1; |
141 | 141 |
} |
142 | 142 |
if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) { |
143 |
- av_log(NULL, AV_LOG_ERROR, "Not a video capture device\n"); |
|
143 |
+ av_log(ctx, AV_LOG_ERROR, "Not a video capture device\n"); |
|
144 | 144 |
close(fd); |
145 | 145 |
|
146 | 146 |
return -1; |
... | ... |
@@ -150,8 +150,10 @@ static int device_open(const char *devname, uint32_t *capabilities) |
150 | 150 |
return fd; |
151 | 151 |
} |
152 | 152 |
|
153 |
-static int device_init(int fd, int *width, int *height, int pix_fmt) |
|
153 |
+static int device_init(AVFormatContext *ctx, int *width, int *height, int pix_fmt) |
|
154 | 154 |
{ |
155 |
+ struct video_data *s = ctx->priv_data; |
|
156 |
+ int fd = s->fd; |
|
155 | 157 |
struct v4l2_format fmt; |
156 | 158 |
int res; |
157 | 159 |
|
... | ... |
@@ -163,7 +165,7 @@ static int device_init(int fd, int *width, int *height, int pix_fmt) |
163 | 163 |
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; |
164 | 164 |
res = ioctl(fd, VIDIOC_S_FMT, &fmt); |
165 | 165 |
if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) { |
166 |
- av_log(NULL, AV_LOG_INFO, "The V4L2 driver changed the video from %dx%d to %dx%d\n", *width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height); |
|
166 |
+ av_log(ctx, AV_LOG_INFO, "The V4L2 driver changed the video from %dx%d to %dx%d\n", *width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height); |
|
167 | 167 |
*width = fmt.fmt.pix.width; |
168 | 168 |
*height = fmt.fmt.pix.height; |
169 | 169 |
} |
... | ... |
@@ -213,8 +215,9 @@ static enum PixelFormat fmt_v4l2ff(uint32_t pix_fmt) |
213 | 213 |
return -1; |
214 | 214 |
} |
215 | 215 |
|
216 |
-static int mmap_init(struct video_data *s) |
|
216 |
+static int mmap_init(AVFormatContext *ctx) |
|
217 | 217 |
{ |
218 |
+ struct video_data *s = ctx->priv_data; |
|
218 | 219 |
struct v4l2_requestbuffers req; |
219 | 220 |
int i, res; |
220 | 221 |
|
... | ... |
@@ -225,29 +228,29 @@ static int mmap_init(struct video_data *s) |
225 | 225 |
res = ioctl (s->fd, VIDIOC_REQBUFS, &req); |
226 | 226 |
if (res < 0) { |
227 | 227 |
if (errno == EINVAL) { |
228 |
- av_log(NULL, AV_LOG_ERROR, "Device does not support mmap\n"); |
|
228 |
+ av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n"); |
|
229 | 229 |
} else { |
230 |
- av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n"); |
|
230 |
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n"); |
|
231 | 231 |
} |
232 | 232 |
|
233 | 233 |
return -1; |
234 | 234 |
} |
235 | 235 |
|
236 | 236 |
if (req.count < 2) { |
237 |
- av_log(NULL, AV_LOG_ERROR, "Insufficient buffer memory\n"); |
|
237 |
+ av_log(ctx, AV_LOG_ERROR, "Insufficient buffer memory\n"); |
|
238 | 238 |
|
239 | 239 |
return -1; |
240 | 240 |
} |
241 | 241 |
s->buffers = req.count; |
242 | 242 |
s->buf_start = av_malloc(sizeof(void *) * s->buffers); |
243 | 243 |
if (s->buf_start == NULL) { |
244 |
- av_log(NULL, AV_LOG_ERROR, "Cannot allocate buffer pointers\n"); |
|
244 |
+ av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n"); |
|
245 | 245 |
|
246 | 246 |
return -1; |
247 | 247 |
} |
248 | 248 |
s->buf_len = av_malloc(sizeof(unsigned int) * s->buffers); |
249 | 249 |
if (s->buf_len == NULL) { |
250 |
- av_log(NULL, AV_LOG_ERROR, "Cannot allocate buffer sizes\n"); |
|
250 |
+ av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer sizes\n"); |
|
251 | 251 |
av_free(s->buf_start); |
252 | 252 |
|
253 | 253 |
return -1; |
... | ... |
@@ -262,21 +265,21 @@ static int mmap_init(struct video_data *s) |
262 | 262 |
buf.index = i; |
263 | 263 |
res = ioctl (s->fd, VIDIOC_QUERYBUF, &buf); |
264 | 264 |
if (res < 0) { |
265 |
- av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n"); |
|
265 |
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n"); |
|
266 | 266 |
|
267 | 267 |
return -1; |
268 | 268 |
} |
269 | 269 |
|
270 | 270 |
s->buf_len[i] = buf.length; |
271 | 271 |
if (s->buf_len[i] < s->frame_size) { |
272 |
- av_log(NULL, AV_LOG_ERROR, "Buffer len [%d] = %d != %d\n", i, s->buf_len[i], s->frame_size); |
|
272 |
+ av_log(ctx, AV_LOG_ERROR, "Buffer len [%d] = %d != %d\n", i, s->buf_len[i], s->frame_size); |
|
273 | 273 |
|
274 | 274 |
return -1; |
275 | 275 |
} |
276 | 276 |
s->buf_start[i] = mmap (NULL, buf.length, |
277 | 277 |
PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset); |
278 | 278 |
if (s->buf_start[i] == MAP_FAILED) { |
279 |
- av_log(NULL, AV_LOG_ERROR, "mmap: %s\n", strerror(errno)); |
|
279 |
+ av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno)); |
|
280 | 280 |
|
281 | 281 |
return -1; |
282 | 282 |
} |
... | ... |
@@ -285,13 +288,14 @@ static int mmap_init(struct video_data *s) |
285 | 285 |
return 0; |
286 | 286 |
} |
287 | 287 |
|
288 |
-static int read_init(struct video_data *s) |
|
288 |
+static int read_init(AVFormatContext *ctx) |
|
289 | 289 |
{ |
290 | 290 |
return -1; |
291 | 291 |
} |
292 | 292 |
|
293 |
-static int mmap_read_frame(struct video_data *s, void *frame, int64_t *ts) |
|
293 |
+static int mmap_read_frame(AVFormatContext *ctx, void *frame, int64_t *ts) |
|
294 | 294 |
{ |
295 |
+ struct video_data *s = ctx->priv_data; |
|
295 | 296 |
struct v4l2_buffer buf; |
296 | 297 |
int res; |
297 | 298 |
|
... | ... |
@@ -303,13 +307,13 @@ static int mmap_read_frame(struct video_data *s, void *frame, int64_t *ts) |
303 | 303 |
while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && |
304 | 304 |
((errno == EAGAIN) || (errno == EINTR))); |
305 | 305 |
if (res < 0) { |
306 |
- av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno)); |
|
306 |
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno)); |
|
307 | 307 |
|
308 | 308 |
return -1; |
309 | 309 |
} |
310 | 310 |
assert (buf.index < s->buffers); |
311 | 311 |
if (buf.bytesused != s->frame_size) { |
312 |
- av_log(NULL, AV_LOG_ERROR, "The v4l2 frame is %d bytes, but %d bytes are expected\n", buf.bytesused, s->frame_size); |
|
312 |
+ av_log(ctx, AV_LOG_ERROR, "The v4l2 frame is %d bytes, but %d bytes are expected\n", buf.bytesused, s->frame_size); |
|
313 | 313 |
|
314 | 314 |
return -1; |
315 | 315 |
} |
... | ... |
@@ -320,7 +324,7 @@ static int mmap_read_frame(struct video_data *s, void *frame, int64_t *ts) |
320 | 320 |
|
321 | 321 |
res = ioctl (s->fd, VIDIOC_QBUF, &buf); |
322 | 322 |
if (res < 0) { |
323 |
- av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n"); |
|
323 |
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n"); |
|
324 | 324 |
|
325 | 325 |
return -1; |
326 | 326 |
} |
... | ... |
@@ -328,13 +332,14 @@ static int mmap_read_frame(struct video_data *s, void *frame, int64_t *ts) |
328 | 328 |
return s->buf_len[buf.index]; |
329 | 329 |
} |
330 | 330 |
|
331 |
-static int read_frame(struct video_data *s, void *frame, int64_t *ts) |
|
331 |
+static int read_frame(AVFormatContext *ctx, void *frame, int64_t *ts) |
|
332 | 332 |
{ |
333 | 333 |
return -1; |
334 | 334 |
} |
335 | 335 |
|
336 |
-static int mmap_start(struct video_data *s) |
|
336 |
+static int mmap_start(AVFormatContext *ctx) |
|
337 | 337 |
{ |
338 |
+ struct video_data *s = ctx->priv_data; |
|
338 | 339 |
enum v4l2_buf_type type; |
339 | 340 |
int i, res; |
340 | 341 |
|
... | ... |
@@ -348,7 +353,7 @@ static int mmap_start(struct video_data *s) |
348 | 348 |
|
349 | 349 |
res = ioctl (s->fd, VIDIOC_QBUF, &buf); |
350 | 350 |
if (res < 0) { |
351 |
- av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno)); |
|
351 |
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno)); |
|
352 | 352 |
|
353 | 353 |
return -1; |
354 | 354 |
} |
... | ... |
@@ -357,7 +362,7 @@ static int mmap_start(struct video_data *s) |
357 | 357 |
type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
358 | 358 |
res = ioctl (s->fd, VIDIOC_STREAMON, &type); |
359 | 359 |
if (res < 0) { |
360 |
- av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", strerror(errno)); |
|
360 |
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", strerror(errno)); |
|
361 | 361 |
|
362 | 362 |
return -1; |
363 | 363 |
} |
... | ... |
@@ -424,7 +429,7 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) |
424 | 424 |
video_device = "/dev/video"; |
425 | 425 |
} |
426 | 426 |
capabilities = 0; |
427 |
- s->fd = device_open(video_device, &capabilities); |
|
427 |
+ s->fd = device_open(s1, video_device, &capabilities); |
|
428 | 428 |
if (s->fd < 0) { |
429 | 429 |
av_free(st); |
430 | 430 |
|
... | ... |
@@ -433,13 +438,13 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) |
433 | 433 |
av_log(s1, AV_LOG_INFO, "[%d]Capabilities: %x\n", s->fd, capabilities); |
434 | 434 |
|
435 | 435 |
desired_format = fmt_ff2v4l(ap->pix_fmt); |
436 |
- if (desired_format == 0 || (device_init(s->fd, &width, &height, desired_format) < 0)) { |
|
436 |
+ if (desired_format == 0 || (device_init(s1, &width, &height, desired_format) < 0)) { |
|
437 | 437 |
int i, done; |
438 | 438 |
|
439 | 439 |
done = 0; i = 0; |
440 | 440 |
while (!done) { |
441 | 441 |
desired_format = fmt_conversion_table[i].v4l2_fmt; |
442 |
- if (device_init(s->fd, &width, &height, desired_format) < 0) { |
|
442 |
+ if (device_init(s1, &width, &height, desired_format) < 0) { |
|
443 | 443 |
desired_format = 0; |
444 | 444 |
i++; |
445 | 445 |
} else { |
... | ... |
@@ -463,13 +468,13 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) |
463 | 463 |
s->frame_size = avpicture_get_size(st->codec->pix_fmt, width, height); |
464 | 464 |
if (capabilities & V4L2_CAP_STREAMING) { |
465 | 465 |
s->io_method = io_mmap; |
466 |
- res = mmap_init(s); |
|
466 |
+ res = mmap_init(s1); |
|
467 | 467 |
if (res == 0) { |
468 |
- res = mmap_start(s); |
|
468 |
+ res = mmap_start(s1); |
|
469 | 469 |
} |
470 | 470 |
} else { |
471 | 471 |
s->io_method = io_read; |
472 |
- res = read_init(s); |
|
472 |
+ res = read_init(s1); |
|
473 | 473 |
} |
474 | 474 |
if (res < 0) { |
475 | 475 |
close(s->fd); |
... | ... |
@@ -499,9 +504,9 @@ static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt) |
499 | 499 |
return AVERROR_IO; |
500 | 500 |
|
501 | 501 |
if (s->io_method == io_mmap) { |
502 |
- res = mmap_read_frame(s, pkt->data, &pkt->pts); |
|
502 |
+ res = mmap_read_frame(s1, pkt->data, &pkt->pts); |
|
503 | 503 |
} else if (s->io_method == io_read) { |
504 |
- res = read_frame(s, pkt->data, &pkt->pts); |
|
504 |
+ res = read_frame(s1, pkt->data, &pkt->pts); |
|
505 | 505 |
} else { |
506 | 506 |
return AVERROR_IO; |
507 | 507 |
} |