comparison libvo/vo_dxr3.c @ 4218:3931c41f740a

Added new syncengine thanks to a new previously undocumented feature of the em8300, this might fix playback on both slow and fast machines (more testing needed). This also requires users to get the em8300 driver from cvs until the next version is released (will probably happen this weekend) Added lots of comments, should be pretty easy to understand most of the internals now Added lots of brackets to if's for's while's etc, this is not a cosmetical thing but rather due to the fact I got some very odd bugs with else's since I didn't properly use brackets (and it's the K&R standard to have brackets everywhere) Fixed some bugs that would occur when disabling libmp1e Switched to default to the new naming scheme of device nodes, the driver will slowly switch over to this state, if it can't find devices under the new name it will try the old naming scheme I stopped opening devices in non-blocking mode, it would break the new syncengine which tries to burst data to the device (alot of times meaning it will fill the fifo pretty fast which would previously result in jerkyness on fast machines) The device now sets the initial state of the pts and speed (probably not needed, but assumption is the mother of all fuckups =) Keep the control interface open during the entire duration of the libvo device, we might need this to flush video buffers on seeking (currently not implemented, therefore seeking is broken) This is beta stuff to the driver, I will get some users to test it for me and do my best to fix seeking as soon as possible...
author mswitch
date Thu, 17 Jan 2002 10:33:47 +0000
parents a5ce64929fac
children 70888f501b4a
comparison
equal deleted inserted replaced
4217:2b141fcd69dd 4218:3931c41f740a
4 * Copyright (C) 2002 David Holm <dholm@iname.com> 4 * Copyright (C) 2002 David Holm <dholm@iname.com>
5 * 5 *
6 */ 6 */
7 7
8 /* ChangeLog added 2002-01-10 8 /* ChangeLog added 2002-01-10
9 * 2002-01-17:
10 * Testrelease of new sync engine (using previously undocumented feature of em8300). Seeking does not work with this one!
11 *
12 * 2002-01-15:
13 * Preliminary subpic support with -vc mpegpes and dvd's
14 * Device interfaces tries the new naming scheme by default (even though most users probably still use the old one)
15 *
9 * 2002-01-10: 16 * 2002-01-10:
10 * I rehauled the entire codebase. I have now changed to 17 * I rehauled the entire codebase. I have now changed to
11 * Kernighan & Ritchie codingstyle, please mail me if you 18 * Kernighan & Ritchie codingstyle, please mail me if you
12 * find any inconcistencies. 19 * find any inconcistencies.
13 */ 20 */
41 48
42 LIBVO_EXTERN (dxr3) 49 LIBVO_EXTERN (dxr3)
43 50
44 #ifdef USE_MP1E 51 #ifdef USE_MP1E
45 /* libmp1e specific stuff */ 52 /* libmp1e specific stuff */
46 rte_context *mp1e_context = NULL; 53 static rte_context *mp1e_context = NULL;
47 rte_codec *mp1e_codec = NULL; 54 static rte_codec *mp1e_codec = NULL;
48 rte_buffer mp1e_buffer; 55 static rte_buffer mp1e_buffer;
49 #endif
50 56
51 /* Color buffer data used with libmp1e */ 57 /* Color buffer data used with libmp1e */
52 static unsigned char *picture_data[3]; 58 static unsigned char *picture_data[3];
53 static unsigned int picture_linesize[3]; 59 static int picture_linesize[3];
60 #endif
54 61
55 /* Resolutions and positions */ 62 /* Resolutions and positions */
56 static int v_width, v_height; 63 static int v_width, v_height;
57 static int s_width, s_height; 64 static int s_width, s_height;
58 static int s_pos_x, s_pos_y; 65 static int s_pos_x, s_pos_y;
76 "David Holm <dholm@iname.com>", 83 "David Holm <dholm@iname.com>",
77 "" 84 ""
78 }; 85 };
79 86
80 #ifdef USE_MP1E 87 #ifdef USE_MP1E
81 void write_dxr3(rte_context* context, void* data, size_t size, void* user_data) 88 void write_dxr3(rte_context *context, void *data, size_t size, void *user_data)
82 { 89 {
83 size_t data_left = size; 90 size_t data_left = size;
84 /* Set the timestamp of the next video packet */ 91 /* Set the timestamp of the next video packet */
85 if (ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts) < 0) 92 if (ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts) < 0) {
86 printf("VO: [dxr3] Unable to set pts\n"); 93 printf("VO: [dxr3] Unable to set pts\n");
87 94 }
88 /* Write the entire video packet */ 95
89 while (data_left) 96 /* Force data into the buffer */
97 while (data_left) {
90 data_left -= write(fd_video, (void*) data + (size - data_left), data_left); 98 data_left -= write(fd_video, (void*) data + (size - data_left), data_left);
91 } 99 }
92 #endif 100 }
93 101 #endif
94 extern int vidmode;
95 102
96 static uint32_t init(uint32_t scr_width, uint32_t scr_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format) 103 static uint32_t init(uint32_t scr_width, uint32_t scr_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format)
97 { 104 {
98 int tmp1,tmp2; 105 int tmp1, tmp2;
106 em8300_register_t reg;
99 char devname[80]; 107 char devname[80];
100 108
101 /* Open the control interface */ 109 /* Open the control interface */
102 if (vo_subdevice) 110 if (vo_subdevice) {
103 sprintf(devname, "/dev/em8300-%s", vo_subdevice); 111 sprintf(devname, "/dev/em8300-%s", vo_subdevice);
104 else 112 } else {
105 sprintf(devname, "/dev/em8300"); 113 /* Try new naming scheme by default */
114 sprintf(devname, "/dev/em8300-0");
115 }
106 fd_control = open(devname, O_WRONLY); 116 fd_control = open(devname, O_WRONLY);
107 if (fd_control < 1) { 117 if (fd_control < 1) {
108 printf("VO: [dxr3] Error opening %s for writing!\n", devname); 118 /* Fall back to old naming scheme */
109 return -1; 119 printf("VO: [dxr3] Error opening %s for writing, trying /dev/em8300 instead\n", devname);
110 } 120 sprintf(devname, "/dev/em8300");
111 121 fd_control = open(devname, O_WRONLY);
112 /* Open the video packet interface */ 122 if (fd_control < 1) {
113 if (vo_subdevice) 123 printf("VO: [dxr3] Error opening /dev/em8300 for writing as well!\nBailing\n");
124 return -1;
125 }
126 }
127
128 /* Open the video interface */
129 if (vo_subdevice) {
114 sprintf(devname, "/dev/em8300_mv-%s", vo_subdevice); 130 sprintf(devname, "/dev/em8300_mv-%s", vo_subdevice);
115 else 131 } else {
132 /* Try new naming scheme by default */
133 sprintf(devname, "/dev/em8300_mv-0");
134 }
135 fd_video = open(devname, O_WRONLY);
136 if (fd_video < 0) {
137 /* Fall back to old naming scheme */
138 printf("VO: [dxr3] Error opening %s for writing, trying /dev/em8300_mv instead\n", devname);
116 sprintf(devname, "/dev/em8300_mv"); 139 sprintf(devname, "/dev/em8300_mv");
117 fd_video = open(devname, O_WRONLY | O_NONBLOCK); 140 fd_video = open(devname, O_WRONLY);
118 if (fd_video < 0) { 141 if (fd_video < 0) {
119 printf("VO: [dxr3] Error opening %s for writing!\n", devname); 142 printf("VO: [dxr3] Error opening /dev/em8300_mv for writing as well!\nBailing\n");
120 uninit(); 143 uninit();
121 return -1; 144 return -1;
122 } else 145 }
146 } else {
123 printf("VO: [dxr3] Opened %s\n", devname); 147 printf("VO: [dxr3] Opened %s\n", devname);
124 148 }
125 /* Open the subpicture packet interface */ 149
126 if (vo_subdevice) 150 /* Open the subpicture interface */
151 if (vo_subdevice) {
127 sprintf(devname, "/dev/em8300_sp-%s", vo_subdevice); 152 sprintf(devname, "/dev/em8300_sp-%s", vo_subdevice);
128 else 153 } else {
129 sprintf(devname, "/dev/em8300_sp"); 154 /* Try new naming scheme by default */
155 sprintf(devname, "/dev/em8300_sp-0");
156 }
130 fd_spu = open(devname, O_WRONLY); 157 fd_spu = open(devname, O_WRONLY);
131 if (fd_spu < 0) { 158 if (fd_spu < 0) {
132 printf("VO: [dxr3] Error opening %s for writing!\n", devname); 159 /* Fall back to old naming scheme */
133 uninit(); 160 printf("VO: [dxr3] Error opening %s for writing, trying /dev/em8300_sp instead\n", devname);
134 return -1; 161 sprintf(devname, "/dev/em8300_sp");
162 fd_spu = open(devname, O_WRONLY);
163 if (fd_spu < 0) {
164 printf("VO: [dxr3] Error opening /dev/em8300_sp for writing as well!\nBailing\n");
165 uninit();
166 return -1;
167 }
135 } 168 }
136 169
137 /* Subpic code isn't working yet, don't set to ON 170 /* This activates the subpicture processor, you can safely disable this and still send */
138 * unless you are really sure what you are doing 171 /* broken subpics to the em8300, if it's enabled and you send broken subpics you will end */
139 */ 172 /* up in a lockup */
140 ioval = EM8300_SPUMODE_ON; 173 ioval = EM8300_SPUMODE_ON;
141 if (ioctl(fd_control, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) { 174 if (ioctl(fd_control, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) {
142 printf("VO: [dxr3] Unable to set subpicture mode!\n"); 175 printf("VO: [dxr3] Unable to set subpicture mode!\n");
143 uninit(); 176 uninit();
144 return -1; 177 return -1;
145 } 178 }
146 179
147 /* Set the playmode to play (just in case another app has set it to something else) */ 180 /* Set the playmode to play (just in case another app has set it to something else) */
148 ioval = EM8300_PLAYMODE_PLAY; 181 ioval = EM8300_PLAYMODE_PLAY;
149 if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) 182 if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) {
150 printf("VO: [dxr3] Unable to set playmode!\n"); 183 printf("VO: [dxr3] Unable to set playmode!\n");
151 184 }
185
186 /* Set start pts and speed */
187 ioctl(fd_control, EM8300_IOCTL_SCR_SET, &vo_pts);
188 ioval = 0x900;
189 ioctl(fd_control, EM8300_IOCTL_SCR_SETSPEED, &ioval);
190 /* Start em8300 prebuffering and sync engine */
191 reg.microcode_register = 1;
192 reg.reg = 0;
193 reg.val = MVCOMMAND_SYNC;
194 ioctl(fd_control, EM8300_IOCTL_WRITEREG, &reg);
195
196 /* Store some variables statically that we need later in another scope */
152 img_format = format; 197 img_format = format;
153 v_width = scr_width; 198 v_width = scr_width;
154 v_height = scr_height; 199 v_height = scr_height;
155 200
156 /* libmp1e requires a width and height that is x|16 */ 201 /* libmp1e requires a width and height that is x|16 */
158 s_width *= 16; 203 s_width *= 16;
159 s_height = (v_height + 15) / 16; 204 s_height = (v_height + 15) / 16;
160 s_height *= 16; 205 s_height *= 16;
161 206
162 /* Try to figure out whether to use widescreen output or not */ 207 /* Try to figure out whether to use widescreen output or not */
208 /* Anamorphic widescreen modes makes this a pain in the ass */
163 tmp1 = abs(height - ((width / 4) * 3)); 209 tmp1 = abs(height - ((width / 4) * 3));
164 tmp2 = abs(height - (int) (width / 2.35)); 210 tmp2 = abs(height - (int) (width / 2.35));
165 if (tmp1 < tmp2) { 211 if (tmp1 < tmp2) {
166 ioval = EM8300_ASPECTRATIO_4_3; 212 ioval = EM8300_ASPECTRATIO_4_3;
167 printf("VO: [dxr3] Setting aspect ratio to 4:3\n"); 213 printf("VO: [dxr3] Setting aspect ratio to 4:3\n");
168 } else { 214 } else {
169 ioval = EM8300_ASPECTRATIO_16_9; 215 ioval = EM8300_ASPECTRATIO_16_9;
170 printf("VO: [dxr3] Setting aspect ratio to 16:9\n"); 216 printf("VO: [dxr3] Setting aspect ratio to 16:9\n");
171 } 217 }
172 ioctl(fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &ioval); 218 ioctl(fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &ioval);
173 close(fd_control);
174 219
175 if (format == IMGFMT_YV12 || format == IMGFMT_YUY2 || format == IMGFMT_BGR24) { 220 if (format == IMGFMT_YV12 || format == IMGFMT_YUY2 || format == IMGFMT_BGR24) {
176 #ifdef USE_MP1E 221 #ifdef USE_MP1E
177 int size; 222 int size;
178 enum rte_frame_rate frame_rate; 223 enum rte_frame_rate frame_rate;
194 printf( "VO: [dxr3] Unable to create context!\n" ); 239 printf( "VO: [dxr3] Unable to create context!\n" );
195 uninit(); 240 uninit();
196 return -1; 241 return -1;
197 } 242 }
198 243
244 /* I wonder if we could benefit from using mpeg2 em8300-wise (hardware processing) */
199 if (!rte_set_format(mp1e_context, "mpeg1")) { 245 if (!rte_set_format(mp1e_context, "mpeg1")) {
200 printf("VO: [dxr3] Unable to set format\n"); 246 printf("VO: [dxr3] Unable to set format\n");
201 uninit(); 247 uninit();
202 return -1; 248 return -1;
203 } 249 }
204 250
205 rte_set_mode(mp1e_context, RTE_VIDEO); 251 rte_set_mode(mp1e_context, RTE_VIDEO);
206 mp1e_codec = rte_codec_set(mp1e_context, RTE_STREAM_VIDEO, 0, "mpeg1-video"); 252 mp1e_codec = rte_codec_set(mp1e_context, RTE_STREAM_VIDEO, 0, "mpeg1-video");
207 253
208 if (vo_fps < 24.0) 254 if (vo_fps < 24.0) {
209 frame_rate = RTE_RATE_1; 255 frame_rate = RTE_RATE_1;
210 else if (vo_fps < 25.0) 256 } else if (vo_fps < 25.0) {
211 frame_rate = RTE_RATE_2; 257 frame_rate = RTE_RATE_2;
212 else if (vo_fps < 29.97) 258 } else if (vo_fps < 29.97) {
213 frame_rate = RTE_RATE_3; 259 frame_rate = RTE_RATE_3;
214 else if (vo_fps < 30.0) 260 } else if (vo_fps < 30.0) {
215 frame_rate = RTE_RATE_4; 261 frame_rate = RTE_RATE_4;
216 else if (vo_fps < 50.0) 262 } else if (vo_fps < 50.0) {
217 frame_rate = RTE_RATE_5; 263 frame_rate = RTE_RATE_5;
218 else if (vo_fps < 59.97) 264 } else if (vo_fps < 59.97) {
219 frame_rate = RTE_RATE_6; 265 frame_rate = RTE_RATE_6;
220 else if (vo_fps < 60.0) 266 } else if (vo_fps < 60.0) {
221 frame_rate = RTE_RATE_7; 267 frame_rate = RTE_RATE_7;
222 else if (vo_fps > 60.0) 268 } else if (vo_fps > 60.0) {
223 frame_rate = RTE_RATE_8; 269 frame_rate = RTE_RATE_8;
224 else 270 } else {
225 frame_rate = RTE_RATE_NORATE; 271 frame_rate = RTE_RATE_NORATE;
226 272 }
227 if (format == IMGFMT_YUY2) 273
274 if (format == IMGFMT_YUY2) {
228 pixel_format = RTE_YUYV; 275 pixel_format = RTE_YUYV;
229 else 276 } else {
230 pixel_format = RTE_YUV420; 277 pixel_format = RTE_YUV420;
278 }
231 if (!rte_set_video_parameters(mp1e_context, pixel_format, mp1e_context->width, mp1e_context->height, frame_rate, 3e6, "I")) { 279 if (!rte_set_video_parameters(mp1e_context, pixel_format, mp1e_context->width, mp1e_context->height, frame_rate, 3e6, "I")) {
232 printf("VO: [dxr3] Unable to set mp1e context!\n"); 280 printf("VO: [dxr3] Unable to set mp1e context!\n");
233 rte_context_destroy(mp1e_context); 281 rte_context_destroy(mp1e_context);
234 mp1e_context = 0; 282 mp1e_context = 0;
235 uninit(); 283 uninit();
244 uninit(); 292 uninit();
245 return -1; 293 return -1;
246 } 294 }
247 295
248 /* This stuff calculations the relative position of video and osd on screen */ 296 /* This stuff calculations the relative position of video and osd on screen */
249 osd_w=s_width; 297 /* Old stuff taken from the dvb driver, should be removed when introducing spuenc */
250 d_pos_x=(s_width-v_width)/2; 298 osd_w = s_width;
299 d_pos_x = (s_width - v_width) / 2;
251 if (d_pos_x < 0) { 300 if (d_pos_x < 0) {
252 s_pos_x = -d_pos_x; 301 s_pos_x = -d_pos_x;
253 d_pos_x = 0; 302 d_pos_x = 0;
254 osd_w = s_width; 303 osd_w = s_width;
255 } else 304 } else {
256 s_pos_x = 0; 305 s_pos_x = 0;
257 306 }
258 osd_h = s_height; 307 osd_h = s_height;
259 d_pos_y = (s_height-v_height)/2; 308 d_pos_y = (s_height - v_height) / 2;
260 if (d_pos_y < 0) { 309 if (d_pos_y < 0) {
261 s_pos_y =- d_pos_y; 310 s_pos_y = -d_pos_y;
262 d_pos_y = 0; 311 d_pos_y = 0;
263 osd_h = s_height; 312 osd_h = s_height;
264 } else 313 } else {
265 s_pos_y = 0; 314 s_pos_y = 0;
266 315 }
267 printf("VO: [dxr3] Position mapping: %d;%d => %d;%d\n", s_pos_x, s_pos_y, d_pos_x, d_pos_y);
268 316
269 size = s_width * s_height; 317 size = s_width * s_height;
270 318
271 if (format == IMGFMT_YUY2) { 319 if (format == IMGFMT_YUY2) {
320 /* YUY2 Needs no conversion, so no need for a pixel buffer */
272 picture_data[0] = NULL; 321 picture_data[0] = NULL;
273 picture_linesize[0] = s_width * 2; 322 picture_linesize[0] = s_width * 2;
274 } else { 323 } else {
324 /* Create a pixel buffer and set up pointers for color components */
275 picture_data[0] = malloc((size * 3)/2); 325 picture_data[0] = malloc((size * 3)/2);
276 picture_data[1] = picture_data[0] + size; 326 picture_data[1] = picture_data[0] + size;
277 picture_data[2] = picture_data[1] + size / 4; 327 picture_data[2] = picture_data[1] + size / 4;
278 picture_linesize[0] = s_width; 328 picture_linesize[0] = s_width;
279 picture_linesize[1] = s_width / 2; 329 picture_linesize[1] = s_width / 2;
280 picture_linesize[2] = s_width / 2; 330 picture_linesize[2] = s_width / 2;
281 } 331 }
282 332
283 333 if (!rte_start_encoding(mp1e_context)) {
284 if(!rte_start_encoding(mp1e_context)) {
285 printf("VO: [dxr3] Unable to start mp1e encoding!\n"); 334 printf("VO: [dxr3] Unable to start mp1e encoding!\n");
286 uninit(); 335 uninit();
287 return -1; 336 return -1;
288 } 337 }
289 338
290 if(format == IMGFMT_BGR24) 339 if (format == IMGFMT_BGR24) {
291 yuv2rgb_init(24, MODE_BGR); 340 yuv2rgb_init(24, MODE_BGR);
341 }
292 return 0; 342 return 0;
293 #endif 343 #endif
294 return -1; 344 return -1;
295 } else if (format == IMGFMT_MPEGPES) { 345 } else if (format == IMGFMT_MPEGPES) {
296 printf("VO: [dxr3] Format: MPEG-PES (no conversion needed)\n"); 346 printf("VO: [dxr3] Format: MPEG-PES (no conversion needed)\n");
307 return &vo_info; 357 return &vo_info;
308 } 358 }
309 359
310 static void draw_alpha(int x0, int y0, int w, int h, unsigned char* src, unsigned char *srca, int srcstride) 360 static void draw_alpha(int x0, int y0, int w, int h, unsigned char* src, unsigned char *srca, int srcstride)
311 { 361 {
362 #ifdef USE_MP1E
312 /* This function draws the osd and subtitles etc. It will change to use spuenc soon */ 363 /* This function draws the osd and subtitles etc. It will change to use spuenc soon */
313 switch (img_format) { 364 switch (img_format) {
314 case IMGFMT_BGR24: 365 case IMGFMT_BGR24:
315 case IMGFMT_YV12: 366 case IMGFMT_YV12:
316 vo_draw_alpha_yv12(w, h, src, srca, srcstride, 367 vo_draw_alpha_yv12(w, h, src, srca, srcstride,
319 case IMGFMT_YUY2: 370 case IMGFMT_YUY2:
320 vo_draw_alpha_yuy2(w, h, src, srca, srcstride, 371 vo_draw_alpha_yuy2(w, h, src, srca, srcstride,
321 picture_data[0] + (x0 + d_pos_x) * 2 + (y0 + d_pos_y) * picture_linesize[0], picture_linesize[0]); 372 picture_data[0] + (x0 + d_pos_x) * 2 + (y0 + d_pos_y) * picture_linesize[0], picture_linesize[0]);
322 break; 373 break;
323 } 374 }
375 #endif
324 } 376 }
325 377
326 static void draw_osd(void) 378 static void draw_osd(void)
327 { 379 {
328 vo_draw_text(osd_w, osd_h, draw_alpha); 380 if (img_format != IMGFMT_MPEGPES) {
381 vo_draw_text(osd_w, osd_h, draw_alpha);
382 }
329 } 383 }
330 384
331 static uint32_t draw_frame(uint8_t * src[]) 385 static uint32_t draw_frame(uint8_t * src[])
332 { 386 {
333 if (img_format == IMGFMT_MPEGPES) { 387 if (img_format == IMGFMT_MPEGPES) {
334 vo_mpegpes_t *p = (vo_mpegpes_t *) src[0]; 388 vo_mpegpes_t *p = (vo_mpegpes_t *) src[0];
335 size_t data_left = p->size; 389 size_t data_left = p->size;
336 390
337 if (p->id == 0x20) { 391 if (p->id == 0x20) {
338 if (ioctl(fd_spu, EM8300_IOCTL_SPU_SETPTS, &vo_pts) < 0) 392 /* Set subpic timestamp */
393 if (ioctl(fd_spu, EM8300_IOCTL_SPU_SETPTS, &vo_pts) < 0) {
339 printf("VO: [dxr3] Unable to set pts\n"); 394 printf("VO: [dxr3] Unable to set pts\n");
340 395 }
341 while (data_left) 396
397 /* Force subpic data into buffer */
398 while (data_left) {
342 data_left -= write(fd_spu, (void*) (p->data + p->size-data_left), data_left); 399 data_left -= write(fd_spu, (void*) (p->data + p->size-data_left), data_left);
400 }
343 } else { 401 } else {
344 if (ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts) < 0) 402 /* Set frame timestamp */
403 if (ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts) < 0) {
345 printf("VO: [dxr3] Unable to set pts\n"); 404 printf("VO: [dxr3] Unable to set pts\n");
346 405 }
347 while (data_left) 406
407 /* Force video data into buffer */
408 while (data_left) {
348 data_left -= write(fd_video, (void*) (p->data + p->size-data_left), data_left); 409 data_left -= write(fd_video, (void*) (p->data + p->size-data_left), data_left);
410 }
349 } 411 }
350 return 0; 412 return 0;
351 } 413 }
352 #ifdef USE_MP1E 414 #ifdef USE_MP1E
353 else if (img_format == IMGFMT_YUY2) { 415 else if (img_format == IMGFMT_YUY2) {
354 picture_data[0] = src[0]; 416 picture_data[0] = src[0];
355 return 0; 417 return 0;
356 } else if (img_format == IMGFMT_BGR24) { 418 } else if (img_format == IMGFMT_BGR24) {
357 /* BGR24 needs to be converted to YUV420 before libmp1e will touch it */ 419 /* BGR24 needs to be converted to YUV420 before libmp1e will touch it */
358 int x, y, w = v_width, h = v_height; 420 int x, y, w = v_width, h = v_height;
359 unsigned char *s,*dY,*dU,*dV; 421 unsigned char *s, *dY, *dU, *dV;
360 422
361 if (d_pos_x+w>picture_linesize[0]) 423 if ((d_pos_x + w) > picture_linesize[0]) {
362 w = picture_linesize[0] - d_pos_x; 424 w = picture_linesize[0] - d_pos_x;
363 if (d_pos_y+h>s_height) 425 }
426 if ((d_pos_y + h) > s_height) {
364 h = s_height - d_pos_y; 427 h = s_height - d_pos_y;
428 }
365 429
366 s = src[0] + s_pos_y * (w * 3); 430 s = src[0] + s_pos_y * (w * 3);
367 431
368 dY = picture_data[0] + d_pos_y * picture_linesize[0]; 432 dY = picture_data[0] + d_pos_y * picture_linesize[0];
369 dU = picture_data[1] + (d_pos_y / 2) * picture_linesize[1]; 433 dU = picture_data[1] + (d_pos_y / 2) * picture_linesize[1];
382 return -1; 446 return -1;
383 } 447 }
384 448
385 static void flip_page(void) 449 static void flip_page(void)
386 { 450 {
451 static int prev_pts = 0;
452 if (prev_pts > vo_pts) {
453 printf("WARNING: Seeking will break a/v sync currently\n");
454 }
387 #ifdef USE_MP1E 455 #ifdef USE_MP1E
388 if (img_format == IMGFMT_YV12) { 456 if (img_format == IMGFMT_YV12) {
389 mp1e_buffer.data = picture_data[0]; 457 mp1e_buffer.data = picture_data[0];
390 mp1e_buffer.time = vo_pts / 90000.0; 458 mp1e_buffer.time = vo_pts / 90000.0;
391 mp1e_buffer.user_data = NULL; 459 mp1e_buffer.user_data = NULL;
394 mp1e_buffer.data = picture_data[0]; 462 mp1e_buffer.data = picture_data[0];
395 mp1e_buffer.time = vo_pts / 90000.0; 463 mp1e_buffer.time = vo_pts / 90000.0;
396 mp1e_buffer.user_data = NULL; 464 mp1e_buffer.user_data = NULL;
397 rte_push_video_buffer(mp1e_context, &mp1e_buffer); 465 rte_push_video_buffer(mp1e_context, &mp1e_buffer);
398 } 466 }
467 prev_pts = vo_pts;
399 #endif 468 #endif
400 } 469 }
401 470
402 static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0) 471 static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0)
403 { 472 {
473 #ifdef USE_MP1E
404 if (img_format == IMGFMT_YV12) { 474 if (img_format == IMGFMT_YV12) {
405 int y; 475 int y;
406 unsigned char *s,*s1; 476 unsigned char *s, *s1;
407 unsigned char *d,*d1; 477 unsigned char *d, *d1;
408 478
409 x0 += d_pos_x; 479 x0 += d_pos_x;
410 y0 += d_pos_y; 480 y0 += d_pos_y;
411 481
412 if ((x0 + w) > picture_linesize[0]) 482 if ((x0 + w) > picture_linesize[0]) {
413 w = picture_linesize[0]-x0; 483 w = picture_linesize[0] - x0;
414 if ((y0 + h) > s_height) 484 }
415 h = s_height-y0; 485 if ((y0 + h) > s_height) {
486 h = s_height - y0;
487 }
416 488
417 s = srcimg[0] + s_pos_x + s_pos_y * stride[0]; 489 s = srcimg[0] + s_pos_x + s_pos_y * stride[0];
418 d = picture_data[0] + x0 + y0 * picture_linesize[0]; 490 d = picture_data[0] + x0 + y0 * picture_linesize[0];
419 for(y = 0; y < h; y++) { 491 for(y = 0; y < h; y++) {
420 memcpy(d, s, w); 492 memcpy(d, s, w);
439 d += picture_linesize[1]; 511 d += picture_linesize[1];
440 d1 += picture_linesize[2]; 512 d1 += picture_linesize[2];
441 } 513 }
442 return 0; 514 return 0;
443 } 515 }
516 #endif
444 return -1; 517 return -1;
445 } 518 }
446 519
447 static uint32_t query_format(uint32_t format) 520 static uint32_t query_format(uint32_t format)
448 { 521 {
449 uint32_t flag = 0; 522 uint32_t flag = 0;
450 523
451 if (format == IMGFMT_MPEGPES) 524 if (format == IMGFMT_MPEGPES) {
452 flag = 0x2 | 0x4 | 0x8; 525 /* Hardware accelerated | Hardware supports subpics | Hardware handles syncing */
453 #ifdef USE_MP1E 526 flag = 0x2 | 0x8 | 0x100;
454 if (format == IMGFMT_YV12) 527 #ifdef USE_MP1E
455 flag = 0x1 | 0x4; 528 } else if (format == IMGFMT_YV12) {
456 if (format == IMGFMT_YUY2) 529 /* Conversion needed | OSD Supported | Hardware handles syncing */
457 flag = 0x1 | 0x4; 530 flag = 0x1 | 0x4 | 0x100;
458 if (format == IMGFMT_BGR24) 531 } else if (format == IMGFMT_YUY2) {
459 flag = 0x1 | 0x4; 532 /* Conversion needed | OSD Supported | Hardware handles syncing */
460 else 533 flag = 0x1 | 0x4 | 0x100;
534 } else if (format == IMGFMT_BGR24) {
535 /* Conversion needed | OSD Supported | Hardware handles syncing */
536 flag = 0x1 | 0x4 | 0x100;
537 } else {
461 printf("VO: [dxr3] Format unsupported, mail dholm@iname.com\n"); 538 printf("VO: [dxr3] Format unsupported, mail dholm@iname.com\n");
462 #else 539 #else
463 else 540 } else {
464 printf("VO: [dxr3] You have disabled libmp1e support, you won't be able to play this format!\n"); 541 printf("VO: [dxr3] You have disabled libmp1e support, you won't be able to play this format!\n");
465 #endif 542 #endif
543 }
466 return flag; 544 return flag;
467 } 545 }
468 546
469 static void uninit(void) 547 static void uninit(void)
470 { 548 {
471 printf("VO: [dxr3] Uninitializing\n"); 549 printf("VO: [dxr3] Uninitializing\n");
472 if (picture_data[0]) 550 #ifdef USE_MP1E
551 if (picture_data[0]) {
473 free(picture_data[0]); 552 free(picture_data[0]);
474 if (fd_video) 553 }
554 #endif
555 if (fd_video) {
475 close(fd_video); 556 close(fd_video);
476 if(fd_spu) 557 }
558 if (fd_spu) {
477 close(fd_spu); 559 close(fd_spu);
560 }
561 if (fd_control) {
562 close(fd_control);
563 }
478 } 564 }
479 565
480 static void check_events(void) 566 static void check_events(void)
481 { 567 {
482 } 568 }