Home | History | Annotate | Download | only in decoder
      1 /******************************************************************************
      2  *
      3  * Copyright (C) 2015 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at:
      8  *
      9  * http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *
     17  *****************************************************************************
     18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
     19 */
     20 /*****************************************************************************/
     21 /*                                                                           */
     22 /*  File Name         : mpeg2dec_api_utils.c                                 */
     23 /*                                                                           */
     24 /*                                                                           */
     25 /*  Description       : This file defines the API interface for MPEG2 Decoder*/
     26 /*                                                                           */
     27 /*  List of Functions : <List the functions defined in this file>            */
     28 /*                                                                           */
     29 /*  Issues / Problems : None                                                 */
     30 /*                                                                           */
     31 /*  Revision History  :                                                      */
     32 /*                                                                           */
     33 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
     34 /*         17 09 2007  Rajendra C Y       Creation                           */
     35 /*                                                                           */
     36 /*****************************************************************************/
     37 
     38 /*****************************************************************************/
     39 /* File Includes                                                             */
     40 /*****************************************************************************/
     41 /* System include files */
     42 
     43 #include <stddef.h>
     44 #include <stdio.h>
     45 #include <string.h>
     46 
     47 /* User include files */
     48 #include "iv_datatypedef.h"
     49 #include "iv.h"
     50 #include "ivd.h"
     51 #include "ithread.h"
     52 
     53 #include "impeg2_job_queue.h"
     54 #include "impeg2_macros.h"
     55 #include "impeg2_buf_mgr.h"
     56 #include "impeg2_disp_mgr.h"
     57 #include "impeg2_defs.h"
     58 #include "impeg2_platform_macros.h"
     59 #include "impeg2_inter_pred.h"
     60 #include "impeg2_idct.h"
     61 #include "impeg2_format_conv.h"
     62 #include "impeg2_mem_func.h"
     63 
     64 #include "impeg2d.h"
     65 #include "impeg2d_api.h"
     66 #include "impeg2d_bitstream.h"
     67 #include "impeg2d_debug.h"
     68 #include "impeg2d_structs.h"
     69 #include "impeg2d_mc.h"
     70 #include "impeg2d_pic_proc.h"
     71 #include "impeg2d_dec_hdr.h"
     72 
     73 void impeg2d_next_start_code(dec_state_t *ps_dec);
     74 void impeg2d_next_code(dec_state_t *ps_dec, UWORD32 u4_start_code_val);
     75 
     76 /*****************************************************************************/
     77 /*                                                                           */
     78 /*  Function Name : impeg2d_dec_hdr                                      */
     79 /*                                                                           */
     80 /*  Description   :                                                          */
     81 /*  Inputs        :                                                          */
     82 /*  Globals       :                                                          */
     83 /*  Processing    :                                                          */
     84 /*  Outputs       :                                                          */
     85 /*  Returns       :                                                          */
     86 /*                                                                           */
     87 /*  Issues        :                                                          */
     88 /*                                                                           */
     89 /*  Revision History:                                                        */
     90 /*                                                                           */
     91 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
     92 /*         17 09 2007  Rajendra C Y          Draft                           */
     93 /*                                                                           */
     94 /*****************************************************************************/
     95 void impeg2d_dec_hdr(void *pv_dec,impeg2d_video_decode_ip_t *ps_ip,
     96                  impeg2d_video_decode_op_t *ps_op)
     97 {
     98 
     99     UWORD32 u4_bits_read;
    100     dec_state_t *ps_dec;
    101     UWORD32 u4_size = ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes;
    102 
    103     ps_dec = (dec_state_t *)pv_dec;
    104     ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
    105     if (u4_size > MAX_BITSTREAM_BUFFER_SIZE)
    106     {
    107         u4_size = MAX_BITSTREAM_BUFFER_SIZE;
    108     }
    109 
    110     memcpy(ps_dec->pu1_input_buffer, ps_ip->s_ivd_video_decode_ip_t.pv_stream_buffer, u4_size);
    111 
    112     impeg2d_bit_stream_init(&(ps_dec->s_bit_stream), ps_dec->pu1_input_buffer,
    113         u4_size);
    114 
    115     {
    116         {
    117             IMPEG2D_ERROR_CODES_T e_error;
    118             e_error = impeg2d_process_video_header(ps_dec);
    119             if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
    120             {
    121                 ps_op->s_ivd_video_decode_op_t.u4_error_code    = e_error;
    122 
    123                 u4_bits_read     = impeg2d_bit_stream_num_bits_read(&ps_dec->s_bit_stream);
    124 
    125                 ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = u4_bits_read>> 3;
    126                 if(ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed > ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes)
    127                 {
    128                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes;
    129                 }
    130                 if(ps_op->s_ivd_video_decode_op_t.u4_error_code == 0)
    131                     ps_op->s_ivd_video_decode_op_t.u4_error_code = e_error;
    132 
    133                 if (IMPEG2D_UNSUPPORTED_DIMENSIONS == e_error)
    134                 {
    135                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
    136                     ps_dec->u2_header_done = 0;
    137 
    138                     ps_op->s_ivd_video_decode_op_t.u4_pic_ht = ps_dec->u2_reinit_max_height;
    139                     ps_op->s_ivd_video_decode_op_t.u4_pic_wd = ps_dec->u2_reinit_max_width;
    140                 }
    141                 impeg2d_next_code(ps_dec, SEQUENCE_HEADER_CODE);
    142                 return;
    143             }
    144         }
    145         ps_op->s_ivd_video_decode_op_t.u4_pic_ht = ps_dec->u2_vertical_size;
    146         ps_op->s_ivd_video_decode_op_t.u4_pic_wd = ps_dec->u2_horizontal_size;
    147 
    148         ps_op->s_ivd_video_decode_op_t.e_pic_type            = IV_NA_FRAME;
    149         ps_op->s_ivd_video_decode_op_t.u4_error_code        = IV_SUCCESS;
    150 
    151         u4_bits_read     = impeg2d_bit_stream_num_bits_read(&ps_dec->s_bit_stream);
    152         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = u4_bits_read>> 3;
    153         if(ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed > ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes)
    154         {
    155             ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes;
    156         }
    157         ps_op->s_ivd_video_decode_op_t.u4_frame_decoded_flag = 0;
    158         /* MOD */
    159         ps_dec->u2_header_done = 1;
    160 
    161     }
    162 }
    163 
    164 /*****************************************************************************/
    165 /*                                                                           */
    166 /*  Function Name : impeg2d_dec_frm                                         */
    167 /*                                                                           */
    168 /*  Description   :                                                          */
    169 /*  Inputs        :                                                          */
    170 /*  Globals       :                                                          */
    171 /*  Processing    :                                                          */
    172 /*  Outputs       :                                                          */
    173 /*  Returns       :                                                          */
    174 /*                                                                           */
    175 /*  Issues        :                                                          */
    176 /*                                                                           */
    177 /*  Revision History:                                                        */
    178 /*                                                                           */
    179 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
    180 /*         17 09 2007  Rajendra C Y          Draft                           */
    181 /*                                                                           */
    182 /*****************************************************************************/
    183 void impeg2d_dec_frm(void *pv_dec,impeg2d_video_decode_ip_t *ps_ip,
    184                  impeg2d_video_decode_op_t *ps_op)
    185 {
    186 
    187 
    188     stream_t *ps_stream;
    189     UWORD32 u4_size = ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes;
    190 
    191     dec_state_t *ps_dec;
    192 
    193     ps_dec = (dec_state_t *)pv_dec;
    194     ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
    195     ps_dec->i4_bytes_consumed = 0;
    196     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
    197 
    198     IMPEG2D_FRM_NUM_SET();
    199     if (u4_size > MAX_BITSTREAM_BUFFER_SIZE)
    200     {
    201         u4_size = MAX_BITSTREAM_BUFFER_SIZE;
    202     }
    203 
    204     memcpy(ps_dec->pu1_input_buffer, ps_ip->s_ivd_video_decode_ip_t.pv_stream_buffer, u4_size);
    205 
    206     ps_dec->pu1_inp_bits_buf = ps_dec->pu1_input_buffer;
    207 
    208     ps_dec->u4_num_inp_bytes = u4_size;
    209     ps_stream  = &ps_dec->s_bit_stream;
    210 
    211     impeg2d_bit_stream_init(ps_stream, ps_dec->pu1_input_buffer, u4_size);
    212 
    213     /* @ */ /* Updating the bufferID */
    214 
    215     ps_dec->u4_xdmBufID     = ps_ip->s_ivd_video_decode_ip_t.u4_ts;
    216 
    217     {
    218         IMPEG2D_ERROR_CODES_T e_error;
    219         /* Process the Bitstream */
    220         e_error = impeg2d_process_video_bit_stream(ps_dec);
    221         if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
    222         {
    223             ps_op->s_ivd_video_decode_op_t.u4_error_code    = e_error;
    224 
    225             if ((IMPEG2D_ERROR_CODES_T) IVD_RES_CHANGED == e_error)
    226             {
    227                 ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
    228                 ps_dec->u2_header_done = 0;
    229             }
    230             else if (IMPEG2D_UNSUPPORTED_DIMENSIONS == e_error)
    231             {
    232                 ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
    233                 ps_dec->u2_header_done = 0;
    234 
    235                 ps_op->s_ivd_video_decode_op_t.u4_pic_ht = ps_dec->u2_reinit_max_height;
    236                 ps_op->s_ivd_video_decode_op_t.u4_pic_wd = ps_dec->u2_reinit_max_width;
    237             }
    238             else
    239             {
    240                 if(ps_dec->i4_num_cores > 1 && 0 != ps_dec->i4_bytes_consumed)
    241                 {
    242                     /* If the number of bytes consumed has been updated by
    243                      * get_slice_pos function, then use that. Else, the bytes consumed is
    244                      * calculated from the offset. The bytes consumed for multi-thread runs
    245                      * is updated only into ps_dec->i4_bytes_consumed if the get_slice_pos
    246                      * function has been called. If that function has not run, then we have
    247                      * encountered an error but still have to consume the bytes in header
    248                      * decode, etc.
    249                      */
    250                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
    251                 }
    252                 else
    253                 {
    254                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
    255                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed -= ((size_t)ps_dec->s_bit_stream.pv_bs_buf & 3);
    256                 }
    257 
    258                 if(ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed
    259                                 > ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes)
    260                 {
    261                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed =
    262                                     ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes;
    263                 }
    264 
    265                 impeg2d_next_start_code(ps_dec);
    266             }
    267 
    268             if(ps_op->s_ivd_video_decode_op_t.u4_error_code == 0)
    269             {
    270                 ps_op->s_ivd_video_decode_op_t.u4_error_code = e_error;
    271             }
    272 
    273             return;
    274         }
    275     }
    276     /**************************************************************************/
    277     /* Remove the bytes left till next start code is encountered              */
    278     /**************************************************************************/
    279     ps_op->s_ivd_video_decode_op_t.u4_error_code  = IV_SUCCESS;
    280 
    281     if(ps_dec->i4_num_cores > 1 && 0 != ps_dec->i4_bytes_consumed)
    282     {
    283         /* If the number of bytes consumed has been updated by
    284          * get_slice_pos function, then use that. Else, the bytes consumed is
    285          * calculated from the offset. The bytes consumed for multi-thread runs
    286          * is updated only into ps_dec->i4_bytes_consumed if the get_slice_pos
    287          * function has been called. If that function has not run, then we have
    288          * encountered an error but still have to consume the bytes in header
    289          * decode, etc.
    290          */
    291         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
    292     }
    293     else
    294     {
    295         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
    296         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed -= ((size_t)ps_dec->s_bit_stream.pv_bs_buf & 3);
    297     }
    298     if(ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed > ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes)
    299     {
    300         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes;
    301     }
    302     ps_op->s_ivd_video_decode_op_t.u4_pic_ht = ps_dec->u2_vertical_size;
    303     ps_op->s_ivd_video_decode_op_t.u4_pic_wd = ps_dec->u2_horizontal_size;
    304 
    305         switch(ps_dec->e_pic_type)
    306         {
    307         case I_PIC :
    308             ps_op->s_ivd_video_decode_op_t.e_pic_type = IV_I_FRAME;
    309             break;
    310 
    311         case P_PIC:
    312             ps_op->s_ivd_video_decode_op_t.e_pic_type = IV_P_FRAME;
    313             break;
    314 
    315         case B_PIC:
    316             ps_op->s_ivd_video_decode_op_t.e_pic_type = IV_B_FRAME;
    317             break;
    318 
    319         case D_PIC:
    320             ps_op->s_ivd_video_decode_op_t.e_pic_type = IV_I_FRAME;
    321             break;
    322 
    323         default :
    324             ps_op->s_ivd_video_decode_op_t.e_pic_type = IV_FRAMETYPE_DEFAULT;
    325             break;
    326         }
    327 
    328         ps_op->s_ivd_video_decode_op_t.u4_frame_decoded_flag = ps_dec->i4_frame_decoded;
    329         ps_op->s_ivd_video_decode_op_t.u4_new_seq = 0;
    330         ps_op->s_ivd_video_decode_op_t.u4_error_code = ps_dec->u4_error_code;
    331 
    332 
    333 }
    334