Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the
  6.  * "Software"), to deal in the Software without restriction, including
  7.  * without limitation the rights to use, copy, modify, merge, publish,
  8.  * distribute, sub license, and/or sell copies of the Software, and to
  9.  * permit persons to whom the Software is furnished to do so, subject to
  10.  * the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the
  13.  * next paragraph) shall be included in all copies or substantial portions
  14.  * of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  19.  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
  20.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  22.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #define _GNU_SOURCE 1
  26. #include "sysdeps.h"
  27. #include "va.h"
  28. #include "va_backend.h"
  29. #include "va_trace.h"
  30. #include "va_fool.h"
  31.  
  32. #include <assert.h>
  33. #include <stdarg.h>
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. #include <errno.h>
  37. #include <string.h>
  38. #include <unistd.h>
  39. #include <sys/types.h>
  40. #include <sys/stat.h>
  41. #include <unistd.h>
  42. #include <time.h>
  43. #include <fcntl.h>
  44.  
  45. /*
  46.  * Do dummy decode/encode, ignore the input data
  47.  * In order to debug memory leak or low performance issues, we need to isolate driver problems
  48.  * We export env "VA_FOOL", with which, we can do fake decode/encode:
  49.  *
  50.  * LIBVA_FOOL_DECODE:
  51.  * . if set, decode does nothing
  52.  * LIBVA_FOOL_ENCODE=<framename>:
  53.  * . if set, encode does nothing, but fill in the coded buffer from the content of files with
  54.  *   name framename.0,framename.1,..., framename.N, framename.0,..., framename.N,...repeatly
  55.  *   Use file name to determine h264 or vp8
  56.  * LIBVA_FOOL_JPEG=<framename>:fill the content of filename to codedbuf for jpeg encoding
  57.  * LIBVA_FOOL_POSTP:
  58.  * . if set, do nothing for vaPutSurface
  59.  */
  60.  
  61.  
  62. /* global settings */
  63. int fool_codec = 0;
  64. int fool_postp  = 0;
  65.  
  66. #define FOOL_BUFID_MAGIC   0x12345600
  67. #define FOOL_BUFID_MASK    0xffffff00
  68.  
  69. struct fool_context {
  70.     int enabled; /* fool_codec is global, and it is for concurent encode/decode */
  71.     char *fn_enc;/* file pattern with codedbuf content for encode */
  72.     char *segbuf_enc; /* the segment buffer of coded buffer, load frome fn_enc */
  73.     int file_count;
  74.  
  75.     char *fn_jpg;/* file name of JPEG fool with codedbuf content */
  76.     char *segbuf_jpg; /* the segment buffer of coded buffer, load frome fn_jpg */
  77.  
  78.     VAEntrypoint entrypoint; /* current entrypoint */
  79.    
  80.     /* all buffers with same type share one malloc-ed memory
  81.      * bufferID = (buffer numbers with the same type << 8) || type
  82.      * the malloc-ed memory can be find by fool_buf[bufferID & 0xff]
  83.      * the size is ignored here
  84.      */
  85.     char *fool_buf[VABufferTypeMax]; /* memory of fool buffers */
  86.     unsigned int fool_buf_size[VABufferTypeMax]; /* size of memory of fool buffers */
  87.     unsigned int fool_buf_element[VABufferTypeMax]; /* element count of created buffers */
  88.     unsigned int fool_buf_count[VABufferTypeMax]; /* count of created buffers */
  89.     VAContextID context;
  90. };
  91.  
  92. #define FOOL_CTX(dpy) ((struct fool_context *)((VADisplayContextP)dpy)->vafool)
  93.  
  94. #define DPY2FOOLCTX(dpy)                                 \
  95.     struct fool_context *fool_ctx = FOOL_CTX(dpy);       \
  96.     if (fool_ctx == NULL)                                \
  97.         return 0; /* no fool for the context */          \
  98.  
  99. #define DPY2FOOLCTX_CHK(dpy)                             \
  100.     struct fool_context *fool_ctx = FOOL_CTX(dpy);       \
  101.     if ((fool_ctx == NULL) || (fool_ctx->enabled == 0))  \
  102.         return 0; /* no fool for the context */          \
  103.  
  104. /* Prototype declarations (functions defined in va.c) */
  105.  
  106. void va_errorMessage(const char *msg, ...);
  107. void va_infoMessage(const char *msg, ...);
  108.  
  109. int  va_parseConfig(char *env, char *env_value);
  110.  
  111. void va_FoolInit(VADisplay dpy)
  112. {
  113.     char env_value[1024];
  114.  
  115.     struct fool_context *fool_ctx = calloc(sizeof(struct fool_context), 1);
  116.    
  117.     if (fool_ctx == NULL)
  118.         return;
  119.    
  120.     if (va_parseConfig("LIBVA_FOOL_POSTP", NULL) == 0) {
  121.         fool_postp = 1;
  122.         va_infoMessage("LIBVA_FOOL_POSTP is on, dummy vaPutSurface\n");
  123.     }
  124.    
  125.     if (va_parseConfig("LIBVA_FOOL_DECODE", NULL) == 0) {
  126.         fool_codec  |= VA_FOOL_FLAG_DECODE;
  127.         va_infoMessage("LIBVA_FOOL_DECODE is on, dummy decode\n");
  128.     }
  129.     if (va_parseConfig("LIBVA_FOOL_ENCODE", &env_value[0]) == 0) {
  130.         fool_codec  |= VA_FOOL_FLAG_ENCODE;
  131.         fool_ctx->fn_enc = strdup(env_value);
  132.         va_infoMessage("LIBVA_FOOL_ENCODE is on, load encode data from file with patten %s\n",
  133.                        fool_ctx->fn_enc);
  134.     }
  135.     if (va_parseConfig("LIBVA_FOOL_JPEG", &env_value[0]) == 0) {
  136.         fool_codec  |= VA_FOOL_FLAG_JPEG;
  137.         fool_ctx->fn_jpg = strdup(env_value);
  138.         va_infoMessage("LIBVA_FOOL_JPEG is on, load encode data from file with patten %s\n",
  139.                        fool_ctx->fn_jpg);
  140.     }
  141.    
  142.     ((VADisplayContextP)dpy)->vafool = fool_ctx;
  143. }
  144.  
  145.  
  146. int va_FoolEnd(VADisplay dpy)
  147. {
  148.     int i;
  149.     DPY2FOOLCTX(dpy);
  150.  
  151.     for (i = 0; i < VABufferTypeMax; i++) {/* free memory */
  152.         if (fool_ctx->fool_buf[i])
  153.             free(fool_ctx->fool_buf[i]);
  154.     }
  155.     if (fool_ctx->segbuf_enc)
  156.         free(fool_ctx->segbuf_enc);
  157.     if (fool_ctx->segbuf_jpg)
  158.         free(fool_ctx->segbuf_jpg);
  159.     if (fool_ctx->fn_enc)
  160.         free(fool_ctx->fn_enc);
  161.     if (fool_ctx->fn_jpg)
  162.         free(fool_ctx->fn_jpg);
  163.  
  164.     free(fool_ctx);
  165.     ((VADisplayContextP)dpy)->vafool = NULL;
  166.    
  167.     return 0;
  168. }
  169.  
  170. int va_FoolCreateConfig(
  171.         VADisplay dpy,
  172.         VAProfile profile,
  173.         VAEntrypoint entrypoint,
  174.         VAConfigAttrib *attrib_list,
  175.         int num_attribs,
  176.         VAConfigID *config_id /* out */
  177. )
  178. {
  179.     DPY2FOOLCTX(dpy);
  180.  
  181.     fool_ctx->entrypoint = entrypoint;
  182.    
  183.     /*
  184.      * check fool_codec to align with current context
  185.      * e.g. fool_codec = decode then for encode, the
  186.      * vaBegin/vaRender/vaEnd also run into fool path
  187.      * which is not desired
  188.      */
  189.     if (((fool_codec & VA_FOOL_FLAG_DECODE) && (entrypoint == VAEntrypointVLD)) ||
  190.         ((fool_codec & VA_FOOL_FLAG_JPEG) && (entrypoint == VAEntrypointEncPicture)))
  191.         fool_ctx->enabled = 1;
  192.     else if ((fool_codec & VA_FOOL_FLAG_ENCODE) && (entrypoint == VAEntrypointEncSlice)) {
  193.         /* H264 is desired */
  194.         if (((profile == VAProfileH264Baseline ||
  195.               profile == VAProfileH264Main ||
  196.               profile == VAProfileH264High ||
  197.               profile == VAProfileH264ConstrainedBaseline)) &&
  198.             strstr(fool_ctx->fn_enc, "h264"))
  199.             fool_ctx->enabled = 1;
  200.  
  201.         /* vp8 is desired */
  202.         if ((profile == VAProfileVP8Version0_3) &&
  203.             strstr(fool_ctx->fn_enc, "vp8"))
  204.             fool_ctx->enabled = 1;
  205.     }
  206.     if (fool_ctx->enabled)
  207.         va_infoMessage("FOOL is enabled for this context\n");
  208.     else
  209.         va_infoMessage("FOOL is not enabled for this context\n");
  210.  
  211.    
  212.     return 0; /* continue */
  213. }
  214.  
  215.  
  216. VAStatus va_FoolCreateBuffer(
  217.     VADisplay dpy,
  218.     VAContextID context,        /* in */
  219.     VABufferType type,          /* in */
  220.     unsigned int size,          /* in */
  221.     unsigned int num_elements,  /* in */
  222.     void *data,                 /* in */
  223.     VABufferID *buf_id          /* out */
  224. )
  225. {
  226.     unsigned int new_size = size * num_elements;
  227.     unsigned int old_size;
  228.     DPY2FOOLCTX_CHK(dpy);
  229.  
  230.     old_size = fool_ctx->fool_buf_size[type] * fool_ctx->fool_buf_element[type];
  231.  
  232.     if (old_size < new_size)
  233.         fool_ctx->fool_buf[type] = realloc(fool_ctx->fool_buf[type], new_size);
  234.    
  235.     fool_ctx->fool_buf_size[type] = size;
  236.     fool_ctx->fool_buf_element[type] = num_elements;
  237.     fool_ctx->fool_buf_count[type]++;
  238.     /* because we ignore the vaRenderPicture,
  239.      * all buffers with same type share same real memory
  240.      * bufferID = (magic number) | type
  241.      */
  242.     *buf_id = FOOL_BUFID_MAGIC | type;
  243.  
  244.     return 1; /* don't call into driver */
  245. }
  246.  
  247. VAStatus va_FoolBufferInfo(
  248.     VADisplay dpy,
  249.     VABufferID buf_id,  /* in */
  250.     VABufferType *type, /* out */
  251.     unsigned int *size,         /* out */
  252.     unsigned int *num_elements /* out */
  253. )
  254. {
  255.     unsigned int magic;
  256.    
  257.     DPY2FOOLCTX_CHK(dpy);
  258.  
  259.     magic = buf_id & FOOL_BUFID_MASK;
  260.     if (magic != FOOL_BUFID_MAGIC)
  261.         return 0; /* could be VAImageBufferType from vaDeriveImage */
  262.    
  263.     *type = buf_id & 0xff;
  264.     *size = fool_ctx->fool_buf_size[*type];
  265.     *num_elements = fool_ctx->fool_buf_element[*type];;
  266.    
  267.     return 1; /* fool is valid */
  268. }
  269.  
  270. static int va_FoolFillCodedBufEnc(struct fool_context *fool_ctx)
  271. {
  272.     char file_name[1024];
  273.     struct stat file_stat = {0};
  274.     VACodedBufferSegment *codedbuf;
  275.     int i, fd = -1;
  276.  
  277.     /* try file_name.file_count, if fail, try file_name.file_count-- */
  278.     for (i=0; i<=1; i++) {
  279.         snprintf(file_name, 1024, "%s.%d",
  280.                  fool_ctx->fn_enc,
  281.                  fool_ctx->file_count);
  282.  
  283.         if ((fd = open(file_name, O_RDONLY)) != -1) {
  284.             fstat(fd, &file_stat);
  285.             fool_ctx->file_count++; /* open next file */
  286.             break;
  287.         } else /* fall back to the first file file */
  288.             fool_ctx->file_count = 0;
  289.     }
  290.     if (fd != -1) {
  291.         fool_ctx->segbuf_enc = realloc(fool_ctx->segbuf_enc, file_stat.st_size);
  292.         read(fd, fool_ctx->segbuf_enc, file_stat.st_size);
  293.         close(fd);
  294.     } else
  295.         va_errorMessage("Open file %s failed:%s\n", file_name, strerror(errno));
  296.  
  297.     codedbuf = (VACodedBufferSegment *)fool_ctx->fool_buf[VAEncCodedBufferType];
  298.     codedbuf->size = file_stat.st_size;
  299.     codedbuf->bit_offset = 0;
  300.     codedbuf->status = 0;
  301.     codedbuf->reserved = 0;
  302.     codedbuf->buf = fool_ctx->segbuf_enc;
  303.     codedbuf->next = NULL;
  304.  
  305.     return 0;
  306. }
  307.  
  308. static int va_FoolFillCodedBufJPG(struct fool_context *fool_ctx)
  309. {
  310.     struct stat file_stat = {0};
  311.     VACodedBufferSegment *codedbuf;
  312.     int fd = -1;
  313.  
  314.     if ((fd = open(fool_ctx->fn_jpg, O_RDONLY)) != -1) {
  315.         fstat(fd, &file_stat);
  316.         fool_ctx->segbuf_jpg = realloc(fool_ctx->segbuf_jpg, file_stat.st_size);
  317.         read(fd, fool_ctx->segbuf_jpg, file_stat.st_size);
  318.         close(fd);
  319.     } else
  320.         va_errorMessage("Open file %s failed:%s\n", fool_ctx->fn_jpg, strerror(errno));
  321.  
  322.     codedbuf = (VACodedBufferSegment *)fool_ctx->fool_buf[VAEncCodedBufferType];
  323.     codedbuf->size = file_stat.st_size;
  324.     codedbuf->bit_offset = 0;
  325.     codedbuf->status = 0;
  326.     codedbuf->reserved = 0;
  327.     codedbuf->buf = fool_ctx->segbuf_jpg;
  328.     codedbuf->next = NULL;
  329.  
  330.     return 0;
  331. }
  332.  
  333.  
  334. static int va_FoolFillCodedBuf(struct fool_context *fool_ctx)
  335. {
  336.     if (fool_ctx->entrypoint == VAEntrypointEncSlice)
  337.         va_FoolFillCodedBufEnc(fool_ctx);
  338.     else if (fool_ctx->entrypoint == VAEntrypointEncPicture)
  339.         va_FoolFillCodedBufJPG(fool_ctx);
  340.        
  341.     return 0;
  342. }
  343.  
  344.  
  345. VAStatus va_FoolMapBuffer(
  346.     VADisplay dpy,
  347.     VABufferID buf_id,  /* in */
  348.     void **pbuf         /* out */
  349. )
  350. {
  351.     unsigned int magic, buftype;
  352.     DPY2FOOLCTX_CHK(dpy);
  353.  
  354.     magic = buf_id & FOOL_BUFID_MASK;
  355.     if (magic != FOOL_BUFID_MAGIC)
  356.         return 0; /* could be VAImageBufferType from vaDeriveImage */
  357.    
  358.     buftype = buf_id & 0xff;
  359.     *pbuf = fool_ctx->fool_buf[buftype];
  360.  
  361.     /* it is coded buffer, fill coded segment from file */
  362.     if (*pbuf && (buftype == VAEncCodedBufferType))
  363.         va_FoolFillCodedBuf(fool_ctx);
  364.    
  365.     return 1; /* fool is valid */
  366. }
  367.  
  368. VAStatus va_FoolCheckContinuity(VADisplay dpy)
  369. {
  370.     DPY2FOOLCTX_CHK(dpy);
  371.  
  372.     return 1; /* fool is valid */
  373. }
  374.  
  375.