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