viddec3test:Add support looped test
authorPradeep Venkatasubbarao <pradeepv@ti.com>
Fri, 21 Mar 2014 08:55:13 +0000 (14:25 +0530)
committerAmarinder Bindra <a-bindra@ti.com>
Fri, 21 Mar 2014 14:52:40 +0000 (20:22 +0530)
This patch adds support for testing in a loop as below.

1.      Open drm, display, dce devices once during init
2.      Allocate dce buffers, input buffers
3.      Viddec3_create
4.      Viddec3_control/process till eof
5.      Viddec3_delete
6.      Got to 2 till loop iterations.
7.      Close drm, display, dce devices once during deinit

example usage:
viddec3test -s <id>:wxh <file> --inloop --fps 30

The test runs infinitely until the user interrupts it.

Signed-off-by: Pradeep Venkatasubbarao <pradeepv@ti.com>
viddec3test.c

index c7f3626a6bc3efa3440179844fc53ee0eb81305c..1c65a800ca85daca76e72d647919c07dc3d11849 100644 (file)
@@ -62,6 +62,7 @@ struct decoder {
 
 /* When true, do not actually call VIDDEC3_process. For benchmarking. */
 static int no_process = 0;
+static int inloop = 0;
 
 /* When true, loop at end of playback. */
 static int loop = 0;
@@ -75,6 +76,7 @@ usage(char *name)
        MSG("viddec3test options:");
        MSG("\t-h, --help: Print this help and exit.");
        MSG("\t--loop\tRestart playback at end of stream.");
+       MSG("\t--inloop\tRestart playback at end of stream along with decoder reinitialization.");
        MSG("\t--no-process\tDo not actually call VIDDEC3_process method. For benchmarking.");
        MSG("");
        disp_usage();
@@ -83,8 +85,9 @@ usage(char *name)
 static void
 decoder_close(struct decoder *decoder)
 {
+       if(!decoder) return;
        /* free output buffers allocated by display */
-       disp_free_buffers(decoder->disp,decoder->num_outBuf);
+       if(inloop < 2 && decoder->disp) disp_free_buffers(decoder->disp,decoder->num_outBuf);
 
        if (decoder->status)         dce_free(decoder->status);
        if (decoder->params)         dce_free(decoder->params);
@@ -99,79 +102,91 @@ decoder_close(struct decoder *decoder)
        if (decoder->outArgs)        dce_free(decoder->outArgs);
        if (decoder->codec)          VIDDEC3_delete(decoder->codec);
        if (decoder->engine)         Engine_close(decoder->engine);
-       if (dev)                     dce_deinit(dev);
-       if (decoder->input_bo)       omap_bo_del(decoder->input_bo);
-       if (decoder->demux)          demux_deinit(decoder->demux);
-       if (decoder->disp)           disp_close(decoder->disp);
+    if (decoder->input_bo)       omap_bo_del(decoder->input_bo);
        if (decoder->outBuf_fd)      free(decoder->outBuf_fd);
-       free(decoder);
+       if(inloop < 2) {
+               if (dev)                             dce_deinit(dev);
+               if (decoder->demux)          demux_deinit(decoder->demux);
+               if (decoder->disp)           disp_close(decoder->disp);
+               if(decoder) free(decoder);
+       }
 }
 
 static struct decoder *
 decoder_open(int argc, char **argv)
 {
-       struct decoder *decoder;
+       static struct decoder *decoder = NULL;
        char *infile = NULL;
        int i;
-       int width, height, padded_width, padded_height;
+       static 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);
+    if(inloop < 2) {
+               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;
                }
-               break;
-       }
-
-       if (check_args(argc, argv) || !infile)
-               goto usage;
-
-       MSG("%p: Opening Demuxer..", decoder);
-       decoder->demux = demux_init(infile, &width, &height);
-       if (!decoder->demux) {
-               ERROR("%p: could not open demuxer", decoder);
-               goto fail;
-       }
-
-       MSG("%p: infile=%s, width=%d, height=%d", decoder, infile, width, height);
-
-       /* calculate output buffer parameters: */
-       width  = ALIGN2 (width, 4);        /* round up to macroblocks */
-       height = ALIGN2 (height, 4);       /* round up to macroblocks */
-
-       if (decoder->demux->cc->codec_id == CODEC_ID_MPEG2VIDEO) {
-                padded_width = width;
-                padded_height= height;
-        }
-        else {
-                padded_width  = ALIGN2 (width + (2*PADX), 7);
-                padded_height = height + 4*PADY;
-        }
-
-       decoder->num_outBuf   = MIN(16, 32768 / ((width/16) * (height/16))) + 3;
-       decoder->padded_width = padded_width;
-       decoder->padded_height = padded_height;
-       MSG("%p: padded_width=%d, padded_height=%d, num_buffers=%d",
+               if (check_args(argc, argv) || !infile)
+                       goto usage;
+               MSG("%p: Opening Demuxer..", decoder);
+               decoder->demux = demux_init(infile, &width, &height);
+               if (!decoder->demux) {
+                       ERROR("%p: could not open demuxer", decoder);
+                       goto fail;
+               }
+               MSG("%p: infile=%s, width=%d, height=%d", decoder, infile, width, height);
+
+               /* calculate output buffer parameters: */
+               width  = ALIGN2 (width, 4);        /* round up to macroblocks */
+               height = ALIGN2 (height, 4);       /* round up to macroblocks */
+               if (decoder->demux->cc->codec_id == CODEC_ID_MPEG2VIDEO) {
+                       padded_width = width;
+                       padded_height= height;
+               }
+               else {
+                       padded_width  = ALIGN2 (width + (2*PADX), 7);
+                       padded_height = height + 4*PADY;
+               }
+               decoder->num_outBuf   = MIN(16, 32768 / ((width/16) * (height/16))) + 3;
+               decoder->padded_width = padded_width;
+               decoder->padded_height = padded_height;
+               MSG("%p: padded_width=%d, padded_height=%d, num_buffers=%d",
                        decoder, padded_width, padded_height, decoder->num_outBuf);
+               dce_set_fd(decoder->disp->fd);
+               dev = dce_init();
+               if(dev == NULL) {
+                       ERROR("%p: dce init failed", dev);
+                       goto fail;
+               }
+               decoder->framebuf = disp_get_fb(decoder->disp);
+               if (! disp_get_vid_buffers(decoder->disp, decoder->num_outBuf,
+                               FOURCC_STR("NV12"), decoder->padded_width, decoder->padded_height)) {
+                       ERROR("%p: could not allocate buffers", decoder);
+                       goto fail;
+               }
+               if(inloop) inloop = 2; /*Don't bother about looping if not asked to*/
+    }
 
        if (!decoder->disp->multiplanar) {
                decoder->uv_offset = padded_width * padded_height;
@@ -186,21 +201,10 @@ decoder_open(int argc, char **argv)
        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);
 
