9bb11f4acb35e417326256206532c688e3ca3921
[platform/adaptation/samsung_exynos/xf86-video-exynos.git] / src / xv / sec_video_tvout.c
1 /**************************************************************************
2
3 xserver-xorg-video-exynos
4
5 Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: Boram Park <boram1288.park@samsung.com>
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
19 of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 #include "sec.h"
32 #include "sec_display.h"
33 #include "sec_crtc.h"
34 #include "sec_output.h"
35 #include "sec_accel.h"
36 #include "sec_util.h"
37 #include "sec_converter.h"
38 #include "sec_video_tvout.h"
39 #include "sec_video_virtual.h"
40 #include "sec_video_fourcc.h"
41 #include "sec_drm_ipp.h"
42 #include "sec_layer.h"
43 #include "sec_prop.h"
44
45 #include <sys/ioctl.h>
46 #include "common.h"
47 #include <drm_fourcc.h>
48
49 #define TVBUF_NUM  3
50
51 /* HW restriction (VP) */
52 #define MIN_WIDTH  32
53 #define MIN_HEIGHT 4
54 #define MAX_WIDTH  1920
55 #define MAX_HEIGHT 1080
56 #define MIN_SCALE  0.25
57 #define MAX_SCALE  16.0
58
59 /* private structure */
60 struct _SECVideoTv
61 {
62     ScrnInfoPtr pScrn;
63
64     SECLayer *layer;
65     SECLayerPos lpos;
66
67     /* used if id is not supported in case of lpos == LAYER_LOWER1. */
68     SECCvt      *cvt;
69     SECVideoBuf **outbuf;
70     int          outbuf_index;
71     int          outbuf_num;
72
73     int          tv_width;
74     int          tv_height;
75
76     xRectangle   tv_rect;
77     int          is_resized;
78     unsigned int convert_id;
79     unsigned int src_id;
80     SECLayerOutput output;
81
82 };
83 #if 0
84 static Bool
85 _secVideoTvCalSize (SECVideoTv* tv, int src_w, int src_h, int dst_w, int dst_h)
86 {
87     float r;
88
89     if (src_w < MIN_WIDTH || src_h < MIN_HEIGHT)
90     {
91         XDBG_WARNING (MTVO, "size(%dx%d) must be more than (%dx%d).\n",
92                       src_w, src_h, MIN_WIDTH, MAX_WIDTH);
93     }
94
95     r = (float)dst_w / src_w;
96     if (r < MIN_SCALE || r > MAX_SCALE)
97     {
98         XDBG_WARNING (MTVO, "ratio_w(%f) is out of range(%f~%f).\n",
99                       r, MIN_SCALE, MAX_SCALE);
100     }
101
102     r = (float)dst_h / src_h;
103     if (r < MIN_SCALE || r > MAX_SCALE)
104     {
105         XDBG_WARNING (MTVO, "ratio_h(%d) is out of range(%f~%f).\n",
106                       r, MIN_SCALE, MAX_SCALE);
107     }
108
109     return TRUE;
110 }
111 #endif
112 static SECVideoBuf*
113 _secVideoTvGetOutBuffer (SECVideoTv* tv, int width, int height, Bool secure)
114 {
115     int i = tv->outbuf_index, j;
116
117     if (!tv->outbuf)
118     {
119         tv->outbuf = (SECVideoBuf**)calloc (tv->outbuf_num, sizeof (SECVideoBuf*));
120         XDBG_RETURN_VAL_IF_FAIL (tv->outbuf != NULL, NULL);
121     }
122
123     i++;
124     if (i >= tv->outbuf_num)
125         i = 0;
126
127     for (j = 0; j < tv->outbuf_num; j++)
128     {
129         if (tv->outbuf[i])
130         {
131             XDBG_DEBUG (MTVO, "outbuf(%p) converting(%d) showing(%d)\n",
132                         tv->outbuf[i], VBUF_IS_CONVERTING (tv->outbuf[i]), tv->outbuf[i]->showing);
133
134             if (tv->outbuf[i] && !VBUF_IS_CONVERTING (tv->outbuf[i]) && !tv->outbuf[i]->showing)
135             {
136                 tv->outbuf_index = i;
137                 return tv->outbuf[i];
138             }
139         }
140         else
141         {
142             SECPtr pSec = SECPTR (tv->pScrn);
143             tv->outbuf[i] = secUtilAllocVideoBuffer (tv->pScrn, tv->convert_id, width, height,
144                                                      (pSec->scanout)?TRUE:FALSE, TRUE, secure);
145             XDBG_RETURN_VAL_IF_FAIL (tv->outbuf[i] != NULL, NULL);
146
147             XDBG_DEBUG (MTVO, "outbuf(%p, %c%c%c%c)\n", tv->outbuf[i], FOURCC_STR (tv->convert_id));
148
149             tv->outbuf_index = i;
150             return tv->outbuf[i];
151         }
152
153         i++;
154         if (i >= tv->outbuf_num)
155             i = 0;
156     }
157
158 #if 0
159     char buffers[1024];
160     CLEAR (buffers);
161     for (j = 0; j < tv->outbuf_num; j++)
162     {
163         if (tv->outbuf[j])
164             snprintf (buffers, 1024, "%s %d(%d,%d) ", buffers, tv->outbuf[j]->keys[0],
165             VBUF_IS_CONVERTING (tv->outbuf[j]), tv->outbuf[j]->showing);
166     }
167
168     XDBG_ERROR (MTVO, "now all outbufs in use! %s\n", buffers);
169 #else
170     XDBG_ERROR (MTVO, "now all outbufs in use!\n");
171 #endif
172
173     return NULL;
174 }
175
176 static Bool
177 _secVideoTvLayerEnsure (SECVideoTv* tv)
178 {
179     SECLayer *layer;
180
181     if (tv->layer)
182         return TRUE;
183
184     XDBG_RETURN_VAL_IF_FAIL (tv->lpos != LAYER_NONE, FALSE);
185
186     layer = secLayerCreate (tv->pScrn, LAYER_OUTPUT_EXT, tv->lpos);
187     XDBG_RETURN_VAL_IF_FAIL (layer != NULL, FALSE);
188
189     tv->layer = layer;
190
191     return TRUE;
192 }
193
194 static void
195 _secVideoTvLayerDestroy (SECVideoTv* tv)
196 {
197     if (tv->layer)
198     {
199         secLayerUnref (tv->layer);
200         tv->layer = NULL;
201     }
202 }
203
204 static int
205 _secVideoTvPutImageInternal (SECVideoTv *tv, SECVideoBuf *vbuf, xRectangle *rect)
206 {
207     int ret = 0;
208
209     XDBG_DEBUG (MTVO, "rect (%d,%d %dx%d) \n",
210                 rect->x, rect->y, rect->width, rect->height);
211
212     if (tv->is_resized == 1)
213     {
214         secLayerFreezeUpdate (tv->layer, FALSE);
215         tv->is_resized = 0;
216     }
217 #if 0
218     if (tv->lpos == LAYER_LOWER1)
219         if (!_secVideoTvCalSize (tv, vbuf->width, vbuf->height,
220                                 rect->width, rect->height))
221         {
222             return 0;
223         }
224 #endif
225     secLayerSetRect (tv->layer, &vbuf->crop, rect);
226
227     ret = secLayerSetBuffer (tv->layer, vbuf);
228
229     if (ret == 0)
230         return 0;
231
232     secLayerShow (tv->layer);
233
234     return ret;
235 }
236
237 static void
238 _secVideoTvCvtCallback (SECCvt *cvt,
239                         SECVideoBuf *src,
240                         SECVideoBuf *dst,
241                         void *cvt_data,
242                         Bool error)
243 {
244     SECVideoTv *tv = (SECVideoTv*)cvt_data;
245     int i;
246
247     XDBG_RETURN_IF_FAIL (tv != NULL);
248     XDBG_RETURN_IF_FAIL (cvt != NULL);
249     XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (dst));
250
251     XDBG_DEBUG (MTVO, "++++++++++++++++++++++++ \n");
252
253     for (i = 0; i < tv->outbuf_num; i++)
254         if (tv->outbuf[i] == dst)
255             break;
256     XDBG_RETURN_IF_FAIL (i < tv->outbuf_num);
257     _secVideoTvPutImageInternal (tv, dst, &tv->tv_rect);
258
259     XDBG_DEBUG (MTVO, "++++++++++++++++++++++++.. \n");
260 }
261
262 SECVideoTv*
263 secVideoTvConnect (ScrnInfoPtr pScrn, unsigned int id, SECLayerPos lpos)
264 {
265     SECVideoTv* tv = NULL;
266     SECModePtr pSecMode;
267     unsigned int convert_id = FOURCC_RGB32;
268     XDBG_RETURN_VAL_IF_FAIL (pScrn != NULL, NULL);
269     XDBG_RETURN_VAL_IF_FAIL (lpos >= LAYER_LOWER1 && lpos <= LAYER_UPPER, NULL);
270     XDBG_RETURN_VAL_IF_FAIL (id > 0, NULL);
271
272     tv = calloc (sizeof (SECVideoTv), 1);
273     XDBG_RETURN_VAL_IF_FAIL (tv != NULL, NULL);
274
275     pSecMode = (SECModePtr) SECPTR (pScrn)->pSecMode;
276
277     if (lpos == LAYER_LOWER1 && pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
278     {
279         /* In case of video-only(virtual), we always use converter. */
280         tv->cvt = secCvtCreate (pScrn, CVT_OP_M2M);
281         XDBG_GOTO_IF_FAIL (tv->cvt != NULL, fail_connect);
282
283         secCvtAddCallback (tv->cvt, _secVideoTvCvtCallback, tv);
284     }
285     else if (lpos == LAYER_LOWER1 && pSecMode->conn_mode == DISPLAY_CONN_MODE_HDMI)
286     {
287         if (!secLayerSupport (pScrn, LAYER_OUTPUT_EXT, lpos, id))
288         {
289             /* used if id is not supported in case of lpos == LAYER_LOWER1. */
290             convert_id = FOURCC_SN12;
291             tv->cvt = secCvtCreate (pScrn, CVT_OP_M2M);
292             XDBG_GOTO_IF_FAIL (tv->cvt != NULL, fail_connect);
293             secCvtAddCallback (tv->cvt, _secVideoTvCvtCallback, tv);
294         }
295         else
296         {
297             XDBG_DEBUG(MTVO, "Not need converting id(%c%c%c%c)\n", FOURCC_STR (id));
298             convert_id = id;
299         }
300     }
301
302     XDBG_DEBUG (MTVO, "id(%c%c%c%c), lpos(%d)!\n", FOURCC_STR (id), lpos);
303     tv->output = LAYER_OUTPUT_EXT;
304     tv->pScrn = pScrn;
305     tv->lpos = lpos;
306     tv->outbuf_index = -1;
307     tv->convert_id = convert_id;
308     tv->outbuf_num = TVBUF_NUM;
309     tv->src_id = id;
310
311     return tv;
312
313 fail_connect:
314     if (tv)
315     {
316         if (tv->cvt)
317             secCvtDestroy (tv->cvt);
318         free (tv);
319     }
320     return NULL;
321 }
322
323 Bool
324 secVideoTvResizeOutput (SECVideoTv* tv, xRectanglePtr src, xRectanglePtr dst)
325 {
326     if (tv == NULL)
327         return FALSE;
328
329     if (tv->outbuf)
330     {
331         int i;
332         for (i = 0; i < tv->outbuf_num; i++)
333             if (tv->outbuf[i])
334                 secUtilVideoBufferUnref (tv->outbuf[i]);
335
336         free (tv->outbuf);
337         tv->outbuf = NULL;
338     }
339
340     if (tv->cvt)
341     {
342         secCvtDestroy (tv->cvt);
343         tv->cvt = NULL;
344     }
345
346     if (!secVideoCanDirectDrawing (tv, src->width, src->height,
347                                    dst->width, dst->height))
348     {
349         secVideoTvReCreateConverter(tv);
350     }
351
352     secLayerFreezeUpdate (tv->layer, TRUE);
353     tv->is_resized = 1;
354     return TRUE;
355 }
356
357 void
358 secVideoTvDisconnect (SECVideoTv* tv)
359 {
360     int i;
361
362     XDBG_RETURN_IF_FAIL (tv != NULL);
363
364     XDBG_DEBUG (MTVO, "!\n");
365
366     if (tv->cvt)
367         secCvtDestroy (tv->cvt);
368
369     _secVideoTvLayerDestroy (tv);
370
371     if (tv->outbuf)
372     {
373         for (i = 0; i < tv->outbuf_num; i++)
374             if (tv->outbuf[i])
375                 secUtilVideoBufferUnref (tv->outbuf[i]);
376
377         free (tv->outbuf);
378     }
379
380     free (tv);
381 }
382
383 Bool
384 secVideoTvSetBuffer (SECVideoTv* tv, SECVideoBuf **vbufs, int bufnum)
385 {
386     int i;
387
388     XDBG_RETURN_VAL_IF_FAIL (tv != NULL, FALSE);
389     XDBG_RETURN_VAL_IF_FAIL (vbufs != NULL, FALSE);
390     XDBG_RETURN_VAL_IF_FAIL (bufnum >= TVBUF_NUM, FALSE);
391
392     if (tv->outbuf)
393     {
394         XDBG_ERROR (MTVO, "already has buffers.\n");
395         return FALSE;
396     }
397
398     tv->outbuf_num = bufnum;
399     tv->outbuf = (SECVideoBuf**)calloc (bufnum, sizeof (SECVideoBuf*));
400     XDBG_RETURN_VAL_IF_FAIL (tv->outbuf != NULL, FALSE);
401
402     for (i = 0; i < tv->outbuf_num; i++)
403     {
404         XDBG_GOTO_IF_FAIL (tv->convert_id == vbufs[i]->id, fail_set_buffer);
405         XDBG_GOTO_IF_FAIL (tv->tv_width == vbufs[i]->width, fail_set_buffer);
406         XDBG_GOTO_IF_FAIL (tv->tv_height == vbufs[i]->height, fail_set_buffer);
407
408         tv->outbuf[i] = secUtilVideoBufferRef (vbufs[i]);
409         XDBG_GOTO_IF_FAIL (tv->outbuf[i] != NULL, fail_set_buffer);
410
411         if (!tv->outbuf[i]->showing && tv->outbuf[i]->need_reset)
412             secUtilClearVideoBuffer (tv->outbuf[i]);
413         else
414             tv->outbuf[i]->need_reset = TRUE;
415     }
416
417     return TRUE;
418
419 fail_set_buffer:
420     if (tv->outbuf)
421     {
422         for (i = 0; i < tv->outbuf_num; i++)
423         {
424             if (tv->outbuf[i])
425             {
426                 secUtilVideoBufferUnref (tv->outbuf[i]);
427                 tv->outbuf[i] = NULL;
428             }
429         }
430
431         free (tv->outbuf);
432         tv->outbuf = NULL;
433     }
434
435     return FALSE;
436 }
437 SECLayerPos
438 secVideoTvGetPos (SECVideoTv *tv)
439 {
440     XDBG_RETURN_VAL_IF_FAIL (tv != NULL, LAYER_NONE);
441
442     return tv->lpos;
443 }
444
445 SECLayer*
446 secVideoTvGetLayer (SECVideoTv *tv)
447 {
448     XDBG_RETURN_VAL_IF_FAIL (tv != NULL, NULL);
449
450     _secVideoTvLayerEnsure (tv);
451
452     return tv->layer;
453 }
454
455 /* HDMI    : 'handles' is "gem handle"
456  * VIRTUAL : 'handles' is "physical address"
457  *           'data' is "raw data"
458  *           only one of 'handles' and 'data' has value.
459  */
460 int
461 secVideoTvPutImage (SECVideoTv *tv, SECVideoBuf *vbuf, xRectangle *rect, int csc_range)
462 {
463     XDBG_RETURN_VAL_IF_FAIL (tv != NULL, 0);
464     XDBG_RETURN_VAL_IF_FAIL (VBUF_IS_VALID (vbuf), 0);
465     XDBG_RETURN_VAL_IF_FAIL (vbuf->id > 0, 0);
466     XDBG_RETURN_VAL_IF_FAIL (rect != NULL, 0);
467
468     XDBG_RETURN_VAL_IF_FAIL (vbuf->handles[0] > 0, 0);
469     XDBG_RETURN_VAL_IF_FAIL (vbuf->pitches[0] > 0, 0);
470     XDBG_RETURN_VAL_IF_FAIL (rect->width > 0, 0);
471     XDBG_RETURN_VAL_IF_FAIL (rect->height > 0, 0);
472     XDBG_RETURN_VAL_IF_FAIL (vbuf->width > 0, 0);
473     XDBG_RETURN_VAL_IF_FAIL (vbuf->height > 0, 0);
474     _secVideoTvLayerEnsure (tv);
475     XDBG_RETURN_VAL_IF_FAIL (tv->layer != NULL, 0);
476
477     if (tv->cvt)
478     {
479         /* can't show buffer to HDMI at now. */
480         SECModePtr pSecMode = (SECModePtr) SECPTR (tv->pScrn)->pSecMode;
481         SECCvtProp src_prop = {0,}, dst_prop = {0,};
482         SECVideoBuf *outbuf;
483         int dst_width, dst_height;
484         xRectangle dst_crop;
485
486
487         /* CHECK */
488         if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
489         {
490             XDBG_RETURN_VAL_IF_FAIL (tv->tv_width > 0, 0);
491             XDBG_RETURN_VAL_IF_FAIL (tv->tv_height > 0, 0);
492             dst_width = tv->tv_width;
493             dst_height = tv->tv_height;
494             dst_crop = *rect;
495
496             tv->tv_rect.x = 0;
497             tv->tv_rect.y = 0;
498             tv->tv_rect.width = tv->tv_width;
499             tv->tv_rect.height = tv->tv_height;
500         }
501         else
502         {
503             dst_width = rect->width;
504             dst_height = rect->height;
505             dst_crop = *rect;
506             dst_crop.x = 0;
507             dst_crop.y = 0;
508
509             tv->tv_rect = *rect;
510         }
511
512         src_prop.id = vbuf->id;
513         src_prop.width = vbuf->width;
514         src_prop.height = vbuf->height;
515         src_prop.crop = vbuf->crop;
516
517         dst_prop.id = tv->convert_id;
518         dst_prop.width = dst_width;
519         dst_prop.height = dst_height;
520         dst_prop.crop = dst_crop;
521         dst_prop.secure = vbuf->secure;
522         dst_prop.csc_range = csc_range;
523
524         if (!secCvtEnsureSize (&src_prop, &dst_prop))
525             return 0;
526
527         outbuf = _secVideoTvGetOutBuffer (tv, dst_prop.width, dst_prop.height, vbuf->secure);
528         if (!outbuf)
529             return 0;
530         outbuf->crop = dst_prop.crop;
531
532         if (!secCvtSetProperpty (tv->cvt, &src_prop, &dst_prop))
533             return 0;
534
535         if (!secCvtConvert (tv->cvt, vbuf, outbuf))
536             return 0;
537
538         XDBG_TRACE (MTVO, "'%c%c%c%c' %dx%d (%d,%d %dx%d) => '%c%c%c%c' %dx%d (%d,%d %dx%d) convert. rect(%d,%d %dx%d)\n",
539                     FOURCC_STR (vbuf->id), vbuf->width, vbuf->height,
540                     vbuf->crop.x, vbuf->crop.y, vbuf->crop.width, vbuf->crop.height,
541                     FOURCC_STR (outbuf->id), outbuf->width, outbuf->height,
542                     outbuf->crop.x, outbuf->crop.y, outbuf->crop.width, outbuf->crop.height,
543                     rect->x, rect->y, rect->width, rect->height);
544
545         return 1;
546     }
547     /* can show buffer to HDMI at now. */
548     return _secVideoTvPutImageInternal (tv, vbuf, rect);
549 }
550
551 void
552 secVideoTvSetSize (SECVideoTv *tv, int width, int height)
553 {
554     XDBG_RETURN_IF_FAIL (tv != NULL);
555
556     tv->tv_width = width;
557     tv->tv_height = height;
558
559     XDBG_TRACE (MTVO, "size(%dx%d) \n", width, height);
560 }
561
562 SECCvt*
563 secVideoTvGetConverter (SECVideoTv *tv)
564 {
565     XDBG_RETURN_VAL_IF_FAIL (tv != NULL, NULL);
566
567     return tv->cvt;
568 }
569
570 void
571 secVideoTvSetConvertFormat (SECVideoTv *tv, unsigned int convert_id)
572 {
573     XDBG_RETURN_IF_FAIL (tv != NULL);
574     XDBG_RETURN_IF_FAIL (convert_id > 0);
575
576     tv->convert_id = convert_id;
577
578     XDBG_TRACE (MTVO, "convert_id(%c%c%c%c) \n", FOURCC_STR (convert_id));
579 }
580
581 Bool
582 secVideoCanDirectDrawing (SECVideoTv *tv, int src_w, int src_h, int dst_w, int dst_h)
583 {
584     XDBG_RETURN_VAL_IF_FAIL(src_w != 0, FALSE);
585     XDBG_RETURN_VAL_IF_FAIL(src_h != 0, FALSE);
586     XDBG_RETURN_VAL_IF_FAIL(dst_w != 0, FALSE);
587     XDBG_RETURN_VAL_IF_FAIL(dst_h != 0, FALSE);
588     int ratio_w = 0;
589     int ratio_h = 0;
590     XDBG_DEBUG(MTVO, "tv(%p) src_w %d, src_h %d, dst_w %d, dst_h %d\n",
591                tv, src_w, src_h, dst_w, dst_h);
592     if (src_w >= dst_w)
593     {
594         ratio_w = src_w / dst_w;
595         if (ratio_w > 4)
596         {
597             XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (1/%d) < 1/4\n", ratio_w);
598             return FALSE;
599         }
600         XDBG_DEBUG(MTVO, "ratio_w = 1/%d\n", ratio_w);
601     }
602     else if (src_w < dst_w)
603     {
604         ratio_w = dst_w / src_w;
605         if (ratio_w > 16)
606         {
607             XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (%d) > 16\n", ratio_w);
608             return FALSE;
609         }
610         XDBG_DEBUG(MTVO, "ratio_w = %d\n", ratio_w);
611     }
612
613     if (src_h >= dst_h)
614     {
615         ratio_h = src_h / dst_h;
616         if (ratio_h > 4)
617         {
618             XDBG_DEBUG(MTVO, "Can't direct draw ratio_h (1/%d) < 1/4\n", ratio_w);
619             return FALSE;
620         }
621         XDBG_DEBUG(MTVO, "ratio_h = 1/%d\n", ratio_h);
622     }
623     else if (src_h < dst_h)
624     {
625         ratio_h = dst_h / src_h;
626         if (ratio_h > 16)
627         {
628             XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (%d) > 16\n", ratio_w);
629             return FALSE;
630         }
631         XDBG_DEBUG(MTVO, "ratio_h = %d\n", ratio_h);
632     }
633
634     if (ratio_w != ratio_h)
635     {
636         XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (%d) != ratio_h (%d)\n", ratio_w, ratio_h);
637         return FALSE;
638     }
639
640     if (tv != NULL)
641     {
642         if (!secLayerSupport (tv->pScrn, tv->output, tv->lpos, tv->src_id))
643         {
644             XDBG_DEBUG(MTVO, "Can't direct draw. Layer not support. lpos(%d), src_id (%c%c%c%c)\n",
645             tv->lpos, FOURCC_STR(tv->src_id));
646             return FALSE;
647         }
648     }
649     XDBG_DEBUG(MTVO, "Support direct drawing\n");
650     return TRUE;
651 }
652
653 Bool
654 secVideoTvReCreateConverter(SECVideoTv* tv)
655 {
656     if (tv == NULL)
657         return FALSE;
658     if (tv->cvt)
659     {
660          secCvtDestroy (tv->cvt);
661     }
662     tv->cvt = secCvtCreate (tv->pScrn, CVT_OP_M2M);
663     XDBG_RETURN_VAL_IF_FAIL (tv->cvt != NULL, FALSE);
664     secCvtAddCallback (tv->cvt, _secVideoTvCvtCallback, tv);
665     return TRUE;
666 }