summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 624534a)
raw | patch | inline | side by side (parent: 624534a)
author | Rob Clark <rob@ti.com> | |
Thu, 26 Jan 2012 20:24:26 +0000 (14:24 -0600) | ||
committer | Rob Clark <rob@ti.com> | |
Thu, 26 Jan 2012 20:24:30 +0000 (14:24 -0600) |
.gitignore | patch | blob | history | |
Makefile.am | patch | blob | history | |
README | patch | blob | history | |
configure.ac | patch | blob | history | |
util/Makefile.am | patch | blob | history | |
util/demux.c | [new file with mode: 0644] | patch | blob |
util/demux.h | [new file with mode: 0644] | patch | blob |
util/util.h | patch | blob | history | |
viddec3test.c | [new file with mode: 0644] | patch | blob |
diff --git a/.gitignore b/.gitignore
index b4f9d7d137afb979c2086b8eb95d0718b339ddf6..ef0bd422a83a3bc29b63d83d88713ee4bd55d64c 100644 (file)
--- a/.gitignore
+++ b/.gitignore
# test executables:
dmabuftest
fliptest
+viddec3test
diff --git a/Makefile.am b/Makefile.am
index 95e8e22f4142bd444edb9e8b733261a557ae152c..e176126d2afd42cb21e3d349702713544308ab72 100644 (file)
--- a/Makefile.am
+++ b/Makefile.am
SUBDIRS = util
bin_PROGRAMS = fliptest dmabuftest
-LDADD_COMMON = @DRM_LIBS@ @X11_LIBS@ util/libutil.la
-CFLAGS = @DRM_CFLAGS@ @X11_CFLAGS@ @WARN_CFLAGS@ -I$(top_srcdir)/util
+if ENABLE_DCE
+bin_PROGRAMS += viddec3test
+endif
+
+LDADD_COMMON = util/libutil.la @DRM_LIBS@ @X11_LIBS@ @DCE_LIBS@
+CFLAGS = @DRM_CFLAGS@ @X11_CFLAGS@ @DCE_CFLAGS@ @WARN_CFLAGS@ -I$(top_srcdir)/util
fliptest_SOURCES = fliptest.c
-fliptest_LDADD = $(LDADD_COMMON) util/libutil.la
+fliptest_LDADD = $(LDADD_COMMON)
dmabuftest_SOURCES = dmabuftest.c
-dmabuftest_LDADD = $(LDADD_COMMON) util/libutil.la
+dmabuftest_LDADD = $(LDADD_COMMON)
+
+if ENABLE_DCE
+viddec3test_SOURCES = viddec3test.c
+viddec3test_LDADD = $(LDADD_COMMON)
+endif
index 7c80a3d8ad244615d658a61bd0ee208464b66c7d..e0668abb26566208b8577596a46fc52e198b2d9a 100644 (file)
--- a/README
+++ b/README
A home for omapdrm tests.
+
+Example to run w/ KMS for full-screen overlay display:
+sudo ./viddec3test -s 7:1920x1080 ~/Videos/h264/quantum_of_solace-tlr1_h1080p.mov
+
+Example to run with x11/dri2video for windowed display:
+export DISPLAY=:0.0
+./viddec3test ~/Videos/h264/quantum_of_solace-tlr1_h1080p.mov
diff --git a/configure.ac b/configure.ac
index 47a356510d494d8034660f3d3a93d922e60d2832..06a930f36f04f5620e03a2e8e94ee38b68f9bf2b 100644 (file)
--- a/configure.ac
+++ b/configure.ac
# Check optional X11:
PKG_CHECK_MODULES(X11, x11 libdri2, [HAVE_X11=yes], [HAVE_X11=no])
-
if test "x$HAVE_X11" = "xyes"; then
AC_DEFINE(HAVE_X11, 1, [Have X11 support])
else
fi
AM_CONDITIONAL(ENABLE_X11, [test "x$HAVE_X11" = xyes])
+# Check for libdce and libav..
+PKG_CHECK_MODULES(DCE, libdce libavformat libavutil, [HAVE_DCE=yes], [HAVE_DCE=no])
+if test "x$HAVE_DCE" = "xyes"; then
+ AC_DEFINE(HAVE_DCE, 1, [Have DCE support])
+ AC_MSG_NOTICE([Detected libdce and libavformat, building video codec tests])
+else
+ AC_MSG_WARN([No libdce and/or libavformat support detected, disabling video codec tests])
+fi
+AM_CONDITIONAL(ENABLE_DCE, [test "x$HAVE_DCE" = xyes])
dnl ===========================================================================
dnl check compiler flags
diff --git a/util/Makefile.am b/util/Makefile.am
index 5c063dc58f152819f49d2ed8b47c393424dfcc0e..9d3ddd2fa24b1530d7707866e0f9b1e8c5ba9777 100644 (file)
--- a/util/Makefile.am
+++ b/util/Makefile.am
libutil_la_SOURCES += display-x11.c
endif
-libutil_la_LIBADD = @DRM_LIBS@ @X11_LIBS@
-libutil_la_CFLAGS = @DRM_CFLAGS@ @X11_CFLAGS@ @WARN_CFLAGS@
+if ENABLE_DCE
+libutil_la_SOURCES += demux.c
+endif
+
+libutil_la_LIBADD = @DRM_LIBS@ @X11_LIBS@ @DCE_LIBS@
+libutil_la_CFLAGS = @DRM_CFLAGS@ @X11_CFLAGS@ @DCE_CFLAGS@ @WARN_CFLAGS@
diff --git a/util/demux.c b/util/demux.c
--- /dev/null
+++ b/util/demux.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2011, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+
+#include "util.h"
+
+struct demux {
+ AVFormatContext *afc;
+ AVStream *st;
+ AVCodecContext *cc;
+ AVBitStreamFilterContext *bsf;
+};
+
+static AVFormatContext *
+open_file(const char *filename)
+{
+ AVFormatContext *afc;
+ int err = av_open_input_file(&afc, filename, NULL, 0, NULL);
+
+ if (!err)
+ err = av_find_stream_info(afc);
+
+ if (err < 0) {
+ ERROR("%s: lavf error %d", filename, err);
+ exit(1);
+ }
+
+ dump_format(afc, 0, filename, 0);
+
+ return afc;
+}
+
+static AVStream *
+find_stream(AVFormatContext *afc)
+{
+ AVStream *st = NULL;
+ unsigned int i;
+
+ for (i = 0; i < afc->nb_streams; i++) {
+ if (afc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && !st)
+ st = afc->streams[i];
+ else
+ afc->streams[i]->discard = AVDISCARD_ALL;
+ }
+
+ return st;
+}
+
+static struct demux * open_stream(const char * filename, int *width, int *height)
+{
+ AVFormatContext *afc = open_file(filename);
+ AVStream *st = find_stream(afc);
+ AVCodecContext *cc = st->codec;
+ AVBitStreamFilterContext *bsf = NULL;
+ struct demux *demux;
+
+ if (cc->codec_id != CODEC_ID_H264) {
+ ERROR("could not open '%s': unsupported codec %d", filename, cc->codec_id);
+ return NULL;
+ }
+
+ if (cc->extradata && cc->extradata_size > 0 && cc->extradata[0] == 1) {
+ MSG("initializing bitstream filter");
+ bsf = av_bitstream_filter_init("h264_mp4toannexb");
+ if (!bsf) {
+ ERROR("could not open '%s': failed to initialize bitstream filter", filename);
+ return NULL;
+ }
+ }
+
+ *width = cc->width;
+ *height = cc->height;
+
+ demux = calloc(1, sizeof(*demux));
+
+ demux->afc = afc;
+ demux->cc = cc;
+ demux->st = st;
+ demux->bsf = bsf;
+
+ return demux;
+}
+
+struct demux * demux_init(const char * filename, int *width, int *height)
+{
+ av_register_all();
+ avcodec_register_all();
+ return open_stream(filename, width, height);
+}
+
+int demux_read(struct demux *demux, char *input, int size)
+{
+ AVPacket pk = {};
+
+ while (!av_read_frame(demux->afc, &pk)) {
+ if (pk.stream_index == demux->st->index) {
+ uint8_t *buf;
+ int bufsize;
+
+ if (demux->bsf) {
+ int ret;
+ MSG("%p %d bytes", pk.data, pk.size);
+ ret = av_bitstream_filter_filter(demux->bsf, demux->cc,
+ NULL, &buf, &bufsize, pk.data, pk.size, 0);
+ if (ret < 0) {
+ ERROR("bsf error: %d", ret);
+ return 0;
+ }
+ } else {
+ buf = pk.data;
+ bufsize = pk.size;
+ }
+
+ if (bufsize > size)
+ bufsize = size;
+
+ memcpy(input, buf, bufsize);
+
+ if (demux->bsf)
+ av_free(buf);
+
+ av_free_packet(&pk);
+
+ return bufsize;
+ }
+ av_free_packet(&pk);
+ }
+
+ return 0;
+}
+
+void demux_deinit(struct demux *demux)
+{
+ av_close_input_file(demux->afc);
+ if (demux->bsf)
+ av_bitstream_filter_close(demux->bsf);
+ free(demux);
+}
diff --git a/util/demux.h b/util/demux.h
--- /dev/null
+++ b/util/demux.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DEMUX_H__
+#define __DEMUX_H__
+
+struct demux;
+
+struct demux * demux_init(const char * filename, int *width, int *height);
+int demux_read(struct demux *demux, char *input, int size);
+void demux_deinit(struct demux *demux);
+
+#endif /* __DEMUX_H__ */
diff --git a/util/util.h b/util/util.h
index 720c11b802cb77f5dddf2a36d00e8095ec62d6eb..cba6234b73dd131228a2444e96bea0966bbfb08a 100644 (file)
--- a/util/util.h
+++ b/util/util.h
#include <omap_drm.h>
#include <omap_drmif.h>
+/* align x to next highest multiple of 2^n */
+#define ALIGN2(x,n) (((x) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
+
typedef enum {
false = 0,
true = 1
diff --git a/viddec3test.c b/viddec3test.c
--- /dev/null
+++ b/viddec3test.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Rob Clark <rob.clark@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <dce.h>
+#include <xdc/std.h>
+#include <ti/xdais/xdas.h>
+#include <ti/sdo/ce/Engine.h>
+#include <ti/sdo/ce/video3/viddec3.h>
+
+#include "util.h"
+#include "demux.h"
+
+/* Padding for width as per Codec Requirement (for h264) */
+#define PADX 32
+/* Padding for height as per Codec requirement (for h264)*/
+#define PADY 24
+
+static void
+usage(char *name)
+{
+ MSG("Usage: %s [OPTIONS] INFILE", name);
+ MSG("Test of viddec3 decoder.");
+ MSG("");
+ disp_usage();
+}
+
+int
+main(int argc, char **argv)
+{
+ struct display *disp;
+ struct demux *demux;
+ struct buffer *framebuf;
+ char *infile = NULL;
+ char *input = NULL;
+ struct omap_bo *input_bo = NULL;
+ int ret = 1, i, input_sz, num_buffers;
+ int width, height, padded_width, padded_height;
+ Engine_Error ec;
+ XDAS_Int32 err;
+ Engine_Handle engine;
+ VIDDEC3_Handle codec;
+ VIDDEC3_Params *params;
+ VIDDEC3_DynamicParams *dynParams;
+ VIDDEC3_Status *status;
+ XDM2_BufDesc *inBufs;
+ XDM2_BufDesc *outBufs;
+ VIDDEC3_InArgs *inArgs;
+ VIDDEC3_OutArgs *outArgs;
+
+ MSG("Opening Display..");
+ disp = disp_open(argc, argv);
+ if (!disp) {
+ usage(argv[0]);
+ return 1;
+ }
+
+ /* loop thru args, find input file.. */
+ for (i = 1; i < argc; i++) {
+ int fd;
+ if (!argv[i]) {
+ continue;
+ }
+ fd = open(argv[i], 0);
+ if (fd > 0) {
+ infile = argv[i];
+ argv[i] = NULL;
+ close(fd);
+ break;
+ }
+ break;
+ }
+
+ if (check_args(argc, argv) || !infile) {
+ ERROR("invalid args");
+ goto usage;
+ }
+
+ MSG("Opening Demuxer..");
+ demux = demux_init(infile, &width, &height);
+ if (!demux) {
+ goto usage;
+ }
+
+ MSG("infile=%s, width=%d, height=%d", infile, width, height);
+
+ /* calculate output buffer parameters: */
+ width = ALIGN2 (width, 4); /* round up to macroblocks */
+ height = ALIGN2 (height, 4); /* round up to macroblocks */
+ padded_width = ALIGN2 (width + (2*PADX), 7);
+ padded_height = height + 4*PADY;
+ num_buffers = MIN(16, 32768 / ((width/16) * (height/16))) + 3;
+
+ MSG("padded_width=%d, padded_height=%d, num_buffers=%d",
+ padded_width, padded_height, num_buffers);
+
+ input_sz = width * height;
+ input_bo = omap_bo_new(disp->dev, input_sz, OMAP_BO_WC);
+ input = omap_bo_map(input_bo);
+
+ framebuf = disp_get_fb(disp);
+
+ if (! disp_get_vid_buffers(disp, num_buffers, FOURCC_STR("NV12"),
+ padded_width, padded_height)) {
+ goto out;
+ }
+
+ MSG("Opening Engine..");
+ dce_set_fd(disp->fd);
+ engine = Engine_open("ivahd_vidsvr", NULL, &ec);
+ if (!engine) {
+ ERROR("fail");
+ goto out;
+ }
+
+ params = dce_alloc(sizeof(IVIDDEC3_Params));
+ params->size = sizeof(IVIDDEC3_Params);
+
+ params->maxWidth = width;
+ params->maxHeight = height;
+ params->maxFrameRate = 30000;
+ params->maxBitRate = 10000000;
+ params->dataEndianness = XDM_BYTE;
+ params->forceChromaFormat= XDM_YUV_420SP;
+ params->operatingMode = IVIDEO_DECODE_ONLY;
+ params->displayDelay = IVIDDEC3_DISPLAY_DELAY_AUTO;
+ params->displayBufsMode = IVIDDEC3_DISPLAYBUFS_EMBEDDED;
+ params->inputDataMode = IVIDEO_ENTIREFRAME;
+ params->metadataType[0] = IVIDEO_METADATAPLANE_NONE;
+ params->metadataType[1] = IVIDEO_METADATAPLANE_NONE;
+ params->metadataType[2] = IVIDEO_METADATAPLANE_NONE;
+ params->numInputDataUnits= 0;
+ params->outputDataMode = IVIDEO_ENTIREFRAME;
+ params->numOutputDataUnits = 0;
+ params->errorInfoMode = IVIDEO_ERRORINFO_OFF;
+
+ codec = VIDDEC3_create(engine, "ivahd_h264dec", params);
+ if (!codec) {
+ ERROR("fail");
+ goto out;
+ }
+
+ dynParams = dce_alloc(sizeof(IVIDDEC3_DynamicParams));
+ dynParams->size = sizeof(IVIDDEC3_DynamicParams);
+
+ dynParams->decodeHeader = XDM_DECODE_AU;
+
+ /*Not Supported: Set default*/
+ dynParams->displayWidth = 0;
+ dynParams->frameSkipMode = IVIDEO_NO_SKIP;
+ dynParams->newFrameFlag = XDAS_TRUE;
+
+ status = dce_alloc(sizeof(IVIDDEC3_Status));
+ status->size = sizeof(IVIDDEC3_Status);
+
+ err = VIDDEC3_control(codec, XDM_SETPARAMS, dynParams, status);
+ if (err) {
+ ERROR("fail: %d", err);
+ goto out;
+ }
+
+ /* not entirely sure why we need to call this here.. just copying omx.. */
+ err = VIDDEC3_control(codec, XDM_GETBUFINFO, dynParams, status);
+ if (err) {
+ ERROR("fail: %d", err);
+ goto out;
+ }
+
+ inBufs = malloc(sizeof(XDM2_BufDesc));
+ inBufs->numBufs = 1;
+ inBufs->descs[0].buf = (XDAS_Int8 *)omap_bo_handle(input_bo);
+ inBufs->descs[0].memType = XDM_MEMTYPE_BO;
+
+ outBufs = malloc(sizeof(XDM2_BufDesc));
+ outBufs->numBufs = 2;
+ outBufs->descs[0].memType = XDM_MEMTYPE_BO;
+ outBufs->descs[1].memType = XDM_MEMTYPE_BO;
+
+ inArgs = dce_alloc(sizeof(IVIDDEC3_InArgs));
+ inArgs->size = sizeof(IVIDDEC3_InArgs);
+
+ outArgs = dce_alloc(sizeof(IVIDDEC3_OutArgs));
+ outArgs->size = sizeof(IVIDDEC3_OutArgs);
+
+ while (inBufs->numBufs && outBufs->numBufs) {
+ struct buffer *buf;
+ int n;
+ suseconds_t t;
+
+ buf = disp_get_vid_buffer(disp);
+ if (!buf) {
+ ERROR("fail: out of buffers");
+ goto shutdown;
+ }
+
+ n = demux_read(demux, input, input_sz);
+ if (n) {
+ inBufs->descs[0].bufSize.bytes = n;
+ inArgs->numBytes = n;
+ MSG("push: %d bytes (%p)", n, buf);
+ } else {
+ /* end of input.. do we need to flush? */
+ MSG("end of input");
+ inBufs->numBufs = 0;
+ inArgs->inputID = 0;
+ }
+
+ inArgs->inputID = (XDAS_Int32)buf;
+ outBufs->descs[0].buf = (XDAS_Int8 *)omap_bo_handle(buf->bo[0]);
+ outBufs->descs[1].buf = (XDAS_Int8 *)omap_bo_handle(buf->bo[1]);
+
+ t = mark(NULL);
+ err = VIDDEC3_process(codec, inBufs, outBufs, inArgs, outArgs);
+ MSG("processed returned in: %ldus", (long int)mark(&t));
+ if (err) {
+ ERROR("process returned error: %d", err);
+ ERROR("extendedError: %08x", outArgs->extendedError);
+ if (XDM_ISFATALERROR(outArgs->extendedError))
+ goto shutdown;
+ }
+
+ for (i = 0; outArgs->outputID[i]; i++) {
+ /* calculate offset to region of interest */
+ XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion);
+
+ /* get the output buffer and write it to file */
+ buf = (struct buffer *)outArgs->outputID[i];
+ MSG("post buffer: %p %d,%d %d,%d", buf,
+ r->topLeft.x, r->topLeft.y,
+ r->bottomRight.x, r->bottomRight.y);
+ disp_post_vid_buffer(disp, buf, r->topLeft.x, r->topLeft.y,
+ r->bottomRight.x - r->topLeft.x,
+ r->bottomRight.y - r->topLeft.y);
+ }
+
+ for (i = 0; outArgs->freeBufID[i]; i++) {
+ buf = (struct buffer *)outArgs->freeBufID[i];
+ disp_put_vid_buffer(disp, buf);
+ }
+
+ if (outArgs->outBufsInUseFlag) {
+ MSG("TODO... outBufsInUseFlag"); // XXX
+ }
+ }
+
+ MSG("Ok!");
+ ret = 0;
+
+shutdown:
+ VIDDEC3_delete(codec);
+
+out:
+ if (engine) Engine_close(engine);
+ if (params) dce_free(params);
+ if (dynParams) dce_free(dynParams);
+ if (status) dce_free(status);
+ if (inBufs) free(inBufs);
+ if (outBufs) free(outBufs);
+ if (inArgs) dce_free(inArgs);
+ if (outArgs) dce_free(outArgs);
+ if (input_bo) omap_bo_del(input_bo);
+ if (demux) demux_deinit(demux);
+
+ return ret;
+
+usage:
+ usage(argv[0]);
+ return ret;
+}