From: malaterre Date: Sat, 21 May 2005 01:20:12 +0000 (+0000) Subject: ENH: GDCM has now a BSD compatible MPEG2 library. Source taken from ftp://ftp.mpeg... X-Git-Tag: Version1.2.bp~708 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=ccc606678fca0bc69bcc76384459682ccef01f17;p=gdcm.git ENH: GDCM has now a BSD compatible MPEG2 library. Source taken from ftp://ftp.mpeg.org/pub/mpeg/mssg/ --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 30494062..c3fd98ce 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,7 +10,10 @@ IF (WIN32) ADD_DEFINITIONS(-DJPEGSTATIC) ENDIF (BUILD_SHARED_LIBS) ENDIF (WIN32) -SUBDIRS(gdcmjpeg) +SUBDIRS( + gdcmjpeg + # gdcmmpeg2 + ) # "jpeglib.h" is defined here: INCLUDE_DIRECTORIES( diff --git a/src/gdcmmpeg2/CMakeLists.txt b/src/gdcmmpeg2/CMakeLists.txt new file mode 100644 index 00000000..82feb098 --- /dev/null +++ b/src/gdcmmpeg2/CMakeLists.txt @@ -0,0 +1 @@ +SUBDIRS(src) diff --git a/src/gdcmmpeg2/Makefile b/src/gdcmmpeg2/Makefile new file mode 100644 index 00000000..6827b7ce --- /dev/null +++ b/src/gdcmmpeg2/Makefile @@ -0,0 +1,78 @@ +# Makefile for mpeg2decode / mpeg2encode + +# Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. + +# +# Disclaimer of Warranty +# +# These software programs are available to the user without any license fee or +# royalty on an "as is" basis. The MPEG Software Simulation Group disclaims +# any and all warranties, whether express, implied, or statuary, including any +# implied warranties or merchantability or of fitness for a particular +# purpose. In no event shall the copyright-holder be liable for any +# incidental, punitive, or consequential damages of any kind whatsoever +# arising from the use of these programs. +# +# This disclaimer of warranty extends to the user of these programs and user's +# customers, employees, agents, transferees, successors, and assigns. +# +# The MPEG Software Simulation Group does not represent or warrant that the +# programs furnished hereunder are free of infringement of any third-party +# patents. +# +# Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, +# are subject to royalty fees to patent holders. Many of these patents are +# general enough such that they are unavoidable regardless of implementation +# design. +# +# + +# uncomment the following two lines if you want to include X11 support +# (mpeg2decode) + +#USE_DISP = -DDISPLAY +#LIBS = -lX11 + +# uncomment the following two lines if you want to use shared memory +# (faster display if server and client run on the same machine) +# (mpeg2decode) + +#USE_SHMEM = -DSH_MEM +#LIBS = -lXext -lX11 + +# if your X11 include files / libraries are in a non standard location: +# set INCLUDEDIR to -I followed by the appropriate include file path and +# set LIBRARYDIR to -L followed by the appropriate library path +# (mpeg2decode) + +#INCLUDEDIR = -I/usr/openwin/include +#LIBRARYDIR = -L/usr/openwin/lib + +# select one of the following CC CFLAGS settings + +# +# GNU gcc +# +CC = gcc +CFLAGS = -O2 + +all: mpeg2decode mpeg2encode + +mpeg2decode: + cd src/mpeg2dec; make 'CC=$(CC)' \ + 'CFLAGS=$(CFLAGS) $(USE_DISP) $(USE_SHMEM) $(INCLUDEDIR)' \ + 'LIBS=$(LIBS)' 'LIBRARYDIR=$(LIBRARYDIR)' + +mpeg2encode: + cd src/mpeg2enc; make 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' + +pc: + cd src/mpeg2dec; make pc 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' + cd src/mpeg2enc; make pc 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' + +clean: + cd src/mpeg2dec; make clean + cd src/mpeg2enc; make clean + +test: + cd verify; ./verify diff --git a/src/gdcmmpeg2/README b/src/gdcmmpeg2/README new file mode 100644 index 00000000..55524ff8 --- /dev/null +++ b/src/gdcmmpeg2/README @@ -0,0 +1,229 @@ + mpeg2encode / mpeg2decode + ========================= + MPEG-2 Encoder / Decoder, Version 1.2, July 19, 1996 + + Copyright (c) 1996 + MPEG Software Simulation Group + + E-mail: mssg@mpeg.org (author contact) + Web: http://www.mpeg.org/MSSG/ + FTP: ftp://ftp.mpeg.org/pub/mpeg/mssg/ + + +Contents: +1. Overview +2. Introduction +3. Contacting the MPEG Software Simulation Group +4. Availability +5. Installation +6. Acknowledgements +7. History of the technical report + + +1. Overview +=========== + +This directory contains our implementation of an ISO/IEC DIS 13818-2 +codec. It converts uncompressed video frames into MPEG-1 and MPEG-2 +video coded bitstream sequences, and vice versa. + +The files mpeg2enc.doc and mpeg2dec.doc in the doc/ directory contain +further information about the codec. The directory verify/ contains +a small set of verification pictures, a small bitstream, and Unix +shell script to automatically test the output of the encoder and decoder. + +A precompiled version of the programs for Win32s (Windows NT/95) will +be made available later date, although it is trivial to make a console +application from the encoder and decoder with most Win32s compilers +(such as Microsoft Visual C++). + +Subdirectories src/mpeg2enc and src/mpeg2dec contain the source code +for the encoder and decoder, subdirectory par/ contains a couple of +example encoder parameter files for 25 and 30 frames/sec MPEG-2 and +MPEG-1 video. + +Summary of changes since July 4, 1994 release: + +This is only the second official release of our MPEG-2 video software. +Only minor bug corrections have been added to the encoder. We still do +not implement scalable encoding, as this is mostly useful only for +academic research. + +The decoder has been updated to meet the final MPEG specification, +although the old decoder will still reconstruct Main Profile and MPEG-1 +bitstreams just fine. The current decoder implements the most +important case of Spatial scalability, as well as SNR and Data +Partitioning. Temporal scalability is not implemented. + +2. Introduction +=============== + +MPEG-2 Video is a generic method for compressed representation of video +sequences using a common coding syntax defined in the document ISO/IEC +13818 Part 2 by the International Organization for Standardization +(ISO) and the International Electrotechnical Commission (IEC), in +collaboration with the International Telecommunications Union (ITU) as +Recommendation H.262. The MPEG-2 concept is similar to MPEG-1, but +includes extensions to cover a wider range of applications. + +The primary application targeted during the MPEG-2 definition process +was the all-digital transmission of interlaced broadcast TV quality +video at coded bitrates between 4 and 9 Mbit/sec. However, the MPEG-2 +syntax has been found to be efficient for other applications such as +those at higher bit rates and sample rates (e.g. HDTV). + +The most significant enhancement over MPEG-1 is the addition of syntax +for efficient coding of interlaced video (e.g. 16x8 block sizes for +motion compensation, field dct organization, Dual Prime prediction, et +al). Several other more subtle enhancements (e.g. 10-bit DCT DC +precision, non-linear macroblock scale quantizer, intra VLC tables, +improved IDCT mismatch control) were adopted which have a moderate +improvement in coding efficiency.... even for progressive video sequences. + +Other key features of MPEG-2 are the scalable extensions which permit +the division of a continuous video signal into two or more coded bitstreams +representing the video at different resolutions (spatial scalability), +picture quality (SNR scalability and data partioning), or frame +rates (temporal scalability). + +The MPEG Software Simulation Group is currently developing MPEG +software with the purpose of providing aid in understanding the various +algorithms which comprise an encoder and decoder, and giving a sample +implementation based on advanced encoding models. The MPEG-2 software +project is an on-going development. Since the current version of the +encoder already employs a reasonable (and the most popular) subset of +the MPEG-2 signal coding toolkit (MPEG-1 and MPEG-2 Main Profile), and +there appears to be sufficient public interest, we have decided to make +a public release of the code. + +The encoder can also be used for generating good quality constant +bitrate MPEG-1 sequences and is (to our knowledge) the first publicly +available encoder based on the relatively sophisticated TM5 coding model. + + +3. Contacting the MPEG Software Simulation Group +================================================ + +We welcome any project-specific questions, comments, suggestions, bug +reports etc. They should be sent to the Internet E-mail address: + + mssg@mpeg.org + +which automatically forwards to the software authors. + +4. Availability +=============== + +The most recent version of the codec source code is available by anonymous +ftp from: + + ftp://ftp.mpeg.org/pub/mpeg/mssg/ + +The directory contains the following files: + + mpeg2vidcodec_v12.tar.gz codec source code and documentation + mpeg2v12.zip source code and Win32s executables + +You need gunzip (GNU zip/unzip) to uncompress the .gz and .zip archives. + +5. Installation +=============== + +mpeg2decode and mpeg2encode have been compiled and tested on the following +platforms: + + - SUN SPARCstation 10, SunOS 4.1.3, (gcc compiler) + - '386-PC, MSDOS 5.0, djgpp v1.11, gcc v2.5.7 and MS Visual C++ 4.0 + +The source code should compile without major modifications on other 32 +bit systems with ANSI C compliant compilers. Systems with 16 bit 'int' +variables or segmented memory models are not supported. + +Please report any modifications you had to apply in order to install the +programs on your system to the address mssg@mpeg.org + +The encoder and decoder are kept in separate sub-directories, +src/mpeg2dec contains the decoder, while src/mpeg2enc contains the +encoder sources. The following installation procedure applies to both +the encoder and the decoder: + + +Step 1: edit Makefile +--------------------- + +You may have to set CC to your C compiler and CFLAGS to the flags required +by the compiler. It is sufficient to set these variables in the top directory +Makefile. They are propagated to the individual Makefiles of the encoder +and decoder. Any other changes have to be applied to the individual Makefiles, +however. + +You can compile the decoder with or without X11 output. Please follow the +instructions in the top-level Makefile to activate X Window System support. + +Step 2: edit src/mpeg2dec/config.h +---------------------------------- + +In most cases, no modification should be required. If your C library +doesn't accept "rb" / "wb" parameters in fopen() (required to disable +LF <-> CR/LF conversion on MSDOS systems), change the #defines RB and WB +to "r" and "w". + + +Step 3: make +------------ + +Type 'make' from the top directory (mpeg2). On a PC with DJGPP installed you +have to enter 'make pc' in the individual source directories to produce +.exe files. + + +Step 4: verification +-------------------- + +In the mpeg/verify directory, you can verify correct compilation of the +codec by typing 'make test'. No differences should be reported. The +only comparison which is allowed to fail is between test.m2v and +new.m2v, caused by floating point accuracy dependencies in the forward +DCT. + + +6. Acknowledgements +=================== +Authors of the current release are: + + Stefan Eckart + Chad Fogg + +420to422, 422to444 scaling filters: + Cheung Auyeung + +Windows 32s port: + Sorin Papuc + +Special thanks are due to + + - J. Steurer, M. Oepen, IRT (Institut fuer Rundfunktechnik, Muenchen): + for contributing motion estimation speed improvements (distance + computation short-circuit in conjunction with spiral search, cf. + dist1(), fullsearch()) + + - Tristan Savatier for his help on numerous + improvements, suggestions, and features. + + Numerous users: + for providing bug reports and Makefiles + +7. History of Technical Report Project +====================================== + +The Technical Report, a document which primarily consists of +a C source code program, was initiated by the MPEG committee to: + + - Provide an example of MPEG video syntax being intelligently employed + to generate good quality video bitstreams. + - A reference tool for implementors + - Aid in understanding the MPEG specification + - decoder which employs full arithmetic accuracy. + +---- +End of Readme file diff --git a/src/gdcmmpeg2/README.gdcm.txt b/src/gdcmmpeg2/README.gdcm.txt new file mode 100644 index 00000000..c1de0ec9 --- /dev/null +++ b/src/gdcmmpeg2/README.gdcm.txt @@ -0,0 +1,14 @@ +This directory contains a subset of the MPEG Software Simulation Group +- Motion Picture Experts Group file interchange format (version 1) -. +We only include enough of distribution to build libmpeg2. We do not + include the subdir par, doc and verify. We do not include either the standard +executables that come with libmpeg2 (verify, mpeg2dec, mpeg2enc). Furthermore, the standard +libmpeg2 build process is replaced with a CMake build process. + +We'd like to thank the MPEG Software Simulation Group for distributing a public MPEG IO library. + +Modifications +------------- + +- modification were made so that compilation with gcc -Wall flags passes without warnings +- remove all explicit tabs and replace by proper amount of spaces diff --git a/src/gdcmmpeg2/src/CMakeLists.txt b/src/gdcmmpeg2/src/CMakeLists.txt new file mode 100644 index 00000000..3603e553 --- /dev/null +++ b/src/gdcmmpeg2/src/CMakeLists.txt @@ -0,0 +1 @@ +SUBDIRS(mpeg2dec) diff --git a/src/gdcmmpeg2/src/mpeg2dec/CHANGES b/src/gdcmmpeg2/src/mpeg2dec/CHANGES new file mode 100644 index 00000000..896f1e1a --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/CHANGES @@ -0,0 +1,95 @@ +CHANGES +---------- + +January 9, 1996 to July 17, 1996 +- cleaned up some code which gave warnings. +- altered some code to be compatible with Sun CC compiler. + However, support in the makefile for non-ansi C compilers + has been dropped (this is a stupid thing to support). + +December 20, 1995 to January 9, 1996: + +verified on HHI #22, TCEH #23 bitstreams. + + 1. new arguments format. Got to be so many argument fields that + a new more consistent format was devised. + + 2. Frame_Store_Flag (-f) option now controls lower layer prediciton + picture format (field or framewise) + + 3. getpic() structural changes + + +Since December 18, 1995: + +1. added special case for current B pictures subsframe.c which + loads entire reference frame for buffer substitution. + +2. fixed -l omission (-lXext) in Makefile that drives Tristan nuts everytime. + + +Since December 14, 1995: + + 1. organized frame buffer substitution routines into subspic.c + 2. added "big file" -b mode for Tristan ;-) + + +Since July 4, 1994: + +1. Concatenated elementary sequences within same bitstream + + Decode can now handle concatenated elementary video sequences of + arbitrary parameters. + +2. TRACE and VERBOSE #ifdef flags + +3. More disciplined naming convention + + normative variables and bitstream elements defined in 13818 are + verbatim, lower case. Implementation specific routines and variables + are capitolized. + +4. Spatial scalability corrections + - see Carsten's document (spatscal.doc) + +5. D-pictures (picture_coding_type==D_TYPE) + + Only two small changes were necessary to accomodate D-pictures: + + a. in Decode_MPEG1_Intra_Block() added line which termines + subroutine after DC coefficient has been processed. + + b. in picture_data(), added line which parses marker bit. + + + 6. forced decoder to display frame progressively (regardless of whether + the picture is frame structured or field structured) when -f flag + is invoked in the command line arguements. + + also: progressive_frame now decides whether a frame is to be displayed + as a frame picture to two field pictures, rather than the older convention + of testing progressive_sequence. + + 7. Adapted systems parser from Stefan's mpeg2play to mpeg2decode. + The major changes are: + + mpeg2dec.c: + - fseek() called twice + + gethdr.c, getpic.c: + instances of Flush_Bits(par,32) changed to Flush_Bits32(par) + + gethdr.c + Get_Bits(par,32) changed to Get_32_Bits(par) + + global.h + added rdmax, sysstream, and bfr[] to parameters struct. + + 8. Restructuring of getpic.c: + + a. moved picture pointer rotation into Update_Picture_Buffers() + b. moved picture output logic into Output_Current_Frame() to + in anticipation of 3:2 pulldown + + + diff --git a/src/gdcmmpeg2/src/mpeg2dec/CMakeLists.txt b/src/gdcmmpeg2/src/mpeg2dec/CMakeLists.txt new file mode 100644 index 00000000..848ea591 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/CMakeLists.txt @@ -0,0 +1,20 @@ +SET(GDCM_MPEG2_SOURCES + mpeg2dec.c + getpic.c + motion.c + getvlc.c + gethdr.c + getblk.c + getbits.c + store.c + recon.c + spatscal.c + idct.c + idctref.c + display.c + systems.c + subspic.c + verify.c + ) +ADD_LIBRARY(gdcmmpeg2 ${GDCM_MPEG2_SOURCES} ) + diff --git a/src/gdcmmpeg2/src/mpeg2dec/EXAMPLES b/src/gdcmmpeg2/src/mpeg2dec/EXAMPLES new file mode 100644 index 00000000..3e51981d --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/EXAMPLES @@ -0,0 +1,49 @@ +EXAMPLES: + +1. to decode a bitstream with double precision IDCT, such as + to create a reference reconstruction set of frames: + + mpeg2decode -r -f -o0 rec%d -b bitstream.mpg + +2. to decode a bitstream with fast integer IDCT, such as + to create a test reconstruction set of frames: + + mpeg2decode -f -o0 rec%d -b bitstream.mpg + +3. To substitute reference pictures with external reference + pictures (ref%d): + + mpeg2decode -f -x ref%d -b bitstream.mpg -o0 rec%d + + +4. Same as 3. only using a single large concatenated file for the + sequence of reconstruction frames. + + mpeg2decode -f -g -x ref%d bitstream.mpg -o0 rec%d + +5. Decode an SNR enhancement bitstream at the same time as base layer + stream: + + mpeg2decode -o0 rec%d -e snr_bitstream.mpg -b base_bitstream.mpg + +6. Decode a Spatially scalable bitstream + + Step 1: create lower layer reconstruction + + mpeg2decode -f -o0 llrec%d -b base_layer.mpg + + Step 2: decode enhancement bitstream, combined reconstruction. + + mpeg2decode -f -l llrec%d -b enhancement_layer.mpg -o0 rec%d + +------------ + where: + -o0 specifies .Y, .U, .V input + -f specifies field interleaved format + -b is the bitstream flag + -g specifies substitute file is a large concatendated one. + -e substitution flag + ref.pic filename of substitution sequence + bitstream.mpg bitstream + test%d output file pattern + diff --git a/src/gdcmmpeg2/src/mpeg2dec/IEEE1180 b/src/gdcmmpeg2/src/mpeg2dec/IEEE1180 new file mode 100644 index 00000000..9ab821d2 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/IEEE1180 @@ -0,0 +1,245 @@ +IEEE 1180 report for mpeg2decode fast integer IDCT: + +From stefan@lis.e-technik.tu-muenchen.de Thu May 26 08:18:36 1994 + +IEEE test conditions: -L = -256, +H = 255, sign = 1, #iters = 10000 +Peak absolute values of errors: + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 +Worst peak error = 1 (meets spec limit 1) + +Mean square errors: + 0.0058 0.0118 0.0097 0.0057 0.0055 0.0117 0.0120 0.0063 + 0.0106 0.0157 0.0142 0.0099 0.0115 0.0168 0.0154 0.0123 + 0.0128 0.0156 0.0152 0.0095 0.0115 0.0147 0.0173 0.0096 + 0.0055 0.0115 0.0103 0.0078 0.0069 0.0092 0.0113 0.0071 + 0.0057 0.0134 0.0123 0.0067 0.0050 0.0109 0.0128 0.0065 + 0.0101 0.0172 0.0159 0.0093 0.0097 0.0148 0.0163 0.0130 + 0.0113 0.0171 0.0148 0.0103 0.0110 0.0153 0.0149 0.0093 + 0.0064 0.0123 0.0104 0.0065 0.0064 0.0111 0.0099 0.0066 +Worst pmse = 0.017300 (meets spec limit 0.06) +Overall mse = 0.010998 (meets spec limit 0.02) + +Mean errors: + 0.0014 0.0004 0.0003 0.0017 0.0003 0.0011 0.0010 -0.0001 + 0.0000 0.0003 0.0010 0.0003 0.0007 -0.0006 0.0004 0.0033 + 0.0000 -0.0008 -0.0006 0.0009 -0.0015 -0.0013 -0.0017 -0.0008 + -0.0017 0.0019 -0.0005 0.0010 0.0005 0.0000 -0.0017 -0.0001 + 0.0007 0.0034 0.0015 0.0021 0.0016 0.0007 -0.0006 0.0011 + -0.0007 0.0004 -0.0001 0.0003 0.0003 0.0004 0.0031 -0.0010 + 0.0009 -0.0005 -0.0004 0.0003 0.0008 -0.0015 -0.0007 -0.0007 + 0.0024 0.0001 0.0018 -0.0003 -0.0006 -0.0001 0.0009 0.0018 +Worst mean error = 0.003400 (meets spec limit 0.015) +Overall mean error = 0.000352 (meets spec limit 0.0015) + +0 elements of IDCT(0) were not zero + + +25.8u 0.1s 0:27 95% 0+216k 0+2io 0pf+0w +IEEE test conditions: -L = -5, +H = 5, sign = 1, #iters = 10000 +Peak absolute values of errors: + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 +Worst peak error = 1 (meets spec limit 1) + +Mean square errors: + 0.0008 0.0008 0.0006 0.0006 0.0006 0.0006 0.0007 0.0005 + 0.0005 0.0003 0.0005 0.0001 0.0003 0.0007 0.0007 0.0004 + 0.0004 0.0012 0.0011 0.0007 0.0010 0.0008 0.0010 0.0003 + 0.0004 0.0004 0.0001 0.0002 0.0004 0.0007 0.0009 0.0004 + 0.0005 0.0005 0.0004 0.0002 0.0006 0.0004 0.0012 0.0003 + 0.0008 0.0006 0.0007 0.0007 0.0003 0.0012 0.0011 0.0004 + 0.0006 0.0002 0.0001 0.0002 0.0005 0.0005 0.0007 0.0005 + 0.0008 0.0004 0.0006 0.0003 0.0008 0.0006 0.0002 0.0003 +Worst pmse = 0.001200 (meets spec limit 0.06) +Overall mse = 0.000561 (meets spec limit 0.02) + +Mean errors: + 0.0008 0.0006 0.0000 0.0006 0.0006 0.0002 0.0005 0.0003 + 0.0005 0.0003 0.0003 0.0001 0.0001 0.0001 0.0005 0.0002 + 0.0004 0.0006 0.0005 0.0007 0.0006 0.0004 0.0002 -0.0001 + 0.0002 0.0002 0.0001 0.0002 0.0004 0.0005 0.0003 0.0002 + 0.0003 0.0003 0.0004 0.0002 0.0006 0.0000 0.0002 0.0003 + -0.0002 0.0004 0.0007 0.0005 0.0001 0.0010 0.0005 -0.0002 + 0.0004 0.0000 0.0001 0.0000 0.0001 0.0003 0.0005 0.0003 + 0.0006 0.0000 0.0002 0.0003 0.0004 0.0002 0.0002 0.0001 +Worst mean error = 0.001000 (meets spec limit 0.015) +Overall mean error = 0.000311 (meets spec limit 0.0015) + +0 elements of IDCT(0) were not zero + + +25.7u 0.1s 0:27 95% 0+216k 0+3io 0pf+0w +IEEE test conditions: -L = -300, +H = 300, sign = 1, #iters = 10000 +Peak absolute values of errors: + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 +Worst peak error = 1 (meets spec limit 1) + +Mean square errors: + 0.0068 0.0097 0.0119 0.0064 0.0065 0.0105 0.0112 0.0050 + 0.0088 0.0130 0.0128 0.0088 0.0111 0.0152 0.0139 0.0109 + 0.0114 0.0127 0.0157 0.0099 0.0114 0.0137 0.0153 0.0109 + 0.0052 0.0097 0.0120 0.0060 0.0067 0.0114 0.0099 0.0065 + 0.0062 0.0096 0.0091 0.0064 0.0076 0.0092 0.0111 0.0058 + 0.0096 0.0139 0.0166 0.0112 0.0092 0.0141 0.0122 0.0103 + 0.0121 0.0138 0.0131 0.0089 0.0108 0.0172 0.0127 0.0104 + 0.0070 0.0109 0.0092 0.0055 0.0057 0.0128 0.0102 0.0069 +Worst pmse = 0.017200 (meets spec limit 0.06) +Overall mse = 0.010316 (meets spec limit 0.02) + +Mean errors: + -0.0010 0.0015 0.0001 -0.0004 0.0005 -0.0001 0.0008 0.0000 + 0.0004 0.0016 0.0006 0.0000 -0.0001 0.0004 0.0011 0.0001 + -0.0008 0.0013 0.0015 0.0003 0.0010 0.0005 -0.0005 0.0021 + 0.0006 0.0013 -0.0004 0.0000 0.0007 -0.0002 -0.0009 0.0003 + 0.0004 0.0004 -0.0001 -0.0004 0.0014 0.0018 0.0017 -0.0002 + 0.0024 0.0007 -0.0002 -0.0018 0.0004 0.0001 0.0010 0.0009 + 0.0001 -0.0002 0.0005 0.0003 -0.0016 0.0004 0.0013 -0.0006 + -0.0012 -0.0017 -0.0008 0.0003 0.0001 0.0018 0.0008 -0.0005 +Worst mean error = 0.002400 (meets spec limit 0.015) +Overall mean error = 0.000309 (meets spec limit 0.0015) + +0 elements of IDCT(0) were not zero + + +25.8u 0.0s 0:27 95% 0+216k 0+4io 0pf+0w +IEEE test conditions: -L = -256, +H = 255, sign = -1, #iters = 10000 +Peak absolute values of errors: + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 +Worst peak error = 1 (meets spec limit 1) + +Mean square errors: + 0.0061 0.0118 0.0097 0.0057 0.0058 0.0113 0.0115 0.0061 + 0.0105 0.0159 0.0138 0.0097 0.0113 0.0166 0.0149 0.0123 + 0.0129 0.0155 0.0152 0.0095 0.0112 0.0145 0.0173 0.0094 + 0.0059 0.0112 0.0105 0.0076 0.0071 0.0091 0.0113 0.0073 + 0.0061 0.0130 0.0128 0.0066 0.0051 0.0108 0.0126 0.0067 + 0.0099 0.0168 0.0161 0.0095 0.0100 0.0149 0.0166 0.0132 + 0.0113 0.0171 0.0150 0.0101 0.0110 0.0157 0.0152 0.0094 + 0.0062 0.0121 0.0102 0.0065 0.0061 0.0112 0.0099 0.0065 +Worst pmse = 0.017300 (meets spec limit 0.06) +Overall mse = 0.010980 (meets spec limit 0.02) + +Mean errors: + -0.0005 0.0006 0.0001 -0.0007 0.0006 -0.0003 -0.0003 0.0011 + 0.0011 0.0003 -0.0002 0.0005 -0.0001 0.0008 0.0001 -0.0027 + 0.0013 0.0015 0.0010 -0.0001 0.0020 0.0019 0.0025 0.0016 + 0.0023 -0.0008 0.0011 -0.0002 0.0007 0.0003 0.0019 0.0009 + -0.0003 -0.0030 -0.0002 -0.0012 -0.0009 0.0000 0.0010 -0.0005 + 0.0009 0.0002 0.0015 0.0007 0.0002 0.0001 -0.0026 0.0018 + 0.0001 0.0011 0.0010 0.0005 -0.0004 0.0023 0.0014 0.0014 + -0.0014 0.0007 -0.0014 0.0009 0.0013 0.0006 -0.0007 -0.0007 +Worst mean error = 0.003000 (meets spec limit 0.015) +Overall mean error = 0.000355 (meets spec limit 0.0015) + +0 elements of IDCT(0) were not zero + + +25.8u 0.1s 0:27 95% 0+216k 0+3io 0pf+0w +IEEE test conditions: -L = -5, +H = 5, sign = -1, #iters = 10000 +Peak absolute values of errors: + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 +Worst peak error = 1 (meets spec limit 1) + +Mean square errors: + 0.0010 0.0007 0.0008 0.0004 0.0008 0.0004 0.0005 0.0007 + 0.0005 0.0007 0.0005 0.0004 0.0006 0.0005 0.0005 0.0003 + 0.0003 0.0011 0.0009 0.0007 0.0008 0.0006 0.0011 0.0006 + 0.0003 0.0004 0.0002 0.0002 0.0003 0.0006 0.0008 0.0006 + 0.0004 0.0005 0.0006 0.0006 0.0003 0.0007 0.0007 0.0003 + 0.0013 0.0006 0.0008 0.0005 0.0004 0.0006 0.0008 0.0004 + 0.0003 0.0003 0.0003 0.0002 0.0005 0.0004 0.0006 0.0005 + 0.0005 0.0003 0.0006 0.0005 0.0011 0.0007 0.0005 0.0003 +Worst pmse = 0.001300 (meets spec limit 0.06) +Overall mse = 0.000561 (meets spec limit 0.02) + +Mean errors: + 0.0002 0.0005 0.0008 0.0000 0.0002 0.0004 0.0003 0.0007 + 0.0001 0.0003 0.0003 0.0002 0.0006 0.0003 0.0001 0.0003 + -0.0001 0.0007 0.0003 0.0001 0.0002 0.0006 0.0005 0.0006 + 0.0001 0.0004 0.0002 0.0002 0.0001 0.0002 0.0004 0.0004 + 0.0002 0.0005 0.0006 0.0004 0.0001 0.0005 0.0005 0.0003 + 0.0009 0.0002 0.0000 0.0001 0.0004 0.0000 0.0006 0.0004 + 0.0003 0.0003 0.0003 0.0002 0.0003 0.0000 0.0004 0.0003 + 0.0003 0.0003 0.0004 0.0003 0.0007 0.0005 0.0005 0.0003 +Worst mean error = 0.000900 (meets spec limit 0.015) +Overall mean error = 0.000333 (meets spec limit 0.0015) + +0 elements of IDCT(0) were not zero + + +25.7u 0.1s 0:27 95% 0+216k 0+0io 0pf+0w +IEEE test conditions: -L = -300, +H = 300, sign = -1, #iters = 10000 +Peak absolute values of errors: + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 +Worst peak error = 1 (meets spec limit 1) + +Mean square errors: + 0.0067 0.0097 0.0118 0.0060 0.0066 0.0107 0.0113 0.0049 + 0.0082 0.0132 0.0128 0.0088 0.0110 0.0152 0.0140 0.0109 + 0.0122 0.0125 0.0156 0.0098 0.0113 0.0139 0.0152 0.0106 + 0.0054 0.0097 0.0121 0.0064 0.0067 0.0110 0.0096 0.0062 + 0.0064 0.0099 0.0090 0.0067 0.0078 0.0089 0.0112 0.0057 + 0.0098 0.0136 0.0165 0.0111 0.0090 0.0138 0.0120 0.0103 + 0.0121 0.0135 0.0131 0.0087 0.0107 0.0168 0.0128 0.0102 + 0.0069 0.0109 0.0091 0.0057 0.0061 0.0125 0.0103 0.0070 +Worst pmse = 0.016800 (meets spec limit 0.06) +Overall mse = 0.010283 (meets spec limit 0.02) + +Mean errors: + 0.0015 -0.0009 0.0006 0.0012 0.0002 0.0007 -0.0001 0.0005 + 0.0004 -0.0010 0.0000 0.0004 0.0006 0.0004 -0.0004 0.0007 + 0.0018 -0.0009 -0.0006 0.0000 -0.0003 -0.0001 0.0014 -0.0006 + -0.0002 -0.0011 0.0009 0.0004 -0.0003 0.0010 0.0010 0.0000 + 0.0004 0.0001 0.0010 0.0011 -0.0008 -0.0017 -0.0006 0.0009 + -0.0020 0.0000 0.0007 0.0021 0.0002 0.0002 -0.0004 -0.0003 + 0.0003 0.0005 -0.0003 -0.0001 0.0017 0.0002 -0.0004 0.0010 + 0.0015 0.0023 0.0013 0.0003 0.0005 -0.0011 -0.0003 0.0006 +Worst mean error = 0.002300 (meets spec limit 0.015) +Overall mean error = 0.000252 (meets spec limit 0.0015) + +0 elements of IDCT(0) were not zero + + +25.8u 0.0s 0:27 94% 0+216k 0+3io 0pf+0w + diff --git a/src/gdcmmpeg2/src/mpeg2dec/Makefile b/src/gdcmmpeg2/src/mpeg2dec/Makefile new file mode 100644 index 00000000..0f9b8b81 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/Makefile @@ -0,0 +1,98 @@ +# Makefile for mpeg2decode + +# Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. + +# +# Disclaimer of Warranty +# +# These software programs are available to the user without any license fee or +# royalty on an "as is" basis. The MPEG Software Simulation Group disclaims +# any and all warranties, whether express, implied, or statuary, including any +# implied warranties or merchantability or of fitness for a particular +# purpose. In no event shall the copyright-holder be liable for any +# incidental, punitive, or consequential damages of any kind whatsoever +# arising from the use of these programs. +# +# This disclaimer of warranty extends to the user of these programs and user's +# customers, employees, agents, transferees, successors, and assigns. +# +# The MPEG Software Simulation Group does not represent or warrant that the +# programs furnished hereunder are free of infringement of any third-party +# patents. +# +# Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, +# are subject to royalty fees to patent holders. Many of these patents are +# general enough such that they are unavoidable regardless of implementation +# design. +# +# + +#WARNINGS = -Wall +#VERIFY = -DVERIFY + +#disable this flag if you do not want bitstream element tracing +#this will speed up the decoder some since it does not have to test +#the trace flag at several critical inner loop locations. +TRACE = -DTRACE + +#disable this flag if you do not need verbose trace, such as +#header information +VERBOSE = -DVERBOSE + +# uncomment the following two lines if you want to include X11 support + +#USE_DISP = -DDISPLAY +#LIBS = -lX11 + +# uncomment the following two lines if you want to use shared memory +# (faster display if server and client run on the same machine) + +#USE_SHMEM = -DSH_MEM +#LIBS = -lXext -lX11 + +# if your X11 include files / libraries are in a non standard location: +# set INCLUDEDIR to -I followed by the appropriate include file path and +# set LIBRARYDIR to -L followed by the appropriate library path and + +#INCLUDEDIR = -I/usr/openwin/include +#LIBRARYDIR = -L/usr/openwin/lib + +# +# GNU gcc +# +CC = gcc +CFLAGS = -O2 $(USE_DISP) $(USE_SHMEM) $(INCLUDEDIR) $(TRACE) $(VERBOSE) $(VERIFY) $(WARNINGS) + +OBJ = mpeg2dec.o getpic.o motion.o getvlc.o gethdr.o getblk.o getbits.o store.o recon.o spatscal.o idct.o idctref.o display.o systems.o subspic.o verify.o + +all: mpeg2decode + +pc: mpeg2dec.exe + +clean: + rm -f *.o *% core mpeg2decode + +mpeg2dec.exe: mpeg2decode + coff2exe mpeg2dec + +mpeg2decode: $(OBJ) + $(CC) $(CFLAGS) $(LIBRARYDIR) -o mpeg2decode $(OBJ) -lm $(LIBS) + +display.o : display.c config.h global.h mpeg2dec.h +getbits.o : getbits.c config.h global.h mpeg2dec.h +getblk.o : getblk.c config.h global.h mpeg2dec.h +gethdr.o : gethdr.c config.h global.h mpeg2dec.h +getpic.o : getpic.c config.h global.h mpeg2dec.h +getvlc.o : getvlc.c config.h global.h mpeg2dec.h getvlc.h +idct.o : idct.c config.h +idctref.o : idctref.c config.h +motion.o : motion.c config.h global.h mpeg2dec.h +mpeg2dec.o : mpeg2dec.c config.h global.h mpeg2dec.h +recon.o : recon.c config.h global.h mpeg2dec.h +spatscal.o : spatscal.c config.h global.h mpeg2dec.h +store.o : store.c config.h global.h mpeg2dec.h + +# additions since July 4, 1994 edition +systems.o : systems.c config.h global.h mpeg2dec.h +subspic.o : subspic.c config.h global.h mpeg2dec.h +verify.o: verify.c config.h global.h mpeg2dec.h diff --git a/src/gdcmmpeg2/src/mpeg2dec/README b/src/gdcmmpeg2/src/mpeg2dec/README new file mode 100644 index 00000000..0c12d581 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/README @@ -0,0 +1,44 @@ +January 9, 1995: +===== +Pre-release caveats: + + - has only been tested with gcc. (I'm not sure we will even bother + with acc, or cc in the future). + + - I'm fully aware of the warnings received by -Wall + + - Verifier still not integrated (due to complexity), although + experimental vbv_delay code included in verify.c + + + +December 20, 1995 +=============================================================== +Frame buffer substitution edition of decoder. + +Restrictions: + - temporal_reference in bitstream must be correct. + + - substitute pictures must have pixel (luminance samples) width + and height equal to coded_picture_width (mb_width*16) and + coded_picture_height (mb_height*16) rather than horizontal_size + and vertical_size, respectively. + + - all input pictures must be interleaved into a frame. + + - frame count (index) is based on absolute display frame order with + no repeated (3:2 pulldown) fields or frames. + +-------------------------------------------------------- +Notes: + + - command line arguements in this edition differ from verifier + style. This decoder's arguments are the same as the + public distribution's (July 4, 1994) code . + + please note that this code, with frame buffer substitution, when it + is released will use the verifier style of arguments. + + - Carsten's updated spatial scalability decoder routines have been + incorperated. + diff --git a/src/gdcmmpeg2/src/mpeg2dec/SPATIAL.DOC b/src/gdcmmpeg2/src/mpeg2dec/SPATIAL.DOC new file mode 100644 index 00000000..84b04ce8 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/SPATIAL.DOC @@ -0,0 +1,154 @@ +The following changes have been made to debug spatial scalability: + +gethdr.c +-------- + +Temporal_reference is used to compute the frame number of each frame, +named true_framenum. The periodic reset at each GOP header as well as +the wrap of temporal_reference at 1024 cause a base value +temp_ref_base to be incremented accordingly. + +spatscal.c +---------- + +getspatref() + +A potential problem: Variable char fname[32] was dimensioned +statically and too small. + +true_framenum is used instead of lower_layer_temporal_reference to +determine the lower layer frame to be read for spatial prediction. + +The verification of lower_layer_temporal_reference is not possible +since the temporal reference values that have been encoded into the +base layer bitstream are not available to the enhancement layer +decoder. + +Since there is no decoder timing information available, the rules on +which frames can legally be used as spatial prediction frames cannot +be checked. + +Lower layer frames are read field-wise or frame-wise, depending on the +lower_layer_progressive_frame flag. Consistency between layers is +checked since the file format for frame and field pictures differs. + +Note that the base layer decoder must not use the -f option to enforce +frame-wise storage. + +Note further that only yuv image format (option -o0) is supported as +input format. + +spatpred() + +The code for the various combinations of llprog_frame, llfieldsel and +prog_frame has been completed and verified with the tceh_conf23 +bitstream that uses all permissive combinations. + + +getpic.c +-------- + +A small bug when storing an I- or P-frame: The prog_frame flag that +the decoder knows when storing the oldrefframe belongs to the current +refframe. Therefore the old value of the flag needs to be memorized. + + +store.c +------- + +A potential problem: the filename variables char outname[32], +tmpname[32] are statically dimensioned and quite small. + + +The concept of time in this video decoder software +-------------------------------------------------- + +When decoding a non-scalable bitstream, the frame number (i.e. +temporal position) of the current I- or P-frame can be derived +implicitly from the number of preceding B-frames after they have been +decoded. Therefore the temporal_reference entry in the picture header +is somewhat redundant and does not necessarily have to be evaluated in +the decoding process. + +Decoding of the enhancement layer of a spatial scalable hierarchy, +however, requires to know the temporal position of each frame at the +instant when it is decoded, since data from a lower layer reference +frame has to be incorporated. + +In the architecture of this video-only decoder decoding of a spatial +scalable hierarchy of bitstreams is done by calling mpeg2decode once +for the base layer bitstream and a second time for the enhancement +layer bitstream, indicating where the decoded base layer frames can be +found (option -s). + +Here the concept of time is only present in the form of frame numbers. +Therefore spatial scalable bitstream hierarchies can only be handled +under the assumption that base and enhancement layer bitstreams are +decoded to image sequences where corresponding images of both layers +have identical frame numbers. + +More specifically this means that base and enhancement layer +bitstreams must contain video with the same frame rate. Furthermore +only the temporally coincident frame of the base layer can be accessed +for spatial prediction by the enhancement layer decoder, since it is +not possible to resolve unambiguously the lower_layer_temporal_reference +which is meant to further specify the lower layer reference frame. + +======================== SPATIAL.DOC ========================0 + +Decoding a spatial scalable hierarchy of bitstreams +--------------------------------------------------- + +With this video-only decoder decoding of a spatial scalable hierarchy +of bitstreams is done by calling mpeg2decode once for the base layer +bitstream and a second time for the enhancement layer bitstream, +indicating where the decoded base layer frames can be found +(using option -s and supplying ). + +mpeg2decode -r -o0 base.mpg base%d%c +mpeg2decode -r -o0 -f -s base%d%c enh.mpg enh%d + +Note that the base layer decoder must not use the -f option to enforce +frame-wise storage. + +Note further that only yuv image format (option -o0) is supported as +input format. + + +Timing / layer synchronisation in this video decoder software +------------------------------------------------------------- + +When decoding a non-scalable bitstream, the frame number (i.e. +temporal position) of the current I- or P-frame can be derived +implicitly from the number of preceding B-frames after they have been +decoded. Therefore the temporal_reference entry in the picture header +is somewhat redundant and does not necessarily have to be evaluated in +the decoding process. + +Decoding of the enhancement layer of a spatial scalable hierarchy, +however, requires to know the temporal position of each frame at the +instant when it is decoded, since data from a lower layer reference +frame has to be incorporated. + +The concept of time is only present in the form of frame numbers. +Therefore spatial scalable bitstream hierarchies can only be handled +under the assumption that base and enhancement layer bitstreams are +decoded to image sequences where corresponding images of both layers +have identical frame numbers. + +More specifically this means that base and enhancement layer +bitstreams must contain video with the same frame rate. Furthermore +only the temporally coincident frame of the base layer can be accessed +for spatial prediction by the enhancement layer decoder, since it is +not possible to resolve unambiguously the lower_layer_temporal_reference +which is meant to further specify the lower layer reference frame. + +Lower layer frames are read field-wise or frame-wise, depending on the +lower_layer_progressive_frame flag. Consistency between layers in this +respect is checked since the file format for frame and field pictures +differs. + + + + + diff --git a/src/gdcmmpeg2/src/mpeg2dec/TODO b/src/gdcmmpeg2/src/mpeg2dec/TODO new file mode 100644 index 00000000..5984171f --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/TODO @@ -0,0 +1,73 @@ + 1. Test bitstream + Small example bitstream (128x128 pixel dimensions) which employs all + picture_structure (top field, bottom field, frame), picture_coding_type + (I, P, and B), macroblock_type (forwards/backwards/interpolated, + intra/non-intra, coded/not-coded, quant/no quant, etc.), and + motion_type (field, frame, 16X8, dual prime) modes. + + 2. add trace printing for mpeg1 getblk routines. + + 3. modify getsys.c to parse program layer bitstreams (Systems) + with variable-length packets. + + 4. 24 bit X11 display + (borrow from Berkeley or find way for our code to use their interface) + + 5. MPEG-2 Transport layer systems streams parsing + + 6. Document IPR issue + + provide CableLabs URL + how IPR relates to our disclaimer. + + 7. TIFF library support (YCbCr 4:4:4, 4:2:2, and 4:2:0 pictures) +[deferred] + +10. IDCT rounding + As per IDCT corridgendum (Savatier, MPEG 95/XXX) + [done, but verified ?] + + +12. green dots in can + [ appears to be a display issue, probably related to convmat[] + error ] + +19. move Dual_Prime calculation into picture_data() + +20. motion vector calculation to include tappable stages to test + whether elements fall within [low:high] range. + +21. Integrate verifier routines + +22. Inter-layer verification routines + - check base and enhancement layers (e.g. SNR) + +23. Spatial verification + - considering that no base layer is available. + +24. SNR verification + [ done ] + +25. DP verification + [ not done. No longer any bitstreams with Data Partitioning distributed + since DP is not part of any official Profile ] + +26. merge all global bitsteam element variables into + common data structure (similar to layer_data). This is needed + for the verifier (whether or not headers in SNR and DP streams + are identical where needed to that of the base layer). + +27. investigate why MS-DOS wants an extra % sign for filename patterns + when more than one filename pattern is used in the command line argument + +28. convert -t (trace) flag into levels, merge with Verbose. + +29. seek to a specified frame number (support for MCI-like functions) + +30. document the "flash" VLC table decoding method in detail. + (namely how to map tables in Annex B to those in getvlc.h) + +31. MPEG-2 program stream compatibility + (a few minor bits of difference in the system header ). + +-------- diff --git a/src/gdcmmpeg2/src/mpeg2dec/config.h b/src/gdcmmpeg2/src/mpeg2dec/config.h new file mode 100644 index 00000000..cfc213fe --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/config.h @@ -0,0 +1,44 @@ +/* config.h, configuration defines */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +/* define NON_ANSI_COMPILER for compilers without function prototyping */ +/* #define NON_ANSI_COMPILER */ + +#ifdef NON_ANSI_COMPILER +#define _ANSI_ARGS_(x) () +#else +#define _ANSI_ARGS_(x) x +#endif + +#define RB "rb" +#define WB "wb" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif diff --git a/src/gdcmmpeg2/src/mpeg2dec/display.c b/src/gdcmmpeg2/src/mpeg2dec/display.c new file mode 100644 index 00000000..21baa012 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/display.c @@ -0,0 +1,1218 @@ +/* display.c, X11 interface */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#ifdef DISPLAY + + /* the Xlib interface is closely modeled after + * mpeg_play 2.0 by the Berkeley Plateau Research Group + */ + +#include +#include + +#include +#include + +#include "config.h" +#include "global.h" + +/* private prototypes */ +static void Display_Image _ANSI_ARGS_((XImage *Ximage_Ptr, unsigned char *Dithered_Image)); +static void Dither_Frame _ANSI_ARGS_((unsigned char *src[])); +static void Dither_Top_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst)); +static void Dither_Bottom_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst)); +static void Dither_Top_Field420 _ANSI_ARGS_((unsigned char *src[], + unsigned char *dst)); +static void Dither_Bottom_Field420 _ANSI_ARGS_((unsigned char *src[], + unsigned char *dst)); + +/* local data */ +static unsigned char *Dithered_Image, *Dithered_Image2; + +static unsigned char Y_Table[256+16]; +static unsigned char Cb_Table[128+16]; +static unsigned char Cr_Table[128+16]; + +/* X11 related variables */ +static Display *Display_Ptr; +static Window Window_Instance; +static GC GC_Instance; +static XImage *Ximage_Ptr, *Ximage_Ptr2; +static unsigned char Pixel[256]; + +#ifdef SH_MEM + +#include +#include +#include + +static int HandleXError _ANSI_ARGS_((Display *dpy, XErrorEvent *event)); +static void InstallXErrorHandler _ANSI_ARGS_((void)); +static void DeInstallXErrorHandler _ANSI_ARGS_((void)); + +static int Shmem_Flag; +static XShmSegmentInfo Shminfo1, Shminfo2; +static int gXErrorFlag; +static int CompletionType = -1; + +static int HandleXError(Dpy, Event) +Display *Dpy; +XErrorEvent *Event; +{ + gXErrorFlag = 1; + + return 0; +} + +static void InstallXErrorHandler() +{ + XSetErrorHandler(HandleXError); + XFlush(Display_Ptr); +} + +static void DeInstallXErrorHandler() +{ + XSetErrorHandler(NULL); + XFlush(Display_Ptr); +} + +#endif + +/* connect to server, create and map window, + * allocate colors and (shared) memory + */ +void Initialize_Display_Process(name) +char *name; +{ + int crv, cbu, cgu, cgv; + int Y, Cb, Cr, R, G, B; + int i; + char dummy; + int screen; + Colormap cmap; + int private; + XColor xcolor; + unsigned int fg, bg; + char *hello = "MPEG-2 Display"; + XSizeHints hint; + XVisualInfo vinfo; + XEvent xev; + unsigned long tmp_pixel; + XWindowAttributes xwa; + + Display_Ptr = XOpenDisplay(name); + + if (Display_Ptr == NULL) + Error("Can not open display\n"); + + screen = DefaultScreen(Display_Ptr); + + hint.x = 200; + hint.y = 200; + hint.width = horizontal_size; + hint.height = vertical_size; + hint.flags = PPosition | PSize; + + /* Get some colors */ + + bg = WhitePixel (Display_Ptr, screen); + fg = BlackPixel (Display_Ptr, screen); + + /* Make the window */ + + if (!XMatchVisualInfo(Display_Ptr, screen, 8, PseudoColor, &vinfo)) + { + if (!XMatchVisualInfo(Display_Ptr, screen, 8, GrayScale, &vinfo)) + Error("requires 8 bit display\n"); + } + + Window_Instance = XCreateSimpleWindow (Display_Ptr, DefaultRootWindow (Display_Ptr), + hint.x, hint.y, hint.width, hint.height, 4, fg, bg); + + XSelectInput(Display_Ptr, Window_Instance, StructureNotifyMask); + + /* Tell other applications about this window */ + + XSetStandardProperties (Display_Ptr, Window_Instance, hello, hello, None, NULL, 0, &hint); + + /* Map window. */ + + XMapWindow(Display_Ptr, Window_Instance); + + /* Wait for map. */ + do + { + XNextEvent(Display_Ptr, &xev); + } + while (xev.type != MapNotify || xev.xmap.event != Window_Instance); + + XSelectInput(Display_Ptr, Window_Instance, NoEventMask); + + /* matrix coefficients */ + crv = Inverse_Table_6_9[matrix_coefficients][0]; + cbu = Inverse_Table_6_9[matrix_coefficients][1]; + cgu = Inverse_Table_6_9[matrix_coefficients][2]; + cgv = Inverse_Table_6_9[matrix_coefficients][3]; + + /* allocate colors */ + + GC_Instance = DefaultGC(Display_Ptr, screen); + cmap = DefaultColormap(Display_Ptr, screen); + private = 0; + + /* color allocation: + * i is the (internal) 8 bit color number, it consists of separate + * bit fields for Y, U and V: i = (yyyyuuvv), we don't use yyyy=0000 + * and yyyy=1111, this leaves 32 colors for other applications + * + * the allocated colors correspond to the following Y, U and V values: + * Y: 24, 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232 + * U,V: -48, -16, 16, 48 + * + * U and V values span only about half the color space; this gives + * usually much better quality, although highly saturated colors can + * not be displayed properly + * + * translation to R,G,B is implicitly done by the color look-up table + */ + for (i=16; i<240; i++) + { + /* color space conversion */ + Y = 16*((i>>4)&15) + 8; + Cb = 32*((i>>2)&3) - 48; + Cr = 32*(i&3) - 48; + + Y = 76309 * (Y - 16); /* (255/219)*65536 */ + + R = Clip[(Y + crv*Cr + 32768)>>16]; + G = Clip[(Y - cgu*Cb - cgv*Cr + 32768)>>16]; + B = Clip[(Y + cbu*Cb + 32786)>>16]; + + /* X11 colors are 16 bit */ + xcolor.red = R << 8; + xcolor.green = G << 8; + xcolor.blue = B << 8; + + if (XAllocColor(Display_Ptr, cmap, &xcolor) != 0) + Pixel[i] = xcolor.pixel; + else + { + /* allocation failed, have to use a private colormap */ + + if (private) + Error("Couldn't allocate private colormap"); + + private = 1; + + if (!Quiet_Flag) + fprintf(stderr, "Using private colormap (%d colors were available).\n", + i-16); + + /* Free colors. */ + while (--i >= 16) + { + tmp_pixel = Pixel[i]; /* because XFreeColors expects unsigned long */ + XFreeColors(Display_Ptr, cmap, &tmp_pixel, 1, 0); + } + + /* i is now 15, this restarts the outer loop */ + + /* create private colormap */ + + XGetWindowAttributes(Display_Ptr, Window_Instance, &xwa); + cmap = XCreateColormap(Display_Ptr, Window_Instance, xwa.visual, AllocNone); + XSetWindowColormap(Display_Ptr, Window_Instance, cmap); + } + } + +#ifdef SH_MEM + if (XShmQueryExtension(Display_Ptr)) + Shmem_Flag = 1; + else + { + Shmem_Flag = 0; + if (!Quiet_Flag) + fprintf(stderr, "Shared memory not supported\nReverting to normal Xlib\n"); + } + + if (Shmem_Flag) + CompletionType = XShmGetEventBase(Display_Ptr) + ShmCompletion; + + InstallXErrorHandler(); + + if (Shmem_Flag) + { + + Ximage_Ptr = XShmCreateImage(Display_Ptr, None, 8, ZPixmap, NULL, + &Shminfo1, + Coded_Picture_Width, Coded_Picture_Height); + + if (!progressive_sequence) + Ximage_Ptr2 = XShmCreateImage(Display_Ptr, None, 8, ZPixmap, NULL, + &Shminfo2, + Coded_Picture_Width, Coded_Picture_Height); + + /* If no go, then revert to normal Xlib calls. */ + + if (Ximage_Ptr==NULL || (!progressive_sequence && Ximage_Ptr2==NULL)) + { + if (Ximage_Ptr!=NULL) + XDestroyImage(Ximage_Ptr); + if (!progressive_sequence && Ximage_Ptr2!=NULL) + XDestroyImage(Ximage_Ptr2); + if (!Quiet_Flag) + fprintf(stderr, "Shared memory error, disabling (Ximage error)\n"); + goto shmemerror; + } + + /* Success here, continue. */ + + Shminfo1.shmid = shmget(IPC_PRIVATE, + Ximage_Ptr->bytes_per_line * Ximage_Ptr->height, + IPC_CREAT | 0777); + if (!progressive_sequence) + Shminfo2.shmid = shmget(IPC_PRIVATE, + Ximage_Ptr2->bytes_per_line * Ximage_Ptr2->height, + IPC_CREAT | 0777); + + if (Shminfo1.shmid<0 || (!progressive_sequence && Shminfo2.shmid<0)) + { + XDestroyImage(Ximage_Ptr); + if (!progressive_sequence) + XDestroyImage(Ximage_Ptr2); + if (!Quiet_Flag) + fprintf(stderr, "Shared memory error, disabling (seg id error)\n"); + goto shmemerror; + } + + Shminfo1.shmaddr = (char *) shmat(Shminfo1.shmid, 0, 0); + Shminfo2.shmaddr = (char *) shmat(Shminfo2.shmid, 0, 0); + + if (Shminfo1.shmaddr==((char *) -1) || + (!progressive_sequence && Shminfo2.shmaddr==((char *) -1))) + { + XDestroyImage(Ximage_Ptr); + if (Shminfo1.shmaddr!=((char *) -1)) + shmdt(Shminfo1.shmaddr); + if (!progressive_sequence) + { + XDestroyImage(Ximage_Ptr2); + if (Shminfo2.shmaddr!=((char *) -1)) + shmdt(Shminfo2.shmaddr); + } + if (!Quiet_Flag) + { + fprintf(stderr, "Shared memory error, disabling (address error)\n"); + } + goto shmemerror; + } + + Ximage_Ptr->data = Shminfo1.shmaddr; + Dithered_Image = (unsigned char *)Ximage_Ptr->data; + Shminfo1.readOnly = False; + XShmAttach(Display_Ptr, &Shminfo1); + if (!progressive_sequence) + { + Ximage_Ptr2->data = Shminfo2.shmaddr; + Dithered_Image2 = (unsigned char *)Ximage_Ptr2->data; + Shminfo2.readOnly = False; + XShmAttach(Display_Ptr, &Shminfo2); + } + + XSync(Display_Ptr, False); + + if (gXErrorFlag) + { + /* Ultimate failure here. */ + XDestroyImage(Ximage_Ptr); + shmdt(Shminfo1.shmaddr); + if (!progressive_sequence) + { + XDestroyImage(Ximage_Ptr2); + shmdt(Shminfo2.shmaddr); + } + if (!Quiet_Flag) + fprintf(stderr, "Shared memory error, disabling.\n"); + gXErrorFlag = 0; + goto shmemerror; + } + else + { + shmctl(Shminfo1.shmid, IPC_RMID, 0); + if (!progressive_sequence) + shmctl(Shminfo2.shmid, IPC_RMID, 0); + } + + if (!Quiet_Flag) + { + fprintf(stderr, "Sharing memory.\n"); + } + } + else + { +shmemerror: + Shmem_Flag = 0; +#endif + + Ximage_Ptr = XCreateImage(Display_Ptr,None,8,ZPixmap,0,&dummy, + Coded_Picture_Width,Coded_Picture_Height,8,0); + + if (!(Dithered_Image = (unsigned char *)malloc(Coded_Picture_Width* + Coded_Picture_Height))) + Error("malloc failed"); + + if (!progressive_sequence) + { + Ximage_Ptr2 = XCreateImage(Display_Ptr,None,8,ZPixmap,0,&dummy, + Coded_Picture_Width,Coded_Picture_Height,8,0); + + if (!(Dithered_Image2 = (unsigned char *)malloc(Coded_Picture_Width* + Coded_Picture_Height))) + Error("malloc failed"); + } + +#ifdef SH_MEM + } + + DeInstallXErrorHandler(); +#endif +} + +void Terminate_Display_Process() +{ +#ifdef SH_MEM + if (Shmem_Flag) + { + XShmDetach(Display_Ptr, &Shminfo1); + XDestroyImage(Ximage_Ptr); + shmdt(Shminfo1.shmaddr); + if (!progressive_sequence) + { + XShmDetach(Display_Ptr, &Shminfo2); + XDestroyImage(Ximage_Ptr2); + shmdt(Shminfo2.shmaddr); + } + } +#endif +} + +static void Display_Image(Ximage_Ptr,Dithered_Image) +XImage *Ximage_Ptr; +unsigned char *Dithered_Image; +{ + /* display dithered image */ +#ifdef SH_MEM + if (Shmem_Flag) + { + XShmPutImage(Display_Ptr, Window_Instance, GC_Instance, Ximage_Ptr, + 0, 0, 0, 0, Ximage_Ptr->width, Ximage_Ptr->height, True); + XFlush(Display_Ptr); + + while (1) + { + XEvent xev; + + XNextEvent(Display_Ptr, &xev); + if (xev.type == CompletionType) + break; + } + } + else +#endif + { + Ximage_Ptr->data = (char *) Dithered_Image; + XPutImage(Display_Ptr, Window_Instance, GC_Instance, Ximage_Ptr, 0, 0, 0, 0, Ximage_Ptr->width, Ximage_Ptr->height); + } +} + +void Display_Second_Field() +{ + Display_Image(Ximage_Ptr2,Dithered_Image2); +} + +/* 4x4 ordered dither + * + * threshold pattern: + * 0 8 2 10 + * 12 4 14 6 + * 3 11 1 9 + * 15 7 13 5 + */ + +void Initialize_Dither_Matrix() +{ + int i, v; + + for (i=-8; i<256+8; i++) + { + v = i>>4; + if (v<1) + v = 1; + else if (v>14) + v = 14; + Y_Table[i+8] = v<<4; + } + + for (i=0; i<128+16; i++) + { + v = (i-40)>>4; + if (v<0) + v = 0; + else if (v>3) + v = 3; + Cb_Table[i] = v<<2; + Cr_Table[i] = v; + } +} + +void dither(src) +unsigned char *src[]; +{ + /* should this test only the display flag, not progressive_sequence ? --CF */ + /* CHANGE 95/05/13: progressive_sequence -> progressive_frame */ + + if( progressive_frame || Display_Progressive_Flag) + Dither_Frame(src); + else + { + if ((picture_structure==FRAME_PICTURE && top_field_first) || picture_structure==BOTTOM_FIELD) + { + /* top field first */ + if (chroma_format==CHROMA420 && hiQdither) + { + Dither_Top_Field420(src,Dithered_Image); + Dither_Bottom_Field420(src,Dithered_Image2); + } + else + { + Dither_Top_Field(src,Dithered_Image); + Dither_Bottom_Field(src,Dithered_Image2); + } + } + else + { + /* bottom field first */ + if (chroma_format==CHROMA420 && hiQdither) + { + Dither_Bottom_Field420(src,Dithered_Image); + Dither_Top_Field420(src,Dithered_Image2); + } + else + { + Dither_Bottom_Field(src,Dithered_Image); + Dither_Top_Field(src,Dithered_Image2); + } + } + } + + Display_Image(Ximage_Ptr,Dithered_Image); +} + +static void Dither_Frame(src) +unsigned char *src[]; +{ + int i,j; + int y,u,v; + unsigned char *py,*pu,*pv,*dst; + + py = src[0]; + pu = src[1]; + pv = src[2]; + dst = Dithered_Image; + + for (j=0; j> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y]|Cb_Table[u]|Cr_Table[v]]; + y = *py++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+8]|Cb_Table[u+8]|Cr_Table[v+8]]; + y = *py++; + u = *pu++ >> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y+2]|Cb_Table[u+2]|Cr_Table[v+2]]; + y = *py++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+10]|Cb_Table[u+10]|Cr_Table[v+10]]; + } + + if (chroma_format==CHROMA420) + { + pu -= Chroma_Width; + pv -= Chroma_Width; + } + + /* line j + 1 */ + for (i=0; i> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y+12]|Cb_Table[u+12]|Cr_Table[v+12]]; + y = *py++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+4]|Cb_Table[u+4]|Cr_Table[v+4]]; + y = *py++; + u = *pu++ >> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y+14]|Cb_Table[u+14]|Cr_Table[v+14]]; + y = *py++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+6]|Cb_Table[u+6]|Cr_Table[v+6]]; + } + + /* line j + 2 */ + for (i=0; i> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y+3]|Cb_Table[u+3]|Cr_Table[v+3]]; + y = *py++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+11]|Cb_Table[u+11]|Cr_Table[v+11]]; + y = *py++; + u = *pu++ >> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y+1]|Cb_Table[u+1]|Cr_Table[v+1]]; + y = *py++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+9]|Cb_Table[u+9]|Cr_Table[v+9]]; + } + + if (chroma_format==CHROMA420) + { + pu -= Chroma_Width; + pv -= Chroma_Width; + } + + /* line j + 3 */ + for (i=0; i> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y+15]|Cb_Table[u+15]|Cr_Table[v+15]]; + y = *py++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+7]|Cb_Table[u+7]|Cr_Table[v+7]]; + y = *py++; + u = *pu++ >> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y+13]|Cb_Table[u+13]|Cr_Table[v+13]]; + y = *py++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+5]|Cb_Table[u+5]|Cr_Table[v+5]]; + } + } + +} + +static void Dither_Top_Field(src,dst) +unsigned char *src[]; +unsigned char *dst; +{ + int i,j; + int y,Y2,u,v; + unsigned char *py,*Y2_ptr,*pu,*pv,*dst2; + + py = src[0]; + Y2_ptr = src[0] + (Coded_Picture_Width<<1); + pu = src[1]; + pv = src[2]; + dst2 = dst + Coded_Picture_Width; + + for (j=0; j> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y]|Cb_Table[u]|Cr_Table[v]]; + *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+12]|Cb_Table[u+12]|Cr_Table[v+12]]; + + y = *py++; + Y2 = *Y2_ptr++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+8]|Cb_Table[u+8]|Cr_Table[v+8]]; + *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+4]|Cb_Table[u+4]|Cr_Table[v+4]]; + + y = *py++; + Y2 = *Y2_ptr++; + u = *pu++ >> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y+2]|Cb_Table[u+2]|Cr_Table[v+2]]; + *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+14]|Cb_Table[u+14]|Cr_Table[v+14]]; + + y = *py++; + Y2 = *Y2_ptr++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+10]|Cb_Table[u+10]|Cr_Table[v+10]]; + *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+6]|Cb_Table[u+6]|Cr_Table[v+6]]; + } + + py += Coded_Picture_Width; + + if (j!=(Coded_Picture_Height-4)) + Y2_ptr += Coded_Picture_Width; + else + Y2_ptr -= Coded_Picture_Width; + + dst += Coded_Picture_Width; + dst2 += Coded_Picture_Width; + + if (chroma_format==CHROMA420) + { + pu -= Chroma_Width; + pv -= Chroma_Width; + } + else + { + pu += Chroma_Width; + pv += Chroma_Width; + } + + /* line j + 2, j + 3 */ + for (i=0; i> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y+3]|Cb_Table[u+3]|Cr_Table[v+3]]; + *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+15]|Cb_Table[u+15]|Cr_Table[v+15]]; + + y = *py++; + Y2 = *Y2_ptr++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+11]|Cb_Table[u+11]|Cr_Table[v+11]]; + *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+7]|Cb_Table[u+7]|Cr_Table[v+7]]; + + y = *py++; + Y2 = *Y2_ptr++; + u = *pu++ >> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[y+1]|Cb_Table[u+1]|Cr_Table[v+1]]; + *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+13]|Cb_Table[u+13]|Cr_Table[v+13]]; + + y = *py++; + Y2 = *Y2_ptr++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[y+9]|Cb_Table[u+9]|Cr_Table[v+9]]; + *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+5]|Cb_Table[u+5]|Cr_Table[v+5]]; + } + + py += Coded_Picture_Width; + Y2_ptr += Coded_Picture_Width; + dst += Coded_Picture_Width; + dst2 += Coded_Picture_Width; + pu += Chroma_Width; + pv += Chroma_Width; + } +} + +static void Dither_Bottom_Field(src,dst) +unsigned char *src[]; +unsigned char *dst; +{ + int i,j; + int y,Y2,u,v; + unsigned char *py,*Y2_ptr,*pu,*pv,*dst2; + + py = src[0] + Coded_Picture_Width; + Y2_ptr = py; + pu = src[1] + Chroma_Width; + pv = src[2] + Chroma_Width; + dst2 = dst + Coded_Picture_Width; + + for (j=0; j> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[((y+Y2)>>1)]|Cb_Table[u]|Cr_Table[v]]; + *dst2++ = Pixel[Y_Table[Y2+12]|Cb_Table[u+12]|Cr_Table[v+12]]; + + y = *py++; + Y2 = *Y2_ptr++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[((y+Y2)>>1)+8]|Cb_Table[u+8]|Cr_Table[v+8]]; + *dst2++ = Pixel[Y_Table[Y2+4]|Cb_Table[u+4]|Cr_Table[v+4]]; + + y = *py++; + Y2 = *Y2_ptr++; + u = *pu++ >> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[((y+Y2)>>1)+2]|Cb_Table[u+2]|Cr_Table[v+2]]; + *dst2++ = Pixel[Y_Table[Y2+14]|Cb_Table[u+14]|Cr_Table[v+14]]; + + y = *py++; + Y2 = *Y2_ptr++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[((y+Y2)>>1)+10]|Cb_Table[u+10]|Cr_Table[v+10]]; + *dst2++ = Pixel[Y_Table[Y2+6]|Cb_Table[u+6]|Cr_Table[v+6]]; + } + + if (j==0) + py -= Coded_Picture_Width; + else + py += Coded_Picture_Width; + + Y2_ptr += Coded_Picture_Width; + dst += Coded_Picture_Width; + dst2 += Coded_Picture_Width; + + if (chroma_format==CHROMA420) + { + pu -= Chroma_Width; + pv -= Chroma_Width; + } + else + { + pu += Chroma_Width; + pv += Chroma_Width; + } + + /* line j + 2. j + 3 */ + for (i=0; i> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[((y+Y2)>>1)+3]|Cb_Table[u+3]|Cr_Table[v+3]]; + *dst2++ = Pixel[Y_Table[Y2+15]|Cb_Table[u+15]|Cr_Table[v+15]]; + + y = *py++; + Y2 = *Y2_ptr++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[((y+Y2)>>1)+11]|Cb_Table[u+11]|Cr_Table[v+11]]; + *dst2++ = Pixel[Y_Table[Y2+7]|Cb_Table[u+7]|Cr_Table[v+7]]; + + y = *py++; + Y2 = *Y2_ptr++; + u = *pu++ >> 1; + v = *pv++ >> 1; + *dst++ = Pixel[Y_Table[((y+Y2)>>1)+1]|Cb_Table[u+1]|Cr_Table[v+1]]; + *dst2++ = Pixel[Y_Table[Y2+13]|Cb_Table[u+13]|Cr_Table[v+13]]; + + y = *py++; + Y2 = *Y2_ptr++; + if (chroma_format==CHROMA444) + { + u = *pu++ >> 1; + v = *pv++ >> 1; + } + *dst++ = Pixel[Y_Table[((y+Y2)>>1)+9]|Cb_Table[u+9]|Cr_Table[v+9]]; + *dst2++ = Pixel[Y_Table[Y2+5]|Cb_Table[u+5]|Cr_Table[v+5]]; + } + + py += Coded_Picture_Width; + Y2_ptr += Coded_Picture_Width; + dst += Coded_Picture_Width; + dst2 += Coded_Picture_Width; + pu += Chroma_Width; + pv += Chroma_Width; + } +} + +static void Dither_Top_Field420(src,dst) +unsigned char *src[]; +unsigned char *dst; +{ + int i,j; + int Y1,Cb1,Cr1,Y2,Cb2,Cr2; + unsigned char *Y1_ptr,*Cb1_ptr,*Cr1_ptr,*Y2_ptr,*Cb2_ptr,*Cr2_ptr,*dst2; + + Y1_ptr = src[0]; + Cb1_ptr = src[1]; + Cr1_ptr = src[2]; + + Y2_ptr = Y1_ptr + (Coded_Picture_Width<<1); + Cb2_ptr = Cb1_ptr + (Chroma_Width<<1); + Cr2_ptr = Cr1_ptr + (Chroma_Width<<1); + + dst2 = dst + Coded_Picture_Width; + + for (j=0; j> 1; + Cr1 = *Cr1_ptr++ >> 1; + Cb2 = *Cb2_ptr++ >> 1; + Cr2 = *Cr2_ptr++ >> 1; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)]|Cb_Table[Cb1]|Cr_Table[Cr1]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+12]|Cb_Table[((3*Cb1+Cb2)>>2)+12] + |Cr_Table[((3*Cr1+Cr2)>>2)+12]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+8]|Cb_Table[Cb1+8]|Cr_Table[Cr1+8]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+4]|Cb_Table[((3*Cb1+Cb2)>>2)+4] + |Cr_Table[((3*Cr1+Cr2)>>2)+4]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + Cb1 = *Cb1_ptr++ >> 1; + Cr1 = *Cr1_ptr++ >> 1; + Cb2 = *Cb2_ptr++ >> 1; + Cr2 = *Cr2_ptr++ >> 1; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+2]|Cb_Table[Cb1+2]|Cr_Table[Cr1+2]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+14]|Cb_Table[((3*Cb1+Cb2)>>2)+14] + |Cr_Table[((3*Cr1+Cr2)>>2)+14]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+10]|Cb_Table[Cb1+10]|Cr_Table[Cr1+10]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+6]|Cb_Table[((3*Cb1+Cb2)>>2)+6] + |Cr_Table[((3*Cr1+Cr2)>>2)+6]]; + } + + Y1_ptr += Coded_Picture_Width; + + if (j!=(Coded_Picture_Height-4)) + Y2_ptr += Coded_Picture_Width; + else + Y2_ptr -= Coded_Picture_Width; + + Cb1_ptr -= Chroma_Width; + Cr1_ptr -= Chroma_Width; + Cb2_ptr -= Chroma_Width; + Cr2_ptr -= Chroma_Width; + + dst += Coded_Picture_Width; + dst2 += Coded_Picture_Width; + + /* line j + 2, j + 3 */ + for (i=0; i> 1; + Cr1 = *Cr1_ptr++ >> 1; + Cb2 = *Cb2_ptr++ >> 1; + Cr2 = *Cr2_ptr++ >> 1; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+3]|Cb_Table[((Cb1+Cb2)>>1)+3] + |Cr_Table[((Cr1+Cr2)>>1)+3]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+15]|Cb_Table[((Cb1+3*Cb2)>>2)+15] + |Cr_Table[((Cr1+3*Cr2)>>2)+15]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+11]|Cb_Table[((Cb1+Cb2)>>1)+11] + |Cr_Table[((Cr1+Cr2)>>1)+11]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+7]|Cb_Table[((Cb1+3*Cb2)>>2)+7] + |Cr_Table[((Cr1+3*Cr2)>>2)+7]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + Cb1 = *Cb1_ptr++ >> 1; + Cr1 = *Cr1_ptr++ >> 1; + Cb2 = *Cb2_ptr++ >> 1; + Cr2 = *Cr2_ptr++ >> 1; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+1]|Cb_Table[((Cb1+Cb2)>>1)+1] + |Cr_Table[((Cr1+Cr2)>>1)+1]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+13]|Cb_Table[((Cb1+3*Cb2)>>2)+13] + |Cr_Table[((Cr1+3*Cr2)>>2)+13]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+9]|Cb_Table[((Cb1+Cb2)>>1)+9] + |Cr_Table[((Cr1+Cr2)>>1)+9]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+5]|Cb_Table[((Cb1+3*Cb2)>>2)+5] + |Cr_Table[((Cr1+3*Cr2)>>2)+5]]; + } + + Y1_ptr += Coded_Picture_Width; + Y2_ptr += Coded_Picture_Width; + Cb1_ptr += Chroma_Width; + Cr1_ptr += Chroma_Width; + if (j!=(Coded_Picture_Height-8)) + { + Cb2_ptr += Chroma_Width; + Cr2_ptr += Chroma_Width; + } + else + { + Cb2_ptr -= Chroma_Width; + Cr2_ptr -= Chroma_Width; + } + dst += Coded_Picture_Width; + dst2+= Coded_Picture_Width; + } +} + +static void Dither_Bottom_Field420(src,dst) +unsigned char *src[]; +unsigned char *dst; +{ + int i,j; + int Y1,Cb1,Cr1,Y2,Cb2,Cr2; + unsigned char *Y1_ptr,*Cb1_ptr,*Cr1_ptr,*Y2_ptr,*Cb2_ptr,*Cr2_ptr,*dst2; + + Y2_ptr = Y1_ptr = src[0] + Coded_Picture_Width; + Cb2_ptr = Cb1_ptr = src[1] + Chroma_Width; + Cr2_ptr = Cr1_ptr = src[2] + Chroma_Width; + + dst2 = dst; + + for (j=0; j> 1; + Cr1 = *Cr1_ptr++ >> 1; + Cb2 = *Cb2_ptr++ >> 1; + Cr2 = *Cr2_ptr++ >> 1; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+15]|Cb_Table[((3*Cb1+Cb2)>>2)+15] + |Cr_Table[((3*Cr1+Cr2)>>2)+15]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)]|Cb_Table[((Cb1+Cb2)>>1)] + |Cr_Table[((Cr1+Cr2)>>1)]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+7]|Cb_Table[((3*Cb1+Cb2)>>2)+7] + |Cr_Table[((3*Cr1+Cr2)>>2)+7]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+8]|Cb_Table[((Cb1+Cb2)>>1)+8] + |Cr_Table[((Cr1+Cr2)>>1)+8]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + Cb1 = *Cb1_ptr++ >> 1; + Cr1 = *Cr1_ptr++ >> 1; + Cb2 = *Cb2_ptr++ >> 1; + Cr2 = *Cr2_ptr++ >> 1; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+13]|Cb_Table[((3*Cb1+Cb2)>>2)+13] + |Cr_Table[((3*Cr1+Cr2)>>2)+13]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+2]|Cb_Table[((Cb1+Cb2)>>1)+2] + |Cr_Table[((Cr1+Cr2)>>1)+2]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+5]|Cb_Table[((3*Cb1+Cb2)>>2)+5] + |Cr_Table[((3*Cr1+Cr2)>>2)+5]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+10]|Cb_Table[((Cb1+Cb2)>>1)+10] + |Cr_Table[((Cr1+Cr2)>>1)+10]]; + } + + if (j!=0) + Y1_ptr += Coded_Picture_Width; + else + Y1_ptr -= Coded_Picture_Width; + + Y2_ptr += Coded_Picture_Width; + + Cb1_ptr -= Chroma_Width; + Cr1_ptr -= Chroma_Width; + Cb2_ptr -= Chroma_Width; + Cr2_ptr -= Chroma_Width; + + if (j!=0) + dst += Coded_Picture_Width; + + dst2 += Coded_Picture_Width; + + /* line j + 2, j + 3 */ + for (i=0; i> 1; + Cr1 = *Cr1_ptr++ >> 1; + Cb2 = *Cb2_ptr++ >> 1; + Cr2 = *Cr2_ptr++ >> 1; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+12]|Cb_Table[((Cb1+3*Cb2)>>2)+12] + |Cr_Table[((Cr1+3*Cr2)>>2)+12]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+3]|Cb_Table[Cb2+3] + |Cr_Table[Cr2+3]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+4]|Cb_Table[((Cb1+3*Cb2)>>2)+4] + |Cr_Table[((Cr1+3*Cr2)>>2)+4]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+11]|Cb_Table[Cb2+11] + |Cr_Table[Cr2+11]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + Cb1 = *Cb1_ptr++ >> 1; + Cr1 = *Cr1_ptr++ >> 1; + Cb2 = *Cb2_ptr++ >> 1; + Cr2 = *Cr2_ptr++ >> 1; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+14]|Cb_Table[((Cb1+3*Cb2)>>2)+14] + |Cr_Table[((Cr1+3*Cr2)>>2)+14]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+1]|Cb_Table[Cb2+1] + |Cr_Table[Cr2+1]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+6]|Cb_Table[((Cb1+3*Cb2)>>2)+6] + |Cr_Table[((Cr1+3*Cr2)>>2)+6]]; + *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+9]|Cb_Table[Cb2+9] + |Cr_Table[Cr2+9]]; + } + + Y1_ptr += Coded_Picture_Width; + Y2_ptr += Coded_Picture_Width; + + if (j!=0) + { + Cb1_ptr += Chroma_Width; + Cr1_ptr += Chroma_Width; + } + else + { + Cb1_ptr -= Chroma_Width; + Cr1_ptr -= Chroma_Width; + } + + Cb2_ptr += Chroma_Width; + Cr2_ptr += Chroma_Width; + + dst += Coded_Picture_Width; + dst2+= Coded_Picture_Width; + } + + Y2_ptr -= (Coded_Picture_Width<<1); + Cb2_ptr -= (Chroma_Width<<1); + Cr2_ptr -= (Chroma_Width<<1); + + /* dither last line */ + for (i=0; i> 1; + Cr1 = *Cr1_ptr++ >> 1; + Cb2 = *Cb2_ptr++ >> 1; + Cr2 = *Cr2_ptr++ >> 1; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+15]|Cb_Table[((3*Cb1+Cb2)>>2)+15] + |Cr_Table[((3*Cr1+Cr2)>>2)+15]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+7]|Cb_Table[((3*Cb1+Cb2)>>2)+7] + |Cr_Table[((3*Cr1+Cr2)>>2)+7]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + Cb1 = *Cb1_ptr++ >> 1; + Cr1 = *Cr1_ptr++ >> 1; + Cb2 = *Cb2_ptr++ >> 1; + Cr2 = *Cr2_ptr++ >> 1; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+13]|Cb_Table[((3*Cb1+Cb2)>>2)+13] + |Cr_Table[((3*Cr1+Cr2)>>2)+13]]; + + Y1 = *Y1_ptr++; + Y2 = *Y2_ptr++; + *dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+5]|Cb_Table[((3*Cb1+Cb2)>>2)+5] + |Cr_Table[((3*Cr1+Cr2)>>2)+5]]; + } + +} +#endif diff --git a/src/gdcmmpeg2/src/mpeg2dec/getbits.c b/src/gdcmmpeg2/src/mpeg2dec/getbits.c new file mode 100644 index 00000000..9b9b593c --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/getbits.c @@ -0,0 +1,202 @@ +/* getbits.c, bit level routines */ + +/* + * All modifications (mpeg2decode -> mpeg2play) are + * Copyright (C) 1996, Stefan Eckart. All Rights Reserved. + */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include +#include + +#include "config.h" +#include "global.h" + +/* initialize buffer, call once before first getbits or showbits */ + +void Initialize_Buffer() +{ + ld->Incnt = 0; + ld->Rdptr = ld->Rdbfr + 2048; + ld->Rdmax = ld->Rdptr; + +#ifdef VERIFY + /* only the verifier uses this particular bit counter + * Bitcnt keeps track of the current parser position with respect + * to the video elementary stream being decoded, regardless + * of whether or not it is wrapped within a systems layer stream + */ + ld->Bitcnt = 0; +#endif + + ld->Bfr = 0; + Flush_Buffer(0); /* fills valid data into bfr */ +} + +void Fill_Buffer() +{ + int Buffer_Level; + + Buffer_Level = read(ld->Infile,ld->Rdbfr,2048); + ld->Rdptr = ld->Rdbfr; + + if (System_Stream_Flag) + ld->Rdmax -= 2048; + + + /* end of the bitstream file */ + if (Buffer_Level < 2048) + { + /* just to be safe */ + if (Buffer_Level < 0) + Buffer_Level = 0; + + /* pad until the next to the next 32-bit word boundary */ + while (Buffer_Level & 3) + ld->Rdbfr[Buffer_Level++] = 0; + + /* pad the buffer with sequence end codes */ + while (Buffer_Level < 2048) + { + ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE>>24; + ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE>>16; + ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE>>8; + ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE&0xff; + } + } +} + + +/* MPEG-1 system layer demultiplexer */ + +int Get_Byte() +{ + while(ld->Rdptr >= ld->Rdbfr+2048) + { + read(ld->Infile,ld->Rdbfr,2048); + ld->Rdptr -= 2048; + ld->Rdmax -= 2048; + } + return *ld->Rdptr++; +} + +/* extract a 16-bit word from the bitstream buffer */ +int Get_Word() +{ + int Val; + + Val = Get_Byte(); + return (Val<<8) | Get_Byte(); +} + + +/* return next n bits (right adjusted) without advancing */ + +unsigned int Show_Bits(N) +int N; +{ + return ld->Bfr >> (32-N); +} + + +/* return next bit (could be made faster than Get_Bits(1)) */ + +unsigned int Get_Bits1() +{ + return Get_Bits(1); +} + + +/* advance by n bits */ + +void Flush_Buffer(N) +int N; +{ + int Incnt; + + ld->Bfr <<= N; + + Incnt = ld->Incnt -= N; + + if (Incnt <= 24) + { + if (System_Stream_Flag && (ld->Rdptr >= ld->Rdmax-4)) + { + do + { + if (ld->Rdptr >= ld->Rdmax) + Next_Packet(); + ld->Bfr |= Get_Byte() << (24 - Incnt); + Incnt += 8; + } + while (Incnt <= 24); + } + else if (ld->Rdptr < ld->Rdbfr+2044) + { + do + { + ld->Bfr |= *ld->Rdptr++ << (24 - Incnt); + Incnt += 8; + } + while (Incnt <= 24); + } + else + { + do + { + if (ld->Rdptr >= ld->Rdbfr+2048) + Fill_Buffer(); + ld->Bfr |= *ld->Rdptr++ << (24 - Incnt); + Incnt += 8; + } + while (Incnt <= 24); + } + ld->Incnt = Incnt; + } + +#ifdef VERIFY + ld->Bitcnt += N; +#endif /* VERIFY */ + +} + + +/* return next n bits (right adjusted) */ + +unsigned int Get_Bits(N) +int N; +{ + unsigned int Val; + + Val = Show_Bits(N); + Flush_Buffer(N); + + return Val; +} + diff --git a/src/gdcmmpeg2/src/mpeg2dec/getblk.c b/src/gdcmmpeg2/src/mpeg2dec/getblk.c new file mode 100644 index 00000000..ffde10dd --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/getblk.c @@ -0,0 +1,570 @@ +/* getblk.c, DCT block decoding */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include + +#include "config.h" +#include "global.h" + + +/* defined in getvlc.h */ +typedef struct { + char run, level, len; +} DCTtab; + +extern DCTtab DCTtabfirst[],DCTtabnext[],DCTtab0[],DCTtab1[]; +extern DCTtab DCTtab2[],DCTtab3[],DCTtab4[],DCTtab5[],DCTtab6[]; +extern DCTtab DCTtab0a[],DCTtab1a[]; + + +/* decode one intra coded MPEG-1 block */ + +void Decode_MPEG1_Intra_Block(comp,dc_dct_pred) +int comp; +int dc_dct_pred[]; +{ + int val, i, j, sign; + unsigned int code; + DCTtab *tab; + short *bp; + + bp = ld->block[comp]; + + /* ISO/IEC 11172-2 section 2.4.3.7: Block layer. */ + /* decode DC coefficients */ + if (comp<4) + bp[0] = (dc_dct_pred[0]+=Get_Luma_DC_dct_diff()) << 3; + else if (comp==4) + bp[0] = (dc_dct_pred[1]+=Get_Chroma_DC_dct_diff()) << 3; + else + bp[0] = (dc_dct_pred[2]+=Get_Chroma_DC_dct_diff()) << 3; + + if (Fault_Flag) return; + + /* D-pictures do not contain AC coefficients */ + if(picture_coding_type == D_TYPE) + return; + + /* decode AC coefficients */ + for (i=1; ; i++) + { + code = Show_Bits(16); + if (code>=16384) + tab = &DCTtabnext[(code>>12)-4]; + else if (code>=1024) + tab = &DCTtab0[(code>>8)-4]; + else if (code>=512) + 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 + { + if (!Quiet_Flag) + printf("invalid Huffman code in Decode_MPEG1_Intra_Block()\n"); + Fault_Flag = 1; + return; + } + + Flush_Buffer(tab->len); + + if (tab->run==64) /* end_of_block */ + return; + + if (tab->run==65) /* escape */ + { + i+= Get_Bits(6); + + val = Get_Bits(8); + if (val==0) + val = Get_Bits(8); + else if (val==128) + val = Get_Bits(8) - 256; + else if (val>128) + val -= 256; + + if((sign = (val<0))) + val = -val; + } + else + { + i+= tab->run; + val = tab->level; + sign = Get_Bits(1); + } + + if (i>=64) + { + if (!Quiet_Flag) + fprintf(stderr,"DCT coeff index (i) out of bounds (intra)\n"); + Fault_Flag = 1; + return; + } + + j = scan[ZIG_ZAG][i]; + val = (val*ld->quantizer_scale*ld->intra_quantizer_matrix[j]) >> 3; + + /* mismatch control ('oddification') */ + if (val!=0) /* should always be true, but it's not guaranteed */ + val = (val-1) | 1; /* equivalent to: if ((val&1)==0) val = val - 1; */ + + /* saturation */ + if (!sign) + bp[j] = (val>2047) ? 2047 : val; /* positive */ + else + bp[j] = (val>2048) ? -2048 : -val; /* negative */ + } +} + + +/* decode one non-intra coded MPEG-1 block */ + +void Decode_MPEG1_Non_Intra_Block(comp) +int comp; +{ + int val, i, j, sign; + unsigned int code; + DCTtab *tab; + short *bp; + + bp = ld->block[comp]; + + /* decode AC coefficients */ + for (i=0; ; i++) + { + code = Show_Bits(16); + if (code>=16384) + { + if (i==0) + tab = &DCTtabfirst[(code>>12)-4]; + else + tab = &DCTtabnext[(code>>12)-4]; + } + else if (code>=1024) + tab = &DCTtab0[(code>>8)-4]; + else if (code>=512) + 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 + { + if (!Quiet_Flag) + printf("invalid Huffman code in Decode_MPEG1_Non_Intra_Block()\n"); + Fault_Flag = 1; + return; + } + + Flush_Buffer(tab->len); + + if (tab->run==64) /* end_of_block */ + return; + + if (tab->run==65) /* escape */ + { + i+= Get_Bits(6); + + val = Get_Bits(8); + if (val==0) + val = Get_Bits(8); + else if (val==128) + val = Get_Bits(8) - 256; + else if (val>128) + val -= 256; + + if((sign = (val<0))) + val = -val; + } + else + { + i+= tab->run; + val = tab->level; + sign = Get_Bits(1); + } + + if (i>=64) + { + if (!Quiet_Flag) + fprintf(stderr,"DCT coeff index (i) out of bounds (inter)\n"); + Fault_Flag = 1; + return; + } + + j = scan[ZIG_ZAG][i]; + val = (((val<<1)+1)*ld->quantizer_scale*ld->non_intra_quantizer_matrix[j]) >> 4; + + /* mismatch control ('oddification') */ + if (val!=0) /* should always be true, but it's not guaranteed */ + val = (val-1) | 1; /* equivalent to: if ((val&1)==0) val = val - 1; */ + + /* saturation */ + if (!sign) + bp[j] = (val>2047) ? 2047 : val; /* positive */ + else + bp[j] = (val>2048) ? -2048 : -val; /* negative */ + } +} + + +/* decode one intra coded MPEG-2 block */ + +void Decode_MPEG2_Intra_Block(comp,dc_dct_pred) +int comp; +int dc_dct_pred[]; +{ + int val, i, j, sign, nc, cc, run; + unsigned int code; + DCTtab *tab; + short *bp; + int *qmat; + struct layer_data *ld1; + + /* with data partitioning, data always goes to base layer */ + ld1 = (ld->scalable_mode==SC_DP) ? &base : ld; + bp = ld1->block[comp]; + + if (base.scalable_mode==SC_DP) + if (base.priority_breakpoint<64) + ld = &enhan; + else + ld = &base; + + cc = (comp<4) ? 0 : (comp&1)+1; + + qmat = (comp<4 || chroma_format==CHROMA420) + ? ld1->intra_quantizer_matrix + : ld1->chroma_intra_quantizer_matrix; + + /* ISO/IEC 13818-2 section 7.2.1: decode DC coefficients */ + if (cc==0) + val = (dc_dct_pred[0]+= Get_Luma_DC_dct_diff()); + else if (cc==1) + val = (dc_dct_pred[1]+= Get_Chroma_DC_dct_diff()); + else + val = (dc_dct_pred[2]+= Get_Chroma_DC_dct_diff()); + + if (Fault_Flag) return; + + bp[0] = val << (3-intra_dc_precision); + + nc=0; + +#ifdef TRACE + if (Trace_Flag) + printf("DCT(%d)i:",comp); +#endif /* TRACE */ + + /* decode AC coefficients */ + for (i=1; ; i++) + { + code = Show_Bits(16); + if (code>=16384 && !intra_vlc_format) + 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 + { + if (!Quiet_Flag) + printf("invalid Huffman code in Decode_MPEG2_Intra_Block()\n"); + Fault_Flag = 1; + return; + } + + Flush_Buffer(tab->len); + +#ifdef TRACE + if (Trace_Flag) + { + printf(" ("); + Print_Bits(code,16,tab->len); + } +#endif /* TRACE */ + + if (tab->run==64) /* end_of_block */ + { +#ifdef TRACE + if (Trace_Flag) + printf("): EOB\n"); +#endif /* TRACE */ + return; + } + + if (tab->run==65) /* escape */ + { +#ifdef TRACE + if (Trace_Flag) + { + putchar(' '); + Print_Bits(Show_Bits(6),6,6); + } +#endif /* TRACE */ + + i+= run = Get_Bits(6); + +#ifdef TRACE + if (Trace_Flag) + { + putchar(' '); + Print_Bits(Show_Bits(12),12,12); + } +#endif /* TRACE */ + + val = Get_Bits(12); + if ((val&2047)==0) + { + if (!Quiet_Flag) + printf("invalid escape in Decode_MPEG2_Intra_Block()\n"); + Fault_Flag = 1; + return; + } + if((sign = (val>=2048))) + val = 4096 - val; + } + else + { + i+= run = tab->run; + val = tab->level; + sign = Get_Bits(1); + +#ifdef TRACE + if (Trace_Flag) + printf("%d",sign); +#endif /* TRACE */ + } + + if (i>=64) + { + if (!Quiet_Flag) + fprintf(stderr,"DCT coeff index (i) out of bounds (intra2)\n"); + Fault_Flag = 1; + return; + } + +#ifdef TRACE + if (Trace_Flag) + printf("): %d/%d",run,sign ? -val : val); +#endif /* TRACE */ + + j = scan[ld1->alternate_scan][i]; + val = (val * ld1->quantizer_scale * qmat[j]) >> 4; + bp[j] = sign ? -val : val; + nc++; + + if (base.scalable_mode==SC_DP && nc==base.priority_breakpoint-63) + ld = &enhan; + } +} + + +/* decode one non-intra coded MPEG-2 block */ + +void Decode_MPEG2_Non_Intra_Block(comp) +int comp; +{ + int val, i, j, sign, nc, run; + unsigned int code; + DCTtab *tab; + short *bp; + int *qmat; + struct layer_data *ld1; + + /* with data partitioning, data always goes to base layer */ + ld1 = (ld->scalable_mode==SC_DP) ? &base : ld; + bp = ld1->block[comp]; + + if (base.scalable_mode==SC_DP) + if (base.priority_breakpoint<64) + ld = &enhan; + else + ld = &base; + + qmat = (comp<4 || chroma_format==CHROMA420) + ? ld1->non_intra_quantizer_matrix + : ld1->chroma_non_intra_quantizer_matrix; + + nc = 0; + +#ifdef TRACE + if (Trace_Flag) + printf("DCT(%d)n:",comp); +#endif /* TRACE */ + + /* decode AC coefficients */ + for (i=0; ; i++) + { + code = Show_Bits(16); + if (code>=16384) + { + if (i==0) + tab = &DCTtabfirst[(code>>12)-4]; + else + tab = &DCTtabnext[(code>>12)-4]; + } + else if (code>=1024) + tab = &DCTtab0[(code>>8)-4]; + else if (code>=512) + 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 + { + if (!Quiet_Flag) + printf("invalid Huffman code in Decode_MPEG2_Non_Intra_Block()\n"); + Fault_Flag = 1; + return; + } + + Flush_Buffer(tab->len); + +#ifdef TRACE + if (Trace_Flag) + { + printf(" ("); + Print_Bits(code,16,tab->len); + } +#endif /* TRACE */ + + if (tab->run==64) /* end_of_block */ + { +#ifdef TRACE + if (Trace_Flag) + printf("): EOB\n"); +#endif /* TRACE */ + return; + } + + if (tab->run==65) /* escape */ + { +#ifdef TRACE + if (Trace_Flag) + { + putchar(' '); + Print_Bits(Show_Bits(6),6,6); + } +#endif /* TRACE */ + + i+= run = Get_Bits(6); + +#ifdef TRACE + if (Trace_Flag) + { + putchar(' '); + Print_Bits(Show_Bits(12),12,12); + } +#endif /* TRACE */ + + val = Get_Bits(12); + if ((val&2047)==0) + { + if (!Quiet_Flag) + printf("invalid escape in Decode_MPEG2_Intra_Block()\n"); + Fault_Flag = 1; + return; + } + if((sign = (val>=2048))) + val = 4096 - val; + } + else + { + i+= run = tab->run; + val = tab->level; + sign = Get_Bits(1); + +#ifdef TRACE + if (Trace_Flag) + printf("%d",sign); +#endif /* TRACE */ + } + + if (i>=64) + { + if (!Quiet_Flag) + fprintf(stderr,"DCT coeff index (i) out of bounds (inter2)\n"); + Fault_Flag = 1; + return; + } + +#ifdef TRACE + if (Trace_Flag) + printf("): %d/%d",run,sign?-val:val); +#endif /* TRACE */ + + j = scan[ld1->alternate_scan][i]; + val = (((val<<1)+1) * ld1->quantizer_scale * qmat[j]) >> 5; + bp[j] = sign ? -val : val; + nc++; + + if (base.scalable_mode==SC_DP && nc==base.priority_breakpoint-63) + ld = &enhan; + } +} diff --git a/src/gdcmmpeg2/src/mpeg2dec/gethdr.c b/src/gdcmmpeg2/src/mpeg2dec/gethdr.c new file mode 100644 index 00000000..4155ec55 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/gethdr.c @@ -0,0 +1,1077 @@ +/* gethdr.c, header decoding */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include + +#include "config.h" +#include "global.h" + + +/* private prototypes */ +static void sequence_header _ANSI_ARGS_((void)); +static void group_of_pictures_header _ANSI_ARGS_((void)); +static void picture_header _ANSI_ARGS_((void)); +static void extension_and_user_data _ANSI_ARGS_((void)); +static void sequence_extension _ANSI_ARGS_((void)); +static void sequence_display_extension _ANSI_ARGS_((void)); +static void quant_matrix_extension _ANSI_ARGS_((void)); +static void sequence_scalable_extension _ANSI_ARGS_((void)); +static void picture_display_extension _ANSI_ARGS_((void)); +static void picture_coding_extension _ANSI_ARGS_((void)); +static void picture_spatial_scalable_extension _ANSI_ARGS_((void)); +static void picture_temporal_scalable_extension _ANSI_ARGS_((void)); +static int extra_bit_information _ANSI_ARGS_((void)); +static void copyright_extension _ANSI_ARGS_((void)); +static void user_data _ANSI_ARGS_((void)); +static void user_data _ANSI_ARGS_((void)); + + + + +/* introduced in September 1995 to assist spatial scalable decoding */ +static void Update_Temporal_Reference_Tacking_Data _ANSI_ARGS_((void)); +/* private variables */ +static int Temporal_Reference_Base = 0; +static int True_Framenum_max = -1; +static int Temporal_Reference_GOP_Reset = 0; + +#define RESERVED -1 +static double frame_rate_Table[16] = +{ + 0.0, + ((23.0*1000.0)/1001.0), + 24.0, + 25.0, + ((30.0*1000.0)/1001.0), + 30.0, + 50.0, + ((60.0*1000.0)/1001.0), + 60.0, + + RESERVED, + RESERVED, + RESERVED, + RESERVED, + RESERVED, + RESERVED, + RESERVED +}; + +/* + * decode headers from one input stream + * until an End of Sequence or picture start code + * is found + */ +int Get_Hdr() +{ + unsigned int code; + + for (;;) + { + /* look for next_start_code */ + next_start_code(); + code = Get_Bits32(); + + switch (code) + { + case SEQUENCE_HEADER_CODE: + sequence_header(); + break; + case GROUP_START_CODE: + group_of_pictures_header(); + break; + case PICTURE_START_CODE: + picture_header(); + return 1; + break; + case SEQUENCE_END_CODE: + return 0; + break; + default: + if (!Quiet_Flag) + fprintf(stderr,"Unexpected next_start_code %08x (ignored)\n",code); + break; + } + } +} + + +/* align to start of next next_start_code */ + +void next_start_code() +{ + /* byte align */ + Flush_Buffer(ld->Incnt&7); + while (Show_Bits(24)!=0x01L) + Flush_Buffer(8); +} + + +/* decode sequence header */ + +static void sequence_header() +{ + int i; + int pos; + + pos = ld->Bitcnt; + horizontal_size = Get_Bits(12); + vertical_size = Get_Bits(12); + aspect_ratio_information = Get_Bits(4); + frame_rate_code = Get_Bits(4); + bit_rate_value = Get_Bits(18); + marker_bit("sequence_header()"); + vbv_buffer_size = Get_Bits(10); + constrained_parameters_flag = Get_Bits(1); + + if((ld->load_intra_quantizer_matrix = Get_Bits(1))) + { + for (i=0; i<64; i++) + ld->intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); + } + else + { + for (i=0; i<64; i++) + ld->intra_quantizer_matrix[i] = default_intra_quantizer_matrix[i]; + } + + if((ld->load_non_intra_quantizer_matrix = Get_Bits(1))) + { + for (i=0; i<64; i++) + ld->non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); + } + else + { + for (i=0; i<64; i++) + ld->non_intra_quantizer_matrix[i] = 16; + } + + /* copy luminance to chrominance matrices */ + for (i=0; i<64; i++) + { + ld->chroma_intra_quantizer_matrix[i] = + ld->intra_quantizer_matrix[i]; + + ld->chroma_non_intra_quantizer_matrix[i] = + ld->non_intra_quantizer_matrix[i]; + } + +#ifdef VERBOSE + if (Verbose_Flag > NO_LAYER) + { + printf("sequence header (byte %d)\n",(pos>>3)-4); + if (Verbose_Flag > SEQUENCE_LAYER) + { + printf(" horizontal_size=%d\n",horizontal_size); + printf(" vertical_size=%d\n",vertical_size); + printf(" aspect_ratio_information=%d\n",aspect_ratio_information); + printf(" frame_rate_code=%d",frame_rate_code); + printf(" bit_rate_value=%d\n",bit_rate_value); + printf(" vbv_buffer_size=%d\n",vbv_buffer_size); + printf(" constrained_parameters_flag=%d\n",constrained_parameters_flag); + printf(" load_intra_quantizer_matrix=%d\n",ld->load_intra_quantizer_matrix); + printf(" load_non_intra_quantizer_matrix=%d\n",ld->load_non_intra_quantizer_matrix); + } + } +#endif /* VERBOSE */ + +#ifdef VERIFY + verify_sequence_header++; +#endif /* VERIFY */ + + extension_and_user_data(); +} + + + +/* decode group of pictures header */ +/* ISO/IEC 13818-2 section 6.2.2.6 */ +static void group_of_pictures_header() +{ + int pos; + + if (ld == &base) + { + Temporal_Reference_Base = True_Framenum_max + 1; /* *CH* */ + Temporal_Reference_GOP_Reset = 1; + } + pos = ld->Bitcnt; + drop_flag = Get_Bits(1); + hour = Get_Bits(5); + minute = Get_Bits(6); + marker_bit("group_of_pictures_header()"); + sec = Get_Bits(6); + frame = Get_Bits(6); + closed_gop = Get_Bits(1); + broken_link = Get_Bits(1); + +#ifdef VERBOSE + if (Verbose_Flag > NO_LAYER) + { + printf("group of pictures (byte %d)\n",(pos>>3)-4); + if (Verbose_Flag > SEQUENCE_LAYER) + { + printf(" drop_flag=%d\n",drop_flag); + printf(" timecode %d:%02d:%02d:%02d\n",hour,minute,sec,frame); + printf(" closed_gop=%d\n",closed_gop); + printf(" broken_link=%d\n",broken_link); + } + } +#endif /* VERBOSE */ + +#ifdef VERIFY + verify_group_of_pictures_header++; +#endif /* VERIFY */ + + extension_and_user_data(); + +} + + +/* decode picture header */ + +/* ISO/IEC 13818-2 section 6.2.3 */ +static void picture_header() +{ + int pos; + int Extra_Information_Byte_Count; + + /* unless later overwritten by picture_spatial_scalable_extension() */ + ld->pict_scal = 0; + + pos = ld->Bitcnt; + temporal_reference = Get_Bits(10); + picture_coding_type = Get_Bits(3); + vbv_delay = Get_Bits(16); + + if (picture_coding_type==P_TYPE || picture_coding_type==B_TYPE) + { + full_pel_forward_vector = Get_Bits(1); + forward_f_code = Get_Bits(3); + } + if (picture_coding_type==B_TYPE) + { + full_pel_backward_vector = Get_Bits(1); + backward_f_code = Get_Bits(3); + } + +#ifdef VERBOSE + if (Verbose_Flag>NO_LAYER) + { + printf("picture header (byte %d)\n",(pos>>3)-4); + if (Verbose_Flag>SEQUENCE_LAYER) + { + printf(" temporal_reference=%d\n",temporal_reference); + printf(" picture_coding_type=%d\n",picture_coding_type); + printf(" vbv_delay=%d\n",vbv_delay); + if (picture_coding_type==P_TYPE || picture_coding_type==B_TYPE) + { + printf(" full_pel_forward_vector=%d\n",full_pel_forward_vector); + printf(" forward_f_code =%d\n",forward_f_code); + } + if (picture_coding_type==B_TYPE) + { + printf(" full_pel_backward_vector=%d\n",full_pel_backward_vector); + printf(" backward_f_code =%d\n",backward_f_code); + } + } + } +#endif /* VERBOSE */ + +#ifdef VERIFY + verify_picture_header++; +#endif /* VERIFY */ + + Extra_Information_Byte_Count = + extra_bit_information(); + + extension_and_user_data(); + + /* update tracking information used to assist spatial scalability */ + Update_Temporal_Reference_Tacking_Data(); +} + +/* decode slice header */ + +/* ISO/IEC 13818-2 section 6.2.4 */ +int slice_header() +{ + int slice_vertical_position_extension; + int quantizer_scale_code; + int pos; + int slice_picture_id_enable = 0; + int slice_picture_id = 0; + int extra_information_slice = 0; + + pos = ld->Bitcnt; + + slice_vertical_position_extension = + (ld->MPEG2_Flag && vertical_size>2800) ? Get_Bits(3) : 0; + + if (ld->scalable_mode==SC_DP) + ld->priority_breakpoint = Get_Bits(7); + + quantizer_scale_code = Get_Bits(5); + ld->quantizer_scale = + ld->MPEG2_Flag ? (ld->q_scale_type ? Non_Linear_quantizer_scale[quantizer_scale_code] : quantizer_scale_code<<1) : quantizer_scale_code; + + /* slice_id introduced in March 1995 as part of the video corridendum + (after the IS was drafted in November 1994) */ + if (Get_Bits(1)) + { + ld->intra_slice = Get_Bits(1); + + slice_picture_id_enable = Get_Bits(1); + slice_picture_id = Get_Bits(6); + + extra_information_slice = extra_bit_information(); + } + else + ld->intra_slice = 0; + +#ifdef VERBOSE + if (Verbose_Flag>PICTURE_LAYER) + { + printf("slice header (byte %d)\n",(pos>>3)-4); + if (Verbose_Flag>SLICE_LAYER) + { + if (ld->MPEG2_Flag && vertical_size>2800) + printf(" slice_vertical_position_extension=%d\n",slice_vertical_position_extension); + + if (ld->scalable_mode==SC_DP) + printf(" priority_breakpoint=%d\n",ld->priority_breakpoint); + + printf(" quantizer_scale_code=%d\n",quantizer_scale_code); + + printf(" slice_picture_id_enable = %d\n", slice_picture_id_enable); + + if(slice_picture_id_enable) + printf(" slice_picture_id = %d\n", slice_picture_id); + + } + } +#endif /* VERBOSE */ + +#ifdef VERIFY + verify_slice_header++; +#endif /* VERIFY */ + + + return slice_vertical_position_extension; +} + + +/* decode extension and user data */ +/* ISO/IEC 13818-2 section 6.2.2.2 */ +static void extension_and_user_data() +{ + int code,ext_ID; + + next_start_code(); + + while ((code = Show_Bits(32))==EXTENSION_START_CODE || code==USER_DATA_START_CODE) + { + if (code==EXTENSION_START_CODE) + { + Flush_Buffer32(); + ext_ID = Get_Bits(4); + switch (ext_ID) + { + case SEQUENCE_EXTENSION_ID: + sequence_extension(); + break; + case SEQUENCE_DISPLAY_EXTENSION_ID: + sequence_display_extension(); + break; + case QUANT_MATRIX_EXTENSION_ID: + quant_matrix_extension(); + break; + case SEQUENCE_SCALABLE_EXTENSION_ID: + sequence_scalable_extension(); + break; + case PICTURE_DISPLAY_EXTENSION_ID: + picture_display_extension(); + break; + case PICTURE_CODING_EXTENSION_ID: + picture_coding_extension(); + break; + case PICTURE_SPATIAL_SCALABLE_EXTENSION_ID: + picture_spatial_scalable_extension(); + break; + case PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID: + picture_temporal_scalable_extension(); + break; + case COPYRIGHT_EXTENSION_ID: + copyright_extension(); + break; + default: + fprintf(stderr,"reserved extension start code ID %d\n",ext_ID); + break; + } + next_start_code(); + } + else + { +#ifdef VERBOSE + if (Verbose_Flag>NO_LAYER) + printf("user data\n"); +#endif /* VERBOSE */ + Flush_Buffer32(); + user_data(); + } + } +} + + +/* decode sequence extension */ + +/* ISO/IEC 13818-2 section 6.2.2.3 */ +static void sequence_extension() +{ + int horizontal_size_extension; + int vertical_size_extension; + int bit_rate_extension; + int vbv_buffer_size_extension; + int pos; + + /* derive bit position for trace */ +#ifdef VERBOSE + pos = ld->Bitcnt; +#endif + + ld->MPEG2_Flag = 1; + + ld->scalable_mode = SC_NONE; /* unless overwritten by sequence_scalable_extension() */ + layer_id = 0; /* unless overwritten by sequence_scalable_extension() */ + + profile_and_level_indication = Get_Bits(8); + progressive_sequence = Get_Bits(1); + chroma_format = Get_Bits(2); + horizontal_size_extension = Get_Bits(2); + vertical_size_extension = Get_Bits(2); + bit_rate_extension = Get_Bits(12); + marker_bit("sequence_extension"); + vbv_buffer_size_extension = Get_Bits(8); + low_delay = Get_Bits(1); + frame_rate_extension_n = Get_Bits(2); + frame_rate_extension_d = Get_Bits(5); + + frame_rate = frame_rate_Table[frame_rate_code] * + ((frame_rate_extension_n+1)/(frame_rate_extension_d+1)); + + /* special case for 422 profile & level must be made */ + if((profile_and_level_indication>>7) & 1) + { /* escape bit of profile_and_level_indication set */ + + /* 4:2:2 Profile @ Main Level */ + if((profile_and_level_indication&15)==5) + { + profile = PROFILE_422; + level = MAIN_LEVEL; + } + } + else + { + profile = profile_and_level_indication >> 4; /* Profile is upper nibble */ + level = profile_and_level_indication & 0xF; /* Level is lower nibble */ + } + + + horizontal_size = (horizontal_size_extension<<12) | (horizontal_size&0x0fff); + vertical_size = (vertical_size_extension<<12) | (vertical_size&0x0fff); + + + /* ISO/IEC 13818-2 does not define bit_rate_value to be composed of + * both the original bit_rate_value parsed in sequence_header() and + * the optional bit_rate_extension in sequence_extension_header(). + * However, we use it for bitstream verification purposes. + */ + + bit_rate_value += (bit_rate_extension << 18); + bit_rate = ((double) bit_rate_value) * 400.0; + vbv_buffer_size += (vbv_buffer_size_extension << 10); + +#ifdef VERBOSE + if (Verbose_Flag>NO_LAYER) + { + printf("sequence extension (byte %d)\n",(pos>>3)-4); + + if (Verbose_Flag>SEQUENCE_LAYER) + { + printf(" profile_and_level_indication=%d\n",profile_and_level_indication); + + if (profile_and_level_indication<128) + { + printf(" profile=%d, level=%d\n",profile,level); + } + + printf(" progressive_sequence=%d\n",progressive_sequence); + printf(" chroma_format=%d\n",chroma_format); + printf(" horizontal_size_extension=%d\n",horizontal_size_extension); + printf(" vertical_size_extension=%d\n",vertical_size_extension); + printf(" bit_rate_extension=%d\n",bit_rate_extension); + printf(" vbv_buffer_size_extension=%d\n",vbv_buffer_size_extension); + printf(" low_delay=%d\n",low_delay); + printf(" frame_rate_extension_n=%d\n",frame_rate_extension_n); + printf(" frame_rate_extension_d=%d\n",frame_rate_extension_d); + } + } +#endif /* VERBOSE */ + +#ifdef VERIFY + verify_sequence_extension++; +#endif /* VERIFY */ + + +} + + +/* decode sequence display extension */ + +static void sequence_display_extension() +{ + int pos; + + pos = ld->Bitcnt; + video_format = Get_Bits(3); + color_description = Get_Bits(1); + + if (color_description) + { + color_primaries = Get_Bits(8); + transfer_characteristics = Get_Bits(8); + matrix_coefficients = Get_Bits(8); + } + + display_horizontal_size = Get_Bits(14); + marker_bit("sequence_display_extension"); + display_vertical_size = Get_Bits(14); + +#ifdef VERBOSE + if (Verbose_Flag>NO_LAYER) + { + printf("sequence display extension (byte %d)\n",(pos>>3)-4); + if (Verbose_Flag>SEQUENCE_LAYER) + { + + printf(" video_format=%d\n",video_format); + printf(" color_description=%d\n",color_description); + + if (color_description) + { + printf(" color_primaries=%d\n",color_primaries); + printf(" transfer_characteristics=%d\n",transfer_characteristics); + printf(" matrix_coefficients=%d\n",matrix_coefficients); + } + printf(" display_horizontal_size=%d\n",display_horizontal_size); + printf(" display_vertical_size=%d\n",display_vertical_size); + } + } +#endif /* VERBOSE */ + +#ifdef VERIFY + verify_sequence_display_extension++; +#endif /* VERIFY */ + +} + + +/* decode quant matrix entension */ +/* ISO/IEC 13818-2 section 6.2.3.2 */ +static void quant_matrix_extension() +{ + int i; + int pos; + + pos = ld->Bitcnt; + + if((ld->load_intra_quantizer_matrix = Get_Bits(1))) + { + for (i=0; i<64; i++) + { + ld->chroma_intra_quantizer_matrix[scan[ZIG_ZAG][i]] + = ld->intra_quantizer_matrix[scan[ZIG_ZAG][i]] + = Get_Bits(8); + } + } + + if((ld->load_non_intra_quantizer_matrix = Get_Bits(1))) + { + for (i=0; i<64; i++) + { + ld->chroma_non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] + = ld->non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] + = Get_Bits(8); + } + } + + if((ld->load_chroma_intra_quantizer_matrix = Get_Bits(1))) + { + for (i=0; i<64; i++) + ld->chroma_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); + } + + if((ld->load_chroma_non_intra_quantizer_matrix = Get_Bits(1))) + { + for (i=0; i<64; i++) + ld->chroma_non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); + } + +#ifdef VERBOSE + if (Verbose_Flag>NO_LAYER) + { + printf("quant matrix extension (byte %d)\n",(pos>>3)-4); + printf(" load_intra_quantizer_matrix=%d\n", + ld->load_intra_quantizer_matrix); + printf(" load_non_intra_quantizer_matrix=%d\n", + ld->load_non_intra_quantizer_matrix); + printf(" load_chroma_intra_quantizer_matrix=%d\n", + ld->load_chroma_intra_quantizer_matrix); + printf(" load_chroma_non_intra_quantizer_matrix=%d\n", + ld->load_chroma_non_intra_quantizer_matrix); + } +#endif /* VERBOSE */ + +#ifdef VERIFY + verify_quant_matrix_extension++; +#endif /* VERIFY */ + +} + + +/* decode sequence scalable extension */ +/* ISO/IEC 13818-2 section 6.2.2.5 */ +static void sequence_scalable_extension() +{ + int pos; + + pos = ld->Bitcnt; + + /* values (without the +1 offset) of scalable_mode are defined in + Table 6-10 of ISO/IEC 13818-2 */ + ld->scalable_mode = Get_Bits(2) + 1; /* add 1 to make SC_DP != SC_NONE */ + + layer_id = Get_Bits(4); + + if (ld->scalable_mode==SC_SPAT) + { + lower_layer_prediction_horizontal_size = Get_Bits(14); + marker_bit("sequence_scalable_extension()"); + lower_layer_prediction_vertical_size = Get_Bits(14); + horizontal_subsampling_factor_m = Get_Bits(5); + horizontal_subsampling_factor_n = Get_Bits(5); + vertical_subsampling_factor_m = Get_Bits(5); + vertical_subsampling_factor_n = Get_Bits(5); + } + + if (ld->scalable_mode==SC_TEMP) + Error("temporal scalability not implemented\n"); + +#ifdef VERBOSE + if (Verbose_Flag>NO_LAYER) + { + printf("sequence scalable extension (byte %d)\n",(pos>>3)-4); + if (Verbose_Flag>SEQUENCE_LAYER) + { + printf(" scalable_mode=%d\n",ld->scalable_mode-1); + printf(" layer_id=%d\n",layer_id); + if (ld->scalable_mode==SC_SPAT) + { + printf(" lower_layer_prediction_horiontal_size=%d\n", + lower_layer_prediction_horizontal_size); + printf(" lower_layer_prediction_vertical_size=%d\n", + lower_layer_prediction_vertical_size); + printf(" horizontal_subsampling_factor_m=%d\n", + horizontal_subsampling_factor_m); + printf(" horizontal_subsampling_factor_n=%d\n", + horizontal_subsampling_factor_n); + printf(" vertical_subsampling_factor_m=%d\n", + vertical_subsampling_factor_m); + printf(" vertical_subsampling_factor_n=%d\n", + vertical_subsampling_factor_n); + } + } + } +#endif /* VERBOSE */ + +#ifdef VERIFY + verify_sequence_scalable_extension++; +#endif /* VERIFY */ + +} + + +/* decode picture display extension */ +/* ISO/IEC 13818-2 section 6.2.3.3. */ +static void picture_display_extension() +{ + int i; + int number_of_frame_center_offsets; + int pos; + + pos = ld->Bitcnt; + /* based on ISO/IEC 13818-2 section 6.3.12 + (November 1994) Picture display extensions */ + + /* derive number_of_frame_center_offsets */ + if(progressive_sequence) + { + if(repeat_first_field) + { + if(top_field_first) + number_of_frame_center_offsets = 3; + else + number_of_frame_center_offsets = 2; + } + else + { + number_of_frame_center_offsets = 1; + } + } + else + { + if(picture_structure!=FRAME_PICTURE) + { + number_of_frame_center_offsets = 1; + } + else + { + if(repeat_first_field) + number_of_frame_center_offsets = 3; + else + number_of_frame_center_offsets = 2; + } + } + + + /* now parse */ + for (i=0; iNO_LAYER) + { + printf("picture display extension (byte %d)\n",(pos>>3)-4); + if (Verbose_Flag>SEQUENCE_LAYER) + { + + for (i=0; iBitcnt; + + f_code[0][0] = Get_Bits(4); + f_code[0][1] = Get_Bits(4); + f_code[1][0] = Get_Bits(4); + f_code[1][1] = Get_Bits(4); + + intra_dc_precision = Get_Bits(2); + picture_structure = Get_Bits(2); + top_field_first = Get_Bits(1); + frame_pred_frame_dct = Get_Bits(1); + concealment_motion_vectors = Get_Bits(1); + ld->q_scale_type = Get_Bits(1); + intra_vlc_format = Get_Bits(1); + ld->alternate_scan = Get_Bits(1); + repeat_first_field = Get_Bits(1); + chroma_420_type = Get_Bits(1); + progressive_frame = Get_Bits(1); + composite_display_flag = Get_Bits(1); + + if (composite_display_flag) + { + v_axis = Get_Bits(1); + field_sequence = Get_Bits(3); + sub_carrier = Get_Bits(1); + burst_amplitude = Get_Bits(7); + sub_carrier_phase = Get_Bits(8); + } + +#ifdef VERBOSE + if (Verbose_Flag>NO_LAYER) + { + printf("picture coding extension (byte %d)\n",(pos>>3)-4); + if (Verbose_Flag>SEQUENCE_LAYER) + { + printf(" forward horizontal f_code=%d\n", f_code[0][0]); + printf(" forward vertical f_code=%d\n", f_code[0][1]); + printf(" backward horizontal f_code=%d\n", f_code[1][0]); + printf(" backward_vertical f_code=%d\n", f_code[1][1]); + printf(" intra_dc_precision=%d\n",intra_dc_precision); + printf(" picture_structure=%d\n",picture_structure); + printf(" top_field_first=%d\n",top_field_first); + printf(" frame_pred_frame_dct=%d\n",frame_pred_frame_dct); + printf(" concealment_motion_vectors=%d\n",concealment_motion_vectors); + printf(" q_scale_type=%d\n",ld->q_scale_type); + printf(" intra_vlc_format=%d\n",intra_vlc_format); + printf(" alternate_scan=%d\n",ld->alternate_scan); + printf(" repeat_first_field=%d\n",repeat_first_field); + printf(" chroma_420_type=%d\n",chroma_420_type); + printf(" progressive_frame=%d\n",progressive_frame); + printf(" composite_display_flag=%d\n",composite_display_flag); + + if (composite_display_flag) + { + printf(" v_axis=%d\n",v_axis); + printf(" field_sequence=%d\n",field_sequence); + printf(" sub_carrier=%d\n",sub_carrier); + printf(" burst_amplitude=%d\n",burst_amplitude); + printf(" sub_carrier_phase=%d\n",sub_carrier_phase); + } + } + } +#endif /* VERBOSE */ + +#ifdef VERIFY + verify_picture_coding_extension++; +#endif /* VERIFY */ +} + + +/* decode picture spatial scalable extension */ +/* ISO/IEC 13818-2 section 6.2.3.5. */ +static void picture_spatial_scalable_extension() +{ + int pos; + + pos = ld->Bitcnt; + + ld->pict_scal = 1; /* use spatial scalability in this picture */ + + lower_layer_temporal_reference = Get_Bits(10); + marker_bit("picture_spatial_scalable_extension(), first marker bit"); + lower_layer_horizontal_offset = Get_Bits(15); + if (lower_layer_horizontal_offset>=16384) + lower_layer_horizontal_offset-= 32768; + marker_bit("picture_spatial_scalable_extension(), second marker bit"); + lower_layer_vertical_offset = Get_Bits(15); + if (lower_layer_vertical_offset>=16384) + lower_layer_vertical_offset-= 32768; + spatial_temporal_weight_code_table_index = Get_Bits(2); + lower_layer_progressive_frame = Get_Bits(1); + lower_layer_deinterlaced_field_select = Get_Bits(1); + +#ifdef VERBOSE + if (Verbose_Flag>NO_LAYER) + { + printf("picture spatial scalable extension (byte %d)\n",(pos>>3)-4); + if (Verbose_Flag>SEQUENCE_LAYER) + { + printf(" lower_layer_temporal_reference=%d\n",lower_layer_temporal_reference); + printf(" lower_layer_horizontal_offset=%d\n",lower_layer_horizontal_offset); + printf(" lower_layer_vertical_offset=%d\n",lower_layer_vertical_offset); + printf(" spatial_temporal_weight_code_table_index=%d\n", + spatial_temporal_weight_code_table_index); + printf(" lower_layer_progressive_frame=%d\n",lower_layer_progressive_frame); + printf(" lower_layer_deinterlaced_field_select=%d\n",lower_layer_deinterlaced_field_select); + } + } +#endif /* VERBOSE */ + +#ifdef VERIFY + verify_picture_spatial_scalable_extension++; +#endif /* VERIFY */ + +} + + +/* decode picture temporal scalable extension + * + * not implemented + */ +/* ISO/IEC 13818-2 section 6.2.3.4. */ +static void picture_temporal_scalable_extension() +{ + Error("temporal scalability not supported\n"); + +#ifdef VERIFY + verify_picture_temporal_scalable_extension++; +#endif /* VERIFY */ +} + + +/* decode extra bit information */ +/* ISO/IEC 13818-2 section 6.2.3.4. */ +static int extra_bit_information() +{ + int Byte_Count = 0; + + while (Get_Bits1()) + { + Flush_Buffer(8); + Byte_Count++; + } + + return(Byte_Count); +} + + + +/* ISO/IEC 13818-2 section 5.3 */ +/* Purpose: this function is mainly designed to aid in bitstream conformance + testing. A simple Flush_Buffer(1) would do */ +void marker_bit(text) +char *text; +{ + int marker; + + marker = Get_Bits(1); + +#ifdef VERIFY + if(!marker) + printf("ERROR: %s--marker_bit set to 0",text); +#endif +} + + +/* ISO/IEC 13818-2 sections 6.3.4.1 and 6.2.2.2.2 */ +static void user_data() +{ + /* skip ahead to the next start code */ + next_start_code(); +} + + + +/* Copyright extension */ +/* ISO/IEC 13818-2 section 6.2.3.6. */ +/* (header added in November, 1994 to the IS document) */ + + +static void copyright_extension() +{ + int pos; + int reserved_data; + + pos = ld->Bitcnt; + + + copyright_flag = Get_Bits(1); + copyright_identifier = Get_Bits(8); + original_or_copy = Get_Bits(1); + + /* reserved */ + reserved_data = Get_Bits(7); + + marker_bit("copyright_extension(), first marker bit"); + copyright_number_1 = Get_Bits(20); + marker_bit("copyright_extension(), second marker bit"); + copyright_number_2 = Get_Bits(22); + marker_bit("copyright_extension(), third marker bit"); + copyright_number_3 = Get_Bits(22); + + if(Verbose_Flag>NO_LAYER) + { + printf("copyright_extension (byte %d)\n",(pos>>3)-4); + if (Verbose_Flag>SEQUENCE_LAYER) + { + printf(" copyright_flag =%d\n",copyright_flag); + + printf(" copyright_identifier=%d\n",copyright_identifier); + + printf(" original_or_copy = %d (original=1, copy=0)\n", + original_or_copy); + + printf(" copyright_number_1=%d\n",copyright_number_1); + printf(" copyright_number_2=%d\n",copyright_number_2); + printf(" copyright_number_3=%d\n",copyright_number_3); + } + } + +#ifdef VERIFY + verify_copyright_extension++; +#endif /* VERIFY */ +} + + + +/* introduced in September 1995 to assist Spatial Scalability */ +static void Update_Temporal_Reference_Tacking_Data() +{ + static int temporal_reference_wrap = 0; + static int temporal_reference_old = 0; + + if (ld == &base) /* *CH* */ + { + if (picture_coding_type!=B_TYPE && temporal_reference!=temporal_reference_old) + /* check first field of */ + { + /* non-B-frame */ + if (temporal_reference_wrap) + {/* wrap occured at previous I- or P-frame */ + /* now all intervening B-frames which could + still have high temporal_reference values are done */ + Temporal_Reference_Base += 1024; + temporal_reference_wrap = 0; + } + + /* distinguish from a reset */ + if (temporal_reference True_Framenum_max) ? + True_Framenum : True_Framenum_max; + } +} diff --git a/src/gdcmmpeg2/src/mpeg2dec/getpic.c b/src/gdcmmpeg2/src/mpeg2dec/getpic.c new file mode 100644 index 00000000..d75b574b --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/getpic.c @@ -0,0 +1,1225 @@ +/* getpic.c, picture decoding */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include + +#include "config.h" +#include "global.h" + +/* private prototypes*/ +static void picture_data _ANSI_ARGS_((int framenum)); +static void macroblock_modes _ANSI_ARGS_((int *pmacroblock_type, int *pstwtype, + int *pstwclass, int *pmotion_type, int *pmotion_vector_count, int *pmv_format, int *pdmv, + int *pmvscale, int *pdct_type)); +static void Clear_Block _ANSI_ARGS_((int comp)); +static void Sum_Block _ANSI_ARGS_((int comp)); +static void Saturate _ANSI_ARGS_((short *bp)); +static void Add_Block _ANSI_ARGS_((int comp, int bx, int by, + int dct_type, int addflag)); +static void Update_Picture_Buffers _ANSI_ARGS_((void)); +static void frame_reorder _ANSI_ARGS_((int bitstream_framenum, + int sequence_framenum)); +static void Decode_SNR_Macroblock _ANSI_ARGS_((int *SNRMBA, int *SNRMBAinc, + int MBA, int MBAmax, int *dct_type)); + +static void motion_compensation _ANSI_ARGS_((int MBA, int macroblock_type, + int motion_type, int PMV[2][2][2], int motion_vertical_field_select[2][2], + int dmvector[2], int stwtype, int dct_type)); + +static void skipped_macroblock _ANSI_ARGS_((int dc_dct_pred[3], + int PMV[2][2][2], int *motion_type, int motion_vertical_field_select[2][2], + int *stwtype, int *macroblock_type)); + +static int slice _ANSI_ARGS_((int framenum, int MBAmax)); + +static int start_of_slice _ANSI_ARGS_ ((int MBAmax, int *MBA, + int *MBAinc, int dc_dct_pred[3], int PMV[2][2][2])); + +static int decode_macroblock _ANSI_ARGS_((int *macroblock_type, + int *stwtype, int *stwclass, int *motion_type, int *dct_type, + int PMV[2][2][2], int dc_dct_pred[3], + int motion_vertical_field_select[2][2], int dmvector[2])); + + +/* decode one frame or field picture */ +void Decode_Picture(bitstream_framenum, sequence_framenum) +int bitstream_framenum, sequence_framenum; +{ + + if (picture_structure==FRAME_PICTURE && Second_Field) + { + /* recover from illegal number of field pictures */ + printf("odd number of field pictures\n"); + Second_Field = 0; + } + + /* IMPLEMENTATION: update picture buffer pointers */ + Update_Picture_Buffers(); + +#ifdef VERIFY + Check_Headers(bitstream_framenum, sequence_framenum); +#endif /* VERIFY */ + + /* ISO/IEC 13818-4 section 2.4.5.4 "frame buffer intercept method" */ + /* (section number based on November 1995 (Dallas) draft of the + conformance document) */ + if(Ersatz_Flag) + Substitute_Frame_Buffer(bitstream_framenum, sequence_framenum); + + /* form spatial scalable picture */ + + /* form spatial scalable picture */ + /* ISO/IEC 13818-2 section 7.7: Spatial scalability */ + if (base.pict_scal && !Second_Field) + { + Spatial_Prediction(); + } + + /* decode picture data ISO/IEC 13818-2 section 6.2.3.7 */ + picture_data(bitstream_framenum); + + /* write or display current or previously decoded reference frame */ + /* ISO/IEC 13818-2 section 6.1.1.11: Frame reordering */ + frame_reorder(bitstream_framenum, sequence_framenum); + + if (picture_structure!=FRAME_PICTURE) + Second_Field = !Second_Field; +} + + +/* decode all macroblocks of the current picture */ +/* stages described in ISO/IEC 13818-2 section 7 */ +static void picture_data(framenum) +int framenum; +{ + int MBAmax; + int ret; + + /* number of macroblocks per picture */ + MBAmax = mb_width*mb_height; + + if (picture_structure!=FRAME_PICTURE) + MBAmax>>=1; /* field picture has half as mnay macroblocks as frame */ + + for(;;) + { + if((ret=slice(framenum, MBAmax))<0) + return; + } + +} + + + +/* decode all macroblocks of the current picture */ +/* ISO/IEC 13818-2 section 6.3.16 */ +static int slice(framenum, MBAmax) +int framenum, MBAmax; +{ + int MBA; + int MBAinc, macroblock_type, motion_type, dct_type; + int dc_dct_pred[3]; + int PMV[2][2][2], motion_vertical_field_select[2][2]; + int dmvector[2]; + int stwtype, stwclass; + int SNRMBA, SNRMBAinc; + int ret; + + MBA = 0; /* macroblock address */ + MBAinc = 0; + + if((ret=start_of_slice(MBAmax, &MBA, &MBAinc, dc_dct_pred, PMV))!=1) + return(ret); + + if (Two_Streams && enhan.scalable_mode==SC_SNR) + { + SNRMBA=0; + SNRMBAinc=0; + } + + Fault_Flag=0; + + for (;;) + { + + /* this is how we properly exit out of picture */ + if (MBA>=MBAmax) + return(-1); /* all macroblocks decoded */ + +#ifdef TRACE + if (Trace_Flag) + printf("frame %d, MB %d\n",framenum,MBA); +#endif /* TRACE */ + +#ifdef DISPLAY + if (!progressive_frame && picture_structure==FRAME_PICTURE + && MBA==(MBAmax>>1) && framenum!=0 && Output_Type==T_X11 + && !Display_Progressive_Flag) + { + Display_Second_Field(); + } +#endif + + ld = &base; + + if (MBAinc==0) + { + if (base.scalable_mode==SC_DP && base.priority_breakpoint==1) + ld = &enhan; + + if (!Show_Bits(23) || Fault_Flag) /* next_start_code or fault */ + { +resync: /* if Fault_Flag: resynchronize to next next_start_code */ + Fault_Flag = 0; + return(0); /* trigger: go to next slice */ + } + else /* neither next_start_code nor Fault_Flag */ + { + if (base.scalable_mode==SC_DP && base.priority_breakpoint==1) + ld = &enhan; + + /* decode macroblock address increment */ + MBAinc = Get_macroblock_address_increment(); + + if (Fault_Flag) goto resync; + } + } + + if (MBA>=MBAmax) + { + /* MBAinc points beyond picture dimensions */ + if (!Quiet_Flag) + printf("Too many macroblocks in picture\n"); + return(-1); + } + + if (MBAinc==1) /* not skipped */ + { + ret = decode_macroblock(¯oblock_type, &stwtype, &stwclass, + &motion_type, &dct_type, PMV, dc_dct_pred, + motion_vertical_field_select, dmvector); + + if(ret==-1) + return(-1); + + if(ret==0) + goto resync; + + } + else /* MBAinc!=1: skipped macroblock */ + { + /* ISO/IEC 13818-2 section 7.6.6 */ + skipped_macroblock(dc_dct_pred, PMV, &motion_type, + motion_vertical_field_select, &stwtype, ¯oblock_type); + } + + /* SCALABILITY: SNR */ + /* ISO/IEC 13818-2 section 7.8 */ + /* NOTE: we currently ignore faults encountered in this routine */ + if (Two_Streams && enhan.scalable_mode==SC_SNR) + Decode_SNR_Macroblock(&SNRMBA, &SNRMBAinc, MBA, MBAmax, &dct_type); + + /* ISO/IEC 13818-2 section 7.6 */ + motion_compensation(MBA, macroblock_type, motion_type, PMV, + motion_vertical_field_select, dmvector, stwtype, dct_type); + + + /* advance to next macroblock */ + MBA++; + MBAinc--; + + /* SCALABILITY: SNR */ + if (Two_Streams && enhan.scalable_mode==SC_SNR) + { + SNRMBA++; + SNRMBAinc--; + } + + if (MBA>=MBAmax) + return(-1); /* all macroblocks decoded */ + } +} + + +/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */ +static void macroblock_modes(pmacroblock_type,pstwtype,pstwclass, + pmotion_type,pmotion_vector_count,pmv_format,pdmv,pmvscale,pdct_type) + int *pmacroblock_type, *pstwtype, *pstwclass; + int *pmotion_type, *pmotion_vector_count, *pmv_format, *pdmv, *pmvscale; + int *pdct_type; +{ + int macroblock_type; + int stwtype, stwcode, stwclass; + int motion_type = 0; + int motion_vector_count, mv_format, dmv, mvscale; + int dct_type; + static unsigned char stwc_table[3][4] + = { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} }; + static unsigned char stwclass_table[9] + = {0, 1, 2, 1, 1, 2, 3, 3, 4}; + + /* get macroblock_type */ + macroblock_type = Get_macroblock_type(); + + if (Fault_Flag) return; + + /* get spatial_temporal_weight_code */ + if (macroblock_type & MB_WEIGHT) + { + if (spatial_temporal_weight_code_table_index==0) + stwtype = 4; + else + { + stwcode = Get_Bits(2); +#ifdef TRACE + if (Trace_Flag) + { + printf("spatial_temporal_weight_code ("); + Print_Bits(stwcode,2,2); + printf("): %d\n",stwcode); + } +#endif /* TRACE */ + stwtype = stwc_table[spatial_temporal_weight_code_table_index-1][stwcode]; + } + } + else + stwtype = (macroblock_type & MB_CLASS4) ? 8 : 0; + + /* SCALABILITY: derive spatial_temporal_weight_class (Table 7-18) */ + stwclass = stwclass_table[stwtype]; + + /* get frame/field motion type */ + if (macroblock_type & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD)) + { + if (picture_structure==FRAME_PICTURE) /* frame_motion_type */ + { + motion_type = frame_pred_frame_dct ? MC_FRAME : Get_Bits(2); +#ifdef TRACE + if (!frame_pred_frame_dct && Trace_Flag) + { + printf("frame_motion_type ("); + Print_Bits(motion_type,2,2); + printf("): %s\n",motion_type==MC_FIELD?"Field": + motion_type==MC_FRAME?"Frame": + motion_type==MC_DMV?"Dual_Prime":"Invalid"); + } +#endif /* TRACE */ + } + else /* field_motion_type */ + { + motion_type = Get_Bits(2); +#ifdef TRACE + if (Trace_Flag) + { + printf("field_motion_type ("); + Print_Bits(motion_type,2,2); + printf("): %s\n",motion_type==MC_FIELD?"Field": + motion_type==MC_16X8?"16x8 MC": + motion_type==MC_DMV?"Dual_Prime":"Invalid"); + } +#endif /* TRACE */ + } + } + else if ((macroblock_type & MACROBLOCK_INTRA) && concealment_motion_vectors) + { + /* concealment motion vectors */ + motion_type = (picture_structure==FRAME_PICTURE) ? MC_FRAME : MC_FIELD; + } +#if 0 + else + { + printf("maroblock_modes(): unknown macroblock type\n"); + motion_type = -1; + } +#endif + + /* derive motion_vector_count, mv_format and dmv, (table 6-17, 6-18) */ + if (picture_structure==FRAME_PICTURE) + { + motion_vector_count = (motion_type==MC_FIELD && stwclass<2) ? 2 : 1; + mv_format = (motion_type==MC_FRAME) ? MV_FRAME : MV_FIELD; + } + else + { + motion_vector_count = (motion_type==MC_16X8) ? 2 : 1; + mv_format = MV_FIELD; + } + + dmv = (motion_type==MC_DMV); /* dual prime */ + + /* field mv predictions in frame pictures have to be scaled + * ISO/IEC 13818-2 section 7.6.3.1 Decoding the motion vectors + * IMPLEMENTATION: mvscale is derived for later use in motion_vectors() + * it displaces the stage: + * + * if((mv_format=="field")&&(t==1)&&(picture_structure=="Frame picture")) + * prediction = PMV[r][s][t] DIV 2; + */ + + mvscale = ((mv_format==MV_FIELD) && (picture_structure==FRAME_PICTURE)); + + /* get dct_type (frame DCT / field DCT) */ + dct_type = (picture_structure==FRAME_PICTURE) + && (!frame_pred_frame_dct) + && (macroblock_type & (MACROBLOCK_PATTERN|MACROBLOCK_INTRA)) + ? Get_Bits(1) + : 0; + +#ifdef TRACE + if (Trace_Flag && (picture_structure==FRAME_PICTURE) + && (!frame_pred_frame_dct) + && (macroblock_type & (MACROBLOCK_PATTERN|MACROBLOCK_INTRA))) + printf("dct_type (%d): %s\n",dct_type,dct_type?"Field":"Frame"); +#endif /* TRACE */ + + /* return values */ + *pmacroblock_type = macroblock_type; + *pstwtype = stwtype; + *pstwclass = stwclass; + *pmotion_type = motion_type; + *pmotion_vector_count = motion_vector_count; + *pmv_format = mv_format; + *pdmv = dmv; + *pmvscale = mvscale; + *pdct_type = dct_type; +} + + +/* move/add 8x8-Block from block[comp] to backward_reference_frame */ +/* copy reconstructed 8x8 block from block[comp] to current_frame[] + * ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data + * This stage also embodies some of the operations implied by: + * - ISO/IEC 13818-2 section 7.6.7: Combining predictions + * - ISO/IEC 13818-2 section 6.1.3: Macroblock +*/ +static void Add_Block(comp,bx,by,dct_type,addflag) +int comp,bx,by,dct_type,addflag; +{ + int cc,i, j, iincr; + unsigned char *rfp; + short *bp; + + + /* derive color component index */ + /* equivalent to ISO/IEC 13818-2 Table 7-1 */ + cc = (comp<4) ? 0 : (comp&1)+1; /* color component index */ + + if (cc==0) + { + /* luminance */ + + if (picture_structure==FRAME_PICTURE) + if (dct_type) + { + /* field DCT coding */ + rfp = current_frame[0] + + Coded_Picture_Width*(by+((comp&2)>>1)) + bx + ((comp&1)<<3); + iincr = (Coded_Picture_Width<<1) - 8; + } + else + { + /* frame DCT coding */ + rfp = current_frame[0] + + Coded_Picture_Width*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); + iincr = Coded_Picture_Width - 8; + } + else + { + /* field picture */ + rfp = current_frame[0] + + (Coded_Picture_Width<<1)*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); + iincr = (Coded_Picture_Width<<1) - 8; + } + } + else + { + /* chrominance */ + + /* scale coordinates */ + if (chroma_format!=CHROMA444) + bx >>= 1; + if (chroma_format==CHROMA420) + by >>= 1; + if (picture_structure==FRAME_PICTURE) + { + if (dct_type && (chroma_format!=CHROMA420)) + { + /* field DCT coding */ + rfp = current_frame[cc] + + Chroma_Width*(by+((comp&2)>>1)) + bx + (comp&8); + iincr = (Chroma_Width<<1) - 8; + } + else + { + /* frame DCT coding */ + rfp = current_frame[cc] + + Chroma_Width*(by+((comp&2)<<2)) + bx + (comp&8); + iincr = Chroma_Width - 8; + } + } + else + { + /* field picture */ + rfp = current_frame[cc] + + (Chroma_Width<<1)*(by+((comp&2)<<2)) + bx + (comp&8); + iincr = (Chroma_Width<<1) - 8; + } + } + + bp = ld->block[comp]; + + if (addflag) + { + for (i=0; i<8; i++) + { + for (j=0; j<8; j++) + { + *rfp = Clip[*bp++ + *rfp]; + rfp++; + } + + rfp+= iincr; + } + } + else + { + for (i=0; i<8; i++) + { + for (j=0; j<8; j++) + *rfp++ = Clip[*bp++ + 128]; + + rfp+= iincr; + } + } +} + + +/* ISO/IEC 13818-2 section 7.8 */ +static void Decode_SNR_Macroblock(SNRMBA, SNRMBAinc, MBA, MBAmax, dct_type) + int *SNRMBA, *SNRMBAinc; + int MBA, MBAmax; + int *dct_type; +{ + int SNRmacroblock_type, SNRcoded_block_pattern, SNRdct_type, dummy; + int slice_vert_pos_ext, quantizer_scale_code, comp, code; + + ld = &enhan; + + if (*SNRMBAinc==0) + { + if (!Show_Bits(23)) /* next_start_code */ + { + next_start_code(); + code = Show_Bits(32); + + if (codeSLICE_START_CODE_MAX) + { + /* only slice headers are allowed in picture_data */ + if (!Quiet_Flag) + printf("SNR: Premature end of picture\n"); + return; + } + + Flush_Buffer32(); + + /* decode slice header (may change quantizer_scale) */ + slice_vert_pos_ext = slice_header(); + + /* decode macroblock address increment */ + *SNRMBAinc = Get_macroblock_address_increment(); + + /* set current location */ + *SNRMBA = + ((slice_vert_pos_ext<<7) + (code&255) - 1)*mb_width + *SNRMBAinc - 1; + + *SNRMBAinc = 1; /* first macroblock in slice: not skipped */ + } + else /* not next_start_code */ + { + if (*SNRMBA>=MBAmax) + { + if (!Quiet_Flag) + printf("Too many macroblocks in picture\n"); + return; + } + + /* decode macroblock address increment */ + *SNRMBAinc = Get_macroblock_address_increment(); + } + } + + if (*SNRMBA!=MBA) + { + /* streams out of sync */ + if (!Quiet_Flag) + printf("Cant't synchronize streams\n"); + return; + } + + if (*SNRMBAinc==1) /* not skipped */ + { + macroblock_modes(&SNRmacroblock_type, &dummy, &dummy, + &dummy, &dummy, &dummy, &dummy, &dummy, + &SNRdct_type); + + if (SNRmacroblock_type & MACROBLOCK_PATTERN) + *dct_type = SNRdct_type; + + if (SNRmacroblock_type & MACROBLOCK_QUANT) + { + quantizer_scale_code = Get_Bits(5); + ld->quantizer_scale = + ld->q_scale_type ? Non_Linear_quantizer_scale[quantizer_scale_code] : quantizer_scale_code<<1; + } + + /* macroblock_pattern */ + if (SNRmacroblock_type & MACROBLOCK_PATTERN) + { + SNRcoded_block_pattern = Get_coded_block_pattern(); + + if (chroma_format==CHROMA422) + SNRcoded_block_pattern = (SNRcoded_block_pattern<<2) | Get_Bits(2); /* coded_block_pattern_1 */ + else if (chroma_format==CHROMA444) + SNRcoded_block_pattern = (SNRcoded_block_pattern<<6) | Get_Bits(6); /* coded_block_pattern_2 */ + } + else + SNRcoded_block_pattern = 0; + + /* decode blocks */ + for (comp=0; compblock[comp]; + + for (i=0; i<64; i++) + *Block_Ptr++ = 0; +} + + +/* SCALABILITY: add SNR enhancement layer block data to base layer */ +/* ISO/IEC 13818-2 section 7.8.3.4: Addition of coefficients from the two layes */ +static void Sum_Block(comp) +int comp; +{ + short *Block_Ptr1, *Block_Ptr2; + int i; + + Block_Ptr1 = base.block[comp]; + Block_Ptr2 = enhan.block[comp]; + + for (i=0; i<64; i++) + *Block_Ptr1++ += *Block_Ptr2++; +} + + +/* limit coefficients to -2048..2047 */ +/* ISO/IEC 13818-2 section 7.4.3 and 7.4.4: Saturation and Mismatch control */ +static void Saturate(Block_Ptr) +short *Block_Ptr; +{ + int i, sum, val; + + sum = 0; + + /* ISO/IEC 13818-2 section 7.4.3: Saturation */ + for (i=0; i<64; i++) + { + val = Block_Ptr[i]; + + if (val>2047) + val = 2047; + else if (val<-2048) + val = -2048; + + Block_Ptr[i] = val; + sum+= val; + } + + /* ISO/IEC 13818-2 section 7.4.4: Mismatch control */ + if ((sum&1)==0) + Block_Ptr[63]^= 1; + +} + + +/* reuse old picture buffers as soon as they are no longer needed + based on life-time axioms of MPEG */ +static void Update_Picture_Buffers() +{ + int cc; /* color component index */ + unsigned char *tmp; /* temporary swap pointer */ + + for (cc=0; cc<3; cc++) + { + /* B pictures do not need to be save for future reference */ + if (picture_coding_type==B_TYPE) + { + current_frame[cc] = auxframe[cc]; + } + else + { + /* only update at the beginning of the coded frame */ + if (!Second_Field) + { + tmp = forward_reference_frame[cc]; + + /* the previously decoded reference frame is stored + coincident with the location where the backward + reference frame is stored (backwards prediction is not + needed in P pictures) */ + forward_reference_frame[cc] = backward_reference_frame[cc]; + + /* update pointer for potential future B pictures */ + backward_reference_frame[cc] = tmp; + } + + /* can erase over old backward reference frame since it is not used + in a P picture, and since any subsequent B pictures will use the + previously decoded I or P frame as the backward_reference_frame */ + current_frame[cc] = backward_reference_frame[cc]; + } + + /* IMPLEMENTATION: + one-time folding of a line offset into the pointer which stores the + memory address of the current frame saves offsets and conditional + branches throughout the remainder of the picture processing loop */ + if (picture_structure==BOTTOM_FIELD) + current_frame[cc]+= (cc==0) ? Coded_Picture_Width : Chroma_Width; + } +} + + +/* store last frame */ + +void Output_Last_Frame_of_Sequence(Framenum) +int Framenum; +{ + if (Second_Field) + printf("last frame incomplete, not stored\n"); + else + Write_Frame(backward_reference_frame,Framenum-1); +} + + + +static void frame_reorder(Bitstream_Framenum, Sequence_Framenum) +int Bitstream_Framenum, Sequence_Framenum; +{ + /* tracking variables to insure proper output in spatial scalability */ + static int Oldref_progressive_frame, Newref_progressive_frame; + + if (Sequence_Framenum!=0) + { + if (picture_structure==FRAME_PICTURE || Second_Field) + { + if (picture_coding_type==B_TYPE) + Write_Frame(auxframe,Bitstream_Framenum-1); + else + { + Newref_progressive_frame = progressive_frame; + progressive_frame = Oldref_progressive_frame; + + Write_Frame(forward_reference_frame,Bitstream_Framenum-1); + + Oldref_progressive_frame = progressive_frame = Newref_progressive_frame; + } + } +#ifdef DISPLAY + else if (Output_Type==T_X11) + { + if(!Display_Progressive_Flag) + Display_Second_Field(); + } +#endif + } + else + Oldref_progressive_frame = progressive_frame; + +} + + +/* ISO/IEC 13818-2 section 7.6 */ +static void motion_compensation(MBA, macroblock_type, motion_type, PMV, + motion_vertical_field_select, dmvector, stwtype, dct_type) +int MBA; +int macroblock_type; +int motion_type; +int PMV[2][2][2]; +int motion_vertical_field_select[2][2]; +int dmvector[2]; +int stwtype; +int dct_type; +{ + int bx, by; + int comp; + + /* derive current macroblock position within picture */ + /* ISO/IEC 13818-2 section 6.3.1.6 and 6.3.1.7 */ + bx = 16*(MBA%mb_width); + by = 16*(MBA/mb_width); + + /* motion compensation */ + if (!(macroblock_type & MACROBLOCK_INTRA)) + form_predictions(bx,by,macroblock_type,motion_type,PMV, + motion_vertical_field_select,dmvector,stwtype); + + /* SCALABILITY: Data Partitioning */ + if (base.scalable_mode==SC_DP) + ld = &base; + + /* copy or add block data into picture */ + for (comp=0; compMPEG2_Flag) + Saturate(ld->block[comp]); + + /* ISO/IEC 13818-2 section Annex A: inverse DCT */ + if (Reference_IDCT_Flag) + Reference_IDCT(ld->block[comp]); + else + Fast_IDCT(ld->block[comp]); + + /* ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data */ + Add_Block(comp,bx,by,dct_type,(macroblock_type & MACROBLOCK_INTRA)==0); + } + +} + + + +/* ISO/IEC 13818-2 section 7.6.6 */ +static void skipped_macroblock(dc_dct_pred, PMV, motion_type, + motion_vertical_field_select, stwtype, macroblock_type) +int dc_dct_pred[3]; +int PMV[2][2][2]; +int *motion_type; +int motion_vertical_field_select[2][2]; +int *stwtype; +int *macroblock_type; +{ + int comp; + + /* SCALABILITY: Data Paritioning */ + if (base.scalable_mode==SC_DP) + ld = &base; + + for (comp=0; compSLICE_START_CODE_MAX) + { + /* only slice headers are allowed in picture_data */ + if (!Quiet_Flag) + printf("start_of_slice(): Premature end of picture\n"); + + return(-1); /* trigger: go to next picture */ + } + + Flush_Buffer32(); + + /* decode slice header (may change quantizer_scale) */ + slice_vert_pos_ext = slice_header(); + + + /* SCALABILITY: Data Partitioning */ + if (base.scalable_mode==SC_DP) + { + ld = &enhan; + next_start_code(); + code = Show_Bits(32); + + if (codeSLICE_START_CODE_MAX) + { + /* only slice headers are allowed in picture_data */ + if (!Quiet_Flag) + printf("DP: Premature end of picture\n"); + return(-1); /* trigger: go to next picture */ + } + + Flush_Buffer32(); + + /* decode slice header (may change quantizer_scale) */ + slice_vert_pos_ext = slice_header(); + + if (base.priority_breakpoint!=1) + ld = &base; + } + + /* decode macroblock address increment */ + *MBAinc = Get_macroblock_address_increment(); + + if (Fault_Flag) + { + printf("start_of_slice(): MBAinc unsuccessful\n"); + return(0); /* trigger: go to next slice */ + } + + /* set current location */ + /* NOTE: the arithmetic used to derive macroblock_address below is + * equivalent to ISO/IEC 13818-2 section 6.3.17: Macroblock + */ + *MBA = ((slice_vert_pos_ext<<7) + (code&255) - 1)*mb_width + *MBAinc - 1; + *MBAinc = 1; /* first macroblock in slice: not skipped */ + + /* reset all DC coefficient and motion vector predictors */ + /* reset all DC coefficient and motion vector predictors */ + /* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */ + dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; + + /* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */ + PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; + PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0; + + /* successfull: trigger decode macroblocks in slice */ + return(1); +} + + +/* ISO/IEC 13818-2 sections 7.2 through 7.5 */ +static int decode_macroblock(macroblock_type, stwtype, stwclass, + motion_type, dct_type, PMV, dc_dct_pred, + motion_vertical_field_select, dmvector) +int *macroblock_type; +int *stwtype; +int *stwclass; +int *motion_type; +int *dct_type; +int PMV[2][2][2]; +int dc_dct_pred[3]; +int motion_vertical_field_select[2][2]; +int dmvector[2]; +{ + /* locals */ + int quantizer_scale_code; + int comp; + + int motion_vector_count; + int mv_format; + int dmv; + int mvscale; + int coded_block_pattern; + + /* SCALABILITY: Data Patitioning */ + if (base.scalable_mode==SC_DP) + { + if (base.priority_breakpoint<=2) + ld = &enhan; + else + ld = &base; + } + + /* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */ + macroblock_modes(macroblock_type, stwtype, stwclass, + motion_type, &motion_vector_count, &mv_format, &dmv, &mvscale, + dct_type); + + if (Fault_Flag) return(0); /* trigger: go to next slice */ + + if (*macroblock_type & MACROBLOCK_QUANT) + { + quantizer_scale_code = Get_Bits(5); + +#ifdef TRACE + if (Trace_Flag) + { + printf("quantiser_scale_code ("); + Print_Bits(quantizer_scale_code,5,5); + printf("): %d\n",quantizer_scale_code); + } +#endif /* TRACE */ + + /* ISO/IEC 13818-2 section 7.4.2.2: Quantizer scale factor */ + if (ld->MPEG2_Flag) + ld->quantizer_scale = + ld->q_scale_type ? Non_Linear_quantizer_scale[quantizer_scale_code] + : (quantizer_scale_code << 1); + else + ld->quantizer_scale = quantizer_scale_code; + + /* SCALABILITY: Data Partitioning */ + if (base.scalable_mode==SC_DP) + /* make sure base.quantizer_scale is valid */ + base.quantizer_scale = ld->quantizer_scale; + } + + /* motion vectors */ + + + /* ISO/IEC 13818-2 section 6.3.17.2: Motion vectors */ + + /* decode forward motion vectors */ + if ((*macroblock_type & MACROBLOCK_MOTION_FORWARD) + || ((*macroblock_type & MACROBLOCK_INTRA) + && concealment_motion_vectors)) + { + if (ld->MPEG2_Flag) + motion_vectors(PMV,dmvector,motion_vertical_field_select, + 0,motion_vector_count,mv_format,f_code[0][0]-1,f_code[0][1]-1, + dmv,mvscale); + else + motion_vector(PMV[0][0],dmvector, + forward_f_code-1,forward_f_code-1,0,0,full_pel_forward_vector); + } + + if (Fault_Flag) return(0); /* trigger: go to next slice */ + + /* decode backward motion vectors */ + if (*macroblock_type & MACROBLOCK_MOTION_BACKWARD) + { + if (ld->MPEG2_Flag) + motion_vectors(PMV,dmvector,motion_vertical_field_select, + 1,motion_vector_count,mv_format,f_code[1][0]-1,f_code[1][1]-1,0, + mvscale); + else + motion_vector(PMV[0][1],dmvector, + backward_f_code-1,backward_f_code-1,0,0,full_pel_backward_vector); + } + + if (Fault_Flag) return(0); /* trigger: go to next slice */ + + if ((*macroblock_type & MACROBLOCK_INTRA) && concealment_motion_vectors) + Flush_Buffer(1); /* remove marker_bit */ + + if (base.scalable_mode==SC_DP && base.priority_breakpoint==3) + ld = &enhan; + + /* macroblock_pattern */ + /* ISO/IEC 13818-2 section 6.3.17.4: Coded block pattern */ + if (*macroblock_type & MACROBLOCK_PATTERN) + { + coded_block_pattern = Get_coded_block_pattern(); + + if (chroma_format==CHROMA422) + { + /* coded_block_pattern_1 */ + coded_block_pattern = (coded_block_pattern<<2) | Get_Bits(2); + +#ifdef TRACE + if (Trace_Flag) + { + printf("coded_block_pattern_1: "); + Print_Bits(coded_block_pattern,2,2); + printf(" (%d)\n",coded_block_pattern&3); + } +#endif /* TRACE */ + } + else if (chroma_format==CHROMA444) + { + /* coded_block_pattern_2 */ + coded_block_pattern = (coded_block_pattern<<6) | Get_Bits(6); + +#ifdef TRACE + if (Trace_Flag) + { + printf("coded_block_pattern_2: "); + Print_Bits(coded_block_pattern,6,6); + printf(" (%d)\n",coded_block_pattern&63); + } +#endif /* TRACE */ + } + } + else + coded_block_pattern = (*macroblock_type & MACROBLOCK_INTRA) ? + (1<MPEG2_Flag) + Decode_MPEG2_Intra_Block(comp,dc_dct_pred); + else + Decode_MPEG1_Intra_Block(comp,dc_dct_pred); + } + else + { + if (ld->MPEG2_Flag) + Decode_MPEG2_Non_Intra_Block(comp); + else + Decode_MPEG1_Non_Intra_Block(comp); + } + + if (Fault_Flag) return(0); /* trigger: go to next slice */ + } + } + + if(picture_coding_type==D_TYPE) + { + /* remove end_of_macroblock (always 1, prevents startcode emulation) */ + /* ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */ + marker_bit("D picture end_of_macroblock bit"); + } + + /* reset intra_dc predictors */ + /* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */ + if (!(*macroblock_type & MACROBLOCK_INTRA)) + dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; + + /* reset motion vector predictors */ + if ((*macroblock_type & MACROBLOCK_INTRA) && !concealment_motion_vectors) + { + /* intra mb without concealment motion vectors */ + /* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */ + PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; + PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0; + } + + /* special "No_MC" macroblock_type case */ + /* ISO/IEC 13818-2 section 7.6.3.5: Prediction in P pictures */ + if ((picture_coding_type==P_TYPE) + && !(*macroblock_type & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_INTRA))) + { + /* non-intra mb without forward mv in a P picture */ + /* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */ + PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; + + /* derive motion_type */ + /* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes, frame_motion_type */ + if (picture_structure==FRAME_PICTURE) + *motion_type = MC_FRAME; + else + { + *motion_type = MC_FIELD; + /* predict from field of same parity */ + motion_vertical_field_select[0][0] = (picture_structure==BOTTOM_FIELD); + } + } + + if (*stwclass==4) + { + /* purely spatially predicted macroblock */ + /* ISO/IEC 13818-2 section 7.7.5.1: Resetting motion vector predictions */ + PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; + PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0; + } + + /* successfully decoded macroblock */ + return(1); + +} /* decode_macroblock */ + + diff --git a/src/gdcmmpeg2/src/mpeg2dec/getvlc.c b/src/gdcmmpeg2/src/mpeg2dec/getvlc.c new file mode 100644 index 00000000..0b019246 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/getvlc.c @@ -0,0 +1,799 @@ +/* getvlc.c, variable length decoding */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include + +#include "config.h" +#include "global.h" +#include "getvlc.h" + +/* private prototypes */ +/* generic picture macroblock type processing functions */ +static int Get_I_macroblock_type _ANSI_ARGS_((void)); +static int Get_P_macroblock_type _ANSI_ARGS_((void)); +static int Get_B_macroblock_type _ANSI_ARGS_((void)); +static int Get_D_macroblock_type _ANSI_ARGS_((void)); + +/* spatial picture macroblock type processing functions */ +static int Get_I_Spatial_macroblock_type _ANSI_ARGS_((void)); +static int Get_P_Spatial_macroblock_type _ANSI_ARGS_((void)); +static int Get_B_Spatial_macroblock_type _ANSI_ARGS_((void)); +static int Get_SNR_macroblock_type _ANSI_ARGS_((void)); + +int Get_macroblock_type() +{ + int macroblock_type = 0; + + if (ld->scalable_mode==SC_SNR) + macroblock_type = Get_SNR_macroblock_type(); + else + { + switch (picture_coding_type) + { + case I_TYPE: + macroblock_type = ld->pict_scal ? Get_I_Spatial_macroblock_type() : Get_I_macroblock_type(); + break; + case P_TYPE: + macroblock_type = ld->pict_scal ? Get_P_Spatial_macroblock_type() : Get_P_macroblock_type(); + break; + case B_TYPE: + macroblock_type = ld->pict_scal ? Get_B_Spatial_macroblock_type() : Get_B_macroblock_type(); + break; + case D_TYPE: + macroblock_type = Get_D_macroblock_type(); + break; + default: + printf("Get_macroblock_type(): unrecognized picture coding type\n"); + break; + } + } + + return macroblock_type; +} + +static int Get_I_macroblock_type() +{ +#ifdef TRACE + if (Trace_Flag) + printf("macroblock_type(I) "); +#endif /* TRACE */ + + if (Get_Bits1()) + { +#ifdef TRACE + if (Trace_Flag) + printf("(1): Intra (1)\n"); +#endif /* TRACE */ + return 1; + } + + if (!Get_Bits1()) + { + if (!Quiet_Flag) + printf("Invalid macroblock_type code\n"); + Fault_Flag = 1; + } + +#ifdef TRACE + if (Trace_Flag) + printf("(01): Intra, Quant (17)\n"); +#endif /* TRACE */ + + return 17; +} + +static char *MBdescr[]={ + "", "Intra", "No MC, Coded", "", + "Bwd, Not Coded", "", "Bwd, Coded", "", + "Fwd, Not Coded", "", "Fwd, Coded", "", + "Interp, Not Coded", "", "Interp, Coded", "", + "", "Intra, Quant", "No MC, Coded, Quant", "", + "", "", "Bwd, Coded, Quant", "", + "", "", "Fwd, Coded, Quant", "", + "", "", "Interp, Coded, Quant", "" +}; + +static int Get_P_macroblock_type() +{ + int code; + +#ifdef TRACE + if (Trace_Flag) + printf("macroblock_type(P) ("); +#endif /* TRACE */ + + if ((code = Show_Bits(6))>=8) + { + code >>= 3; + Flush_Buffer(PMBtab0[code].len); +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,3,PMBtab0[code].len); + printf("): %s (%d)\n",MBdescr[(int)PMBtab0[code].val],PMBtab0[code].val); + } +#endif /* TRACE */ + return PMBtab0[code].val; + } + + if (code==0) + { + if (!Quiet_Flag) + printf("Invalid macroblock_type code\n"); + Fault_Flag = 1; + return 0; + } + + Flush_Buffer(PMBtab1[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,6,PMBtab1[code].len); + printf("): %s (%d)\n",MBdescr[(int)PMBtab1[code].val],PMBtab1[code].val); + } +#endif /* TRACE */ + + return PMBtab1[code].val; +} + +static int Get_B_macroblock_type() +{ + int code; + +#ifdef TRACE + if (Trace_Flag) + printf("macroblock_type(B) ("); +#endif /* TRACE */ + + if ((code = Show_Bits(6))>=8) + { + code >>= 2; + Flush_Buffer(BMBtab0[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,4,BMBtab0[code].len); + printf("): %s (%d)\n",MBdescr[(int)BMBtab0[code].val],BMBtab0[code].val); + } +#endif /* TRACE */ + + return BMBtab0[code].val; + } + + if (code==0) + { + if (!Quiet_Flag) + printf("Invalid macroblock_type code\n"); + Fault_Flag = 1; + return 0; + } + + Flush_Buffer(BMBtab1[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,6,BMBtab1[code].len); + printf("): %s (%d)\n",MBdescr[(int)BMBtab1[code].val],BMBtab1[code].val); + } +#endif /* TRACE */ + + return BMBtab1[code].val; +} + +static int Get_D_macroblock_type() +{ + if (!Get_Bits1()) + { + if (!Quiet_Flag) + printf("Invalid macroblock_type code\n"); + Fault_Flag=1; + } + + return 1; +} + +/* macroblock_type for pictures with spatial scalability */ +static int Get_I_Spatial_macroblock_type() +{ + int code; + +#ifdef TRACE + if (Trace_Flag) + printf("macroblock_type(I,spat) ("); +#endif /* TRACE */ + + code = Show_Bits(4); + + if (code==0) + { + if (!Quiet_Flag) + printf("Invalid macroblock_type code\n"); + Fault_Flag = 1; + return 0; + } + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,4,spIMBtab[code].len); + printf("): %02x\n",spIMBtab[code].val); + } +#endif /* TRACE */ + + Flush_Buffer(spIMBtab[code].len); + return spIMBtab[code].val; +} + +static int Get_P_Spatial_macroblock_type() +{ + int code; + +#ifdef TRACE + if (Trace_Flag) + printf("macroblock_type(P,spat) ("); +#endif /* TRACE */ + + code = Show_Bits(7); + + if (code<2) + { + if (!Quiet_Flag) + printf("Invalid macroblock_type code\n"); + Fault_Flag = 1; + return 0; + } + + if (code>=16) + { + code >>= 3; + Flush_Buffer(spPMBtab0[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,4,spPMBtab0[code].len); + printf("): %02x\n",spPMBtab0[code].val); + } +#endif /* TRACE */ + + return spPMBtab0[code].val; + } + + Flush_Buffer(spPMBtab1[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,7,spPMBtab1[code].len); + printf("): %02x\n",spPMBtab1[code].val); + } +#endif /* TRACE */ + + return spPMBtab1[code].val; +} + +static int Get_B_Spatial_macroblock_type() +{ + int code; + VLCtab *p; + +#ifdef TRACE + if (Trace_Flag) + printf("macroblock_type(B,spat) ("); +#endif /* TRACE */ + + code = Show_Bits(9); + + if (code>=64) + p = &spBMBtab0[(code>>5)-2]; + else if (code>=16) + p = &spBMBtab1[(code>>2)-4]; + else if (code>=8) + p = &spBMBtab2[code-8]; + else + { + if (!Quiet_Flag) + printf("Invalid macroblock_type code\n"); + Fault_Flag = 1; + return 0; + } + + Flush_Buffer(p->len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,9,p->len); + printf("): %02x\n",p->val); + } +#endif /* TRACE */ + + return p->val; +} + +static int Get_SNR_macroblock_type() +{ + int code; + +#ifdef TRACE /* *CH* */ + if (Trace_Flag) + printf("macroblock_type(SNR) ("); +#endif TRACE + + code = Show_Bits(3); + + if (code==0) + { + if (!Quiet_Flag) + printf("Invalid macroblock_type code\n"); + Fault_Flag = 1; + return 0; + } + + Flush_Buffer(SNRMBtab[code].len); + +#ifdef TRACE /* *CH* */ + if (Trace_Flag) + { + Print_Bits(code,3,SNRMBtab[code].len); + printf("): %s (%d)\n",MBdescr[(int)SNRMBtab[code].val],SNRMBtab[code].val); + } +#endif TRACE + + + return SNRMBtab[code].val; +} + +int Get_motion_code() +{ + int code; + +#ifdef TRACE + if (Trace_Flag) + printf("motion_code ("); +#endif /* TRACE */ + + if (Get_Bits1()) + { +#ifdef TRACE + if (Trace_Flag) + printf("0): 0\n"); +#endif /* TRACE */ + return 0; + } + + if ((code = Show_Bits(9))>=64) + { + code >>= 6; + Flush_Buffer(MVtab0[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,3,MVtab0[code].len); + printf("%d): %d\n", + Show_Bits(1),Show_Bits(1)?-MVtab0[code].val:MVtab0[code].val); + } +#endif /* TRACE */ + + return Get_Bits1()?-MVtab0[code].val:MVtab0[code].val; + } + + if (code>=24) + { + code >>= 3; + Flush_Buffer(MVtab1[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,6,MVtab1[code].len); + printf("%d): %d\n", + Show_Bits(1),Show_Bits(1)?-MVtab1[code].val:MVtab1[code].val); + } +#endif /* TRACE */ + + return Get_Bits1()?-MVtab1[code].val:MVtab1[code].val; + } + + if ((code-=12)<0) + { + if (!Quiet_Flag) +/* HACK */ + printf("Invalid motion_vector code (MBA %d, pic %d)\n", global_MBA, global_pic); + Fault_Flag=1; + return 0; + } + + Flush_Buffer(MVtab2[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code+12,9,MVtab2[code].len); + printf("%d): %d\n", + Show_Bits(1),Show_Bits(1)?-MVtab2[code].val:MVtab2[code].val); + } +#endif /* TRACE */ + + return Get_Bits1() ? -MVtab2[code].val : MVtab2[code].val; +} + +/* get differential motion vector (for dual prime prediction) */ +int Get_dmvector() +{ +#ifdef TRACE + if (Trace_Flag) + printf("dmvector ("); +#endif /* TRACE */ + + if (Get_Bits(1)) + { +#ifdef TRACE + if (Trace_Flag) + printf(Show_Bits(1) ? "11): -1\n" : "10): 1\n"); +#endif /* TRACE */ + return Get_Bits(1) ? -1 : 1; + } + else + { +#ifdef TRACE + if (Trace_Flag) + printf("0): 0\n"); +#endif /* TRACE */ + return 0; + } +} + +int Get_coded_block_pattern() +{ + int code; + +#ifdef TRACE + if (Trace_Flag) + printf("coded_block_pattern_420 ("); +#endif /* TRACE */ + + if ((code = Show_Bits(9))>=128) + { + code >>= 4; + Flush_Buffer(CBPtab0[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,5,CBPtab0[code].len); + printf("): "); + Print_Bits(CBPtab0[code].val,6,6); + printf(" (%d)\n",CBPtab0[code].val); + } +#endif /* TRACE */ + + return CBPtab0[code].val; + } + + if (code>=8) + { + code >>= 1; + Flush_Buffer(CBPtab1[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,8,CBPtab1[code].len); + printf("): "); + Print_Bits(CBPtab1[code].val,6,6); + printf(" (%d)\n",CBPtab1[code].val); + } +#endif /* TRACE */ + + return CBPtab1[code].val; + } + + if (code<1) + { + if (!Quiet_Flag) + printf("Invalid coded_block_pattern code\n"); + Fault_Flag = 1; + return 0; + } + + Flush_Buffer(CBPtab2[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,9,CBPtab2[code].len); + printf("): "); + Print_Bits(CBPtab2[code].val,6,6); + printf(" (%d)\n",CBPtab2[code].val); + } +#endif /* TRACE */ + + return CBPtab2[code].val; +} + +int Get_macroblock_address_increment() +{ + int code, val; + +#ifdef TRACE + if (Trace_Flag) + printf("macroblock_address_increment ("); +#endif /* TRACE */ + + val = 0; + + while ((code = Show_Bits(11))<24) + { + if (code!=15) /* if not macroblock_stuffing */ + { + if (code==8) /* if macroblock_escape */ + { +#ifdef TRACE + if (Trace_Flag) + printf("00000001000 "); +#endif /* TRACE */ + + val+= 33; + } + else + { + if (!Quiet_Flag) + printf("Invalid macroblock_address_increment code\n"); + + Fault_Flag = 1; + return 1; + } + } + else /* macroblock suffing */ + { +#ifdef TRACE + if (Trace_Flag) + printf("00000001111 "); +#endif /* TRACE */ + } + + Flush_Buffer(11); + } + + /* macroblock_address_increment == 1 */ + /* ('1' is in the MSB position of the lookahead) */ + if (code>=1024) + { + Flush_Buffer(1); +#ifdef TRACE + if (Trace_Flag) + printf("1): %d\n",val+1); +#endif /* TRACE */ + return val + 1; + } + + /* codes 00010 ... 011xx */ + if (code>=128) + { + /* remove leading zeros */ + code >>= 6; + Flush_Buffer(MBAtab1[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code,5,MBAtab1[code].len); + printf("): %d\n",val+MBAtab1[code].val); + } +#endif /* TRACE */ + + + return val + MBAtab1[code].val; + } + + /* codes 00000011000 ... 0000111xxxx */ + code-= 24; /* remove common base */ + Flush_Buffer(MBAtab2[code].len); + +#ifdef TRACE + if (Trace_Flag) + { + Print_Bits(code+24,11,MBAtab2[code].len); + printf("): %d\n",val+MBAtab2[code].val); + } +#endif /* TRACE */ + + return val + MBAtab2[code].val; +} + +/* combined MPEG-1 and MPEG-2 stage. parse VLC and + perform dct_diff arithmetic. + + MPEG-1: ISO/IEC 11172-2 section + MPEG-2: ISO/IEC 13818-2 section 7.2.1 + + Note: the arithmetic here is presented more elegantly than + the spec, yet the results, dct_diff, are the same. +*/ + +int Get_Luma_DC_dct_diff() +{ + int code, size, dct_diff; + +#ifdef TRACE +/* + if (Trace_Flag) + printf("dct_dc_size_luminance: ("); +*/ +#endif /* TRACE */ + + /* decode length */ + code = Show_Bits(5); + + if (code<31) + { + size = DClumtab0[code].val; + Flush_Buffer(DClumtab0[code].len); +#ifdef TRACE +/* + if (Trace_Flag) + { + Print_Bits(code,5,DClumtab0[code].len); + printf("): %d",size); + } +*/ +#endif /* TRACE */ + } + else + { + code = Show_Bits(9) - 0x1f0; + size = DClumtab1[code].val; + Flush_Buffer(DClumtab1[code].len); + +#ifdef TRACE +/* + if (Trace_Flag) + { + Print_Bits(code+0x1f0,9,DClumtab1[code].len); + printf("): %d",size); + } +*/ +#endif /* TRACE */ + } + +#ifdef TRACE +/* + if (Trace_Flag) + printf(", dct_dc_differential ("); +*/ +#endif /* TRACE */ + + if (size==0) + dct_diff = 0; + else + { + dct_diff = Get_Bits(size); +#ifdef TRACE +/* + if (Trace_Flag) + Print_Bits(dct_diff,size,size); +*/ +#endif /* TRACE */ + if ((dct_diff & (1<<(size-1)))==0) + dct_diff-= (1< RGB mapping + * + * entries are {crv,cbu,cgu,cgv} + * + * crv=(255/224)*65536*(1-cr)/0.5 + * cbu=(255/224)*65536*(1-cb)/0.5 + * cgu=(255/224)*65536*(cb/cg)*(1-cb)/0.5 + * cgv=(255/224)*65536*(cr/cg)*(1-cr)/0.5 + * + * where Y=cr*R+cg*G+cb*B (cr+cg+cb=1) + */ + +/* ISO/IEC 13818-2 section 6.3.6 sequence_display_extension() */ + +EXTERN int Inverse_Table_6_9[8][4] +#ifdef GLOBAL += +{ + {117504, 138453, 13954, 34903}, /* no sequence_display_extension */ + {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */ + {104597, 132201, 25675, 53279}, /* unspecified */ + {104597, 132201, 25675, 53279}, /* reserved */ + {104448, 132798, 24759, 53109}, /* FCC */ + {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */ + {104597, 132201, 25675, 53279}, /* SMPTE 170M */ + {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */ +} +#endif +; + + + + + +/* output types (Output_Type) */ +#define T_YUV 0 +#define T_SIF 1 +#define T_TGA 2 +#define T_PPM 3 +#define T_X11 4 +#define T_X11HIQ 5 + +/* decoder operation control variables */ +EXTERN int Output_Type; +EXTERN int hiQdither; + +/* decoder operation control flags */ +EXTERN int Quiet_Flag; +EXTERN int Trace_Flag; +EXTERN int Fault_Flag; +EXTERN int Verbose_Flag; +EXTERN int Two_Streams; +EXTERN int Spatial_Flag; +EXTERN int Reference_IDCT_Flag; +EXTERN int Frame_Store_Flag; +EXTERN int System_Stream_Flag; +EXTERN int Display_Progressive_Flag; +EXTERN int Ersatz_Flag; +EXTERN int Big_Picture_Flag; +EXTERN int Verify_Flag; +EXTERN int Stats_Flag; +EXTERN int User_Data_Flag; +EXTERN int Main_Bitstream_Flag; + + +/* filenames */ +EXTERN char *Output_Picture_Filename; +EXTERN char *Substitute_Picture_Filename; +EXTERN char *Main_Bitstream_Filename; +EXTERN char *Enhancement_Layer_Bitstream_Filename; + + +/* buffers for multiuse purposes */ +EXTERN char Error_Text[256]; +EXTERN unsigned char *Clip; + +/* pointers to generic picture buffers */ +EXTERN unsigned char *backward_reference_frame[3]; +EXTERN unsigned char *forward_reference_frame[3]; + +EXTERN unsigned char *auxframe[3]; +EXTERN unsigned char *current_frame[3]; +EXTERN unsigned char *substitute_frame[3]; + + +/* pointers to scalability picture buffers */ +EXTERN unsigned char *llframe0[3]; +EXTERN unsigned char *llframe1[3]; + +EXTERN short *lltmp; +EXTERN char *Lower_Layer_Picture_Filename; + + + + +/* non-normative variables derived from normative elements */ +EXTERN int Coded_Picture_Width; +EXTERN int Coded_Picture_Height; +EXTERN int Chroma_Width; +EXTERN int Chroma_Height; +EXTERN int block_count; +EXTERN int Second_Field; +EXTERN int profile, level; + +/* normative derived variables (as per ISO/IEC 13818-2) */ +EXTERN int horizontal_size; +EXTERN int vertical_size; +EXTERN int mb_width; +EXTERN int mb_height; +EXTERN double bit_rate; +EXTERN double frame_rate; + + + +/* headers */ + +/* ISO/IEC 13818-2 section 6.2.2.1: sequence_header() */ +EXTERN int aspect_ratio_information; +EXTERN int frame_rate_code; +EXTERN int bit_rate_value; +EXTERN int vbv_buffer_size; +EXTERN int constrained_parameters_flag; + +/* ISO/IEC 13818-2 section 6.2.2.3: sequence_extension() */ +EXTERN int profile_and_level_indication; +EXTERN int progressive_sequence; +EXTERN int chroma_format; +EXTERN int low_delay; +EXTERN int frame_rate_extension_n; +EXTERN int frame_rate_extension_d; + +/* ISO/IEC 13818-2 section 6.2.2.4: sequence_display_extension() */ +EXTERN int video_format; +EXTERN int color_description; +EXTERN int color_primaries; +EXTERN int transfer_characteristics; +EXTERN int matrix_coefficients; +EXTERN int display_horizontal_size; +EXTERN int display_vertical_size; + +/* ISO/IEC 13818-2 section 6.2.3: picture_header() */ +EXTERN int temporal_reference; +EXTERN int picture_coding_type; +EXTERN int vbv_delay; +EXTERN int full_pel_forward_vector; +EXTERN int forward_f_code; +EXTERN int full_pel_backward_vector; +EXTERN int backward_f_code; + + +/* ISO/IEC 13818-2 section 6.2.3.1: picture_coding_extension() header */ +EXTERN int f_code[2][2]; +EXTERN int intra_dc_precision; +EXTERN int picture_structure; +EXTERN int top_field_first; +EXTERN int frame_pred_frame_dct; +EXTERN int concealment_motion_vectors; + +EXTERN int intra_vlc_format; + +EXTERN int repeat_first_field; + +EXTERN int chroma_420_type; +EXTERN int progressive_frame; +EXTERN int composite_display_flag; +EXTERN int v_axis; +EXTERN int field_sequence; +EXTERN int sub_carrier; +EXTERN int burst_amplitude; +EXTERN int sub_carrier_phase; + + + +/* ISO/IEC 13818-2 section 6.2.3.3: picture_display_extension() header */ +EXTERN int frame_center_horizontal_offset[3]; +EXTERN int frame_center_vertical_offset[3]; + + + +/* ISO/IEC 13818-2 section 6.2.2.5: sequence_scalable_extension() header */ +EXTERN int layer_id; +EXTERN int lower_layer_prediction_horizontal_size; +EXTERN int lower_layer_prediction_vertical_size; +EXTERN int horizontal_subsampling_factor_m; +EXTERN int horizontal_subsampling_factor_n; +EXTERN int vertical_subsampling_factor_m; +EXTERN int vertical_subsampling_factor_n; + + +/* ISO/IEC 13818-2 section 6.2.3.5: picture_spatial_scalable_extension() header */ +EXTERN int lower_layer_temporal_reference; +EXTERN int lower_layer_horizontal_offset; +EXTERN int lower_layer_vertical_offset; +EXTERN int spatial_temporal_weight_code_table_index; +EXTERN int lower_layer_progressive_frame; +EXTERN int lower_layer_deinterlaced_field_select; + + + + + + +/* ISO/IEC 13818-2 section 6.2.3.6: copyright_extension() header */ +EXTERN int copyright_flag; +EXTERN int copyright_identifier; +EXTERN int original_or_copy; +EXTERN int copyright_number_1; +EXTERN int copyright_number_2; +EXTERN int copyright_number_3; + +/* ISO/IEC 13818-2 section 6.2.2.6: group_of_pictures_header() */ +EXTERN int drop_flag; +EXTERN int hour; +EXTERN int minute; +EXTERN int sec; +EXTERN int frame; +EXTERN int closed_gop; +EXTERN int broken_link; + + + +/* layer specific variables (needed for SNR and DP scalability) */ +EXTERN struct layer_data { + /* bit input */ + int Infile; + unsigned char Rdbfr[2048]; + unsigned char *Rdptr; + unsigned char Inbfr[16]; + /* from mpeg2play */ + unsigned int Bfr; + unsigned char *Rdmax; + int Incnt; + int Bitcnt; + /* sequence header and quant_matrix_extension() */ + int intra_quantizer_matrix[64]; + int non_intra_quantizer_matrix[64]; + int chroma_intra_quantizer_matrix[64]; + int chroma_non_intra_quantizer_matrix[64]; + + int load_intra_quantizer_matrix; + int load_non_intra_quantizer_matrix; + int load_chroma_intra_quantizer_matrix; + int load_chroma_non_intra_quantizer_matrix; + + int MPEG2_Flag; + /* sequence scalable extension */ + int scalable_mode; + /* picture coding extension */ + int q_scale_type; + int alternate_scan; + /* picture spatial scalable extension */ + int pict_scal; + /* slice/macroblock */ + int priority_breakpoint; + int quantizer_scale; + int intra_slice; + short block[12][64]; +} base, enhan, *ld; + + + +#ifdef VERIFY +EXTERN int verify_sequence_header; +EXTERN int verify_group_of_pictures_header; +EXTERN int verify_picture_header; +EXTERN int verify_slice_header; +EXTERN int verify_sequence_extension; +EXTERN int verify_sequence_display_extension; +EXTERN int verify_quant_matrix_extension; +EXTERN int verify_sequence_scalable_extension; +EXTERN int verify_picture_display_extension; +EXTERN int verify_picture_coding_extension; +EXTERN int verify_picture_spatial_scalable_extension; +EXTERN int verify_picture_temporal_scalable_extension; +EXTERN int verify_copyright_extension; +#endif /* VERIFY */ + + +EXTERN int Decode_Layer; + +/* verify.c */ +#ifdef VERIFY +void Check_Headers _ANSI_ARGS_((int Bitstream_Framenum, int Sequence_Framenum)); +void Clear_Verify_Headers _ANSI_ARGS_((void)); +#endif /* VERIFY */ + + +EXTERN int global_MBA; +EXTERN int global_pic; +EXTERN int True_Framenum; diff --git a/src/gdcmmpeg2/src/mpeg2dec/idct.c b/src/gdcmmpeg2/src/mpeg2dec/idct.c new file mode 100644 index 00000000..f8aeb833 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/idct.c @@ -0,0 +1,211 @@ +/* idct.c, inverse fast discrete cosine transform */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +/**********************************************************/ +/* 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" + +#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) */ + +/* global declarations */ +void Initialize_Fast_IDCT _ANSI_ARGS_((void)); +void Fast_IDCT _ANSI_ARGS_((short *block)); + +/* private data */ +static short iclip[1024]; /* clipping table */ +static short *iclp; + +/* private prototypes */ +static void idctrow _ANSI_ARGS_((short *blk)); +static void idctcol _ANSI_ARGS_((short *blk)); + +/* 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 idctrow(blk) +short *blk; +{ + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + /* shortcut */ + if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) | + (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3]))) + { + blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3; + return; + } + + x0 = (blk[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 */ + blk[0] = (x7+x1)>>8; + blk[1] = (x3+x2)>>8; + blk[2] = (x0+x4)>>8; + blk[3] = (x8+x6)>>8; + blk[4] = (x8-x6)>>8; + blk[5] = (x0-x4)>>8; + blk[6] = (x3-x2)>>8; + blk[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 idctcol(blk) +short *blk; +{ + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + /* shortcut */ + if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) | + (x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3]))) + { + blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]= + iclp[(blk[8*0]+32)>>6]; + return; + } + + x0 = (blk[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 */ + blk[8*0] = iclp[(x7+x1)>>14]; + blk[8*1] = iclp[(x3+x2)>>14]; + blk[8*2] = iclp[(x0+x4)>>14]; + blk[8*3] = iclp[(x8+x6)>>14]; + blk[8*4] = iclp[(x8-x6)>>14]; + blk[8*5] = iclp[(x0-x4)>>14]; + blk[8*6] = iclp[(x3-x2)>>14]; + blk[8*7] = iclp[(x7-x1)>>14]; +} + +/* two dimensional inverse discrete cosine transform */ +void Fast_IDCT(block) +short *block; +{ + int i; + + for (i=0; i<8; i++) + idctrow(block+8*i); + + for (i=0; i<8; i++) + idctcol(block+i); +} + +void Initialize_Fast_IDCT() +{ + int i; + + iclp = iclip+512; + for (i= -512; i<512; i++) + iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i); +} diff --git a/src/gdcmmpeg2/src/mpeg2dec/idctref.c b/src/gdcmmpeg2/src/mpeg2dec/idctref.c new file mode 100644 index 00000000..51a60091 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/idctref.c @@ -0,0 +1,108 @@ +/* Reference_IDCT.c, Inverse Discrete Fourier Transform, double precision */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +/* Perform IEEE 1180 reference (64-bit floating point, separable 8x1 + * direct matrix multiply) Inverse Discrete Cosine Transform +*/ + + +/* Here we use math.h to generate constants. Compiler results may + vary a little */ + +#include + +#include "config.h" + +#ifndef PI +# ifdef M_PI +# define PI M_PI +# else +# define PI 3.14159265358979323846 +# endif +#endif + +/* global declarations */ +void Initialize_Fast_IDCTref _ANSI_ARGS_((void)); +void Reference_IDCT _ANSI_ARGS_((short *block)); + +/* private data */ + +/* cosine transform matrix for 8x1 IDCT */ +static double c[8][8]; + +/* initialize DCT coefficient matrix */ + +void Initialize_Reference_IDCT() +{ + int freq, time; + double scale; + + for (freq=0; freq < 8; freq++) + { + scale = (freq == 0) ? sqrt(0.125) : 0.5; + for (time=0; time<8; time++) + c[freq][time] = scale*cos((PI/8.0)*freq*(time + 0.5)); + } +} + +/* perform IDCT matrix multiply for 8x8 coefficient block */ + +void Reference_IDCT(block) +short *block; +{ + int i, j, k, v; + double partial_product; + double tmp[64]; + + for (i=0; i<8; i++) + for (j=0; j<8; j++) + { + partial_product = 0.0; + + for (k=0; k<8; k++) + partial_product+= c[k][j]*block[8*i+k]; + + tmp[8*i+j] = partial_product; + } + + /* Transpose operation is integrated into address mapping by switching + loop order of i and j */ + + for (j=0; j<8; j++) + for (i=0; i<8; i++) + { + partial_product = 0.0; + + for (k=0; k<8; k++) + partial_product+= c[k][i]*tmp[8*k+j]; + + v = (int) floor(partial_product+0.5); + block[8*i+j] = (v<-256) ? -256 : ((v>255) ? 255 : v); + } +} diff --git a/src/gdcmmpeg2/src/mpeg2dec/motion.c b/src/gdcmmpeg2/src/mpeg2dec/motion.c new file mode 100644 index 00000000..c0957780 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/motion.c @@ -0,0 +1,236 @@ +/* motion.c, motion vector decoding */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include + +#include "config.h" +#include "global.h" + +/* private prototypes */ +static void decode_motion_vector _ANSI_ARGS_((int *pred, int r_size, int motion_code, + int motion_residualesidual, int full_pel_vector)); + +/* ISO/IEC 13818-2 sections 6.2.5.2, 6.3.17.2, and 7.6.3: Motion vectors */ +void motion_vectors(PMV,dmvector, + motion_vertical_field_select,s,motion_vector_count,mv_format,h_r_size,v_r_size,dmv,mvscale) +int PMV[2][2][2]; +int dmvector[2]; +int motion_vertical_field_select[2][2]; +int s, motion_vector_count, mv_format, h_r_size, v_r_size, dmv, mvscale; +{ + if (motion_vector_count==1) + { + if (mv_format==MV_FIELD && !dmv) + { + motion_vertical_field_select[1][s] = motion_vertical_field_select[0][s] = Get_Bits(1); +#ifdef TRACE + if (Trace_Flag) + { + printf("motion_vertical_field_select[][%d] (%d): %d\n",s, + motion_vertical_field_select[0][s],motion_vertical_field_select[0][s]); + } +#endif /* TRACE */ + } + + motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); + + /* update other motion vector predictors */ + PMV[1][s][0] = PMV[0][s][0]; + PMV[1][s][1] = PMV[0][s][1]; + } + else + { + motion_vertical_field_select[0][s] = Get_Bits(1); +#ifdef TRACE + if (Trace_Flag) + { + printf("motion_vertical_field_select[0][%d] (%d): %d\n",s, + motion_vertical_field_select[0][s],motion_vertical_field_select[0][s]); + } +#endif /* TRACE */ + motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); + + motion_vertical_field_select[1][s] = Get_Bits(1); +#ifdef TRACE + if (Trace_Flag) + { + printf("motion_vertical_field_select[1][%d] (%d): %d\n",s, + motion_vertical_field_select[1][s],motion_vertical_field_select[1][s]); + } +#endif /* TRACE */ + motion_vector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); + } +} + +/* get and decode motion vector and differential motion vector + for one prediction */ +void motion_vector(PMV,dmvector, + h_r_size,v_r_size,dmv,mvscale,full_pel_vector) +int *PMV; +int *dmvector; +int h_r_size; +int v_r_size; +int dmv; /* MPEG-2 only: get differential motion vectors */ +int mvscale; /* MPEG-2 only: field vector in frame pic */ +int full_pel_vector; /* MPEG-1 only */ +{ + int motion_code, motion_residual; + + /* horizontal component */ + /* ISO/IEC 13818-2 Table B-10 */ + motion_code = Get_motion_code(); + + motion_residual = (h_r_size!=0 && motion_code!=0) ? Get_Bits(h_r_size) : 0; + +#ifdef TRACE + if (Trace_Flag) + { + if (h_r_size!=0 && motion_code!=0) + { + printf("motion_residual ("); + Print_Bits(motion_residual,h_r_size,h_r_size); + printf("): %d\n",motion_residual); + } + } +#endif /* TRACE */ + + + decode_motion_vector(&PMV[0],h_r_size,motion_code,motion_residual,full_pel_vector); + + if (dmv) + dmvector[0] = Get_dmvector(); + + + /* vertical component */ + motion_code = Get_motion_code(); + motion_residual = (v_r_size!=0 && motion_code!=0) ? Get_Bits(v_r_size) : 0; + +#ifdef TRACE + if (Trace_Flag) + { + if (v_r_size!=0 && motion_code!=0) + { + printf("motion_residual ("); + Print_Bits(motion_residual,v_r_size,v_r_size); + printf("): %d\n",motion_residual); + } + } +#endif /* TRACE */ + + if (mvscale) + PMV[1] >>= 1; /* DIV 2 */ + + decode_motion_vector(&PMV[1],v_r_size,motion_code,motion_residual,full_pel_vector); + + if (mvscale) + PMV[1] <<= 1; + + if (dmv) + dmvector[1] = Get_dmvector(); + +#ifdef TRACE + if (Trace_Flag) + printf("PMV = %d,%d\n",PMV[0],PMV[1]); +#endif /* TRACE */ +} + +/* calculate motion vector component */ +/* ISO/IEC 13818-2 section 7.6.3.1: Decoding the motion vectors */ +/* Note: the arithmetic here is more elegant than that which is shown + in 7.6.3.1. The end results (PMV[][][]) should, however, be the same. */ + +static void decode_motion_vector(pred,r_size,motion_code,motion_residual,full_pel_vector) +int *pred; +int r_size, motion_code, motion_residual; +int full_pel_vector; /* MPEG-1 (ISO/IEC 11172-1) support */ +{ + int lim, vec; + + lim = 16<> 1) : (*pred); + + if (motion_code>0) + { + vec+= ((motion_code-1)<=lim) + vec-= lim + lim; + } + else if (motion_code<0) + { + vec-= ((-motion_code-1)<0))>>1) + dmvector[0]; + DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1; + + /* vector for prediction of bottom field from top field */ + DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0]; + DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1; + } + else + { + /* vector for prediction of top field from bottom field */ + DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0]; + DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1; + + /* vector for prediction of bottom field from top field */ + DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0]; + DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1; + } + } + else + { + /* vector for prediction from field of opposite 'parity' */ + DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0]; + DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1]; + + /* correct for vertical field shift */ + if (picture_structure==TOP_FIELD) + DMV[0][1]--; + else + DMV[0][1]++; + } +} + diff --git a/src/gdcmmpeg2/src/mpeg2dec/mpeg2dec.c b/src/gdcmmpeg2/src/mpeg2dec/mpeg2dec.c new file mode 100644 index 00000000..cb213760 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/mpeg2dec.c @@ -0,0 +1,765 @@ + +/* mpeg2dec.c, main(), initialization, option processing */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include +#include +#include +#include + +#define GLOBAL +#include "config.h" +#include "global.h" + +/* private prototypes */ +static int video_sequence _ANSI_ARGS_((int *framenum)); +static int Decode_Bitstream _ANSI_ARGS_((void)); +static int Headers _ANSI_ARGS_((void)); +static void Initialize_Sequence _ANSI_ARGS_((void)); +static void Initialize_Decoder _ANSI_ARGS_((void)); +static void Deinitialize_Sequence _ANSI_ARGS_((void)); +static void Process_Options _ANSI_ARGS_((int argc, char *argv[])); + + +#if OLD +static int Get_Val _ANSI_ARGS_((char *argv[])); +#endif + +/* #define DEBUG */ + +static void Clear_Options(); +#ifdef DEBUG +static void Print_Options(); +#endif + +int main(argc,argv) +int argc; +char *argv[]; +{ + int ret, code; + + Clear_Options(); + + /* decode command line arguments */ + Process_Options(argc,argv); + +#ifdef DEBUG + Print_Options(); +#endif + + ld = &base; /* select base layer context */ + + /* open MPEG base layer bitstream file(s) */ + /* NOTE: this is either a base layer stream or a spatial enhancement stream */ + if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0) + { + fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename); + exit(1); + } + + + if(base.Infile != 0) + { + Initialize_Buffer(); + + if(Show_Bits(8)==0x47) + { + sprintf(Error_Text,"Decoder currently does not parse transport streams\n"); + Error(Error_Text); + } + + next_start_code(); + code = Show_Bits(32); + + switch(code) + { + case SEQUENCE_HEADER_CODE: + break; + case PACK_START_CODE: + System_Stream_Flag = 1; + case VIDEO_ELEMENTARY_STREAM: + System_Stream_Flag = 1; + break; + default: + sprintf(Error_Text,"Unable to recognize stream type\n"); + Error(Error_Text); + break; + } + + lseek(base.Infile, 0l, 0); + Initialize_Buffer(); + } + + if(base.Infile!=0) + { + lseek(base.Infile, 0l, 0); + } + + Initialize_Buffer(); + + if(Two_Streams) + { + ld = &enhan; /* select enhancement layer context */ + + if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0) + { + sprintf(Error_Text,"enhancment layer bitstream file %s not found\n", + Enhancement_Layer_Bitstream_Filename); + + Error(Error_Text); + } + + Initialize_Buffer(); + ld = &base; + } + + Initialize_Decoder(); + + ret = Decode_Bitstream(); + + close(base.Infile); + + if (Two_Streams) + close(enhan.Infile); + + return 0; +} + +/* IMPLEMENTAION specific rouintes */ +static void Initialize_Decoder() +{ + int i; + + /* Clip table */ + if (!(Clip=(unsigned char *)malloc(1024))) + Error("Clip[] malloc failed\n"); + + Clip += 384; + + for (i=-384; i<640; i++) + Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i); + + /* IDCT */ + if (Reference_IDCT_Flag) + Initialize_Reference_IDCT(); + else + Initialize_Fast_IDCT(); + +} + +/* mostly IMPLEMENTAION specific rouintes */ +static void Initialize_Sequence() +{ + int cc, size; + static int Table_6_20[3] = {6,8,12}; + + /* check scalability mode of enhancement layer */ + if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP)) + Error("unsupported scalability mode\n"); + + /* force MPEG-1 parameters for proper decoder behavior */ + /* see ISO/IEC 13818-2 section D.9.14 */ + if (!base.MPEG2_Flag) + { + progressive_sequence = 1; + progressive_frame = 1; + picture_structure = FRAME_PICTURE; + frame_pred_frame_dct = 1; + chroma_format = CHROMA420; + matrix_coefficients = 5; + } + + /* round to nearest multiple of coded macroblocks */ + /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */ + mb_width = (horizontal_size+15)/16; + mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32) + : (vertical_size+15)/16; + + Coded_Picture_Width = 16*mb_width; + Coded_Picture_Height = 16*mb_height; + + /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */ + Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width + : Coded_Picture_Width>>1; + Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height + : Coded_Picture_Height>>1; + + /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */ + block_count = Table_6_20[chroma_format-1]; + + for (cc=0; cc<3; cc++) + { + if (cc==0) + size = Coded_Picture_Width*Coded_Picture_Height; + else + size = Chroma_Width*Chroma_Height; + + if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size))) + Error("backward_reference_frame[] malloc failed\n"); + + if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size))) + Error("forward_reference_frame[] malloc failed\n"); + + if (!(auxframe[cc] = (unsigned char *)malloc(size))) + Error("auxframe[] malloc failed\n"); + + if(Ersatz_Flag) + if (!(substitute_frame[cc] = (unsigned char *)malloc(size))) + Error("substitute_frame[] malloc failed\n"); + + + if (base.scalable_mode==SC_SPAT) + { + /* this assumes lower layer is 4:2:0 */ + if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1)))) + Error("llframe0 malloc failed\n"); + if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1)))) + Error("llframe1 malloc failed\n"); + } + } + + /* SCALABILITY: Spatial */ + if (base.scalable_mode==SC_SPAT) + { + if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short)))) + Error("lltmp malloc failed\n"); + } + +#ifdef DISPLAY + if (Output_Type==T_X11) + { + Initialize_Display_Process(""); + Initialize_Dither_Matrix(); + } +#endif /* DISPLAY */ + +} + +void Error(text) +char *text; +{ + fprintf(stderr,text); + exit(1); +} + +/* Trace_Flag output */ +void Print_Bits(code,bits,len) +int code,bits,len; +{ + int i; + for (i=0; i>(bits-1-i))&1); +} + + + +/* option processing */ +static void Process_Options(argc,argv) +int argc; /* argument count */ +char *argv[]; /* argument vector */ +{ + int i, LastArg, NextArg; + + /* at least one argument should be present */ + if (argc<2) + { + printf("\n%s, %s\n",Version,Author); + printf("Usage: mpeg2decode {options}\n\ +Options: -b file main bitstream (base or spatial enhancement layer)\n\ + -cn file conformance report (n: level)\n\ + -e file enhancement layer bitstream (SNR or Data Partitioning)\n\ + -f store/display interlaced video in frame format\n\ + -g concatenated file format for substitution method (-x)\n\ + -in file information & statistics report (n: level)\n\ + -l file file name pattern for lower layer sequence\n\ + (for spatial scalability)\n\ + -on file output format (0:YUV 1:SIF 2:TGA 3:PPM 4:X11 5:X11HiQ)\n\ + -q disable warnings to stderr\n\ + -r use double precision reference IDCT\n\ + -t enable low level tracing to stdout\n\ + -u file print user_data to stdio or file\n\ + -vn verbose output (n: level)\n\ + -x file filename pattern of picture substitution sequence\n\n\ +File patterns: for sequential filenames, \"printf\" style, e.g. rec%%d\n\ + or rec%%d%%c for fieldwise storage\n\ +Levels: 0:none 1:sequence 2:picture 3:slice 4:macroblock 5:block\n\n\ +Example: mpeg2decode -b bitstream.mpg -f -r -o0 rec%%d\n\ + \n"); + exit(0); + } + + + Output_Type = -1; + i = 1; + + /* command-line options are proceeded by '-' */ + + while(i < argc) + { + /* check if this is the last argument */ + LastArg = ((argc-i)==1); + + /* parse ahead to see if another flag immediately follows current + argument (this is used to tell if a filename is missing) */ + if(!LastArg) + NextArg = (argv[i+1][0]=='-'); + else + NextArg = 0; + + /* second character, [1], after '-' is the switch */ + if(argv[i][0]=='-') + { + switch(toupper(argv[i][1])) + { + /* third character. [2], is the value */ + case 'B': + Main_Bitstream_Flag = 1; + + if(NextArg || LastArg) + { + printf("ERROR: -b must be followed the main bitstream filename\n"); + } + else + Main_Bitstream_Filename = argv[++i]; + + break; + + + case 'C': + +#ifdef VERIFY + Verify_Flag = atoi(&argv[i][2]); + + if((Verify_Flag < NO_LAYER) || (Verify_Flag > ALL_LAYERS)) + { + printf("ERROR: -c level (%d) out of range [%d,%d]\n", + Verify_Flag, NO_LAYER, ALL_LAYERS); + exit(ERROR); + } +#else /* VERIFY */ + printf("This program not compiled for Verify_Flag option\n"); +#endif /* VERIFY */ + break; + + case 'E': + Two_Streams = 1; /* either Data Partitioning (DP) or SNR Scalability enhancment */ + + if(NextArg || LastArg) + { + printf("ERROR: -e must be followed by filename\n"); + exit(ERROR); + } + else + Enhancement_Layer_Bitstream_Filename = argv[++i]; + + break; + + + case 'F': + Frame_Store_Flag = 1; + break; + + case 'G': + Big_Picture_Flag = 1; + break; + + + case 'I': +#ifdef VERIFY + Stats_Flag = atoi(&argv[i][2]); +#else /* VERIFY */ + printf("WARNING: This program not compiled for -i option\n"); +#endif /* VERIFY */ + break; + + case 'L': /* spatial scalability flag */ + Spatial_Flag = 1; + + if(NextArg || LastArg) + { + printf("ERROR: -l must be followed by filename\n"); + exit(ERROR); + } + else + Lower_Layer_Picture_Filename = argv[++i]; + + break; + + case 'O': + + Output_Type = atoi(&argv[i][2]); + + if((Output_Type==4) || (Output_Type==5)) + Output_Picture_Filename = ""; /* no need of filename */ + else if(NextArg || LastArg) + { + printf("ERROR: -o must be followed by filename\n"); + exit(ERROR); + } + else + /* filename is separated by space, so it becomes the next argument */ + Output_Picture_Filename = argv[++i]; + +#ifdef DISPLAY + if (Output_Type==T_X11HIQ) + { + hiQdither = 1; + Output_Type=T_X11; + } +#endif /* DISPLAY */ + break; + + case 'Q': + Quiet_Flag = 1; + break; + + case 'R': + Reference_IDCT_Flag = 1; + break; + + case 'T': +#ifdef TRACE + Trace_Flag = 1; +#else /* TRACE */ + printf("WARNING: This program not compiled for -t option\n"); +#endif /* TRACE */ + break; + + case 'U': + User_Data_Flag = 1; + + case 'V': +#ifdef VERBOSE + Verbose_Flag = atoi(&argv[i][2]); +#else /* VERBOSE */ + printf("This program not compiled for -v option\n"); +#endif /* VERBOSE */ + break; + + + case 'X': + Ersatz_Flag = 1; + + if(NextArg || LastArg) + { + printf("ERROR: -x must be followed by filename\n"); + exit(ERROR); + } + else + Substitute_Picture_Filename = argv[++i]; + + break; + + + + default: + fprintf(stderr,"undefined option -%c ignored. Exiting program\n", + argv[i][1]); + + exit(ERROR); + + } /* switch() */ + } /* if argv[i][0] == '-' */ + + i++; + + /* check for bitstream filename argument (there must always be one, at the very end + of the command line arguments */ + + } /* while() */ + + + /* options sense checking */ + + if(Main_Bitstream_Flag!=1) + { + printf("There must be a main bitstream specified (-b filename)\n"); + } + + /* force display process to show frame pictures */ + if((Output_Type==4 || Output_Type==5) && Frame_Store_Flag) + Display_Progressive_Flag = 1; + else + Display_Progressive_Flag = 0; + +#ifdef VERIFY + /* parse the bitstream, do not actually decode it completely */ + + +#if 0 + if(Output_Type==-1) + { + Decode_Layer = Verify_Flag; + printf("FYI: Decoding bitstream elements up to: %s\n", + Layer_Table[Decode_Layer]); + } + else +#endif + Decode_Layer = ALL_LAYERS; + +#endif /* VERIFY */ + + /* no output type specified */ + if(Output_Type==-1) + { + Output_Type = 9; + Output_Picture_Filename = ""; + } + + +#ifdef DISPLAY + if (Output_Type==T_X11) + { + if(Frame_Store_Flag) + Display_Progressive_Flag = 1; + else + Display_Progressive_Flag = 0; + + Frame_Store_Flag = 1; /* to avoid calling dither() twice */ + } +#endif + + +} + + +#ifdef OLD +/* + this is an old routine used to convert command line arguments + into integers +*/ +static int Get_Val(argv) +char *argv[]; +{ + int val; + + if (sscanf(argv[1]+2,"%d",&val)!=1) + return 0; + + while (isdigit(argv[1][2])) + argv[1]++; + + return val; +} +#endif + + + +static int Headers() +{ + int ret; + + ld = &base; + + + /* return when end of sequence (0) or picture + header has been parsed (1) */ + + ret = Get_Hdr(); + + + if (Two_Streams) + { + ld = &enhan; + if (Get_Hdr()!=ret && !Quiet_Flag) + fprintf(stderr,"streams out of sync\n"); + ld = &base; + } + + return ret; +} + + + +static int Decode_Bitstream() +{ + int ret; + int Bitstream_Framenum; + + Bitstream_Framenum = 0; + + for(;;) + { + +#ifdef VERIFY + Clear_Verify_Headers(); +#endif /* VERIFY */ + + ret = Headers(); + + if(ret==1) + { + ret = video_sequence(&Bitstream_Framenum); + } + else + return(ret); + } + +} + + +static void Deinitialize_Sequence() +{ + int i; + + /* clear flags */ + base.MPEG2_Flag=0; + + for(i=0;i<3;i++) + { + free(backward_reference_frame[i]); + free(forward_reference_frame[i]); + free(auxframe[i]); + + if (base.scalable_mode==SC_SPAT) + { + free(llframe0[i]); + free(llframe1[i]); + } + } + + if (base.scalable_mode==SC_SPAT) + free(lltmp); + +#ifdef DISPLAY + if (Output_Type==T_X11) + Terminate_Display_Process(); +#endif +} + + +static int video_sequence(Bitstream_Framenumber) +int *Bitstream_Framenumber; +{ + int Bitstream_Framenum; + int Sequence_Framenum; + int Return_Value; + + Bitstream_Framenum = *Bitstream_Framenumber; + Sequence_Framenum=0; + + Initialize_Sequence(); + + /* decode picture whose header has already been parsed in + Decode_Bitstream() */ + + + Decode_Picture(Bitstream_Framenum, Sequence_Framenum); + + /* update picture numbers */ + if (!Second_Field) + { + Bitstream_Framenum++; + Sequence_Framenum++; + } + + /* loop through the rest of the pictures in the sequence */ + while ((Return_Value=Headers())) + { + Decode_Picture(Bitstream_Framenum, Sequence_Framenum); + + if (!Second_Field) + { + Bitstream_Framenum++; + Sequence_Framenum++; + } + } + + /* put last frame */ + if (Sequence_Framenum!=0) + { + Output_Last_Frame_of_Sequence(Bitstream_Framenum); + } + + Deinitialize_Sequence(); + +#ifdef VERIFY + Clear_Verify_Headers(); +#endif /* VERIFY */ + + *Bitstream_Framenumber = Bitstream_Framenum; + return(Return_Value); +} + + + +static void Clear_Options() +{ + Verbose_Flag = 0; + Output_Type = 0; + Output_Picture_Filename = " "; + hiQdither = 0; + Output_Type = 0; + Frame_Store_Flag = 0; + Spatial_Flag = 0; + Lower_Layer_Picture_Filename = " "; + Reference_IDCT_Flag = 0; + Trace_Flag = 0; + Quiet_Flag = 0; + Ersatz_Flag = 0; + Substitute_Picture_Filename = " "; + Two_Streams = 0; + Enhancement_Layer_Bitstream_Filename = " "; + Big_Picture_Flag = 0; + Main_Bitstream_Flag = 0; + Main_Bitstream_Filename = " "; + Verify_Flag = 0; + Stats_Flag = 0; + User_Data_Flag = 0; +} + + +#ifdef DEBUG +static void Print_Options() +{ + + printf("Verbose_Flag = %d\n", Verbose_Flag); + printf("Output_Type = %d\n", Output_Type); + printf("Output_Picture_Filename = %s\n", Output_Picture_Filename); + printf("hiQdither = %d\n", hiQdither); + printf("Output_Type = %d\n", Output_Type); + printf("Frame_Store_Flag = %d\n", Frame_Store_Flag); + printf("Spatial_Flag = %d\n", Spatial_Flag); + printf("Lower_Layer_Picture_Filename = %s\n", Lower_Layer_Picture_Filename); + printf("Reference_IDCT_Flag = %d\n", Reference_IDCT_Flag); + printf("Trace_Flag = %d\n", Trace_Flag); + printf("Quiet_Flag = %d\n", Quiet_Flag); + printf("Ersatz_Flag = %d\n", Ersatz_Flag); + printf("Substitute_Picture_Filename = %s\n", Substitute_Picture_Filename); + printf("Two_Streams = %d\n", Two_Streams); + printf("Enhancement_Layer_Bitstream_Filename = %s\n", Enhancement_Layer_Bitstream_Filename); + printf("Big_Picture_Flag = %d\n", Big_Picture_Flag); + printf("Main_Bitstream_Flag = %d\n", Main_Bitstream_Flag); + printf("Main_Bitstream_Filename = %s\n", Main_Bitstream_Filename); + printf("Verify_Flag = %d\n", Verify_Flag); + printf("Stats_Flag = %d\n", Stats_Flag); + printf("User_Data_Flag = %d\n", User_Data_Flag); + +} +#endif diff --git a/src/gdcmmpeg2/src/mpeg2dec/mpeg2dec.h b/src/gdcmmpeg2/src/mpeg2dec/mpeg2dec.h new file mode 100644 index 00000000..059b8610 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/mpeg2dec.h @@ -0,0 +1,129 @@ +/* mpeg2dec.h, MPEG specific defines */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#define ERROR (-1) + +#define PICTURE_START_CODE 0x100 +#define SLICE_START_CODE_MIN 0x101 +#define SLICE_START_CODE_MAX 0x1AF +#define USER_DATA_START_CODE 0x1B2 +#define SEQUENCE_HEADER_CODE 0x1B3 +#define SEQUENCE_ERROR_CODE 0x1B4 +#define EXTENSION_START_CODE 0x1B5 +#define SEQUENCE_END_CODE 0x1B7 +#define GROUP_START_CODE 0x1B8 +#define SYSTEM_START_CODE_MIN 0x1B9 +#define SYSTEM_START_CODE_MAX 0x1FF + +#define ISO_END_CODE 0x1B9 +#define PACK_START_CODE 0x1BA +#define SYSTEM_START_CODE 0x1BB + +#define VIDEO_ELEMENTARY_STREAM 0x1e0 + +/* scalable_mode */ +#define SC_NONE 0 +#define SC_DP 1 +#define SC_SPAT 2 +#define SC_SNR 3 +#define SC_TEMP 4 + +/* picture coding type */ +#define I_TYPE 1 +#define P_TYPE 2 +#define B_TYPE 3 +#define D_TYPE 4 + +/* picture structure */ +#define TOP_FIELD 1 +#define BOTTOM_FIELD 2 +#define FRAME_PICTURE 3 + +/* macroblock type */ +#define MACROBLOCK_INTRA 1 +#define MACROBLOCK_PATTERN 2 +#define MACROBLOCK_MOTION_BACKWARD 4 +#define MACROBLOCK_MOTION_FORWARD 8 +#define MACROBLOCK_QUANT 16 +#define SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG 32 +#define PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS 64 + + +/* motion_type */ +#define MC_FIELD 1 +#define MC_FRAME 2 +#define MC_16X8 2 +#define MC_DMV 3 + +/* mv_format */ +#define MV_FIELD 0 +#define MV_FRAME 1 + +/* chroma_format */ +#define CHROMA420 1 +#define CHROMA422 2 +#define CHROMA444 3 + +/* extension start code IDs */ + +#define SEQUENCE_EXTENSION_ID 1 +#define SEQUENCE_DISPLAY_EXTENSION_ID 2 +#define QUANT_MATRIX_EXTENSION_ID 3 +#define COPYRIGHT_EXTENSION_ID 4 +#define SEQUENCE_SCALABLE_EXTENSION_ID 5 +#define PICTURE_DISPLAY_EXTENSION_ID 7 +#define PICTURE_CODING_EXTENSION_ID 8 +#define PICTURE_SPATIAL_SCALABLE_EXTENSION_ID 9 +#define PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID 10 + +#define ZIG_ZAG 0 + +#define PROFILE_422 (128+5) +#define MAIN_LEVEL 8 + +/* Layers: used by Verbose_Flag, Verifier_Flag, Stats_Flag, and Trace_Flag */ +#define NO_LAYER 0 +#define SEQUENCE_LAYER 1 +#define PICTURE_LAYER 2 +#define SLICE_LAYER 3 +#define MACROBLOCK_LAYER 4 +#define BLOCK_LAYER 5 +#define EVENT_LAYER 6 +#define ALL_LAYERS 7 + + + +#define FILENAME_LENGTH 256 + + + + +#define MB_WEIGHT 32 +#define MB_CLASS4 64 + diff --git a/src/gdcmmpeg2/src/mpeg2dec/recon.c b/src/gdcmmpeg2/src/mpeg2dec/recon.c new file mode 100644 index 00000000..4a21264b --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/recon.c @@ -0,0 +1,467 @@ +/* Predict.c, motion compensation routines */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include + +#include "config.h" +#include "global.h" + +/* private prototypes */ +static void form_prediction _ANSI_ARGS_((unsigned char *src[], int sfield, + unsigned char *dst[], int dfield, + int lx, int lx2, int w, int h, int x, int y, int dx, int dy, + int average_flag)); + +static void form_component_prediction _ANSI_ARGS_((unsigned char *src, unsigned char *dst, + int lx, int lx2, int w, int h, int x, int y, int dx, int dy, int average_flag)); + +void form_predictions(bx,by,macroblock_type,motion_type,PMV,motion_vertical_field_select,dmvector,stwtype) +int bx, by; +int macroblock_type; +int motion_type; +int PMV[2][2][2], motion_vertical_field_select[2][2], dmvector[2]; +int stwtype; +{ + int currentfield; + unsigned char **predframe; + int DMV[2][2]; + int stwtop, stwbot; + + stwtop = stwtype%3; /* 0:temporal, 1:(spat+temp)/2, 2:spatial */ + stwbot = stwtype/3; + + if ((macroblock_type & MACROBLOCK_MOTION_FORWARD) + || (picture_coding_type==P_TYPE)) + { + if (picture_structure==FRAME_PICTURE) + { + if ((motion_type==MC_FRAME) + || !(macroblock_type & MACROBLOCK_MOTION_FORWARD)) + { + /* frame-based prediction (broken into top and bottom halves + for spatial scalability prediction purposes) */ + if (stwtop<2) + form_prediction(forward_reference_frame,0,current_frame,0, + Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by, + PMV[0][0][0],PMV[0][0][1],stwtop); + + if (stwbot<2) + form_prediction(forward_reference_frame,1,current_frame,1, + Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by, + PMV[0][0][0],PMV[0][0][1],stwbot); + } + else if (motion_type==MC_FIELD) /* field-based prediction */ + { + /* top field prediction */ + if (stwtop<2) + form_prediction(forward_reference_frame,motion_vertical_field_select[0][0], + current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, + bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,stwtop); + + /* bottom field prediction */ + if (stwbot<2) + form_prediction(forward_reference_frame,motion_vertical_field_select[1][0], + current_frame,1,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, + bx,by>>1,PMV[1][0][0],PMV[1][0][1]>>1,stwbot); + } + else if (motion_type==MC_DMV) /* dual prime prediction */ + { + /* calculate derived motion vectors */ + Dual_Prime_Arithmetic(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]>>1); + + if (stwtop<2) + { + /* predict top field from top field */ + form_prediction(forward_reference_frame,0,current_frame,0, + Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1, + PMV[0][0][0],PMV[0][0][1]>>1,0); + + /* predict and add to top field from bottom field */ + form_prediction(forward_reference_frame,1,current_frame,0, + Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1, + DMV[0][0],DMV[0][1],1); + } + + if (stwbot<2) + { + /* predict bottom field from bottom field */ + form_prediction(forward_reference_frame,1,current_frame,1, + Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1, + PMV[0][0][0],PMV[0][0][1]>>1,0); + + /* predict and add to bottom field from top field */ + form_prediction(forward_reference_frame,0,current_frame,1, + Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1, + DMV[1][0],DMV[1][1],1); + } + } + else + /* invalid motion_type */ + printf("invalid motion_type\n"); + } + else /* TOP_FIELD or BOTTOM_FIELD */ + { + /* field picture */ + currentfield = (picture_structure==BOTTOM_FIELD); + + /* determine which frame to use for prediction */ + if ((picture_coding_type==P_TYPE) && Second_Field + && (currentfield!=motion_vertical_field_select[0][0])) + predframe = backward_reference_frame; /* same frame */ + else + predframe = forward_reference_frame; /* previous frame */ + + if ((motion_type==MC_FIELD) + || !(macroblock_type & MACROBLOCK_MOTION_FORWARD)) + { + /* field-based prediction */ + if (stwtop<2) + form_prediction(predframe,motion_vertical_field_select[0][0],current_frame,0, + Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by, + PMV[0][0][0],PMV[0][0][1],stwtop); + } + else if (motion_type==MC_16X8) + { + if (stwtop<2) + { + form_prediction(predframe,motion_vertical_field_select[0][0],current_frame,0, + Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by, + PMV[0][0][0],PMV[0][0][1],stwtop); + + /* determine which frame to use for lower half prediction */ + if ((picture_coding_type==P_TYPE) && Second_Field + && (currentfield!=motion_vertical_field_select[1][0])) + predframe = backward_reference_frame; /* same frame */ + else + predframe = forward_reference_frame; /* previous frame */ + + form_prediction(predframe,motion_vertical_field_select[1][0],current_frame,0, + Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by+8, + PMV[1][0][0],PMV[1][0][1],stwtop); + } + } + else if (motion_type==MC_DMV) /* dual prime prediction */ + { + if (Second_Field) + predframe = backward_reference_frame; /* same frame */ + else + predframe = forward_reference_frame; /* previous frame */ + + /* calculate derived motion vectors */ + Dual_Prime_Arithmetic(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]); + + /* predict from field of same parity */ + form_prediction(forward_reference_frame,currentfield,current_frame,0, + Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by, + PMV[0][0][0],PMV[0][0][1],0); + + /* predict from field of opposite parity */ + form_prediction(predframe,!currentfield,current_frame,0, + Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by, + DMV[0][0],DMV[0][1],1); + } + else + /* invalid motion_type */ + printf("invalid motion_type\n"); + } + stwtop = stwbot = 1; + } + + if (macroblock_type & MACROBLOCK_MOTION_BACKWARD) + { + if (picture_structure==FRAME_PICTURE) + { + if (motion_type==MC_FRAME) + { + /* frame-based prediction */ + if (stwtop<2) + form_prediction(backward_reference_frame,0,current_frame,0, + Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by, + PMV[0][1][0],PMV[0][1][1],stwtop); + + if (stwbot<2) + form_prediction(backward_reference_frame,1,current_frame,1, + Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by, + PMV[0][1][0],PMV[0][1][1],stwbot); + } + else /* field-based prediction */ + { + /* top field prediction */ + if (stwtop<2) + form_prediction(backward_reference_frame,motion_vertical_field_select[0][1], + current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, + bx,by>>1,PMV[0][1][0],PMV[0][1][1]>>1,stwtop); + + /* bottom field prediction */ + if (stwbot<2) + form_prediction(backward_reference_frame,motion_vertical_field_select[1][1], + current_frame,1,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, + bx,by>>1,PMV[1][1][0],PMV[1][1][1]>>1,stwbot); + } + } + else /* TOP_FIELD or BOTTOM_FIELD */ + { + /* field picture */ + if (motion_type==MC_FIELD) + { + /* field-based prediction */ + form_prediction(backward_reference_frame,motion_vertical_field_select[0][1], + current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16, + bx,by,PMV[0][1][0],PMV[0][1][1],stwtop); + } + else if (motion_type==MC_16X8) + { + form_prediction(backward_reference_frame,motion_vertical_field_select[0][1], + current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, + bx,by,PMV[0][1][0],PMV[0][1][1],stwtop); + + form_prediction(backward_reference_frame,motion_vertical_field_select[1][1], + current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, + bx,by+8,PMV[1][1][0],PMV[1][1][1],stwtop); + } + else + /* invalid motion_type */ + printf("invalid motion_type\n"); + } + } +} + +static void form_prediction(src,sfield,dst,dfield,lx,lx2,w,h,x,y,dx,dy,average_flag) +unsigned char *src[]; /* prediction source buffer */ +int sfield; /* prediction source field number (0 or 1) */ +unsigned char *dst[]; /* prediction destination buffer */ +int dfield; /* prediction destination field number (0 or 1)*/ +int lx,lx2; /* line strides */ +int w,h; /* prediction block/sub-block width, height */ +int x,y; /* pixel co-ordinates of top-left sample in current MB */ +int dx,dy; /* horizontal, vertical prediction address */ +int average_flag; /* add prediction error to prediction ? */ +{ + /* Y */ + form_component_prediction(src[0]+(sfield?lx2>>1:0),dst[0]+(dfield?lx2>>1:0), + lx,lx2,w,h,x,y,dx,dy,average_flag); + + if (chroma_format!=CHROMA444) + { + lx>>=1; lx2>>=1; w>>=1; x>>=1; dx/=2; + } + + if (chroma_format==CHROMA420) + { + h>>=1; y>>=1; dy/=2; + } + + /* Cb */ + form_component_prediction(src[1]+(sfield?lx2>>1:0),dst[1]+(dfield?lx2>>1:0), + lx,lx2,w,h,x,y,dx,dy,average_flag); + + /* Cr */ + form_component_prediction(src[2]+(sfield?lx2>>1:0),dst[2]+(dfield?lx2>>1:0), + lx,lx2,w,h,x,y,dx,dy,average_flag); +} + +/* ISO/IEC 13818-2 section 7.6.4: Forming predictions */ +/* NOTE: the arithmetic below produces numerically equivalent results + * to 7.6.4, yet is more elegant. It differs in the following ways: + * + * 1. the vectors (dx, dy) are based on cartesian frame + * coordiantes along a half-pel grid (always positive numbers) + * In contrast, vector[r][s][t] are differential (with positive and + * negative values). As a result, deriving the integer vectors + * (int_vec[t]) from dx, dy is accomplished by a simple right shift. + * + * 2. Half pel flags (xh, yh) are equivalent to the LSB (Least + * Significant Bit) of the half-pel coordinates (dx,dy). + * + * + * NOTE: the work of combining predictions (ISO/IEC 13818-2 section 7.6.7) + * is distributed among several other stages. This is accomplished by + * folding line offsets into the source and destination (src,dst) + * addresses (note the call arguments to form_prediction() in Predict()), + * line stride variables lx and lx2, the block dimension variables (w,h), + * average_flag, and by the very order in which Predict() is called. + * This implementation design (implicitly different than the spec) + * was chosen for its elegance. +*/ + +static void form_component_prediction(src,dst,lx,lx2,w,h,x,y,dx,dy,average_flag) +unsigned char *src; +unsigned char *dst; +int lx; /* raster line increment */ +int lx2; +int w,h; +int x,y; +int dx,dy; +int average_flag; /* flag that signals bi-directional or Dual-Prime + averaging (7.6.7.1 and 7.6.7.4). if average_flag==1, + a previously formed prediction has been stored in + pel_pred[] */ +{ + int xint; /* horizontal integer sample vector: analogous to int_vec[0] */ + int yint; /* vertical integer sample vectors: analogous to int_vec[1] */ + int xh; /* horizontal half sample flag: analogous to half_flag[0] */ + int yh; /* vertical half sample flag: analogous to half_flag[1] */ + int i, j, v; + unsigned char *s; /* source pointer: analogous to pel_ref[][] */ + unsigned char *d; /* destination pointer: analogous to pel_pred[][] */ + + /* half pel scaling for integer vectors */ + xint = dx>>1; + yint = dy>>1; + + /* derive half pel flags */ + xh = dx & 1; + yh = dy & 1; + + /* compute the linear address of pel_ref[][] and pel_pred[][] + based on cartesian/raster cordinates provided */ + s = src + lx*(y+yint) + x + xint; + d = dst + lx*y + x; + + if (!xh && !yh) /* no horizontal nor vertical half-pel */ + { + if (average_flag) + { + for (j=0; j=0?1:0))>>1; + } + + s+= lx2; + d+= lx2; + } + } + else + { + for (j=0; j>1); + d[i]=(v+(v>=0?1:0))>>1; + } + + s+= lx2; + d+= lx2; + } + } + else + { + for (j=0; j>1; + } + + s+= lx2; + d+= lx2; + } + } + } + else if (xh && !yh) /* horizontal but no vertical half-pel */ + { + if (average_flag) + { + for (j=0; j>1); + d[i] = (v+(v>=0?1:0))>>1; + } + + s+= lx2; + d+= lx2; + } + } + else + { + for (j=0; j>1; + } + + s+= lx2; + d+= lx2; + } + } + } + else /* if (xh && yh) horizontal and vertical half-pel */ + { + if (average_flag) + { + for (j=0; j>2); + d[i] = (v+(v>=0?1:0))>>1; + } + + s+= lx2; + d+= lx2; + } + } + else + { + for (j=0; j>2; + } + + s+= lx2; + d+= lx2; + } + } + } +} diff --git a/src/gdcmmpeg2/src/mpeg2dec/spatscal.c b/src/gdcmmpeg2/src/mpeg2dec/spatscal.c new file mode 100644 index 00000000..55d26f24 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/spatscal.c @@ -0,0 +1,331 @@ + +#include +#include "config.h" +#include "global.h" + +/* private prototypes */ +static void Read_Lower_Layer_Component_Framewise _ANSI_ARGS_((int comp, int lw, int lh)); +static void Read_Lower_Layer_Component_Fieldwise _ANSI_ARGS_((int comp, int lw, int lh)); +static void Make_Spatial_Prediction_Frame _ANSI_ARGS_((int progressive_frame, + int llprogressive_frame, unsigned char *fld0, unsigned char *fld1, + short *tmp, unsigned char *dst, int llx0, int lly0, int llw, int llh, + int horizontal_size, int vertical_size, int vm, int vn, int hm, int hn, + int aperture)); +static void Deinterlace _ANSI_ARGS_((unsigned char *fld0, unsigned char *fld1, + int j0, int lx, int ly, int aperture)); +static void Subsample_Vertical _ANSI_ARGS_((unsigned char *s, short *d, + int lx, int lys, int lyd, int m, int n, int j0, int dj)); +static void Subsample_Horizontal _ANSI_ARGS_((short *s, unsigned char *d, + int x0, int lx, int lxs, int lxd, int ly, int m, int n)); + + + +/* get reference frame */ +void Spatial_Prediction() +{ + + if(Frame_Store_Flag) + { + Read_Lower_Layer_Component_Framewise(0,lower_layer_prediction_horizontal_size, + lower_layer_prediction_vertical_size); /* Y */ + Read_Lower_Layer_Component_Framewise(1,lower_layer_prediction_horizontal_size>>1, + lower_layer_prediction_vertical_size>>1); /* Cb ("U") */ + Read_Lower_Layer_Component_Framewise(2,lower_layer_prediction_horizontal_size>>1, + lower_layer_prediction_vertical_size>>1); /* Cr ("V") */ + } + else + { + Read_Lower_Layer_Component_Fieldwise(0,lower_layer_prediction_horizontal_size, + lower_layer_prediction_vertical_size); /* Y */ + Read_Lower_Layer_Component_Fieldwise(1,lower_layer_prediction_horizontal_size>>1, + lower_layer_prediction_vertical_size>>1); /* Cb ("U") */ + Read_Lower_Layer_Component_Fieldwise(2,lower_layer_prediction_horizontal_size>>1, + lower_layer_prediction_vertical_size>>1); /* Cr ("V") */ + } + + + Make_Spatial_Prediction_Frame /* Y */ + (progressive_frame,lower_layer_progressive_frame,llframe0[0],llframe1[0], + lltmp,current_frame[0],lower_layer_horizontal_offset, + lower_layer_vertical_offset, + lower_layer_prediction_horizontal_size, + lower_layer_prediction_vertical_size, + horizontal_size,vertical_size,vertical_subsampling_factor_m, + vertical_subsampling_factor_n,horizontal_subsampling_factor_m, + horizontal_subsampling_factor_n, + picture_structure!=FRAME_PICTURE); /* this changed from CD to DIS */ + + Make_Spatial_Prediction_Frame /* Cb */ + (progressive_frame,lower_layer_progressive_frame,llframe0[1],llframe1[1], + lltmp,current_frame[1],lower_layer_horizontal_offset/2, + lower_layer_vertical_offset/2, + lower_layer_prediction_horizontal_size>>1, + lower_layer_prediction_vertical_size>>1, + horizontal_size>>1,vertical_size>>1,vertical_subsampling_factor_m, + vertical_subsampling_factor_n,horizontal_subsampling_factor_m, + horizontal_subsampling_factor_n,1); + + Make_Spatial_Prediction_Frame /* Cr */ + (progressive_frame,lower_layer_progressive_frame,llframe0[2],llframe1[2], + lltmp,current_frame[2],lower_layer_horizontal_offset/2, + lower_layer_vertical_offset/2, + lower_layer_prediction_horizontal_size>>1, + lower_layer_prediction_vertical_size>>1, + horizontal_size>>1,vertical_size>>1,vertical_subsampling_factor_m, + vertical_subsampling_factor_n,horizontal_subsampling_factor_m, + horizontal_subsampling_factor_n,1); + +} + +static void Read_Lower_Layer_Component_Framewise(comp,lw,lh) + int comp; + int lw, lh; +{ + FILE *fd; + char fname[256]; + char ext[3][3] = {".Y",".U",".V"}; +/* char *ext = {".Y",".U",".V"}; */ + int i,j; + + sprintf(fname,Lower_Layer_Picture_Filename,True_Framenum); + strcat(fname,ext[comp]); +#ifdef VERBOSE + if (Verbose_Flag>1) + printf("reading %s\n",fname); +#endif VERBOSE + fd=fopen(fname,"rb"); + if (fd==NULL) exit(-1); + for (j=0; j1) + printf("reading %s\n",fname); +#endif VERBOSE + fd=fopen(fname,"rb"); + if (fd==NULL) exit(-1); + for (j=0; j1) + printf("reading %s\n",fname); +#endif VERBOSE + fd=fopen(fname,"rb"); + if (fd==NULL) exit(-1); + for (j=1; j progressive / interlaced */ + Subsample_Vertical(fld0,tmp,llw,llh,llh2,vm,vn,0,1); + } + else if (progressive_frame) + { + /* interlaced -> progressive */ + if (lower_layer_deinterlaced_field_select) + { + Deinterlace(fld1,fld0,0,llw,llh,aperture); + Subsample_Vertical(fld1,tmp,llw,llh,llh2,vm,vn,0,1); + } + else + { + Deinterlace(fld0,fld1,1,llw,llh,aperture); + Subsample_Vertical(fld0,tmp,llw,llh,llh2,vm,vn,0,1); + } + } + else + { + /* interlaced -> interlaced */ + Deinterlace(fld0,fld1,1,llw,llh,aperture); + Deinterlace(fld1,fld0,0,llw,llh,aperture); + Subsample_Vertical(fld0,tmp,llw,llh,llh2,vm,vn,0,2); + Subsample_Vertical(fld1,tmp,llw,llh,llh2,vm,vn,1,2); + } + + /* vertical limits */ + if (lly0<0) + { + tmp-= llw*lly0; + llh2+= lly0; + if (llh2<0) + llh2 = 0; + h = (vertical_sizellh2) + h = llh2; + } + + /* horizontal limits */ + if (llx0<0) + { + x0 = -llx0; + llw2+= llx0; + if (llw2<0) + llw2 = 0; + w = (horizontal_sizellw2) + w = llw2; + } + + Subsample_Horizontal(tmp,dst,x0,w,llw,horizontal_size,h,hm,hn); +} + +/* deinterlace one field (interpolate opposite parity samples) + * + * deinterlacing is done in-place: if j0=1, fld0 contains the input field in + * its even lines and the odd lines are interpolated by this routine + * if j0=0, the input field is in the odd lines and the even lines are + * interpolated + * + * fld0: field to be deinterlaced + * fld1: other field (referenced by the two field aperture filter) + * j0: 0: interpolate even (top) lines, 1: interpolate odd (bottom) lines + * lx: width of fld0 and fld1 + * ly: height of the deinterlaced field (has to be even) + * aperture: 1: use one field aperture filter (two field otherwise) + */ +static void Deinterlace(fld0,fld1,j0,lx,ly,aperture) +unsigned char *fld0,*fld1; +int j0,lx,ly; /* ly has to be even */ +int aperture; +{ + int i,j,v; + unsigned char *p0, *p0m1, *p0p1, *p1, *p1m2, *p1p2; + + /* deinterlace one field */ + for (j=j0; j>1; + else + { + p1 = fld1 + lx*j; + p1m2 = (j<2) ? p1 : p1-2*lx; + p1p2 = (j>=ly-2) ? p1 : p1+2*lx; + for (i=0; i=0) ? 8 : 7))>>4]; + } + } + } +} + +/* vertical resampling */ +static void Subsample_Vertical(s,d,lx,lys,lyd,m,n,j0,dj) +unsigned char *s; +short *d; +int lx, lys, lyd, m, n, j0, dj; +{ + int i, j, c1, c2, jd; + unsigned char *s1, *s2; + short *d1; + + for (j=j0; j>1))/n; + c1 = 16 - c2; + for (i=0; i>1))/n; + c1 = 16 - c2; + for (j=0; j=0) ? 128 : 127))>>8; + d1+= lxd; + s1+= lxs; + s2+= lxs; + } + } +} + + diff --git a/src/gdcmmpeg2/src/mpeg2dec/store.c b/src/gdcmmpeg2/src/mpeg2dec/store.c new file mode 100644 index 00000000..8867416a --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/store.c @@ -0,0 +1,576 @@ +/* store.c, picture output routines */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include +#include +#include + +#include "config.h" +#include "global.h" + +/* private prototypes */ +static void store_one _ANSI_ARGS_((char *outname, unsigned char *src[], + int offset, int incr, int height)); +static void store_yuv _ANSI_ARGS_((char *outname, unsigned char *src[], + int offset, int incr, int height)); +static void store_sif _ANSI_ARGS_((char *outname, unsigned char *src[], + int offset, int incr, int height)); +static void store_ppm_tga _ANSI_ARGS_((char *outname, unsigned char *src[], + int offset, int incr, int height, int tgaflag)); +static void store_yuv1 _ANSI_ARGS_((char *name, unsigned char *src, + int offset, int incr, int width, int height)); +static void putbyte _ANSI_ARGS_((int c)); +static void putword _ANSI_ARGS_((int w)); +static void conv422to444 _ANSI_ARGS_((unsigned char *src, unsigned char *dst)); +static void conv420to422 _ANSI_ARGS_((unsigned char *src, unsigned char *dst)); + +#define OBFRSIZE 4096 +static unsigned char obfr[OBFRSIZE]; +static unsigned char *optr; +static int outfile; + +/* + * store a picture as either one frame or two fields + */ +void Write_Frame(src,frame) +unsigned char *src[]; +int frame; +{ + char outname[FILENAME_LENGTH]; + + if (progressive_sequence || progressive_frame || Frame_Store_Flag) + { + /* progressive */ + sprintf(outname,Output_Picture_Filename,frame,'f'); + store_one(outname,src,0,Coded_Picture_Width,vertical_size); + } + else + { + /* interlaced */ + sprintf(outname,Output_Picture_Filename,frame,'a'); + store_one(outname,src,0,Coded_Picture_Width<<1,vertical_size>>1); + + sprintf(outname,Output_Picture_Filename,frame,'b'); + store_one(outname,src, + Coded_Picture_Width,Coded_Picture_Width<<1,vertical_size>>1); + } +} + +/* + * store one frame or one field + */ +static void store_one(outname,src,offset,incr,height) +char *outname; +unsigned char *src[]; +int offset, incr, height; +{ + switch (Output_Type) + { + case T_YUV: + store_yuv(outname,src,offset,incr,height); + break; + case T_SIF: + store_sif(outname,src,offset,incr,height); + break; + case T_TGA: + store_ppm_tga(outname,src,offset,incr,height,1); + break; + case T_PPM: + store_ppm_tga(outname,src,offset,incr,height,0); + break; +#ifdef DISPLAY + case T_X11: + dither(src); + break; +#endif + default: + break; + } +} + +/* separate headerless files for y, u and v */ +static void store_yuv(outname,src,offset,incr,height) +char *outname; +unsigned char *src[]; +int offset,incr,height; +{ + int hsize; + char tmpname[FILENAME_LENGTH]; + + hsize = horizontal_size; + + sprintf(tmpname,"%s.Y",outname); + store_yuv1(tmpname,src[0],offset,incr,hsize,height); + + if (chroma_format!=CHROMA444) + { + offset>>=1; incr>>=1; hsize>>=1; + } + + if (chroma_format==CHROMA420) + { + height>>=1; + } + + sprintf(tmpname,"%s.U",outname); + store_yuv1(tmpname,src[1],offset,incr,hsize,height); + + sprintf(tmpname,"%s.V",outname); + store_yuv1(tmpname,src[2],offset,incr,hsize,height); +} + +/* auxiliary routine */ +static void store_yuv1(name,src,offset,incr,width,height) +char *name; +unsigned char *src; +int offset,incr,width,height; +{ + int i, j; + unsigned char *p; + + if (!Quiet_Flag) + fprintf(stderr,"saving %s\n",name); + + if ((outfile = open(name,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1) + { + sprintf(Error_Text,"Couldn't create %s\n",name); + Error(Error_Text); + } + + optr=obfr; + + for (i=0; i>1) + *Coded_Picture_Height))) + Error("malloc failed"); + if (!(v422 = (unsigned char *)malloc((Coded_Picture_Width>>1) + *Coded_Picture_Height))) + Error("malloc failed"); + } + + conv420to422(src[1],u422); + conv420to422(src[2],v422); + } + + strcat(outname,".SIF"); + + if (!Quiet_Flag) + fprintf(stderr,"saving %s\n",outname); + + if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1) + { + sprintf(Error_Text,"Couldn't create %s\n",outname); + Error(Error_Text); + } + + optr = obfr; + + for (i=0; i>1) + (incr>>1)*i; + pv = v422 + (offset>>1) + (incr>>1)*i; + + for (j=0; j>1) + *Coded_Picture_Height))) + Error("malloc failed"); + if (!(v422 = (unsigned char *)malloc((Coded_Picture_Width>>1) + *Coded_Picture_Height))) + Error("malloc failed"); + } + + if (!(u444 = (unsigned char *)malloc(Coded_Picture_Width + *Coded_Picture_Height))) + Error("malloc failed"); + + if (!(v444 = (unsigned char *)malloc(Coded_Picture_Width + *Coded_Picture_Height))) + Error("malloc failed"); + } + + if (chroma_format==CHROMA420) + { + conv420to422(src[1],u422); + conv420to422(src[2],v422); + conv422to444(u422,u444); + conv422to444(v422,v444); + } + else + { + conv422to444(src[1],u444); + conv422to444(src[2],v444); + } + } + + strcat(outname,tgaflag ? ".tga" : ".ppm"); + + if (!Quiet_Flag) + fprintf(stderr,"saving %s\n",outname); + + if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1) + { + sprintf(Error_Text,"Couldn't create %s\n",outname); + Error(Error_Text); + } + + optr = obfr; + + if (tgaflag) + { + /* TGA header */ + for (i=0; i<12; i++) + putbyte(tga24[i]); + + putword(horizontal_size); putword(height); + putbyte(tga24[12]); putbyte(tga24[13]); + } + else + { + /* PPM header */ + sprintf(header,"P6\n%d %d\n255\n",horizontal_size,height); + + for (i=0; header[i]!=0; i++) + putbyte(header[i]); + } + + /* matrix coefficients */ + crv = Inverse_Table_6_9[matrix_coefficients][0]; + cbu = Inverse_Table_6_9[matrix_coefficients][1]; + cgu = Inverse_Table_6_9[matrix_coefficients][2]; + cgv = Inverse_Table_6_9[matrix_coefficients][3]; + + for (i=0; i>16]; + g = Clip[(y - cgu*u - cgv*v + 32768)>>16]; + b = Clip[(y + cbu*u + 32786)>>16]; + + if (tgaflag) + { + putbyte(b); putbyte(g); putbyte(r); + } + else + { + putbyte(r); putbyte(g); putbyte(b); + } + } + } + + if (optr!=obfr) + write(outfile,obfr,optr-obfr); + + close(outfile); +} + +static void putbyte(c) +int c; +{ + *optr++ = c; + + if (optr == obfr+OBFRSIZE) + { + write(outfile,obfr,OBFRSIZE); + optr = obfr; + } +} + +static void putword(w) +int w; +{ + putbyte(w); putbyte(w>>8); +} + +/* horizontal 1:2 interpolation filter */ +static void conv422to444(src,dst) +unsigned char *src,*dst; +{ + int i, i2, w, j, im3, im2, im1, ip1, ip2, ip3; + + w = Coded_Picture_Width>>1; + + if (base.MPEG2_Flag) + { + for (j=0; j>8]; + } + src+= w; + dst+= Coded_Picture_Width; + } + } + else + { + for (j=0; j>8]; + + dst[i2+1] = Clip[(int)( 5*src[ip3] + -21*src[ip2] + +70*src[ip1] + +228*src[i] + -37*src[im1] + +11*src[im2]+128)>>8]; + } + src+= w; + dst+= Coded_Picture_Width; + } + } +} + +/* vertical 1:2 interpolation filter */ +static void conv420to422(src,dst) +unsigned char *src,*dst; +{ + int w, h, i, j, j2; + int jm6, jm5, jm4, jm3, jm2, jm1, jp1, jp2, jp3, jp4, jp5, jp6, jp7; + + w = Coded_Picture_Width>>1; + h = Coded_Picture_Height>>1; + + if (progressive_frame) + { + /* intra frame */ + for (i=0; i>8]; + + dst[w*(j2+1)] = Clip[(int)( 3*src[w*jp3] + -16*src[w*jp2] + +67*src[w*jp1] + +227*src[w*j] + -32*src[w*jm1] + +7*src[w*jm2]+128)>>8]; + } + src++; + dst++; + } + } + else + { + /* intra field */ + for (i=0; i>8]; + + /* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */ + /* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */ + dst[w*(j2+2)] = Clip[(int)( 7*src[w*jm4] + -35*src[w*jm2] + +194*src[w*j] + +110*src[w*jp2] + -24*src[w*jp4] + +4*src[w*jp6]+128)>>8]; + + /* bottom field */ + jm5 = (j<5) ? 1 : j-5; + jm3 = (j<3) ? 1 : j-3; + jm1 = (j<1) ? 1 : j-1; + jp1 = (j>8]; + + dst[w*(j2+3)] = Clip[(int)( 1*src[w*jp7] + -7*src[w*jp5] + +30*src[w*jp3] + +248*src[w*jp1] + -21*src[w*jm1] + +5*src[w*jm3]+128)>>8]; + } + src++; + dst++; + } + } +} diff --git a/src/gdcmmpeg2/src/mpeg2dec/subspic.c b/src/gdcmmpeg2/src/mpeg2dec/subspic.c new file mode 100644 index 00000000..67bb555d --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/subspic.c @@ -0,0 +1,392 @@ +/* #define DEBUG */ +/* subspic.c, Frame buffer substitution routines */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include +#include +#include + +#include "config.h" +#include "global.h" + +/* private prototypes*/ +static void Read_Frame _ANSI_ARGS_((char *filename, + unsigned char *frame_buffer[], int framenum)); +static void Copy_Frame _ANSI_ARGS_((unsigned char *src, unsigned char *dst, + int width, int height, int parity, int incr)); +static int Read_Components _ANSI_ARGS_ ((char *filename, + unsigned char *frame[3], int framenum)); +static int Read_Component _ANSI_ARGS_ ((char *fname, unsigned char *frame, + int width, int height)); +static int Extract_Components _ANSI_ARGS_ ((char *filename, + unsigned char *frame[3], int framenum)); + + +/* substitute frame buffer routine */ +void Substitute_Frame_Buffer (bitstream_framenum, sequence_framenum) +int bitstream_framenum; +int sequence_framenum; +{ + /* static tracking variables */ + static int previous_temporal_reference; + static int previous_bitstream_framenum; + static int previous_anchor_temporal_reference; + static int previous_anchor_bitstream_framenum; + static int previous_picture_coding_type; + static int bgate; + + /* local temporary variables */ + int substitute_display_framenum; + + +#ifdef DEBUG + printf("SUB: seq fn(%d) bitfn(%d) tempref(%d) picstr(%d) type(%d)\n", + sequence_framenum, bitstream_framenum, temporal_reference, + picture_structure, picture_coding_type); +#endif + + /* we don't substitute at the first picture of a sequence */ + if((sequence_framenum!=0)||(Second_Field)) + { + /* only at the start of the frame */ + if ((picture_structure==FRAME_PICTURE)||(!Second_Field)) + { + if(picture_coding_type==P_TYPE) + { + /* the most recently decoded reference frame needs substituting */ + substitute_display_framenum = bitstream_framenum - 1; + + Read_Frame(Substitute_Picture_Filename, forward_reference_frame, + substitute_display_framenum); + } + /* only the first B frame in a consequitve set of B pictures + loads a substitute backward_reference_frame since all subsequent + B frames predict from the same reference pictures */ + else if((picture_coding_type==B_TYPE)&&(bgate!=1)) + { + substitute_display_framenum = + (previous_temporal_reference - temporal_reference) + + bitstream_framenum - 1; + + Read_Frame(Substitute_Picture_Filename, backward_reference_frame, + substitute_display_framenum); + } + } /* P fields can predict from the two most recently decoded fields, even + from the first field of the same frame being decoded */ + else if(Second_Field && (picture_coding_type==P_TYPE)) + { + /* our favourite case: the IP field picture pair */ + if((previous_picture_coding_type==I_TYPE)&&(picture_coding_type==P_TYPE)) + { + substitute_display_framenum = bitstream_framenum; + } + else /* our more generic P field picture pair */ + { + substitute_display_framenum = + (temporal_reference - previous_anchor_temporal_reference) + + bitstream_framenum - 1; + } + + Read_Frame(Substitute_Picture_Filename, current_frame, substitute_display_framenum); + } +#ifdef DEBUG + else if((picture_coding_type!=B_TYPE)||(picture_coding_type!=D_TYPE)) + { + printf("NO SUBS FOR THIS PICTURE\n"); + } +#endif + } + + + /* set b gate so we don't redundantly load next time around */ + if(picture_coding_type==B_TYPE) + bgate = 1; + else + bgate = 0; + + /* update general tracking variables */ + if((picture_structure==FRAME_PICTURE)||(!Second_Field)) + { + previous_temporal_reference = temporal_reference; + previous_bitstream_framenum = bitstream_framenum; + } + + /* update reference frame tracking variables */ + if((picture_coding_type!=B_TYPE) && + ((picture_structure==FRAME_PICTURE)||Second_Field)) + { + previous_anchor_temporal_reference = temporal_reference; + previous_anchor_bitstream_framenum = bitstream_framenum; + } + + previous_picture_coding_type = picture_coding_type; + +} + + +/* Note: fields are only read to serve as the same-frame reference for + a second field */ +static void Read_Frame(fname,frame,framenum) +char *fname; +unsigned char *frame[]; +int framenum; +{ + int parity; + int rerr = 0; + int field_mode; + + if(framenum<0) + printf("ERROR: framenum (%d) is less than zero\n", framenum); + + + if(Big_Picture_Flag) + rerr = Extract_Components(fname, substitute_frame, framenum); + else + rerr = Read_Components(fname, substitute_frame, framenum); + + if(rerr!=0) + { + printf("was unable to substitute frame\n"); + } + + /* now copy to the appropriate buffer */ + /* first field (which we are attempting to substitute) must be + of opposite field parity to the current one */ + if((Second_Field)&&(picture_coding_type==P_TYPE)) + { + parity = (picture_structure==TOP_FIELD ? 1:0); + field_mode = (picture_structure==FRAME_PICTURE ? 0:1); + } + else + { + /* Like frame structued pictures, B pictures only substitute an entire frame + since both fields always predict from the same frame (with respect + to forward/backwards directions) */ + parity = 0; + field_mode = 0; + } + + + Copy_Frame(substitute_frame[0], frame[0], Coded_Picture_Width, + Coded_Picture_Height, parity, field_mode); + + Copy_Frame(substitute_frame[1], frame[1], Chroma_Width, Chroma_Height, + parity, field_mode); + + Copy_Frame(substitute_frame[2], frame[2], Chroma_Width, Chroma_Height, + parity, field_mode); + +#ifdef VERBOSE + if(Verbose_Flag > NO_LAYER) + printf("substituted %s %d\n", + (field_mode ? (parity?"bottom field":"bottom field"):"frame"), framenum); +#endif +} + + + + +static int Read_Components(filename, frame, framenum) +char *filename; +unsigned char *frame[3]; +int framenum; +{ + int err = 0; + char outname[FILENAME_LENGTH]; + char name[FILENAME_LENGTH]; + + sprintf(outname,filename,framenum); + + + sprintf(name,"%s.Y",outname); + err += Read_Component(name, frame[0], Coded_Picture_Width, + Coded_Picture_Height); + + sprintf(name,"%s.U",outname); + err += Read_Component(name, frame[1], Chroma_Width, Chroma_Height); + + sprintf(name,"%s.V",outname); + err += Read_Component(name, frame[2], Chroma_Width, Chroma_Height); + + return(err); +} + + +static int Read_Component(Filename, Frame, Width, Height) +char *Filename; +unsigned char *Frame; +int Width; +int Height; +{ + int Size; + int Bytes_Read; + int Infile; + + Size = Width*Height; + +#ifdef DEBUG + printf("SUBS: reading %s\n", filename); +#endif + + if(!(Infile=open(Filename,O_RDONLY|O_BINARY))<0) + { + printf("ERROR: unable to open reference filename (%s)\n", Filename); + return(-1); + } + + Bytes_Read = read(Infile, Frame, Size); + + if(Bytes_Read!=Size) + { + printf("was able to read only %d bytes of %d of file %s\n", + Bytes_Read, Size, Filename); + } + + close(Infile); + return(0); +} + + +/* optimization: do not open the big file each time. Open once at start + of decoder, and close at the very last frame */ + +/* Note: "big" files were used in E-mail exchanges almost exclusively by the + MPEG Committee's syntax validation and conformance ad-hoc groups from + the year 1993 until 1995 */ +static int Extract_Components(filename, frame, framenum) +char *filename; +unsigned char *frame[3]; +int framenum; +{ +/* int err = 0; */ + FILE *fd; + int line; + int size, offset; + + + if (!(fd = fopen(filename,"rb"))) + { + sprintf(Error_Text,"Couldn't open %s\n",filename); + return(-1); + } + + /* compute size of each frame (in bytes) */ + size = (Coded_Picture_Width*Coded_Picture_Height); + + if(chroma_format==CHROMA444) + size = (size * 3); + else if(chroma_format==CHROMA422) + size = (size * 2); + else if(chroma_format==CHROMA420) + size = ((size*3)>>1); + else + printf("ERROR: chroma_format (%d) not recognized\n", chroma_format); + + + /* compute distance into "big" file */ + offset = size*framenum; + +#ifdef DEBUG + printf("EXTRACTING: frame(%d) offset(%d), size (%d) from %s\n", + framenum, offset, size, filename); +#endif + + /* seek to location in big file where desired frame begins */ + /* note: this offset cannot exceed a few billion bytes due to the */ + /* obvious limitations of 32-bit integers */ + fseek(fd, offset, 0); + + /* Y */ + for (line=0; line +#include + +#include "config.h" +#include "global.h" + +/* initialize buffer, call once before first getbits or showbits */ + +/* parse system layer, ignore everything we don't need */ +void Next_Packet() +{ + unsigned int code; + int l; + + for(;;) + { + code = Get_Long(); + + /* remove system layer byte stuffing */ + while ((code & 0xffffff00) != 0x100) + code = (code<<8) | Get_Byte(); + + switch(code) + { + case PACK_START_CODE: /* pack header */ + /* skip pack header (system_clock_reference and mux_rate) */ + ld->Rdptr += 8; + break; + case VIDEO_ELEMENTARY_STREAM: + code = Get_Word(); /* packet_length */ + ld->Rdmax = ld->Rdptr + code; + + code = Get_Byte(); + + if((code>>6)==0x02) + { + ld->Rdptr++; + code=Get_Byte(); /* parse PES_header_data_length */ + ld->Rdptr+=code; /* advance pointer by PES_header_data_length */ + printf("MPEG-2 PES packet\n"); + return; + } + else if(code==0xff) + { + /* parse MPEG-1 packet header */ + while((code=Get_Byte())== 0xFF); + } + + /* stuffing bytes */ + if(code>=0x40) + { + if(code>=0x80) + { + fprintf(stderr,"Error in packet header\n"); + exit(1); + } + /* skip STD_buffer_scale */ + ld->Rdptr++; + code = Get_Byte(); + } + + if(code>=0x30) + { + if(code>=0x40) + { + fprintf(stderr,"Error in packet header\n"); + exit(1); + } + /* skip presentation and decoding time stamps */ + ld->Rdptr += 9; + } + else if(code>=0x20) + { + /* skip presentation time stamps */ + ld->Rdptr += 4; + } + else if(code!=0x0f) + { + fprintf(stderr,"Error in packet header\n"); + exit(1); + } + return; + case ISO_END_CODE: /* end */ + /* simulate a buffer full of sequence end codes */ + l = 0; + while (l<2048) + { + ld->Rdbfr[l++] = SEQUENCE_END_CODE>>24; + ld->Rdbfr[l++] = SEQUENCE_END_CODE>>16; + ld->Rdbfr[l++] = SEQUENCE_END_CODE>>8; + ld->Rdbfr[l++] = SEQUENCE_END_CODE&0xff; + } + ld->Rdptr = ld->Rdbfr; + ld->Rdmax = ld->Rdbfr + 2048; + return; + default: + if(code>=SYSTEM_START_CODE) + { + /* skip system headers and non-video packets*/ + code = Get_Word(); + ld->Rdptr += code; + } + else + { + fprintf(stderr,"Unexpected startcode %08x in system layer\n",code); + exit(1); + } + break; + } + } +} + + + +void Flush_Buffer32() +{ + int Incnt; + + ld->Bfr = 0; + + Incnt = ld->Incnt; + Incnt -= 32; + + if (System_Stream_Flag && (ld->Rdptr >= ld->Rdmax-4)) + { + while (Incnt <= 24) + { + if (ld->Rdptr >= ld->Rdmax) + Next_Packet(); + ld->Bfr |= Get_Byte() << (24 - Incnt); + Incnt += 8; + } + } + else + { + while (Incnt <= 24) + { + if (ld->Rdptr >= ld->Rdbfr+2048) + Fill_Buffer(); + ld->Bfr |= *ld->Rdptr++ << (24 - Incnt); + Incnt += 8; + } + } + ld->Incnt = Incnt; + +#ifdef VERIFY + ld->Bitcnt += 32; +#endif /* VERIFY */ +} + + +unsigned int Get_Bits32() +{ + unsigned int l; + + l = Show_Bits(32); + Flush_Buffer32(); + + return l; +} + + +int Get_Long() +{ + int i; + + i = Get_Word(); + return (i<<16) | Get_Word(); +} + + diff --git a/src/gdcmmpeg2/src/mpeg2dec/verify.c b/src/gdcmmpeg2/src/mpeg2dec/verify.c new file mode 100644 index 00000000..ff7b1d88 --- /dev/null +++ b/src/gdcmmpeg2/src/mpeg2dec/verify.c @@ -0,0 +1,303 @@ +/* verify.c + * + * Bitstream verification routines + * + * + */ +#ifdef VERIFY + +#include +#include +#include +#include +#include /* needed for ceil() */ + +#include "config.h" +#include "global.h" + +/* #define DEBUG */ +#ifdef DEBUG +#define PC +#endif + +#ifdef PC +#include /* needed for getch() */ +#endif /* PC */ + +/* + Check picture headers: due to the VBV definition of picture data, + this routine must be called immediately before any picture data + is parsed. (before the first slice start code, including any slice + start code stuffing). +*/ + + +static void Check_VBV_Delay _ANSI_ARGS_((int Bitstream_Framenum, int Sequence_Framenum)); + + +void Check_Headers(Bitstream_Framenum, Sequence_Framenum) +int Bitstream_Framenum; +int Sequence_Framenum; +{ + + + if((!low_delay)&&(vbv_delay!=0)&&(vbv_delay!=0xFFFF)) + Check_VBV_Delay(Bitstream_Framenum, Sequence_Framenum); + + /* clear out the header tracking variables so we have an accurate + count next time */ + Clear_Verify_Headers(); +} + + + +/* + * Verify vbv_delay value in picture header + * (low_delay==1 checks not implemented. this does not exhaustively test all + * possibilities suggested in ISO/IEC 13818-2 Annex C. It only checks + * for constant rate streams) + * + * Q:how do we tell a variable rate stream from a constant rate stream anyway? + * it's not as simple as vbv_delay==0xFFFF, since we need meaningful + * vbv_delay values to calculate the piecewise rate in the first place! + * + * Also: no special provisions at the beginning or end of a sequence + */ + +static void Check_VBV_Delay(Bitstream_Framenum, Sequence_Framenum) +int Bitstream_Framenum; +int Sequence_Framenum; +{ + double B; /* buffer size */ + double Bn; /* buffer fullness for picture n */ + double R; /* bitrate */ + double I; /* time interval (t[n+1] - t[n]) */ + double T; /* inverse of the frame rate (frame period) */ + + int d; + int internal_vbv_delay; + + static int previous_IorP_picture_structure; + static int previous_IorP_repeat_first_field; + static int previous_IorP_top_field_first; + static int previous_vbv_delay; + static int previous_bitstream_position; + + static double previous_Bn; + static double E; /* maximum quantization error or mismatch */ + + + + if((Sequence_Framenum==0)&&(!Second_Field)) + { /* first coded picture of sequence */ + + R = bit_rate; + + /* the initial buffer occupancy is taken on faith + that is, we believe what is transmitted in the first coded picture header + to be the true/actual buffer occupancy */ + + Bn = (R * (double) vbv_delay) / 90000.0; + B = 16 * 1024 * vbv_buffer_size; + + + /* maximum quantization error in bitrate (bit_rate_value is quantized/ + rounded-up to units of 400 bits/sec as per ISO/IEC 13818-2 + section 6.3.3 */ + + E = (400.0/frame_rate) + 400; + +#ifdef DEBUG + printf("vbv_buffer_size (B) = %.0f, Bn=%f, E=%f, \nbitrate=%f, vbv_delay=%d frame_rate=%f\n", + B, Bn, E, bit_rate, vbv_delay, frame_rate); +#endif + + } + else /* not the first coded picture of sequence */ + { + + /* derive the interval (I). The interval tells us how many constant rate bits + * will have been downloaded to the buffer during the current picture period + * + * interval assumes that: + * 1. whilst we are decoding the current I or P picture, we are displaying + * the previous I or P picture which was stored in the reorder + * buffer (pointed to by forward_reference_frame in this implementation) + * + * 2. B pictures are output ("displayed") at the time when they are decoded + * + */ + + if(progressive_sequence) /* Annex C.9 (progressive_sequence==1, low_delay==0) */ + { + + T = 1/frame_rate; /* inverse of the frame rate (frame period) */ + + if(picture_coding_type==B_TYPE) + { + if(repeat_first_field==1) + { + if(top_field_first==1) + I = T*3; /* three frame periods */ + else + I = T*2; /* two frame periods */ + } + else + I = T; /* one frame period */ + } + else /* P or I frame */ + { + if(previous_IorP_repeat_first_field==1) + { + if(previous_IorP_top_field_first==1) + I = 3*T; + else + I = 2*T; + } + else + I = T; + } + } + else /* Annex C.11 (progressive_sequence==0, low_delay==0) */ + { + + T = 1/(2*frame_rate); /* inverse of two times the frame rate (field period) */ + + if(picture_coding_type==B_TYPE) + { + if(picture_structure==FRAME_PICTURE) + { + if(repeat_first_field==0) + I = 2*T; /* two field periods */ + else + I = 3*T; /* three field periods */ + } + else /* B field */ + { + I = T; /* one field period */ + } + } + else /* I or P picture */ + { + if(picture_structure==FRAME_PICTURE) + { + if(previous_IorP_repeat_first_field==0) + I = 2*T; + else + I = 3*T; + } + else + { + if(Second_Field==0) /* first field of current frame */ + I = T; + else /* second field of current frame */ + { + /* formula: previous I or P display period (2*T or 3*T) minus the + very recent decode period (T) of the first field of the current + frame */ + + if(previous_IorP_picture_structure!=FRAME_PICTURE + || previous_IorP_repeat_first_field==0) + I = 2*T - T; /* a net of one field period */ + else if(previous_IorP_picture_structure==FRAME_PICTURE + && previous_IorP_repeat_first_field==1) + I = 3*T - T; /* a net of two field periods */ + } + } + } + } + + /* derive coded size of previous picture */ + d = ld->Bitcnt - previous_bitstream_position; + + /* Rate = Distance/Time */ + + /* piecewise constant rate (variable rate stream) calculation + * R = ((double) d /((previous_vbv_delay - vbv_delay)/90000 + I)); + */ + + R = bit_rate; + + /* compute buffer fullness just before removing picture n + * + * Bn = previous_Bn + (I*R) - d; (recursive formula) + * + * where: + * + * n is the current picture + * + * Bn is the buffer fullness for the current picture + * + * previous_Bn is the buffer fullness of the previous picture + * + * (I*R ) is the bits accumulated during the current picture + * period + * + * d is the number of bits removed during the decoding of the + * previous picture + */ + + Bn = previous_Bn + (I*R) - d; + + /* compute internally derived vbv_delay (rouding up with ceil()) */ + internal_vbv_delay = (int) ceil((90000 * Bn / bit_rate)); + +#ifdef DEBUG + printf("\nvbv_delay: internal=%d, bitstream=%d\n", internal_vbv_delay, vbv_delay); + + printf("Bn=%f, prevBn=%f, I=%f, R=%f, d=%d\n", Bn, previous_Bn, I, R, d); + printf("frame(%d), pictstruct(%d), picttype(%d)\n", Sequence_Framenum, + picture_structure, picture_coding_type); + + /* report error */ + if(internal_vbv_delay != vbv_delay) + { + printf("WARNING: internal_vbv_delay(%d) != vbv_delay(%d)\n", + internal_vbv_delay, vbv_delay); + } +#endif + + } /* not the first coded picture of sequence */ + + +#ifdef PC + getch(); +#endif /* PC */ + + /* update generic tracking variables */ + previous_bitstream_position = ld->Bitcnt ; + previous_vbv_delay = vbv_delay; + previous_Bn = Bn; + + /* reference picture: reordered/delayed output picture */ + if(picture_coding_type!=B_TYPE) + { + previous_IorP_repeat_first_field = repeat_first_field; + previous_IorP_top_field_first = top_field_first; + previous_IorP_picture_structure = picture_structure; + } + +} + + + +/* variables to keep track of the occurance of redundant headers between pictures */ +void Clear_Verify_Headers() +{ + verify_sequence_header = 0; + verify_group_of_pictures_header = 0; + verify_picture_header = 0; + verify_slice_header = 0; + verify_sequence_extension = 0; + verify_sequence_display_extension = 0; + verify_quant_matrix_extension = 0; + verify_sequence_scalable_extension = 0; + verify_picture_display_extension = 0; + verify_picture_coding_extension = 0; + verify_picture_spatial_scalable_extension = 0; + verify_picture_temporal_scalable_extension = 0; + verify_copyright_extension = 0; +} + +#endif /* VERIFY */ +