/* * Copyright (C) 2012 Texas Instruments * Author: Ramprasad * * 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 . */ #include #include #include #include #include #include #include #include "util.h" #define MAX_IO_BUFS 8 /* Used for mpeg4 esds data copy */ /* omap drm device handle */ struct omap_device *dev = NULL; struct decoder { struct display *disp; struct buffer *framebuf; Engine_Handle engine; VIDDEC2_Handle codec; VIDDEC2_Params *params; VIDDEC2_DynamicParams *dynParams; VIDDEC2_Status *status; XDM1_BufDesc *inBufs; XDM_BufDesc *outBufs; VIDDEC2_InArgs *inArgs; VIDDEC2_OutArgs *outArgs; XDAS_Int8 **outBuffer; XDAS_Int32 *outBufSizes; char *input; struct omap_bo *input_bo; int input_sz, uv_offset; int padded_width; int padded_height; int num_outBuf; }; static void usage(char *name) { MSG("Usage: %s -s : INFILE -w width -h height", name); MSG("example: %s -s 4:800x480 file.yuv -w 176 -h 144", name); MSG("Test of universalCopy ."); MSG(""); MSG("yuvcopytest options:"); MSG("\t --help: Print this help and exit."); MSG(""); disp_usage(); } static void decoder_close(struct decoder *decoder) { if(!decoder) goto bailout; /* free output buffers allocated by display */ disp_free_buffers(decoder->disp,decoder->num_outBuf); if (decoder->params) dsp_dce_free(decoder->params); if (decoder->dynParams) dsp_dce_free(decoder->dynParams); if (decoder->status) dsp_dce_free(decoder->status); if (decoder->inBufs) { dsp_dce_buf_unlock(1, &(decoder->inBufs->descs[0].buf)); close(decoder->inBufs->descs[0].buf); dsp_dce_free(decoder->inBufs); } if (decoder->outBufs) dsp_dce_free(decoder->outBufs); if (decoder->inArgs) dsp_dce_free(decoder->inArgs); if (decoder->outArgs) dsp_dce_free(decoder->outArgs); if (decoder->outBuffer) dsp_dce_free(decoder->outBuffer); if (decoder->outBufSizes) dsp_dce_free(decoder->outBufSizes); if (decoder->input_bo) omap_bo_del(decoder->input_bo); if (decoder->codec) VIDDEC2_delete(decoder->codec); if (decoder->engine) Engine_close(decoder->engine); if (decoder->disp) disp_close(decoder->disp); free(decoder); bailout: if (dev) dce_deinit(dev); } static struct decoder * decoder_open(int argc, char** argv) { struct decoder *decoder; char *infile = NULL; int i; int width , height ,padded_width, padded_height; Engine_Error ec; XDAS_Int32 err; decoder = calloc(1, sizeof(*decoder)); if (!decoder) return NULL; MSG("%p: Opening Display..", decoder); decoder->disp = disp_open(argc, argv); if (!decoder->disp) goto usage; /* 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; } for(i = 1; i < argc; i++){ if(!argv[i]) continue; if(!strcmp(argv[i],"-w")){ argv[i] = NULL; width = atoi(argv[i+1]); argv[i+1] = NULL; continue; } if(!strcmp(argv[i], "-h")){ argv[i] = NULL; height = atoi(argv[i+1]); argv[i+1] = NULL; } } MSG("width = %d, height = %d\n", width, height); if (check_args(argc, argv) || !infile) goto usage; /* calculate output buffer parameters: */ width = ALIGN2 (width, 4); /* round up to macroblocks */ height = ALIGN2 (height, 4); /* round up to macroblocks */ padded_width = width; padded_height= height; decoder->num_outBuf = 2; decoder->padded_width = padded_width; decoder->padded_height = padded_height; decoder->input_sz = width * height; decoder->input_bo = omap_bo_new(decoder->disp->dev, decoder->input_sz, OMAP_BO_WC); decoder->input = omap_bo_map(decoder->input_bo); decoder->framebuf = disp_get_fb(decoder->disp); MSG("Fill input buffer with yuv luma data\n"); { FILE *fd; fd = fopen(infile, "rb"); fread(decoder->input, width*height, sizeof(char), fd); fclose(fd); } if (! disp_get_vid_buffers(decoder->disp, decoder->num_outBuf, FOURCC_STR("NV12"), padded_width, padded_height)) { ERROR("%p: could not allocate buffers", decoder); goto fail; } MSG("%p: Opening Engine..", decoder); dce_set_fd(decoder->disp->fd); dev = dce_init(); if(dev == NULL) { ERROR("%p: dce init failed", dev); goto fail; } decoder->engine = Engine_open("dsp_vidsvr", NULL, &ec); if (!decoder->engine) { ERROR("%p: could not open engine", decoder); goto fail; } decoder->params = dsp_dce_alloc(sizeof(IVIDDEC2_Params)); decoder->params->size = sizeof(IVIDDEC2_Params); decoder->codec = VIDDEC2_create(decoder->engine, "dsp_universalCopy", decoder->params); if (!decoder->codec) { ERROR("%p: could not create codec", decoder); goto fail; } decoder->dynParams = dsp_dce_alloc(sizeof(IVIDDEC2_DynamicParams)); decoder->dynParams->size = sizeof(IVIDDEC2_DynamicParams); decoder->status = dsp_dce_alloc(sizeof(IVIDDEC2_Status)); decoder->status->size = sizeof(IVIDDEC2_Status); err = VIDDEC2_control(decoder->codec, XDM_SETPARAMS, decoder->dynParams, decoder->status); if (err) { ERROR("%p: fail: %d", decoder, err); goto fail; } /* not entirely sure why we need to call this here.. just copying omx.. */ err = VIDDEC2_control(decoder->codec, XDM_GETBUFINFO, decoder->dynParams, decoder->status); if (err) { ERROR("%p: fail: %d", decoder, err); goto fail; } decoder->outBuffer = dsp_dce_alloc(sizeof(XDAS_Int8*) * MAX_IO_BUFS); decoder->outBufSizes = dsp_dce_alloc(sizeof(XDAS_Int32)* MAX_IO_BUFS); decoder->inBufs = dsp_dce_alloc(sizeof(XDM1_BufDesc)); decoder->inBufs->numBufs = 1; decoder->inBufs->descs[0].buf = (XDAS_Int8 *)omap_bo_dmabuf(decoder->input_bo); decoder->inBufs->descs[0].bufSize = omap_bo_size(decoder->input_bo); dsp_dce_buf_lock(1, &(decoder->inBufs->descs[0].buf)); decoder->outBufs = dsp_dce_alloc(sizeof(XDM_BufDesc)); decoder->outBufs->numBufs = 2; decoder->outBufs->bufs = (XDAS_Int8**)decoder->outBuffer; decoder->outBufs->bufSizes = &decoder->outBufSizes[0]; decoder->inArgs = dsp_dce_alloc(sizeof(IVIDDEC2_InArgs)); decoder->inArgs->size = sizeof(IVIDDEC2_InArgs); decoder->outArgs = dsp_dce_alloc(sizeof(IVIDDEC2_OutArgs)); decoder->outArgs->size = sizeof(IVIDDEC2_OutArgs); return decoder; usage: usage(argv[0]); fail: if (decoder) decoder_close(decoder); return NULL; } static int decoder_process(struct decoder *decoder) { XDM1_BufDesc *inBufs = decoder->inBufs; XDM_BufDesc *outBufs = decoder->outBufs; VIDDEC2_InArgs *inArgs = decoder->inArgs; VIDDEC2_OutArgs *outArgs = decoder->outArgs; struct buffer *buf; XDAS_Int32 width = decoder->padded_width; XDAS_Int32 height = decoder->padded_height; XDAS_Int32 err; char *src,*dst; XDAS_Int32 i, success = XDAS_TRUE; buf = disp_get_vid_buffer(decoder->disp); if (!buf) { ERROR("%p: fail: out of buffers", decoder); return -1; } decoder->outBuffer[0] = buf->fd[0]; decoder->outBuffer[1] = (buf->multiplanar) ? buf->fd[1]:(XDAS_Int8 *)((decoder->outBuffer[0])); dsp_dce_buf_lock(2,&decoder->outBuffer[0]); decoder->outBufSizes[0] = decoder->padded_width * decoder->padded_height; decoder->outBufSizes[1] = decoder->padded_width * (decoder->padded_height/2); err = VIDDEC2_process(decoder->codec, inBufs, outBufs, inArgs, outArgs); if (err) { ERROR("%p: process returned error: %d", decoder, err); return -1; } dsp_dce_buf_unlock(2, &decoder->outBuffer[0]); disp_post_vid_buffer(decoder->disp, buf, 0, 0, width, height); /* Display the output buffer for 10 seconds */ sleep(10); disp_put_vid_buffer(decoder->disp, buf); src = (char*)decoder->input; dst = (char*)omap_bo_map(buf->bo[0]); MSG("Comparing output buffer with input buffer\n"); for(i = 0; i < decoder->input_sz; i++){ if(*src != *dst){ MSG("yuvcopytest failed at %d, 0x%x, 0x%x\n", i, *src, *dst); success = XDAS_FALSE; break; } src++; dst++; } if(success ==XDAS_TRUE) MSG("yuvcopytest executed successfully\n"); return 0; } int main(int argc, char **argv) { struct decoder *decoder = NULL; int i; for (i = 1; i < argc; i++) if ( !strcmp(argv[i], "--help")) { usage(argv[0]); exit(0); } decoder = decoder_open(argc,argv); if(decoder) decoder_process(decoder); if(decoder) decoder_close(decoder); decoder = NULL; return 0; }