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 libmpeg2_changes.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 STATE_INTERNAL_NORETURN
;
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
== 0xb7) ?
151 mpeg2_header_end (mpeg2dec
) : mpeg2_parse_header (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
);
164 if ((int)state
> (int)STATE_INTERNAL_NORETURN
)
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 mpeg2dec
->action
= mpeg2_seek_header
;
204 switch (mpeg2dec
->code
) {
206 return mpeg2dec
->state
;
210 return (mpeg2dec
->state
== STATE_SLICE
) ? STATE_SLICE
: STATE_INVALID
;
212 mpeg2dec
->action
= seek_chunk
;
213 return STATE_INVALID
;
217 mpeg2_state_t
mpeg2_parse_header (mpeg2dec_t
* mpeg2dec
)
219 static int (* process_header
[]) (mpeg2dec_t
* mpeg2dec
) = {
220 mpeg2_header_picture
, mpeg2_header_extension
, mpeg2_header_user_data
,
221 mpeg2_header_sequence
, NULL
, NULL
, NULL
, NULL
, mpeg2_header_gop
223 int size_buffer
, size_chunk
, copied
;
225 mpeg2dec
->action
= mpeg2_parse_header
;
226 mpeg2dec
->info
.user_data
= NULL
; mpeg2dec
->info
.user_data_len
= 0;
228 size_buffer
= mpeg2dec
->buf_end
- mpeg2dec
->buf_start
;
229 size_chunk
= (mpeg2dec
->chunk_buffer
+ BUFFER_SIZE
-
230 mpeg2dec
->chunk_ptr
);
231 if (size_buffer
<= size_chunk
) {
232 copied
= copy_chunk (mpeg2dec
, size_buffer
);
234 mpeg2dec
->bytes_since_tag
+= size_buffer
;
235 mpeg2dec
->chunk_ptr
+= size_buffer
;
239 copied
= copy_chunk (mpeg2dec
, size_chunk
);
241 /* filled the chunk buffer without finding a start code */
242 mpeg2dec
->bytes_since_tag
+= size_chunk
;
243 mpeg2dec
->code
= 0xb4;
244 mpeg2dec
->action
= mpeg2_seek_header
;
245 return STATE_INVALID
;
248 mpeg2dec
->bytes_since_tag
+= copied
;
250 if (process_header
[mpeg2dec
->code
& 0x0b] (mpeg2dec
)) {
251 mpeg2dec
->code
= mpeg2dec
->buf_start
[-1];
252 mpeg2dec
->action
= mpeg2_seek_header
;
253 return STATE_INVALID
;
256 mpeg2dec
->code
= mpeg2dec
->buf_start
[-1];
257 switch (RECEIVED (mpeg2dec
->code
, mpeg2dec
->state
)) {
259 /* state transition after a sequence header */
260 case RECEIVED (0x00, STATE_SEQUENCE
):
261 case RECEIVED (0xb8, STATE_SEQUENCE
):
262 mpeg2_header_sequence_finalize (mpeg2dec
);
265 /* other legal state transitions */
266 case RECEIVED (0x00, STATE_GOP
):
267 mpeg2_header_gop_finalize (mpeg2dec
);
269 case RECEIVED (0x01, STATE_PICTURE
):
270 case RECEIVED (0x01, STATE_PICTURE_2ND
):
271 mpeg2_header_picture_finalize (mpeg2dec
, mpeg2_accels
);
272 mpeg2dec
->action
= mpeg2_header_slice_start
;
275 /* legal headers within a given state */
276 case RECEIVED (0xb2, STATE_SEQUENCE
):
277 case RECEIVED (0xb2, STATE_GOP
):
278 case RECEIVED (0xb2, STATE_PICTURE
):
279 case RECEIVED (0xb2, STATE_PICTURE_2ND
):
280 case RECEIVED (0xb5, STATE_SEQUENCE
):
281 case RECEIVED (0xb5, STATE_PICTURE
):
282 case RECEIVED (0xb5, STATE_PICTURE_2ND
):
283 mpeg2dec
->chunk_ptr
= mpeg2dec
->chunk_start
;
287 mpeg2dec
->action
= mpeg2_seek_header
;
288 return STATE_INVALID
;
291 mpeg2dec
->chunk_start
= mpeg2dec
->chunk_ptr
= mpeg2dec
->chunk_buffer
;
292 mpeg2dec
->user_data_len
= 0;
293 return mpeg2dec
->state
;
297 int mpeg2_convert (mpeg2dec_t
* mpeg2dec
, mpeg2_convert_t convert
, void * arg
)
299 mpeg2_convert_init_t convert_init
;
302 error
= convert (MPEG2_CONVERT_SET
, NULL
, &(mpeg2dec
->sequence
), 0,
303 mpeg2_accels
, arg
, &convert_init
);
305 mpeg2dec
->convert
= convert
;
306 mpeg2dec
->convert_arg
= arg
;
307 mpeg2dec
->convert_id_size
= convert_init
.id_size
;
308 mpeg2dec
->convert_stride
= 0;
313 int mpeg2_stride (mpeg2dec_t
* mpeg2dec
, int stride
)
315 if (!mpeg2dec
->convert
) {
316 if (stride
< (int) mpeg2dec
->sequence
.width
)
317 stride
= mpeg2dec
->sequence
.width
;
318 mpeg2dec
->decoder
.stride_frame
= stride
;
320 mpeg2_convert_init_t convert_init
;
322 stride
= mpeg2dec
->convert (MPEG2_CONVERT_STRIDE
, NULL
,
323 &(mpeg2dec
->sequence
), stride
,
324 mpeg2_accels
, mpeg2dec
->convert_arg
,
326 mpeg2dec
->convert_id_size
= convert_init
.id_size
;
327 mpeg2dec
->convert_stride
= stride
;
332 void mpeg2_set_buf (mpeg2dec_t
* mpeg2dec
, uint8_t * buf
[3], void * id
)
336 if (mpeg2dec
->custom_fbuf
) {
337 if (mpeg2dec
->state
== STATE_SEQUENCE
) {
338 mpeg2dec
->fbuf
[2] = mpeg2dec
->fbuf
[1];
339 mpeg2dec
->fbuf
[1] = mpeg2dec
->fbuf
[0];
341 mpeg2_set_fbuf (mpeg2dec
, (mpeg2dec
->decoder
.coding_type
==
342 PIC_FLAG_CODING_TYPE_B
));
343 fbuf
= mpeg2dec
->fbuf
[0];
345 fbuf
= &(mpeg2dec
->fbuf_alloc
[mpeg2dec
->alloc_index
].fbuf
);
346 mpeg2dec
->alloc_index_user
= ++mpeg2dec
->alloc_index
;
348 fbuf
->buf
[0] = buf
[0];
349 fbuf
->buf
[1] = buf
[1];
350 fbuf
->buf
[2] = buf
[2];
352 // HACK! FIXME! At first I frame, copy pointers to prediction frame too!
353 if (mpeg2dec
->custom_fbuf
&& !mpeg2dec
->fbuf
[1]->buf
[0]){
354 mpeg2dec
->fbuf
[1]->buf
[0]=buf
[0];
355 mpeg2dec
->fbuf
[1]->buf
[1]=buf
[1];
356 mpeg2dec
->fbuf
[1]->buf
[2]=buf
[2];
357 mpeg2dec
->fbuf
[1]->id
=NULL
;
359 // printf("libmpeg2: FBUF 0:%p 1:%p 2:%p\n",
360 // mpeg2dec->fbuf[0]->buf[0],mpeg2dec->fbuf[1]->buf[0],mpeg2dec->fbuf[2]->buf[0]);
363 void mpeg2_custom_fbuf (mpeg2dec_t
* mpeg2dec
, int custom_fbuf
)
365 mpeg2dec
->custom_fbuf
= custom_fbuf
;
368 void mpeg2_skip (mpeg2dec_t
* mpeg2dec
, int skip
)
370 mpeg2dec
->first_decode_slice
= 1;
371 mpeg2dec
->nb_decode_slices
= skip
? 0 : (0xb0 - 1);
374 void mpeg2_slice_region (mpeg2dec_t
* mpeg2dec
, int start
, int end
)
376 start
= (start
< 1) ? 1 : (start
> 0xb0) ? 0xb0 : start
;
377 end
= (end
< start
) ? start
: (end
> 0xb0) ? 0xb0 : end
;
378 mpeg2dec
->first_decode_slice
= start
;
379 mpeg2dec
->nb_decode_slices
= end
- start
;
382 void mpeg2_tag_picture (mpeg2dec_t
* mpeg2dec
, uint32_t tag
, uint32_t tag2
)
384 mpeg2dec
->tag_previous
= mpeg2dec
->tag_current
;
385 mpeg2dec
->tag2_previous
= mpeg2dec
->tag2_current
;
386 mpeg2dec
->tag_current
= tag
;
387 mpeg2dec
->tag2_current
= tag2
;
388 mpeg2dec
->num_tags
++;
389 mpeg2dec
->bytes_since_tag
= 0;
392 uint32_t mpeg2_accel (uint32_t accel
)
395 mpeg2_accels
= mpeg2_detect_accel (accel
) | MPEG2_ACCEL_DETECT
;
396 mpeg2_cpu_state_init (mpeg2_accels
);
397 mpeg2_idct_init (mpeg2_accels
);
398 mpeg2_mc_init (mpeg2_accels
);
400 return mpeg2_accels
& ~MPEG2_ACCEL_DETECT
;
403 void mpeg2_reset (mpeg2dec_t
* mpeg2dec
, int full_reset
)
405 mpeg2dec
->buf_start
= mpeg2dec
->buf_end
= NULL
;
406 mpeg2dec
->num_tags
= 0;
407 mpeg2dec
->shift
= 0xffffff00;
408 mpeg2dec
->code
= 0xb4;
409 mpeg2dec
->action
= mpeg2_seek_header
;
410 mpeg2dec
->state
= STATE_INVALID
;
413 mpeg2_reset_info(&(mpeg2dec
->info
));
414 mpeg2dec
->info
.gop
= NULL
;
415 mpeg2dec
->info
.user_data
= NULL
;
416 mpeg2dec
->info
.user_data_len
= 0;
418 mpeg2dec
->info
.sequence
= NULL
;
419 mpeg2_header_state_init (mpeg2dec
);
424 mpeg2dec_t
* mpeg2_init (void)
426 mpeg2dec_t
* mpeg2dec
;
428 mpeg2_accel (MPEG2_ACCEL_DETECT
);
430 mpeg2dec
= (mpeg2dec_t
*) mpeg2_malloc (sizeof (mpeg2dec_t
),
431 MPEG2_ALLOC_MPEG2DEC
);
432 if (mpeg2dec
== NULL
)
435 memset (mpeg2dec
->decoder
.DCTblock
, 0, 64 * sizeof (int16_t));
436 memset (mpeg2dec
->quantizer_matrix
, 0, 4 * 64 * sizeof (uint8_t));
438 mpeg2dec
->chunk_buffer
= (uint8_t *) mpeg2_malloc (BUFFER_SIZE
+ 4,
441 mpeg2dec
->sequence
.width
= (unsigned)-1;
442 mpeg2_reset (mpeg2dec
, 1);
447 void mpeg2_close (mpeg2dec_t
* mpeg2dec
)
449 mpeg2_header_state_init (mpeg2dec
);
450 mpeg2_free (mpeg2dec
->chunk_buffer
);
451 mpeg2_free (mpeg2dec
);