Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2007-2008 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. /*
  26.  * it is a real program to show how VAAPI decode work,
  27.  * It does VLD decode for a simple MPEG2 clip "mpeg2-I.m2v"
  28.  * "mpeg2-I.m2v" and VA parameters are hardcoded into mpeg2vldemo.c,
  29.  * See mpeg2-I.jif to know how those VA parameters come from
  30.  *
  31.  * gcc -o  mpeg2vldemo  mpeg2vldemo.c -lva -lva-x11 -I/usr/include/va
  32.  * ./mpeg2vldemo  : only do decode
  33.  * ./mpeg2vldemo <any parameter >: decode+display
  34.  *
  35.  */  
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <stdlib.h>
  39. #include <getopt.h>
  40. #include <unistd.h>
  41. #include <sys/types.h>
  42. #include <sys/stat.h>
  43. #include <fcntl.h>
  44. #include <assert.h>
  45. #include <va/va.h>
  46. #include "va_display.h"
  47.  
  48. #define CHECK_VASTATUS(va_status,func)                                  \
  49. if (va_status != VA_STATUS_SUCCESS) {                                   \
  50.     fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \
  51.     exit(1);                                                            \
  52. }
  53.  
  54. /* Data dump of a 16x16 MPEG2 video clip,it has one I frame
  55.  */
  56. static unsigned char mpeg2_clip[]={
  57.     0x00,0x00,0x01,0xb3,0x01,0x00,0x10,0x13,0xff,0xff,0xe0,0x18,0x00,0x00,0x01,0xb5,
  58.     0x14,0x8a,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0xb8,0x00,0x08,0x00,0x00,0x00,0x00,
  59.     0x01,0x00,0x00,0x0f,0xff,0xf8,0x00,0x00,0x01,0xb5,0x8f,0xff,0xf3,0x41,0x80,0x00,
  60.     0x00,0x01,0x01,0x13,0xe1,0x00,0x15,0x81,0x54,0xe0,0x2a,0x05,0x43,0x00,0x2d,0x60,
  61.     0x18,0x01,0x4e,0x82,0xb9,0x58,0xb1,0x83,0x49,0xa4,0xa0,0x2e,0x05,0x80,0x4b,0x7a,
  62.     0x00,0x01,0x38,0x20,0x80,0xe8,0x05,0xff,0x60,0x18,0xe0,0x1d,0x80,0x98,0x01,0xf8,
  63.     0x06,0x00,0x54,0x02,0xc0,0x18,0x14,0x03,0xb2,0x92,0x80,0xc0,0x18,0x94,0x42,0x2c,
  64.     0xb2,0x11,0x64,0xa0,0x12,0x5e,0x78,0x03,0x3c,0x01,0x80,0x0e,0x80,0x18,0x80,0x6b,
  65.     0xca,0x4e,0x01,0x0f,0xe4,0x32,0xc9,0xbf,0x01,0x42,0x69,0x43,0x50,0x4b,0x01,0xc9,
  66.     0x45,0x80,0x50,0x01,0x38,0x65,0xe8,0x01,0x03,0xf3,0xc0,0x76,0x00,0xe0,0x03,0x20,
  67.     0x28,0x18,0x01,0xa9,0x34,0x04,0xc5,0xe0,0x0b,0x0b,0x04,0x20,0x06,0xc0,0x89,0xff,
  68.     0x60,0x12,0x12,0x8a,0x2c,0x34,0x11,0xff,0xf6,0xe2,0x40,0xc0,0x30,0x1b,0x7a,0x01,
  69.     0xa9,0x0d,0x00,0xac,0x64
  70. };
  71.  
  72. /* hardcoded here without a bitstream parser helper
  73.  * please see picture mpeg2-I.jpg for bitstream details
  74.  */
  75. static VAPictureParameterBufferMPEG2 pic_param={
  76.   horizontal_size:16,
  77.   vertical_size:16,
  78.   forward_reference_picture:0xffffffff,
  79.   backward_reference_picture:0xffffffff,
  80.   picture_coding_type:1,
  81.   f_code:0xffff,
  82.   {
  83.       {
  84.         intra_dc_precision:0,
  85.         picture_structure:3,
  86.         top_field_first:0,
  87.         frame_pred_frame_dct:1,
  88.         concealment_motion_vectors:0,
  89.         q_scale_type:0,
  90.         intra_vlc_format:0,
  91.         alternate_scan:0,
  92.         repeat_first_field:0,
  93.         progressive_frame:1 ,
  94.         is_first_field:1
  95.       },
  96.   }
  97. };
  98.  
  99. /* see MPEG2 spec65 for the defines of matrix */
  100. static VAIQMatrixBufferMPEG2 iq_matrix = {
  101.   load_intra_quantiser_matrix:1,
  102.   load_non_intra_quantiser_matrix:1,
  103.   load_chroma_intra_quantiser_matrix:0,
  104.   load_chroma_non_intra_quantiser_matrix:0,
  105.   intra_quantiser_matrix:{
  106.          8, 16, 16, 19, 16, 19, 22, 22,
  107.         22, 22, 22, 22, 26, 24, 26, 27,
  108.         27, 27, 26, 26, 26, 26, 27, 27,
  109.         27, 29, 29, 29, 34, 34, 34, 29,
  110.         29, 29, 27, 27, 29, 29, 32, 32,
  111.         34, 34, 37, 38, 37, 35, 35, 34,
  112.         35, 38, 38, 40, 40, 40, 48, 48,
  113.         46, 46, 56, 56, 58, 69, 69, 83
  114.     },
  115.   non_intra_quantiser_matrix:{16},
  116.   chroma_intra_quantiser_matrix:{0},
  117.   chroma_non_intra_quantiser_matrix:{0}
  118. };
  119.  
  120. #if 1
  121. static VASliceParameterBufferMPEG2 slice_param={
  122.   slice_data_size:150,
  123.   slice_data_offset:0,
  124.   slice_data_flag:0,
  125.   macroblock_offset:38, /* 4byte + 6bits=38bits */
  126.   slice_horizontal_position:0,
  127.   slice_vertical_position:0,
  128.   quantiser_scale_code:2,
  129.   intra_slice_flag:0
  130. };
  131. #endif
  132.  
  133. #define CLIP_WIDTH  16
  134. #define CLIP_HEIGHT 16
  135.  
  136. #define WIN_WIDTH  (CLIP_WIDTH<<1)
  137. #define WIN_HEIGHT (CLIP_HEIGHT<<1)
  138.  
  139. int main(int argc,char **argv)
  140. {
  141.     VAEntrypoint entrypoints[5];
  142.     int num_entrypoints,vld_entrypoint;
  143.     VAConfigAttrib attrib;
  144.     VAConfigID config_id;
  145.     VASurfaceID surface_id;
  146.     VAContextID context_id;
  147.     VABufferID pic_param_buf,iqmatrix_buf,slice_param_buf,slice_data_buf;
  148.     int major_ver, minor_ver;
  149.     VADisplay   va_dpy;
  150.     VAStatus va_status;
  151.     int putsurface=0;
  152.  
  153.     va_init_display_args(&argc, argv);
  154.  
  155.     if (argc > 1)
  156.         putsurface=1;
  157.    
  158.     va_dpy = va_open_display();
  159.     va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
  160.     assert(va_status == VA_STATUS_SUCCESS);
  161.    
  162.     va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileMPEG2Main, entrypoints,
  163.                              &num_entrypoints);
  164.     CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
  165.  
  166.     for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; vld_entrypoint++) {
  167.         if (entrypoints[vld_entrypoint] == VAEntrypointVLD)
  168.             break;
  169.     }
  170.     if (vld_entrypoint == num_entrypoints) {
  171.         /* not find VLD entry point */
  172.         assert(0);
  173.     }
  174.  
  175.     /* Assuming finding VLD, find out the format for the render target */
  176.     attrib.type = VAConfigAttribRTFormat;
  177.     vaGetConfigAttributes(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
  178.                           &attrib, 1);
  179.     if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) {
  180.         /* not find desired YUV420 RT format */
  181.         assert(0);
  182.     }
  183.    
  184.     va_status = vaCreateConfig(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD,
  185.                               &attrib, 1,&config_id);
  186.     CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
  187.  
  188.     va_status = vaCreateSurfaces(
  189.         va_dpy,
  190.         VA_RT_FORMAT_YUV420, CLIP_WIDTH, CLIP_HEIGHT,
  191.         &surface_id, 1,
  192.         NULL, 0
  193.     );
  194.     CHECK_VASTATUS(va_status, "vaCreateSurfaces");
  195.  
  196.     /* Create a context for this decode pipe */
  197.     va_status = vaCreateContext(va_dpy, config_id,
  198.                                CLIP_WIDTH,
  199.                                ((CLIP_HEIGHT+15)/16)*16,
  200.                                VA_PROGRESSIVE,
  201.                                &surface_id,
  202.                                1,
  203.                                &context_id);
  204.     CHECK_VASTATUS(va_status, "vaCreateContext");
  205.    
  206.     va_status = vaCreateBuffer(va_dpy, context_id,
  207.                               VAPictureParameterBufferType,
  208.                               sizeof(VAPictureParameterBufferMPEG2),
  209.                               1, &pic_param,
  210.                               &pic_param_buf);
  211.     CHECK_VASTATUS(va_status, "vaCreateBuffer");
  212.    
  213.     va_status = vaCreateBuffer(va_dpy, context_id,
  214.                               VAIQMatrixBufferType,
  215.                               sizeof(VAIQMatrixBufferMPEG2),
  216.                               1, &iq_matrix,
  217.                               &iqmatrix_buf );
  218.     CHECK_VASTATUS(va_status, "vaCreateBuffer");
  219.  
  220.     va_status = vaCreateBuffer(va_dpy, context_id,
  221.                               VASliceParameterBufferType,
  222.                               sizeof(VASliceParameterBufferMPEG2),
  223.                               1,
  224.                               &slice_param, &slice_param_buf);
  225.     CHECK_VASTATUS(va_status, "vaCreateBuffer");
  226.  
  227.     va_status = vaCreateBuffer(va_dpy, context_id,
  228.                               VASliceDataBufferType,
  229.                               0xc4-0x2f+1,
  230.                               1,
  231.                               mpeg2_clip+0x2f,
  232.                               &slice_data_buf);
  233.     CHECK_VASTATUS(va_status, "vaCreateBuffer");
  234.  
  235.     va_status = vaBeginPicture(va_dpy, context_id, surface_id);
  236.     CHECK_VASTATUS(va_status, "vaBeginPicture");
  237.  
  238.     va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1);
  239.     CHECK_VASTATUS(va_status, "vaRenderPicture");
  240.    
  241.     va_status = vaRenderPicture(va_dpy,context_id, &iqmatrix_buf, 1);
  242.     CHECK_VASTATUS(va_status, "vaRenderPicture");
  243.    
  244.     va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1);
  245.     CHECK_VASTATUS(va_status, "vaRenderPicture");
  246.    
  247.     va_status = vaRenderPicture(va_dpy,context_id, &slice_data_buf, 1);
  248.     CHECK_VASTATUS(va_status, "vaRenderPicture");
  249.    
  250.     va_status = vaEndPicture(va_dpy,context_id);
  251.     CHECK_VASTATUS(va_status, "vaEndPicture");
  252.  
  253.     va_status = vaSyncSurface(va_dpy, surface_id);
  254.     CHECK_VASTATUS(va_status, "vaSyncSurface");
  255.  
  256.     if (putsurface) {
  257.         VARectangle src_rect, dst_rect;
  258.  
  259.         src_rect.x      = 0;
  260.         src_rect.y      = 0;
  261.         src_rect.width  = CLIP_WIDTH;
  262.         src_rect.height = CLIP_HEIGHT;
  263.  
  264.         dst_rect.x      = 0;
  265.         dst_rect.y      = 0;
  266.         dst_rect.width  = WIN_WIDTH;
  267.         dst_rect.height = WIN_HEIGHT;
  268.  
  269.         va_status = va_put_surface(va_dpy, surface_id, &src_rect, &dst_rect);
  270.         CHECK_VASTATUS(va_status, "vaPutSurface");
  271.     }
  272.     printf("press any key to exit\n");
  273.     getchar();
  274.  
  275.     vaDestroySurfaces(va_dpy,&surface_id,1);
  276.     vaDestroyConfig(va_dpy,config_id);
  277.     vaDestroyContext(va_dpy,context_id);
  278.  
  279.     vaTerminate(va_dpy);
  280.     va_close_display(va_dpy);
  281.     return 0;
  282. }
  283.