summaryrefslogtreecommitdiffstats
path: root/libmpeg2
diff options
context:
space:
mode:
authorarpi_esp <arpi_esp@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-02-24 20:28:24 +0000
committerarpi_esp <arpi_esp@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-02-24 20:28:24 +0000
commitd34041569e71fc9bd772354e94dc9d16061072a5 (patch)
tree8f481cae1c70f32d1756fbe5f39000577b73042d /libmpeg2
parente95a95ece09bac96bdfd37322f96c6f57ef79ebc (diff)
downloadmpv-d34041569e71fc9bd772354e94dc9d16061072a5.tar.bz2
mpv-d34041569e71fc9bd772354e94dc9d16061072a5.tar.xz
Initial revision
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpeg2')
-rw-r--r--libmpeg2/Makefile35
-rw-r--r--libmpeg2/attributes.h31
-rw-r--r--libmpeg2/decode.c319
-rw-r--r--libmpeg2/header.c273
-rw-r--r--libmpeg2/idct.c289
-rw-r--r--libmpeg2/idct_mlib.c47
-rw-r--r--libmpeg2/idct_mmx.c706
-rw-r--r--libmpeg2/mm_accel.h30
-rw-r--r--libmpeg2/mmx.h255
-rw-r--r--libmpeg2/motion_comp.c125
-rw-r--r--libmpeg2/motion_comp_mlib.c180
-rw-r--r--libmpeg2/motion_comp_mmx.c1025
-rw-r--r--libmpeg2/mpeg2.h57
-rw-r--r--libmpeg2/mpeg2_internal.h220
-rw-r--r--libmpeg2/slice.c1797
-rw-r--r--libmpeg2/sse.h256
-rw-r--r--libmpeg2/stats.c316
-rw-r--r--libmpeg2/vlc.h425
18 files changed, 6386 insertions, 0 deletions
diff --git a/libmpeg2/Makefile b/libmpeg2/Makefile
new file mode 100644
index 0000000000..5e2f8e8cfc
--- /dev/null
+++ b/libmpeg2/Makefile
@@ -0,0 +1,35 @@
+
+LIBNAME = libmpeg2.a
+
+include ../config.mak
+
+SRCS = decode.c header.c idct.c idct_mmx.c motion_comp.c motion_comp_mmx.c slice.c stats.c
+OBJS = decode.o header.o idct.o idct_mmx.o motion_comp.o motion_comp_mmx.o slice.o stats.o
+CFLAGS = $(OPTFLAGS) -DMPG12PLAY
+INCLUDE = -I. -I../libvo -I..
+
+.SUFFIXES: .c .o
+
+# .PHONY: all clean
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCLUDE) -o $@ $<
+
+$(LIBNAME): $(OBJS)
+ $(AR) r $(LIBNAME) $(OBJS)
+
+all: $(LIBNAME)
+
+clean:
+ rm -f *.o *.a *~
+
+distclean:
+ makedepend
+ rm -f Makefile.bak *.o *.a *~
+
+dep: depend
+
+depend:
+ makedepend -- $(CFLAGS) -- $(SRCS) &> /dev/null
+
+# DO NOT DELETE
diff --git a/libmpeg2/attributes.h b/libmpeg2/attributes.h
new file mode 100644
index 0000000000..dfbf129411
--- /dev/null
+++ b/libmpeg2/attributes.h
@@ -0,0 +1,31 @@
+/*
+ * attributes.h
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+//use gcc attribs to align critical data structures
+
+/* maximum supported data alignment */
+#define ATTRIBUTE_ALIGNED_MAX 64
+
+#ifdef ATTRIBUTE_ALIGNED_MAX
+#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
+#else
+#define ATTR_ALIGN(align)
+#endif
diff --git a/libmpeg2/decode.c b/libmpeg2/decode.c
new file mode 100644
index 0000000000..e8bbb02112
--- /dev/null
+++ b/libmpeg2/decode.c
@@ -0,0 +1,319 @@
+/* Copyright (C) Aaron Holtzman <aholtzma@ess.engr.uvic.ca> - Nov 1999 */
+/* Some cleanup & hacking by A'rpi/ESP-team - Oct 2000 */
+
+/* mpeg2dec version: */
+#define PACKAGE "mpeg2dec"
+//#define VERSION "0.1.7-cvs"
+#define VERSION "0.1.8-cvs"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "config.h"
+
+//#include "video_out.h"
+
+#include "mpeg2.h"
+#include "mpeg2_internal.h"
+
+#include "../linux/shmem.h"
+
+//#include "motion_comp.h"
+//#include "idct.h"
+//#include "header.h"
+//#include "slice.h"
+//#include "stats.h"
+
+#include "attributes.h"
+#ifdef __i386__
+#include "mmx.h"
+#endif
+
+//this is where we keep the state of the decoder
+//picture_t picture_data;
+//picture_t *picture=&picture_data;
+picture_t *picture=NULL;
+
+//global config struct
+mpeg2_config_t config;
+
+// the maximum chunk size is determined by vbv_buffer_size which is 224K for
+// MP@ML streams. (we make no pretenses ofdecoding anything more than that)
+//static uint8_t chunk_buffer[224 * 1024 + 4];
+//static uint32_t shift = 0;
+
+static int drop_flag = 0;
+static int drop_frame = 0;
+
+int quant_store[MBR+1][MBC+1]; // [Review]
+
+void mpeg2_init (void)
+{
+
+ printf (PACKAGE"-"VERSION" (C) 2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>\n");
+ config.flags = 0;
+#ifdef HAVE_MMX
+ config.flags |= MM_ACCEL_X86_MMX;
+#endif
+#ifdef HAVE_SSE
+ config.flags |= MM_ACCEL_X86_MMXEXT;
+#endif
+#ifdef HAVE_3DNOW
+ config.flags |= MM_ACCEL_X86_3DNOW;
+#endif
+#ifdef HAVE_MLIB
+ config.flags |= MM_ACCEL_MLIB;
+#endif
+
+ printf("libmpeg2 config flags = 0x%X\n",config.flags);
+
+ picture=shmem_alloc(sizeof(picture_t)); // !!! NEW HACK :) !!!
+
+ header_state_init (picture);
+ picture->repeat_count=0;
+
+ picture->pp_options=0;
+
+ idct_init ();
+ motion_comp_init ();
+}
+
+void mpeg2_allocate_image_buffers (picture_t * picture)
+{
+ int frame_size,buff_size;
+ unsigned char *base=NULL;
+
+ // height+1 requires for yuv2rgb_mmx code (it reads next line after last)
+ frame_size = picture->coded_picture_width * (1+picture->coded_picture_height);
+ frame_size = (frame_size+31)&(~31); // align to 32 byte boundary
+ buff_size = frame_size + (frame_size/4)*2; // 4Y + 1U + 1V
+
+ // allocate images in YV12 format
+ base = shmem_alloc(buff_size);
+ picture->throwaway_frame[0] = base;
+ picture->throwaway_frame[1] = base + frame_size * 5 / 4;
+ picture->throwaway_frame[2] = base + frame_size;
+
+ base = shmem_alloc(buff_size);
+ picture->backward_reference_frame[0] = base;
+ picture->backward_reference_frame[1] = base + frame_size * 5 / 4;
+ picture->backward_reference_frame[2] = base + frame_size;
+
+ base = shmem_alloc(buff_size);
+ picture->forward_reference_frame[0] = base;
+ picture->forward_reference_frame[1] = base + frame_size * 5 / 4;
+ picture->forward_reference_frame[2] = base + frame_size;
+
+ base = shmem_alloc(buff_size);
+ picture->pp_frame[0] = base;
+ picture->pp_frame[1] = base + frame_size * 5 / 4;
+ picture->pp_frame[2] = base + frame_size;
+
+}
+
+static void decode_reorder_frames (void)
+{
+ if (picture->picture_coding_type != B_TYPE) {
+
+ //reuse the soon to be outdated forward reference frame
+ picture->current_frame[0] = picture->forward_reference_frame[0];
+ picture->current_frame[1] = picture->forward_reference_frame[1];
+ picture->current_frame[2] = picture->forward_reference_frame[2];
+
+ //make the backward reference frame the new forward reference frame
+ picture->forward_reference_frame[0] =
+ picture->backward_reference_frame[0];
+ picture->forward_reference_frame[1] =
+ picture->backward_reference_frame[1];
+ picture->forward_reference_frame[2] =
+ picture->backward_reference_frame[2];
+
+ picture->backward_reference_frame[0] = picture->current_frame[0];
+ picture->backward_reference_frame[1] = picture->current_frame[1];
+ picture->backward_reference_frame[2] = picture->current_frame[2];
+
+ } else {
+
+ picture->current_frame[0] = picture->throwaway_frame[0];
+ picture->current_frame[1] = picture->throwaway_frame[1];
+ picture->current_frame[2] = picture->throwaway_frame[2];
+
+ }
+}
+
+static int in_slice_flag=0;
+
+static int parse_chunk (vo_functions_t * output, int code, uint8_t * buffer)
+{
+ int is_frame_done = 0;
+
+ stats_header (code, buffer);
+
+ is_frame_done = in_slice_flag && ((!code) || (code >= 0xb0));
+ if (is_frame_done) {
+ in_slice_flag = 0;
+
+ if(picture->picture_structure != FRAME_PICTURE) printf("Field! %d \n",picture->second_field);
+
+ if ( ((HACK_MODE == 2) || (picture->mpeg1))
+ && ((picture->picture_structure == FRAME_PICTURE) ||
+ (picture->second_field))
+ ) {
+ uint8_t ** bar;
+ int stride[3];
+
+ if (picture->picture_coding_type == B_TYPE)
+ bar = picture->throwaway_frame;
+ else
+ bar = picture->forward_reference_frame;
+
+ stride[0]=picture->coded_picture_width;
+ stride[1]=stride[2]=stride[0]/2;
+
+ if(picture->pp_options){
+ // apply OpenDivX postprocess filter
+ postprocess(bar, stride[0],
+ picture->pp_frame, stride[0],
+ picture->coded_picture_width, picture->coded_picture_height,
+ &quant_store[1][1], (MBC+1), picture->pp_options);
+ output->draw_slice (picture->pp_frame, stride,
+ picture->display_picture_width,
+ picture->display_picture_height, 0, 0);
+ } else {
+ output->draw_slice (bar, stride,
+ picture->display_picture_width,
+ picture->display_picture_height, 0, 0);
+ }
+
+ }
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMX) emms ();
+#endif
+ output->flip_page ();
+ }
+
+ switch (code) {
+ case 0x00: /* picture_start_code */
+ if (header_process_picture_header (picture, buffer)) {
+ printf ("bad picture header\n");
+ exit (1);
+ }
+
+ drop_frame = drop_flag && (picture->picture_coding_type == B_TYPE);
+ //decode_reorder_frames ();
+ break;
+
+ case 0xb3: /* sequence_header_code */
+ if (header_process_sequence_header (picture, buffer)) {
+ printf ("bad sequence header\n");
+ exit (1);
+ }
+ break;
+
+ case 0xb5: /* extension_start_code */
+ if (header_process_extension (picture, buffer)) {
+ printf ("bad extension\n");
+ exit (1);
+ }
+ break;
+
+ default:
+// if (code >= 0xb9) printf ("stream not demultiplexed ?\n");
+ if (code >= 0xb0) break;
+
+ if (!(in_slice_flag)) {
+ in_slice_flag = 1;
+
+ if(!(picture->second_field)) decode_reorder_frames ();
+ }
+
+ if (!drop_frame) {
+ uint8_t ** bar;
+
+ slice_process (picture, code, buffer);
+
+ if ((HACK_MODE < 2) && (!(picture->mpeg1))) {
+ uint8_t * foo[3];
+ uint8_t ** bar;
+ //frame_t * bar;
+ int stride[3];
+ int offset;
+
+ if (picture->picture_coding_type == B_TYPE)
+ bar = picture->throwaway_frame;
+ else
+ bar = picture->forward_reference_frame;
+
+ offset = (code-1) * 4 * picture->coded_picture_width;
+ if ((! HACK_MODE) && (picture->picture_coding_type == B_TYPE))
+ offset = 0;
+
+ foo[0] = bar[0] + 4 * offset;
+ foo[1] = bar[1] + offset;
+ foo[2] = bar[2] + offset;
+
+ stride[0]=picture->coded_picture_width;
+ stride[1]=stride[2]=stride[0]/2;
+
+ output->draw_slice (foo, stride,
+ picture->display_picture_width, 16, 0, (code-1)*16);
+ }
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMX) emms ();
+#endif
+
+ }
+ }
+
+ return is_frame_done;
+}
+
+
+int mpeg2_decode_data (vo_functions_t *output, uint8_t *current, uint8_t *end)
+{
+ //static uint8_t code = 0xff;
+ //static uint8_t chunk_buffer[65536];
+ //static uint8_t *chunk_ptr = chunk_buffer;
+ //static uint32_t shift = 0;
+ uint8_t code;
+ uint8_t *pos=NULL;
+ uint8_t *start=current;
+ int ret = 0;
+
+// printf("RCVD %d bytes\n",end-current);
+
+while(current<end){
+ // FIND NEXT HEAD:
+ unsigned int head=-1;
+ uint8_t c;
+ //--------------------
+ while(current<end){
+ c=current[0];
+ ++current;
+ head<<=8;
+ if(head==0x100) break; // synced
+ head|=c;
+ }
+ //--------------------
+ if(pos){
+ //if((code&0x100)!=0x100) printf("libmpeg2: FATAL! code=%X\n",code);
+ //printf("pos=%d chunk %3X size=%d next-code=%X\n",pos-start,code,current-pos,head|c);
+ ret+=parse_chunk(output, code&0xFF, pos);
+ }
+ //--------------------
+ pos=current;code=head|c;
+}
+
+ if(code==0x1FF) ret+=parse_chunk(output, 0xFF, NULL); // send 'end of frame'
+
+ return ret;
+}
+
+void mpeg2_drop (int flag)
+{
+ drop_flag = flag;
+}
+
diff --git a/libmpeg2/header.c b/libmpeg2/header.c
new file mode 100644
index 0000000000..8f5b34359e
--- /dev/null
+++ b/libmpeg2/header.c
@@ -0,0 +1,273 @@
+/*
+ * slice.c
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "attributes.h"
+
+// default intra quant matrix, in zig-zag order
+static uint8_t default_intra_quantizer_matrix[64] ATTR_ALIGN(16) = {
+ 8,
+ 16, 16,
+ 19, 16, 19,
+ 22, 22, 22, 22,
+ 22, 22, 26, 24, 26,
+ 27, 27, 27, 26, 26, 26,
+ 26, 27, 27, 27, 29, 29, 29,
+ 34, 34, 34, 29, 29, 29, 27, 27,
+ 29, 29, 32, 32, 34, 34, 37,
+ 38, 37, 35, 35, 34, 35,
+ 38, 38, 40, 40, 40,
+ 48, 48, 46, 46,
+ 56, 56, 58,
+ 69, 69,
+ 83
+};
+
+uint8_t scan_norm[64] ATTR_ALIGN(16) =
+{
+ // Zig-Zag scan pattern
+ 0, 1, 8,16, 9, 2, 3,10,
+ 17,24,32,25,18,11, 4, 5,
+ 12,19,26,33,40,48,41,34,
+ 27,20,13, 6, 7,14,21,28,
+ 35,42,49,56,57,50,43,36,
+ 29,22,15,23,30,37,44,51,
+ 58,59,52,45,38,31,39,46,
+ 53,60,61,54,47,55,62,63
+};
+
+uint8_t scan_alt[64] ATTR_ALIGN(16) =
+{
+ // Alternate scan pattern
+ 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49,
+ 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43,
+ 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45,
+ 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63
+};
+
+void header_state_init (picture_t * picture)
+{
+ //FIXME we should set pointers to the real scan matrices here (mmx vs
+ //normal) instead of the ifdefs in header_process_picture_coding_extension
+
+ picture->scan = scan_norm;
+}
+
+static const int frameratecode2framerate[16] = {
+ 0, 24000*10000/1001, 24*10000,25*10000, 30000*10000/1001, 30*10000,50*10000,60000*10000/1001,
+ 60*10000, 0,0,0,0,0,0,0
+};
+
+int header_process_sequence_header (picture_t * picture, uint8_t * buffer)
+{
+ unsigned int h_size;
+ unsigned int v_size;
+ int i;
+
+ if ((buffer[6] & 0x20) != 0x20)
+ return 1; // missing marker_bit
+
+ v_size = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
+
+ picture->display_picture_width = (v_size >> 12);
+ picture->display_picture_height = (v_size & 0xfff);
+
+ h_size = ((v_size >> 12) + 15) & ~15;
+ v_size = ((v_size & 0xfff) + 15) & ~15;
+
+ if ((h_size > 768) || (v_size > 576))
+ return 1; // size restrictions for MP@ML or MPEG1
+
+ //XXX this needs field fixups
+ picture->coded_picture_width = h_size;
+ picture->coded_picture_height = v_size;
+ picture->last_mba = ((h_size * v_size) >> 8) - 1;
+
+ // this is not used by the decoder
+ picture->aspect_ratio_information = buffer[3] >> 4;
+ picture->frame_rate_code = buffer[3] & 15;
+ picture->frame_rate = frameratecode2framerate[picture->frame_rate_code];
+
+ picture->bitrate = (buffer[4]<<10)|(buffer[5]<<2)|(buffer[6]>>6);
+
+ if (buffer[7] & 2) {
+ for (i = 0; i < 64; i++)
+ picture->intra_quantizer_matrix[scan_norm[i]] =
+ (buffer[i+7] << 7) | (buffer[i+8] >> 1);
+ buffer += 64;
+ } else {
+ for (i = 0; i < 64; i++)
+ picture->intra_quantizer_matrix[scan_norm[i]] =
+ default_intra_quantizer_matrix [i];
+ }
+
+ if (buffer[7] & 1) {
+ for (i = 0; i < 64; i++)
+ picture->non_intra_quantizer_matrix[scan_norm[i]] =
+ buffer[i+8];
+ } else {
+ for (i = 0; i < 64; i++)
+ picture->non_intra_quantizer_matrix[i] = 16;
+ }
+
+ // MPEG1 - for testing only
+ picture->mpeg1 = 1;
+ picture->intra_dc_precision = 0;
+ picture->frame_pred_frame_dct = 1;
+ picture->q_scale_type = 0;
+ picture->concealment_motion_vectors = 0;
+ //picture->alternate_scan = 0;
+ picture->picture_structure = FRAME_PICTURE;
+ //picture->second_field = 0;
+
+ return 0;
+}
+
+static int header_process_sequence_extension (picture_t * picture,
+ uint8_t * buffer)
+{
+ // MPEG1 - for testing only
+ picture->mpeg1 = 0;
+
+ // check chroma format, size extensions, marker bit
+ if(((buffer[1]>>1)&3)!=1){
+ printf("This CHROMA format not yet supported :(\n");
+ return 1;
+ }
+ if ((buffer[1] & 1) || (buffer[2] & 0xe0)){
+ printf("Big resolution video not yet supported :(\n");
+ return 1;
+ }
+ if((buffer[3] & 0x01) != 0x01) return 1; // marker bit
+
+
+ // this is not used by the decoder
+ picture->progressive_sequence = (buffer[1] >> 3) & 1;
+
+ if (picture->progressive_sequence)
+ picture->coded_picture_height =
+ (picture->coded_picture_height + 31) & ~31;
+ picture->bitrate>>=1; // hack
+
+ return 0;
+}
+
+static int header_process_quant_matrix_extension (picture_t * picture,
+ uint8_t * buffer)
+{
+ int i;
+
+ if (buffer[0] & 8) {
+ for (i = 0; i < 64; i++)
+ picture->intra_quantizer_matrix[scan_norm[i]] =
+ (buffer[i] << 5) | (buffer[i+1] >> 3);
+ buffer += 64;
+ }
+
+ if (buffer[0] & 4) {
+ for (i = 0; i < 64; i++)
+ picture->non_intra_quantizer_matrix[scan_norm[i]] =
+ (buffer[i] << 6) | (buffer[i+1] >> 2);
+ }
+
+ return 0;
+}
+
+static int header_process_picture_coding_extension (picture_t * picture, uint8_t * buffer)
+{
+ //pre subtract 1 for use later in compute_motion_vector
+ picture->f_code[0][0] = (buffer[0] & 15) - 1;
+ picture->f_code[0][1] = (buffer[1] >> 4) - 1;
+ picture->f_code[1][0] = (buffer[1] & 15) - 1;
+ picture->f_code[1][1] = (buffer[2] >> 4) - 1;
+
+ picture->intra_dc_precision = (buffer[2] >> 2) & 3;
+ picture->picture_structure = buffer[2] & 3;
+ picture->frame_pred_frame_dct = (buffer[3] >> 6) & 1;
+ picture->concealment_motion_vectors = (buffer[3] >> 5) & 1;
+ picture->q_scale_type = (buffer[3] >> 4) & 1;
+ picture->intra_vlc_format = (buffer[3] >> 3) & 1;
+
+ if (buffer[3] & 4) // alternate_scan
+ picture->scan = scan_alt;
+ else
+ picture->scan = scan_norm;
+
+ // these are not used by the decoder
+ picture->top_field_first = buffer[3] >> 7;
+ picture->repeat_first_field = (buffer[3] >> 1) & 1;
+ picture->progressive_frame = buffer[4] >> 7;
+
+ // repeat_first implementation by A'rpi/ESP-team, based on libmpeg3:
+ if(picture->repeat_count>=100) picture->repeat_count=0;
+ if(picture->repeat_first_field){
+ if(picture->progressive_sequence){
+ if(picture->top_field_first)
+ picture->repeat_count+=200;
+ else
+ picture->repeat_count+=100;
+ } else
+ if(picture->progressive_frame){
+ picture->repeat_count+=50;
+ }
+ }
+
+ return 0;
+}
+
+int header_process_extension (picture_t * picture, uint8_t * buffer)
+{
+ switch (buffer[0] & 0xf0) {
+ case 0x10: // sequence extension
+ return header_process_sequence_extension (picture, buffer);
+
+ case 0x30: // quant matrix extension
+ return header_process_quant_matrix_extension (picture, buffer);
+
+ case 0x80: // picture coding extension
+ return header_process_picture_coding_extension (picture, buffer);
+ }
+
+ return 0;
+}
+
+int header_process_picture_header (picture_t *picture, uint8_t * buffer)
+{
+ picture->picture_coding_type = (buffer [1] >> 3) & 7;
+
+ // forward_f_code and backward_f_code - used in mpeg1 only
+ picture->f_code[0][1] = (buffer[3] >> 2) & 1;
+ picture->f_code[0][0] =
+ (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1;
+ picture->f_code[1][1] = (buffer[4] >> 6) & 1;
+ picture->f_code[1][0] = ((buffer[4] >> 3) & 7) - 1;
+
+ // move in header_process_picture_header
+ picture->second_field =
+ (picture->picture_structure != FRAME_PICTURE) &&
+ !(picture->second_field);
+
+ return 0;
+}
diff --git a/libmpeg2/idct.c b/libmpeg2/idct.c
new file mode 100644
index 0000000000..7411e176dd
--- /dev/null
+++ b/libmpeg2/idct.c
@@ -0,0 +1,289 @@
+/*
+ * idct.c
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * Portions of this code are from the MPEG software simulation group
+ * idct implementation. This code will be replaced with a new
+ * implementation soon.
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**********************************************************/
+/* inverse two dimensional DCT, Chen-Wang algorithm */
+/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */
+/* 32-bit integer arithmetic (8 bit coefficients) */
+/* 11 mults, 29 adds per DCT */
+/* sE, 18.8.91 */
+/**********************************************************/
+/* coefficients extended to 12 bit for IEEE1180-1990 */
+/* compliance sE, 2.1.94 */
+/**********************************************************/
+
+/* this code assumes >> to be a two's-complement arithmetic */
+/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "mm_accel.h"
+
+#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
+#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
+#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
+#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
+#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
+#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
+
+
+// idct main entry point
+void (*idct_block_copy) (int16_t * block, uint8_t * dest, int stride);
+void (*idct_block_add) (int16_t * block, uint8_t * dest, int stride);
+
+static void idct_block_copy_c (int16_t *block, uint8_t * dest, int stride);
+static void idct_block_add_c (int16_t *block, uint8_t * dest, int stride);
+
+static uint8_t clip_lut[1024];
+#define CLIP(i) ((clip_lut+384)[ (i)])
+
+void idct_init (void)
+{
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMXEXT) {
+ fprintf (stderr, "Using MMXEXT for IDCT transform\n");
+ idct_block_copy = idct_block_copy_mmxext;
+ idct_block_add = idct_block_add_mmxext;
+ idct_mmx_init ();
+ } else if (config.flags & MM_ACCEL_X86_MMX) {
+ fprintf (stderr, "Using MMX for IDCT transform\n");
+ idct_block_copy = idct_block_copy_mmx;
+ idct_block_add = idct_block_add_mmx;
+ idct_mmx_init ();
+ } else
+#endif
+#ifdef LIBMPEG2_MLIB
+ if (config.flags & MM_ACCEL_MLIB) {
+ fprintf (stderr, "Using mlib for IDCT transform\n");
+ idct_block_copy = idct_block_copy_mlib;
+ idct_block_add = idct_block_add_mlib;
+ } else
+#endif
+ {
+ int i;
+
+ fprintf (stderr, "No accelerated IDCT transform found\n");
+ idct_block_copy = idct_block_copy_c;
+ idct_block_add = idct_block_add_c;
+ for (i = -384; i < 640; i++)
+ clip_lut[i+384] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
+ }
+}
+
+/* row (horizontal) IDCT
+ *
+ * 7 pi 1
+ * dst[k] = sum c[l] * src[l] * cos ( -- * ( k + - ) * l )
+ * l=0 8 2
+ *
+ * where: c[0] = 128
+ * c[1..7] = 128*sqrt (2)
+ */
+
+static void inline idct_row (int16_t * block)
+{
+ int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ x1 = block[4] << 11;
+ x2 = block[6];
+ x3 = block[2];
+ x4 = block[1];
+ x5 = block[7];
+ x6 = block[5];
+ x7 = block[3];
+
+ /* shortcut */
+ if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) {
+ block[0] = block[1] = block[2] = block[3] = block[4] =
+ block[5] = block[6] = block[7] = block[0]<<3;
+ return;
+ }
+
+ x0 = (block[0] << 11) + 128; /* for proper rounding in the fourth stage */
+
+ /* first stage */
+ x8 = W7 * (x4 + x5);
+ x4 = x8 + (W1 - W7) * x4;
+ x5 = x8 - (W1 + W7) * x5;
+ x8 = W3 * (x6 + x7);
+ x6 = x8 - (W3 - W5) * x6;
+ x7 = x8 - (W3 + W5) * x7;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6 * (x3 + x2);
+ x2 = x1 - (W2 + W6) * x2;
+ x3 = x1 + (W2 - W6) * x3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x4 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ block[0] = (x7 + x1) >> 8;
+ block[1] = (x3 + x2) >> 8;
+ block[2] = (x0 + x4) >> 8;
+ block[3] = (x8 + x6) >> 8;
+ block[4] = (x8 - x6) >> 8;
+ block[5] = (x0 - x4) >> 8;
+ block[6] = (x3 - x2) >> 8;
+ block[7] = (x7 - x1) >> 8;
+}
+
+/* column (vertical) IDCT
+ *
+ * 7 pi 1
+ * dst[8*k] = sum c[l] * src[8*l] * cos ( -- * ( k + - ) * l )
+ * l=0 8 2
+ *
+ * where: c[0] = 1/1024
+ * c[1..7] = (1/1024)*sqrt (2)
+ */
+
+static void inline idct_col (int16_t *block)
+{
+ int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ /* shortcut */
+ x1 = block [8*4] << 8;
+ x2 = block [8*6];
+ x3 = block [8*2];
+ x4 = block [8*1];
+ x5 = block [8*7];
+ x6 = block [8*5];
+ x7 = block [8*3];
+
+#if 0
+ if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) {
+ block[8*0] = block[8*1] = block[8*2] = block[8*3] = block[8*4] =
+ block[8*5] = block[8*6] = block[8*7] = (block[8*0] + 32) >> 6;
+ return;
+ }
+#endif
+
+ x0 = (block[8*0] << 8) + 8192;
+
+ /* first stage */
+ x8 = W7 * (x4 + x5) + 4;
+ x4 = (x8 + (W1 - W7) * x4) >> 3;
+ x5 = (x8 - (W1 + W7) * x5) >> 3;
+ x8 = W3 * (x6 + x7) + 4;
+ x6 = (x8 - (W3 - W5) * x6) >> 3;
+ x7 = (x8 - (W3 + W5) * x7) >> 3;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6 * (x3 + x2) + 4;
+ x2 = (x1 - (W2 + W6) * x2) >> 3;
+ x3 = (x1 + (W2 - W6) * x3) >> 3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x4 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ block[8*0] = (x7 + x1) >> 14;
+ block[8*1] = (x3 + x2) >> 14;
+ block[8*2] = (x0 + x4) >> 14;
+ block[8*3] = (x8 + x6) >> 14;
+ block[8*4] = (x8 - x6) >> 14;
+ block[8*5] = (x0 - x4) >> 14;
+ block[8*6] = (x3 - x2) >> 14;
+ block[8*7] = (x7 - x1) >> 14;
+}
+
+void idct_block_copy_c (int16_t * block, uint8_t * dest, int stride)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ idct_row (block + 8 * i);
+
+ for (i = 0; i < 8; i++)
+ idct_col (block + i);
+
+ i = 8;
+ do {
+ dest[0] = CLIP (block[0]);
+ dest[1] = CLIP (block[1]);
+ dest[2] = CLIP (block[2]);
+ dest[3] = CLIP (block[3]);
+ dest[4] = CLIP (block[4]);
+ dest[5] = CLIP (block[5]);
+ dest[6] = CLIP (block[6]);
+ dest[7] = CLIP (block[7]);
+
+ dest += stride;
+ block += 8;
+ } while (--i);
+}
+
+void idct_block_add_c (int16_t * block, uint8_t * dest, int stride)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ idct_row (block + 8 * i);
+
+ for (i = 0; i < 8; i++)
+ idct_col (block + i);
+
+ i = 8;
+ do {
+ dest[0] = CLIP (block[0] + dest[0]);
+ dest[1] = CLIP (block[1] + dest[1]);
+ dest[2] = CLIP (block[2] + dest[2]);
+ dest[3] = CLIP (block[3] + dest[3]);
+ dest[4] = CLIP (block[4] + dest[4]);
+ dest[5] = CLIP (block[5] + dest[5]);
+ dest[6] = CLIP (block[6] + dest[6]);
+ dest[7] = CLIP (block[7] + dest[7]);
+
+ dest += stride;