Commit 566d4f7a authored by Aaron Holtzman's avatar Aaron Holtzman
Browse files

Minor build fixes and a cleanup in decode.

ah
parent 00482b6b
......@@ -63,11 +63,11 @@ if test "x$DISPLAY_DRIVER" = x -a x$enable_mga = xyes; then
if test -c "/dev/mga_vid"; then
AC_MSG_RESULT(found)
DISPLAY_DRIVER=display_mga_vid.o
AM_CONDITIONAL(BUILD_MGA_DRIVER, test 1)
else
AC_MSG_RESULT(not found)
fi
fi
AM_CONDITIONAL(BUILD_MGA_DRIVER, test "$DISPLAY_DRIVER" = "display_mga_vid.o")
AC_ARG_ENABLE(gatos,
......@@ -105,6 +105,15 @@ fi
if test "x$DISPLAY_DRIVER" = x; then
AC_MSG_WARN(no accelerated display driver found -> using X11)
DISPLAY_DRIVER="display_x11.o yuv2rgb.o"
dnl Checks for libraries. (X11)
AC_PATH_XTRA
AC_CHECK_LIB(Xv, XvShmCreateImage,
X_LIBS="$X_LIBS -lXv"
ROOT_CFLAGS="$ROOT_CFLAGS -DHAVE_XV",,
$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS)
AM_CONDITIONAL(HAVE_X, test "x$no_x" != "xyes")
fi
dnl
......@@ -138,14 +147,6 @@ else
fi
dnl Checks for libraries. (X11)
AC_PATH_XTRA
AC_CHECK_LIB(Xv, XvShmCreateImage,
X_LIBS="$X_LIBS -lXv"
ROOT_CFLAGS="$ROOT_CFLAGS -DHAVE_XV",,
$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS)
AM_CONDITIONAL(HAVE_X, test "x$no_x" != "xyes")
dnl Figure out which OS we're on and what to do about it
case "$host" in
*-linux*) ;;
......
......@@ -31,6 +31,9 @@
/* private prototypes */
static void Display_Image (XImage * myximage, unsigned char *ImageData);
/* since it doesn't seem to be defined on some platforms */
int XShmGetEventBase(Display*);
/* local data */
static unsigned char *ImageData;
......@@ -125,7 +128,7 @@ uint_32 display_init(uint_32 width, uint_32 height, uint_32 fullscreen, char *ti
image_width = width;
if (X_already_started)
return;
return 0;
if(getenv("DISPLAY"))
name = getenv("DISPLAY");
......@@ -276,7 +279,6 @@ uint_32 display_init(uint_32 width, uint_32 height, uint_32 fullscreen, char *ti
if (!Quiet_Flag)
fprintf(stderr, "Shared memory not supported\nReverting to normal Xlib\n");
}
if (Shmem_Flag)
CompletionType = XShmGetEventBase(mydisplay) + ShmCompletion;
......
......@@ -62,9 +62,6 @@ uint_32 has_sync = 0;
static uint_32 is_display_initialized = 0;
static uint_32 is_sequence_needed = 1;
//FIXME obsolete need to clean up
//frame structure to pass back to caller
static mpeg2_frame_t mpeg2_frame;
void
mpeg2_init(mpeg2_display_t *foo)
......@@ -232,36 +229,26 @@ mpeg2_decode_data(uint_8 *data_start,uint_8 *data_end)
if(is_frame_done)
{
//decide which frame to send to the display
if(picture.picture_coding_type == B_TYPE)
//FIXME
//we can't initialize the display until we know how big the picture is
if(!is_display_initialized)
{
mpeg2_frame.frame[0] = picture.throwaway_frame[0];
mpeg2_frame.frame[1] = picture.throwaway_frame[1];
mpeg2_frame.frame[2] = picture.throwaway_frame[2];
mpeg2_display.init(picture.coded_picture_width,picture.coded_picture_height,0,0);
is_display_initialized = 1;
}
//decide which frame to send to the display
if(picture.picture_coding_type == B_TYPE)
mpeg2_display.draw_frame(picture.throwaway_frame);
else
{
mpeg2_frame.frame[0] = picture.forward_reference_frame[0];
mpeg2_frame.frame[1] = picture.forward_reference_frame[1];
mpeg2_frame.frame[2] = picture.forward_reference_frame[2];
}
mpeg2_display.draw_frame(picture.forward_reference_frame);
mpeg2_frame.width = picture.coded_picture_width;
mpeg2_frame.height = picture.coded_picture_height;
if(bitstream_show(32) == SEQUENCE_END_CODE)
is_sequence_needed = 1;
is_frame_done = 0;
//FIXME
//we can't initialize the display until we know how big the picture is
if(!is_display_initialized)
{
mpeg2_display.init(mpeg2_frame.width,mpeg2_frame.height,0,0);
is_display_initialized = 1;
}
mpeg2_display.draw_frame(mpeg2_frame.frame);
ret++;
}
}
......
/*
* parse.c
*
* Copyright (C) Aaron Holtzman <aholtzma@ess.engr.uvic.ca> - Nov 1999
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation,
*
*/
#include <stddef.h>
#include <stdio.h>
#include "config.h"
#include "mpeg2.h"
#include "mpeg2_internal.h"
#include "bitstream.h"
#include "stats.h"
#include "parse.h"
//FIXME remove when you put vlc_get_block_coeff into vlc.
typedef struct {
char run, level, len;
} DCTtab;
extern DCTtab DCTtabfirst[],DCTtabnext[],DCTtab0[],DCTtab1[];
extern DCTtab DCTtab2[],DCTtab3[],DCTtab4[],DCTtab5[],DCTtab6[];
extern DCTtab DCTtab0a[],DCTtab1a[];
//FIXME remove when you put vlc_get_block_coeff into vlc.
uint_32 non_linear_quantizer_scale[32] =
{
0, 1, 2, 3, 4, 5, 6, 7,
8,10,12,14,16,18,20,22,
24,28,32,36,40,44,48,52,
56,64,72,80,88,96,104,112
};
#ifdef __i386__
static const uint_8 scan_norm_mmx[64] =
{
// MMX Zig-Zag scan pattern (transposed)
0, 8, 1, 2, 9,16,24,17,
10, 3, 4, 11,18,25,32,40,
33,26,19,12, 5, 6,13,20,
27,34,41,48,56,49,42,35,
28,21,14, 7,15,22,29,36,
43,50,57,58,51,44,37,30,
23,31,38,45,52,59,60,53,
46,39,47,54,61,62,55,63
};
static const uint_8 scan_alt_mmx[64] =
{
// Alternate scan pattern (transposed)
0, 1, 2, 3, 8, 9,16,17,
10,11, 4, 5, 6, 7,15,14,
13,12,19,18,24,25,32,33,
26,27,20,21,22,23,28,29,
30,31,34,35,40,41,48,49,
42,43,36,37,38,39,44,45,
46,47,50,51,56,57,58,59,
52,53,54,55,60,61,62,63,
};
#endif
static const uint_8 scan_norm[64] =
{
// 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
};
static const uint_8 scan_alt[64] =
{
// 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
};
static uint_8 default_intra_quantization_matrix[64] =
{
8, 16, 19, 22, 26, 27, 29, 34,
16, 16, 22, 24, 27, 29, 34, 37,
19, 22, 26, 27, 29, 34, 34, 38,
22, 22, 26, 27, 29, 34, 37, 40,
22, 26, 27, 29, 32, 35, 40, 48,
26, 27, 29, 32, 35, 40, 48, 58,
26, 27, 29, 34, 38, 46, 56, 69,
27, 29, 35, 38, 46, 56, 69, 83
};
static uint_8 default_non_intra_quantization_matrix[64] =
{
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16
};
static void parse_sequence_display_extension(picture_t *picture);
static void parse_sequence_extension(picture_t *picture);
static void parse_picture_coding_extension(picture_t *picture);
void
parse_state_init(picture_t *picture)
{
picture->intra_quantizer_matrix = default_intra_quantization_matrix;
picture->non_intra_quantizer_matrix = default_non_intra_quantization_matrix;
//FIXME we should set pointers to the real scan matrices
//here (mmx vs normal) instead of the ifdefs in parse_picture_coding_extension
#ifdef __i386__
if(config.flags & MPEG2_MMX_ENABLE)
picture->scan = scan_norm_mmx;
else
#endif
picture->scan = scan_norm;
}
//FIXME remove once we get everything working
void parse_marker_bit(char *string)
{
int marker;
marker = bitstream_get(1);
if(!marker)
fprintf(stderr,"(parse) %s marker_bit set to 0\n",string);
}
void
parse_sequence_header(picture_t *picture)
{
uint_32 i;
picture->horizontal_size = bitstream_get(12);
picture->vertical_size = bitstream_get(12);
//XXX this needs field fixups
picture->coded_picture_height = ((picture->vertical_size + 15)/16) * 16;
picture->coded_picture_width = ((picture->horizontal_size + 15)/16) * 16;
picture->last_mba = ((picture->coded_picture_height * picture->coded_picture_width) >> 8) - 1;
picture->aspect_ratio_information = bitstream_get(4);
picture->frame_rate_code = bitstream_get(4);
picture->bit_rate_value = bitstream_get(18);
parse_marker_bit("sequence_header");
picture->vbv_buffer_size = bitstream_get(10);
picture->constrained_parameters_flag = bitstream_get(1);
if((picture->use_custom_intra_quantizer_matrix = bitstream_get(1)))
{
picture->intra_quantizer_matrix = picture->custom_intra_quantization_matrix;
for (i=0; i < 64; i++)
picture->custom_intra_quantization_matrix[scan_norm[i]] = bitstream_get(8);
}
else
picture->intra_quantizer_matrix = default_intra_quantization_matrix;
if((picture->use_custom_non_intra_quantizer_matrix = bitstream_get(1)))
{
picture->non_intra_quantizer_matrix = picture->custom_non_intra_quantization_matrix;
for (i=0; i < 64; i++)
picture->custom_non_intra_quantization_matrix[scan_norm[i]] = bitstream_get(8);
}
else
picture->non_intra_quantizer_matrix = default_non_intra_quantization_matrix;
stats_sequence_header(picture);
}
void
parse_extension(picture_t *picture)
{
uint_32 code;
code = bitstream_get(4);
switch(code)
{
case PICTURE_CODING_EXTENSION_ID:
parse_picture_coding_extension(picture);
break;
case SEQUENCE_EXTENSION_ID:
parse_sequence_extension(picture);
break;
case SEQUENCE_DISPLAY_EXTENSION_ID:
parse_sequence_display_extension(picture);
break;
default:
fprintf(stderr,"(parse) unsupported extension %x\n",code);
exit(1);
}
}
void
parse_user_data(void)
{
while (bitstream_show(24)!=0x01L)
bitstream_flush(8);
}
static void
parse_sequence_extension(picture_t *picture)
{
/*picture->profile_and_level_indication = */ bitstream_get(8);
picture->progressive_sequence = bitstream_get(1);
picture->chroma_format = bitstream_get(2);
/*picture->horizontal_size_extension = */ bitstream_get(2);
/*picture->vertical_size_extension = */ bitstream_get(2);
/*picture->bit_rate_extension = */ bitstream_get(12);
parse_marker_bit("sequence_extension");
/*picture->vbv_buffer_size_extension = */ bitstream_get(8);
/*picture->low_delay = */ bitstream_get(1);
/*picture->frame_rate_extension_n = */ bitstream_get(2);
/*picture->frame_rate_extension_d = */ bitstream_get(5);
stats_sequence_ext(picture);
//
//XXX since we don't support anything but 4:2:0, die gracefully
if(picture->chroma_format != CHROMA_420)
{
fprintf(stderr,"(parse) sorry, mpeg2dec doesn't support color formats other than 4:2:0\n");
exit(1);
}
}
static void
parse_sequence_display_extension(picture_t *picture)
{
picture->video_format = bitstream_get(3);
picture->color_description = bitstream_get(1);
if (picture->color_description)
{
picture->color_primaries = bitstream_get(8);
picture->transfer_characteristics = bitstream_get(8);
picture->matrix_coefficients = bitstream_get(8);
}
picture->display_horizontal_size = bitstream_get(14);
parse_marker_bit("sequence_display_extension");
picture->display_vertical_size = bitstream_get(14);
stats_sequence_display_ext(picture);
}
void
parse_gop_header(picture_t *picture)
{
picture->drop_flag = bitstream_get(1);
picture->hour = bitstream_get(5);
picture->minute = bitstream_get(6);
parse_marker_bit("gop_header");
picture->sec = bitstream_get(6);
picture->frame = bitstream_get(6);
picture->closed_gop = bitstream_get(1);
picture->broken_link = bitstream_get(1);
stats_gop_header(picture);
}
static void
parse_picture_coding_extension(picture_t *picture)
{
//pre subtract 1 for use later in compute_motion_vector
picture->f_code[0][0] = bitstream_get(4) - 1;
picture->f_code[0][1] = bitstream_get(4) - 1;
picture->f_code[1][0] = bitstream_get(4) - 1;
picture->f_code[1][1] = bitstream_get(4) - 1;
picture->intra_dc_precision = bitstream_get(2);
picture->picture_structure = bitstream_get(2);
picture->top_field_first = bitstream_get(1);
picture->frame_pred_frame_dct = bitstream_get(1);
picture->concealment_motion_vectors = bitstream_get(1);
picture->q_scale_type = bitstream_get(1);
picture->intra_vlc_format = bitstream_get(1);
picture->alternate_scan = bitstream_get(1);
#ifdef __i386__
if(config.flags & MPEG2_MMX_ENABLE)
{
if(picture->alternate_scan)
picture->scan = scan_alt_mmx;
else
picture->scan = scan_norm_mmx;
}
else
#endif
{
if(picture->alternate_scan)
picture->scan = scan_alt;
else
picture->scan = scan_norm;
}
picture->repeat_first_field = bitstream_get(1);
/*chroma_420_type isn't used */ bitstream_get(1);
picture->progressive_frame = bitstream_get(1);
picture->composite_display_flag = bitstream_get(1);
if (picture->composite_display_flag)
{
//This info is not used in the decoding process
/* picture->v_axis = */ bitstream_get(1);
/* picture->field_sequence = */ bitstream_get(3);
/* picture->sub_carrier = */ bitstream_get(1);
/* picture->burst_amplitude = */ bitstream_get(7);
/* picture->sub_carrier_phase = */ bitstream_get(8);
}
//XXX die gracefully if we encounter a field picture based stream
if(picture->picture_structure != FRAME_PICTURE)
{
fprintf(stderr,"(parse) sorry, mpeg2dec doesn't support field based pictures yet\n");
exit(1);
}
stats_picture_coding_ext_header(picture);
}
void
parse_picture_header(picture_t *picture)
{
picture->temporal_reference = bitstream_get(10);
picture->picture_coding_type = bitstream_get(3);
picture->vbv_delay = bitstream_get(16);
if (picture->picture_coding_type==P_TYPE || picture->picture_coding_type==B_TYPE)
{
picture->full_pel_forward_vector = bitstream_get(1);
picture->forward_f_code = bitstream_get(3);
}
if (picture->picture_coding_type==B_TYPE)
{
picture->full_pel_backward_vector = bitstream_get(1);
picture->backward_f_code = bitstream_get(3);
}
stats_picture_header(picture);
}
void
parse_slice_header(const picture_t *picture, slice_t *slice)
{
uint_32 intra_slice_flag;
slice->quantizer_scale_code = bitstream_get(5);
if (picture->q_scale_type)
slice->quantizer_scale = non_linear_quantizer_scale[slice->quantizer_scale_code];
else
slice->quantizer_scale = slice->quantizer_scale_code << 1 ;
if ((intra_slice_flag = bitstream_get(1)))
{
//Ignore the value of intra_slice
bitstream_get(1);
slice->slice_picture_id_enable = bitstream_get(1);
slice->slice_picture_id = bitstream_get(6);
//Ignore all the extra_data
while(bitstream_get(1))
bitstream_flush(8);
}
//reset intra dc predictor
slice->dc_dct_pred[0]=slice->dc_dct_pred[1]=slice->dc_dct_pred[2]=
1<<(picture->intra_dc_precision + 7) ;
stats_slice_header(slice);
}
//This goes into vlc.c when it gets written
inline sint_32
vlc_get_block_coeff(uint_16 non_intra_dc,uint_16 intra_vlc_format)
{
uint_32 code;
DCTtab *tab;
uint_16 run;
sint_16 val;
//this routines handles intra AC and non-intra AC/DC coefficients
code = bitstream_show(16);
if (code>=16384 && !intra_vlc_format)
{
if (non_intra_dc)
tab = &DCTtabfirst[(code>>12)-4];
else
tab = &DCTtabnext[(code>>12)-4];
}
else if (code>=1024)
{
if (intra_vlc_format)
tab = &DCTtab0a[(code>>8)-4];
else
tab = &DCTtab0[(code>>8)-4];
}
else if (code>=512)
{
if (intra_vlc_format)
tab = &DCTtab1a[(code>>6)-8];
else
tab = &DCTtab1[(code>>6)-8];
}
else if (code>=256)
tab = &DCTtab2[(code>>4)-16];
else if (code>=128)
tab = &DCTtab3[(code>>3)-16];
else if (code>=64)
tab = &DCTtab4[(code>>2)-16];
else if (code>=32)
tab = &DCTtab5[(code>>1)-16];
else if (code>=16)
tab = &DCTtab6[code-16];
else
{
fprintf(stderr,"(vlc) invalid huffman code 0x%x in vlc_get_block_coeff()\n",code);
exit(1);
return 0;
}
bitstream_flush(tab->len);
if (tab->run==64) // end_of_block
return 0;
if (tab->run==65) /* escape */
{
run = bitstream_get(6);
val = bitstream_get(12);
if ((val&2047)==0)
{
fprintf(stderr,"invalid escape in vlc_get_block_coeff()\n");
return 0;
}