-       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("ivahd_vidsvr", NULL, &ec);
        if (!decoder->engine) {
                ERROR("%p: could not open engine", decoder);
@@ -302,6 +306,7 @@ decoder_open(int argc, char **argv)
 usage:
        usage(argv[0]);
 fail:
+       if(inloop) inloop = 1; /*Error case: delete everything*/
        if (decoder)
                decoder_close(decoder);
        return NULL;
@@ -320,17 +325,16 @@ decoder_process(struct decoder *decoder)
        XDAS_Int32 err;
        int eof = 0; /* end of file flag */
 
-       buf = disp_get_vid_buffer(decoder->disp);
-       if (!buf) {
-               ERROR("%p: fail: out of buffers", decoder);
-               return -1;
-       }
 
        /* demux; in loop mode, we can do two tries at the end of the stream. */
        for (i = 0; i < 2; i++) {
                n = demux_read(decoder->demux, decoder->input, decoder->input_sz);
                if (n) {
-
+                       buf = disp_get_vid_buffer(decoder->disp);
+                       if (!buf) {
+                               ERROR("%p: fail: out of buffers", decoder);
+                               return -1;
+                       }
                        inBufs->descs[0].bufSize.bytes = n;
                        inArgs->numBytes = n;
                        DBG("%p: push: %d bytes (%p)", decoder, n, buf);
@@ -346,7 +350,7 @@ decoder_process(struct decoder *decoder)
                                        return -1;
                                }
                                MSG("%p: rewound.", decoder);
-                               continue;
+                               if(!inloop) continue;
                        }
                        eof = 1; /* set the flag for end of file to 1 */
                        /* Control call call with XDM_FLUSH command */
@@ -369,7 +373,7 @@ decoder_process(struct decoder *decoder)
                if(buf->multiplanar){
                        decoder->outBuf_fd[0] = buf->fd[0];
                        decoder->outBuf_fd[1] = buf->fd[1];
-                       dce_buf_lock(2,decoder->outBuf_fd);
+            dce_buf_lock(2,decoder->outBuf_fd);
                }
                else{
                        decoder->outBuf_fd[0] = buf->fd[0];
@@ -383,9 +387,13 @@ decoder_process(struct decoder *decoder)
                if (no_process) {
                        /* Do not process. This is for benchmarking. We need to "fake"
                         * the outArgs. */
-                       outArgs->outputID[0] = buf;
+                       outArgs->outputID[0] = 0;
+                       outArgs->freeBufID[0] = 0;
+                       if(!eof) {
+                               outArgs->outputID[0] = buf;
+                               outArgs->freeBufID[0] = buf;
+                       }
                        outArgs->outputID[1] = NULL;
-                       outArgs->freeBufID[0] = buf;
                        outArgs->freeBufID[1] = NULL;
                        outArgs->outBufsInUseFlag = 0;
 
@@ -408,7 +416,8 @@ decoder_process(struct decoder *decoder)
 
                        /* get the output buffer and write it to file */
                        buf = (struct buffer *)outArgs->outputID[i];
-                       disp_post_vid_buffer(decoder->disp, buf,
+                       if(!no_process)
+                               disp_post_vid_buffer(decoder->disp, buf,
                                        r->topLeft.x, r->topLeft.y,
                                        r->bottomRight.x - r->topLeft.x,
                                        r->bottomRight.y - r->topLeft.y);
@@ -429,35 +438,28 @@ decoder_process(struct decoder *decoder)
                }
 
                if(freeBufCount){
-                       dce_buf_unlock(freeBufCount,decoder->outBuf_fd);
+            if(!eof)dce_buf_unlock(freeBufCount,decoder->outBuf_fd);
                        freeBufCount =0;
                }
                if (outArgs->outBufsInUseFlag) {
                        MSG("%p: TODO... outBufsInUseFlag", decoder); // XXX
                }
-       } while ((err == 0) && eof);
+       } while ((err == 0) && eof && !no_process);
 
        return (inBufs->numBufs > 0) ? 0 : -1;
 }
 
 void *decode_stream(void *decoderHandle)
 {
-       int n = 0;
-       struct decoder *decoders = (struct decoder*)decoderHandle;
-
-       do {
-               if (decoders) {
-                       int ret = decoder_process(decoders);
-                       if (ret) {
-                               decoder_close(decoders);
-                               decoders = NULL;
-                               n = 0;
-                               continue;
-                       }
-                       n++;
-               }
-       } while(n > 0);
-
+       int ret = 0;
+       struct decoder *decoder = (struct decoder*)decoderHandle;
+    int n = 0;
+    if(!decoder) goto exit;
+
+    while((ret = decoder_process(decoder)) == 0);
+    if((ret != -1 && ret != 0) && inloop) inloop = 1; /*Assuming Good case. Otherwise logic gets messy*/
+    decoder_close(decoder);
+exit:
        return NULL;
 }
 
