3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * Modified for use with MPlayer, see libmpeg-0.4.1.diff for the exact changes.
24 * detailed changelog at http://svn.mplayerhq.hu/mplayer/trunk/
30 #include <string.h> /* memcmp/memset, try to remove */
35 #include "attributes.h"
36 #include "mpeg2_internal.h"
38 static int mpeg2_accels
= 0;
40 #define BUFFER_SIZE (1194 * 1024)
42 const mpeg2_info_t
* mpeg2_info (mpeg2dec_t
* mpeg2dec
)
44 return &(mpeg2dec
->info
);
47 static inline int skip_chunk (mpeg2dec_t
* mpeg2dec
, int bytes
)
57 current
= mpeg2dec
->buf_start
;
58 shift
= mpeg2dec
->shift
;
59 limit
= current
+ bytes
;
63 if (shift
== 0x00000100) {
66 mpeg2dec
->shift
= 0xffffff00;
67 skipped
= current
- mpeg2dec
->buf_start
;
68 mpeg2dec
->buf_start
= current
;
71 shift
= (shift
| byte
) << 8;
72 } while (current
< limit
);
74 mpeg2dec
->shift
= shift
;
75 mpeg2dec
->buf_start
= current
;
79 static inline int copy_chunk (mpeg2dec_t
* mpeg2dec
, int bytes
)
90 current
= mpeg2dec
->buf_start
;
91 shift
= mpeg2dec
->shift
;
92 chunk_ptr
= mpeg2dec
->chunk_ptr
;
93 limit
= current
+ bytes
;
97 if (shift
== 0x00000100) {
100 mpeg2dec
->shift
= 0xffffff00;
101 mpeg2dec
->chunk_ptr
= chunk_ptr
+ 1;
102 copied
= current
- mpeg2dec
->buf_start
;
103 mpeg2dec
->buf_start
= current
;
106 shift
= (shift
| byte
) << 8;
108 } while (current
< limit
);
110 mpeg2dec
->shift
= shift
;
111 mpeg2dec
->buf_start
= current
;
115 void mpeg2_buffer (mpeg2dec_t
* mpeg2dec
, uint8_t * start
, uint8_t * end
)
117 mpeg2dec
->buf_start
= start
;
118 mpeg2dec
->buf_end
= end
;
121 int mpeg2_getpos (mpeg2dec_t
* mpeg2dec
)
123 return mpeg2dec
->buf_end
- mpeg2dec
->buf_start
;
126 static inline mpeg2_state_t
seek_chunk (mpeg2dec_t
* mpeg2dec
)
130 size
= mpeg2dec
->buf_end
- mpeg2dec
->buf_start
;
131 skipped
= skip_chunk (mpeg2dec
, size
);
133 mpeg2dec
->bytes_since_tag
+= size
;
136 mpeg2dec
->bytes_since_tag
+= skipped
;
137 mpeg2dec
->code
= mpeg2dec
->buf_start
[-1];
138 return (mpeg2_state_t
)-1;
141 mpeg2_state_t
mpeg2_seek_header (mpeg2dec_t
* mpeg2dec
)
143 while (mpeg2dec
->code
!= 0xb3 &&
144 ((mpeg2dec
->code
!= 0xb7 && mpeg2dec
->code
!= 0xb8 &&
145 mpeg2dec
->code
) || mpeg2dec
->sequence
.width
== (unsigned)-1))
146 if (seek_chunk (mpeg2dec
) == STATE_BUFFER
)
148 mpeg2dec
->chunk_start
= mpeg2dec
->chunk_ptr
= mpeg2dec
->chunk_buffer
;
149 mpeg2dec
->user_data_len
= 0;
150 return (mpeg2dec
->code
? mpeg2_parse_header (mpeg2dec
) :
151 mpeg2_header_picture_start (mpeg2dec
));
154 #define RECEIVED(code,state) (((state) << 8) + (code))
156 mpeg2_state_t
mpeg2_parse (mpeg2dec_t
* mpeg2dec
)
158 int size_buffer
, size_chunk
, copied
;
160 if (mpeg2dec
->action
) {
163 state
= mpeg2dec
->action (mpeg2dec
);
169 while ((unsigned) (mpeg2dec
->code
- mpeg2dec
->first_decode_slice
) <
170 mpeg2dec
->nb_decode_slices
) {
171 size_buffer
= mpeg2dec
->buf_end
- mpeg2dec
->buf_start
;
172 size_chunk
= (mpeg2dec
->chunk_buffer
+ BUFFER_SIZE
-
173 mpeg2dec
->chunk_ptr
);
174 if (size_buffer
<= size_chunk
) {
175 copied
= copy_chunk (mpeg2dec
, size_buffer
);
177 mpeg2dec
->bytes_since_tag
+= size_buffer
;
178 mpeg2dec
->chunk_ptr
+= size_buffer
;
182 copied
= copy_chunk (mpeg2dec
, size_chunk
);
184 /* filled the chunk buffer without finding a start code */
185 mpeg2dec
->bytes_since_tag
+= size_chunk
;
186 mpeg2dec
->action
= seek_chunk
;
187 return STATE_INVALID
;
190 mpeg2dec
->bytes_since_tag
+= copied
;
192 mpeg2_slice (&(mpeg2dec
->decoder
), mpeg2dec
->code
,
193 mpeg2dec
->chunk_start
);
194 mpeg2dec
->code
= mpeg2dec
->buf_start
[-1];
195 mpeg2dec
->chunk_ptr
= mpeg2dec
->chunk_start
;
197 if ((unsigned) (mpeg2dec
->code
- 1) >= 0xb0 - 1)
199 if (seek_chunk (mpeg2dec
) == STATE_BUFFER
)
203 switch (mpeg2dec
->code
) {
205 mpeg2dec
->action
= mpeg2_header_picture_start
;
206 return mpeg2dec
->state
;
208 mpeg2dec
->action
= mpeg2_header_end
;
212 mpeg2dec
->action
= mpeg2_parse_header
;
215 mpeg2dec
->action
= seek_chunk
;
216 return STATE_INVALID
;
218 return (mpeg2dec
->state
== STATE_SLICE
) ? STATE_SLICE
: STATE_INVALID
;
221 mpeg2_state_t
mpeg2_parse_header (mpeg2dec_t
* mpeg2dec
)
223 static int (* process_header
[]) (mpeg2dec_t
* mpeg2dec
) = {
224 mpeg2_header_picture
, mpeg2_header_extension
, mpeg2_header_user_data
,
225 mpeg2_header_sequence
, NULL
, NULL
, NULL
, NULL
, mpeg2_header_gop
227 int size_buffer
, size_chunk
, copied
;
229 mpeg2dec
->action
= mpeg2_parse_header
;
230 mpeg2dec
->info
.user_data
= NULL
; mpeg2dec
->info
.user_data_len
= 0;
232 size_buffer
= mpeg2dec
->buf_end
- mpeg2dec
->buf_start
;
233 size_chunk
= (mpeg2dec
->chunk_buffer
+ BUFFER_SIZE
-
234 mpeg2dec
->chunk_ptr
);
235 if (size_buffer
<= size_chunk
) {
236 copied
= copy_chunk (mpeg2dec
, size_buffer
);
238 mpeg2dec
->bytes_since_tag
+= size_buffer
;
239 mpeg2dec
->chunk_ptr
+= size_buffer
;
243 copied
= copy_chunk (mpeg2dec
, size_chunk
);
245 /* filled the chunk buffer without finding a start code */
246 mpeg2dec
->bytes_since_tag
+= size_chunk
;
247 mpeg2dec
->code
= 0xb4;
248 mpeg2dec
->action
= mpeg2_seek_header
;
249 return STATE_INVALID
;
252 mpeg2dec
->bytes_since_tag
+= copied
;
254 if (process_header
[mpeg2dec
->code
& 0x0b] (mpeg2dec
)) {
255 mpeg2dec
->code
= mpeg2dec
->buf_start
[-1];
256 mpeg2dec
->action
= mpeg2_seek_header
;
257 return STATE_INVALID
;
260 mpeg2dec
->code
= mpeg2dec
->buf_start
[-1];
261 switch (RECEIVED (mpeg2dec
->code
, mpeg2dec
->state
)) {
263 /* state transition after a sequence header */
264 case RECEIVED (0x00, STATE_SEQUENCE
):
265 mpeg2dec
->action
= mpeg2_header_picture_start
;
266 case RECEIVED (0xb8, STATE_SEQUENCE
):
267 mpeg2_header_sequence_finalize (mpeg2dec
);
270 /* other legal state transitions */
271 case RECEIVED (0x00, STATE_GOP
):
272 mpeg2_header_gop_finalize (mpeg2dec
);
273 mpeg2dec
->action
= mpeg2_header_picture_start
;
275 case RECEIVED (0x01, STATE_PICTURE
):
276 case RECEIVED (0x01, STATE_PICTURE_2ND
):
277 mpeg2_header_picture_finalize (mpeg2dec
, mpeg2_accels
);
278 mpeg2dec
->action
= mpeg2_header_slice_start
;
281 /* legal headers within a given state */
282 case RECEIVED (0xb2, STATE_SEQUENCE
):
283 case RECEIVED (0xb2, STATE_GOP
):
284 case RECEIVED (0xb2, STATE_PICTURE
):
285 case RECEIVED (0xb2, STATE_PICTURE_2ND
):
286 case RECEIVED (0xb5, STATE_SEQUENCE
):
287 case RECEIVED (0xb5, STATE_PICTURE
):
288 case RECEIVED (0xb5, STATE_PICTURE_2ND
):
289 mpeg2dec
->chunk_ptr
= mpeg2dec
->chunk_start
;
293 mpeg2dec
->action
= mpeg2_seek_header
;
294 return STATE_INVALID
;
297 mpeg2dec
->chunk_start
= mpeg2dec
->chunk_ptr
= mpeg2dec
->chunk_buffer
;
298 mpeg2dec
->user_data_len
= 0;
299 return mpeg2dec
->state
;
303 int mpeg2_convert (mpeg2dec_t
* mpeg2dec
, mpeg2_convert_t convert
, void * arg
)
305 mpeg2_convert_init_t convert_init
;
308 error
= convert (MPEG2_CONVERT_SET
, NULL
, &(mpeg2dec
->sequence
), 0,
309 mpeg2_accels
, arg
, &convert_init
);
311 mpeg2dec
->convert
= convert
;
312 mpeg2dec
->convert_arg
= arg
;
313 mpeg2dec
->convert_id_size
= convert_init
.id_size
;
314 mpeg2dec
->convert_stride
= 0;
319 int mpeg2_stride (mpeg2dec_t
* mpeg2dec
, int stride
)
321 if (!mpeg2dec
->convert
) {
322 if (stride
< (int) mpeg2dec
->sequence
.width
)
323 stride
= mpeg2dec
->sequence
.width
;
324 mpeg2dec
->decoder
.stride_frame
= stride
;
326 mpeg2_convert_init_t convert_init
;
328 stride
= mpeg2dec
->convert (MPEG2_CONVERT_STRIDE
, NULL
,
329 &(mpeg2dec
->sequence
), stride
,
330 mpeg2_accels
, mpeg2dec
->convert_arg
,
332 mpeg2dec
->convert_id_size
= convert_init
.id_size
;
333 mpeg2dec
->convert_stride
= stride
;
338 void mpeg2_set_buf (mpeg2dec_t
* mpeg2dec
, uint8_t * buf
[3], void * id
)
342 if (mpeg2dec
->custom_fbuf
) {
343 if (mpeg2dec
->state
== STATE_SEQUENCE
) {
344 mpeg2dec
->fbuf
[2] = mpeg2dec
->fbuf
[1];
345 mpeg2dec
->fbuf
[1] = mpeg2dec
->fbuf
[0];
347 mpeg2_set_fbuf (mpeg2dec
, (mpeg2dec
->decoder
.coding_type
==
348 PIC_FLAG_CODING_TYPE_B
));
349 fbuf
= mpeg2dec
->fbuf
[0];
351 fbuf
= &(mpeg2dec
->fbuf_alloc
[mpeg2dec
->alloc_index
].fbuf
);
352 mpeg2dec
->alloc_index_user
= ++mpeg2dec
->alloc_index
;
354 fbuf
->buf
[0] = buf
[0];
355 fbuf
->buf
[1] = buf
[1];
356 fbuf
->buf
[2] = buf
[2];
358 // HACK! FIXME! At first I frame, copy pointers to prediction frame too!
359 if (mpeg2dec
->custom_fbuf
&& !mpeg2dec
->fbuf
[1]->buf
[0]){
360 mpeg2dec
->fbuf
[1]->buf
[0]=buf
[0];
361 mpeg2dec
->fbuf
[1]->buf
[1]=buf
[1];
362 mpeg2dec
->fbuf
[1]->buf
[2]=buf
[2];
363 mpeg2dec
->fbuf
[1]->id
=NULL
;
365 // printf("libmpeg2: FBUF 0:%p 1:%p 2:%p\n",
366 // mpeg2dec->fbuf[0]->buf[0],mpeg2dec->fbuf[1]->buf[0],mpeg2dec->fbuf[2]->buf[0]);
369 void mpeg2_custom_fbuf (mpeg2dec_t
* mpeg2dec
, int custom_fbuf
)
371 mpeg2dec
->custom_fbuf
= custom_fbuf
;
374 void mpeg2_skip (mpeg2dec_t
* mpeg2dec
, int skip
)
376 mpeg2dec
->first_decode_slice
= 1;
377 mpeg2dec
->nb_decode_slices
= skip
? 0 : (0xb0 - 1);
380 void mpeg2_slice_region (mpeg2dec_t
* mpeg2dec
, int start
, int end
)
382 start
= (start
< 1) ? 1 : (start
> 0xb0) ? 0xb0 : start
;
383 end
= (end
< start
) ? start
: (end
> 0xb0) ? 0xb0 : end
;
384 mpeg2dec
->first_decode_slice
= start
;
385 mpeg2dec
->nb_decode_slices
= end
- start
;
388 void mpeg2_tag_picture (mpeg2dec_t
* mpeg2dec
, uint32_t tag
, uint32_t tag2
)
390 mpeg2dec
->tag_previous
= mpeg2dec
->tag_current
;
391 mpeg2dec
->tag2_previous
= mpeg2dec
->tag2_current
;
392 mpeg2dec
->tag_current
= tag
;
393 mpeg2dec
->tag2_current
= tag2
;
394 mpeg2dec
->num_tags
++;
395 mpeg2dec
->bytes_since_tag
= 0;
398 uint32_t mpeg2_accel (uint32_t accel
)
401 if (accel
& MPEG2_ACCEL_DETECT
)
402 accel
|= mpeg2_detect_accel ();
403 mpeg2_accels
= accel
|= MPEG2_ACCEL_DETECT
;
404 mpeg2_cpu_state_init (accel
);
405 mpeg2_idct_init (accel
);
406 mpeg2_mc_init (accel
);
408 return mpeg2_accels
& ~MPEG2_ACCEL_DETECT
;
411 void mpeg2_reset (mpeg2dec_t
* mpeg2dec
, int full_reset
)
413 mpeg2dec
->buf_start
= mpeg2dec
->buf_end
= NULL
;
414 mpeg2dec
->num_tags
= 0;
415 mpeg2dec
->shift
= 0xffffff00;
416 mpeg2dec
->code
= 0xb4;
417 mpeg2dec
->action
= mpeg2_seek_header
;
418 mpeg2dec
->state
= STATE_INVALID
;
421 mpeg2_reset_info(&(mpeg2dec
->info
));
422 mpeg2dec
->info
.gop
= NULL
;
423 mpeg2dec
->info
.user_data
= NULL
;
424 mpeg2dec
->info
.user_data_len
= 0;
426 mpeg2dec
->info
.sequence
= NULL
;
427 mpeg2_header_state_init (mpeg2dec
);
432 mpeg2dec_t
* mpeg2_init (void)
434 mpeg2dec_t
* mpeg2dec
;
436 mpeg2_accel (MPEG2_ACCEL_DETECT
);
438 mpeg2dec
= (mpeg2dec_t
*) mpeg2_malloc (sizeof (mpeg2dec_t
),
439 MPEG2_ALLOC_MPEG2DEC
);
440 if (mpeg2dec
== NULL
)
443 memset (mpeg2dec
->decoder
.DCTblock
, 0, 64 * sizeof (int16_t));
444 memset (mpeg2dec
->quantizer_matrix
, 0, 4 * 64 * sizeof (uint8_t));
446 mpeg2dec
->chunk_buffer
= (uint8_t *) mpeg2_malloc (BUFFER_SIZE
+ 4,
449 mpeg2dec
->sequence
.width
= (unsigned)-1;
450 mpeg2_reset (mpeg2dec
, 1);
455 void mpeg2_close (mpeg2dec_t
* mpeg2dec
)
457 mpeg2_header_state_init (mpeg2dec
);
458 mpeg2_free (mpeg2dec
->chunk_buffer
);
459 mpeg2_free (mpeg2dec
);