Home | History | Annotate | Download | only in decode
      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