@@ -480,6 +482,11 @@ main(int argc, char **argv)
                        no_process = 1;
                        argv[i] = NULL;
 
+               } else if (!strcmp(argv[i], "--inloop")) {
+                       inloop = 1; // this means inloop is detected
+                       DBG("detected inloop = %d\n", inloop);
+                       loop = 1; //we want rewind as well
+                       argv[i] = NULL;
                } else if (!strcmp(argv[i], "--")) {
                        argv[first] = argv[0];
                        decoders[ndecoders++] = decoder_open(i - first, &argv[first]);
@@ -488,8 +495,9 @@ main(int argc, char **argv)
        }
 
        argv[first] = argv[0];
+       argc = i - first;
 
-       decoders[ndecoders++] = decoder_open(i - first, &argv[first]);
+       if(ndecoders) decoders[ndecoders++] = decoder_open(argc ,&argv[first]);
 
        if (ndecoders > 1) {
                pthread_t threadIds[8];
@@ -509,7 +517,12 @@ main(int argc, char **argv)
                }
        }
        else {
-               decode_stream(decoders[0]);
+               int itr = 0;
+               do {
+                       decoders[0] = decoder_open(argc, &argv[first]);
+                       decode_stream(decoders[0]);
+                       MSG("=================Iteration %d complete =============== %d\n", ++itr);
+               }while(inloop);
        }
 
        return 0;