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