Mercurial > libavformat.hg
annotate v4l.c @ 2660:022174d849d5 libavformat
fix issue 225, instead of stoping when wrong atom size is found,
limit atom size to what is left, assuming container atom has correct size..
cricket4.3g2 has incorrect moov atom size which indicates that file size should be
2 bytes bigger than it is and quicktime reads it correctly though.
author | bcoudurier |
---|---|
date | Mon, 22 Oct 2007 14:36:14 +0000 |
parents | 590fa259d1dd |
children | 59fb7b65fcc6 |
rev | line source |
---|---|
0 | 1 /* |
2 * Linux video grab interface | |
3 * Copyright (c) 2000,2001 Fabrice Bellard. | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1316
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1316
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1316
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 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:
1316
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1316
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 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:
1316
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 |
0 | 20 */ |
21 #include "avformat.h" | |
2153
6d873194ff86
Fix linking: emms_c is a macro, #include the correct header file.
diego
parents:
2152
diff
changeset
|
22 #include "dsputil.h" |
0 | 23 #include <unistd.h> |
24 #include <fcntl.h> | |
25 #include <sys/ioctl.h> | |
26 #include <sys/mman.h> | |
27 #include <sys/time.h> | |
236
ee98d63dbba7
kernel header bug workaround by (Ronald Bultje <rbultje at ronald dot bitfreak dot net>)
michaelni
parents:
159
diff
changeset
|
28 #define _LINUX_TIME_H 1 |
ee98d63dbba7
kernel header bug workaround by (Ronald Bultje <rbultje at ronald dot bitfreak dot net>)
michaelni
parents:
159
diff
changeset
|
29 #include <linux/videodev.h> |
0 | 30 #include <time.h> |
31 | |
32 typedef struct { | |
33 int fd; | |
34 int frame_format; /* see VIDEO_PALETTE_xxx */ | |
35 int use_mmap; | |
36 int width, height; | |
37 int frame_rate; | |
85
25062c9b1f86
per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents:
65
diff
changeset
|
38 int frame_rate_base; |
65 | 39 int64_t time_frame; |
0 | 40 int frame_size; |
41 struct video_capability video_cap; | |
42 struct video_audio audio_saved; | |
65 | 43 uint8_t *video_buf; |
0 | 44 struct video_mbuf gb_buffers; |
45 struct video_mmap gb_buf; | |
46 int gb_frame; | |
47 | |
48 /* ATI All In Wonder specific stuff */ | |
49 /* XXX: remove and merge in libavcodec/imgconvert.c */ | |
50 int aiw_enabled; | |
51 int deint; | |
52 int halfw; | |
65 | 53 uint8_t *src_mem; |
54 uint8_t *lum_m4_mem; | |
0 | 55 } VideoData; |
56 | |
2130
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
57 struct { |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
58 int palette; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
59 int depth; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
60 enum PixelFormat pix_fmt; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
61 } video_formats [] = { |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
62 {.palette = VIDEO_PALETTE_YUV420P, .depth = 12, .pix_fmt = PIX_FMT_YUV420P }, |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
63 {.palette = VIDEO_PALETTE_YUV422, .depth = 16, .pix_fmt = PIX_FMT_YUYV422 }, |
2131
551f836ed80e
extending video4linux support to handle the additional formats UYVY, YUYV and RGB565
mhoffman
parents:
2130
diff
changeset
|
64 {.palette = VIDEO_PALETTE_UYVY, .depth = 16, .pix_fmt = PIX_FMT_UYVY422 }, |
551f836ed80e
extending video4linux support to handle the additional formats UYVY, YUYV and RGB565
mhoffman
parents:
2130
diff
changeset
|
65 {.palette = VIDEO_PALETTE_YUYV, .depth = 16, .pix_fmt = PIX_FMT_YUYV422 }, |
2130
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
66 /* NOTE: v4l uses BGR24, not RGB24 */ |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
67 {.palette = VIDEO_PALETTE_RGB24, .depth = 24, .pix_fmt = PIX_FMT_BGR24 }, |
2131
551f836ed80e
extending video4linux support to handle the additional formats UYVY, YUYV and RGB565
mhoffman
parents:
2130
diff
changeset
|
68 {.palette = VIDEO_PALETTE_RGB565, .depth = 16, .pix_fmt = PIX_FMT_BGR565 }, |
2130
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
69 {.palette = VIDEO_PALETTE_GREY, .depth = 8, .pix_fmt = PIX_FMT_GRAY8 }, |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
70 }; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
71 |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
72 |
0 | 73 static int aiw_init(VideoData *s); |
74 static int aiw_read_picture(VideoData *s, uint8_t *data); | |
75 static int aiw_close(VideoData *s); | |
76 | |
77 static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |
78 { | |
79 VideoData *s = s1->priv_data; | |
80 AVStream *st; | |
81 int width, height; | |
82 int video_fd, frame_size; | |
85
25062c9b1f86
per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents:
65
diff
changeset
|
83 int ret, frame_rate, frame_rate_base; |
1137 | 84 int desired_palette, desired_depth; |
159
7d698c3213a0
tv standard selection support for dv1394 and grab (v4l)
al3x
parents:
85
diff
changeset
|
85 struct video_tuner tuner; |
0 | 86 struct video_audio audio; |
1068
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
87 struct video_picture pict; |
451
31784bdb76ee
ring buffer fix by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
370
diff
changeset
|
88 int j; |
2130
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
89 int vformat_num = sizeof(video_formats) / sizeof(video_formats[0]); |
0 | 90 |
1012 | 91 if (ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0) { |
92 av_log(s1, AV_LOG_ERROR, "Bad capture size (%dx%d) or wrong time base (%d)\n", | |
93 ap->width, ap->height, ap->time_base.den); | |
94 | |
0 | 95 return -1; |
1012 | 96 } |
885 | 97 |
0 | 98 width = ap->width; |
99 height = ap->height; | |
743 | 100 frame_rate = ap->time_base.den; |
101 frame_rate_base = ap->time_base.num; | |
0 | 102 |
1012 | 103 if((unsigned)width > 32767 || (unsigned)height > 32767) { |
104 av_log(s1, AV_LOG_ERROR, "Capture size is out of range: %dx%d\n", | |
105 width, height); | |
106 | |
639 | 107 return -1; |
1012 | 108 } |
885 | 109 |
0 | 110 st = av_new_stream(s1, 0); |
111 if (!st) | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1760
diff
changeset
|
112 return AVERROR(ENOMEM); |
921 | 113 av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ |
0 | 114 |
115 s->width = width; | |
116 s->height = height; | |
85
25062c9b1f86
per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents:
65
diff
changeset
|
117 s->frame_rate = frame_rate; |
25062c9b1f86
per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents:
65
diff
changeset
|
118 s->frame_rate_base = frame_rate_base; |
0 | 119 |
1795
62792a60f740
implement new grabbing interface, as described here:
gpoirier
parents:
1787
diff
changeset
|
120 video_fd = open(s1->filename, O_RDWR); |
0 | 121 if (video_fd < 0) { |
1795
62792a60f740
implement new grabbing interface, as described here:
gpoirier
parents:
1787
diff
changeset
|
122 perror(s1->filename); |
0 | 123 goto fail; |
124 } | |
885 | 125 |
0 | 126 if (ioctl(video_fd,VIDIOCGCAP, &s->video_cap) < 0) { |
127 perror("VIDIOCGCAP"); | |
128 goto fail; | |
129 } | |
130 | |
131 if (!(s->video_cap.type & VID_TYPE_CAPTURE)) { | |
887 | 132 av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not handle capture\n"); |
0 | 133 goto fail; |
134 } | |
135 | |
136 desired_palette = -1; | |
1137 | 137 desired_depth = -1; |
2130
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
138 for (j = 0; j < vformat_num; j++) { |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
139 if (ap->pix_fmt == video_formats[j].pix_fmt) { |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
140 desired_palette = video_formats[j].palette; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
141 desired_depth = video_formats[j].depth; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
142 break; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
143 } |
885 | 144 } |
159
7d698c3213a0
tv standard selection support for dv1394 and grab (v4l)
al3x
parents:
85
diff
changeset
|
145 |
7d698c3213a0
tv standard selection support for dv1394 and grab (v4l)
al3x
parents:
85
diff
changeset
|
146 /* set tv standard */ |
7d698c3213a0
tv standard selection support for dv1394 and grab (v4l)
al3x
parents:
85
diff
changeset
|
147 if (ap->standard && !ioctl(video_fd, VIDIOCGTUNER, &tuner)) { |
887 | 148 if (!strcasecmp(ap->standard, "pal")) |
149 tuner.mode = VIDEO_MODE_PAL; | |
150 else if (!strcasecmp(ap->standard, "secam")) | |
151 tuner.mode = VIDEO_MODE_SECAM; | |
152 else | |
153 tuner.mode = VIDEO_MODE_NTSC; | |
154 ioctl(video_fd, VIDIOCSTUNER, &tuner); | |
159
7d698c3213a0
tv standard selection support for dv1394 and grab (v4l)
al3x
parents:
85
diff
changeset
|
155 } |
885 | 156 |
0 | 157 /* unmute audio */ |
158 audio.audio = 0; | |
159 ioctl(video_fd, VIDIOCGAUDIO, &audio); | |
160 memcpy(&s->audio_saved, &audio, sizeof(audio)); | |
161 audio.flags &= ~VIDEO_AUDIO_MUTE; | |
162 ioctl(video_fd, VIDIOCSAUDIO, &audio); | |
163 | |
1068
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
164 ioctl(video_fd, VIDIOCGPICT, &pict); |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
165 #if 0 |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
166 printf("v4l: colour=%d hue=%d brightness=%d constrast=%d whiteness=%d\n", |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
167 pict.colour, |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
168 pict.hue, |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
169 pict.brightness, |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
170 pict.contrast, |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
171 pict.whiteness); |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
172 #endif |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
173 /* try to choose a suitable video format */ |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
174 pict.palette = desired_palette; |
1137 | 175 pict.depth= desired_depth; |
1068
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
176 if (desired_palette == -1 || (ret = ioctl(video_fd, VIDIOCSPICT, &pict)) < 0) { |
2130
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
177 for (j = 0; j < vformat_num; j++) { |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
178 pict.palette = video_formats[j].palette; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
179 pict.depth = video_formats[j].depth; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
180 if (-1 != ioctl(video_fd, VIDIOCSPICT, &pict)) |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
181 break; |
1068
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
182 } |
2130
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
183 if (j >= vformat_num) |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
184 goto fail1; |
1068
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
185 } |
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
186 |
0 | 187 ret = ioctl(video_fd,VIDIOCGMBUF,&s->gb_buffers); |
188 if (ret < 0) { | |
189 /* try to use read based access */ | |
190 struct video_window win; | |
191 int val; | |
192 | |
193 win.x = 0; | |
194 win.y = 0; | |
195 win.width = width; | |
196 win.height = height; | |
197 win.chromakey = -1; | |
198 win.flags = 0; | |
199 | |
200 ioctl(video_fd, VIDIOCSWIN, &win); | |
201 | |
202 s->frame_format = pict.palette; | |
203 | |
204 val = 1; | |
205 ioctl(video_fd, VIDIOCCAPTURE, &val); | |
206 | |
455
e5174af0f52f
fix rounding errors with NTSC patch by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
451
diff
changeset
|
207 s->time_frame = av_gettime() * s->frame_rate / s->frame_rate_base; |
0 | 208 s->use_mmap = 0; |
885 | 209 |
0 | 210 /* ATI All In Wonder automatic activation */ |
211 if (!strcmp(s->video_cap.name, "Km")) { | |
212 if (aiw_init(s) < 0) | |
213 goto fail; | |
214 s->aiw_enabled = 1; | |
2268 | 215 /* force 420P format because conversion from YUV422 to YUV420P |
0 | 216 is done in this driver (ugly) */ |
217 s->frame_format = VIDEO_PALETTE_YUV420P; | |
218 } | |
219 } else { | |
220 s->video_buf = mmap(0,s->gb_buffers.size,PROT_READ|PROT_WRITE,MAP_SHARED,video_fd,0); | |
221 if ((unsigned char*)-1 == s->video_buf) { | |
1604
ec546897df3d
fall back mmap() call using MAP_PRIVATE for working on no-mmu systems
aurel
parents:
1556
diff
changeset
|
222 s->video_buf = mmap(0,s->gb_buffers.size,PROT_READ|PROT_WRITE,MAP_PRIVATE,video_fd,0); |
ec546897df3d
fall back mmap() call using MAP_PRIVATE for working on no-mmu systems
aurel
parents:
1556
diff
changeset
|
223 if ((unsigned char*)-1 == s->video_buf) { |
ec546897df3d
fall back mmap() call using MAP_PRIVATE for working on no-mmu systems
aurel
parents:
1556
diff
changeset
|
224 perror("mmap"); |
ec546897df3d
fall back mmap() call using MAP_PRIVATE for working on no-mmu systems
aurel
parents:
1556
diff
changeset
|
225 goto fail; |
ec546897df3d
fall back mmap() call using MAP_PRIVATE for working on no-mmu systems
aurel
parents:
1556
diff
changeset
|
226 } |
0 | 227 } |
228 s->gb_frame = 0; | |
455
e5174af0f52f
fix rounding errors with NTSC patch by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
451
diff
changeset
|
229 s->time_frame = av_gettime() * s->frame_rate / s->frame_rate_base; |
885 | 230 |
0 | 231 /* start to grab the first frame */ |
232 s->gb_buf.frame = s->gb_frame % s->gb_buffers.frames; | |
233 s->gb_buf.height = height; | |
234 s->gb_buf.width = width; | |
1068
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
235 s->gb_buf.format = pict.palette; |
885 | 236 |
1068
b14b8b976bce
Fix v4l grabbing with some webcams, and simplify the code.
lucabe
parents:
1012
diff
changeset
|
237 ret = ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf); |
0 | 238 if (ret < 0) { |
239 if (errno != EAGAIN) { | |
240 fail1: | |
370
845f9de2c883
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
236
diff
changeset
|
241 av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not support suitable format\n"); |
0 | 242 } else { |
370
845f9de2c883
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
236
diff
changeset
|
243 av_log(s1, AV_LOG_ERROR,"Fatal: grab device does not receive any video signal\n"); |
0 | 244 } |
245 goto fail; | |
246 } | |
887 | 247 for (j = 1; j < s->gb_buffers.frames; j++) { |
248 s->gb_buf.frame = j; | |
249 ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf); | |
250 } | |
0 | 251 s->frame_format = s->gb_buf.format; |
252 s->use_mmap = 1; | |
253 } | |
254 | |
2130
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
255 for (j = 0; j < vformat_num; j++) { |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
256 if (s->frame_format == video_formats[j].palette) { |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
257 frame_size = width * height * video_formats[j].depth / 8; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
258 st->codec->pix_fmt = video_formats[j].pix_fmt; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
259 break; |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
260 } |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
261 } |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
262 |
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
263 if (j >= vformat_num) |
0 | 264 goto fail; |
2130
861cfbc6297a
convert if then else video palette to pix_fmt construct to simpiler table based lookup.
mhoffman
parents:
2087
diff
changeset
|
265 |
0 | 266 s->fd = video_fd; |
267 s->frame_size = frame_size; | |
885 | 268 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
269 st->codec->codec_type = CODEC_TYPE_VIDEO; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
270 st->codec->codec_id = CODEC_ID_RAWVIDEO; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
271 st->codec->width = width; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
272 st->codec->height = height; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
273 st->codec->time_base.den = frame_rate; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
274 st->codec->time_base.num = frame_rate_base; |
861 | 275 st->codec->bit_rate = frame_size * 1/av_q2d(st->codec->time_base) * 8; |
0 | 276 |
277 return 0; | |
278 fail: | |
279 if (video_fd >= 0) | |
280 close(video_fd); | |
281 av_free(st); | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2268
diff
changeset
|
282 return AVERROR(EIO); |
0 | 283 } |
284 | |
65 | 285 static int v4l_mm_read_picture(VideoData *s, uint8_t *buf) |
0 | 286 { |
65 | 287 uint8_t *ptr; |
0 | 288 |
451
31784bdb76ee
ring buffer fix by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
370
diff
changeset
|
289 while (ioctl(s->fd, VIDIOCSYNC, &s->gb_frame) < 0 && |
31784bdb76ee
ring buffer fix by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
370
diff
changeset
|
290 (errno == EAGAIN || errno == EINTR)); |
31784bdb76ee
ring buffer fix by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
370
diff
changeset
|
291 |
31784bdb76ee
ring buffer fix by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
370
diff
changeset
|
292 ptr = s->video_buf + s->gb_buffers.offsets[s->gb_frame]; |
31784bdb76ee
ring buffer fix by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
370
diff
changeset
|
293 memcpy(buf, ptr, s->frame_size); |
31784bdb76ee
ring buffer fix by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
370
diff
changeset
|
294 |
0 | 295 /* Setup to capture the next frame */ |
451
31784bdb76ee
ring buffer fix by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
370
diff
changeset
|
296 s->gb_buf.frame = s->gb_frame; |
0 | 297 if (ioctl(s->fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) { |
298 if (errno == EAGAIN) | |
370
845f9de2c883
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
236
diff
changeset
|
299 av_log(NULL, AV_LOG_ERROR, "Cannot Sync\n"); |
0 | 300 else |
301 perror("VIDIOCMCAPTURE"); | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2268
diff
changeset
|
302 return AVERROR(EIO); |
0 | 303 } |
304 | |
305 /* This is now the grabbing frame */ | |
451
31784bdb76ee
ring buffer fix by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
370
diff
changeset
|
306 s->gb_frame = (s->gb_frame + 1) % s->gb_buffers.frames; |
0 | 307 |
308 return s->frame_size; | |
309 } | |
310 | |
311 static int grab_read_packet(AVFormatContext *s1, AVPacket *pkt) | |
312 { | |
313 VideoData *s = s1->priv_data; | |
65 | 314 int64_t curtime, delay; |
0 | 315 struct timespec ts; |
316 | |
317 /* Calculate the time of the next frame */ | |
1556 | 318 s->time_frame += INT64_C(1000000); |
0 | 319 |
320 /* wait based on the frame rate */ | |
321 for(;;) { | |
322 curtime = av_gettime(); | |
455
e5174af0f52f
fix rounding errors with NTSC patch by (Luca Abeni <lucabe72 at email dot it>)
michael
parents:
451
diff
changeset
|
323 delay = s->time_frame * s->frame_rate_base / s->frame_rate - curtime; |
0 | 324 if (delay <= 0) { |
1556 | 325 if (delay < INT64_C(-1000000) * s->frame_rate_base / s->frame_rate) { |
0 | 326 /* printf("grabbing is %d frames late (dropping)\n", (int) -(delay / 16666)); */ |
1556 | 327 s->time_frame += INT64_C(1000000); |
0 | 328 } |
329 break; | |
885 | 330 } |
0 | 331 ts.tv_sec = delay / 1000000; |
332 ts.tv_nsec = (delay % 1000000) * 1000; | |
333 nanosleep(&ts, NULL); | |
334 } | |
335 | |
336 if (av_new_packet(pkt, s->frame_size) < 0) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2268
diff
changeset
|
337 return AVERROR(EIO); |
0 | 338 |
921 | 339 pkt->pts = curtime; |
0 | 340 |
341 /* read one frame */ | |
342 if (s->aiw_enabled) { | |
343 return aiw_read_picture(s, pkt->data); | |
344 } else if (s->use_mmap) { | |
345 return v4l_mm_read_picture(s, pkt->data); | |
346 } else { | |
347 if (read(s->fd, pkt->data, pkt->size) != pkt->size) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2268
diff
changeset
|
348 return AVERROR(EIO); |
0 | 349 return s->frame_size; |
350 } | |
351 } | |
352 | |
353 static int grab_read_close(AVFormatContext *s1) | |
354 { | |
355 VideoData *s = s1->priv_data; | |
356 | |
357 if (s->aiw_enabled) | |
358 aiw_close(s); | |
359 | |
360 if (s->use_mmap) | |
361 munmap(s->video_buf, s->gb_buffers.size); | |
362 | |
363 /* mute audio. we must force it because the BTTV driver does not | |
364 return its state correctly */ | |
365 s->audio_saved.flags |= VIDEO_AUDIO_MUTE; | |
366 ioctl(s->fd, VIDIOCSAUDIO, &s->audio_saved); | |
367 | |
368 close(s->fd); | |
369 return 0; | |
370 } | |
371 | |
2526
7d80b6e8adec
Remove video_grab_ prefix from video_grab_{bktr,v4l}
ramiro
parents:
2274
diff
changeset
|
372 AVInputFormat v4l_demuxer = { |
27
fcdea3df94fe
dv patch by Max Krasnyansky (maxk at qualcomm dot com)
bellard
parents:
0
diff
changeset
|
373 "video4linux", |
0 | 374 "video grab", |
375 sizeof(VideoData), | |
376 NULL, | |
377 grab_read_header, | |
378 grab_read_packet, | |
379 grab_read_close, | |
380 .flags = AVFMT_NOFILE, | |
381 }; | |
382 | |
383 /* All in Wonder specific stuff */ | |
384 /* XXX: remove and merge in libavcodec/imgconvert.c */ | |
385 | |
386 static int aiw_init(VideoData *s) | |
387 { | |
388 int width, height; | |
389 | |
390 width = s->width; | |
391 height = s->height; | |
392 | |
393 if ((width == s->video_cap.maxwidth && height == s->video_cap.maxheight) || | |
394 (width == s->video_cap.maxwidth && height == s->video_cap.maxheight*2) || | |
395 (width == s->video_cap.maxwidth/2 && height == s->video_cap.maxheight)) { | |
885 | 396 |
0 | 397 s->deint=0; |
398 s->halfw=0; | |
399 if (height == s->video_cap.maxheight*2) s->deint=1; | |
400 if (width == s->video_cap.maxwidth/2) s->halfw=1; | |
401 } else { | |
370
845f9de2c883
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
236
diff
changeset
|
402 av_log(NULL, AV_LOG_ERROR, "\nIncorrect Grab Size Supplied - Supported Sizes Are:\n"); |
845f9de2c883
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
236
diff
changeset
|
403 av_log(NULL, AV_LOG_ERROR, " %dx%d %dx%d %dx%d\n\n", |
0 | 404 s->video_cap.maxwidth,s->video_cap.maxheight, |
405 s->video_cap.maxwidth,s->video_cap.maxheight*2, | |
406 s->video_cap.maxwidth/2,s->video_cap.maxheight); | |
407 goto fail; | |
408 } | |
409 | |
410 if (s->halfw == 0) { | |
411 s->src_mem = av_malloc(s->width*2); | |
412 } else { | |
413 s->src_mem = av_malloc(s->width*4); | |
414 } | |
415 if (!s->src_mem) goto fail; | |
416 | |
417 s->lum_m4_mem = av_malloc(s->width); | |
418 if (!s->lum_m4_mem) | |
419 goto fail; | |
420 return 0; | |
421 fail: | |
422 av_freep(&s->src_mem); | |
423 av_freep(&s->lum_m4_mem); | |
424 return -1; | |
425 } | |
426 | |
427 #ifdef HAVE_MMX | |
2087
fa4066708500
Drop unnecessary libavcodec/ prefix in #include path.
diego
parents:
1982
diff
changeset
|
428 #include "i386/mmx.h" |
0 | 429 |
430 #define LINE_WITH_UV \ | |
431 movq_m2r(ptr[0],mm0); \ | |
432 movq_m2r(ptr[8],mm1); \ | |
433 movq_r2r(mm0, mm4); \ | |
434 punpcklbw_r2r(mm1,mm0); \ | |
435 punpckhbw_r2r(mm1,mm4); \ | |
436 movq_r2r(mm0,mm5); \ | |
437 punpcklbw_r2r(mm4,mm0); \ | |
438 punpckhbw_r2r(mm4,mm5); \ | |
439 movq_r2r(mm0,mm1); \ | |
440 punpcklbw_r2r(mm5,mm1); \ | |
441 movq_r2m(mm1,lum[0]); \ | |
442 movq_m2r(ptr[16],mm2); \ | |
443 movq_m2r(ptr[24],mm1); \ | |
444 movq_r2r(mm2,mm4); \ | |
445 punpcklbw_r2r(mm1,mm2); \ | |
446 punpckhbw_r2r(mm1,mm4); \ | |
447 movq_r2r(mm2,mm3); \ | |
448 punpcklbw_r2r(mm4,mm2); \ | |
449 punpckhbw_r2r(mm4,mm3); \ | |
450 movq_r2r(mm2,mm1); \ | |
451 punpcklbw_r2r(mm3,mm1); \ | |
452 movq_r2m(mm1,lum[8]); \ | |
453 punpckhdq_r2r(mm2,mm0); \ | |
454 punpckhdq_r2r(mm3,mm5); \ | |
455 movq_r2m(mm0,cb[0]); \ | |
456 movq_r2m(mm5,cr[0]); | |
457 | |
458 #define LINE_NO_UV \ | |
459 movq_m2r(ptr[0],mm0);\ | |
460 movq_m2r(ptr[8],mm1);\ | |
461 movq_r2r(mm0, mm4);\ | |
462 punpcklbw_r2r(mm1,mm0); \ | |
463 punpckhbw_r2r(mm1,mm4);\ | |
464 movq_r2r(mm0,mm5);\ | |
465 punpcklbw_r2r(mm4,mm0);\ | |
466 punpckhbw_r2r(mm4,mm5);\ | |
467 movq_r2r(mm0,mm1);\ | |
468 punpcklbw_r2r(mm5,mm1);\ | |
469 movq_r2m(mm1,lum[0]);\ | |
470 movq_m2r(ptr[16],mm2);\ | |
471 movq_m2r(ptr[24],mm1);\ | |
472 movq_r2r(mm2,mm4);\ | |
473 punpcklbw_r2r(mm1,mm2);\ | |
474 punpckhbw_r2r(mm1,mm4);\ | |
475 movq_r2r(mm2,mm3);\ | |
476 punpcklbw_r2r(mm4,mm2);\ | |
477 punpckhbw_r2r(mm4,mm3);\ | |
478 movq_r2r(mm2,mm1);\ | |
479 punpcklbw_r2r(mm3,mm1);\ | |
480 movq_r2m(mm1,lum[8]); | |
481 | |
482 #define LINE_WITHUV_AVG \ | |
483 movq_m2r(ptr[0], mm0);\ | |
484 movq_m2r(ptr[8], mm1);\ | |
485 movq_r2r(mm0, mm4);\ | |
486 punpcklbw_r2r(mm1,mm0);\ | |
487 punpckhbw_r2r(mm1,mm4);\ | |
488 movq_r2r(mm0,mm5);\ | |
489 punpcklbw_r2r(mm4,mm0);\ | |
490 punpckhbw_r2r(mm4,mm5);\ | |
491 movq_r2r(mm0,mm1);\ | |
492 movq_r2r(mm5,mm2);\ | |
493 punpcklbw_r2r(mm7,mm1);\ | |
494 punpcklbw_r2r(mm7,mm2);\ | |
495 paddw_r2r(mm6,mm1);\ | |
496 paddw_r2r(mm2,mm1);\ | |
497 psraw_i2r(1,mm1);\ | |
498 packuswb_r2r(mm7,mm1);\ | |
499 movd_r2m(mm1,lum[0]);\ | |
500 movq_m2r(ptr[16],mm2);\ | |
501 movq_m2r(ptr[24],mm1);\ | |
502 movq_r2r(mm2,mm4);\ | |
503 punpcklbw_r2r(mm1,mm2);\ | |
504 punpckhbw_r2r(mm1,mm4);\ | |
505 movq_r2r(mm2,mm3);\ | |
506 punpcklbw_r2r(mm4,mm2);\ | |
507 punpckhbw_r2r(mm4,mm3);\ | |
508 movq_r2r(mm2,mm1);\ | |
509 movq_r2r(mm3,mm4);\ | |
510 punpcklbw_r2r(mm7,mm1);\ | |
511 punpcklbw_r2r(mm7,mm4);\ | |
512 paddw_r2r(mm6,mm1);\ | |
513 paddw_r2r(mm4,mm1);\ | |
514 psraw_i2r(1,mm1);\ | |
515 packuswb_r2r(mm7,mm1);\ | |
516 movd_r2m(mm1,lum[4]);\ | |
517 punpckhbw_r2r(mm7,mm0);\ | |
518 punpckhbw_r2r(mm7,mm2);\ | |
519 paddw_r2r(mm6,mm0);\ | |
520 paddw_r2r(mm2,mm0);\ | |
521 psraw_i2r(1,mm0);\ | |
522 packuswb_r2r(mm7,mm0);\ | |
523 punpckhbw_r2r(mm7,mm5);\ | |
524 punpckhbw_r2r(mm7,mm3);\ | |
525 paddw_r2r(mm6,mm5);\ | |
526 paddw_r2r(mm3,mm5);\ | |
527 psraw_i2r(1,mm5);\ | |
528 packuswb_r2r(mm7,mm5);\ | |
529 movd_r2m(mm0,cb[0]);\ | |
530 movd_r2m(mm5,cr[0]); | |
531 | |
532 #define LINE_NOUV_AVG \ | |
533 movq_m2r(ptr[0],mm0);\ | |
534 movq_m2r(ptr[8],mm1);\ | |
535 pand_r2r(mm5,mm0);\ | |
536 pand_r2r(mm5,mm1);\ | |
537 pmaddwd_r2r(mm6,mm0);\ | |
538 pmaddwd_r2r(mm6,mm1);\ | |
539 packssdw_r2r(mm1,mm0);\ | |
540 paddw_r2r(mm6,mm0);\ | |
541 psraw_i2r(1,mm0);\ | |
542 movq_m2r(ptr[16],mm2);\ | |
543 movq_m2r(ptr[24],mm3);\ | |
544 pand_r2r(mm5,mm2);\ | |
545 pand_r2r(mm5,mm3);\ | |
546 pmaddwd_r2r(mm6,mm2);\ | |
547 pmaddwd_r2r(mm6,mm3);\ | |
548 packssdw_r2r(mm3,mm2);\ | |
549 paddw_r2r(mm6,mm2);\ | |
550 psraw_i2r(1,mm2);\ | |
551 packuswb_r2r(mm2,mm0);\ | |
552 movq_r2m(mm0,lum[0]); | |
553 | |
554 #define DEINT_LINE_LUM(ptroff) \ | |
555 movd_m2r(lum_m4[(ptroff)],mm0);\ | |
556 movd_m2r(lum_m3[(ptroff)],mm1);\ | |
557 movd_m2r(lum_m2[(ptroff)],mm2);\ | |
558 movd_m2r(lum_m1[(ptroff)],mm3);\ | |
559 movd_m2r(lum[(ptroff)],mm4);\ | |
560 punpcklbw_r2r(mm7,mm0);\ | |
561 movd_r2m(mm2,lum_m4[(ptroff)]);\ | |
562 punpcklbw_r2r(mm7,mm1);\ | |
563 punpcklbw_r2r(mm7,mm2);\ | |
564 punpcklbw_r2r(mm7,mm3);\ | |
565 punpcklbw_r2r(mm7,mm4);\ | |
566 psllw_i2r(2,mm1);\ | |
567 psllw_i2r(1,mm2);\ | |
568 paddw_r2r(mm6,mm1);\ | |
569 psllw_i2r(2,mm3);\ | |
570 paddw_r2r(mm2,mm1);\ | |
571 paddw_r2r(mm4,mm0);\ | |
572 paddw_r2r(mm3,mm1);\ | |
573 psubusw_r2r(mm0,mm1);\ | |
574 psrlw_i2r(3,mm1);\ | |
575 packuswb_r2r(mm7,mm1);\ | |
576 movd_r2m(mm1,lum_m2[(ptroff)]); | |
577 | |
578 #else | |
2087
fa4066708500
Drop unnecessary libavcodec/ prefix in #include path.
diego
parents:
1982
diff
changeset
|
579 #include "dsputil.h" |
0 | 580 |
581 #define LINE_WITH_UV \ | |
582 lum[0]=ptr[0];lum[1]=ptr[2];lum[2]=ptr[4];lum[3]=ptr[6];\ | |
583 cb[0]=ptr[1];cb[1]=ptr[5];\ | |
584 cr[0]=ptr[3];cr[1]=ptr[7];\ | |
585 lum[4]=ptr[8];lum[5]=ptr[10];lum[6]=ptr[12];lum[7]=ptr[14];\ | |
586 cb[2]=ptr[9];cb[3]=ptr[13];\ | |
587 cr[2]=ptr[11];cr[3]=ptr[15];\ | |
588 lum[8]=ptr[16];lum[9]=ptr[18];lum[10]=ptr[20];lum[11]=ptr[22];\ | |
589 cb[4]=ptr[17];cb[5]=ptr[21];\ | |
590 cr[4]=ptr[19];cr[5]=ptr[23];\ | |
591 lum[12]=ptr[24];lum[13]=ptr[26];lum[14]=ptr[28];lum[15]=ptr[30];\ | |
592 cb[6]=ptr[25];cb[7]=ptr[29];\ | |
593 cr[6]=ptr[27];cr[7]=ptr[31]; | |
594 | |
595 #define LINE_NO_UV \ | |
596 lum[0]=ptr[0];lum[1]=ptr[2];lum[2]=ptr[4];lum[3]=ptr[6];\ | |
597 lum[4]=ptr[8];lum[5]=ptr[10];lum[6]=ptr[12];lum[7]=ptr[14];\ | |
598 lum[8]=ptr[16];lum[9]=ptr[18];lum[10]=ptr[20];lum[11]=ptr[22];\ | |
599 lum[12]=ptr[24];lum[13]=ptr[26];lum[14]=ptr[28];lum[15]=ptr[30]; | |
600 | |
601 #define LINE_WITHUV_AVG \ | |
602 sum=(ptr[0]+ptr[2]+1) >> 1;lum[0]=sum; \ | |
603 sum=(ptr[4]+ptr[6]+1) >> 1;lum[1]=sum; \ | |
604 sum=(ptr[1]+ptr[5]+1) >> 1;cb[0]=sum; \ | |
605 sum=(ptr[3]+ptr[7]+1) >> 1;cr[0]=sum; \ | |
606 sum=(ptr[8]+ptr[10]+1) >> 1;lum[2]=sum; \ | |
607 sum=(ptr[12]+ptr[14]+1) >> 1;lum[3]=sum; \ | |
608 sum=(ptr[9]+ptr[13]+1) >> 1;cb[1]=sum; \ | |
609 sum=(ptr[11]+ptr[15]+1) >> 1;cr[1]=sum; \ | |
610 sum=(ptr[16]+ptr[18]+1) >> 1;lum[4]=sum; \ | |
611 sum=(ptr[20]+ptr[22]+1) >> 1;lum[5]=sum; \ | |
612 sum=(ptr[17]+ptr[21]+1) >> 1;cb[2]=sum; \ | |
613 sum=(ptr[19]+ptr[23]+1) >> 1;cr[2]=sum; \ | |
614 sum=(ptr[24]+ptr[26]+1) >> 1;lum[6]=sum; \ | |
615 sum=(ptr[28]+ptr[30]+1) >> 1;lum[7]=sum; \ | |
616 sum=(ptr[25]+ptr[29]+1) >> 1;cb[3]=sum; \ | |
885 | 617 sum=(ptr[27]+ptr[31]+1) >> 1;cr[3]=sum; |
0 | 618 |
619 #define LINE_NOUV_AVG \ | |
620 sum=(ptr[0]+ptr[2]+1) >> 1;lum[0]=sum; \ | |
621 sum=(ptr[4]+ptr[6]+1) >> 1;lum[1]=sum; \ | |
622 sum=(ptr[8]+ptr[10]+1) >> 1;lum[2]=sum; \ | |
623 sum=(ptr[12]+ptr[14]+1) >> 1;lum[3]=sum; \ | |
624 sum=(ptr[16]+ptr[18]+1) >> 1;lum[4]=sum; \ | |
625 sum=(ptr[20]+ptr[22]+1) >> 1;lum[5]=sum; \ | |
626 sum=(ptr[24]+ptr[26]+1) >> 1;lum[6]=sum; \ | |
885 | 627 sum=(ptr[28]+ptr[30]+1) >> 1;lum[7]=sum; |
0 | 628 |
629 #define DEINT_LINE_LUM(ptroff) \ | |
630 sum=(-lum_m4[(ptroff)]+(lum_m3[(ptroff)]<<2)+(lum_m2[(ptroff)]<<1)+(lum_m1[(ptroff)]<<2)-lum[(ptroff)]); \ | |
631 lum_m4[(ptroff)]=lum_m2[(ptroff)];\ | |
632 lum_m2[(ptroff)]=cm[(sum+4)>>3];\ | |
633 sum=(-lum_m4[(ptroff)+1]+(lum_m3[(ptroff)+1]<<2)+(lum_m2[(ptroff)+1]<<1)+(lum_m1[(ptroff)+1]<<2)-lum[(ptroff)+1]); \ | |
634 lum_m4[(ptroff)+1]=lum_m2[(ptroff)+1];\ | |
635 lum_m2[(ptroff)+1]=cm[(sum+4)>>3];\ | |
636 sum=(-lum_m4[(ptroff)+2]+(lum_m3[(ptroff)+2]<<2)+(lum_m2[(ptroff)+2]<<1)+(lum_m1[(ptroff)+2]<<2)-lum[(ptroff)+2]); \ | |
637 lum_m4[(ptroff)+2]=lum_m2[(ptroff)+2];\ | |
638 lum_m2[(ptroff)+2]=cm[(sum+4)>>3];\ | |
639 sum=(-lum_m4[(ptroff)+3]+(lum_m3[(ptroff)+3]<<2)+(lum_m2[(ptroff)+3]<<1)+(lum_m1[(ptroff)+3]<<2)-lum[(ptroff)+3]); \ | |
640 lum_m4[(ptroff)+3]=lum_m2[(ptroff)+3];\ | |
641 lum_m2[(ptroff)+3]=cm[(sum+4)>>3]; | |
642 | |
643 #endif | |
644 | |
645 | |
646 /* Read two fields separately. */ | |
647 static int aiw_read_picture(VideoData *s, uint8_t *data) | |
648 { | |
65 | 649 uint8_t *ptr, *lum, *cb, *cr; |
0 | 650 int h; |
651 #ifndef HAVE_MMX | |
652 int sum; | |
653 #endif | |
65 | 654 uint8_t* src = s->src_mem; |
655 uint8_t *ptrend = &src[s->width*2]; | |
0 | 656 lum=data; |
657 cb=&lum[s->width*s->height]; | |
658 cr=&cb[(s->width*s->height)/4]; | |
659 if (s->deint == 0 && s->halfw == 0) { | |
660 while (read(s->fd,src,s->width*2) < 0) { | |
661 usleep(100); | |
662 } | |
663 for (h = 0; h < s->height-2; h+=2) { | |
664 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { | |
665 LINE_WITH_UV | |
666 } | |
667 read(s->fd,src,s->width*2); | |
668 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16) { | |
669 LINE_NO_UV | |
670 } | |
671 read(s->fd,src,s->width*2); | |
672 } | |
673 /* | |
674 * Do last two lines | |
675 */ | |
676 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { | |
677 LINE_WITH_UV | |
678 } | |
679 read(s->fd,src,s->width*2); | |
680 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16) { | |
681 LINE_NO_UV | |
682 } | |
683 /* drop second field */ | |
684 while (read(s->fd,src,s->width*2) < 0) { | |
685 usleep(100); | |
686 } | |
687 for (h = 0; h < s->height - 1; h++) { | |
688 read(s->fd,src,s->width*2); | |
689 } | |
690 } else if (s->halfw == 1) { | |
691 #ifdef HAVE_MMX | |
692 mmx_t rounder; | |
693 mmx_t masker; | |
694 rounder.uw[0]=1; | |
695 rounder.uw[1]=1; | |
696 rounder.uw[2]=1; | |
697 rounder.uw[3]=1; | |
698 masker.ub[0]=0xff; | |
699 masker.ub[1]=0; | |
700 masker.ub[2]=0xff; | |
701 masker.ub[3]=0; | |
702 masker.ub[4]=0xff; | |
703 masker.ub[5]=0; | |
704 masker.ub[6]=0xff; | |
705 masker.ub[7]=0; | |
706 pxor_r2r(mm7,mm7); | |
707 movq_m2r(rounder,mm6); | |
708 #endif | |
709 while (read(s->fd,src,s->width*4) < 0) { | |
710 usleep(100); | |
711 } | |
712 ptrend = &src[s->width*4]; | |
713 for (h = 0; h < s->height-2; h+=2) { | |
714 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8, cb+=4, cr+=4) { | |
715 LINE_WITHUV_AVG | |
716 } | |
717 read(s->fd,src,s->width*4); | |
718 #ifdef HAVE_MMX | |
719 movq_m2r(masker,mm5); | |
720 #endif | |
721 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8) { | |
722 LINE_NOUV_AVG | |
723 } | |
724 read(s->fd,src,s->width*4); | |
725 } | |
726 /* | |
727 * Do last two lines | |
728 */ | |
729 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8, cb+=4, cr+=4) { | |
730 LINE_WITHUV_AVG | |
731 } | |
732 read(s->fd,src,s->width*4); | |
733 #ifdef HAVE_MMX | |
734 movq_m2r(masker,mm5); | |
735 #endif | |
736 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8) { | |
737 LINE_NOUV_AVG | |
738 } | |
739 /* drop second field */ | |
740 while (read(s->fd,src,s->width*4) < 0) { | |
741 usleep(100); | |
742 } | |
743 for (h = 0; h < s->height - 1; h++) { | |
744 read(s->fd,src,s->width*4); | |
745 } | |
746 } else { | |
65 | 747 uint8_t *lum_m1, *lum_m2, *lum_m3, *lum_m4; |
0 | 748 #ifdef HAVE_MMX |
749 mmx_t rounder; | |
750 rounder.uw[0]=4; | |
751 rounder.uw[1]=4; | |
752 rounder.uw[2]=4; | |
753 rounder.uw[3]=4; | |
754 movq_m2r(rounder,mm6); | |
755 pxor_r2r(mm7,mm7); | |
756 #else | |
1491 | 757 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; |
0 | 758 #endif |
759 | |
760 /* read two fields and deinterlace them */ | |
761 while (read(s->fd,src,s->width*2) < 0) { | |
762 usleep(100); | |
763 } | |
764 for (h = 0; h < (s->height/2)-2; h+=2) { | |
765 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { | |
766 LINE_WITH_UV | |
767 } | |
768 read(s->fd,src,s->width*2); | |
769 /* skip a luminance line - will be filled in later */ | |
770 lum += s->width; | |
771 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { | |
772 LINE_WITH_UV | |
773 } | |
774 /* skip a luminance line - will be filled in later */ | |
775 lum += s->width; | |
776 read(s->fd,src,s->width*2); | |
777 } | |
778 /* | |
779 * Do last two lines | |
780 */ | |
781 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { | |
782 LINE_WITH_UV | |
783 } | |
784 /* skip a luminance line - will be filled in later */ | |
785 lum += s->width; | |
786 read(s->fd,src,s->width*2); | |
787 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { | |
788 LINE_WITH_UV | |
789 } | |
790 /* | |
791 * | |
792 * SECOND FIELD | |
793 * | |
794 */ | |
795 lum=&data[s->width]; | |
796 while (read(s->fd,src,s->width*2) < 0) { | |
797 usleep(10); | |
798 } | |
799 /* First (and last) two lines not interlaced */ | |
800 for (h = 0; h < 2; h++) { | |
801 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16) { | |
802 LINE_NO_UV | |
803 } | |
804 read(s->fd,src,s->width*2); | |
805 /* skip a luminance line */ | |
806 lum += s->width; | |
807 } | |
808 lum_m1=&lum[-s->width]; | |
809 lum_m2=&lum_m1[-s->width]; | |
810 lum_m3=&lum_m2[-s->width]; | |
811 memmove(s->lum_m4_mem,&lum_m3[-s->width],s->width); | |
812 for (; h < (s->height/2)-1; h++) { | |
813 lum_m4=s->lum_m4_mem; | |
814 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16,lum_m1+=16,lum_m2+=16,lum_m3+=16,lum_m4+=16) { | |
815 LINE_NO_UV | |
816 | |
817 DEINT_LINE_LUM(0) | |
818 DEINT_LINE_LUM(4) | |
819 DEINT_LINE_LUM(8) | |
820 DEINT_LINE_LUM(12) | |
821 } | |
822 read(s->fd,src,s->width*2); | |
823 /* skip a luminance line */ | |
824 lum += s->width; | |
825 lum_m1 += s->width; | |
826 lum_m2 += s->width; | |
827 lum_m3 += s->width; | |
828 // lum_m4 += s->width; | |
829 } | |
830 /* | |
831 * Do last line | |
832 */ | |
833 lum_m4=s->lum_m4_mem; | |
834 for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, lum_m1+=16, lum_m2+=16, lum_m3+=16, lum_m4+=16) { | |
835 LINE_NO_UV | |
836 | |
837 DEINT_LINE_LUM(0) | |
838 DEINT_LINE_LUM(4) | |
839 DEINT_LINE_LUM(8) | |
840 DEINT_LINE_LUM(12) | |
841 } | |
842 } | |
2152
5493fd53a671
emms --> emms_c, patch by Ronald S. Bultje, rbultje ronald.bitfreak net
diego
parents:
2131
diff
changeset
|
843 emms_c(); |
0 | 844 return s->frame_size; |
845 } | |
846 | |
847 static int aiw_close(VideoData *s) | |
848 { | |
849 av_freep(&s->lum_m4_mem); | |
850 av_freep(&s->src_mem); | |
851 return 0; | |
852 } |