Mercurial > mplayer.hg
annotate libvo/vo_dxr3.c @ 3208:98a587aaf505
Support for YV12 with DXR3, patch by D. Holm.
author | atmos4 |
---|---|
date | Thu, 29 Nov 2001 19:18:48 +0000 |
parents | 039a973b3dda |
children | 8ba06b63f873 |
rev | line source |
---|---|
2645 | 1 #define PES_MAX_SIZE 2048 |
2 /* | |
3 * vo_dxr3.c - DXR3/H+ video out | |
4 * | |
5 * Copyright (C) 2001 David Holm <dholm@iname.com> | |
6 * | |
7 */ | |
8 | |
9 #include "fastmemcpy.h" | |
10 #include <stdio.h> | |
11 #include <stdlib.h> | |
12 #include <string.h> | |
2921 | 13 #include <unistd.h> |
14 #include <linux/em8300.h> | |
15 #include <sys/ioctl.h> | |
16 #include <sys/stat.h> | |
17 #include <sys/types.h> | |
18 #include <fcntl.h> | |
2645 | 19 #include <stdio.h> |
20 #include <time.h> | |
21 | |
22 #include "config.h" | |
23 #include "video_out.h" | |
24 #include "video_out_internal.h" | |
25 | |
2866
4f6190ab52e7
Added a temporary fix to the DXR3 win32 codec playback, win32 codecs might prove to play back an unscaled image!
mswitch
parents:
2770
diff
changeset
|
26 #include "../postproc/rgb2rgb.h" |
2645 | 27 #ifdef HAVE_MMX |
28 #include "mmx.h" | |
29 #endif | |
30 | |
31 LIBVO_EXTERN (dxr3) | |
32 | |
3201 | 33 #ifdef USE_MP1E |
34 #include <rte.h> | |
35 rte_context* mp1e_context = NULL; | |
36 rte_codec* mp1e_codec = NULL; | |
37 rte_buffer mp1e_buffer; | |
2645 | 38 #endif |
39 | |
3201 | 40 static unsigned char *picture_data[3]; |
41 static unsigned int picture_linesize[3]; | |
2770 | 42 static unsigned char *spubuf=NULL; |
43 static int v_width,v_height; | |
2866
4f6190ab52e7
Added a temporary fix to the DXR3 win32 codec playback, win32 codecs might prove to play back an unscaled image!
mswitch
parents:
2770
diff
changeset
|
44 static int s_width,s_height; |
3201 | 45 static int c_width,c_height; |
2645 | 46 static int s_pos_x,s_pos_y; |
47 static int d_pos_x,d_pos_y; | |
48 static int osd_w,osd_h; | |
2770 | 49 static int img_format = 0; |
2866
4f6190ab52e7
Added a temporary fix to the DXR3 win32 codec playback, win32 codecs might prove to play back an unscaled image!
mswitch
parents:
2770
diff
changeset
|
50 static int palette[] = { 0x000000, 0x494949, 0xb5b5b5, 0xffffff }; |
2921 | 51 static int fd_control = -1; |
52 static int fd_video = -1; | |
53 static int fd_spu = -1; | |
54 static int ioval = 0; | |
2645 | 55 |
56 static vo_info_t vo_info = | |
57 { | |
58 "DXR3/H+ video out", | |
59 "dxr3", | |
60 "David Holm <dholm@iname.com>", | |
61 "" | |
62 }; | |
63 | |
3201 | 64 #ifdef USE_MP1E |
65 void write_dxr3( rte_context* context, void* data, size_t size, void* user_data ) | |
66 { | |
67 if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts ) < 0 ) | |
68 printf( "VO: [dxr3] Unable to set PTS\n" ); | |
69 write( fd_video, data, size ); | |
70 } | |
71 #endif | |
72 | |
2645 | 73 static uint32_t |
2866
4f6190ab52e7
Added a temporary fix to the DXR3 win32 codec playback, win32 codecs might prove to play back an unscaled image!
mswitch
parents:
2770
diff
changeset
|
74 init(uint32_t scr_width, uint32_t scr_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format) |
2645 | 75 { |
2921 | 76 fd_control = open( "/dev/em8300", O_WRONLY ); |
77 if( fd_control < 1 ) | |
2645 | 78 { |
2921 | 79 printf( "VO: [dxr3] Error opening /dev/em8300 for writing!\n" ); |
80 return -1; | |
81 } | |
82 fd_video = open( "/dev/em8300_mv", O_WRONLY ); | |
83 if( fd_video < 0 ) | |
84 { | |
85 printf( "VO: [dxr3] Error opening /dev/em8300_mv for writing!\n" ); | |
86 return -1; | |
87 } | |
88 else printf( "VO: [dxr3] Opened /dev/em8300_mv\n" ); | |
89 fd_spu = open( "/dev/em8300_sp", O_WRONLY ); | |
90 if( fd_spu < 0 ) | |
91 { | |
92 printf( "VO: [dxr3] Error opening /dev/em8300_sp for writing!\n" ); | |
93 return -1; | |
2645 | 94 } |
95 | |
2770 | 96 /* Subpic code isn't working yet, don't set to ON |
97 unless you are really sure what you are doing */ | |
2921 | 98 ioval = EM8300_SPUMODE_OFF; |
99 if( ioctl( fd_control, EM8300_IOCTL_SET_SPUMODE, &ioval ) < 0 ) | |
100 { | |
101 printf( "VO: [dxr3] Unable to set subpicture mode!\n" ); | |
102 return -1; | |
103 } | |
2770 | 104 |
2921 | 105 if( ioctl( fd_spu, EM8300_IOCTL_SPU_SETPALETTE, palette ) < 0 ) |
106 { | |
107 printf( "VO: [dxr3] Unable to set subpicture palette!\n" ); | |
108 return -1; | |
109 } | |
110 | |
111 ioval = EM8300_PLAYMODE_PLAY; | |
2968 | 112 if( ioctl( fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval ) < 0 ) |
2921 | 113 printf( "VO: [dxr3] Unable to set playmode!\n" ); |
114 | |
115 close( fd_control ); | |
2645 | 116 |
117 img_format = format; | |
2770 | 118 v_width = width; |
119 v_height = height; | |
3201 | 120 s_width = scr_width; |
121 s_height = scr_height; | |
2921 | 122 spubuf = malloc(53220); /* 53220 bytes is the standardized max size of a subpic */ |
123 | |
3208 | 124 if( format == IMGFMT_YV12 || format == IMGFMT_YUY2 ) |
2645 | 125 { |
3201 | 126 #ifdef USE_MP1E |
2645 | 127 int size; |
3201 | 128 enum rte_frame_rate frame_rate; |
2645 | 129 |
3201 | 130 if( !rte_init() ) |
2968 | 131 { |
3201 | 132 printf( "VO: [dxr3] Unable to initialize RTE!\n" ); |
133 return -1; | |
134 } | |
135 | |
2645 | 136 if(width<=352 && height<=288){ |
3201 | 137 c_width=352; |
138 c_height=288; | |
2645 | 139 } else |
140 if(width<=352 && height<=576){ | |
3201 | 141 c_width=352; |
142 c_height=576; | |
2645 | 143 } else |
144 if(width<=480 && height<=576){ | |
3201 | 145 c_width=480; |
146 c_height=576; | |
2645 | 147 } else |
148 if(width<=544 && height<=576){ | |
3201 | 149 c_width=544; |
150 c_height=576; | |
2645 | 151 } else { |
3201 | 152 c_width=704; |
153 c_height=576; | |
2645 | 154 } |
3201 | 155 |
156 mp1e_context = rte_context_new( c_width, c_height, "mp1e", (void*)0xdeadbeef ); | |
157 rte_set_verbosity( mp1e_context, 0 ); | |
158 | |
159 if( !mp1e_context ) | |
160 { | |
161 printf( "VO: [dxr3] Unable to create context!\n" ); | |
162 return -1; | |
163 } | |
164 | |
165 if( !rte_set_format( mp1e_context, "mpeg1" ) ) | |
166 { | |
167 printf( "VO: [dxr3] Unable to set format\n" ); | |
168 return -1; | |
169 } | |
170 | |
171 rte_set_mode( mp1e_context, RTE_VIDEO ); | |
172 mp1e_codec = rte_codec_set( mp1e_context, RTE_STREAM_VIDEO, 0, "mpeg1-video" ); | |
2866
4f6190ab52e7
Added a temporary fix to the DXR3 win32 codec playback, win32 codecs might prove to play back an unscaled image!
mswitch
parents:
2770
diff
changeset
|
173 |
3201 | 174 if( vo_fps < 24.0 ) frame_rate = RTE_RATE_1; |
175 else if( vo_fps < 25.0 ) frame_rate = RTE_RATE_2; | |
176 else if( vo_fps < 29.97 ) frame_rate = RTE_RATE_3; | |
177 else if( vo_fps < 30.0 ) frame_rate = RTE_RATE_4; | |
178 else if( vo_fps < 50.0 ) frame_rate = RTE_RATE_5; | |
179 else if( vo_fps < 59.97 ) frame_rate = RTE_RATE_6; | |
180 else if( vo_fps < 60.0 ) frame_rate = RTE_RATE_7; | |
181 else if( vo_fps > 60.0 ) frame_rate = RTE_RATE_8; | |
182 else frame_rate = RTE_RATE_NORATE; | |
183 | |
184 if( !rte_set_video_parameters( mp1e_context, RTE_YUV420, mp1e_context->width, | |
185 mp1e_context->height, frame_rate, | |
186 3e6, "I" ) ) | |
187 { | |
188 printf( "VO: [dxr3] Unable to set RTE context!\n" ); | |
189 rte_context_destroy( mp1e_context ); | |
190 return -1; | |
191 } | |
192 | |
193 rte_set_input( mp1e_context, RTE_VIDEO, RTE_PUSH, TRUE, NULL, NULL, NULL ); | |
3208 | 194 rte_set_output( mp1e_context, (void*)write_dxr3, NULL, NULL ); |
3201 | 195 |
196 if( !rte_init_context( mp1e_context ) ) | |
197 { | |
198 printf( "VO: [dxr3] Unable to init RTE context!\n" ); | |
199 rte_context_delete( mp1e_context ); | |
200 return -1; | |
201 } | |
202 | |
2866
4f6190ab52e7
Added a temporary fix to the DXR3 win32 codec playback, win32 codecs might prove to play back an unscaled image!
mswitch
parents:
2770
diff
changeset
|
203 osd_w=scr_width; |
3201 | 204 d_pos_x=(c_width-(int)scr_width)/2; |
3208 | 205 if(d_pos_x<0) |
206 { | |
207 s_pos_x=-d_pos_x;d_pos_x=0; | |
208 osd_w=c_width; | |
2645 | 209 } else s_pos_x=0; |
210 | |
2866
4f6190ab52e7
Added a temporary fix to the DXR3 win32 codec playback, win32 codecs might prove to play back an unscaled image!
mswitch
parents:
2770
diff
changeset
|
211 osd_h=scr_height; |
3201 | 212 d_pos_y=(c_height-(int)scr_height)/2; |
3208 | 213 if(d_pos_y<0) |
214 { | |
215 s_pos_y=-d_pos_y;d_pos_y=0; | |
216 osd_h=c_height; | |
2645 | 217 } else s_pos_y=0; |
218 | |
2968 | 219 printf("VO: [dxr3] position mapping: %d;%d => %d;%d\n",s_pos_x,s_pos_y,d_pos_x,d_pos_y); |
3201 | 220 |
221 size = c_width*c_height; | |
222 | |
223 picture_data[0] = malloc((size * 3)/2); | |
224 picture_data[1] = picture_data[0] + size; | |
225 picture_data[2] = picture_data[1] + size / 4; | |
226 picture_linesize[0] = c_width; | |
227 picture_linesize[1] = c_width / 2; | |
228 picture_linesize[2] = c_width / 2; | |
229 memset(picture_data[0],0,size); | |
230 | |
231 if( !rte_start_encoding( mp1e_context ) ) | |
2968 | 232 { |
3201 | 233 printf( "VO: [dxr3] Unable to start mp1e encoding!\n" ); |
234 uninit(); | |
235 return -1; | |
236 } | |
2770 | 237 |
238 return 0; | |
239 #endif | |
240 return -1; | |
241 } | |
2645 | 242 else if(format==IMGFMT_MPEGPES) |
243 { | |
2921 | 244 printf( "VO: [dxr3] Format: MPEG-PES (no conversion needed)\n" ); |
2645 | 245 return 0; |
246 } | |
247 | |
2968 | 248 printf( "VO: [dxr3] Format: Unsupported\n" ); |
2645 | 249 return -1; |
250 } | |
251 | |
2866
4f6190ab52e7
Added a temporary fix to the DXR3 win32 codec playback, win32 codecs might prove to play back an unscaled image!
mswitch
parents:
2770
diff
changeset
|
252 static const vo_info_t* get_info(void) |
2645 | 253 { |
254 return &vo_info; | |
255 } | |
256 | |
2866
4f6190ab52e7
Added a temporary fix to the DXR3 win32 codec playback, win32 codecs might prove to play back an unscaled image!
mswitch
parents:
2770
diff
changeset
|
257 static void draw_alpha(int x0, int y0, int w, int h, unsigned char* src, unsigned char *srca, int srcstride) |
2645 | 258 { |
259 } | |
260 | |
261 static void draw_osd(void) | |
262 { | |
263 } | |
264 | |
265 static uint32_t draw_frame(uint8_t * src[]) | |
266 { | |
267 if( img_format == IMGFMT_MPEGPES ) | |
268 { | |
2770 | 269 int data_left; |
2645 | 270 vo_mpegpes_t *p=(vo_mpegpes_t *)src[0]; |
3201 | 271 |
272 if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts ) < 0 ) | |
273 printf( "VO: [dxr3] Unable to set PTS\n" ); | |
2968 | 274 |
2645 | 275 data_left = p->size; |
276 while( data_left ) | |
2921 | 277 data_left -= write( fd_video, &((unsigned char*)p->data)[p->size-data_left], data_left ); |
278 | |
2645 | 279 return 0; |
280 } | |
3208 | 281 else if( img_format == IMGFMT_YUY2 ) |
282 { | |
283 int w=v_width,h=v_height; | |
284 unsigned char *s,*dY,*dU,*dV; | |
285 | |
286 if(d_pos_x+w>picture_linesize[0]) w=picture_linesize[0]-d_pos_x; | |
287 if(d_pos_y+h>c_height) h=c_height-d_pos_y; | |
288 | |
289 s = src[0]+s_pos_x+s_pos_y*(w*2); | |
290 dY = picture_data[0]+d_pos_x+d_pos_y*picture_linesize[0]; | |
291 dU = picture_data[1]+(d_pos_x/2)+(d_pos_y/2)*picture_linesize[1]; | |
292 dV = picture_data[2]+(d_pos_x/2)+(d_pos_y/2)*picture_linesize[2]; | |
293 | |
294 yuy2toyv12( s, dY, dU, dV, w, h, picture_linesize[0], picture_linesize[1], w*2 ); | |
295 | |
296 mp1e_buffer.data = picture_data[0]; | |
297 mp1e_buffer.time = vo_pts/90000.0; | |
298 mp1e_buffer.user_data = NULL; | |
299 rte_push_video_buffer( mp1e_context, &mp1e_buffer ); | |
300 return 0; | |
301 } | |
2645 | 302 |
2968 | 303 printf( "VO: [dxr3] Error in draw_frame(...)\n" ); |
2645 | 304 return -1; |
305 } | |
306 | |
307 static void flip_page (void) | |
308 { | |
3201 | 309 if( img_format == IMGFMT_YV12 ) |
310 { | |
311 mp1e_buffer.data = picture_data[0]; | |
312 mp1e_buffer.time = vo_pts/90000.0; | |
313 mp1e_buffer.user_data = NULL; | |
314 rte_push_video_buffer( mp1e_context, &mp1e_buffer ); | |
315 } | |
2645 | 316 } |
317 | |
318 static uint32_t draw_slice( uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0 ) | |
319 { | |
320 unsigned char* s; | |
321 unsigned char* d; | |
3201 | 322 |
2645 | 323 if( img_format == IMGFMT_YV12 ) |
3201 | 324 { |
325 #ifdef USE_MP1E | |
2645 | 326 x0+=d_pos_x; |
327 y0+=d_pos_y; | |
3201 | 328 if(x0+w>picture_linesize[0]) w=picture_linesize[0]-x0; |
329 if(y0+h>c_height) h=c_height-y0; | |
2645 | 330 |
331 s=srcimg[0]+s_pos_x+s_pos_y*stride[0]; | |
3201 | 332 d=picture_data[0]+x0+y0*picture_linesize[0]; |
3208 | 333 memcpy(d,s,(w*h)); |
2645 | 334 |
3208 | 335 s=srcimg[1]+s_pos_x+s_pos_y*stride[1]; |
336 d=picture_data[1]+(x0/2)+(y0/2)*picture_linesize[1]; | |
337 memcpy(d,s,(w*h)/4); | |
2645 | 338 |
3208 | 339 s=srcimg[2]+s_pos_x+s_pos_y*stride[2]; |
340 d=picture_data[2]+(x0/2)+(y0/2)*picture_linesize[2]; | |
341 memcpy(d,s,(w*h)/4); | |
342 | |
2645 | 343 return 0; |
344 #endif | |
3201 | 345 printf( "VO: [dxr3] You need to install mp1e rte, read DOCS/DXR3\n" ); |
2645 | 346 return -1; |
347 } | |
348 | |
349 return -1; | |
350 } | |
351 | |
352 | |
353 static uint32_t | |
354 query_format(uint32_t format) | |
355 { | |
2968 | 356 if(format==IMGFMT_MPEGPES) return 1; |
3201 | 357 #ifdef USE_MP1E |
2968 | 358 if(format==IMGFMT_YV12) return 1; |
3208 | 359 if(format==IMGFMT_YUY2) return 1; |
2770 | 360 #else |
3208 | 361 if(format==IMGFMT_YV12) {printf("VO: [dxr3] You need to compile with mp1e rte to play this file! Read DOCS/DXR3\n" ); return 0;} |
362 if(format==IMGFMT_YUY2) {printf("VO: [dxr3] You need to compile with mp1e rte to play this file! Read DOCS/DXR3\n" ); return 0;} | |
3201 | 363 #endif |
3208 | 364 else printf( "VO: [dxr3] Format unsupported, mail dholm@iname.com\n" ); |
2645 | 365 return 0; |
366 } | |
367 | |
3208 | 368 static void uninit(void) |
2645 | 369 { |
2968 | 370 printf( "VO: [dxr3] Uninitializing\n" ); |
3201 | 371 #ifdef USE_MP1E |
372 if( mp1e_context ) rte_stop( mp1e_context ); | |
373 if( mp1e_context ) rte_context_delete( mp1e_context ); | |
374 if( picture_data[0] ) free(picture_data[0]); | |
375 #endif | |
376 if( spubuf ) free(spubuf); | |
377 if( fd_video ) close(fd_video); | |
378 if( fd_spu ) close(fd_spu); | |
2645 | 379 } |
380 | |
381 | |
382 static void check_events(void) | |
383 { | |
384 } | |
385 |