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