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