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