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 - MIN_BUFFER_BYTES_AT_EOS;
    108     }
    109 
    110     impeg2d_bit_stream_init(&(ps_dec->s_bit_stream),ps_ip->s_ivd_video_decode_ip_t.pv_stream_buffer,
    111         u4_size);
    112 
    113     {
    114         {
    115             IMPEG2D_ERROR_CODES_T e_error;
    116             e_error = impeg2d_process_video_header(ps_dec);
    117             if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
    118             {
    119                 ps_op->s_ivd_video_decode_op_t.u4_error_code    = e_error;
    120 
    121                 u4_bits_read     = impeg2d_bit_stream_num_bits_read(&ps_dec->s_bit_stream);
    122 
    123                 ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = u4_bits_read>> 3;
    124                 if(ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed > ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes)
    125                 {
    126                     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                 if(ps_op->s_ivd_video_decode_op_t.u4_error_code == 0)
    129                     ps_op->s_ivd_video_decode_op_t.u4_error_code = e_error;
    130 
    131                 if (IMPEG2D_UNSUPPORTED_DIMENSIONS == e_error)
    132                 {
    133                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
    134                     ps_dec->u2_header_done = 0;
    135 
    136                     ps_op->s_ivd_video_decode_op_t.u4_pic_ht = ps_dec->u2_reinit_max_height;
    137                     ps_op->s_ivd_video_decode_op_t.u4_pic_wd = ps_dec->u2_reinit_max_width;
    138                 }
    139                 impeg2d_next_code(ps_dec, SEQUENCE_HEADER_CODE);
    140                 return;
    141             }
    142         }
    143         ps_op->s_ivd_video_decode_op_t.u4_pic_ht = ps_dec->u2_vertical_size;
    144         ps_op->s_ivd_video_decode_op_t.u4_pic_wd = ps_dec->u2_horizontal_size;
    145 
    146         ps_op->s_ivd_video_decode_op_t.e_pic_type            = IV_NA_FRAME;
    147         ps_op->s_ivd_video_decode_op_t.u4_error_code        = IV_SUCCESS;
    148 
    149         u4_bits_read     = impeg2d_bit_stream_num_bits_read(&ps_dec->s_bit_stream);
    150         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = u4_bits_read>> 3;
    151         if(ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed > ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes)
    152         {
    153             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_frame_decoded_flag = 0;
    156         /* MOD */
    157         ps_dec->u2_header_done = 1;
    158 
    159     }
    160 }
    161 
    162 /*****************************************************************************/
    163 /*                                                                           */
    164 /*  Function Name : impeg2d_dec_frm                                         */
    165 /*                                                                           */
    166 /*  Description   :                                                          */
    167 /*  Inputs        :                                                          */
    168 /*  Globals       :                                                          */
    169 /*  Processing    :                                                          */
    170 /*  Outputs       :                                                          */
    171 /*  Returns       :                                                          */
    172 /*                                                                           */
    173 /*  Issues        :                                                          */
    174 /*                                                                           */
    175 /*  Revision History:                                                        */
    176 /*                                                                           */
    177 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
    178 /*         17 09 2007  Rajendra C Y          Draft                           */
    179 /*                                                                           */
    180 /*****************************************************************************/
    181 void impeg2d_dec_frm(void *pv_dec,impeg2d_video_decode_ip_t *ps_ip,
    182                  impeg2d_video_decode_op_t *ps_op)
    183 {
    184 
    185 
    186     stream_t *ps_stream;
    187     UWORD32 u4_size = ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes;
    188 
    189     dec_state_t *ps_dec;
    190 
    191     ps_dec = (dec_state_t *)pv_dec;
    192     ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
    193     ps_dec->i4_bytes_consumed = 0;
    194     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
    195 
    196     IMPEG2D_FRM_NUM_SET();
    197     if (u4_size >= MAX_BITSTREAM_BUFFER_SIZE)
    198     {
    199         u4_size = MAX_BITSTREAM_BUFFER_SIZE - MIN_BUFFER_BYTES_AT_EOS;
    200     }
    201 
    202     ps_dec->pu1_inp_bits_buf = ps_ip->s_ivd_video_decode_ip_t.pv_stream_buffer;
    203     ps_dec->u4_num_inp_bytes = u4_size;
    204     ps_stream  = &ps_dec->s_bit_stream;
    205 
    206     impeg2d_bit_stream_init(ps_stream,ps_ip->s_ivd_video_decode_ip_t.pv_stream_buffer,u4_size);
    207 
    208     /* @ */ /* Updating the bufferID */
    209 
    210     ps_dec->u4_xdmBufID     = ps_ip->s_ivd_video_decode_ip_t.u4_ts;
    211 
    212     {
    213         IMPEG2D_ERROR_CODES_T e_error;
    214         /* Process the Bitstream */
    215         e_error = impeg2d_process_video_bit_stream(ps_dec);
    216         if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
    217         {
    218             ps_op->s_ivd_video_decode_op_t.u4_error_code    = e_error;
    219 
    220             if ((IMPEG2D_ERROR_CODES_T) IVD_RES_CHANGED == e_error)
    221             {
    222                 ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
    223                 ps_dec->u2_header_done = 0;
    224             }
    225             else if (IMPEG2D_UNSUPPORTED_DIMENSIONS == e_error)
    226             {
    227                 ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
    228                 ps_dec->u2_header_done = 0;
    229 
    230                 ps_op->s_ivd_video_decode_op_t.u4_pic_ht = ps_dec->u2_reinit_max_height;
    231                 ps_op->s_ivd_video_decode_op_t.u4_pic_wd = ps_dec->u2_reinit_max_width;
    232             }
    233             else
    234             {
    235                 if(ps_dec->i4_num_cores > 1 && 0 != ps_dec->i4_bytes_consumed)
    236                 {
    237                     /* If the number of bytes consumed has been updated by
    238                      * get_slice_pos function, then use that. Else, the bytes consumed is
    239                      * calculated from the offset. The bytes consumed for multi-thread runs
    240                      * is updated only into ps_dec->i4_bytes_consumed if the get_slice_pos
    241                      * function has been called. If that function has not run, then we have
    242                      * encountered an error but still have to consume the bytes in header
    243                      * decode, etc.
    244                      */
    245                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
    246                 }
    247                 else
    248                 {
    249                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
    250                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed -= ((size_t)ps_dec->s_bit_stream.pv_bs_buf & 3);
    251                 }
    252 
    253                 if(ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed
    254                                 > ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes)
    255                 {
    256                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed =
    257                                     ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes;
    258                 }
    259 
    260                 impeg2d_next_start_code(ps_dec);
    261             }
    262 
    263             if(ps_op->s_ivd_video_decode_op_t.u4_error_code == 0)
    264             {
    265                 ps_op->s_ivd_video_decode_op_t.u4_error_code = e_error;
    266             }
    267 
    268             return;
    269         }
    270     }
    271     /**************************************************************************/
    272     /* Remove the bytes left till next start code is encountered              */
    273     /**************************************************************************/
    274     ps_op->s_ivd_video_decode_op_t.u4_error_code  = IV_SUCCESS;
    275 
    276     if(ps_dec->i4_num_cores > 1 && 0 != ps_dec->i4_bytes_consumed)
    277     {
    278         /* If the number of bytes consumed has been updated by
    279          * get_slice_pos function, then use that. Else, the bytes consumed is
    280          * calculated from the offset. The bytes consumed for multi-thread runs
    281          * is updated only into ps_dec->i4_bytes_consumed if the get_slice_pos
    282          * function has been called. If that function has not run, then we have
    283          * encountered an error but still have to consume the bytes in header
    284          * decode, etc.
    285          */
    286         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
    287     }
    288     else
    289     {
    290         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
    291         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed -= ((size_t)ps_dec->s_bit_stream.pv_bs_buf & 3);
    292     }
    293     if(ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed > ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes)
    294     {
    295         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes;
    296     }
    297     ps_op->s_ivd_video_decode_op_t.u4_pic_ht = ps_dec->u2_vertical_size;
    298     ps_op->s_ivd_video_decode_op_t.u4_pic_wd = ps_dec->u2_horizontal_size;
    299 
    300         switch(ps_dec->e_pic_type)
    301         {
    302         case I_PIC :
    303             ps_op->s_ivd_video_decode_op_t.e_pic_type = IV_I_FRAME;
    304             break;
    305 
    306         case P_PIC:
    307             ps_op->s_ivd_video_decode_op_t.e_pic_type = IV_P_FRAME;
    308             break;
    309 
    310         case B_PIC:
    311             ps_op->s_ivd_video_decode_op_t.e_pic_type = IV_B_FRAME;
    312             break;
    313 
    314         case D_PIC:
    315             ps_op->s_ivd_video_decode_op_t.e_pic_type = IV_I_FRAME;
    316             break;
    317 
    318         default :
    319             ps_op->s_ivd_video_decode_op_t.e_pic_type = IV_FRAMETYPE_DEFAULT;
    320             break;
    321         }
    322 
    323         ps_op->s_ivd_video_decode_op_t.u4_frame_decoded_flag = ps_dec->i4_frame_decoded;
    324         ps_op->s_ivd_video_decode_op_t.u4_new_seq = 0;
    325         ps_op->s_ivd_video_decode_op_t.u4_error_code = ps_dec->u4_error_code;
    326 
    327 
    328 }
    329