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;
339 fmt.fmt.pix_mp.colorspace = vpe->src.colorspace;
341 switch (vpe->deint) {
342 case 1:
343 fmt.fmt.pix_mp.field = V4L2_FIELD_ALTERNATE;
344 break;
345 case 2:
346 fmt.fmt.pix_mp.field = V4L2_FIELD_SEQ_TB;
347 break;
348 case 0:
349 default:
350 fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
351 break;
352 }
354 ret = ioctl(vpe->fd, VIDIOC_S_FMT, &fmt);
355 if (ret < 0) {
356 pexit( "vpe i/p: S_FMT failed: %s\n", strerror(errno));
357 } else {
358 vpe->src.size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
359 vpe->src.size_uv = fmt.fmt.pix_mp.plane_fmt[1].sizeimage;
360 }
362 ret = ioctl(vpe->fd, VIDIOC_G_FMT, &fmt);
363 if (ret < 0)
364 pexit( "vpe i/p: G_FMT_2 failed: %s\n", strerror(errno));
366 printf("vpe i/p: G_FMT: width = %u, height = %u, 4cc = %.4s\n",
367 fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
368 (char*)&fmt.fmt.pix_mp.pixelformat);
370 set_crop(vpe);
372 memset(&rqbufs, 0, sizeof(rqbufs));
373 rqbufs.count = NUMBUF;
374 rqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
375 rqbufs.memory = V4L2_MEMORY_DMABUF;
377 ret = ioctl(vpe->fd, VIDIOC_REQBUFS, &rqbufs);
378 if (ret < 0)
379 pexit( "vpe i/p: REQBUFS failed: %s\n", strerror(errno));
381 vpe->src.numbuf = rqbufs.count;
382 dprintf("vpe i/p: allocated buffers = %d\n", rqbufs.count);
384 return 0;
386 }
388 /**
389 *****************************************************************************
390 * @brief: Initialize vpe output by calling set_format, reqbuf ioctls.
391 * Also allocates buffer to display the vpe output.
392 *
393 * @param: vpe struct vpe pointer
394 *
395 * @return: 0 on success
396 *****************************************************************************
397 */
398 int vpe_output_init(struct vpe *vpe)
399 {
400 int ret, i;
401 struct v4l2_format fmt;
402 struct v4l2_requestbuffers rqbufs;
404 memset(&fmt, 0, sizeof fmt);
405 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
407 ret = ioctl(vpe->fd, VIDIOC_G_FMT, &fmt);
408 if (ret < 0)
409 pexit( "vpe o/p: G_FMT_1 failed: %s\n", strerror(errno));
411 fmt.fmt.pix_mp.width = vpe->dst.width;
412 fmt.fmt.pix_mp.height = vpe->dst.height;
413 fmt.fmt.pix_mp.pixelformat = vpe->dst.fourcc;
414 fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
415 fmt.fmt.pix_mp.colorspace = vpe->dst.colorspace;
417 ret = ioctl(vpe->fd, VIDIOC_S_FMT, &fmt);
418 if (ret < 0)
419 pexit( "vpe o/p: S_FMT failed: %s\n", strerror(errno));
421 ret = ioctl(vpe->fd, VIDIOC_G_FMT, &fmt);
422 if (ret < 0)
423 pexit( "vpe o/p: G_FMT_2 failed: %s\n", strerror(errno));
425 printf("vpe o/p: G_FMT: width = %u, height = %u, 4cc = %.4s\n",
426 fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
427 (char*)&fmt.fmt.pix_mp.pixelformat);
429 memset(&rqbufs, 0, sizeof(rqbufs));
430 rqbufs.count = NUMBUF;
431 rqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
432 rqbufs.memory = V4L2_MEMORY_DMABUF;
434 ret = ioctl(vpe->fd, VIDIOC_REQBUFS, &rqbufs);
435 if (ret < 0)
436 pexit( "vpe o/p: REQBUFS failed: %s\n", strerror(errno));
438 vpe->dst.numbuf = rqbufs.count;
439 dprintf("vpe o/p: allocated buffers = %d\n", rqbufs.count);
441 vpe->disp_bufs = disp_get_vid_buffers(vpe->disp, NUMBUF, vpe->dst.fourcc,
442 vpe->dst.width, vpe->dst.height);
443 if (!vpe->disp_bufs)
444 pexit("allocating display buffer failed\n");
446 for (i = 0; i < NUMBUF; i++) {
447 vpe->output_buf_dmafd[i] = omap_bo_dmabuf(vpe->disp_bufs[i]->bo[0]);
448 vpe->disp_bufs[i]->fd[0] = vpe->output_buf_dmafd[i];
450 if(vpe->dst.coplanar) {
451 vpe->output_buf_dmafd_uv[i] = omap_bo_dmabuf(vpe->disp_bufs[i]->bo[1]);
452 vpe->disp_bufs[i]->fd[1] = vpe->output_buf_dmafd_uv[i];
453 }
454 /* display only image widthxheight, no full screen */
455 vpe->disp_bufs[i]->noScale = true;
456 dprintf("vpe->disp_bufs_fd[%d] = %d\n", i, vpe->output_buf_dmafd[i]);
457 }
459 dprintf("allocating display buffer success\n");
460 return 0;
461 }
463 /**
464 *****************************************************************************
465 * @brief: queue buffer to vpe input
466 *
467 * @param: vpe struct vpe pointer
468 * @param: index buffer index to queue
469 *
470 * @return: 0 on success
471 *****************************************************************************
472 */
473 int vpe_input_qbuf(struct vpe *vpe, int index)
474 {
475 int ret, i;
476 struct v4l2_buffer buf;
477 struct v4l2_plane planes[2];
479 dprintf("vpe: src QBUF (%d):%s field", vpe->field,
480 vpe->field==V4L2_FIELD_TOP?"top":"bottom");
482 memset(&buf, 0, sizeof buf);
483 memset(&planes, 0, sizeof planes);
485 planes[0].length = planes[0].bytesused = vpe->src.size;
486 if(vpe->src.coplanar)
487 planes[1].length = planes[1].bytesused = vpe->src.size_uv;
489 planes[0].data_offset = planes[1].data_offset = 0;
491 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
492 buf.memory = V4L2_MEMORY_DMABUF;
493 buf.index = index;
494 buf.m.planes = &planes;
495 buf.field = vpe->field;
496 if(vpe->src.coplanar)
497 buf.length = 2;
498 else
499 buf.length = 1;
501 buf.m.planes[0].m.fd = vpe->input_buf_dmafd[index];
502 if(vpe->src.coplanar)
503 buf.m.planes[1].m.fd = vpe->input_buf_dmafd_uv[index];
505 ret = ioctl(vpe->fd, VIDIOC_QBUF, &buf);
506 if (ret < 0)
507 pexit( "vpe i/p: QBUF failed: %s, index = %d\n",
508 strerror(errno), index);
510 return 0;
511 }
513 /**
514 *****************************************************************************
515 * @brief: queue buffer to vpe output
516 *
517 * @param: vpe struct vpe pointer
518 * @param: index buffer index to queue
519 *
520 * @return: 0 on success
521 *****************************************************************************
522 */
523 int vpe_output_qbuf(struct vpe *vpe, int index)
524 {
525 int ret, i;
526 struct v4l2_buffer buf;
527 struct v4l2_plane planes[2];
529 dprintf("vpe output buffer queue\n");
531 memset(&buf, 0, sizeof buf);
532 memset(&planes, 0, sizeof planes);
534 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
535 buf.memory = V4L2_MEMORY_DMABUF;
536 buf.index = index;
537 buf.m.planes = &planes;
538 if(vpe->dst.coplanar)
539 buf.length = 2;
540 else
541 buf.length = 1;
543 buf.m.planes[0].m.fd = vpe->output_buf_dmafd[index];
545 if(vpe->dst.coplanar)
546 buf.m.planes[1].m.fd = vpe->output_buf_dmafd_uv[index];
548 ret = ioctl(vpe->fd, VIDIOC_QBUF, &buf);
549 if (ret < 0)
550 pexit( "vpe o/p: QBUF failed: %s, index = %d\n",
551 strerror(errno), index);
553 return 0;
554 }
556 /**
557 *****************************************************************************
558 * @brief: start stream
559 *
560 * @param: fd device fd
561 * @param: type buffer type (CAPTURE or OUTPUT)
562 *
563 * @return: 0 on success
564 *****************************************************************************
565 */
566 int stream_ON(int fd, int type)
567 {
568 int ret;
570 ret = ioctl(fd, VIDIOC_STREAMON, &type);
571 if (ret < 0)
572 pexit("STREAMON failed, %d: %s\n", type, strerror(errno));
574 dprintf("stream ON: done! fd = %d, type = %d\n", fd, type);
576 return 0;
577 }
579 /**
580 *****************************************************************************
581 * @brief: stop stream
582 *
583 * @param: fd device fd
584 * @param: type buffer type (CAPTURE or OUTPUT)
585 *
586 * @return: 0 on success
587 *****************************************************************************
588 */
589 int stream_OFF(int fd, int type)
590 {
591 int ret;
593 ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
594 if (ret < 0)
595 pexit("STREAMOFF failed, %d: %s\n", type, strerror(errno));
597 dprintf("stream OFF: done! fd = %d, type = %d\n", fd, type);
599 return 0;
600 }
602 /**
603 *****************************************************************************
604 * @brief: dequeue vpe input buffer
605 *
606 * @param: vpe struct vpe pointer
607 *
608 * @return: buf.index index of dequeued buffer
609 *****************************************************************************
610 */
611 int vpe_input_dqbuf(struct vpe *vpe)
612 {
613 int ret;
614 struct v4l2_buffer buf;
615 struct v4l2_plane planes[2];
617 dprintf("vpe input dequeue buffer\n");
619 memset(&buf, 0, sizeof buf);
620 memset(&planes, 0, sizeof planes);
622 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
623 buf.memory = V4L2_MEMORY_DMABUF;
624 buf.m.planes = &planes;
625 if(vpe->src.coplanar)
626 buf.length = 2;
627 else
628 buf.length = 1;
629 ret = ioctl(vpe->fd, VIDIOC_DQBUF, &buf);
630 if (ret < 0)
631 pexit("vpe i/p: DQBUF failed: %s\n", strerror(errno));
633 dprintf("vpe i/p: DQBUF index = %d\n", buf.index);
635 return buf.index;
636 }
638 /**
639 *****************************************************************************
640 * @brief: dequeue vpe output buffer
641 *
642 * @param: vpe struct vpe pointer
643 *
644 * @return: buf.index index of dequeued buffer
645 *****************************************************************************
646 */
647 int vpe_output_dqbuf(struct vpe *vpe)
648 {
649 int ret;
650 struct v4l2_buffer buf;
651 struct v4l2_plane planes[2];
653 dprintf("vpe output dequeue buffer\n");
655 memset(&buf, 0, sizeof buf);
656 memset(&planes, 0, sizeof planes);
658 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
659 buf.memory = V4L2_MEMORY_DMABUF;
660 buf.m.planes = &planes;
661 if(vpe->dst.coplanar)
662 buf.length = 2;
663 else
664 buf.length = 1;
665 ret = ioctl(vpe->fd, VIDIOC_DQBUF, &buf);
666 if (ret < 0)
667 pexit("vpe o/p: DQBUF failed: %s\n", strerror(errno));
669 dprintf("vpe o/p: DQBUF index = %d\n", buf.index);
671 return buf.index;
672 }
674 /**
675 *****************************************************************************
676 * @brief: buffer retried by index and displays the contents
677 *
678 * @param: vpe struct vpe pointer
679 * @param: index index of dequeued output buffer
680 *
681 * @return: 0 on success
682 *****************************************************************************
683 */
684 int display_buffer(struct vpe *vpe, int index)
685 {
686 int ret;
687 struct buffer *buf;
689 buf = vpe->disp_bufs[index];
690 ret = disp_post_vid_buffer(vpe->disp, buf, 0, 0, vpe->dst.width,
691 vpe->dst.height);
692 if (ret)
693 pexit("disp post vid buf failed\n");
695 return 0;
696 }