576addf194bf579ad5815efb47b7adea5db32db3
1 /*
2 * Copyright (c) 2013-2014, Texas Instruments Incorporated
3 * Author: alaganraj <alaganraj.s@ti.com>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * Contact information for paper mail:
33 * Texas Instruments
34 * Post Office Box 655303
35 * Dallas, Texas 75265
36 * Contact information:
37 * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
38 * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
39 * ============================================================================
40 *
41 */
43 /*
44 * @File vpe-common.c
45 * @Brief vpe specific common functions, used to integrate vpe
46 * with other modules.
47 *
48 * Input buffer must be allocated in application, queue it to vpe
49 * by passing buffer index
50 *
51 * Output buffer allocated in vpe_output_init() as vpe output intended
52 * to display on LCD.
53 */
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <fcntl.h>
57 #include <unistd.h>
58 #include <stdint.h>
59 #include <string.h>
60 #include <errno.h>
62 #include <linux/videodev2.h>
63 #include <linux/v4l2-controls.h>
65 #include <sys/mman.h>
66 #include <sys/ioctl.h>
68 #include <xf86drm.h>
69 #include <omap_drm.h>
70 #include <omap_drmif.h>
72 #include "util.h"
74 #define pexit(fmt, arg...) { \
75 printf(fmt, ## arg); \
76 exit(1); \
77 }
79 #define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_PRIVATE_BASE)
80 #define NUMBUF 6
82 //#define vpe_debug
84 #ifdef vpe_debug
85 #define dprintf(fmt, arg...) printf(fmt, ## arg)
86 #else
87 #define dprintf(fmt, arg...) do {} while(0)
88 #endif
90 struct image_params {
91 int width;
92 int height;
93 int fourcc;
94 int size;
95 int size_uv;
96 int coplanar;
97 enum v4l2_colorspace colorspace;
98 int numbuf;
99 };
101 struct vpe {
102 int fd;
103 int field;
104 int deint;
105 int translen;
106 struct image_params src;
107 struct image_params dst;
108 struct v4l2_crop crop;
109 int input_buf_dmafd[NUMBUF];
110 int input_buf_dmafd_uv[NUMBUF];
111 int output_buf_dmafd[NUMBUF];
112 int output_buf_dmafd_uv[NUMBUF];
113 struct display *disp;
114 struct buffer **disp_bufs;
115 };
117 /**
118 *****************************************************************************
119 * @brief: open the device
120 *
121 * @return: vpe struct vpe pointer
122 *****************************************************************************
123 */
124 struct vpe *vpe_open(void)
125 {
126 char devname[20] = "/dev/video0";
127 struct vpe *vpe;
129 vpe = calloc(1, sizeof(*vpe));
131 vpe->fd = open(devname, O_RDWR);
132 if(vpe->fd < 0)
133 pexit("Cant open %s\n", devname);
135 printf("vpe:%s open success!!!\n", devname);
137 return vpe;
138 }
140 /**
141 *****************************************************************************
142 * @brief: close the device and free memory
143 *
144 * @param: vpe struct vpe pointer
145 *
146 * @return: 0 on success
147 *****************************************************************************
148 */
149 int vpe_close(struct vpe *vpe)
150 {
151 close(vpe->fd);
152 free(vpe);
154 return 0;
155 }
157 /**
158 *****************************************************************************
159 * @brief: fills 4cc, size, coplanar, colorspace based on command line input
160 *
161 * @param: format char pointer
162 * @param: image struct image_params pointer
163 *
164 * @return: 0 on success
165 *****************************************************************************
166 */
167 int describeFormat (char *format, struct image_params *image)
168 {
169 image->size = -1;
170 image->fourcc = -1;
171 if (strcmp (format, "rgb24") == 0) {
172 image->fourcc = V4L2_PIX_FMT_RGB24;
173 image->size = image->height * image->width * 3;
174 image->coplanar = 0;
175 image->colorspace = V4L2_COLORSPACE_SRGB;
177 } else if (strcmp (format, "bgr24") == 0) {
178 image->fourcc = V4L2_PIX_FMT_BGR24;
179 image->size = image->height * image->width * 3;
180 image->coplanar = 0;
181 image->colorspace = V4L2_COLORSPACE_SRGB;
183 } else if (strcmp (format, "argb32") == 0) {
184 image->fourcc = V4L2_PIX_FMT_RGB32;
185 image->size = image->height * image->width * 4;
186 image->coplanar = 0;
187 image->colorspace = V4L2_COLORSPACE_SRGB;
189 } else if (strcmp (format, "abgr32") == 0) {
190 image->fourcc = V4L2_PIX_FMT_BGR32;
191 image->size = image->height * image->width * 4;
192 image->coplanar = 0;
193 image->colorspace = V4L2_COLORSPACE_SRGB;
195 } else if (strcmp (format, "yuv444") == 0) {
196 image->fourcc = V4L2_PIX_FMT_YUV444;
197 image->size = image->height * image->width * 3;
198 image->coplanar = 0;
199 image->colorspace = V4L2_COLORSPACE_SMPTE170M;
201 } else if (strcmp (format, "yvyu") == 0) {
202 image->fourcc = V4L2_PIX_FMT_YVYU;
203 image->size = image->height * image->width * 2;
204 image->coplanar = 0;
205 image->colorspace = V4L2_COLORSPACE_SMPTE170M;
207 } else if (strcmp (format, "yuyv") == 0) {
208 image->fourcc = V4L2_PIX_FMT_YUYV;
209 image->size = image->height * image->width * 2;
210 image->coplanar = 0;
211 image->colorspace = V4L2_COLORSPACE_SMPTE170M;
213 } else if (strcmp (format, "uyvy") == 0) {
214 image->fourcc = V4L2_PIX_FMT_UYVY;
215 image->size = image->height * image->width * 2;
216 image->coplanar = 0;
217 image->colorspace = V4L2_COLORSPACE_SMPTE170M;
219 } else if (strcmp (format, "vyuy") == 0) {
220 image->fourcc = V4L2_PIX_FMT_VYUY;
221 image->size = image->height * image->width * 2;
222 image->coplanar = 0;
223 image->colorspace = V4L2_COLORSPACE_SMPTE170M;
225 } else if (strcmp (format, "nv16") == 0) {
226 image->fourcc = V4L2_PIX_FMT_NV16;
227 image->size = image->height * image->width * 2;
228 image->coplanar = 0;
229 image->colorspace = V4L2_COLORSPACE_SMPTE170M;
231 } else if (strcmp (format, "nv61") == 0) {
232 image->fourcc = V4L2_PIX_FMT_NV61;
233 image->size = image->height * image->width * 2;
234 image->coplanar = 0;
235 image->colorspace = V4L2_COLORSPACE_SMPTE170M;
237 } else if (strcmp (format, "nv12") == 0) {
238 image->fourcc = V4L2_PIX_FMT_NV12;
239 image->size = image->height * image->width * 1.5;
240 image->coplanar = 1;
241 image->colorspace = V4L2_COLORSPACE_SMPTE170M;
243 } else if (strcmp (format, "nv21") == 0) {
244 image->fourcc = V4L2_PIX_FMT_NV21;
245 image->size = image->height * image->width * 1.5;
246 image->coplanar = 1;
247 image->colorspace = V4L2_COLORSPACE_SMPTE170M;
249 } else {
250 return 0;
252 }
254 return 1;
255 }
257 /**
258 *****************************************************************************
259 * @brief: sets crop parameters
260 *
261 * @param: vpe struct vpe pointer
262 *
263 * @return: 0 on success
264 *****************************************************************************
265 */
266 static int set_crop(struct vpe *vpe)
267 {
268 int ret = 0;
270 if ((vpe->crop.c.top == 0) && (vpe->crop.c.left == 0) &&
271 (vpe->crop.c.width == 0) && (vpe->crop.c.height == 0)) {
272 dprintf("setting default crop params\n");
273 vpe->crop.c.top = 0;
274 vpe->crop.c.left = 0;
275 vpe->crop.c.width = vpe->src.width;
276 vpe->crop.c.height = vpe->src.height;
277 vpe->crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
278 }
280 ret = ioctl(vpe->fd, VIDIOC_S_CROP, &vpe->crop);
281 if (ret < 0)
282 pexit("error setting crop\n");
284 return 0;
285 }
287 /**
288 *****************************************************************************
289 * @brief: sets control, howmany jobs to be handled on multi instance
290 *
291 * @param: vpe struct vpe pointer
292 *
293 * @return: 0 on success
294 *****************************************************************************
295 */
296 static int set_ctrl(struct vpe *vpe)
297 {
298 int ret;
299 struct v4l2_control ctrl;
301 memset(&ctrl, 0, sizeof(ctrl));
302 ctrl.id = V4L2_CID_TRANS_NUM_BUFS;
303 ctrl.value = vpe->translen;
304 ret = ioctl(vpe->fd, VIDIOC_S_CTRL, &ctrl);
305 if (ret < 0)
306 pexit("vpe: S_CTRL failed\n");
308 return 0;
309 }
311 /**
312 *****************************************************************************
313 * @brief: Intialize the vpe input by calling set_control, set_format,
314 * set_crop, refbuf ioctls
315 *
316 * @param: vpe struct vpe pointer
317 *
318 * @return: 0 on success
319 *****************************************************************************
320 */
321 int vpe_input_init(struct vpe *vpe)
322 {
323 int ret;
324 struct v4l2_format fmt;
325 struct v4l2_requestbuffers rqbufs;
327 set_ctrl(vpe);
329 memset(&fmt, 0, sizeof fmt);
330 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
332 ret = ioctl(vpe->fd, VIDIOC_G_FMT, &fmt);
333 if (ret < 0)
334 pexit( "vpe i/p: G_FMT_1 failed: %s\n", strerror(errno));
336 fmt.fmt.pix_mp.width = vpe->src.width;
337 fmt.fmt.pix_mp.height = vpe->src.height;
338 fmt.fmt.pix_mp.pixelformat = vpe->src.fourcc;
340 switch (vpe->deint) {
341 case 1:
342 fmt.fmt.pix_mp.field = V4L2_FIELD_ALTERNATE;
343 break;
344 case 2:
345 fmt.fmt.pix_mp.field = V4L2_FIELD_SEQ_TB;
346 break;
347 case 0:
348 default:
349 fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
350 break;
351 }
353 ret = ioctl(vpe->fd, VIDIOC_S_FMT, &fmt);
354 if (ret < 0) {
355 pexit( "vpe i/p: S_FMT failed: %s\n", strerror(errno));
356 } else {
357 vpe->src.size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
358 vpe->src.size_uv = fmt.fmt.pix_mp.plane_fmt[1].sizeimage;
359 }
361 ret = ioctl(vpe->fd, VIDIOC_G_FMT, &fmt);
362 if (ret < 0)
363 pexit( "vpe i/p: G_FMT_2 failed: %s\n", strerror(errno));
365 printf("vpe i/p: G_FMT: width = %u, height = %u, 4cc = %.4s\n",
366 fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
367 (char*)&fmt.fmt.pix_mp.pixelformat);
369 set_crop(vpe);
371 memset(&rqbufs, 0, sizeof(rqbufs));
372 rqbufs.count = NUMBUF;
373 rqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
374 rqbufs.memory = V4L2_MEMORY_DMABUF;
376 ret = ioctl(vpe->fd, VIDIOC_REQBUFS, &rqbufs);
377 if (ret < 0)
378 pexit( "vpe i/p: REQBUFS failed: %s\n", strerror(errno));
380 vpe->src.numbuf = rqbufs.count;
381 dprintf("vpe i/p: allocated buffers = %d\n", rqbufs.count);
383 return 0;
385 }
387 /**
388 *****************************************************************************
389 * @brief: Initialize vpe output by calling set_format, reqbuf ioctls.
390 * Also allocates buffer to display the vpe output.
391 *
392 * @param: vpe struct vpe pointer
393 *
394 * @return: 0 on success
395 *****************************************************************************
396 */
397 int vpe_output_init(struct vpe *vpe)
398 {
399 int ret, i;
400 struct v4l2_format fmt;
401 struct v4l2_requestbuffers rqbufs;
403 memset(&fmt, 0, sizeof fmt);
404 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
406 ret = ioctl(vpe->fd, VIDIOC_G_FMT, &fmt);
407 if (ret < 0)
408 pexit( "vpe o/p: G_FMT_1 failed: %s\n", strerror(errno));
410 fmt.fmt.pix_mp.width = vpe->dst.width;
411 fmt.fmt.pix_mp.height = vpe->dst.height;
412 fmt.fmt.pix_mp.pixelformat = vpe->dst.fourcc;
413 fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
415 ret = ioctl(vpe->fd, VIDIOC_S_FMT, &fmt);
416 if (ret < 0)
417 pexit( "vpe o/p: S_FMT failed: %s\n", strerror(errno));
419 ret = ioctl(vpe->fd, VIDIOC_G_FMT, &fmt);
420 if (ret < 0)
421 pexit( "vpe o/p: G_FMT_2 failed: %s\n", strerror(errno));
423 printf("vpe o/p: G_FMT: width = %u, height = %u, 4cc = %.4s\n",
424 fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
425 (char*)&fmt.fmt.pix_mp.pixelformat);
427 memset(&rqbufs, 0, sizeof(rqbufs));
428 rqbufs.count = NUMBUF;
429 rqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
430 rqbufs.memory = V4L2_MEMORY_DMABUF;
432 ret = ioctl(vpe->fd, VIDIOC_REQBUFS, &rqbufs);
433 if (ret < 0)
434 pexit( "vpe o/p: REQBUFS failed: %s\n", strerror(errno));
436 vpe->dst.numbuf = rqbufs.count;
437 dprintf("vpe o/p: allocated buffers = %d\n", rqbufs.count);
439 vpe->disp_bufs = disp_get_vid_buffers(vpe->disp, NUMBUF, vpe->dst.fourcc,
440 vpe->dst.width, vpe->dst.height);
441 if (!vpe->disp_bufs)
442 pexit("allocating display buffer failed\n");
444 for (i = 0; i < NUMBUF; i++) {
445 vpe->output_buf_dmafd[i] = omap_bo_dmabuf(vpe->disp_bufs[i]->bo[0]);
446 vpe->disp_bufs[i]->fd[0] = vpe->output_buf_dmafd[i];
448 if(vpe->dst.coplanar) {
449 vpe->output_buf_dmafd_uv[i] = omap_bo_dmabuf(vpe->disp_bufs[i]->bo[1]);
450 vpe->disp_bufs[i]->fd[1] = vpe->output_buf_dmafd_uv[i];
451 }
452 /* display only image widthxheight, no full screen */
453 vpe->disp_bufs[i]->noScale = true;
454 dprintf("vpe->disp_bufs_fd[%d] = %d\n", i, vpe->output_buf_dmafd[i]);
455 }
457 dprintf("allocating display buffer success\n");
458 return 0;
459 }
461 /**
462 *****************************************************************************
463 * @brief: queue buffer to vpe input
464 *
465 * @param: vpe struct vpe pointer
466 * @param: index buffer index to queue
467 *
468 * @return: 0 on success
469 *****************************************************************************
470 */
471 int vpe_input_qbuf(struct vpe *vpe, int index)
472 {
473 int ret, i;
474 struct v4l2_buffer buf;
475 struct v4l2_plane planes[2];
477 dprintf("vpe: src QBUF (%d):%s field", vpe->field,
478 vpe->field==V4L2_FIELD_TOP?"top":"bottom");
480 memset(&buf, 0, sizeof buf);
481 memset(&planes, 0, sizeof planes);
483 planes[0].length = planes[0].bytesused = vpe->src.size;
484 if(vpe->src.coplanar)
485 planes[1].length = planes[1].bytesused = vpe->src.size_uv;
487 planes[0].data_offset = planes[1].data_offset = 0;
489 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
490 buf.memory = V4L2_MEMORY_DMABUF;
491 buf.index = index;
492 buf.m.planes = &planes;
493 buf.field = vpe->field;
494 if(vpe->src.coplanar)
495 buf.length = 2;
496 else
497 buf.length = 1;
499 buf.m.planes[0].m.fd = vpe->input_buf_dmafd[index];
500 if(vpe->src.coplanar)
501 buf.m.planes[1].m.fd = vpe->input_buf_dmafd_uv[index];
503 ret = ioctl(vpe->fd, VIDIOC_QBUF, &buf);
504 if (ret < 0)
505 pexit( "vpe i/p: QBUF failed: %s, index = %d\n",
506 strerror(errno), index);
508 return 0;
509 }
511 /**
512 *****************************************************************************
513 * @brief: queue buffer to vpe output
514 *
515 * @param: vpe struct vpe pointer
516 * @param: index buffer index to queue
517 *
518 * @return: 0 on success
519 *****************************************************************************
520 */
521 int vpe_output_qbuf(struct vpe *vpe, int index)
522 {
523 int ret, i;
524 struct v4l2_buffer buf;
525 struct v4l2_plane planes[2];
527 dprintf("vpe output buffer queue\n");
529 memset(&buf, 0, sizeof buf);
530 memset(&planes, 0, sizeof planes);
532 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
533 buf.memory = V4L2_MEMORY_DMABUF;
534 buf.index = index;
535 buf.m.planes = &planes;
536 if(vpe->dst.coplanar)
537 buf.length = 2;
538 else
539 buf.length = 1;
541 buf.m.planes[0].m.fd = vpe->output_buf_dmafd[index];
543 if(vpe->dst.coplanar)
544 buf.m.planes[1].m.fd = vpe->output_buf_dmafd_uv[index];
546 ret = ioctl(vpe->fd, VIDIOC_QBUF, &buf);
547 if (ret < 0)
548 pexit( "vpe o/p: QBUF failed: %s, index = %d\n",
549 strerror(errno), index);
551 return 0;
552 }
554 /**
555 *****************************************************************************
556 * @brief: start stream
557 *
558 * @param: fd device fd
559 * @param: type buffer type (CAPTURE or OUTPUT)
560 *
561 * @return: 0 on success
562 *****************************************************************************
563 */
564 int stream_ON(int fd, int type)
565 {
566 int ret;
568 ret = ioctl(fd, VIDIOC_STREAMON, &type);
569 if (ret < 0)
570 pexit("STREAMON failed, %d: %s\n", type, strerror(errno));
572 dprintf("stream ON: done! fd = %d, type = %d\n", fd, type);
574 return 0;
575 }
577 /**
578 *****************************************************************************
579 * @brief: stop stream
580 *
581 * @param: fd device fd
582 * @param: type buffer type (CAPTURE or OUTPUT)
583 *
584 * @return: 0 on success
585 *****************************************************************************
586 */
587 int stream_OFF(int fd, int type)
588 {
589 int ret;
591 ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
592 if (ret < 0)
593 pexit("STREAMOFF failed, %d: %s\n", type, strerror(errno));
595 dprintf("stream OFF: done! fd = %d, type = %d\n", fd, type);
597 return 0;
598 }
600 /**
601 *****************************************************************************
602 * @brief: dequeue vpe input buffer
603 *
604 * @param: vpe struct vpe pointer
605 *
606 * @return: buf.index index of dequeued buffer
607 *****************************************************************************
608 */
609 int vpe_input_dqbuf(struct vpe *vpe)
610 {
611 int ret;
612 struct v4l2_buffer buf;
613 struct v4l2_plane planes[2];
615 dprintf("vpe input dequeue buffer\n");
617 memset(&buf, 0, sizeof buf);
618 memset(&planes, 0, sizeof planes);
620 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
621 buf.memory = V4L2_MEMORY_DMABUF;
622 buf.m.planes = &planes;
623 if(vpe->src.coplanar)
624 buf.length = 2;
625 else
626 buf.length = 1;
627 ret = ioctl(vpe->fd, VIDIOC_DQBUF, &buf);
628 if (ret < 0)
629 pexit("vpe i/p: DQBUF failed: %s\n", strerror(errno));
631 dprintf("vpe i/p: DQBUF index = %d\n", buf.index);
633 return buf.index;
634 }
636 /**
637 *****************************************************************************
638 * @brief: dequeue vpe output buffer
639 *
640 * @param: vpe struct vpe pointer
641 *
642 * @return: buf.index index of dequeued buffer
643 *****************************************************************************
644 */
645 int vpe_output_dqbuf(struct vpe *vpe)
646 {
647 int ret;
648 struct v4l2_buffer buf;
649 struct v4l2_plane planes[2];
651 dprintf("vpe output dequeue buffer\n");
653 memset(&buf, 0, sizeof buf);
654 memset(&planes, 0, sizeof planes);
656 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
657 buf.memory = V4L2_MEMORY_DMABUF;
658 buf.m.planes = &planes;
659 if(vpe->dst.coplanar)
660 buf.length = 2;
661 else
662 buf.length = 1;
663 ret = ioctl(vpe->fd, VIDIOC_DQBUF, &buf);
664 if (ret < 0)
665 pexit("vpe o/p: DQBUF failed: %s\n", strerror(errno));
667 dprintf("vpe o/p: DQBUF index = %d\n", buf.index);
669 return buf.index;
670 }
672 /**
673 *****************************************************************************
674 * @brief: buffer retried by index and displays the contents
675 *
676 * @param: vpe struct vpe pointer
677 * @param: index index of dequeued output buffer
678 *
679 * @return: 0 on success
680 *****************************************************************************
681 */
682 int display_buffer(struct vpe *vpe, int index)
683 {
684 int ret;
685 struct buffer *buf;
687 buf = vpe->disp_bufs[index];
688 ret = disp_post_vid_buffer(vpe->disp, buf, 0, 0, vpe->dst.width,
689 vpe->dst.height);
690 if (ret)
691 pexit("disp post vid buf failed\n");
693 return 0;
694 }