mpeg2/ 750 270 132 0 5565721071 5054 mpeg2/doc/ 750 270 132 0 5565713045 5623 mpeg2/doc/mpeg2enc.doc 640 270 132 56355 5565712512 10134 mpeg2encode =========== MPEG-2 Video Encoder, Version 1.0, May 1994 MPEG Software Simulation Group (MPEG-L@netcom.com) Contents: ========= 1. Overview 2. Features and Limitations 3. Usage 4. Interpreting the status information 5. Description of the Encoder Model 6. References 1. Overview =========== This is the first public release of our MPEG-2 encoder. It converts an ordered set of uncompressed input pictures into a compressed bitstream compliant with ISO/IEC 13818-2 DIS [1] (MPEG-2). This program will evolve to become: ISO/IEC 13818-5 Software Simulation of MPEG-2 Systems, Video, and Audio. 2. Features and Limitations =========================== 2.1 Features - generates constant bit rate streams - encoder model based on MPEG-2 test model 5 (TM5) rev. 2 [2] - progressive and interlaced video - also generates ISO/IEC 11172-2 (MPEG-1) sequences - input formats: separate YUV, combined YUV, PPM - trace and statistics output - verifies user parameter settings are legal within Profile and Level 2.2 Current limitations The encoder currently does not support - scalable extensions - field-coded pictures - generation of dual prime motion vectors - MPEG-1 integer pel vectors (half-pel is typically 1 dB better anyway) and D frame sequences. - checking for maximum number of generated bits per macroblock - automatic 3:2 pulldown detection or irregular 3:2 pulldown signaling. - intra refresh slices (e.g. low delay) - concealment motion vectors - special low delay mode rate control - editing of encoded video - variable bit rate encoding - scene change rate control 3. Usage ======== The execution template for the encoder is: mpeg2encode parameter_file output.m2v Coding parameters can be modified by editing the parameter_file. Since the parser expects the operating parameters to be on certain line numbers, kindly do not insert or delete lines from the file. Lines are terminated by ^M (Control-M). The first line of the parameter file is a comment which is inserted near the beginning of the MPEG bitstream as a user_data field, and can be used for arbitrary purposes. The remaining lines are described below: /* name of source frame files */ A printf format string defining the name of the input files. It has to contain exactly one numerical descriptor (%d, %x etc.): Example: frame%02d Then the encoder looks for files: frame00, frame01, frame02 The encoder adds an extension (.yuv, .ppm, etc.) which depends on the input file format. Input files have to be in frame format, containing two interleaved fields (for interlaced video). /* name of reconstructed frame files */ This user parameter tells the encoder what name to give the reconstructed frames. These frames are identical to frame reconstructions of decoders following normative guidelines (except of course for differences caused by different IDCT implementation). Specifying a name starting with - (or just - by itself) disables output of reconstructed frames. The reconstructed frames are always stored in Y,U,V format (see below), independent of the input file format. /* name of intra quant matrix file ("-": default matrix) */ Setting this to a value other than - specifies a file containing a custom intra quantization matrix to be used instead of the default matrix specified in ISO/IEC 13818-2 and 11172-2. This file has to contain 64 integer values (range 1...255) separated by white space (blank, tab, or newline), one corresponding to each of the 64 DCT coefficients. They are ordered line by line, i.e. v-u frequency matrix order (not by the zig-zag pattern used for transmission). The file intra.mat contains the default matrix as a starting point for customization. It is neither necessary or recommended to specify the default matrix explicitly. Large values correspond to coarse quantization and consequently more noise at that particular spatial frequency. For the intra quantization matrix, the first value in the file (DC value) is ignored. Use the parameter intra_dc_precision (see below) to define the quantization of the DC value. /* name of non intra quant matrix file ("-": default matrix) */ This parameter field follows the same rules as described for the above intra quant matrix parameter, but specifies the file for the NON-INTRA coded (predicted / interpolated) blocks. In this case the first coefficient of the matrix is NOT ignored. The default matrix uses a constant value of 16 for all 64 coefficients. (a flat matrix is thought to statistically minimize mean square error). The file inter.mat contains an alternate matrix, used in the MPEG-2 test model. /* name of statistics file */ Statistics output is stored into the specified file. - directs statistics output to stdout. /* input picture file format */ A number defining the format of the source input frames. Code Format description ---- ------------------------------------------------------------------ 0 separate files for luminance (.Y extension), and chrominance (.U, .V) all files are in headerless 8 bit per pixel format .U and .V must have half horizontal and vertical resolution (4:2:0). Note that in this document, Cb = U, and Cr = V. This format is also used in the Stanford encoder. 1 similar to 0, but concatenated into one file (extension .yuv) this format is used by the Berkeley MPEG-1 encoder 2 PPM, Portable PixMap, only the raw format (P6) is supported /* number of frames */ This defines the length of the sequence in integer units of frames. /* number of first frame */ Usually 0 or 1, but any other (positive) value is valid. /* timecode of first frame */ This line is used to set the timecode encoded into the first 'Group of Pictures' header. The format is based on the SMPTE style: hh:mm:ss:ff (hh=hour, mm=minute, ss=second, ff=frame (0..picture_rate-1) /* N (# of frames in GOP) */ This defines the distance between I frames (and 'Group of Pictures' headers). Common values are 15 for 30 Hz video and 12 for 25 Hz video. /* M (I/P frame distance) */ Distance between consecutive I or P frames. Usually set to 3. N has to be a multiple of M. M = 1 means no B frames in the sequence. (in a future edition of this program, M=0 will mean only I frames). /* ISO/IEC 11172-2 stream */ Set to 1 if you want to generate an MPEG-1 sequence. In this case some of the subsequent MPEG-2 specific values are ignored. /* horizontal_size */ Pixel width of the frames. It does not need to be a multiple of 16. You have to provide a correct value even for PPM files (the PPM file header is currently ignored). /* vertical_size */ Pixel height of the frames. It does not need to be a multiple of 16. You have to provide a correct value even for PPM files (the PPM file header is currently ignored). /* aspect_ratio_information */ Defines the display aspect ratio. Legal values are: Code Meaning ---- -------------- 1 square pels 2 4:3 display 3 16:9 display 4 2.21:1 display MPEG-1 uses a different coding of aspect ratios. In this cases codes 1 to 14 are valid. /* frame_rate_code */ Defines the frame rate (for interlaced sequences: field rate is twice the frame rate). Legal values are: Code Frames/sec Meaning ---- ---------- ----------------------------------------------- 1 24000/1001 23.976 fps -- NTSC encapsulated film rate 2 24 Standard international cinema film rate 3 25 PAL (625/50) video frame rate 4 30000/1001 29.97 -- NTSC video frame rate 5 30 NTSC drop-frame (525/60) video frame rate 6 50 double frame rate/progressive PAL 7 60000/1001 double frame rate NTSC 8 60 double frame rate drop-frame NTSC /* bit_rate */ A positive floating point value specifying the target bitrate. In units of bits/sec. /* vbv_buffer_size (in multiples 16 kbit) */ Specifies, according to the Video Buffering Verifier decoder model, the size of the bitstream input buffer required in downstream decoders in order for the sequence to be decoded without underflows or or overflows. You probably will wish to leave this value at 112 for MPEG-2 Main Profile at Main Level, and 20 for Constrained Parameters Bitstreams MPEG-1. /* low_delay */ When set to 1, this flag specifies whether encoder operates in low delay mode. Essentially, no B pictures are coded and a different rate control strategy is adopted which allows picture skipping and VBV underflows. This feature has not yet been implemented. Please leave at zero for now. /* constrained_parameters_flag */ Always 0 for MPEG-2. You may set this to 1 if you encode an MPEG-1 sequence which meets the parameter limits defined in ISO/IEC 11172-2 for constrained parameter bitstreams: horizontal_size <= 768 vertical_size <= 576 picture_area <= 396 macroblocks pixel_rate <= 396x25 macroblocks per second vbv_buffer_size <= 20x16384 bit bitrate <= 1856000 bits/second motion vector range <= -64...63.5 /* Profile ID */ Specifies the subset of the MPEG-2 syntax required for decoding the sequence. All MPEG-2 sequences generated by the current version of the encoder are either Main Profile or Simple Profile sequences. Code Meaning Typical use ---- -------------------------- ------------------------ 1 High Profile production equipment requiring 4:2:2 2 Spatially Scalable Profile Simulcasting 3 SNR Scalable Profile Simulcasting 4 Main Profile 95 % of TVs, VCRs, cable applications 5 Simple Profile Low cost memory, e.g. no B pictures /* Level ID */ Specifies coded parameter constraints, such as bitrate, sample rate, and maximum allowed motion vector range. Code Meaning Typical use ---- --------------- ----------------------------------------------- 4 High Level HDTV production rates: e.g. 1920 x 1080 x 30 Hz 6 High 1440 Level HDTV consumer rates: e.g. 1440 x 960 x 30 Hz 8 Main Level CCIR 601 rates: e.g. 720 x 480 x 30 Hz 10 Low Level SIF video rate: e.g. 352 x 240 x 30 Hz /* progressive_sequence */ 0 in the case of a sequences containing interlaced video (e.g. video camera source), 1 for progressive video (e.g. film source). /* video_format: 0=comp., 1=PAL, 2=NTSC, 3=SECAM, 4=MAC, 5=unspec. */ /* color_primaries */ Specifies the x, y chromaticity coordinates of the source primaries. Code Meaning ---- ------- 1 ITU-R Rec. 709 (1990) 2 unspecified 4 ITU-R Rec. 624-4 System M 5 ITU-R Rec. 624-4 System B, G 6 SMPTE 170M 7 SMPTE 240M (1987) /* transfer_characteristics */ Specifies the opto-electronic transfer characteristic of the source picture. Code Meaning ---- ------- 1 ITU-R Rec. 709 (1990) 2 unspecified 4 ITU-R Rec. 624-4 System M 5 ITU-R Rec. 624-4 System B, G 6 SMPTE 170M 7 SMPTE 240M (1987) 8 linear transfer characteristics /* matrix_coefficients */ Specifies the matrix coefficients used in deriving luminance and chrominance signals from the green, blue, and red primaries. Code Meaning ---- ------- 1 ITU-R Rec. 709 (1990) 2 unspecified 4 FCC 5 ITU-R Rec. 624-4 System B, G 6 SMPTE 170M 7 SMPTE 240M (1987) /* display_horizontal_size */ /* display_vertical_size */ Display_horizontal_size and display_vertical_size specify the "intended display's" active region (which may be smaller or larger than the encoded frame size). /* intra_dc_precision */ Specifies the effective precision of the DC coefficient in MPEG-2 intra coded macroblocks. 10-bits usually achieves quality saturation. Code Meaning ---- ----------------- 0 8 bit 1 9 bit 2 10 bit 3 11 bit /* top_field_first */ Specifies which of the two fields of an interlaced frame comes earlier. The top field corresponds to what is often called the "odd field," and the bottom field is also sometimes called the "even field." Code Meaning ---- ----------------- 0 bottom field first 1 top field first /* frame_pred_frame_dct (I P B) */ Setting this parameter to 1 restricts motion compensation to frame prediction and DCT to frame DCT. You have to specify this separately for I, P and B picture types. /* concealment_motion_vectors (I P B) */ Setting these three flags informs encoder whether or not to generate concealment motion vectors for intra coded macroblocks in the three respective coded picture types. This feature is mostly useful in Intra-coded pictures, but may also be used in low-delay applications (which attempts to exclusively use P pictures for video signal refresh, saving the time it takes to download a coded Intra picture across a channel). concealment_motion_vectors in B pictures are rather pointless since there is no error propagation from B pictures. This feature is currently not implemented. Please leave values at zero. /* q_scale_type (I P B) */ These flag sets linear (0) or non-linear (1) quantization scale type for the three respective picture types. This feature has not been integrated yet (modification to rate control is necessary). Please leave flags at zero for now. /* intra_vlc_format (I P B) */ Selects one of the two variable length coding tables for intra coded blocks. Table 1 is considered to be statistically optimized for Intra coded pictures coded within the sweet spot range (e.g. 0.3 to 0.6 bit/pixel) of MPEG-2. Code Meaning ---- ----------------- 0 table 0 (= MPEG-1) 1 table 1 /* alternate_scan (I P B) */ Selects one of two entropy scanning patterns defining the order in which quantized DCT coefficients are run-length coded. The alternate scanning pattern is considered to be better suited for interlaced video where the encoder does not employ sophisticated forward quantization (as is the case in our current encoder). Code Meaning ---- ----------------- 0 Zig-Zag scan (= MPEG-1) 1 Alternate scan /* repeat_first_field */ If set to one, the first field of a frame is repeated after the second by the display process. The exact function depends on progressive_sequence and top_field_first. repeat_first_field is mainly intended to serve as a signal for the Decoder's Display Process to perform 3:2 pulldown. /* progressive_frame */ Specifies whether the frames are interlaced (0) or progressive (1). MPEG-2 permits mixing of interlaced and progressive video. The encoder currently only supports either interlaced or progressive video. progressive_frame is therefore constant for all frames and usually set identical to progressive_sequence. /* intra_slice refresh picture period (P factor) */ This value indicates the number of successive P pictures in which all slices (macroblock rows in our encoder model) are refreshed with intra coded macroblocks. This feature assists low delay mode coding. It is currently not implemented. /* rate control: r (reaction parameter) */ /* rate control: avg_act (initial average activity) */ /* rate control: Xi (initial I frame global complexity measure) */ /* rate control: Xp (initial P frame global complexity measure) */ /* rate control: Xb (initial B frame global complexity measure) */ /* rate control: d0i (initial I frame virtual buffer fullness) */ /* rate control: d0p (initial P frame virtual buffer fullness) */ /* rate control: d0b (initial B frame virtual buffer fullness) */ These parameters modify the behavior of the rate control scheme. Usually set them to 0, in which case default values are computed by the encoder. /* P: forw_hor_f_code forw_vert_f_code search_width/height */ /* B1: forw_hor_f_code forw_vert_f_code search_width/height */ /* B1: back_hor_f_code back_vert_f_code search_width/height */ /* B2: forw_hor_f_code forw_vert_f_code search_width/height */ /* B2: back_hor_f_code back_vert_f_code search_width/height */ This set of parameters specifies the maximum length of the motion vectors. If this length is set smaller than the actual movement of objects in the picture, motion compensation becomes ineffective and picture quality drops. If it is set too large, an excessive number of bits is allocated for motion vector transmission, indirectly reducing picture quality, too. All f_code values have to be in the range 1 to 9 (1 to 7 for MPEG-1), which translate into maximum motion vector lengths as follows: code range (inclusive) max search width/height ================================================ 1 -8 ... +7.5 7 2 -16 ... +15.5 15 3 -32 ... +31.5 31 4 -64 ... +63.5 63 5 -128 ... +127.5 127 6 -256 ... +255.5 255 7 -512 ... +511.5 511 8 -1024 ... +1023.5 1023 9 -2048 ... +2047.5 2047 f_code is specified individually for each picture type (P,Bn), direction (forward prediction, backward prediction) and component (horizontal, vertical). Bn is the n'th B frame surrounded by I or P frames (e.g.: I B1 B2 B3 P B1 B2 B3 P ...). For MPEG-1 sequences, horizontal and vertical f_code have to be identical and the range is restricted to 1...7. P frame values have to be specified if N (N = # of frames in GOP) is greater than 1 (otherwise the sequences contains only I frames). M - 1 (M = distance between I/P frames) sets (two lines each) of values have to specified for B frames. The first line of each set defines values for forward prediction (i.e. from a past frame), the second line those for backward prediction (from a future frame). search_width and search_height set the (half) width of the window used for motion estimation. The encoder currently employs exhaustive integer vector block matching. Execution time for this algorithm depends on the product of search_width and search_height and, too a large extent, determines the speed of the encoder. Therefore these values have to be chosen carefully. Here is an example of how to set these values, assuming a maximum motion of 10 pels per frame in horizontal and 5 pels per frame in vertical direction and M=3 (I B1 B2 P): search width / height: forward hor. vert. backward hor. vert. I -> B1 10 5 B1 <- P 20 10 I -> B2 20 10 B2 <- P 10 5 I -> P 30 15 f_code values are then selected as the smallest ones resulting in a range larger than the search widths / heights: 3 2 30 15 /* P: forw_hor_f_code forw_vert_f_code search_width/height */ 2 1 10 5 /* B1: forw_hor_f_code forw_vert_f_code search_width/height */ 3 2 20 10 /* B1: back_hor_f_code back_vert_f_code search_width/height */ 3 2 20 10 /* B2: forw_hor_f_code forw_vert_f_code search_width/height */ 2 1 10 5 /* B2: back_hor_f_code back_vert_f_code search_width/height */ 4. Interpreting the status information ====================================== 4.1 Description of the macroblock_type map The status information routine prints a two-character code for each macroblock in the picture currently being coded: First character: S: skipped I: intra coded F: forward frame predicted f: forward field predicted B: backward frame predicted b: backward field predicted D: frame interpolated d: field interpolated 0: forward predicted without motion compensation Second character: space: coded, no quantization change Q: coded, quantization change N: not coded (only predicted) 4.2 Description of the mquant map The mquant map displays the dynamically changing quantization parameter as determined by the rate control algorithm. Larger values correspond to coarser quantization. Not displayed values indicate same quantization as in the previous macroblock. Currently all values are even, odd values occur only in conjunction with the (not yet implemented) non-linear quantization scale table. 5. Encoder model ================ The encoder model describes the "algorithm" or "intelligence" of the encoder. 5.1 Motion estimation Exhaustive search pattern with L1 (Minimum Absolute Difference) matching criteria on the original (non-coded) reference frame. Performed only on luminance samples. Half pel search is done on a neighborhood of 8 bi-linearly interpolated luminance samples from the reconstructed reference frame. 5.2 Rate control and adaptive quantization The encoder adheres to a single-pass coding philosophy (no a priori measurements guide the allocation of bits at the global layers). Target bit allocation for the current picture being encoded is based on global bit budget for the Group of Pictures (dependently coded sequence of pictures), and a ratio of weighted relative coding complexities of the three picture types. Coding complexity (X) is estimated as a picture's product of: average macroblock quantization step size (Q) and the number of bits (S) generated by coding the picture (e.g. X = Q*S). Local bit allocation is based on two measurements: 1. deviancy from estimated buffer fullness for the Nth macroblock 2. normalized spatial activity The picture is approximated and estimated to have a uniform distribution of bits. If the local trend of generated bits begin to stray from this estimation, a compensation factor emerges to modulate the macroblock quantization scale (mquant). The compensation factor is the difference between where the buffer fullness was predicted at the Nth macroblock and where the buffer fullness truly is) Local spatial activity is estimated as the minimum variance of the four luminance 8x8 blocks of the original picture being coded. The variance measure is then normalized against the average variance of the most recently coded picture of the same type. The scaled product of the local activity measure and the buffer compensation factor are combined to modify the final mquant value which will be used in the quantization stage of the subsequent block coding processes. 5.3 Decision The macroblock decision process selects the various prediction switches (yes/no coding of prediction error, yes/no motion compensation) which provide the best quality for the relative coding bit cost. The decision process follows the piecewise path of least distortion, approximating that the decision stages (whether to use forwards, backwards compensation or none at all..., etc.) are mostly uncorrelated (i.e. can be independently decided). 5.4 Macroblock coding The forward DCT is based on the fast Chen-Wang 1984 algorithm. Quantization is a mirror of the normative inverse quantizer, as specified in the MPEG-2 Test Model. No special dithering or entropy-constrained methods are currently employed. 6. References ============= [1] ISO/IEC 13818 Draft International Standard: Generic Coding of Moving Pictures and Associated Audio, Part 2: video [2] Test Model 5, ISO/IEC JTC1/SC29/WG11/ N0400, MPEG93/457, April 1993. re assists low delay mode coding. It is currently not implemented. /* rate control: r (reaction parameter) */ /* rate control: avg_act (initial average activity) */ /* rate control: Xi (initial I frame global complexity measure) */ /* rate control: Xp (initial P frampeg2/doc/FAQ 640 270 132 243410 5564131656 6310 MPEG-2 Technical (and sometimes political) Frequently Asked Questions (FAQ) list. Copyright 1994 by Chad Fogg (cfogg@netcom.com) Draft 3.3 (May 10, 1994) 1. MPEG is a DCT based scheme, right? 2. What does the MPEG video syntax feature that codes video efficiently? 3. What does the syntax provide for error robustness? 4. What is the significance of each layer in MPEG video ? 5. How does the syntax facilitate parallelism? 6. I hear the encoder is not part of the standard? 7. Are some encoders better than others? 8. Can MPEG-1 encode higher sample rates than 352 x 240 x 30 Hz ? 9. What are Constrained Parameters Bitstreams (CPB) for video? 10. Why is Constrained Parameters so important? 11. Who uses constrained parameters bitstreams? 12. Are there ways of circumventing constrained parameters bitstreams for SIF class applications and decoders ? 13. Are there any other conformance points like CPB for MPEG-1? 14. What frame rates are permitted in MPEG? 15. Special prediction switches for MPEG-2 16. What is MPEG-2 Video Main Profile and Main Level? 17. Does anybody actually use the scalability modes? 18. What's the difference between Field and Frame pictures? 19. What do B-pictures buy you? 20. Why do some people hate B-frames? 21. Why was the 16x16 area chosen? 22. Why was the 8x8 DCT size chosen? 23. What is motion compensated prediction, and why is it a pain? 24. What are the various prediction modes in MPEG-2? 24.1 Frame: 24.2 Field predictions in frame-coded pictures: 24.3 Field predictions in field-coded pictures: 24.4 16x8 predictions in field-coded pictures: 24.5 Dual Prime prediction in frame and field-coded pictures 24.6 Field and frame organized macroblocks: 25. How do you tell a MPEG-1 bitstream from a MPEG-2 bitstream? 26. What is the reasoning behind MPEG syntax symbols? 27. Why bother to research compressed video when there is a standard? 28. Where can I get a copy of the latest MPEG-2 draft? 29. What are the latest working drafts of MPEG-2 ? 30. What is the latest version of the MPEG-1 documents? 31. What is the evolution of ISO standard documents? 32. Where is a good introductory paper to MPEG? 33. What are some journals on related MPEG topics ? 34. Is there a book on MPEG video? 35. Is it MPEG-2 (Arabic numbers) or MPEG-II (roman)? 36. What happened to MPEG-3? 37. What is MPEG-4? 38. What are the scaleable modes of MPEG-2? 39. Why MPEG-2? Wasn't MPEG-1 enough? 40. What did MPEG-2 add to MPEG-1 in terms of syntax/algorithms ? 41. How do MPEG and JPEG differ? 42. How do MPEG and H.261 differ? 43. Is H.261 the de facto teleconferencing standard? 44. What is the TM rate control and adaptive quantization technique ? 45. How does the TM work? 46. What is a good motion estimation method, then? 47. Is exhaustive search "optimal" ? 48. What are some advanced encoding methods? 49. Is so-and-so really MPEG compliant ? 50. What are the tell-tale MPEG artifacts? 51. Where are the weak points of MPEG video ? 52. What are some myths about MPEG? 53. What is the color space of MPEG? 54. Dont you mean 4:1:1 ? 55. Why did MPEG choose 4:2:0 ? Isnt 4:2:2 the standard for TV? 56. What is the precision of MPEG samples? 57. What is all the fuss with cositing of chroma components? 58. How would you explain MPEG to the data compression expert? 59. How does MPEG video really compare to TV, VHS, laserdisc ? 60. What are the typical MPEG-2 bitrates and picture quality? 61. At what bitrates is MPEG-2 video optimal? 62. Why does film perform so well with MPEG ? 63. What is the best compression ratio for MPEG ? 64. Can MPEG be used to code still frames? 65. Is there an MPEG file format? 66. What are some pre-processing enhancements ? 67. Why use these "advanced" pre-filtering techniques? 68. What about post-processing enhancements? 69. Can motion vectors be used to measure object velocity? 70. How do you code interlaced video with MPEG-1 syntax? 71. Is MPEG patented? 72. How many cable box alliances are there? 73. Will there be an MPEG video tape format? 74. Where will be see MPEG in everyday life? 75. What is the best compression ratio for MPEG ? 76. Is there a MPEG CD-ROM format? 1. MPEG is a DCT based scheme, right? The DCT and Huffman algorithms receive the most press coverage (e.g. MPEG is a DCT based scheme with Huffman coding), but are in fact fairly insignificant. The variety of coding modes signaled to the decoder as context-dependent side information are chiefly responsible for the efficiency of the MPEG syntax. 2. What does the MPEG video syntax feature that codes video efficiently? A. Here are some of the statistical conditions and their syntax counterparts. Occlusion: forward, backwards, or bi-directional temporal prediction in B pictures. Smooth optical flow fields: variable length coding of 1-D prediction errors for motion vectors. Spatial correlation beyond 8x8 sample block boundaries: 1-D prediction of DC coefficients in consecutive group intra-coded macroblocks. High temporal correlation: variable on/off coding of prediction error at the macroblock (no-coding) or individual block (coded block pattern) level. Temporal de-correlation: forward, backwards, or bidirectional prediction. Content dependent quality: locally adaptive quantization Temporal prediction accuracy: "half-pel" sample accuracy. High locally correlated signal refresh pictures (I picture) and prediction errors: DCT Subjective coding: location-dependent quantization of DCT coefficients. 3. What does the syntax provide for error robustness? 1. Byte-aligned start codes in the coded bitstream. 2. End of block codes in coded blocks. 3. Slices. 4. slice_vertical_position embedded as sub-field within slice start codes. 5. slices commencing at regular locations in picture (MPEG-2) 4. What is the significance of each layer in MPEG video ? Sequence: Set of pictures sharing same sampling dimensions, bit rate, chromaticy (MPEG-1), quantization matrices (MPEG-1 only). Group of Pictures: Random access point giving SMPTE time code within sequence. Guaranteed to start with an I picture. Picture: Samples of a common plane -- "captured" from the same time instant. Slice: Error resynchronization unit of macroblocks. At the commencement of a slice, all inter-macroblock coding dependencies are reset. Likewise, all macroblocks within a common slice can be dependently coded. Macroblock: Least common multiple of Y, Cb, Cr 8x8 blocks in 4:2:0 sampling structure. For MPEG-1, the smallest granularity of temporal prediction. Block: Smallest granularity of spatial decorrelation. 5. How does the syntax facilitate parallelism? A. For MPEG-1, slices may consist of an arbitrary number of macroblocks. The coded bitstream must first be mapped into fixed-length elements before true parallelism in a decoder application can be exploited. Further, since macroblocks have coding dependencies on previous macroblocks within the same slice, the data hierarchy must be pre-processed down to the layer of DC DCT coefficients. After this, blocks may be independently inverse transformed and quantized, temporally predicted, and reconstructed to buffer memory. Parallelism is usually more of a concern for encoders. Macroblock motion estimation and some rate control stages can be processed independently. An encoder also has the freedom to choose the slice structure. 6. I hear the encoder is not part of the standard? A. The encoder rests just outside the normative scope of the standard, as long as the bitstreams it produces are compliant. The decoder, however, is almost deterministic: a given bitstream should reconstruct to a unique set of pictures. Statistically speaking, an occasional error of a Least Significant Bit is permitted as a result of the fact that the IDCT function is the only non-normative stage in the decoder (the designer is free to choose among many DCT algorithms and implementations). The IEEE 1180 test referenced in Annex A of the MPEG-1 and MPEG-2 specifications spells out the statistical mismatch tolerance between the Reference IDCT, which uses 64-bit floating point accuracy, and the Test IDCT. 7. Are some encoders better than others? A. Yes. For example, the range over which a compensated prediction macroblock is searched for has a great influence over final picture quality. At a certain point a very large range can actually become detrimental (it may encourage large differential motion vectors). Practical ranges are usually between +/- 15 and +/- 32. As the range doubles, for instance, the search area quadruples. 8. Can MPEG-1 encode higher sample rates than 352 x 240 x 30 Hz ? A. Yes. The MPEG-1 syntax permits sampling dimensions as high as 4095 x 4095 x 60 frames per second. The MPEG most people think of as "MPEG- 1" is actually a kind of subset known as Constrained Parameters bitstream (CPB). 9. What are Constrained Parameters Bitstreams (CPB) for video? A. MPEG-1 CPB are a limited set of sampling and bitrate parameters designed to normalize decoder computational complexity, buffer size, and memory bandwidth while still addressing the widest possible range of applications. The parameter limits were intentionally designed so that a decoder implementation would need only 4 Megabits of DRAM. Parameter Limit -------------- --------------------------- pixels/line 704 lines/picture 480 or 576 pixels*lines 352*240 or 352*288 picture rate 30 Hz bit rate 1.862million bits/sec buffer size 40 Kilobytes (327,680 bits) The sampling limits of CPB are bounded at the ever popular SIF rate: 396 macroblocks (101,376 pixels) per picture if the picture rate is less than or equal to 25 Hz, and 330 macroblocks (84,480 pixels) per picture if the picture rate is 30 Hz. The MPEG nomenclature loosely defines a "pixel" or "pel" as a unit vector containing a complete luminance sample and one fractional (0.25 in 4:2:0 format) sample from each of the two chrominance (Cb and Cr) channels. Thus, the corresponding bandwidth figure can be computed as: 352 samples/line x 240 lines/picture x 30 pictures/sec x 1.5 samples/pixel or 3.8 Ms/s (million samples/sec) including chroma, but not including blanking intervals. Since most decoders are capable of sustaining VLC decoding at a faster rate than 1.8 Mbit/sec, the coded video bitrate has become the most often waived parameter of CPB. An encoder which intelligently employs the syntax tools should achieve SIF quality saturation at about 2 Mbit/sec, whereas an encoder producing streams containing only I (Intra) pictures might require as much as 4 Mbit/sec to achieve the same video quality. 10. Why is Constrained Parameters so important? A. It is an optimum point that allows (just barely) cost effective VLSI implementations in 1992 technology (0.8 microns). It also implies a nominal guarantee of interoperability for decoders and encoders. Since CPB is a canonical conformance point, MPEG devices which are not capable of meeting SIF rates are usually not considered to be true MPEG. 11. Who uses constrained parameters bitstreams? A. Applications which are focused on CPB are Compact Disc (White Book or CD- I) and computer video applications. Set-top TV decoders fall into a higher sampling rate category known as CCIR 601 or Broadcast rate. 12. Are there ways of circumventing constrained parameters bitstreams for SIF class applications and decoders ? A. Yes, some. Remember that CPB limits pictures by macroblock count. 416 x 240 x 24 Hz sampling rates are still within the constraints, but this would only be of benefit in NTSC (240 lines/field) displays. Deviating from 352 samples/line could throw off many decoder implementations which possess limited horizontal sample rate conversion abilities. Some decoders do in fact include a few rate conversion modes, with a filter usually implemented via binary taps (shifts and adds). Likewise, the target sample rates are usually limited or ratios (e.g. 640, 540, 480 pixels/line, etc.). Future MPEG decoders will likely include on-chip arbitrary sample rate converters, perhaps capable of operating in the vertical direction (although there is little need of this in applications using standard TV monitors, with the possible exception of windowing in cable box graphical user interfaces). 13. Are there any other conformance points like CPB for MPEG-1? A. Undocumented ones, yes. A second generation of decoder chips emerged on the market about 1 year after the first wave of SIF-class decoders. Both LSI Logic and SGS-Thomson introduced CCIR 601 class MPEG-1 decodersto fill in the gap between canonical MPEG-1 and the emergence of MPEG-2. Under non- disclosure agreement, C-Cube had the CL-950. 14. What frame rates are permitted in MPEG? A. A limited set is available for the choosing in MPEG-1, although "tricks" could be played with Systems-layer Time Stamps to convey non-standard rates. The set is: 23.976 Hz (3-2 pulldown NTSC), 24 Hz (Film), 25 Hz (PAL/SECAM or 625/60 video), 29.97 (NTSC), 30 Hz (drop-frame NTSC or component 525/60), 50 Hz (double-rate PAL), 59.97 Hz (double rate NTSC), and 60 Hz (double-rate drop-frame NTSC/component 525/60 video). 15. Special prediction switches for MPEG-2 MPEG-2 sequence / \ progressive interlaced sequence sequence / \ Field picture Frame picture / \ Frame or field pred. Frame MB prediction only / \ Field dct Frame dct 16. What is MPEG-2 Video Main Profile and Main Level? A. MPEG-2 Video Main Profile and Main Level is analogous to MPEG-1's CPB,with sampling limits at CCIR 601 parameters (720 x 480 x 30 Hz). Profiles limit syntax (i.e. algorithms), whereas Levels place limits on coding parameters (sample rates, frame dimensions, coded bitrates, etc.). Together, Video Main Profile and Main Level (abbreviated as MP@ML) normalize complexity within feasible limits of 1994 VLSI technology (0.5 micron), yet still meet the needs of the majority of application users.MP@ML is the conformance point for most cable and satellite systems. Profiles ====== Simple: I and P pictures only. 4:2:0 sampling ratio. 8,9, or 10 bits DC precision. Main: I, P, and B pictures. Dual Prime with no B-pictures only. 4:2:0 sampling ratio. 8, 9, or 10 bits sample precision. SNR profile: Spatial profile: High: 8,9,10, or 11 bits sample precision. 4:2:2 and 4:4:4 sampling ratio. Level ==== Simple: SIF video rate (3.041280 Mhz), 4 Mbit/sec, 0.489472 Mbit VBV buffer, 64 vertical in frame, 32Vertical in field, 1:7 fcode hor. Main: CCIR 601 video rate (10.368 Mhz), 15 Mbit/sec, 1.835008 Mbit VBV buffer, 128 V in frame, 64 V in field, 1:8 f_code Hor. High 1440: 1440 x 1152 x 30 Hz (47.0016 Mhz), 60 Mbit/sec. 7.340032 Mbit VBV buffer, 128 V in Fe, 1:9 fcode H. High: 1920 x 1152 x 30 Hz (62.6688 Mhz), 80 Mbit/sec. 9.787392 Mbit VBV buffer. 1:9 fcode H 17. Does anybody actually use the scalability modes? A. At this time, scalability has found itself a limited number of applications, although research is definitely underway for its use in HDTV. Experiments have been demonstrated in Europe where, for example, PAL-rate video (720 x 576 x 25 fps) is embedded in the same stream as HDTV rate video (1440 x 1152 x 25 fps). The Nov. 1992 VADIS experiment divided the base layer (PAL) and enhancement into 4 and 16 Mbit/sec channels, respectively. The U.S. Grand Alliance favors HDTV simulcasting (separate NTSC analog and digital HDTV broadcasts). Temporal scalability is the pet scalability mode as the possible future solution for coding 60 Hz progressive sequences while maintaining backwards compatibility with early-wave equipment (e.g. 1920 x 1080 x 30 Hz displays) . To elaborate, the first wave receivers of the late 1990s would be limited to 62at 0 Hz interlaced/30 Hz progressive HDTV decoders. Essentially, 60 interlaced fields would be coded in a, for example, 16 Mbit/sec stream in 1996, and when VLSI processes shift another thousand or so angstroms down the wavelength scale, an 8 Mbit/sec enhancement layer containing the coded "high pass" between 60 Hz progressive and 60 Hz interlaced would be simulcasted or multiplexed. Several corporate mouths have been known to water at the mention of charging the quality conscious subscriber an extra fee for the enhancement layer. 18. What's the difference between Field and Frame pictures? A. A frame-coded picture consists of samples from both even and odd fields. A frame picture is coded in progressive order (an even line, then an odd line, etc.) and in the case of MPEG-2, may optionally switch between field and frame order on a macroblock basis. The Display Process, which is *almost* completely outside the scope of the MPEG specification, can chose to re- interlace the picture by displaying the odd and even lines at different times (16 milliseconds apart for 60 Hz displays). In fact, most pictures, regardless of whether they were coded as a Field or Frame, end up being displayed interlaced due to the fact that most TV sets are interlaced. 19. What do B-pictures buy you? A. Since bi-directional macroblock predictions are an average of two macroblock areas, noise is reduced at low bit rates (like a 3-D filter, if you will). At nominal MPEG-1 video (352 x 240 x 30, 1.15 Mbit/sec) rates, it is said that B-frames improves SNR by as much as 2 dB. (0.5 dB gain is usually considered worth-while in MPEG). However, at higher bit rates, B- frames become less useful since they inherently do not contribute to the progressive refinement of an image sequence (i.e. not used as prediction by subsequent coded frames). Regardless, B-frames are still politically controversial. B pictures are interpolative in two ways: 1. predictions in the bi- directional macroblocks are an average from block areas of two pictures 2. B pictures fill in or interpolate the 3-D video signal over a 33 or 25 millisecond picture period without contributing to the overall signal quality beyond that immediate point in time. In other words, a B pictures, regardless of its internal make-up of macroblock types, has a life limited to its immediate self. As mentioned before, its energy does not propagate into other frames. In a sense, bits spent on B pictures are wasted. 20. Why do some people hate B-frames? A. Computational complexity, bandwidth, delay, and picture buffer size are the four B-frame Pet Peeves. Computational complexity in the decoder is increased since a some macroblock modes require averaging between two macroblocks. Worst case, memory bandwidth is increased an extra 15.2 MByte/s (4:2:0 601 rates, not including any half pel or page-mode overhead) for this extra prediction. An extra picture buffer is needed to store the future prediction reference (bi-directionality). Finally, extra delay is introduced in encoding since the frame used for backwards prediction needs to be transmitted to the decoder before the intermediate B-pictures can be decoded and displayed. Cable television (e.g. -- more like i.e.-- General Instruments) have been particularly adverse to B-frames since, for CCIR 601 rate video, the extra picture buffer pushes the decoder DRAM memory requirements past the magic 8- Mbit (1 Mbyte) threshold into the evil realm of 16 Mbits (2 Mbyte).... although 8-Mbits is fine for 352 x 480 B picture sequence. However, cable often forgets that DRAM does not come in convenient high-volume (low cost) 8- Mbit packages as does the friendly 4-Mbit and 16-Mbit. In a few years, the cost difference between 16 Mbit and 8 Mbit will become insignificant compared to the bandwidth savings gain through higher compression. For the time being, some cable boxes will start with 8-Mbit and allow future drop-in upgrades to the full 16-Mbit. 21. Why was the 16x16 area chosen? A. The 16x16 area corresponds to the Least Common Multiple (LCM) of 8x8 blocks, given the normative 4:2:0 chroma ratio. Starting with medium size images, the 16x16 area provides a good balance between side information overhead & complexity and motion compensated prediction accuracy. In gist, 16x16 seemed like a good trade-off. 22. Why was the 8x8 DCT size chosen? A. Experiments showed little improvements with larger sizes vs. the increased complexity. A fast DCT algorithm will require roughly double the arithmetic operations per sample when the transform point size is doubled. Naturally, the best compaction efficiency has been demonstrated using locally adaptive block sizes (e.g. 16x16, 16x8, 8x8, 8x4, and 4x4) [See Baker and Sullivan]. Naturally, this introduces additional side information overhead and forces the decoder to implement programmable or hardwired recursive DCT algorithms. If the DCT size becomes too large, then more edges (local discontinuities) and the like become absorbed into the transform block, resulting in wider propagation of Gibbs (ringing) and other phenomena. Finally, with larger transform sizes, the DC term is even more critically sensitive to quantization noise. 23. What is motion compensated prediction, and why is it a pain? A. MCP in the decoder can be thought of as having four stages: 1. Motion vector computation 2. Prediction retrieval various predictions are 16x16, 16x8, 8x4, 8x8 plus any half-pel overhead (e.g. 17x16, 17x17, etc). 3. Filtering 3.1 Forming half-pel predictions through bi-linear interpolation. 3.2 Averaging two predictions together (B macroblocks, Dual Prime) 4. Combination and ordering 4.1 combining 1 or 2 predictions from stage three into upper and lower halves (16 x 8, field in frame) 4.2 interleaving or grouping together odd and even lines in frame picture predictions. The final, combined prediction is always a 16x16 block of luminance and 8x8 block of chrominance, just like we experience in MPEG-1. A single motion vector can be associated with each source, hence a macroblock can have as many as 4 motion vectors. 24. What are the various prediction modes in MPEG-2? 24.1 Frame: Predictions are formed from a 16 x 16 pixel area in a previously reconstructed frame. Identical to MPEG-1. There can be only one source in forward or backward predicted macroblocks, and two sources in bi-directional macroblocks. The prediction frame itself may have been coded as either a frame or two fields, however once a frame is reconstructed, it is simply a frame as far as future predictions are concerned. 24.2 Field predictions in frame-coded pictures: Separate predictions are formed for the top (8 lines from field 1)and bottom (8 lines from field 2) portions of the macroblock. A total of two motion vectors in forward or backward predictions, four in bi-directional. 24.3 Field predictions in field-coded pictures: Predictions are formed from the two most recently decoded fields. Prediction sizes are 16x16, however the 16 lines have a corresponding projection onto a 16x32 pixel area of a frame. One motion vector for forward or backward predictions, and two for bi-directional. 24.4 16x8 predictions in field-coded pictures: Like field macroblocks in frame-coded pictures, the upper and lower 8 lines in this macroblock mode can have different predictions (hence two motion vectors). This mode compensates for the reduced temporal prediction precision of field picture macroblocks (a result of the fact that fields inherently possess half the number of lines that frames do). The field prediction area projected onto a frame is restored to 16 lines. 2 motion vectors for backwards or forwards, 4 for bi-directional. 24.5 Dual Prime prediction in frame and field-coded pictures Predictions for the current macroblock are formed from the average of two 16 x 8 line areas from the two most recently decoded fields. Dual Prime was devised as an alternative for B pictures in low delay applications, but still offers many of the signal quality benefits of B-pictures. Dual Prime requires one less prediction picture buffer, but still retains the same instantaneous prediction bandwidth of a B picture system. As an alternative to coding separate motion vectors for each of the upper and lower 16x8 areas, a full motion vector is sent for the first area, and a +1, 0, or -1 differential vector (variable length coded) is specified for the second prediction area. A macroblock will have total of two full motion vectors and two differential vectors in frame-coded pictures. Due to the prediction bandwidth overhead, Main Profile restricts the use of Dual Prime prediction to P picture sequences only. High Profile permits use of Dual Prime in B pictures. 24.6 Field and frame organized macroblocks: Originally intended as a cheaper means of achieving field-decorrelation in frame-coded pictures without the fussy overhead of separate field prediction estimates, the dct coefficients (quantized prediction error for a given macroblock) may be organized into either a field or frame pattern. Essentially this means that the prediction error for the combined 16x16 macroblock may be grouped into field or frame blocks. A bit in the macroblock header (dct_type) indicates whether the upper and lower portions of the macroblock are to be interleaved (frame organized) or remain separated (field organized). 25. How do you tell a MPEG-1 bitstream from a MPEG-2 bitstream? A. All MPEG-2 bitstreams must contain specific extension headers that *immediately* follow MPEG-1 headers. At the highest layer, for example, the MPEG-1 style sequence_header() is followed by sequence_extension() exclusive to MPEG-2. Some extension headers are specific to MPEG-2 profiles. For example, sequence_scalable_extension() is not allowed in Main Profile bitstreams. A simple program need only scan the coded bitstream for byte-aligned start codes to determine whether the stream is MPEG-1 or MPEG-2. 26. What is the reasoning behind MPEG syntax symbols? A. Here are some of the Whys and Wherefores of MPEG symbols: Start codes These 32-bit byte-aligned codes provide a mechanism for cheaply searching coded bitstreams for commencement of various layers of video without having to actually parse variable-length codes or perform any decoder arithmetic. Start codes also provide a mechanism for resynchronization in the presence of bit errors. Coded block pattern (CBP --not to be confused with Constrained Parameters!) When the frame prediction is particularly good, the displaced frame difference (DFD, or prediction error) tends to be small, often with entire block energy being reduced to zero after quantization. This usually happens only at low bit rates. Coded block patterns prevent the need for transmitting EOB symbols in those zero coded blocks. DCT_coefficient_first Each intra coded block has a DC coefficient. With coded block patterns signaling all possible combinations of all-zero valued blocks, the dct_coef_first mechanism assigns a different meaning to the VLC codeword that would otherwise represent EOB as the first coefficient. End of Block: Saves unnecessary run-length codes. At optimal bitrates, there tends to be few AC coefficients concentrated in the early stages of the zig-zag vector. In MPEG-1, the 2-bit length of EOB implies that there is an average of only 3 or 4 non-zero AC coefficients per block. In MPEG-2 Intra (I) pictures, with a 4-bit EOB code, this number is between 9 and 16 coefficients. Since EOB is required for all coded blocks, its absence can signal that a syntax error has occurred in the bitstream. Macroblock stuffing A genuine pain for VLSI implementations, macroblock stuffing was introduced to maintain smoother, constant bitrate control in MPEG-1. However, with normalized complexity measures and buffer management performed a priori (pre-frame, pre-slice, and pre-macroblock) in the MPEG-2 encoder test model, the need for such localized smoothing evaporated. Stuffing can be achieved through virtually unlimited slice start code padding if required. A good rule of thumb: if you find yourself often using stuffing more than once per slice, you probably don't have a very good rate control algorithm. Anyway, macroblock stuffing is now illegal in MPEG-2, so don t start using it if you already haven t. MPEG's modified Huffman VLC tables The VLC tables in MPEG are not Huffman tables in the true sense of Huffman coding, but are more like the tables used in Group 3 fax. They are entropy constrained, that is, non-downloadable and optimized for a limited range of bit rates (sweet spots). With the exception of a few codewords, the larger tables were carried over from the H.261 standard of 1990. MPEG-2 added an "Intra table". Note that the dct_coefficient tables assume positive/negative coefficient pmf symmetry. 27. Why bother to research compressed video when there is a standard? A. Despite the worldwide standard, many areas remain open for research: advanced encoding and pre-processing, motion estimation, macroblock decision models, rate control and buffer management in editing environments, etc. There's practically no end to it. 28. Where can I get a copy of the latest MPEG-2 draft? A. Contact your national standards body (e.g. ANSI Sales in NYC for the U.S., British Standards Institute in the UK, etc.). A number of private organizations offer ISO documents. 29. What are the latest working drafts of MPEG-2 ? A. MPEG-2 has reached voting document of the Draft International Standard for : Information Technology -- Generic Coding of Moving Pictures and Associated Audio. Recommendation H.262, ISO/IEC Draft International Standard 13818-2. [produced March 25, 1994, not yet approved by voting process]. Audio is Part 1, Video Part 2, and Systems is Part 3. A committee draft for Conformance (Part 4) is expected in Novemeber 1994, as well as the Technical Report on Software Simulation (Part 5). 30. What is the latest version of the MPEG-1 documents? A. Systems (ISO/IEC IS 11172-1), Video (ISO/IEC IS 11172-2), and Audio (ISO/IEC IS 11172-3) have reached the final document stage. Part 4, Conformance Testing, is currently DIS 31. What is the evolution of ISO standard documents? A. In chronological order: ISO/Committee notation Authors notation --------------------------------------- ------------------------- Problem (unofficial first stage) Barroom Witticism New work Item (NI) Napkin Item New Proposal (NP) Need Permission Working Draft (WD) Were Drunk Committee Draft (CD) Calendar Deadlock Draft International Standard (DIS) Doesnt Include Substance International Standard (IS) Induced patent Statements 32. Where is a good introductory paper to MPEG? A. Didier Le Gall, "MPEG: A Video Compression Standard for Multimedia Applications," Communications of the ACM, April 1991, Vol.34, No.4, pp. 47-58 33. What are some journals on related MPEG topics ? A. IEEE Transactions on Consumer Electronics IEEE Transactions on Broadcasting IEEE Transactions on Circuits and Systems for Video Technology Advanced Electronic Imaging Electronic Engineering Times (EE Times -- more tabloid coverage. Unfortunate columns by Richard Doherty) IEEE Int'l Conference on Acoustics, Speech, and Signal Processing (ICASSP) International Broadcasting Convention (IBC) Society of Motion Pictures and Television Engineers (SMPTE) SPIE conference on Visual Communications and Image Processing SPIE conference on Video Compression for Personal Computers IEEE Multimedia [first edition Spring 1994] 34. Is there a book on MPEG video? A. Yes, there will be a book published sometime in 1994 by the same authors who brought you the JPEG book (Bill Pennebaker, Joan Mitchell). Didier Le Gall will be an additional co-author, and will insure digressions into, e.g. arithmetic coding aspects, be kept to a minimum :-) 35. Is it MPEG-2 (Arabic numbers) or MPEG-II (roman)? A. Committee insiders most often use the Arabic notation with the hyphen, e.g. MPEG-2. Only the most retentive use the official designation: Phase 2. In fact, M.P.E.G. itself is a nickname. The official title is: ISO/IEC JTC1 SC29 WG11. The militaristic lingo has so far managed to keep the enemy (DVI) confused and out of the picture. ISO: International Organization for Standardization IEC: International Electrotechnical Commission JTC1: Joint Technical Committee 1 SC29: Sub-committee 29 WG11: Work Group 11 (moving pictures with... uh, audio) 36. What happened to MPEG-3? A. MPEG-3 was to have targeted HDTV applications with sampling dimensions up to 1920 x 1080 x 30 Hz and coded bitrates between 20 and 40 Mbit/sec. It was later discovered that with some (compatible) fine tuning, MPEG-2 and MPEG-1 syntax worked very well for HDTV rate video. The key is to maintain an optimal balance between sample rate and coded bit rate. Also, the standardization window for HDTV was rapidly closing. Europe and the United States were on the brink of committing to analog-digital subnyquist hybrid algorithms (D-MAC, MUSE, et al). European all-digital projects such as HD-DIVINE and VADIS demonstrated better picture quality with respect to bandwidth using the MPEG syntax. In the United States, the Sarnoff/NBC/Philips/Thomson HDTV consortium had used MPEG-1 syntax from the beginning of its all-digital proposal, and with the exception of motion artifacts (due to limited search range in the encoder), was deemed to have the best picture quality of all three digital proponents. HDTV is now part of the MPEG-2 High-1440 Level and High Level toolkit. 37. What is MPEG-4? A. MPEG-4 targets the Very Low Bitrate applications defined loosely as having sampling dimensions up to 176 x 144 x 10 Hz and coded bit rates between 4800 and 64,000 bits/sec. This new standard would be used, for example, in low bit rate videophones over analog telephone lines. This effort is in the very early stages. Morphology, fractals, model based, and anal retentive block transform coding are all in the offering. MPEG-4 is now in the application identification phase. Scaleable modes of MPEG-2 38. What are the scaleable modes of MPEG-2? A. Scaleable video is permitted only in the High Profiles. Currently, there are four scaleable modes in the MPEG-2 toolkit. These modes break MPEG-2 video into different layers (base, middle, and high layers) mostly for purposes of prioritizing video data. For example, the high priority channel (bitstream) can be coded with a combination of extra error correction information and/or increased signal strength (i.e. higher Carrier- to-Noise ratio or lower Bit Error Rate) than the lower priority channel. For example, in HDTV, the high priority bitstream (720 x 480) can be decoded under noise conditions were the lower priority (1440 x 960) cannot. This is part of the "graceful degradation concept. Breaking a video signal into two streams (base and enhancements) has a penalty, however. Usually less than 1.5 dB. Another purpose of salability is complexity division. A standard TV set need only decode the 720 x 480 channel, thus requiring a less expensive decoder processor than a TV set wishing to display 1440 x 960. This is known as simulcasting. A brief summary of the MPEG-2 video scalability modes: Spatial Scalablity-- Useful in simulcasting, and for feasible software decoding of the lower resolution, base layer. This spatial domain method codes a base layer at lower sampling dimensions (i.e. "resolution") than the upper layers. The upsampled reconstructed lower (base) layers are then used as prediction for the higher layers. Data Partitioning-- Similar to JPEG's frequency progressive mode, only the slice layer indicates the maximum number of block transform coefficients contained in the particular bitstream (known as the "priority break point"). Data partitioning is a frequency domain method that breaks the block of 64 quantized transform coefficients into two bitstreams. The first, higher priority bitstream contains the more critical lower frequency coefficients and side informations (such as DC values, motion vectors). The second, lower priority bitstream carries higher frequency AC data. SNR Scalability-- Similar to the point transform in JPEG, SNR scalability is a spatial domain method where channels are coded at identical sample rates, but with differing picture quality (achieved through quantization step sizes). The higher priority bitstream contains base layer data that can be added to a lower priority refinement layer to construct a higher quality picture. Temporal Scalability--- A temporal domain method useful in, e.g., stereoscopic video. The first, higher priority bitstreams codes video at a lower frame rate, and the intermediate frames can be coded in a second bitstream using the first bitstream reconstruction as prediction. In stereoscopic vision, for example, the left video channel can be prediction from the right channel. Other scalability modes were experimented with in MPEG-2 video (such as Frequency Scalability), but were eventually dropped in favor of methods that demonstrated comparable or better picture quality with greater simplicity. 39. Why MPEG-2? Wasn't MPEG-1 enough? A. MPEG-1 was optimized for CD-ROM or applications at about 1.5 Mbit/sec. Video was strictly non-interlaced (i.e. progressive). The international cooperation executed well enough for MPEG-1, that the committee began to address applications at broadcast TV sample rates using the CCIR 601 recommendation (720 samples/line by 480 lines per frame by 30 frames per second or about 15.2 million samples/sec including chroma) as the reference. Unfortunately, today's TV scanning pattern is interlaced. This introduces a duality in block coding: do local redundancy areas (blocks) exist exclusively in a field or a frame.(or a particle or wave) ? The answer of course is that some blocks are one or the other at different times, depending on motion activity. The additional man years of experimentation and implementation between MPEG-1 and MPEG-2 improved the method of block-based transform coding. 40. What did MPEG-2 add to MPEG-1 in terms of syntax/algorithms ? A. Here is a brief summary: Sequence layer: More aspect ratios. A minor, yet necessary part of the syntax. Horizontal and vertical dimensions are now required to be a multiple of 16 in frame coded pictures, and the vertical dimension must be a multiple of 32 in field coded pictures. 4:2:2 and 4:4:4 macroblocks were added in the Next profiles. Syntax can now signal frame sizes as large as 16383 x 16383. Syntax signals source video type (NTSC, PAL, SECAM, MAC, component) to help post-processing and display. Source video color primaries (609, 170M, 240M, D65, etc.) and opto- electronic transfer characteristics (709, 624-4M, 170M etc.) can be indicated. Four scaleable modes [see scalability discussion] Picture layer: All MPEG-2 motion vectors are specified to a half-pel sample grid. DC precision can be user-selected as 8, 9, 10, or 11 bits. New scalar quantization matrices may be downloaded once per picture. In High profile, separate chrominance matrices now exist (Y and C no longer have to share) Concealment motion vectors were added to I-pictures in order to increase robustness from bit errors. I pictures are the most critical and sensitive picture in a group of pictures. A non-linear macroblock quantization factor providing a wider dynamic range, from 0.5 to 56, than the linear MPEG-1 (1 to 32) range. Both are sent as a 5-bit FLC side information in the macroblock and slice headers. New Intra-VLC table for dct_coefficient_next (AC run-level events) that is a better match for the histogram of Intra-coded pictures. EOB is 4 bits. The old table, dct_coef_next, are reserved for use in non-intra pictures (P, B), although they new table can be used for Intra-coded macroblocks in P and B pictures as well. Alternate scanning pattern that (supposedly) improves entropy coding performance over the original Zig-Zag scan used in H.261, JPEG, and MPEG-1. The extra scanning pattern is geared towards interlaced video. Syntax to signal an irregular 3:2 pulldown process (repeat_field_first flag) Progressive and interlaced frame coding Syntax to indicate source composite video characteristics useful in post- processing operations. (v-axis, field sequence, sub_carrier, phase, burst_amplitude, etc.) Pan & scanning syntax that tells decoder how to, for example, window a 4:3 image within a wider 16:9 aspect ratio coded image. Vertical pan offset has 1/16th pixel accuracy. Macroblock layer: Macroblock stuffing is now illegal in MPEG-2 (hurray!!). If stuffing is really needed, the encoder can pad slice start codes. Two organizations for macroblock coefficients (interlaced and progressive) signaled by dct_type flag. Now only one run-level escape code code (24-bits) instead of the single (20- bits) and double escape (28-bits) in MPEG-1. Improved mismatch control in quantization over the original oddification method in MPEG-1. Now specifies adding or subtracting one to the 63rd AC coefficient depending on parity of the summed coefficients. MPEG-2 mismatch control is performed on the transform coefficients, whereas in MPEG- 1, it is applied to the quantized transform coefficients. Many additional prediction modes (16x8 MC, field MC, Dual Prime) and, correspondingly, macroblock modes. Overall, MPEG-2's greatest compression improvements over MPEG-1 are: prediction modes, Intra VLC table, DC precision, non-linear macroblock quantization. Implementation improvements: macroblock stuffing was eliminated. 41. How do MPEG and JPEG differ? A. The most fundamental difference is MPEG's use of block-based motion compensated prediction (MCP)---a method falling into the general category of temporal DPCM. The second most fundamental difference is in the target application. JPEG adopts a general purpose philosophy: independence from color space (up to 255 components per frame) and quantization tables for each component. Extended modes in JPEG include two sample precision (8 and 12 bit sample accuracy), combinations of frequency progressive, spatial hierarchically progressive, and amplitude (point transform) progressive scanning modes. Further color independence is made possible thanks to downloadable Huffman tables (up to one for each component.) Since MPEG is targeted for a set of specific applications, there is only one color space (4:2:0 YCbCr), one sample precision (8 bits), and one scanning mode (sequential). Luminance and chrominance share quantization and VLC tables. MPEG adds adaptive quantization at the macroblock (16 x 16 pixel area) layer. This permits both smoother bit rate control and more perceptually uniform quantization throughout the picture and image sequence. However, adaptive quantization is part of the Enhanced JPEG charter (ISO/IEC 10918-3) currently in verification stage. MPEG variable length coding tables are non-downloadable, and are therefore optimized for a limited range of compression ratios appropriate for the target applications. The local spatial decorrelation methods in MPEG and JPEG are very similar. Picture data is block transform coded with the two-dimensional orthanormal 8x8 DCT, with asymmetric basis vectors about time (aka DCT- II). The resulting 63 AC transform coefficients are mapped in a zig-zag pattern (or alternative scan pattern in MPEG-2) to statistically increase the runs of zeros. Coefficients of the vector are then uniformly scalar quantized, run-length coded, and finally the run-length symbols are variable length coded using a canonical (JPEG) or modified Huffman (MPEG) scheme. Global frame redundancy is reduced by 1-D DPCM of the block DC coefficients, followed by quantization and variable length entropy coding of the quantized DC coefficient. MCP DCT ZZ Q Frame -> 8x8 spatial block -> 8x8 frequency block -> Zig-zag scan -> RLC VLC quanitzation -> run-length coding -> variable length coding. The similarities have made it possible for the development of hard-wired silicon that can code both standards. Even some highly microcoded architectures employing hardwired instruction primitives or functional blocks benefit from JPEG/MPEG similarities. There are many additional yet minor differences. They include: 1. In addition to the 8-bit mode, DCT and quantization precision in MPEG has a 9-bit and 12-bit mode, respectively, exclusively in non- intra coded macroblocks. A 1-bit expansion takes place in the macroblock difference operation. 2. Mismatch control in MPEG-1 forces quantized coefficients to become odd values (oddification). JPEG does not employ any mismatch mechanism. 3. JPEG run-length coding produces run-size tokens (run of zeros, non-zero coefficient magnitude) whereas MPEG produces fully concatenated run-level tokens that do not require magnitude differential bits. 4. DC values in MPEG-1 are limited to 8-bit precision (a constant stepsize of 8), whereas JPEG DC precision can occupy all possible 11- bits. MPEG-2, however, re-introduced extra DC precision critical even at high compression ratios. Difference between MPEG and H.261 42. How do MPEG and H.261 differ? A. H.261, also known as Px64, was targeted for teleconferencing applications where motion is naturally more limited. Motion vectors are restricted to a range of +/- 15 pixel unit displacements. Prediction accuracy is reduced since H.261 motion vectors are specified to only integer-pel accuracy. Other quality syntactic differences include: no B-pictures, inferior mismatch control. 43. Is H.261 the de facto teleconferencing standard? A. Not exactly. To date, about seventy percent of the industrial teleconferencing hardware market is controlled by PictureTel of Mass. The second largest market controller is Compression Labs of Silicon Valley. PictureTel hardware includes compatibility with H.261 as a lowest common denominator, but when in communication with other PictureTel hardware, it can switch to a mode superior at low bit rates (less than 300kbits/sec). In fact, over 2/3 of all teleconferencing is done at two-times switched 56 channel (~P = 2) bandwidth. ISDN is still expensive. In each direction, video and audio are coded at an aggregate rate of 112 kbits/sec (2*56 kbits/sec). The PictureTel proprietary compression algorithm is acknowledged to be a combination of spatial pyramid, lattice vector quantizer, and an unidentified entropy coding method. Motion compensation is considerably more refined and sophisticated than the 16x16 integer-pel block method specified in H.261. The Compression Labs proprietary algorithm also offers significant improvement over H.261 when linked to other CLI hardware. Local decorrelation is based on a DCT-VQ hybrid. Currently, ITU-TS (International Telecommunications Union-- teleconferencing Sector), formerly CCITT, is quietly defining an improvement to H.261 with the participation of industry vendors. Rate control 44. What is the TM rate control and adaptive quantization technique ? A. The Test model (MPEG-2) and Simulation Model (MPEG-1) were not, by any stretch of the imagination, meant to epitomize state-of-the art encoding quality. They were, however, designed to exercise the syntax, verify proposals, and test the *relative* compression performance of proposals in a timely manner that could be duplicated by co- experimenters. Without simplicity, there would have been no doubt endless debates over model interpretation. Regardless of all else, more advanced techniques would probably trespass into proprietary territory. The final test model for MPEG-2 is TM version 5b, aka TM version 6. The final MPEG-1 simulation model is version 3. The MPEG-2 TM rate control method offers a dramatic improvement over the SM method. TM adds more accurate estimation of macroblock complexity through use of limited a priori information. Macroblock quantization adjustments are computed on a macroblock basis, instead of once-per-slice. 45. How does the TM work? A. Rate control and adaptive quantization are divided into three steps: Step One:Bit Allocation In Complexity Estimation, the global complexity measures assign relative weights to each picture type (I,P,B). These weights (Xi, Xp, Xb) are reflected by the typical coded frame size of I, P, and B pictures (see typical frame size discussion). I pictures are usually assigned the largest weight since they have the greatest stability factor in an image sequence. B pictures are assigned the smallest weight since B energy do not propagate into other pictures and are usually highly correlated with neighboring P and I pictures. The bit target for a frame is based on the frame type, the remaining number of bits left in the Group of Pictures (GOP) allocation, and the immediate statistical history of previously coded pictures. Step Two: Rate Control Rate control attempts to adjust bit allocation if there is significant difference between the target bits (anticipated bits) and actual coded bits for a block of data. If the virtual buffer begins to overflow, the macroblock quantization step size is increased, resulting in a smaller yield of coded bits in subsequent macroblocks. Likewise, if underflow begins, the step size is decreased. The Test Model approximates that the target picture has spatially uniform distribution of bits. This is a safe approximation since spatial activity and perceived quantization noise are almost inversely proportional. Of course, the user is free to design a custom distribution, perhaps targeting more bits in areas that contain text, for example. Step Three: Adaptive Quantization The final step modulates the macroblock quantization step size obtained in Step 2 by a local activity measure. The activity measure itself is normalized against the most recently coded picture of the same type (I, P, or B). The activity for a macroblock is chosen as the minimum among the four 8x8 block luminance variances. Choosing the minimum block is part of the concept that a macroblock is no better than the block of highest visible distortion (weakest link in the chain). 46. What is a good motion estimation method, then? A. When shopping for motion vectors, the three basic characteristics are: Search range, search pattern, and matching criteria. Search pattern has the greatest impact on finding the best vector. Hierarchical search patterns first find the best match between downsampled images of the reference and target pictures and then refine the vector through progressively higher resolutions. When compared to other fast methods, hierarchical patterns are less likely to be confused by extremely local distortion minimums as being a best match. Also note that subsampled search and hierarchical search are not synonymous. Q. Is there a limit to the length of motion vectors? The search area is unlimited, but the reconstructed motion vectors must not: a. point beyond the picture boundaries (1 <= MV_x <= luminancewidth - 16) and (1 <= MV_y <= luminanceheight - 16). The - 16 is due to the fact that the motion vector origin is the upper left hand corner of a macroblock) b. In Constrained Parameters MPEG-1, the motion vector is limited to a range of [-64,+63.5] luminance samples with half-pel accuracy, and [- 128,+127.5] with integer pel accuracy. Break the constrained parameters rules and your video sequence will not likely display on many hardware devices. c. In MPEG-2 Video Main Profile at Main Level, the motion vectors are always on a half-pel co-ordinate grid, and the vertical range is restricted to [-64, +63.5], and the horizontal limit is [-256,+255.5]. d. in MPEG-1, the syntactic limit of the motion vector is [-1024,+1023] integer pel, horizontal and vertical. e. in MPEG-2, the syntactic limit of the motion vector is [-2048,+2047.5] horizontal, [-1024,+1023.5] vertical. 47. Is exhaustive search "optimal" ? A. Definitely not in the context of block-based MCP video. Since one motion vector represents the prediction of 256 pixels, divergent pixels within the macroblock are misrepresented by the "global" vector. This leads back to the general philosophy of block-based coding as an approximation technique. In their ICASSP93 paper, Sullivan discusses ways in which block-based prediction schemes can solve part of this problem. Exhaustive search may find blocks with the least distortion (displaced frame difference) but will not produce motion vectors with the lowest entropy. 48. What are some advanced encoding methods? Quantizer feedback: determine the dependent quantization stepsize by modeling quantization error propagating over multiple pictures. [Uz/et al ICASSP 93, Ortega/Vetterli/et al ICASSP 93] Smoothness constraint placed on local activity measures. immediate blocks outside target macroblock are considered when selecting macroblock quantization stepsize .[Thomson/Savitier patent] Horizontal variance: measure variance between columns of pixels in addition to the traditional measure of variance along rows (lines) when making field/frame macroblock prediction decision. DFD energy: examine DFD energy/variance when making Intra/Non-intra macroblock decision. Activity measures: use total bits from a first-pass encoding of a picture or macroblock as a measure of the activity. Coded bits is a more accurate reflection of local complexity than variance. [Thomson/Savitier patent] motion vector cost: this is true for any syntax elements, really. Signaling a macroblock quantization factor or a large motion vector differential can cost more than making up the difference with extra quantized DFD (prediction error) bits. The optimum can be found with, some Lagrangian operator. In summary, any compression system with side information, there is a optimum point between signaling overhead (e.g. prediction) and prediction error. Liberal Interpretations of the Forward DCT: Borrowing from the concept that the DCT is simply a filter bank, a technique that seems to be gaining popularity is basis vector shaping. Usually this is combined with the quantization stage since the two are tied closely together in a rate-distortion sense. The idea is to use the basis vector shaping as a cheap alternative to pre-filtering by combining the more desirable data adaptive properties of pre-filtering/ pre-processing into the transformation process... yet still reconstruct a picture in the decoder using the standard IDCT that looks reasonably like the source. Some more clever schemes will apply a form of windowing. [Warning: watch out for eigenimage/basis vector orthoganality. ] Frequency-domain enhancements: Enhancements are applied after the DCT (and possibly quantization)stage to the transform coefficients. This borrows from the concept: if you don't like the (quantized) transformed results, simply reshape them into something you do like. Suppressing isolated small amplitudes is popular. Temporal spreading of quantization error: This method is similar to the original intent behind color subcarrier phase alternation by field in the NTSC, PAL, and SECAM analog TV standards: for stationary areas, noise does not hang" in one location, but dances about the image over time to give a more uniform effect. Distribution makes it more difficult for the eye to "catch on" to trouble spots (due to the latent temporal response curve of human vision). Simple encoder models tend to do this naturally but will not solve all situations. Look-ahead and adaptive frame cycle structures: analyze picture activity several pictures into the future, looking for scene changes or motion statistics. It is easy to spot encoders that do not employ any advanced encoding techniques: reconstructed video usually contains ringing around edges, color bleeding, and lots of noise. 49. Is so-and-so really MPEG compliant ? A. At the very least, there are two areas of conformance/compliance in MPEG: 1. Compliant bitstreams 2. compliant decoders. Technically speaking, video bitstreams consisting entirely of I-frames (such as those generated by Xing software) are syntactically compliant with the MPEG specification. The I-frame sequence is simply a subset of the full syntax. Compliant bitstreams must obey the range limits (e.g. motion vectors limited to +/-128, frame sizes, frame rates, etc.)and syntax rules (e.g. all slices must commence and terminate with a non-skipped macroblock, no gaps between slices, etc.). Decoders, however, cannot escape true conformance. For example, a decoder that cannot decode P or B frames are *not* legal MPEG. Likewise, full arithmetic precision must be obeyed before any decoder can be called "MPEG compliant." The IDCT, inverse quantizer, and motion compensated predictor must meet the specification requirements... which are fairly rigid (e.g. no more than 1 least significant bit of error between reference and test decoders). Real-time conformance is more complicated to measure than arithmetic precision, but it is reasonable to expect that decoders that skip frames on reasonable bitstreams are not likely to be considered compliant. Artifacts 50. What are the tell-tale MPEG artifacts? A. If the encoder did its job properly, and the user specified a proper balance between sample rate and bitrate, there shouldn't be any visible artifacts. However, in sub-optimal systems, you can look for: Gibbs phenomenon/Ringing/Aliasing (too few AC bits, not enough pre-processing) Blockiness (not considering your neighbors before quantizing) Posterization (too few DC bits) Checkerboards (DCT eigenimages as a result of too few AC coefficients) Colorbleeding (not considering color in encoder cost model, not subtracting color at edges of objects, etc.) 51. Where are the weak points of MPEG video ? A. Texture patterns (rapidly alternating lines) sharp edges (especially text) [installment 3] 52. What are some myths about MPEG? A. There are a few major myths that I am aware of: 1. Block displacements: macroblock predictions are formed out of arbitrary 16x16 (or 16x8/16x16 in MPEG-2) areas from previously reconstructed pictures. Many people believe that the prediction macroblocks have boundaries that fall on interchange boundaries (pixel 0, 15, 31, 53... line 0, 15, 31, 53... etc.). In fact, motion vectors represent relative translations with respect to the target reconstruction macroblock coordinates. The motion vectors can point to half pixel coordinates, requiring that the prediction macroblock to be formed via bi-linear interpolation of pixels. 2. Displaced frame (macroblock) difference construction: the prediction error formed as the difference between the prediction macroblock and source macroblock is coded much like an Intra macroblock. The prediction may come from different locations (as in bi-directional prediction--or in MPEG-2--16x8, field-in-frame, and Dual Prime), but the DFD is always coded as a 16x16 unit. 3. Compression ratios You hear 200:1 and 100:1 in the media. Utter rubbish. The true range is between 16:1 and 40:1. Spreading misinformation about compression ratios in public will catch the attention of the infamous MPEG Police. They say mild-mannered Michael Barnsley will snap, without warning, into violent rage if he doesnt get the upper bunk bed. 4. Picture coding types all consist of the same macroblocks Macroblocks within I pictures are strictly intra-coded. Macroblocks within P pictures can be either predicted or intra-coded, and B pictures they can be bi-directional, forward, backward, or intra. Additional macroblock modes switches include: predicted with no motion compensation, modified macroblock quantization, coding of prediction error or not. The switches are concatenated into the macroblock_type side information and variable length coded in the macroblock header. 53. What is the color space of MPEG? MPEG strictly specifies the YCbCr color space, not YUV or YIQ or YPbPr or YDrDb or any other color difference variations. Regardless of any bitstream parameters, MPEG-1 and MPEG-2 Video Main Profile specify 4:2:0 chroma ratio, where the color difference channels (Cb, Cr) have half the resolution or sample grid density in both the horizontal and vertical direction with respect to luminance. MPEG-2 High Profile includes an option for 4:2:2 and 4:4:4 coding. Applications for this are likely to be broadcasting and contribution equipment. 54. Dont you mean 4:1:1 ? A. No, here is a table of ratios: CCIR 601 (60 Hz) image Chroma sub-sampling factors format Y Cb, Cr Vertical Horizontal ----- --------- ---------- -------- ---------- 4:4:4 720 x 480 720 x 480 none none 4:2:2 720 x 480 360 x 480 none 2:1 4:2:0 720 x 480 360 x 240 2:1 2:1 4:1:1 720 x 480 720 x 120 none 4:1 4:1:0 720 x 480 180 x 120 4:1 4:1 3:2:2, 3:1:1, and 3:1:0 are less common variations. 55. Why did MPEG choose 4:2:0 ? Isnt 4:2:2 the standard for TV? A. At least three reasons I can think of: 1. 4:2:0 picture memory requirements are 33% less than the size of 4:2:2 pictures. MPEG-1 decoder are able to snugly fit all 3 SIF pictures (1 reconstruction & display, 2 prediction) into 512 KBytes of buffer space. CCIR 601 is a tighter fit into 2 Mbytes. 2. The subjective difference between 4:2:0 and 4:2:2 is minimal, when considering consumer display equipment and distribution compression ratios. 3. Vertical decimation increases compression efficiency by reducing syntax overhead posed in an 8 block (4:2:0) macroblock structure. 4. You re compressing the hell out of the video signal, so what possible difference can the 0:0:2 high-pass make? Interlacing and the 62 microsecond gap between successively scanned lines introduces some discontinuities, but most of this can be alleviated through pre-processing. 56. What is the precision of MPEG samples? A. By definition, MPEG samples have no more and no less than 8-bits uniform sample precision (256 quantization levels). For luminance (which is unsigned) data, black corresponds to level 0, white is level 255. However, in CCIR recommendation 601 chromaticy, levels 0 through 14 and 236 through 255 are reserved for blanking signal excursions. MPEG currently has no such clipped excursion restrictions, although decoder might take care to insure active samples do not exceed these limits. With three color components per pixel, the total combination is roughly 16.8 million colors (i.e. 24-bits). 57. What is all the fuss with cositing of chroma components? A. It is moderately important to properly co-site chroma samples, otherwise a sort of chroma shifting effect (exhibited as a halo) may result when the reconstructed video is displayed. In MPEG-1 video, the chroma samples are exactly centered between the 4 luminance samples (Fig 1.) To maintain compatibility with the CCIR 601 horizontal chroma locations and simplify implementation (eliminate need for phase shift), MPEG-2 chroma samples are arranged as per Fig.2. Y Y Y Y Y Y Y Y YC Y YC Y C C C C Y Y X Y Y Y Y Y YC Y YC Y Y Y Y Y Y Y Y Y YC Y YC Y C C C C Y Y Y Y Y Y Y Y YC Y YC Y Fig.1 MPEG-1 Fig.2 MPEG-2 Fig.3 MPEG-2 and 4:2:0 organization 4:2:0 organization CCIR Rec. 601 4:2:2 organization MPEG for the data compression expert 58. How would you explain MPEG to the data compression expert? A. MPEG video is a block-based video scheme. 59. How does MPEG video really compare to TV, VHS, laserdisc ? A. VHS picture quality can be achieved for source film video at about 1 million bits per second (with proprietary encoding methods). It is very difficult to objectively compare MPEG to VHS. The response curve of VHS places -3 dB at around 2 MHz of analog luminance bandwidth (equivalent to 200 samples/line). VHS chroma is considerably less dense in the horizontal direction than MPEG source video (compare 80 samples/line to 176!). From a sampling density perspective, VHS is superior only in the vertical direction (480 luminance lines compared to 240)... but when taking into account (supposedly such things as) interfield magnetic tape crosstalk and the TV monitor Kell factor, the perceptual vertical advantage is not all that significant. VHS is prone to such inconveniences as timing errors (an annoyance addressed by time base correctors), whereas digital video is fully discretized. Pre-recorded VHS is typically recorded at very high duplication speeds (5 to 15 times real time playback speed), opening up additional avenues for artifacts. In gist, MPEG-1 at its nominal parameters can match VHSs sexy low-pass-filtered look. With careful coding schemes, broadcast NTSC quality can be approximated at about 3 Mbit/sec, and PAL quality at about 4 Mbit/sec. Of course, sports sequences with complex spatial-temporal activity should be treated with bit rates more like 5 and 6 Mbit/sec, respectively. Laserdisc is a tough one to compare. Laserdiscs are encoded with composite video (NTSC or PAL). Manufacturers of laser disc players make claims of up to 425 TVL (or 567 samples/line) response. Thus it could be said the laserdisc has a 567 x 480 x 30 Hz "potential resolution". The carrier-to-noise ratio is typically better than 48 dB. Timing is excellent. Yet some of the clean characteristics of laserdisc can be achieved with MPEG-1 at 1.15 Mbit/sec (SIF rates), especially for those areas of medium detail (low spatial activity) in the presence of uniform motion. This may be why some people say MPEG-1 video at 1.15 Mbit/sec looks almost as good as Laserdisc or Super VHS at times. 60. What are the typical MPEG-2 bitrates and picture quality? Picture type I P B Average MPEG-1 SIF @ 1.15 Mbit/sec 150,000 50,000 20,000 38,000 MPEG-2 601 400,000 200,000 80,000 130,000 @ 4.00 Mbit/sec Note: parameters assume Test Model for encoding, I frame distance of 15 (N = 15), and a P frame distance of 3 (M = 3). Of course, among differing source material, scene changes, and use of advanced encoder models... these numbers can be significantly different. 61. At what bitrates is MPEG-2 video optimal? A. The Test subgroup has defined a few examples: "Sweet spot" sampling dimensions and bit rates for MPEG-2: Dimensions Coded rate Comments ------------- ---------- ---------------------------------------- --- 352x480x24 Hz 2 Mbit/sec Half horizontal 601. Looks almost NTSC (progressive) broadcast quality, and is a good (better) substitute for VHS. Intended for film src. 544x480x30 Hz 4 Mbit/sec PAL broadcast quality (nearly full capture (interlaced) of 5.4 MHz luminance carrier). Also 4:3 image dimensions windowed within 720 sample/line 16:9 aspect ratio via pan&scan. 704x480x30 Hz 6 Mbit/sec Full CCIR 601 sampling dimensions. (interlaced) [these numbers subject to change at whim of MPEG Test subgroup] 62. Why does film perform so well with MPEG ? A. Several reasons, really: 1) The frame rate is 24 Hz (instead of 30 Hz) which is a savings of some 20%. 2) the film source video is inherently progressive. Hence no fussy interlaced spectral frequencies. 3) the pre-digital source was severely oversampled (compare 352 x 240 SIF to 35 millimeter film at, say, 3000 x 2000 samples). This can result in a very high quality signal, whereas most video cameras do not oversample, especially in the vertical direction. 4) Finally, the spatial and temporal modulation transfer function (MTF) characteristics (motion blur, etc) of film are more amenable to the transform and quantization methods of MPEG. 63. What is the best compression ratio for MPEG ? A. The MPEG sweet spot is about 1.2 bits/pel Intra and .35 bits/pel inter. Experimentation has shown that intra frame coding with the familiar DCT-Quantization-Huffman hybrid algorithm achieves optimal performance at about an average of 1.2 bits/sample or about 6:1 compression ratio. Below this point, artifacts become noticeable. 64. Can MPEG be used to code still frames? A. Yes. There are, of course, advantages and disadvantages to using MPEG over JPEG: Disadvantages: 1. MPEG has only one color space 2. MPEG-1 and MPEG-2 Main Profile luma and chroma share quanitzation and VLC tables 3. MPEG-1 is syntactically limited to 4k x 4k images, and 16k x 16k for MPEG-2. Advantages: 1. MPEG possesses adaptive quantization 2. With its limited still image syntax, MPEG averts any temptation to use unnecessary, expensive, and academic encoding methods that have little impact on the overall picture quality (you know who you are). Philips CD-I spec. has a requirement for a MPEG still frame mode, with double SIF image resolution. This is technically feasible mostly thanks to the fact that only one picture buffer is needed to decode a still image instead of three buffers. 65. Is there an MPEG file format? A. Not exactly. The necessary signal elements that indicate image size, picture rate, aspect ratio, etc. are already contained within the sequence layer of the MPEG video stream. The Whitebook format for Karoke and CD-I movies specify a range of (time-division) multiplexing strategies for audio and video bitstreams. A directory format listing scenes and their locations on the disc is associated with the White Book specification. 66. What are some pre-processing enhancements ? Adaptive de-interlacing: This method maps interlaced video from a higher sampling rate (e.g 720 x 480) into a lower rate, progressive format (352 x 240). The most basic algorithm measures the correlation between two immediate macroblock fields, and if the correlation is high enough, uses an average of both fields to form a frame macroblock. Otherwise, a field area from one field (usually of the same parity) is selected. More clever algorithms are much more complex than this, and may involve median filtering, and multirate/multidimensional tools. Pre-anti-aliasing and Pre-blockiness reduction: A common method in still image coding is to pre-smooth the image before encoding. For example, if pre-analysis of a frame indicates that serious artifacts will arise if the picture were to be coded in the current condition (i.e. below the sweet spot), a pre-anti-aliasing filter can be applied. This can be as simple as having a smoothing severity proportional to the image activity. The pre-filter can be global (same smoothing factor for whole image or sequence) or locally adaptive. More complex methods will again use multirate/multidimensional methods. One straightforward concept from multidimensional/multirate e-processing is to apply source video whose resolution (sampling density) is greater than the target source and reconstruction sample rates. This follows the basic principles of oversampling, as found in A/D converters. These filters emphasize the fact that most information content is contained in the lower harmonics of a picture anyway. VHS is hardly considered to be a sharp cut-off medium, tragically implying that "320 x 480 potential" of VHS is never truly realized. 67. Why use these "advanced" pre-filtering techniques? A. Think of the DCT and quantizer as an A/D converter. Think of the DCT/Q pre-filter as the required anti-alias prefilter found before every A/D. The big difference of course is that the DCT quantizer assigns a varying number of bits per transform coefficient. Judging on the normalized activity measured in the pre-analysis stage of video encoding (assuming you even have a pre-analysis stage), and the target buffer size status, you have a fairly good idea of how many bits can be spared for the target macroblock, for example. Other pre-filtering techniques mostly take into account: texture patterns, masking, edges, and motion activity. Many additional advanced techniques can be applied at different immediate layers of video encoding (picture, slice, macroblock, block, etc.). 68. What about post-processing enhancements? Some research has been carried out in this area. Non-linear interpolation methods have been published by Wu and Gersho (e.g. ICASSP 93), convex hull projections for MAP (Severinson, ICASSP 93), and others. Post-processing unfortunately defies the spirit of MPEG conformance. Decoders should produce similar reconstructions. Enhancements should ideally be done during the pre- processing and encoding stages. 69. Can motion vectors be used to measure object velocity? A. Motion vector information cannot be reliably used as a means of determining object velocity unless the encoder model specifically set out to do so. First, encoder models that optimize picture quality generate vectors that typically minimize prediction error and, consequently, the vectors often do not represent true object translation. Standards converters that resample one frame rate to another (as in NTSC to PAL) use different methods (motion vector field estimation, edge detection, et al) that are not concerned with optimizing ratios such as SNR vs bitrate. Secondly, motion vectors are not transmitted for all macroblocks anyway. 70. How do you code interlaced video with MPEG-1 syntax? A. Two methods can be applied to interlaced video that maintain syntactic compatibility with MPEG-1 (which was originally designed for progressive frames only). In the field concatenation method, the encoder model can carefully construct predictions and prediction errors that realize good compression but maintain field integrity (distinction between adjacent fields of opposite parity). Some pre-processing techniques can also be applied to the interlaced source video that would, e.g., lessen sharp vertical frequencies. This technique is not efficient of course. On the other hand, if the original source was progressive (e.g. film), then it is more trivial to convert the interlaced source to a progressive format before encoding. (MPEG-2 would then only offer superior performance through greater DC block precision, non-linear mquant, intra VLC, etc.) Reconstructed frames are re-interlaced in the decoder Display process. The second syntactically compatible method codes fields as separate pictures. This approach has been acknowledged not to work as well. 71. Is MPEG patented? A. Yes and no. Many encoding methods are patented. Approximately 11 blocking patents, that is, patents that are general enough to be unavoidable in any implementation have been recently identified. A patent pool is being formed within MPEG where a single royalty fee would be split among the 31 patent-holding companies. 72. How many cable box alliances are there? A. Many. To start with: Scientific Atlanta (SA), Kaledia, and Motorola: SA will build the box, Motorola the chips, and Kaleida the O/S and user interface (using ScriptX of course). Silicon Graphics (SGI), Scientific Atlanta, and Toshiba For the Time Warner's Orlando trial, SGI will provide the RISC (MIPS R4000) and software, SA will do the box again, and Toshiba will provide the chips. General Instruments (GI) and Microsoft: GI will make the box and Intel will supply the special low-cost 386SL processor on which a 1MB flash EPROM executable core of Microsoft windows and DOS will run. Microsoft will develop the user interface. Hewlett Packard (HP): HP will manufacture and/or design low cost, open architecture set-top decoder boxes (not a part of the Eon wireless deal). The CPU will explicitly not use a 80x68 based processor. CLI and Philips: Compression Labs will provide the encoder technology and Philips will provide the decoder techology for an ADSL system whose transport structure will be put together by Broadband Technologies. ["These alliances subject to change at the whim of PR departments and market forces."] 73. Will there be an MPEG video tape format? A. Not exactly. A consortium of international companies are co- developing a consumer digital video 6 millimeter wide, metal particle tape format. Due to the initial high cost of MPEG encoders, a JPEG-like compression method will be used for inexpensive encoding of typical consumer source video (broadcast PAL, NTSC). The natural consequence of still image methods is less efficient use of bandwidth: 25 Mbit/sec for the same subjective real-time playback quality achieved at 6 Mbit/sec possible with MPEG-2. A second bit rate mode, 50 Mbit/sec, is designated for HDTV. Pre-coded digital video from, e.g., broadcast sources will be directly recorded to tape and "passed-through" as a coded bitstream to the video decompression box upon tape playback. Assuming if linear tape speed is to be proportional to bit rate, the recording time of a pre-compressed MPEG-2 program at the upper limit of 5 Mbit/sec for broadcast quality video, the recording time would be over 20 hours. Channel coding schemes (error correction, convolution coding, etc.), however, will most likely be optimized for the tape medium and therefore may differ from the channel methods for cable, terrestrial, and satellite. (A Zenith-Goldstar S-VHS based experiment did, however, directly record the 4-VSB broadcast baseband signal of the old Zenith/AT&T HDTV proposal). More specs: (Summarized from EE Times July 5, 1993 article) tape width: 6.35 mm Audio: two channel 48 KHz 16-bit audio, or 4 channel at 32 KHz at 12-bit Tape format: metal evaporated tape, 13.5 microns thick Cassette dimensions: (millimeters) Recording times: Size Width Height Depth 525/625 (25Mb/sec) HDTV (50 Mb/s) -------- ----- ------ ----- ------------------ -------------- Standard 125 78 14.6 4h30min 2h15min Small 66 48 12.2 1 hour 30min Linear tape speeds: 18.812 mm/s (60Hz), 18.831 mm/s (50 Hz) Video compression: DCT based Participants: Matsushita, Sony, Philips, Thomson, Hitachi, Mitsubishi, Sanyo, Sharp, Toshiba, JVC. MPEG in everyday life 74. Where will be see MPEG in everyday life? A. Just about wherever you see video today. DBS (Direct Broadcast Satellite) The Hughes/USSB DBS service will use MPEG-2 video and audio. Thomson has exclusive rights to manufacture the decoding boxes for the first 18 months of operation. Hughes/USSB DBS will begin its U.S. service in April 1994. Two satellites at 101 degrees West will share the power requirements of 120 Watts per 27 MHz transponder over a total of 32 transponders. Multi source channel rate control methods will be employed to optimally allocate bits between several programs normalized to one 22 Mbit/sec data carrier. Bit allocation adapts to instantaneous co- channel spatial and co-channel temporal activity. An average of 150 channels are planned with the addition of a second set of satellites augmenting the power level of each transponder to 240 Watts. The coded throughput of each transponder will increase to 30 Mbit/sec. CATV (Cable Television) Despite conflicting options, the cable industry has more or less settled on MPEG-2 video. Audio is less than settled. For example, General Instruments (the largest U.S. consumer cable set-top box manufacturer) have announced the planned exclusive use of Dolby AC-3. The General Instruments DigiCipher I video syntax is similar to MPEG-2 syntax, but employs smaller macroblock predictions and no B-frames. The DigiCipher II specification will include modes to support both the GI and full MPEG-2 Video Main Profile syntax. Digicipher-I services such as HBO will upgrade to DigiCipher II in 1994. HDTV The U.S. Grand Alliance, a consortium of companies that formerly competed to win the U.S. terrestrial HDTV standard, have already agreed to use the MPEG-2 Video and Systems syntax---including B-pictures. Both interlaced(1920 x 1080 x 30 Hz) and progressive (1280 x 720 x 60 Hz) modes will be supported. The Alliance has also settled upon a modulation method (VSB) convolution coding (Viterbi), and error correction (Reed- Soloman) specification. In September 1993, the consortium of 85 European companies signed an agreement to fund a project known Digital Video Broadcasting (DVB) which will develop a standard for cable and terrestrial transmission by the end of 1994. The scheme will use MPEG-2. This consortium has put the final nail in the coffin of the D-MAC scheme for gradual migration towards an all-digital, HDTV consumer transmission standard. The only remaining analog or digital-analog hybrid system left in the world is NHK's MUSE (which will probably be axed in a few years as soon as it appears to be politically secure thing to do). 75. What is the best compression ratio for MPEG ? A. The MPEG sweet spot is about 1.2 bits/pel Intra and .35 bits/pel inter. Experimentation has shown that intra frame coding with the familiar DCT-Quantization-Entropy hybrid algorithm achieves optimal performance at about an average of 1.2 bits/sample or about 6:1 compression ratio. Below this point, artifacts become noticeable. 76. Is there a MPEG CD-ROM format? A. Yes, a consortium of international companies (Matsushita, Philips, Sony, JVC, et al) have agreed upon a specification for MPEG video and audio. 2 hour long movies are stored on two 650 MByte compact discs. The video rate is 1.15 Mbit/sec, the audio rate is either 128 kbit/sec or 192 kbit/sec Layer I or Layer II.(this seems to contradict the Philips 224 kbit/s audio spec?). Although the Video, Systems, and Audio syntax are identical, the CD-I movie format and the White Book format are not compatible. Researchers are busy experimenting with denser and faster rate CD formats, perhaps using green or blue laser wavelengths. One demonstration stretched the pit and track density to its limits, improving areal density by almost 2 fold. vertical frequencies. This technique is not efficient of course. On the other hand, if the original source was progressive (e.g. film), then it is more trivial to convert the interlaced source to a progressive format before encoding. (MPEG-2 wmpeg2/doc/mpeg2dec.doc 640 270 132 14462 5565712654 10122 mpeg2decode =========== MPEG-2 Decoder, Version 1.0, May 1994 MPEG Software Simulation Group (MPEG-L@netcom.com) The program mpeg2decode is our implementation of an ISO/IEC DIS 13818-2 decoder. It converts MPEG-1 and MPEG-2 video bitstreams into uncompressed video. Features ======== + decodes non-scalable, spatial scalable, SNR scalable and data partitioning MPEG-2 video bitstreams + supports Simple, Main, SNR Scalable and Spatially Scalable Profile streams at all defined levels + decodes MPEG-1 (ISO/IEC IS 11172-2) video bitstreams (except D-picture sequences) + several output formats: separate and interleaved Y,U,V component, Truevision TGA, PBMPLUS PPM + optional output of detailed decoding information + robustness against stream syntax errors + fast IEEE 1180-1990 compliant integer arithmetic inverse DCT + optional double precision floating point inverse DCT Missing Features ================ - spatial scalability other than interlaced -> interlaced - D-picture MPEG-1 sequences - chroma format 4:2:2, 4:4:4 - temporal scalability - error concealment - repeat_field_first and other mostly display process oriented features Introduction ============ mpeg2decode takes one or more ISO/IEC DIS 13818-2 [1] MPEG-2 video bitstreams and converts them to uncompressed video. Since MPEG-2 is (by definition) forward compatible with MPEG-1, mpeg2decode also decodes MPEG-1 sequences (ISO/IEC IS 11172-2 [2]). The decoder is not optimized for speed, although some parts (e.g. variable length decoding, inverse DCT) are based on relatively fast algorithms. The emphasis was on correct implementation of the standard and simple structure of the program. Its main purpose is to demonstrate a sample implementation of an MPEG-2 decoder and to serve as an educational tool. Our hope is that this implementation makes it easier to understand the relatively complex details of the standard. As you can deduce from the list of missing features, mpeg2decode is still under development. However, we considered the current version to be complete enough to justify a public release. The decoder has been extensively tested on bitstreams produced by a variety of encoders from the MPEG research community to ascertain validity of the implementation. Of course we can't guarantee complete compliance with the standard. Usage ===== mpeg2decode {options} input.m2v {upper.m2v} outfile Options: -vn verbose output (n: level) Instructs mpeg2decode to generate informative ouput about the sequence to stdout. Increasing level (-v1, -v2, etc.) results in more detailed output. -on output format (0: YUV, 1: SIF, 2: TGA, 3:PPM) To choose a file format for the decoded pictures. Default is 0 (YUV). The following formats are currently supported: YUV: three headerless files, one for each component. The luminance component is stored with an extension of .Y, the chrominance components are stored as .U and .V respectively, with half resolution in both dimensions (4:2:0). All components are stored in row storage from top left to bottom right. SIF: one headerless file, with interleaved components. Component order is Cb, Y, Cr, Y. This format is also known as Abekas or CCIR Rec. 656 format. The chrominance components have half resolution in horizontal direction (4:2:2) and are aligned with the even luminance samples. File extension is .SIF. TGA: Truevision TGA [4] 24 bit R,G,B format in uncompressed (no run length coding) format with .tga extension. PPM: Portable PixMap format as defined in PBMPLUS [5], a graphics package by Jef Poskanzer. Extension is .ppm. -f store interlaced frames in frame format By default, interlaced video is stored field by field. The -f option permits to store both fields of a frame into one file. -r use double precision reference IDCT The -r option selects a double precision inverse DCT which is primarily useful for comparing results from different decoders. The defaults is to use a faster integer arithmetic only IDCT implementation which meets the criteria of IEEE 1180-1990 [3]. -s infile spatial scalable sequence Spatial scalable video is decoded in two passes. The -s option specifies the names of the output files from the first (lower layer) pass to the second (enhancement layer) pass. 'infile' describes the name format of the lower layer pictures for spatial scalable sequences in a format similar to outfile as described below. outfile describes the names of the output files as a printf format string; it has to contain exactly one integer format descriptor (e.g. %d, %02d) and, except for frame storage (-f option or progressive video), a %c descriptor example: out%02d_%c generates files out00_a.*, out00_b.*, out01_a.*, ... ('a' denotes the top field, 'b' the bottom field, .* is the suffix appropriate for the output format) upper.m2v is the name of the upper layer bitstream of an SNR scalable stream or a data partioning scalable bitstream (input.m2v is the lower layer). Examples ======== non-scalable stream (one layer, one pass): mpeg2decode base.m2v f%d%c SNR-scalable stream (two layers, one pass): mpeg2decode base.m2v snr.m2v f%d%c spatial-scalable stream (two layers, two passes): mpeg2decode base.m2v l%d%c mpeg2decode -s l%d%c spatial.m2v f%d%c hybrid spatial/SNR-scalable stream (three layers, two passes): mpeg2decode base.m2v l%d%c mpeg2decode -s l%d%c spatial.m2v snr.m2v f%d%c hybrid SNR/spatial-scalable stream (three layers, two passes): mpeg2decode base.m2v snr.m2v l%d%c mpeg2decode -s l%d%c spatial.m2v f%d%c hybrid SNR/spatial/SNR-scalable stream (four layers, two passes): mpeg2decode base.m2v snr1.m2v l%d%c mpeg2decode -s l%d%c spatial.m2v snr2.m2v f%d%c etc. References ========== [1] Draft International Standard ISO/IEC DIS 13818: Generic Coding of Moving Pictures and Associated Audio, Part 2: Video. [2] International Standard ISO/IEC IS 11172: Coding of moving pictures and associated audio for digital storage media up to about 1,5 Mbit/s, Part 2: Video. [3] IEEE Standard Specifications for the Implementations of 8 by 8 Inverse Discrete Cosine Transform, IEEE Std 1180-1990, December 6, 1990. [4] Truevision TGA (TM) File Format Specification Version 2.0, January 1991. [5] Jef Poskanzer: PBMPLUS, Extended Portable Bitmap Toolkit, December 10, 1991. ee complete compliance with the standard. Usage ===== mpeg2decode {options} input.m2v {upper.m2v} outfile Options: -vn verbose output (n: level) Instructs mpeg2decode to generate informative ouput abmpeg2/doc/CHANGES.encoder 640 270 132 1735 5565707756 10344 94/05/17 public release of version 1.0 ====================================== 94/05/15 cfogg - renamed zz to zig_zag_scan, zz2 to alternate_scan, quanttab to default_intra_quantizer_matrix, qscaletab to non_linear_mquant_table - additional comments 94/05/15 sE style changes and some additional comments in all files fdctref.c: - same PI guessing as in idctref.c 94/05/12 sE name changed to mpeg2encode readpic.c: - conv444to422 and conv422to420 now convert one component per call, not both at the same time - changed subsampling filters to be based on those proposed by Cheung - added filter for MPEG-1 4:4:4 to 4:2:2 subsampling 94/05/11 sE mpg2enc.c: - changed definition of sample rate from width*height*picture_rate to horizontal_size*vertical_size*picture_rate - added display of version / copyright when called without parameters global.h: - added version[] and author[] strings (similar to the decoder) 94/04/?? sE first preliminary alpha release er). Examples ======== non-scalampeg2/doc/CHANGES.decoder 640 270 132 2715 5565707757 10332 94/05/17 public release of version 1.0 ====================================== 94/05/16 sE style changes, some comments store.c: - indexing bug in conv420to422 fixed 94/05/12 sE name changed to mpeg2decode store.c: - conv422to444 and conv420to422 now convert one component per call, not both at the same time - changed upsampling filters to be based on those proposed by Cheung - added filter for MPEG-1 4:2:2 to 4:4:4 upsampling 94/05/11 sE global.h: - updated all prototypes getpict.c: - fixed bug in No_MC predicted macroblocks in P-field pictures; motion_type and mv_field_sel are now set to correct values - changed name of DC coef. predictors to dc_dct_pred[3] and made them local to getMBs, they are now passed as parameters to getintrablock() and getmpg2intrablock() getblk.c: - changed name of DC coef. predictors (cf. getpict.c) 94/05/08 sE getblk.c getvlc.h: - changed format of the DCT coefficient tables to a more readable (though less efficient) format by semi-automatic conversion, added comments store.c: - changed suffixes of seperate component files from .y/.u/.v to .Y/.U/.V - added matrix_coefficients dependency of color space conversion for RGB output formats gethdr.c: - made matrix_coefficients global (used by store.c) - changed frame_centre_horizontal_offset and frame_centre_vertical_offset from unsigned to signed bitstring (simsbf) - fixed wrong sign extension of llx0, lly0 94/04/?? sE first preliminary alpha release passes): mpeg2decode base.m2v snr.m2v l%d%c mpegmpeg2/src/ 750 270 132 0 5565612415 5644 mpeg2/src/mpeg2enc/ 750 270 132 0 5565721044 7343 mpeg2/src/mpeg2enc/config.h 640 270 132 2666 5565357462 11072 /* config.h, configuration defines */ /* Copyright (C) 1994, 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 re readable (though less efficient) format by semi-automatic conversion,mpeg2/src/mpeg2enc/mpeg2enc.h 640 270 132 6020 5565374544 11311 /* mpg2enc.h, defines and types */ /* Copyright (C) 1994, 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 PICTURE_START_CODE 0x100L #define SLICE_MIN_START 0x101L #define SLICE_MAX_START 0x1AFL #define USER_START_CODE 0x1B2L #define SEQ_START_CODE 0x1B3L #define EXT_START_CODE 0x1B5L #define SEQ_END_CODE 0x1B7L #define GOP_START_CODE 0x1B8L #define ISO_END_CODE 0x1B9L #define PACK_START_CODE 0x1BAL #define SYSTEM_START_CODE 0x1BBL /* 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 MB_INTRA 1 #define MB_PATTERN 2 #define MB_BACKWARD 4 #define MB_FORWARD 8 #define MB_QUANT 16 /* 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 /* extension start code IDs */ #define SEQ_ID 1 #define DISP_ID 2 #define QUANT_ID 3 #define SEQSCAL_ID 5 #define PANSCAN_ID 7 #define CODING_ID 8 #define SPATSCAL_ID 9 #define TEMPSCAL_ID 10 /* inputtype */ #define T_Y_U_V 0 #define T_YUV 1 #define T_PPM 2 /* macroblock information */ struct mbinfo { int mb_type; /* intra/forward/backward/interpolated */ int motion_type; /* frame/field/16x8/dual_prime */ int dct_type; /* field/frame DCT */ int mquant; /* quantization parameter */ int cbp; /* coded block pattern */ int skipped; /* skipped macroblock */ int MV[2][2][2]; /* motion vectors */ int mv_field_sel[2][2]; /* motion vertical field select */ int dmvector[2]; /* dual prime vectors */ int var; /* for debugging */ }; /* motion data */ struct motion_data { int forw_hor_f_code,forw_vert_f_code; /* vector range */ int sxf,syf; /* search range */ int back_hor_f_code,back_vert_f_code; int sxb,syb; }; ored in row storage from top left to bottom right. SIF: one headerless file, with interleaved components. Component order is Cb, Y, Cr, Y. This format is also known as Abekas or CCIR Rec. 656 format. The chrominance components have half resolution in horizontal direction (4:2:2) and are aligned with the even luminance samples. File extension is .SIF. TGA: Truevision TGA [4] 24 bit R,G,B format in uncompressed (no run length coding) format with .tga extension. mpeg2/src/mpeg2enc/predict.c 640 270 132 25752 5565402750 11262 /* predict.c, motion compensated prediction */ /* Copyright (C) 1994, 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" static void predict_mb _ANSI_ARGS_(( unsigned char *oldref[], unsigned char *newref[], unsigned char *cur[], int lx, int bx, int by, int pict_type, int pict_struct, int mb_type, int motion_type, int secondfield, int PMV[2][2][2], int mv_field_sel[2][2], int dmvector[2])); static void pred _ANSI_ARGS_((unsigned char *src[], int sfield, unsigned char *dst[], int dfield, int lx, int w, int h, int x, int y, int dx, int dy, int addflag)); static void pred_comp _ANSI_ARGS_((unsigned char *src, unsigned char *dst, int lx, int w, int h, int x, int y, int dx, int dy, int addflag)); void clearblock _ANSI_ARGS_((unsigned char *cur[], int lx, int i0, int j0)); /* only temporarily */ static void calc_DMV(){}; /* form prediction for a complete frame * * reff: reference frame for forward prediction * refb: reference frame for backward prediction * cur: destination (current) frame * mbi: macroblock info */ void predict(reff,refb,cur,mbi) unsigned char *reff[],*refb[],*cur[3]; struct mbinfo *mbi; { int i, j, k; k = 0; for (j=0; j>1,PMV[0][0][0],PMV[0][0][1]>>1,addflag); /* bottom field prediction */ pred(oldref,mv_field_sel[1][0],cur,1, lx<<1,16,8,bx,by>>1,PMV[1][0][0],PMV[1][0][1]>>1,addflag); } else if (motion_type==MC_DMV) /* dual prime prediction */ { /* calculate derived motion vectors */ calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]>>1); /* predict top field from top field */ pred(oldref,0,cur,0, lx<<1,16,8,bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,0); /* predict bottom field from bottom field */ pred(oldref,1,cur,1, lx<<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 */ pred(oldref,1,cur,0, lx<<1,16,8,bx,by>>1,DMV[0][0],DMV[0][1],1); /* predict and add to bottom field from top field */ pred(oldref,0,cur,1, lx<<1,16,8,bx,by>>1,DMV[1][0],DMV[1][1],1); } else { /* invalid motion_type */ if (!quiet) fprintf(stderr,"invalid motion_type\n"); } } else /* TOP_FIELD or BOTTOM_FIELD */ { /* field picture */ currentfield = (pict_struct==BOTTOM_FIELD); /* determine which frame to use for prediction */ if ((pict_type==P_TYPE) && secondfield && (currentfield!=mv_field_sel[0][0])) predframe = cur; /* same frame */ else predframe = oldref; /* previous frame */ if ((motion_type==MC_FIELD) || !(mb_type & MB_FORWARD)) { /* field-based prediction */ pred(predframe,mv_field_sel[0][0],cur,currentfield, lx<<1,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],addflag); } else if (motion_type==MC_16X8) { pred(predframe,mv_field_sel[0][0],cur,currentfield, lx<<1,16,8,bx,by,PMV[0][0][0],PMV[0][0][1],addflag); /* determine which frame to use for lower half prediction */ if ((pict_type==P_TYPE) && secondfield && (currentfield!=mv_field_sel[1][0])) predframe = cur; /* same frame */ else predframe = oldref; /* previous frame */ pred(predframe,mv_field_sel[1][0],cur,currentfield, lx<<1,16,8,bx,by+8,PMV[1][0][0],PMV[1][0][1],addflag); } else if (motion_type==MC_DMV) /* dual prime prediction */ { /* calculate derived motion vectors */ calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]); /* predict from field of same parity */ pred(oldref,currentfield,cur,currentfield, lx<<1,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],0); /* predict from field of opposite parity */ pred(predframe,!currentfield,cur,currentfield, lx<<1,16,16,bx,by,DMV[0][0],DMV[0][1],1); } else { /* invalid motion_type */ if (!quiet) fprintf(stderr,"invalid motion_type\n"); } } addflag = 1; } if (mb_type & MB_BACKWARD) { if (pict_struct==FRAME_PICTURE) { if (motion_type==MC_FRAME) { /* frame-based prediction */ pred(newref,0,cur,0, lx,16,16,bx,by,PMV[0][1][0],PMV[0][1][1],addflag); } else /* field-based prediction */ { /* top field prediction */ pred(newref,mv_field_sel[0][1],cur,0, lx<<1,16,8,bx,by>>1,PMV[0][1][0],PMV[0][1][1]>>1,addflag); /* bottom field prediction */ pred(newref,mv_field_sel[1][1],cur,1, lx<<1,16,8,bx,by>>1,PMV[1][1][0],PMV[1][1][1]>>1,addflag); } } else /* TOP_FIELD or BOTTOM_FIELD */ { /* field picture */ currentfield = (pict_struct==BOTTOM_FIELD); if (motion_type==MC_FIELD) { /* field-based prediction */ pred(newref,mv_field_sel[0][1],cur,currentfield, lx<<1,16,16,bx,by,PMV[0][1][0],PMV[0][1][1],addflag); } else if (motion_type==MC_16X8) { pred(newref,mv_field_sel[0][1],cur,currentfield, lx<<1,16,8,bx,by,PMV[0][1][0],PMV[0][1][1],addflag); pred(newref,mv_field_sel[1][1],cur,currentfield, lx<<1,16,8,bx,by+8,PMV[1][1][0],PMV[1][1][1],addflag); } else { /* invalid motion_type */ if (!quiet) fprintf(stderr,"invalid motion_type\n"); } } } } static void pred(src,sfield,dst,dfield,lx,w,h,x,y,dx,dy,addflag) unsigned char *src[]; int sfield; unsigned char *dst[]; int dfield; int lx; int w, h; int x, y; int dx, dy; int addflag; { /* Y */ pred_comp(src[0]+(sfield?lx>>1:0),dst[0]+(dfield?lx>>1:0), lx,w,h,x,y,dx,dy,addflag); /* Cb */ pred_comp(src[1]+(sfield?lx>>2:0),dst[1]+(dfield?lx>>2:0), lx>>1,w>>1,h>>1,x>>1,y>>1,dx/2,dy/2,addflag); /* Cr */ pred_comp(src[2]+(sfield?lx>>2:0),dst[2]+(dfield?lx>>2:0), lx>>1,w>>1,h>>1,x>>1,y>>1,dx/2,dy/2,addflag); } /* low level prediction routine * * src: prediction source * dst: prediction destination * lx: line width (for both src and dst) * x,y: destination coordinates * dx,dy: half pel motion vector * w,h: size of prediction block * addflag: store or add prediction */ static void pred_comp(src,dst,lx,w,h,x,y,dx,dy,addflag) unsigned char *src; unsigned char *dst; int lx; int w, h; int x, y; int dx, dy; int addflag; { int xint, xh, yint, yh; int i, j; unsigned char *s, *d; /* half pel scaling */ xint = dx>>1; xh = dx & 1; yint = dy>>1; yh = dy & 1; /* origins */ s = src+lx*(y+yint)+x+xint; d = dst+lx*y+x; if (!xh && !yh) if (addflag) for (j=0; j>1; s+= lx; d+= lx; } else for (j=0; j>1)+1)>>1; s+= lx; d+= lx; } else for (j=0; j>1; s+= lx; d+= lx; } else if (xh && !yh) if (addflag) for (j=0; j>1)+1)>>1; s+= lx; d+= lx; } else for (j=0; j>1; s+= lx; d+= lx; } else /* if (xh && yh) */ if (addflag) for (j=0; j>2)+1)>>1; s+= lx; d+= lx; } else for (j=0; j>2; s+= lx; d+= lx; } } void clearblock(cur,lx,i0,j0) unsigned char *cur[]; int lx, i0, j0; { int i, j; unsigned char *p; p = cur[0]+i0+lx*j0; for (j=0; j<16; j++) { for (i=0; i<16; i++) p[i] = 128; p+= lx; } p = cur[1]+(i0>>1)+(lx>>1)*(j0>>1); for (j=0; j<8; j++) { for (i=0; i<8; i++) p[i] = 128; p+= lx>>1; } p = cur[2]+(i0>>1)+(lx>>1)*(j0>>1); for (j=0; j<8; j++) { for (i=0; i<8; i++) p[i] = 128; p+= lx>>1; } } pe; int pict_struct; impeg2/src/mpeg2enc/putbits.c 640 270 132 4300 5565402742 11265 /* putbits.c, bit-level output */ /* Copyright (C) 1994, 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" extern FILE *outfile; /* the only global var we need here */ /* private data */ static unsigned char outbfr; static int outcnt; static int bytecnt; /* initialize buffer, call once before first putbits or alignbits */ void initbits() { outcnt = 8; bytecnt = 0; } /* write rightmost n (0<=n<=32) bits of val to outfile */ void putbits(val,n) int val; int n; { int i; unsigned int mask; mask = 1 << (n-1); /* selects first (leftmost) bit */ for (i=0; i>= 1; /* select next bit */ outcnt--; if (outcnt==0) /* 8 bit buffer full */ { putc(outbfr,outfile); outcnt = 8; bytecnt++; } } } /* zero bit stuffing to next byte boundary (5.2.3, 6.2.1) */ void alignbits() { if (outcnt!=8) putbits(0,outcnt); } /* return total number of generated bits */ int bitcount() { return 8*bytecnt + (8-outcnt); } fprintf(stderr,"invalid motion_type\n"); } } else /* TOP_FIELD or BOTTOM_FIELD */ { /* field picture */ currentfield = (pict_struct==BOTTOM_FIELD); /* determine which frame to use for prediction */ if ((pict_type==P_TYPE) && secondfield && (currentfield!=mv_field_sel[0mpeg2/src/mpeg2enc/putmpg.c 640 270 132 7426 5565623347 11131 /* putmpg.c, block and motion vector encoding routines */ /* Copyright (C) 1994, 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" /* generate variable length codes for an intra-coded block (6.2.6, 6.3.17) */ void putintrablk(blk,cc) short *blk; int cc; { int n, dct_diff, run, signed_level; /* DC coefficient (7.2.1) */ dct_diff = blk[0] - dc_dct_pred[cc]; /* difference to previous block */ dc_dct_pred[cc] = blk[0]; if (cc==0) putDClum(dct_diff); else putDCchrom(dct_diff); /* AC coefficients (7.2.2) */ run = 0; for (n=1; n<64; n++) { /* use appropriate entropy scanning pattern */ signed_level = blk[(altscan ? alternate_scan : zig_zag_scan)[n]]; if (signed_level!=0) { putAC(run,signed_level,intravlc); run = 0; } else run++; /* count zero coefficients */ } /* End of Block -- normative block punctuation */ if (intravlc) putbits(6,4); /* 0110 (Table B-15) */ else putbits(2,2); /* 10 (Table B-14) */ } /* generate variable length codes for a non-intra-coded block (6.2.6, 6.3.17) */ void putnonintrablk(blk) short *blk; { int n, run, signed_level, first; run = 0; first = 1; for (n=0; n<64; n++) { /* use appropriate entropy scanning pattern */ signed_level = blk[(altscan ? alternate_scan : zig_zag_scan)[n]]; if (signed_level!=0) { if (first) { /* first coefficient in non-intra block */ putACfirst(run,signed_level); first = 0; } else putAC(run,signed_level,0); run = 0; } else run++; /* count zero coefficients */ } /* End of Block -- normative block punctuation */ putbits(2,2); } /* generate variable length code for a motion vector component (7.6.3.1) */ void putmv(dmv,f_code) int dmv,f_code; { int r_size, f, vmin, vmax, dv, temp, motion_code, motion_residual; r_size = f_code - 1; /* number of fixed length code ('residual') bits */ f = 1<vmax) dmv-= dv; else if (dmvvmax) if (!quiet) fprintf(stderr,"invalid motion vector\n"); /* split dmv into motion_code and motion_residual */ temp = ((dmv<0) ? -dmv : dmv) + f - 1; motion_code = temp>>r_size; if (dmv<0) motion_code = -motion_code; motion_residual = temp & (f-1); putmotioncode(motion_code); /* variable length code */ if (r_size!=0 && motion_code!=0) putbits(motion_residual,r_size); /* fixed length code */ } parity */ pred(predframe,!currentfield,cur,currentfield, lx<<1,16,16,bx,by,DMV[0][0],DMV[0][1],1); } else { /* invalid motion_type */ if (!quiet) fprintf(stderr,"invalid mmpeg2/src/mpeg2enc/putvlc.c 640 270 132 12407 5565405526 11142 /* putvlc.c, generation of variable length codes */ /* Copyright (C) 1994, 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 "vlc.h" /* private prototypes */ static void putDC _ANSI_ARGS_((sVLCtable *tab, int val)); /* generate variable length code for luminance DC coefficient */ void putDClum(val) int val; { putDC(DClumtab,val); } /* generate variable length code for chrominance DC coefficient */ void putDCchrom(val) int val; { putDC(DCchromtab,val); } /* generate variable length code for DC coefficient (7.2.1) */ static void putDC(tab,val) sVLCtable *tab; int val; { int absval, size; absval = (val<0) ? -val : val; /* abs(val) */ if (absval>2047) { /* should never happen */ sprintf(errortext,"DC value out of range (%d)\n",val); error(errortext); } /* compute dct_dc_size */ size = 0; while (absval) { absval >>= 1; size++; } /* generate VLC for dct_dc_size (Table B-12 or B-13) */ putbits(tab[size].code,tab[size].len); /* append fixed length code (dc_dct_differential) */ if (size!=0) { if (val>=0) absval = val; else absval = val + (1<63 || signed_level==0 || level>2047 || (mpeg1 && (signed_level<-256 || signed_level>255))) { sprintf(errortext,"AC value out of range (run=%d, signed_level=%d)\n", run,signed_level); error(errortext); } len = 0; if (run<2 && level<41) { /* vlcformat selects either of Table B-14 / B-15 */ ptab = &(vlcformat ? dct_code_tab1a : dct_code_tab1)[run][level-1]; len = ptab->len; } else if (run<32 && level<6) { /* vlcformat selects either of Table B-14 / B-15 */ ptab = &(vlcformat?dct_code_tab2a:dct_code_tab2)[run-2][level-1]; len = ptab->len; } if (len!=0) /* a VLC code exists */ { putbits(ptab->code,len); putbits(signed_level<0,1); /* sign */ } else { /* no VLC for this (run, level) combination: use escape coding (7.2.2.3) */ putbits(1l,6); /* Escape */ putbits(run,6); /* 6 bit code for run */ if (mpeg1) { /* ISO/IEC 11172-2 uses a 8 or 16 bit code */ if (signed_level>127) putbits(0,8); if (signed_level<-127) putbits(128,8); putbits(signed_level,8); } else { /* ISO/IEC 13818-2 uses a 12 bit code, Table B-16 */ putbits(signed_level,12); } } } /* generate variable length code for macroblock_address_increment (6.3.16) */ void putaddrinc(addrinc) int addrinc; { while (addrinc>33) { putbits(0x08,11); /* macroblock_escape */ addrinc-= 33; } putbits(addrinctab[addrinc-1].code,addrinctab[addrinc-1].len); } /* generate variable length code for macroblock_type (6.3.16.1) */ void putmbtype(pict_type,mb_type) int pict_type,mb_type; { putbits(mbtypetab[pict_type-1][mb_type].code, mbtypetab[pict_type-1][mb_type].len); } /* generate variable length code for motion_code (6.3.16.3) */ void putmotioncode(motion_code) int motion_code; { int abscode; abscode = (motion_code>=0) ? motion_code : -motion_code; /* abs(motion_code) */ putbits(motionvectab[abscode].code,motionvectab[abscode].len); if (motion_code!=0) putbits(motion_code<0,1); /* sign, 0=positive, 1=negative */ } /* generate variable length code for coded_block_pattern (6.3.16.4) * * 4:2:2, 4:4:4 not implemented */ void putcbp(cbp) int cbp; { putbits(cbptable[cbp-1].code,cbptable[cbp-1].len); } } else { /* invalid motion_type */ if (!quiet) fprintf(stderr,"invalid motion_type\n"); } } } } static void pred(src,sfield,dst,dfield,lx,w,h,x,y,dx,dy,addflag) unsigned char *src[]; int sfielmpeg2/src/mpeg2enc/quantize.c 640 270 132 10567 5565410120 11454 /* quantize.c, quantization / inverse quantization */ /* Copyright (C) 1994, 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" static void iquant1_intra _ANSI_ARGS_((short *src, short *dst, int dc_prec, unsigned char *quant_mat, int mquant)); static void iquant1_non_intra _ANSI_ARGS_((short *src, short *dst, unsigned char *quant_mat, int mquant)); /* Test Model 5 quantization */ int quant_intra(src,dst,dc_prec,quant_mat,mquant) short *src, *dst; int dc_prec; unsigned char *quant_mat; int mquant; { int i; int x, y, d; x = src[0]; d = 8>>dc_prec; /* intra_dc_mult */ dst[0] = (x>=0) ? (x+(d>>1))/d : -((-x+(d>>1))/d); /* round(x/d) */ for (i=1; i<64; i++) { x = src[i]; d = quant_mat[i]; y = (32*(x>=0 ? x : -x) + (d>>1))/d; /* round(32*x/quant_mat) */ d = (3*mquant+2)>>2; dst[i] = (x>=0 ? y+d : -y-d)/(2*mquant); /* (y+0.75*mquant) / (2*mquant) */ } return 1; } int quant_non_intra(src,dst,quant_mat,mquant) short *src, *dst; unsigned char *quant_mat; int mquant; { int i; int x, y, d; int nzflag; nzflag = 0; for (i=0; i<64; i++) { x = src[i]; d = quant_mat[i]; y = (32*(x>=0 ? x : -x) + (d>>1))/d; /* round(32*x/quant_mat) */ if ((dst[i] = (x>=0 ? y : -y)/(2*mquant)) != 0) /* y / (2*mquant) */ nzflag=1; } return nzflag; } /* MPEG-2 inverse quantization */ void iquant_intra(src,dst,dc_prec,quant_mat,mquant) short *src, *dst; int dc_prec; unsigned char *quant_mat; int mquant; { int i, val, sum; if (mpeg1) iquant1_intra(src,dst,dc_prec,quant_mat,mquant); else { sum = dst[0] = src[0] << (3-dc_prec); for (i=1; i<64; i++) { val = (int)(src[i]*quant_mat[i]*mquant)/16; sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val); } /* mismatch control */ if ((sum&1)==0) dst[63]^= 1; } } void iquant_non_intra(src,dst,quant_mat,mquant) short *src, *dst; unsigned char *quant_mat; int mquant; { int i, val, sum; if (mpeg1) iquant1_non_intra(src,dst,quant_mat,mquant); else { sum = 0; for (i=0; i<64; i++) { val = src[i]; if (val!=0) val = (int)((2*val+(val>0 ? 1 : -1))*quant_mat[i]*mquant)/32; sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val); } /* mismatch control */ if ((sum&1)==0) dst[63]^= 1; } } /* MPEG-1 inverse quantization */ static void iquant1_intra(src,dst,dc_prec,quant_mat,mquant) short *src, *dst; int dc_prec; unsigned char *quant_mat; int mquant; { int i, val; dst[0] = src[0] << (3-dc_prec); for (i=1; i<64; i++) { val = (int)(src[i]*quant_mat[i]*mquant)/16; /* mismatch control */ if ((val&1)==0 && val!=0) val+= (val>0) ? -1 : 1; /* saturation */ dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val); } } static void iquant1_non_intra(src,dst,quant_mat,mquant) short *src, *dst; unsigned char *quant_mat; int mquant; { int i, val; for (i=0; i<64; i++) { val = src[i]; if (val!=0) { val = (int)((2*val+(val>0 ? 1 : -1))*quant_mat[i]*mquant)/32; /* mismatch control */ if ((val&1)==0 && val!=0) val+= (val>0) ? -1 : 1; } /* saturation */ dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val); } } *ptab; level = (signed_level<0) ? -signed_level : signed_level; /* abs(signed_level) */ /* make sure run and signed_level are valimpeg2/src/mpeg2enc/vlc.h 640 270 132 26122 5564126342 10410 /* vlc.h, variable length code tables (used by routines in putvlc.c) */ /* Copyright (C) 1994, 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. * */ /* type definitions for variable length code table entries */ typedef struct { unsigned char code; /* right justified */ char len; } VLCtable; /* for codes longer than 8 bits (excluding leading zeroes) */ typedef struct { unsigned short code; /* right justified */ char len; } sVLCtable; /* data from ISO/IEC 13818-2 DIS, Annex B, variable length code tables */ /* Table B-1, variable length codes for macroblock_address_increment * * indexed by [macroblock_address_increment-1] * 'macroblock_escape' is treated elsewhere */ static VLCtable addrinctab[33]= { {0x01,1}, {0x03,3}, {0x02,3}, {0x03,4}, {0x02,4}, {0x03,5}, {0x02,5}, {0x07,7}, {0x06,7}, {0x0b,8}, {0x0a,8}, {0x09,8}, {0x08,8}, {0x07,8}, {0x06,8}, {0x17,10}, {0x16,10}, {0x15,10}, {0x14,10}, {0x13,10}, {0x12,10}, {0x23,11}, {0x22,11}, {0x21,11}, {0x20,11}, {0x1f,11}, {0x1e,11}, {0x1d,11}, {0x1c,11}, {0x1b,11}, {0x1a,11}, {0x19,11}, {0x18,11} }; /* Table B-2, B-3, B-4 variable length codes for macroblock_type * * indexed by [macroblock_type] */ static VLCtable mbtypetab[3][32]= { /* I */ { {0,0}, {1,1}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {1,2}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0} }, /* P */ { {0,0}, {3,5}, {1,2}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {1,3}, {0,0}, {1,1}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {1,6}, {1,5}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {2,5}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0} }, /* B */ { {0,0}, {3,5}, {0,0}, {0,0}, {2,3}, {0,0}, {3,3}, {0,0}, {2,4}, {0,0}, {3,4}, {0,0}, {2,2}, {0,0}, {3,2}, {0,0}, {0,0}, {1,6}, {0,0}, {0,0}, {0,0}, {0,0}, {2,6}, {0,0}, {0,0}, {0,0}, {3,6}, {0,0}, {0,0}, {0,0}, {2,5}, {0,0} } }; /* Table B-5 ... B-8 variable length codes for macroblock_type in * scalable sequences * * not implemented */ /* Table B-9, variable length codes for coded_block_pattern * * indexed by [coded_block_pattern-1] */ static VLCtable cbptable[63]= { {0x0b,5}, {0x09,5}, {0x0d,6}, {0x0d,4}, {0x17,7}, {0x13,7}, {0x1f,8}, {0x0c,4}, {0x16,7}, {0x12,7}, {0x1e,8}, {0x13,5}, {0x1b,8}, {0x17,8}, {0x13,8}, {0x0b,4}, {0x15,7}, {0x11,7}, {0x1d,8}, {0x11,5}, {0x19,8}, {0x15,8}, {0x11,8}, {0x0f,6}, {0x0f,8}, {0x0d,8}, {0x03,9}, {0x0f,5}, {0x0b,8}, {0x07,8}, {0x07,9}, {0x0a,4}, {0x14,7}, {0x10,7}, {0x1c,8}, {0x0e,6}, {0x0e,8}, {0x0c,8}, {0x02,9}, {0x10,5}, {0x18,8}, {0x14,8}, {0x10,8}, {0x0e,5}, {0x0a,8}, {0x06,8}, {0x06,9}, {0x12,5}, {0x1a,8}, {0x16,8}, {0x12,8}, {0x0d,5}, {0x09,8}, {0x05,8}, {0x05,9}, {0x0c,5}, {0x08,8}, {0x04,8}, {0x04,9}, {0x07,3}, {0x0a,5}, {0x08,5}, {0x0c,6} }; /* Table B-10, variable length codes for motion_code * * indexed by [abs(motion_code)] * sign of motion_code is treated elsewhere */ static VLCtable motionvectab[17]= { {0x01,1}, {0x01,2}, {0x01,3}, {0x01,4}, {0x03,6}, {0x05,7}, {0x04,7}, {0x03,7}, {0x0b,9}, {0x0a,9}, {0x09,9}, {0x11,10}, {0x10,10}, {0x0f,10}, {0x0e,10}, {0x0d,10}, {0x0c,10} }; /* Table B-11, variable length codes for dmvector * * treated elsewhere */ /* Table B-12, variable length codes for dct_dc_size_luminance * * indexed by [dct_dc_size_luminance] */ static sVLCtable DClumtab[12]= { {0x0004,3}, {0x0000,2}, {0x0001,2}, {0x0005,3}, {0x0006,3}, {0x000e,4}, {0x001e,5}, {0x003e,6}, {0x007e,7}, {0x00fe,8}, {0x01fe,9}, {0x01ff,9} }; /* Table B-13, variable length codes for dct_dc_size_chrominance * * indexed by [dct_dc_size_chrominance] */ static sVLCtable DCchromtab[12]= { {0x0000,2}, {0x0001,2}, {0x0002,2}, {0x0006,3}, {0x000e,4}, {0x001e,5}, {0x003e,6}, {0x007e,7}, {0x00fe,8}, {0x01fe,9}, {0x03fe,10},{0x03ff,10} }; /* Table B-14, DCT coefficients table zero * * indexed by [run][level-1] * split into two tables (dct_code_tab1, dct_code_tab2) to reduce size * 'first DCT coefficient' condition and 'End of Block' are treated elsewhere * codes do not include s (sign bit) */ static VLCtable dct_code_tab1[2][40]= { /* run = 0, level = 1...40 */ { {0x03, 2}, {0x04, 4}, {0x05, 5}, {0x06, 7}, {0x26, 8}, {0x21, 8}, {0x0a,10}, {0x1d,12}, {0x18,12}, {0x13,12}, {0x10,12}, {0x1a,13}, {0x19,13}, {0x18,13}, {0x17,13}, {0x1f,14}, {0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14}, {0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14}, {0x16,14}, {0x15,14}, {0x14,14}, {0x13,14}, {0x12,14}, {0x11,14}, {0x10,14}, {0x18,15}, {0x17,15}, {0x16,15}, {0x15,15}, {0x14,15}, {0x13,15}, {0x12,15}, {0x11,15}, {0x10,15} }, /* run = 1, level = 1...18 */ { {0x03, 3}, {0x06, 6}, {0x25, 8}, {0x0c,10}, {0x1b,12}, {0x16,13}, {0x15,13}, {0x1f,15}, {0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15}, {0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16}, {0x11,16}, {0x10,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0} } }; static VLCtable dct_code_tab2[30][5]= { /* run = 2...31, level = 1...5 */ {{0x05, 4}, {0x04, 7}, {0x0b,10}, {0x14,12}, {0x14,13}}, {{0x07, 5}, {0x24, 8}, {0x1c,12}, {0x13,13}, {0x00, 0}}, {{0x06, 5}, {0x0f,10}, {0x12,12}, {0x00, 0}, {0x00, 0}}, {{0x07, 6}, {0x09,10}, {0x12,13}, {0x00, 0}, {0x00, 0}}, {{0x05, 6}, {0x1e,12}, {0x14,16}, {0x00, 0}, {0x00, 0}}, {{0x04, 6}, {0x15,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x07, 7}, {0x11,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x05, 7}, {0x11,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x27, 8}, {0x10,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x23, 8}, {0x1a,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x22, 8}, {0x19,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x20, 8}, {0x18,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x0e,10}, {0x17,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x0d,10}, {0x16,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x08,10}, {0x15,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1f,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1a,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x19,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x17,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x16,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1f,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1e,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1d,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1c,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1b,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1f,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1e,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1d,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1c,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1b,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}} }; /* Table B-15, DCT coefficients table one * * indexed by [run][level-1] * split into two tables (dct_code_tab1a, dct_code_tab2a) to reduce size * 'End of Block' is treated elsewhere * codes do not include s (sign bit) */ static VLCtable dct_code_tab1a[2][40]= { /* run = 0, level = 1...40 */ { {0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5}, {0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7}, {0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8}, {0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14}, {0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14}, {0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14}, {0x16,14}, {0x15,14}, {0x14,14}, {0x13,14}, {0x12,14}, {0x11,14}, {0x10,14}, {0x18,15}, {0x17,15}, {0x16,15}, {0x15,15}, {0x14,15}, {0x13,15}, {0x12,15}, {0x11,15}, {0x10,15} }, /* run = 1, level = 1...18 */ { {0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8}, {0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15}, {0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15}, {0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16}, {0x11,16}, {0x10,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0} } }; static VLCtable dct_code_tab2a[30][5]= { /* run = 2...31, level = 1...5 */ {{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10}, {0x14,13}}, {{0x07, 5}, {0x26, 8}, {0x1c,12}, {0x13,13}, {0x00, 0}}, {{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x00, 0}, {0x00, 0}}, {{0x07, 6}, {0x04, 9}, {0x12,13}, {0x00, 0}, {0x00, 0}}, {{0x06, 7}, {0x1e,12}, {0x14,16}, {0x00, 0}, {0x00, 0}}, {{0x04, 7}, {0x15,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x05, 7}, {0x11,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x78, 7}, {0x11,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x7a, 7}, {0x10,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x21, 8}, {0x1a,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x25, 8}, {0x19,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x24, 8}, {0x18,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x05, 9}, {0x17,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x07, 9}, {0x16,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x0d,10}, {0x15,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1f,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1a,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x19,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x17,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x16,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1f,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1e,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1d,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1c,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1b,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1f,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1e,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1d,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1c,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1b,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}} }; if (!xh && !yh) if (addflag) for (j=0; j>1; s+= lx; d+= lx; } else for (j=0; j #include #include "config.h" #include "global.h" /* private prototypes */ static int frametotc _ANSI_ARGS_((int frame)); /* generate sequence header (6.2.2.1, 6.3.3) * * matrix download not implemented */ void putseqhdr() { int i; alignbits(); putbits(SEQ_START_CODE,32); /* sequence_header_code */ putbits(horizontal_size,12); /* horizontal_size_value */ putbits(vertical_size,12); /* vertical_size_value */ putbits(aspectratio,4); /* aspect_ratio_information */ putbits(frame_rate_code,4); /* frame_rate_code */ putbits((int)ceil(bit_rate/400.0),18); /* bit_rate_value */ putbits(1,1); /* marker_bit */ putbits(vbv_buffer_size,10); /* vbv_buffer_size_value */ putbits(constrparms,1); /* constrained_parameters_flag */ putbits(load_iquant,1); /* load_intra_quantizer_matrix */ if (load_iquant) for (i=0; i<64; i++) /* matrices are always downloaded in zig-zag order */ putbits(intra_q[zig_zag_scan[i]],8); /* intra_quantizer_matrix */ putbits(load_niquant,1); /* load_non_intra_quantizer_matrix */ if (load_niquant) for (i=0; i<64; i++) putbits(inter_q[zig_zag_scan[i]],8); /* non_intra_quantizer_matrix */ } /* generate sequence extension (6.2.2.3, 6.3.5) header (MPEG-2 only) */ void putseqext() { alignbits(); putbits(EXT_START_CODE,32); /* extension_start_code */ putbits(SEQ_ID,4); /* extension_start_code_identifier */ putbits((profile<<4)|level,8); /* profile_and_level_indication */ putbits(prog_seq,1); /* progressive sequence */ putbits(1,2); /* chroma_format */ putbits(horizontal_size>>12,2); /* horizontal_size_extension */ putbits(vertical_size>>12,2); /* vertical_size_extension */ putbits(((int)ceil(bit_rate/400.0))>>18,12); /* bit_rate_extension */ putbits(1,1); /* marker_bit */ putbits(vbv_buffer_size>>10,8); /* vbv_buffer_size_extension */ putbits(0,1); /* low_delay -- currently not implemented */ putbits(0,2); /* frame_rate_extension_n */ putbits(0,5); /* frame_rate_extension_d */ } /* generate sequence display extension (6.2.2.4, 6.3.6) * * content not yet user setable */ void putseqdispext() { alignbits(); putbits(EXT_START_CODE,32); /* extension_start_code */ putbits(DISP_ID,4); /* extension_start_code_identifier */ putbits(video_format,3); /* video_format */ putbits(1,1); /* colour_description */ putbits(color_primaries,8); /* colour_primaries */ putbits(transfer_characteristics,8); /* transfer_characteristics */ putbits(matrix_coefficients,8); /* matrix_coefficients */ putbits(display_horizontal_size,14); /* display_horizontal_size */ putbits(1,1); /* marker_bit */ putbits(display_vertical_size,14); /* display_vertical_size */ } /* output a zero terminated string as user data (6.2.2.2.2, 6.3.4.1) * * string must not emulate start codes */ void putuserdata(userdata) char *userdata; { alignbits(); putbits(USER_START_CODE,32); /* user_data_start_code */ while (*userdata) putbits(*userdata++,8); } /* generate group of pictures header (6.2.2.6, 6.3.9) * * uses tc0 (timecode of first frame) and frame0 (number of first frame) */ void putgophdr(frame,closed_gop) int frame,closed_gop; { int tc; alignbits(); putbits(GOP_START_CODE,32); /* group_start_code */ tc = frametotc(tc0+frame); putbits(tc,25); /* time_code */ putbits(closed_gop,1); /* closed_gop */ putbits(0,1); /* broken_link */ } /* convert frame number to time_code * * drop_frame not implemented */ static int frametotc(frame) int frame; { int fps, pict, sec, minute, hour, tc; fps = (int)(picture_rate+0.5); pict = frame%fps; frame = (frame-pict)/fps; sec = frame%60; frame = (frame-sec)/60; minute = frame%60; frame = (frame-minute)/60; hour = frame%24; tc = (hour<<19) | (minute<<13) | (1<<12) | (sec<<6) | pict; return tc; } /* generate picture header (6.2.3, 6.3.10) */ void putpicthdr() { alignbits(); putbits(PICTURE_START_CODE,32); /* picture_start_code */ putbits(temp_ref,10); /* temporal_reference */ putbits(pict_type,3); /* picture_coding_type */ calc_vbv_delay(); putbits(vbv_delay,16); /* vbv_delay */ if (pict_type==P_TYPE || pict_type==B_TYPE) { putbits(0,1); /* full_pel_forward_vector */ if (mpeg1) putbits(forw_hor_f_code,3); else putbits(7,3); /* forward_f_code */ } if (pict_type==B_TYPE) { putbits(0,1); /* full_pel_backward_vector */ if (mpeg1) putbits(back_hor_f_code,3); else putbits(7,3); /* backward_f_code */ } putbits(0,1); /* extra_bit_picture */ } /* generate picture coding extension (6.2.3.1, 6.3.11) * * composite display information (v_axis etc.) not implemented */ void putpictcodext() { alignbits(); putbits(EXT_START_CODE,32); /* extension_start_code */ putbits(CODING_ID,4); /* extension_start_code_identifier */ putbits(forw_hor_f_code,4); /* forward_horizontal_f_code */ putbits(forw_vert_f_code,4); /* forward_vertical_f_code */ putbits(back_hor_f_code,4); /* backward_horizontal_f_code */ putbits(back_vert_f_code,4); /* backward_vertical_f_code */ putbits(dc_prec,2); /* intra_dc_precision */ putbits(pict_struct,2); /* picture_structure */ putbits(topfirst,1); /* top_field_first */ putbits(frame_pred_dct,1); /* frame_pred_frame_dct */ putbits(0,1); /* concealment_motion_vectors -- currently not implemented */ putbits(q_scale_type,1); /* q_scale_type */ putbits(intravlc,1); /* intra_vlc_format */ putbits(altscan,1); /* alternate_scan */ putbits(repeatfirst,1); /* repeat_first_field */ putbits(prog_frame,1); /* chroma_420_type */ putbits(prog_frame,1); /* progressive_frame */ putbits(0,1); /* composite_display_flag */ } /* generate sequence_end_code (6.2.2) */ void putseqend() { alignbits(); putbits(SEQ_END_CODE,32); } 16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}, {{0x1c,16}, {0x00, 0}, {0x00, 0}, {0mpeg2/src/mpeg2enc/global.h 640 270 132 23632 5565656326 11102 /* global.h, global variables, function prototypes */ /* Copyright (C) 1994, 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 "mpeg2enc.h" /* choose between declaration (GLOBAL undefined) * and definition (GLOBAL defined) * GLOBAL is defined in exactly one file (mpeg2enc.c) */ #ifndef GLOBAL #define EXTERN extern #else #define EXTERN #endif /* prototypes of global functions */ /* fdctref.c */ void init_fdct _ANSI_ARGS_((void)); void fdct _ANSI_ARGS_((short *block)); /* idct.c */ void idct _ANSI_ARGS_((short *block)); void init_idct _ANSI_ARGS_((void)); /* motion.c */ void motion_estimation _ANSI_ARGS_((unsigned char *oldorg, unsigned char *neworg, unsigned char *oldref, unsigned char *newref, unsigned char *cur, int sxf, int syf, int sxb, int syb, struct mbinfo *mbi)); /* mpeg2enc.c */ void error _ANSI_ARGS_((char *text)); /* predict.c */ void predict _ANSI_ARGS_((unsigned char *reff[], unsigned char *refb[], unsigned char *cur[3], struct mbinfo *mbi)); void clearblock _ANSI_ARGS_((unsigned char *cur[], int lx, int i0, int j0)); /* putbits.c */ void initbits _ANSI_ARGS_((void)); void putbits _ANSI_ARGS_((int val, int n)); void alignbits _ANSI_ARGS_((void)); int bitcount _ANSI_ARGS_((void)); /* puthdr.c */ void putseqhdr _ANSI_ARGS_((void)); void putseqext _ANSI_ARGS_((void)); void putseqdispext _ANSI_ARGS_((void)); void putuserdata _ANSI_ARGS_((char *userdata)); void putgophdr _ANSI_ARGS_((int frame, int closed_gop)); void putpicthdr _ANSI_ARGS_((void)); void putpictcodext _ANSI_ARGS_((void)); void putseqend _ANSI_ARGS_((void)); /* putmpg.c */ void putintrablk _ANSI_ARGS_((short *blk, int cc)); void putnonintrablk _ANSI_ARGS_((short *blk)); void putmv _ANSI_ARGS_((int dmv, int f_code)); /* putpic.c */ void putpict _ANSI_ARGS_((unsigned char *frame)); /* putseq.c */ void putseq _ANSI_ARGS_((void)); /* putvlc.c */ void putDClum _ANSI_ARGS_((int val)); void putDCchrom _ANSI_ARGS_((int val)); void putACfirst _ANSI_ARGS_((int run, int val)); void putAC _ANSI_ARGS_((int run, int signed_level, int vlcformat)); void putaddrinc _ANSI_ARGS_((int addrinc)); void putmbtype _ANSI_ARGS_((int pict_type, int mb_type)); void putmotioncode _ANSI_ARGS_((int motion_code)); void putcbp _ANSI_ARGS_((int cbp)); /* quantize.c */ int quant_intra _ANSI_ARGS_((short *src, short *dst, int dc_prec, unsigned char *quant_mat, int mquant)); int quant_non_intra _ANSI_ARGS_((short *src, short *dst, unsigned char *quant_mat, int mquant)); void iquant_intra _ANSI_ARGS_((short *src, short *dst, int dc_prec, unsigned char *quant_mat, int mquant)); void iquant_non_intra _ANSI_ARGS_((short *src, short *dst, unsigned char *quant_mat, int mquant)); /* ratectl.c */ void rc_init_seq _ANSI_ARGS_((void)); void rc_init_GOP _ANSI_ARGS_((int n)); void rc_init_pict _ANSI_ARGS_((void)); void rc_update_pict _ANSI_ARGS_((void)); int rc_start_mb _ANSI_ARGS_((void)); int rc_calc_mquant _ANSI_ARGS_((int j, unsigned char *p)); void init_vbv_delay _ANSI_ARGS_((void)); void calc_vbv_delay _ANSI_ARGS_((void)); /* readpic.c */ void readframe _ANSI_ARGS_((char *fname, unsigned char *frame[])); /* stats.c */ void calcSNR _ANSI_ARGS_((unsigned char *org[3], unsigned char *rec[3])); void stats _ANSI_ARGS_((void)); /* transfrm.c */ void transform _ANSI_ARGS_((unsigned char *pred[], unsigned char *cur[], struct mbinfo *mbi, short blocks[][6][64])); void itransform _ANSI_ARGS_((unsigned char *pred[], unsigned char *cur[], struct mbinfo *mbi, short blocks[][6][64])); void dct_type_estimation _ANSI_ARGS_((unsigned char *pred, unsigned char *cur, struct mbinfo *mbi)); /* writepic.c */ void writeframe _ANSI_ARGS_((char *fname, unsigned char *frame[])); /* global variables */ EXTERN char version[] #ifdef GLOBAL ="mpeg2encode V1.0, 94/05/16" #endif ; EXTERN char author[] #ifdef GLOBAL ="(C) 1994, MPEG Software Simulation Group" #endif ; /* zig-zag scan */ EXTERN unsigned char zig_zag_scan[64] #ifdef GLOBAL = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5, 12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28, 35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51, 58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 } #endif ; /* alternate scan */ EXTERN unsigned char alternate_scan[64] #ifdef GLOBAL = { 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49, 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43, 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45, 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63 } #endif ; /* default intra quantization matrix */ EXTERN unsigned char default_intra_quantizer_matrix[64] #ifdef GLOBAL = { 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83 } #endif ; /* non-linear quantization coefficient table */ EXTERN unsigned char non_linear_mquant_table[32] #ifdef GLOBAL = { 0, 1, 2, 3, 4, 5, 6, 7, 8,10,12,14,16,18,20,22, 24,28,32,36,40,44,48,52, 56,64,72,80,88,96,104,112 } #endif ; /* picture data arrays */ /* reconstructed frames */ EXTERN unsigned char *newrefframe[3], *oldrefframe[3], *auxframe[3]; /* original frames */ EXTERN unsigned char *neworgframe[3], *oldorgframe[3], *auxorgframe[3]; /* prediction of current frame */ EXTERN unsigned char *predframe[3]; /* 8*8 block data */ EXTERN short (*blocks)[6][64]; /* intra / non_intra quantization matrices */ EXTERN unsigned char intra_q[64], inter_q[64]; /* prediction values for DCT coefficient (0,0) */ EXTERN int dc_dct_pred[3]; /* macroblock side information array */ EXTERN struct mbinfo *mbinfo; /* motion estimation parameters */ EXTERN struct motion_data *motion_data; /* clipping (=saturation) table */ EXTERN unsigned char *clp; /* name strings */ EXTERN char id_string[256], tplorg[256], tplref[256]; EXTERN char iqname[256], niqname[256]; EXTERN char statname[256]; EXTERN char errortext[256]; EXTERN FILE *outfile, *statfile; /* file descriptors */ EXTERN int inputtype; /* format of input frames */ EXTERN int quiet; /* suppress warnings */ /* coding model parameters */ EXTERN int N; /* number of frames in Group of Pictures */ EXTERN int M; /* distance between I/P frames */ EXTERN int P; /* intra slice refresh interval */ EXTERN int nframes; /* total number of frames to encode */ EXTERN int frame0, tc0; /* number and timecode of first frame */ /* sequence specific data (sequence header) */ EXTERN int horizontal_size, vertical_size; /* frame size (pels) */ EXTERN int width, height; /* encoded frame size (pels) multiples of 16 or 32 */ EXTERN int mb_width, mb_height; /* frame size (macroblocks) */ EXTERN int aspectratio; /* aspect ratio information (pel or display) */ EXTERN int frame_rate_code; /* coded value of frame rate */ EXTERN double picture_rate; /* frames per second */ EXTERN double bit_rate; /* bits per second */ EXTERN int vbv_buffer_size; /* size of VBV buffer (* 16 kbit) */ EXTERN int constrparms; /* constrained parameters flag (MPEG-1 only) */ EXTERN int load_iquant, load_niquant; /* use non-default quant. matrices */ /* sequence specific data (sequence extension) */ EXTERN int profile, level; /* syntax / parameter constraints */ EXTERN int prog_seq; /* progressive sequence */ EXTERN int low_delay; /* no B pictures, skipped pictures */ EXTERN int mpeg1; /* ISO/IEC IS 11172-2 sequence */ /* sequence specific data (sequence display extension) */ EXTERN int video_format; /* component, PAL, NTSC, SECAM or MAC */ EXTERN int color_primaries; /* source primary chromaticity coordinates */ EXTERN int transfer_characteristics; /* opto-electronic transfer char. (gamma) */ EXTERN int matrix_coefficients; /* Eg,Eb,Er / Y,Cb,Cr matrix coefficients */ EXTERN int display_horizontal_size, display_vertical_size; /* display size */ /* picture specific data (picture header) */ EXTERN int temp_ref; /* temporal reference */ EXTERN int pict_type; /* picture coding type (I, P or B) */ EXTERN int vbv_delay; /* video buffering verifier delay (1/90000 seconds) */ /* picture specific data (picture coding extension) */ EXTERN int forw_hor_f_code, forw_vert_f_code; EXTERN int back_hor_f_code, back_vert_f_code; /* motion vector ranges */ EXTERN int dc_prec; /* DC coefficient precision for intra coded blocks */ EXTERN int pict_struct; /* picture structure (frame, top / bottom field) */ EXTERN int topfirst; /* display top field first */ /* use only frame prediction and frame DCT (I,P,B,current) */ EXTERN int frame_pred_dct_tab[3], frame_pred_dct; EXTERN int conceal_tab[3]; /* use concealment motion vectors (I,P,B) */ EXTERN int qscale_tab[3], q_scale_type; /* linear/non-linear quantizaton table */ EXTERN int intravlc_tab[3], intravlc; /* intra vlc format (I,P,B,current) */ EXTERN int altscan_tab[3], altscan; /* alternate scan (I,P,B,current) */ EXTERN int repeatfirst; /* repeat first field after second field */ EXTERN int prog_frame; /* progressive frame */ mpeg2enc.c */ void error _ANSI_ARGS_((char *text)); /* predict.c */ void predict _ANSI_ARGS_((unsignempeg2/src/mpeg2enc/fdctref.c 640 270 132 4206 5565360414 11214 /* fdctref.c, forward discrete cosine transform, double precision */ /* Copyright (C) 1994, 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" #ifndef PI # ifdef M_PI # define PI M_PI # else # define PI 3.14159265358979323846 # endif #endif /* global declarations */ void init_fdct _ANSI_ARGS_((void)); void fdct _ANSI_ARGS_((short *block)); /* private data */ static double c[8][8]; /* transform coefficients */ void init_fdct() { int i, j; double s; for (i=0; i<8; i++) { s = (i==0) ? sqrt(0.125) : 0.5; for (j=0; j<8; j++) c[i][j] = s * cos((PI/8.0)*i*(j+0.5)); } } void fdct(block) short *block; { int i, j, k; double s; double tmp[64]; for (i=0; i<8; i++) for (j=0; j<8; j++) { s = 0.0; for (k=0; k<8; k++) s += c[j][k] * block[8*i+k]; tmp[8*i+j] = s; } for (j=0; j<8; j++) for (i=0; i<8; i++) { s = 0.0; for (k=0; k<8; k++) s += c[i][k] * tmp[8*k+j]; block[8*i+j] = (int)floor(s+0.5); } } t)); void putaddrinc _ANSI_ARGS_((int addrinc)); void putmbtype _ANSI_ARGS_((int pict_type, int mb_type)); void putmotioncode _ANSI_ARGS_((int motion_code)); void putcbp _ANSI_ARGS_((int cbp)); /* quantize.c */ int quant_intra _ANSI_ARGS_((short *src, short *dst, int dc_prec, unsigned char *quant_mat, int mquant)); int quant_non_intra _ANSI_ARGS_((short *src, short *dst, mpeg2/src/mpeg2enc/readpic.c 640 270 132 30336 5565720751 11235 /* readpic.c, read source pictures */ /* Copyright (C) 1994, 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" /* private prototypes */ static void read_y_u_v _ANSI_ARGS_((char *fname, unsigned char *frame[])); static void read_yuv _ANSI_ARGS_((char *fname, unsigned char *frame[])); static void read_ppm _ANSI_ARGS_((char *fname, unsigned char *frame[])); static void border_extend _ANSI_ARGS_((unsigned char *frame, int w1, int h1, int w2, int h2)); static void conv444to422 _ANSI_ARGS_((unsigned char *src, unsigned char *dst)); static void conv422to420 _ANSI_ARGS_((unsigned char *src, unsigned char *dst)); void readframe(fname,frame) char *fname; unsigned char *frame[]; { switch (inputtype) { case T_Y_U_V: read_y_u_v(fname,frame); break; case T_YUV: read_yuv(fname,frame); break; case T_PPM: read_ppm(fname,frame); break; default: break; } } static void read_y_u_v(fname,frame) char *fname; unsigned char *frame[]; { int i; char name[128]; FILE *fd; sprintf(name,"%s.Y",fname); if (!(fd = fopen(name,"rb"))) { sprintf(errortext,"Couldn't open %s\n",name); error(errortext); } for (i=0; i>1); i++) fread(frame[1]+i*(width>>1),1,horizontal_size>>1,fd); fclose(fd); border_extend(frame[1], horizontal_size>>1,vertical_size>>1,width>>1,height>>1); sprintf(name,"%s.V",fname); if (!(fd = fopen(name,"rb"))) { sprintf(errortext,"Couldn't open %s\n",name); error(errortext); } for (i=0; i<(vertical_size>>1); i++) fread(frame[2]+i*(width>>1),1,horizontal_size>>1,fd); fclose(fd); border_extend(frame[2], horizontal_size>>1,vertical_size>>1,width>>1,height>>1); } static void read_yuv(fname,frame) char *fname; unsigned char *frame[]; { int i; char name[128]; FILE *fd; sprintf(name,"%s.yuv",fname); if (!(fd = fopen(name,"rb"))) { sprintf(errortext,"Couldn't open %s\n",name); error(errortext); } /* Y */ for (i=0; i>1); i++) fread(frame[1]+i*(width>>1),1,horizontal_size>>1,fd); border_extend(frame[1], horizontal_size>>1,vertical_size>>1,width>>1,height>>1); /* Cr */ for (i=0; i<(vertical_size>>1); i++) fread(frame[2]+i*(width>>1),1,horizontal_size>>1,fd); border_extend(frame[2], horizontal_size>>1,vertical_size>>1,width>>1,height>>1); fclose(fd); } static void read_ppm(fname,frame) char *fname; unsigned char *frame[]; { int i, j; int r, g, b; double y, u, v; double cr, cg, cb, cu, cv; char name[128]; FILE *fd; unsigned char *yp, *up, *vp; static unsigned char *u444, *v444, *u422, *v422; static double coef[7][3] = { {0.2125,0.7154,0.0721}, /* ITU-R Rec. 709 (1990) */ {0.299, 0.587, 0.114}, /* unspecified */ {0.299, 0.587, 0.114}, /* reserved */ {0.30, 0.59, 0.11}, /* FCC */ {0.299, 0.587, 0.114}, /* ITU-R Rec. 624-4 System B, G */ {0.299, 0.587, 0.114}, /* SMPTE 170M */ {0.212, 0.701, 0.087}}; /* SMPTE 240M (1987) */ i = matrix_coefficients; if (i>8) i = 3; cr = coef[i-1][0]; cg = coef[i-1][1]; cb = coef[i-1][2]; cu = 0.5/(1.0-cb); cv = 0.5/(1.0-cr); if (!u444) { u444 = (unsigned char *)malloc(width*height); v444 = (unsigned char *)malloc(width*height); u422 = (unsigned char *)malloc((width>>1)*height); v422 = (unsigned char *)malloc((width>>1)*height); } sprintf(name,"%s.ppm",fname); if (!(fd = fopen(name,"rb"))) { sprintf(errortext,"Couldn't open %s\n",name); error(errortext); } /* skip header */ getc(fd); getc(fd); /* magic number (P6) */ pbm_getint(fd); pbm_getint(fd); pbm_getint(fd); /* width height maxcolors */ for (i=0; i>1] = clp[(int)(228*(src[i]+src[ip1]) +70*(src[im1]+src[ip2]) -37*(src[im2]+src[ip3]) -21*(src[im3]+src[ip4]) +11*(src[im4]+src[ip5]) + 5*(src[im5]+src[ip6])+256)>>9]; } src+= width; dst+= width>>1; } } else { /* MPEG-2 */ for (j=0; j>1] = clp[(int)( 22*(src[im5]+src[ip5])-52*(src[im3]+src[ip3]) +159*(src[im1]+src[ip1])+256*src[i]+256)>>9]; } src+= width; dst+= width>>1; } } } /* vertical filter and 2:1 subsampling */ static void conv422to420(src,dst) unsigned char *src, *dst; { int w, i, j, jm6, jm5, jm4, jm3, jm2, jm1; int jp1, jp2, jp3, jp4, jp5, jp6; w = width>>1; if (prog_frame) { /* intra frame */ for (i=0; i>1)] = clp[(int)(228*(src[w*j]+src[w*jp1]) +70*(src[w*jm1]+src[w*jp2]) -37*(src[w*jm2]+src[w*jp3]) -21*(src[w*jm3]+src[w*jp4]) +11*(src[w*jm4]+src[w*jp5]) + 5*(src[w*jm5]+src[w*jp6])+256)>>9]; } src++; dst++; } } else { /* intra field */ for (i=0; i>1)] = clp[(int)(8*src[w*jm5] +5*src[w*jm4] -30*src[w*jm3] -18*src[w*jm2] +113*src[w*jm1] +242*src[w*j] +192*src[w*jp1] +35*src[w*jp2] -38*src[w*jp3] -10*src[w*jp4] +11*src[w*jp5] +2*src[w*jp6]+256)>>9]; /* bottom field */ jm6 = (j<9) ? 1 : j-9; jm5 = (j<7) ? 1 : j-7; jm4 = (j<5) ? 1 : j-5; jm3 = (j<3) ? 1 : j-3; jm2 = (j<1) ? 1 : j-1; jm1 = (j>1)+1)] = clp[(int)(8*src[w*jp6] +5*src[w*jp5] -30*src[w*jp4] -18*src[w*jp3] +113*src[w*jp2] +242*src[w*jp1] +192*src[w*jm1] +35*src[w*jm2] -38*src[w*jm3] -10*src[w*jm4] +11*src[w*jm5] +2*src[w*jm6]+256)>>9]; } src++; dst++; } } } /* pbm_getc() and pbm_getint() are essentially taken from * PBMPLUS (C) Jef Poskanzer * but without error/EOF checking */ char pbm_getc(file) FILE* file; { char ch; ch = getc(file); if (ch=='#') { do { ch = getc(file); } while (ch!='\n' && ch!='\r'); } return ch; } int pbm_getint(file) FILE* file; { char ch; int i; do { ch = pbm_getc(file); } while (ch==' ' || ch=='\t' || ch=='\n' || ch=='\r'); i = 0; do { i = i*10 + ch-'0'; ch = pbm_getc(file); } while (ch>='0' && ch<='9'); return i; } *up, *vp; static unsigned char *u444, *v444, *u422, *v422; static double coef[7][3] = { {0.2125,0.7154,0.0721}, /* ITU-R Rec. 709 (1990) */ {0.299, 0.587, 0.114}, /* unspecified */ {0.299, 0.587, 0.114}, /* reserved */ {0.30, 0.59, 0.11}, /* FCC */ {0.299, 0.5mpeg2/src/mpeg2enc/transfrm.c 640 270 132 12646 5565420406 11460 /* transfrm.c, forward / inverse transformation */ /* Copyright (C) 1994, 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" /* private prototypes*/ static void add_pred _ANSI_ARGS_((unsigned char *pred, unsigned char *cur, int lx, short *blk)); static void sub_pred _ANSI_ARGS_((unsigned char *pred, unsigned char *cur, int lx, short *blk)); /* subtract prediction and transform prediction error */ void transform(pred,cur,mbi,blocks) unsigned char *pred[], *cur[]; struct mbinfo *mbi; short blocks[][6][64]; { int i, j, k, n, comp, offs, lx; k = 0; for (j=0; j>1)); lx = width<<1; } else { /* frame DCT */ offs = i + ((n&1)<<3) + width*(j+((n&2)<<2)); lx = width; } } else { comp = n-3; offs = (i>>1) + (width>>1)*(j>>1); lx = width>>1; } sub_pred(pred[comp]+offs,cur[comp]+offs,lx,blocks[k][n]); fdct(blocks[k][n]); } k++; } } /* inverse transform prediction error and add prediction */ void itransform(pred,cur,mbi,blocks) unsigned char *pred[],*cur[]; struct mbinfo *mbi; short blocks[][6][64]; { int i, j, k, n, comp, offs, lx; k = 0; for (j=0; j>1)); lx = width<<1; } else { /* frame DCT */ offs = i + ((n&1)<<3) + width*(j+((n&2)<<2)); lx = width; } } else { comp = n-3; offs = (i>>1) + (width>>1)*(j>>1); lx = width>>1; } idct(blocks[k][n]); add_pred(pred[comp]+offs,cur[comp]+offs,lx,blocks[k][n]); } k++; } } /* add prediction and prediction error, saturate to 0...255 */ static void add_pred(pred,cur,lx,blk) unsigned char *pred, *cur; int lx; short *blk; { int i, j; for (j=0; j<8; j++) { for (i=0; i<8; i++) cur[i] = clp[blk[i] + pred[i]]; blk+= 8; cur+= lx; pred+= lx; } } /* subtract prediction from block data */ static void sub_pred(pred,cur,lx,blk) unsigned char *pred, *cur; int lx; short *blk; { int i, j; for (j=0; j<8; j++) { for (i=0; i<8; i++) blk[i] = cur[i] - pred[i]; blk+= 8; cur+= lx; pred+= lx; } } /* * select between frame and field DCT * * preliminary version: based on inter-field correlation */ void dct_type_estimation(pred,cur,mbi) unsigned char *pred,*cur; struct mbinfo *mbi; { short blk0[128], blk1[128]; int i, j, i0, j0, k, offs, s0, s1, sq0, sq1, s01; double d, r; k = 0; for (j0=0; j00.0) { r = (s01-(s0*s1)/128.0)/sqrt(d); if (r>0.5) mbi[k].dct_type = 0; /* frame DCT */ else mbi[k].dct_type = 1; /* field DCT */ } else mbi[k].dct_type = 1; /* field DCT */ } k++; } } (j> to be a two's-complement arithmetic */ /* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ #include "config.h" #define W1 5681 /* 4096*sqrt(2)*cos(1*pi/16) */ #define W2 5352 /* 4096*sqrt(2)*cos(2*pi/16) */ #define W3 4816 /* 4096*sqrt(2)*cos(3*pi/16) */ #define W5 3218 /* 4096*sqrt(2)*cos(5*pi/16) */ #define W6 2217 /* 4096*sqrt(2)*cos(6*pi/16) */ #define W7 1130 /* 4096*sqrt(2)*cos(7*pi/16) */ /* global declarations */ void init_idct _ANSI_ARGS_((void)); void idct _ANSI_ARGS_((short *block)); /* private data */ static long temp[64]; /* intermediate storage for 1D transform */ static short iclip[1024]; /* clipping table */ static short *iclp; /* private prototypes */ static void idctrow _ANSI_ARGS_((short *src, long *dst)); static void idctcol _ANSI_ARGS_((long *src, short *dst)); /* row (horizontal) IDCT * * 7 pi 1 * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l ) * l=0 8 2 * * where: c[0] = 256*sqrt(0.5) * c[1..7] = 256 */ static void idctrow(src,dst) short *src; long *dst; { long x0, x1, x2, x3, x4, x5, x6, x7, x8; /* shortcut */ if (!src[0] && !src[1] && !src[2] && !src[3] && !src[4] && !src[5] && !src[6] && !src[7]) { dst[0]=dst[1]=dst[2]=dst[3]=dst[4]=dst[5]=dst[6]=dst[7]=0; return; } /* first stage */ x0 = src[0]; x1 = src[4]; x2 = src[6]; x3 = src[2]; x4 = src[1]; x5 = src[7]; x6 = src[5]; x7 = src[3]; 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)<<12) + 16; /* +16 for proper rounding in the fourth stage */ x0 = ((x0-x1)<<12) + 16; 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 */ dst[0] = (x7+x1)>>5; dst[1] = (x3+x2)>>5; dst[2] = (x0+x4)>>5; dst[3] = (x8+x6)>>5; dst[4] = (x8-x6)>>5; dst[5] = (x0-x4)>>5; dst[6] = (x3-x2)>>5; dst[7] = (x7-x1)>>5; } /* 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*sqrt(0.5) * c[1..7] = 1/1024 */ static void idctcol(src,dst) long *src; short *dst; { long x0, x1, x2, x3, x4, x5, x6, x7, x8; /* first stage */ x0 = src[8*0]; x1 = src[8*4]; x2 = src[8*6]; x3 = src[8*2]; x4 = src[8*1]; x5 = src[8*7]; x6 = src[8*5]; x7 = src[8*3]; x8 = W7*(x4+x5) + 2048; x4 = (x8+(W1-W7)*x4)>>12; x5 = (x8-(W1+W7)*x5)>>12; x8 = W3*(x6+x7) + 2048; x6 = (x8-(W3-W5)*x6)>>12; x7 = (x8-(W3+W5)*x7)>>12; /* second stage */ x8 = x0 + x1; x0 -= x1; x1 = W6*(x3+x2) + 2048; x2 = (x1-(W2+W6)*x2)>>12; x3 = (x1+(W2-W6)*x3)>>12; x1 = x4 + x6; x4 -= x6; x6 = x5 + x7; x5 -= x7; /* third stage */ x7 = x8 + x3 + 512; x8 += -x3 + 512; x3 = x0 + x2 + 512; x0 += -x2 + 512; x2 = (181*(x4+x5)+128)>>8; x4 = (181*(x4-x5)+128)>>8; /* fourth stage */ dst[8*0] = iclp[(x7+x1)>>10]; dst[8*1] = iclp[(x3+x2)>>10]; dst[8*2] = iclp[(x0+x4)>>10]; dst[8*3] = iclp[(x8+x6)>>10]; dst[8*4] = iclp[(x8-x6)>>10]; dst[8*5] = iclp[(x0-x4)>>10]; dst[8*6] = iclp[(x3-x2)>>10]; dst[8*7] = iclp[(x7-x1)>>10]; } /* two dimensional inverse discrete cosine transform */ void idct(block) short *block; { int i; for (i=0; i<8; i++) idctrow(block+8*i, temp+8*i); for (i=0; i<8; i++) idctcol(temp+i, block+i); } void init_idct() { int i; iclp = iclip+512; for (i= -512; i<512; i++) iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i); } = (s01-(s0*s1)/128.0)/sqrt(d); if (r>0.5) mbi[k].dct_type = 0; /* frame DCT */ else mbi[k].dct_type = 1; /* field DCT */ } else mbi[k].dct_type = 1; /* field DCT */ } k++; } } (j #include "config.h" #include "global.h" /* private prototypes */ static void frame_estimate _ANSI_ARGS_((unsigned char *org, unsigned char *ref, unsigned char *mb, int i, int j, int sx, int sy, int *iminp, int *jminp, int *imintp, int *jmintp, int *iminbp, int *jminbp, int *dframep, int *dfieldp, int *tselp, int *bselp)); static int fullsearch _ANSI_ARGS_((unsigned char *org, unsigned char *ref, unsigned char *blk, int lx, int i0, int j0, int sx, int sy, int h, int xmax, int ymax, int *iminp, int *jminp)); static int dist1 _ANSI_ARGS_((unsigned char *blk1, unsigned char *blk2, int lx, int hx, int hy, int h)); static int dist2 _ANSI_ARGS_((unsigned char *blk1, unsigned char *blk2, int lx, int hx, int hy, int h)); static int bdist1 _ANSI_ARGS_((unsigned char *pf, unsigned char *pb, unsigned char *p2, int lx, int hxf, int hyf, int hxb, int hyb, int h)); static int bdist2 _ANSI_ARGS_((unsigned char *pf, unsigned char *pb, unsigned char *p2, int lx, int hxf, int hyf, int hxb, int hyb, int h)); static int variance _ANSI_ARGS_((unsigned char *p, int lx)); /* * motion estimation for progressive and interlaced frame pictures * * oldorg: source frame for forward prediction (P and B frames) * neworg: source frame for backward prediction (B frames only) * oldref: reconstructed frame for forward prediction (P and B frames) * newref: reconstructed frame for backward prediction (B frames only) * cur: current frame (the one for which the prediction is formed) * sxf,syf: forward search window (frame coordinates) * sxb,syb: backward search window (frame coordinates) * mbi: pointer to macroblock info structure * * results: * mbi-> * mb_type: 0, MB_INTRA, MB_FORWARD, MB_BACKWARD, MB_FORWARD|MB_BACKWARD * MV[][][]: motion vectors (frame format) * mv_field_sel: top/bottom field (for field prediction) * motion_type: MC_FRAME, MC_FIELD * * uses global vars: pict_type, frame_pred_dct */ void motion_estimation(oldorg,neworg,oldref,newref,cur,sxf,syf,sxb,syb,mbi) unsigned char *oldorg,*neworg,*oldref,*newref,*cur; int sxf,syf,sxb,syb; struct mbinfo *mbi; { int i,j; int imin,jmin,iminf,jminf,iminr,jminr; int imint,jmint,iminb,jminb; int imintf,jmintf,iminbf,jminbf; int imintr,jmintr,iminbr,jminbr; int var,v0; int dmc,dmcf,dmcr,dmci,vmc,vmcf,vmcr,vmci; int dmcfield,dmcfieldf,dmcfieldr,dmcfieldi; int tsel,bsel,tself,bself,tselr,bselr; unsigned char *mb; for (j=0; jmb_type = MB_INTRA; else if (pict_type==P_TYPE) { var = variance(mb,width); if (frame_pred_dct) { dmc = fullsearch(oldorg,oldref,mb, width,i,j,sxf,syf,16,width,height,&imin,&jmin); vmc = dist2(oldref+(imin>>1)+width*(jmin>>1),mb, width,imin&1,jmin&1,16); mbi->motion_type = MC_FRAME; } else { frame_estimate(oldorg,oldref,mb,i,j,sxf,syf, &imin,&jmin,&imint,&jmint,&iminb,&jminb, &dmc,&dmcfield,&tsel,&bsel); /* select between frame and field prediction */ if (dmc<=dmcfield) { mbi->motion_type = MC_FRAME; vmc = dist2(oldref+(imin>>1)+width*(jmin>>1),mb, width,imin&1,jmin&1,16); } else { mbi->motion_type = MC_FIELD; dmc = dmcfield; vmc = dist2(oldref+(tsel?width:0)+(imint>>1)+(width<<1)*(jmint>>1), mb,width<<1,imint&1,jmint&1,8); vmc+= dist2(oldref+(bsel?width:0)+(iminb>>1)+(width<<1)*(jminb>>1), mb+width,width<<1,iminb&1,jminb&1,8); } } if (vmc>var && vmc>=9*256) mbi->mb_type = MB_INTRA; else { v0 = dist2(oldref+i+width*j,mb,width,0,0,16); if (4*v0>5*vmc && v0>=9*256) { var = vmc; mbi->mb_type = MB_FORWARD; if (mbi->motion_type==MC_FRAME) { mbi->MV[0][0][0] = imin - (i<<1); mbi->MV[0][0][1] = jmin - (j<<1); } else { /* these are FRAME vectors */ mbi->MV[0][0][0] = imint - (i<<1); mbi->MV[0][0][1] = (jmint<<1) - (j<<1); mbi->MV[1][0][0] = iminb - (i<<1); mbi->MV[1][0][1] = (jminb<<1) - (j<<1); mbi->mv_field_sel[0][0] = tsel; mbi->mv_field_sel[1][0] = bsel; } } else { var = v0; mbi->mb_type = 0; mbi->motion_type = MC_FRAME; /* probably redundant */ mbi->MV[0][0][0] = 0; mbi->MV[0][0][1] = 0; } } } else /* if (pict_type==B_TYPE) */ { var = variance(mb,width); if (frame_pred_dct) { /* forward */ dmcf = fullsearch(oldorg,oldref,mb, width,i,j,sxf,syf,16,width,height,&iminf,&jminf); vmcf = dist2(oldref+(iminf>>1)+width*(jminf>>1),mb, width,iminf&1,jminf&1,16); /* backward */ dmcr = fullsearch(neworg,newref,mb, width,i,j,sxb,syb,16,width,height,&iminr,&jminr); vmcr = dist2(newref+(iminr>>1)+width*(jminr>>1),mb, width,iminr&1,jminr&1,16); /* interpolated (bidirectional) */ vmci = bdist2(oldref+(iminf>>1)+width*(jminf>>1), newref+(iminr>>1)+width*(jminr>>1), mb,width,iminf&1,jminf&1,iminr&1,jminr&1,16); /* decisions */ if (vmcf<=vmcr && vmcf<=vmci) { vmc = vmcf; mbi->mb_type = MB_FORWARD; } else if (vmcr<=vmci) { vmc = vmcr; mbi->mb_type = MB_BACKWARD; } else { vmc = vmci; mbi->mb_type = MB_FORWARD|MB_BACKWARD; } mbi->motion_type = MC_FRAME; } else { /* forward prediction */ frame_estimate(oldorg,oldref,mb,i,j,sxf,syf, &iminf,&jminf,&imintf,&jmintf,&iminbf,&jminbf, &dmcf,&dmcfieldf,&tself,&bself); /* backward prediction */ frame_estimate(neworg,newref,mb,i,j,sxb,syb, &iminr,&jminr,&imintr,&jmintr,&iminbr,&jminbr, &dmcr,&dmcfieldr,&tselr,&bselr); /* calculate interpolated distance */ /* frame */ dmci = bdist1(oldref+(iminf>>1)+width*(jminf>>1), newref+(iminr>>1)+width*(jminr>>1), mb,width,iminf&1,jminf&1,iminr&1,jminr&1,16); /* top field */ dmcfieldi = bdist1(oldref+(imintf>>1)+(tself?width:0)+(width<<1)*(jmintf>>1), newref+(imintr>>1)+(tselr?width:0)+(width<<1)*(jmintr>>1), mb,width<<1,imintf&1,jmintf&1,imintr&1,jmintr&1,8); /* bottom field */ dmcfieldi+= bdist1(oldref+(iminbf>>1)+(bself?width:0)+(width<<1)*(jminbf>>1), newref+(iminbr>>1)+(bselr?width:0)+(width<<1)*(jminbr>>1), mb+width,width<<1,iminbf&1,jminbf&1,iminbr&1,jminbr&1,8); /* select prediction type of minimum distance */ if (dmcimb_type = MB_FORWARD|MB_BACKWARD; mbi->motion_type = MC_FRAME; vmc = bdist2(oldref+(iminf>>1)+width*(jminf>>1), newref+(iminr>>1)+width*(jminr>>1), mb,width,iminf&1,jminf&1,iminr&1,jminr&1,16); } else if (dmcfieldimb_type = MB_FORWARD|MB_BACKWARD; mbi->motion_type = MC_FIELD; vmc = bdist2(oldref+(imintf>>1)+(tself?width:0)+(width<<1)*(jmintf>>1), newref+(imintr>>1)+(tselr?width:0)+(width<<1)*(jmintr>>1), mb,width<<1,imintf&1,jmintf&1,imintr&1,jmintr&1,8); vmc+= bdist2(oldref+(iminbf>>1)+(bself?width:0)+(width<<1)*(jminbf>>1), newref+(iminbr>>1)+(bselr?width:0)+(width<<1)*(jminbr>>1), mb+width,width<<1,iminbf&1,jminbf&1,iminbr&1,jminbr&1,8); } else if (dmcfmb_type = MB_FORWARD; mbi->motion_type = MC_FRAME; vmc = dist2(oldref+(iminf>>1)+width*(jminf>>1),mb, width,iminf&1,jminf&1,16); } else if (dmcfieldfmb_type = MB_FORWARD; mbi->motion_type = MC_FIELD; vmc = dist2(oldref+(tself?width:0)+(imintf>>1)+(width<<1)*(jmintf>>1), mb,width<<1,imintf&1,jmintf&1,8); vmc+= dist2(oldref+(bself?width:0)+(iminbf>>1)+(width<<1)*(jminbf>>1), mb+width,width<<1,iminbf&1,jminbf&1,8); } else if (dmcrmb_type = MB_BACKWARD; mbi->motion_type = MC_FRAME; vmc = dist2(newref+(iminr>>1)+width*(jminr>>1),mb, width,iminr&1,jminr&1,16); } else { /* field, backward */ mbi->mb_type = MB_BACKWARD; mbi->motion_type = MC_FIELD; vmc = dist2(newref+(tselr?width:0)+(imintr>>1)+(width<<1)*(jmintr>>1), mb,width<<1,imintr&1,jmintr&1,8); vmc+= dist2(newref+(bselr?width:0)+(iminbr>>1)+(width<<1)*(jminbr>>1), mb+width,width<<1,iminbr&1,jminbr&1,8); } } if (vmc>var && vmc>=9*256) mbi->mb_type = MB_INTRA; else { var = vmc; if (mbi->motion_type==MC_FRAME) { mbi->MV[0][0][0] = iminf - (i<<1); mbi->MV[0][0][1] = jminf - (j<<1); mbi->MV[0][1][0] = iminr - (i<<1); mbi->MV[0][1][1] = jminr - (j<<1); } else { /* these are FRAME vectors */ mbi->MV[0][0][0] = imintf - (i<<1); mbi->MV[0][0][1] = (jmintf<<1) - (j<<1); mbi->MV[1][0][0] = iminbf - (i<<1); mbi->MV[1][0][1] = (jminbf<<1) - (j<<1); mbi->mv_field_sel[0][0] = tself; mbi->mv_field_sel[1][0] = bself; mbi->MV[0][1][0] = imintr - (i<<1); mbi->MV[0][1][1] = (jmintr<<1) - (j<<1); mbi->MV[1][1][0] = iminbr - (i<<1); mbi->MV[1][1][1] = (jminbr<<1) - (j<<1); mbi->mv_field_sel[0][1] = tselr; mbi->mv_field_sel[1][1] = bselr; } } } mbi->var = var; mbi++; } if (!quiet) { putc('.',stderr); fflush(stderr); } } if (!quiet) putc('\n',stderr); } /* * frame picture motion estimation * * org: top left pel of source reference frame * ref: top left pel of reconstructed reference frame * mb: macroblock to be matched * i,j: location of mb relative to ref (=center of search window) * sx,sy: half widths of search window * iminp,jminp,dframep: location and value of best frame prediction * imintp,jmintp,tselp: location of best field pred. for top field of mb * iminbp,jminbp,bselp: location of best field pred. for bottom field of mb * dfieldp: value of field prediction */ static void frame_estimate(org,ref,mb,i,j,sx,sy, iminp,jminp,imintp,jmintp,iminbp,jminbp,dframep,dfieldp,tselp,bselp) unsigned char *org,*ref,*mb; int i,j,sx,sy; int *iminp,*jminp; int *imintp,*jmintp,*iminbp,*jminbp; int *dframep,*dfieldp; int *tselp,*bselp; { int dt,db,dmint,dminb; int imint,iminb,jmint,jminb; /* frame prediction */ *dframep = fullsearch(org,ref,mb,width,i,j,sx,sy,16,width,height, iminp,jminp); /* predict top field from top field */ dt = fullsearch(org,ref,mb,width<<1,i,j>>1,sx,sy>>1,8,width,height>>1, &imint,&jmint); /* predict top field from bottom field */ db = fullsearch(org+width,ref+width,mb,width<<1,i,j>>1,sx,sy>>1,8,width,height>>1, &iminb,&jminb); /* select prediction for top field */ if (dt<=db) { dmint=dt; *imintp=imint; *jmintp=jmint; *tselp=0; } else { dmint=db; *imintp=iminb; *jmintp=jminb; *tselp=1; } /* predict bottom field from top field */ dt = fullsearch(org,ref,mb+width,width<<1,i,j>>1,sx,sy>>1,8,width,height>>1, &imint,&jmint); /* predict bottom field from bottom field */ db = fullsearch(org+width,ref+width,mb+width,width<<1,i,j>>1,sx,sy>>1,8,width,height>>1, &iminb,&jminb); /* select prediction for bottom field */ if (db<=dt) { dminb=db; *iminbp=iminb; *jminbp=jminb; *bselp=1; } else { dminb=dt; *iminbp=imint; *jminbp=jmint; *bselp=0; } *dfieldp=dmint+dminb; } /* * full search block matching * * blk: top left pel of (16*h) block * h: height of block * lx: distance (in bytes) of vertically adjacent pels in ref,blk * org: top left pel of source reference picture * ref: top left pel of reconstructed reference picture * i0,j0: center of search window * sx,sy: half widths of search window * xmax,ymax: right/bottom limits of search area * iminp,jminp: pointers to where the result is stored * result is given as half pel offset from ref(0,0) * i.e. NOT relative to (i0,j0) */ static int fullsearch(org,ref,blk,lx,i0,j0,sx,sy,h,xmax,ymax,iminp,jminp) unsigned char *org,*ref,*blk; int lx,i0,j0,sx,sy,h,xmax,ymax; int *iminp,*jminp; { int i,j,imin,jmin,ilow,ihigh,jlow,jhigh; int d,dmin; dmin=65536; ilow = i0 - sx; ihigh = i0 + sx; if (ilow<0) ilow = 0; if (ihigh>xmax-16) ihigh = xmax-16; jlow = j0 - sy; jhigh = j0 + sy; if (jlow<0) jlow = 0; if (jhigh>ymax-h) jhigh = ymax-h; /* full pel */ for (j=jlow; j<=jhigh; j++) for (i=ilow; i<=ihigh; i++) { d = dist1(org+i+lx*j,blk,lx,0,0,h); if (d0); ihigh = imin + (imin<((xmax-16)<<1)); jlow = jmin - (jmin>0); jhigh = jmin + (jmin<((ymax-h)<<1)); for (j=jlow; j<=jhigh; j++) for (i=ilow; i<=ihigh; i++) { d = dist1(ref+(i>>1)+lx*(j>>1),blk,lx,i&1,j&1,h); if (d=0) s+= v; else s-= v; } p1+= lx; p2+= lx; } else if (hx && !hy) for (j=0; j>1) - p2[i]; if (v>=0) s+= v; else s-= v; } p1+= lx; p2+= lx; } else if (!hx && hy) { p1a = p1 + lx; for (j=0; j>1) - p2[i]; if (v>=0) s+= v; else s-= v; } p1 = p1a; p1a+= lx; p2+= lx; } } else /* if (hx && hy) */ { p1a = p1 + lx; for (j=0; j>2) - p2[i]; if (v>=0) s+= v; else s-= v; } p1 = p1a; p1a+= lx; p2+= lx; } } return s; } /* * total squared difference between two (16*h) blocks * including optional half pel interpolation of blk1 (hx,hy) * blk1,blk2: addresses of top left pels of both blocks * lx: distance (in bytes) of vertically adjacent pels * hx,hy: flags for horizontal and/or vertical interpolation * h: height of block (usually 8 or 16) */ static int dist2(blk1,blk2,lx,hx,hy,h) unsigned char *blk1,*blk2; int lx,hx,hy,h; { unsigned char *p1,*p1a,*p2; int i,j; int s,v; s = 0; p1 = blk1; p2 = blk2; if (!hx && !hy) for (j=0; j>1) - p2[i]; s+= v*v; } p1+= lx; p2+= lx; } else if (!hx && hy) { p1a = p1 + lx; for (j=0; j>1) - p2[i]; s+= v*v; } p1 = p1a; p1a+= lx; p2+= lx; } } else /* if (hx && hy) */ { p1a = p1 + lx; for (j=0; j>2) - p2[i]; s+= v*v; } p1 = p1a; p1a+= lx; p2+= lx; } } return s; } /* * absolute difference error between a (16*h) block and a bidirectional * prediction * * p2: address of top left pel of block * pf,hxf,hyf: address and half pel flags of forward ref. block * pb,hxb,hyb: address and half pel flags of backward ref. block * h: height of block * lx: distance (in bytes) of vertically adjacent pels in p2,pf,pb */ static int bdist1(pf,pb,p2,lx,hxf,hyf,hxb,hyb,h) unsigned char *pf,*pb,*p2; int lx,hxf,hyf,hxb,hyb,h; { unsigned char *pfa,*pfb,*pfc,*pba,*pbb,*pbc; int i,j; int s,v; pfa = pf + hxf; pfb = pf + lx*hyf; pfc = pfb + hxf; pba = pb + hxb; pbb = pb + lx*hyb; pbc = pbb + hxb; s = 0; for (j=0; j>2) + ((unsigned int)(*pb++ + *pba++ + *pbb++ + *pbc++ + 2)>>2) + 1)>>1) - *p2++; if (v>=0) s+= v; else s-= v; } p2+= lx-16; pf+= lx-16; pfa+= lx-16; pfb+= lx-16; pfc+= lx-16; pb+= lx-16; pba+= lx-16; pbb+= lx-16; pbc+= lx-16; } return s; } /* * squared error between a (16*h) block and a bidirectional * prediction * * p2: address of top left pel of block * pf,hxf,hyf: address and half pel flags of forward ref. block * pb,hxb,hyb: address and half pel flags of backward ref. block * h: height of block * lx: distance (in bytes) of vertically adjacent pels in p2,pf,pb */ static int bdist2(pf,pb,p2,lx,hxf,hyf,hxb,hyb,h) unsigned char *pf,*pb,*p2; int lx,hxf,hyf,hxb,hyb,h; { unsigned char *pfa,*pfb,*pfc,*pba,*pbb,*pbc; int i,j; int s,v; pfa = pf + hxf; pfb = pf + lx*hyf; pfc = pfb + hxf; pba = pb + hxb; pbb = pb + lx*hyb; pbc = pbb + hxb; s = 0; for (j=0; j>2) + ((unsigned int)(*pb++ + *pba++ + *pbb++ + *pbc++ + 2)>>2) + 1)>>1) - *p2++; s+=v*v; } p2+= lx-16; pf+= lx-16; pfa+= lx-16; pfb+= lx-16; pfc+= lx-16; pb+= lx-16; pba+= lx-16; pbb+= lx-16; pbc+= lx-16; } return s; } /* * variance of a (16*16) block, multiplied by 256 * p: address of top left pel of block * lx: distance (in bytes) of vertically adjacent pels */ static int variance(p,lx) unsigned char *p; int lx; { int i,j; unsigned int v,s,s2; s = s2 = 0; for (j=0; j<16; j++) { for (i=0; i<16; i++) { v = *p++; s+= v; s2+= v*v; } p+= lx-16; } return s2 - (s*s)/256; } rch(org+width,ref+width,mb,width<<1,i,j>>1,sx,sy>>1,8,width,height>>1, &iminb,&jminb); /* select prediction for top field */ if (dt<=db) { dmint=dt; *imintp=imint; *jmintp=jmint; *tselp=0; } else { dmint=db; *imintp=iminb; *jmintp=jminb; *tselp=1; } /* predict bottom field from top field */ dt = fullsearchmpeg2/src/mpeg2enc/putpic.c 640 270 132 20417 5565623475 11136 /* putpic.c, block and motion vector encoding routines */ /* Copyright (C) 1994, 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 putmvs _ANSI_ARGS_((int MV[2][2][2], int PMV[2][2][2], int mv_field_sel[2][2], int s, int motion_type, int hor_f_code, int vert_f_code)); /* quantization / variable length encoding of a complete picture */ void putpict(frame) unsigned char *frame; { int i, j, k, comp, cc; int mb_type; int PMV[2][2][2]; int prev_mquant, mquant; int cbp, MBAinc; rc_init_pict(); /* set up rate control */ /* picture header and picture coding extension */ putpicthdr(); if (!mpeg1) putpictcodext(); prev_mquant = rc_start_mb(); /* initialize quantization parameter */ k = 0; for (j=0; j>7,3); /* slice_vertical_position_extension */ } putbits(prev_mquant>>1,5); /* quantiser_scale_code */ putbits(0,1); /* extra_bit_slice */ /* reset predictors */ for (cc=0; cc<3; cc++) dc_dct_pred[cc] = 0; 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; MBAinc = i + 1; /* first MBAinc denotes absolute position */ } mb_type = mbinfo[k].mb_type; /* determine mquant (rate control) */ mquant = rc_calc_mquant(k,frame+(i<<4)+(j<<4)*width); /* ignore small changes in mquant */ if (mquant>=8 && (mquant-prev_mquant)>=-4 && (mquant-prev_mquant)<=4) mbinfo[k].mquant = prev_mquant; else mbinfo[k].mquant = mquant; /* quantize macroblock */ if (mb_type & MB_INTRA) { for (comp=0;comp<6;comp++) quant_intra(blocks[k][comp],blocks[k][comp], dc_prec,intra_q,mbinfo[k].mquant); mbinfo[k].cbp = cbp = 63; } else { cbp = 0; for (comp=0; comp<6; comp++) cbp = (cbp<<1) | quant_non_intra(blocks[k][comp],blocks[k][comp], inter_q,mbinfo[k].mquant); mbinfo[k].cbp = cbp; if (cbp) mb_type|= MB_PATTERN; } /* output mquant if it has changed */ if (cbp && prev_mquant!=mbinfo[k].mquant) mb_type|= MB_QUANT; /* check if macroblock can be skipped */ if (i!=0 && i!=mb_width-1 && !cbp) { /* no DCT coefficients and neither first or last macroblock of slice */ if (pict_type==P_TYPE && !(mb_type&MB_FORWARD)) { /* P picture, no motion vectors -> skip */ /* reset predictors */ for (cc=0; cc<3; cc++) dc_dct_pred[cc] = 0; 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; mbinfo[k].mb_type = mb_type; mbinfo[k].skipped = 1; MBAinc++; k++; continue; } if (pict_type==B_TYPE && mbinfo[k].motion_type==MC_FRAME && ((mbinfo[k-1].mb_type^mb_type)&(MB_FORWARD|MB_BACKWARD))==0 && ((PMV[0][0][0]==mbinfo[k].MV[0][0][0] && PMV[0][0][1]==mbinfo[k].MV[0][0][1]) || !(mb_type&MB_FORWARD)) && ((PMV[0][1][0]==mbinfo[k].MV[0][1][0] && PMV[0][1][1]==mbinfo[k].MV[0][1][1]) || !(mb_type&MB_BACKWARD))) { /* conditions for skipping in B frames: * - must be frame predicted (in frame pictures) * - must be the same prediction type (forward/backward/interp.) * as previous macroblock * - relevant vectors (forward/backward/both) have to be the same * as in previous macroblock */ mbinfo[k].mb_type = mb_type; mbinfo[k].skipped = 1; MBAinc++; k++; continue; } } /* macroblock cannot be skipped */ mbinfo[k].skipped = 0; if (pict_type==P_TYPE && !cbp && !(mb_type&MB_FORWARD)) mb_type|= MB_FORWARD; /* there's no VLC for 'No MC, Not Coded' */ putaddrinc(MBAinc); /* macroblock_address_increment */ MBAinc = 1; putmbtype(pict_type,mb_type); /* macroblock type */ if (mb_type & (MB_FORWARD|MB_BACKWARD) && !frame_pred_dct) putbits(mbinfo[k].motion_type,2); if (cbp && !frame_pred_dct) putbits(mbinfo[k].dct_type,1); if (mb_type & MB_QUANT) { putbits(mbinfo[k].mquant>>1,5); prev_mquant = mbinfo[k].mquant; } if (mb_type & MB_FORWARD) { /* forward motion vectors, update predictors */ putmvs(mbinfo[k].MV,PMV,mbinfo[k].mv_field_sel,0, mbinfo[k].motion_type,forw_hor_f_code,forw_vert_f_code); } if (mb_type & MB_BACKWARD) { /* backward motion vectors, update predictors */ putmvs(mbinfo[k].MV,PMV,mbinfo[k].mv_field_sel,1, mbinfo[k].motion_type,back_hor_f_code,back_vert_f_code); } if (mb_type & MB_PATTERN) putcbp(cbp); for (comp=0; comp<6; comp++) { /* block loop */ if (cbp & (32>>comp)) { if (mb_type & MB_INTRA) { cc = (comp<4) ? 0 : comp-3; putintrablk(blocks[k][comp],cc); } else putnonintrablk(blocks[k][comp]); } } /* reset predictors */ if (!(mb_type & MB_INTRA)) for (cc=0; cc<3; cc++) dc_dct_pred[cc] = 0; if (mb_type & MB_INTRA || (pict_type==P_TYPE && !(mb_type & MB_FORWARD))) { 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; } mbinfo[k].mb_type = mb_type; k++; } } rc_update_pict(); } /* output motion vectors (6.2.5.2, 6.3.16.2) * * this routine also updates the predictions for motion vectors (PMV) * * field pictures and dual prime vectors not implemented */ static void putmvs(MV,PMV,mv_field_sel,s,motion_type,hor_f_code,vert_f_code) int MV[2][2][2],PMV[2][2][2]; int mv_field_sel[2][2]; int s,motion_type,hor_f_code,vert_f_code; { if (motion_type==MC_FRAME) { putmv(MV[0][s][0]-PMV[0][s][0],hor_f_code); putmv(MV[0][s][1]-PMV[0][s][1],vert_f_code); PMV[0][s][0]=PMV[1][s][0]=MV[0][s][0]; PMV[0][s][1]=PMV[1][s][1]=MV[0][s][1]; } else { putbits(mv_field_sel[0][s],1); putmv(MV[0][s][0]-PMV[0][s][0],hor_f_code); putmv((MV[0][s][1]>>1)-(PMV[0][s][1]>>1),vert_f_code); putbits(mv_field_sel[1][s],1); putmv(MV[1][s][0]-PMV[1][s][0],hor_f_code); putmv((MV[1][s][1]>>1)-(PMV[1][s][1]>>1),vert_f_code); PMV[0][s][0]=MV[0][s][0]; PMV[0][s][1]=MV[0][s][1]; PMV[1][s][0]=MV[1][s][0]; PMV[1][s][1]=MV[1][s][1]; } } ow * sx,sy: half widths of search window * xmax,ymax: right/bottom limits of search area * iminp,jminp: pointers to where the result is stored * result is given as half pel offset from ref(0,0) * i.e. NOT relatmpeg2/src/mpeg2enc/putseq.c 640 270 132 16055 5565420716 11147 /* putseq.c, sequence level routines */ /* Copyright (C) 1994, 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" void putseq() { /* this routine assumes (N % M) == 0 */ int i, j, k, f, f0, n, sxf, syf, sxb, syb; FILE *fd; char name[256]; unsigned char *neworg[3], *newref[3]; static char ipb[5] = {' ','I','P','B','D'}; rc_init_seq(); /* initialize rate control */ /* sequence header, sequence extension and sequence display extension */ putseqhdr(); if (!mpeg1) { putseqext(); putseqdispext(); } /* optionally output some text data (description, copyright or whatever) */ if (strlen(id_string) > 1) putuserdata(id_string); /* loop through all frames in encoding/decoding order */ for (i=0; i=nframes) f = nframes - 1; if (i==f0) /* first displayed frame in GOP is I */ { /* I frame */ pict_type = I_TYPE; forw_hor_f_code = forw_vert_f_code = 15; back_hor_f_code = back_vert_f_code = 15; /* n: number of frames in current GOP */ n = (i==0) ? N-(M-1) : N; /* last GOP may contain less frames */ if (n > nframes-f0) n = nframes-f0; rc_init_GOP(n); putgophdr(f0,i==0); /* set closed_GOP in first GOP only */ } else { /* P frame */ pict_type = P_TYPE; forw_hor_f_code = motion_data[0].forw_hor_f_code; forw_vert_f_code = motion_data[0].forw_vert_f_code; back_hor_f_code = back_vert_f_code = 15; sxf = motion_data[0].sxf; syf = motion_data[0].sxf; } } else { /* B frame */ for (j=0; j<3; j++) { neworg[j] = auxorgframe[j]; newref[j] = auxframe[j]; } /* f: frame number in display order */ f = i - 1; pict_type = B_TYPE; n = (i-2)%M + 1; /* first B: n=1, second B: n=2, ... */ forw_hor_f_code = motion_data[n].forw_hor_f_code; forw_vert_f_code = motion_data[n].forw_vert_f_code; back_hor_f_code = motion_data[n].back_hor_f_code; back_vert_f_code = motion_data[n].back_vert_f_code; sxf = motion_data[n].sxf; syf = motion_data[n].syf; sxb = motion_data[n].sxb; syb = motion_data[n].syb; } temp_ref = f - f0; frame_pred_dct = frame_pred_dct_tab[pict_type-1]; intravlc = intravlc_tab[pict_type-1]; altscan = altscan_tab[pict_type-1]; fprintf(statfile,"\nFrame %d (#%d in display order):\n",i,f); fprintf(statfile," picture_type=%c\n",ipb[pict_type]); fprintf(statfile," temporal_reference=%d\n",temp_ref); fprintf(statfile," frame_pred_frame_dct=%d\n",frame_pred_dct); fprintf(statfile," intra_vlc_format=%d\n",intravlc); fprintf(statfile," alternate_scan=%d\n",altscan); if (pict_type!=I_TYPE) { fprintf(statfile," forward search window: %d...%d / %d...%d\n", -sxf,sxf,-syf,syf); fprintf(statfile," forward vector range: %d...%d.5 / %d...%d.5\n", -(4<>1)-(PMV[1][s][1]>>1),vert_f_code); PMV[0][s][0]=MV[0][s][0]; PMV[0][s][1]=MV[0][s][1]; PMV[1][s][0]=MV[1][s][0]; PMV[1][s][1]=MV[1][s][1]; } } ow * sx,sy: half widths of search window * xmax,ymax: right/bottom limits of search area * iminp,jminp: pointers to where the result is stored * result is given as half pel offset from ref(0,0) * i.e. NOT relatmpeg2/src/mpeg2enc/stats.c 640 270 132 13165 5565420730 10757 /* stats.c, coding statistics */ /* Copyright (C) 1994, 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" void calcSNR(org,rec) unsigned char *org[3]; unsigned char *rec[3]; { int i, j; double v1, s1, s2, e2; unsigned char *porg, *prec; s1 = s2 = e2 = 0.0; for (j=0; j>1); j++) { porg = org[1] + j*(width>>1); prec = rec[1] + j*(width>>1); for (i=0; i<(horizontal_size>>1); i++) { v1 = porg[i]; s1+= v1; s2+= v1*v1; v1-= prec[i]; e2+= v1*v1; } } s1/= horizontal_size*vertical_size/4; s2/= horizontal_size*vertical_size/4; e2/= horizontal_size*vertical_size/4; s2-= s1*s1; fprintf(statfile,"U: variance=%3.3g, MSE=%3.3g (%3.3g dB), SNR=%3.3g dB\n", s2,e2,10.0*log10(255.0*255.0/e2),10.0*log10(s2/e2)); s1 = s2 = e2 = 0.0; for (j=0; j<(vertical_size>>1); j++) { porg = org[2] + j*(width>>1); prec = rec[2] + j*(width>>1); for (i=0; i<(horizontal_size>>1); i++) { v1 = porg[i]; s1+= v1; s2+= v1*v1; v1-= prec[i]; e2+= v1*v1; } } s1/= horizontal_size*vertical_size/4; s2/= horizontal_size*vertical_size/4; e2/= horizontal_size*vertical_size/4; s2-= s1*s1; fprintf(statfile,"V: variance=%3.3g, MSE=%3.3g (%3.3g dB), SNR=%3.3g dB\n", s2,e2,10.0*log10(255.0*255.0/e2),10.0*log10(s2/e2)); } void stats() { int i, j, k, nmb, mb_type; int n_skipped, n_intra, n_ncoded, n_interp, n_forward, n_backward; struct mbinfo *mbi; nmb = mb_width*mb_height; n_skipped=n_intra=n_ncoded=n_interp=n_forward=n_backward=0; for (k=0; kskipped) n_skipped++; else if (mbi->mb_type & MB_INTRA) n_intra++; else if (!(mbi->mb_type & MB_PATTERN)) n_ncoded++; if (mbi->mb_type & MB_FORWARD) { if (mbi->mb_type & MB_BACKWARD) n_interp++; else n_forward++; } else if (mbi->mb_type & MB_BACKWARD) n_backward++; } fprintf(statfile,"\nframe statistics:\n"); fprintf(statfile," # of intra coded macroblocks: %4d (%.1f%%)\n", n_intra,100.0*(double)n_intra/nmb); fprintf(statfile," # of not coded macroblocks: %4d (%.1f%%)\n", n_ncoded,100.0*(double)n_ncoded/nmb); fprintf(statfile," # of skipped macroblocks: %4d (%.1f%%)\n", n_skipped,100.0*(double)n_skipped/nmb); fprintf(statfile," # of forw. pred. macroblocks: %4d (%.1f%%)\n", n_forward,100.0*(double)n_forward/nmb); fprintf(statfile," # of backw. pred. macroblocks: %4d (%.1f%%)\n", n_backward,100.0*(double)n_backward/nmb); fprintf(statfile," # of interpolated macroblocks: %4d (%.1f%%)\n", n_interp,100.0*(double)n_interp/nmb); fprintf(statfile,"\nmacroblock_type map:\n"); k = 0; for (j=0; jmb_type; if (mbi->skipped) putc('S',statfile); else if (mb_type & MB_INTRA) putc('I',statfile); else switch (mb_type & (MB_FORWARD|MB_BACKWARD)) { case MB_FORWARD: putc(mbi->motion_type==MC_FRAME?'F':'f',statfile); break; case MB_BACKWARD: putc(mbi->motion_type==MC_FRAME?'B':'b',statfile); break; case MB_FORWARD|MB_BACKWARD: putc(mbi->motion_type==MC_FRAME?'D':'d',statfile); break; default: putc('0',statfile); break; } if (mb_type & MB_QUANT) putc('Q',statfile); else if (mb_type & (MB_PATTERN|MB_INTRA)) putc(' ',statfile); else putc('N',statfile); putc(' ',statfile); k++; } putc('\n',statfile); } fprintf(statfile,"\nmquant map:\n"); k=0; for (j=0; j #include #include "config.h" #include "global.h" /* private prototypes */ static double var_sblk _ANSI_ARGS_((unsigned char *p, int lx)); /* rate control variables */ static int outbitcnt; double Xi, Xp, Xb, r, d0i, d0p, d0b, avg_act; static double R, T, d, actsum; static int Np, Nb, S, Q; void rc_init_seq() { /* reaction parameter (constant) */ if (r==0.0) r = 2.0*bit_rate/picture_rate; /* average activity */ if (avg_act==0.0) avg_act = 400.0; /* remaining # of bits in GOP */ R = 0; /* global complexity measure */ if (Xi==0.0) Xi = 160.0*bit_rate/115.0; if (Xp==0.0) Xp = 60.0*bit_rate/115.0; if (Xb==0.0) Xb = 42.0*bit_rate/115.0; /* virtual buffer fullness */ if (d0i==0.0) d0i = 10.0*r/31.0; if (d0p==0.0) d0p = 10.0*r/31.0; if (d0b==0.0) d0b = 1.4*10.0*r/31.0; fprintf(statfile,"\nrate control: sequence initialization\n"); fprintf(statfile, " initial global complexity measures (I,P,B): Xi=%.0f, Xp=%.0f, Xb=%.0f\n", Xi, Xp, Xb); fprintf(statfile," reaction parameter: r=%.0f\n", r); fprintf(statfile, " initial virtual buffer fullness (I,P,B): d0i=%.0f, d0p=%.0f, d0b=%.0f\n", d0i, d0p, d0b); fprintf(statfile," initial avarage activity: avg_act=%.1f\n", avg_act); } void rc_init_GOP(n) int n; { R+= N*bit_rate/picture_rate; Np = N/M - 1; Nb = N - Np - 1; fprintf(statfile,"\nrate control: new group of pictures (GOP)\n"); fprintf(statfile," target number of bits for GOP: R=%.0f\n",R); fprintf(statfile," number of P frames in GOP: Np=%d\n",Np); fprintf(statfile," number of B frames in GOP: Nb=%d\n",Nb); } /* Note: we need to substitute K for the 1.4 and 1.0 constants -- this can be modified to fit image content */ /* Step 1: compute target bits for current picture being coded */ void rc_init_pict() { double Tmin; switch (pict_type) { case I_TYPE: T = R/(1.0+Np*Xp/(Xi*1.0)+Nb*Xb/(Xi*1.4)); d = d0i; break; case P_TYPE: T = R/(Np+Nb*1.0*Xb/(1.4*Xp)); d = d0p; break; case B_TYPE: T = R/(Nb+Np*1.4*Xp/(1.0*Xb)); d = d0b; break; } Tmin = bit_rate/(8.0*picture_rate); if (T31) mquant = 31; mquant <<= 1; /* fprintf(statfile,"rc_start_mb:\n"); fprintf(statfile,"mquant=%d\n",mquant); */ return mquant; } /* Step 2: measure virtual buffer - estimated buffer discrepency */ int rc_calc_mquant(j,p) int j; unsigned char *p; { int mquant; double dj, Qj, actj, N_actj, var; /* measure virtual buffer discrepency from uniform distribution model */ dj = d + (bitcount()-S) - j*(T/(mb_width*mb_height)); /* scale against dynamic range of mquant and the bits/picture count */ Qj = dj*31.0/r; /* take minimum spatial activity measure of luminance blocks */ /* frame */ actj = var_sblk(p,width); var = var_sblk(p+8,width); if (var31) mquant = 31; Q+= mquant; mquant <<= 1; /* fprintf(statfile,"rc_calc_mquant(%d):\n",j); fprintf(statfile,"bitcount=%d, dj=%f, Qj=%f, actj=%f, N_actj=%f, mquant=%d\n", bitcount(),dj,Qj,actj,N_actj,mquant); */ return mquant; } /* compute variance of 8x8 block */ static double var_sblk(p,lx) unsigned char *p; int lx; { int i, j; unsigned int v, s, s2; s = s2 = 0; for (j=0; j<8; j++) { for (i=0; i<8; i++) { v = *p++; s+= v; s2+= v*v; } p+= lx - 8; } return s2/64.0 - (s/64.0)*(s/64.0); } void init_vbv_delay() { outbitcnt = (int)(((7*vbv_buffer_size*16384)/8)*90000.0/bit_rate) -(int)(90000.0/picture_rate+0.5); } void calc_vbv_delay() { outbitcnt += (int)(90000.0/picture_rate+0.5); vbv_delay = (int)(outbitcnt-bitcount()*90000.0/bit_rate); fprintf(statfile,"\nvbv_delay=%d\n",vbv_delay); if (vbv_delay<0) { if (!quiet) fprintf(stderr,"vbv_delay underflow: %d\n",vbv_delay); vbv_delay = 0; } if (vbv_delay>65535) { if (!quiet) fprintf(stderr,"vbv_delay overflow: %d\n",vbv_delay); vbv_delay = 65535; } } Tmin = bit_rate/(8.0*picture_rate); if (T #include #include "config.h" #include "global.h" void writeframe(fname,frame) char *fname; unsigned char *frame[]; { char name[128]; FILE *fd; if (fname[0]=='-') return; /* Y */ sprintf(name,"%s.Y",fname); if (!(fd = fopen(name,"wb"))) { sprintf(errortext,"Couldn't create %s\n",name); error(errortext); } fwrite(frame[0],1,horizontal_size*vertical_size,fd); fclose(fd); /* Cb */ sprintf(name,"%s.U",fname); if (!(fd = fopen(name,"wb"))) { sprintf(errortext,"Couldn't create %s\n",name); error(errortext); } fwrite(frame[1],1,(horizontal_size>>1)*(vertical_size>>1),fd); fclose(fd); /* Cr */ sprintf(name,"%s.V",fname); if (!(fd = fopen(name,"wb"))) { sprintf(errortext,"Couldn't create %s\n",name); error(errortext); } fwrite(frame[2],1,(horizontal_size>>1)*(vertical_size>>1),fd); fclose(fd); } near) range */ if (mquant<1) mquant = 1; if (mquant>31) mquant = 31; Q+= mquant; mquant <<= 1; /* fprintf(statfile,"rc_calc_mquant(%d):\n",j); fprintf(statfile,"bitcount=%d, dj=%f, Qj=%f, actj=%f, N_actj=%f, mquant=%d\n", bitcount(),dj,Qj,actj,N_actj,mquant); */ return mquant; } /* compute variance of 8x8 block */ static double var_sblk(p,lx) unsigned chmpeg2/src/mpeg2enc/mpeg2enc.c 640 270 132 50407 5565712765 11335 /* mpeg2enc.c, main() and parameter file reading */ /* Copyright (C) 1994, 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 #define GLOBAL /* used by global.h */ #include "config.h" #include "global.h" /* private prototypes */ static void init _ANSI_ARGS_((void)); static void readparmfile _ANSI_ARGS_((char *fname)); static void readquantmat _ANSI_ARGS_((void)); int main(argc,argv) int argc; char *argv[]; { if (argc!=3) { printf("\n%s, %s\n",version,author); printf("Usage: mpeg2encode in.par out.m2v\n"); exit(0); } /* read parameter file */ readparmfile(argv[1]); /* read quantization matrices */ readquantmat(); /* open output file */ if (!(outfile=fopen(argv[2],"wb"))) { sprintf(errortext,"Couldn't create output file %s",argv[1]); error(errortext); } init(); putseq(); fclose(outfile); fclose(statfile); return 0; } static void init() { int i; initbits(); init_fdct(); init_idct(); /* field pictures not yet implemented */ pict_struct=FRAME_PICTURE; /* Non-linear qscale not yet implemented */ q_scale_type=0; /* round picture dimensions to nearest multiple of 16 or 32 */ mb_width = (horizontal_size+15)/16; mb_height = prog_seq ? (vertical_size+15)/16 : 2*((vertical_size+31)/32); width = 16*mb_width; height = 16*mb_height; init_vbv_delay(); /* clip table */ if (!(clp = (unsigned char *)malloc(1024))) error("malloc failed\n"); clp+= 384; for (i=-384; i<640; i++) clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i); for (i=0; i<3; i++) { if (!(newrefframe[i] = (unsigned char *)malloc(width*height/(i?4:1)))) error("malloc failed\n"); if (!(oldrefframe[i] = (unsigned char *)malloc(width*height/(i?4:1)))) error("malloc failed\n"); if (!(auxframe[i] = (unsigned char *)malloc(width*height/(i?4:1)))) error("malloc failed\n"); if (!(neworgframe[i] = (unsigned char *)malloc(width*height/(i?4:1)))) error("malloc failed\n"); if (!(oldorgframe[i] = (unsigned char *)malloc(width*height/(i?4:1)))) error("malloc failed\n"); if (!(auxorgframe[i] = (unsigned char *)malloc(width*height/(i?4:1)))) error("malloc failed\n"); if (!(predframe[i] = (unsigned char *)malloc(width*height/(i?4:1)))) error("malloc failed\n"); } mbinfo = (struct mbinfo *)malloc(mb_width*mb_height*sizeof(struct mbinfo)); if (!mbinfo) error("malloc failed\n"); blocks = (short (*)[6][64])malloc(mb_width*mb_height*sizeof(short [6][64])); /* open statistics output file */ if (statname[0]=='-') statfile = stdout; else if (!(statfile = fopen(statname,"w"))) { sprintf(errortext,"Couldn't create statistics output file %s",statname); error(errortext); } } void error(text) char *text; { fprintf(stderr,text); putc('\n',stderr); exit(1); } static void readparmfile(fname) char *fname; { int i; int h,m,s,f; double sample_rate; FILE *fd; char line[256]; static double ratetab[8]= {24000.0/1001.0,24.0,25.0,30000.0/1001.0,30.0,50.0,60000.0/1001.0,60.0}; extern double r,avg_act,Xi,Xb,Xp,d0i,d0p,d0b; /* rate control */ if (!(fd = fopen(fname,"r"))) { sprintf(errortext,"Couldn't open parameter file %s",fname); error(errortext); } fgets(id_string,254,fd); fgets(line,254,fd); sscanf(line,"%s",tplorg); fgets(line,254,fd); sscanf(line,"%s",tplref); fgets(line,254,fd); sscanf(line,"%s",iqname); fgets(line,254,fd); sscanf(line,"%s",niqname); fgets(line,254,fd); sscanf(line,"%s",statname); fgets(line,254,fd); sscanf(line,"%d",&inputtype); fgets(line,254,fd); sscanf(line,"%d",&nframes); fgets(line,254,fd); sscanf(line,"%d",&frame0); fgets(line,254,fd); sscanf(line,"%d:%d:%d:%d",&h,&m,&s,&f); fgets(line,254,fd); sscanf(line,"%d",&N); fgets(line,254,fd); sscanf(line,"%d",&M); fgets(line,254,fd); sscanf(line,"%d",&mpeg1); fgets(line,254,fd); sscanf(line,"%d",&horizontal_size); fgets(line,254,fd); sscanf(line,"%d",&vertical_size); fgets(line,254,fd); sscanf(line,"%d",&aspectratio); fgets(line,254,fd); sscanf(line,"%d",&frame_rate_code); fgets(line,254,fd); sscanf(line,"%lf",&bit_rate); fgets(line,254,fd); sscanf(line,"%d",&vbv_buffer_size); fgets(line,254,fd); sscanf(line,"%d",&low_delay); fgets(line,254,fd); sscanf(line,"%d",&constrparms); fgets(line,254,fd); sscanf(line,"%d",&profile); fgets(line,254,fd); sscanf(line,"%d",&level); fgets(line,254,fd); sscanf(line,"%d",&prog_seq); fgets(line,254,fd); sscanf(line,"%d",&video_format); fgets(line,254,fd); sscanf(line,"%d",&color_primaries); fgets(line,254,fd); sscanf(line,"%d",&transfer_characteristics); fgets(line,254,fd); sscanf(line,"%d",&matrix_coefficients); fgets(line,254,fd); sscanf(line,"%d",&display_horizontal_size); fgets(line,254,fd); sscanf(line,"%d",&display_vertical_size); fgets(line,254,fd); sscanf(line,"%d",&dc_prec); fgets(line,254,fd); sscanf(line,"%d",&topfirst); fgets(line,254,fd); sscanf(line,"%d %d %d", frame_pred_dct_tab,frame_pred_dct_tab+1,frame_pred_dct_tab+2); fgets(line,254,fd); sscanf(line,"%d %d %d", conceal_tab,conceal_tab+1,conceal_tab+2); fgets(line,254,fd); sscanf(line,"%d %d %d", qscale_tab,qscale_tab+1,qscale_tab+2); fgets(line,254,fd); sscanf(line,"%d %d %d", intravlc_tab,intravlc_tab+1,intravlc_tab+2); fgets(line,254,fd); sscanf(line,"%d %d %d", altscan_tab,altscan_tab+1,altscan_tab+2); fgets(line,254,fd); sscanf(line,"%d",&repeatfirst); fgets(line,254,fd); sscanf(line,"%d",&prog_frame); /* intra slice interval refresh period */ fgets(line,254,fd); sscanf(line,"%d",&P); fgets(line,254,fd); sscanf(line,"%lf",&r); fgets(line,254,fd); sscanf(line,"%lf",&avg_act); fgets(line,254,fd); sscanf(line,"%lf",&Xi); fgets(line,254,fd); sscanf(line,"%lf",&Xp); fgets(line,254,fd); sscanf(line,"%lf",&Xb); fgets(line,254,fd); sscanf(line,"%lf",&d0i); fgets(line,254,fd); sscanf(line,"%lf",&d0p); fgets(line,254,fd); sscanf(line,"%lf",&d0b); if (N<1) error("N must be positive"); if (M<1) error("M must be positive"); if (N%M != 0) error("N must be an integer multiple of M"); motion_data = (struct motion_data *)malloc(M*sizeof(struct motion_data)); if (!motion_data) error("Couldn't allocate motion_data\n"); for (i=0; i8) error("frame_rate code must be between 1 and 8"); picture_rate = ratetab[frame_rate_code-1]; /* timecode -> frame number */ tc0 = h; tc0 = 60*tc0 + m; tc0 = 60*tc0 + s; tc0 = (int)(picture_rate+0.5)*tc0 + f; /* make flags boolean (x!=0 -> x=1) */ constrparms = !!constrparms; prog_seq = !!prog_seq; topfirst = !!topfirst; for (i=0; i<3; i++) { frame_pred_dct_tab[i] = !!frame_pred_dct_tab[i]; intravlc_tab[i] = !!intravlc_tab[i]; altscan_tab[i] = !!altscan_tab[i]; } repeatfirst = !!repeatfirst; prog_frame = !!prog_frame; /* range checks */ if ((horizontal_size&4095)==0) error("horizontal_size must not be a multiple of 4096"); if (!(horizontal_size>0 && horizontal_size<16384)) error("horizontal_size must be between 1 and 16383"); if (mpeg1 && horizontal_size>4095) error("horizontal_size must be less than 4096"); if (horizontal_size%2 != 0) error("horizontal_size must be a even (4:2:0)"); if ((vertical_size&4095)==0) error("vertical_size must not be a multiple of 4096"); if (!(vertical_size>0 && vertical_size<16384)) error("vertical_size must be between 1 and 16383"); if (mpeg1 && vertical_size>4095) error("vertical size must be less than 4096"); if (vertical_size%2 != 0) error("vertical_size must be a even (4:2:0)"); if (mpeg1) { if (aspectratio<1 || aspectratio>14) error("pel_aspect_ratio must be between 1 and 14"); } else { if (aspectratio<1 || aspectratio>4) error("aspect_ratio_information must be 1, 2, 3 or 4"); } if (bit_rate<=0.0) error("bit_rate must be positive"); if (!(vbv_buffer_size>0 && vbv_buffer_size<0x40000)) error("vbv_buffer_size must be in range 1..(2^18-1)"); if (mpeg1 && vbv_buffer_size>=1024) error("vbv_buffer_size must be less than 1024"); if (dc_prec<0 || dc_prec>3) error("intra_dc_precision must be in range 0...3"); for (i=0; i9) error("f_code must be between 1 and 9"); if (motion_data[i].forw_vert_f_code<1 || motion_data[i].forw_vert_f_code>9) error("f_code must be between 1 and 9"); if (mpeg1 && motion_data[i].forw_hor_f_code>7) error("f_code must be le less than 8"); if (mpeg1 && motion_data[i].forw_vert_f_code>7) error("f_code must be le less than 8"); if (motion_data[i].sxf<=0) error("search window must be positive"); if (motion_data[i].syf<=0) error("search window must be positive"); if (i!=0) { if (motion_data[i].back_hor_f_code<1 || motion_data[i].back_hor_f_code>9) error("f_code must be between 1 and 9"); if (motion_data[i].back_vert_f_code<1 || motion_data[i].back_vert_f_code>9) error("f_code must be between 1 and 9"); if (mpeg1 && motion_data[i].back_hor_f_code>7) error("f_code must be le less than 8"); if (mpeg1 && motion_data[i].back_vert_f_code>7) error("f_code must be le less than 8"); if (motion_data[i].sxb<=0) error("search window must be positive"); if (motion_data[i].syb<=0) error("search window must be positive"); } } if (!mpeg1) { /* profile and level checks */ if (profile<1 || profile>5) error("undefined Profile"); if (level<4 || level>10 || level&1) error("undefined Level"); if (profile<4) error("This encoder currently generates only Simple and Main profile bitstreams"); if (profile>5 || profile<1) error("Profile out of legal range"); if (profile==5 && M!=1) error("Simple profile does not allow B pictures"); /* Table 8-8 */ if (frame_rate_code>5 && level>=8) error("Picture rate greater than permitted in specified Level"); /* need to implement progressive_sequence and repeat first field check for picture rates of 25, 29.97, and 30 fps */ for (i=0; i7 && level==10) || (motion_data[i].forw_hor_f_code>8 && level==8) || (motion_data[i].forw_hor_f_code>9 && level<=6)) error("forward vertical f_code greater than permitted in specified Level"); if ((motion_data[i].forw_vert_f_code>4 && level==10) || (motion_data[i].forw_vert_f_code>4 && level<=8)) error("forward vertical f_code greater than permitted in specified Level"); if (i!=0) { if ((motion_data[i].back_hor_f_code>7 && level==10) || (motion_data[i].back_hor_f_code>8 && level==8) || (motion_data[i].back_hor_f_code>9 && level<=6)) error("backward horizontal f_code greater than permitted in specified Level"); if ((motion_data[i].back_vert_f_code>4 && level==10) || (motion_data[i].back_vert_f_code>4 && level<=8)) error("backward vertical f_code greater than permitted in specified Level"); } } /* Table 8-10 */ if (horizontal_size>1920 && level==4) error("Horizontal size is greater than High Level limit"); if (horizontal_size>1440 && level==6) error("Horizontal size is greater than High 1440 Level limit"); if (horizontal_size>720 && level==8) error("Horizontal size is greater than Main Level limit"); if (horizontal_size>352 && level==10) error("Horizontal size is greater than Low Level limit"); if (vertical_size>1152 && level==4) error("Vertical size is greater than High Level limit"); if (vertical_size>1152 && level==6) error("Vertical size is greater than High 1440 Level limit"); if (vertical_size>576 && level==8) error("Vertical size is greater than Main Level limit"); if (vertical_size>288 && level==10) error("Vertical size is greater than Low Level limit"); /* Table 8-11 */ sample_rate = horizontal_size*vertical_size*picture_rate; if (sample_rate>62668800.0 && level == 4) error("Sample rate is greater than High Level limit"); if (sample_rate>47001600.0 && level == 6) error("Sample rate is greater than High 1440 Level limit"); if (sample_rate>10368000.0 && level == 8) error("Sample rate is greater than Main Level limit"); if (sample_rate>3041280.0 && level == 10) error("Sample rate is greater than Low Level limit"); /* need to add checks for illegal combinations of levels and profiles (e.g. SP@HL) */ /* Table 8-12 */ if (bit_rate>80.0E6 && level==4) error("Bit rate exceeds High Level limit"); if (bit_rate>60.0E6 && level==6) error("Bit rate exceeds High 1440 Level limit"); if (bit_rate>15.0E6 && level==8) error("Bit rate exceeds Main Level limit"); if (bit_rate>4.0E6 && level==10) error("Bit rate exceeds Low Level limit"); /* Table 8-13 */ if ((vbv_buffer_size*16*1024)>9781248 && level==4) error("vbv_buffer_size exceeds High Level limit"); if ((vbv_buffer_size*16*1024)>7340032 && level==6) error("vbv_buffer_size exceeds High 1440 Level limit"); if ((vbv_buffer_size*16*1024)>1835008 && level==8) error("vbv_buffer_size exceeds Main Level limit"); if ((vbv_buffer_size*16*1024)>475136 && level==10) error("vbv_buffer_size exceeds Low Level limit"); } else { /* MPEG-1 */ if (constrparms) { if (horizontal_size>768 || vertical_size>576 || ((horizontal_size+15)/16)*((vertical_size+15)/16)>396 || ((horizontal_size+15)/16)*((vertical_size+15)/16)*picture_rate>396*25.0 || picture_rate>30.0) { if (!quiet) fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n"); constrparms = 0; } } if (constrparms) { for (i=0; i4) { if (!quiet) fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n"); constrparms = 0; break; } if (motion_data[i].forw_vert_f_code>4) { if (!quiet) fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n"); constrparms = 0; break; } if (i!=0) { if (motion_data[i].back_hor_f_code>4) { if (!quiet) fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n"); constrparms = 0; break; } if (motion_data[i].back_vert_f_code>4) { if (!quiet) fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n"); constrparms = 0; break; } } } } } /* relational checks */ if (mpeg1) { if (!prog_seq) { if (!quiet) fprintf(stderr,"Warning: setting progressive_sequence = 1\n"); prog_seq = 1; } if (dc_prec!=0) { if (!quiet) fprintf(stderr,"Warning: setting intra_dc_precision = 0\n"); dc_prec = 0; } for (i=0; i<3; i++) if (intravlc_tab[i]) { if (!quiet) fprintf(stderr,"Warning: setting intravlc_tab[%d] = 0\n",i); intravlc_tab[i] = 0; } for (i=0; i<3; i++) if (altscan_tab[i]) { if (!quiet) fprintf(stderr,"Warning: setting altscan_tab[%d] = 0\n",i); altscan_tab[i] = 0; } } if (!mpeg1 && constrparms) { if (!quiet) fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n"); constrparms = 0; } if (prog_seq && !prog_frame) { if (!quiet) fprintf(stderr,"Warning: setting progressive_frame = 1\n"); prog_frame = 1; } if (!prog_frame && repeatfirst) { if (!quiet) fprintf(stderr,"Warning: setting repeat_first_field = 0\n"); repeatfirst = 0; } if (prog_frame) { for (i=0; i<3; i++) if (!frame_pred_dct_tab[i]) { if (!quiet) fprintf(stderr,"Warning: setting frame_pred_frame_dct[%d] = 1\n",i); frame_pred_dct_tab[i] = 1; } } if (prog_seq && !repeatfirst && topfirst) { if (!quiet) fprintf(stderr,"Warning: setting top_field_first = 0\n"); topfirst = 0; } /* search windows */ for (i=0; i (4< (4< (4< (4<255) error("invalid value in quant matrix"); intra_q[i] = v; } fclose(fd); } if (niqname[0]=='-') { /* use default non-intra matrix */ load_niquant = 0; for (i=0; i<64; i++) inter_q[i] = 16; } else { /* read customized non-intra matrix */ load_niquant = 1; if (!(fd = fopen(niqname,"r"))) { sprintf(errortext,"Couldn't open quant matrix file %s",niqname); error(errortext); } for (i=0; i<64; i++) { fscanf(fd,"%d",&v); if (v<1 || v>255) error("invalid value in quant matrix"); inter_q[i] = v; } fclose(fd); } } || (motion_data[i].back_hor_f_code>9 && level<=6)) error("backward horizontal f_code greater than permitted in specified Level"); if ((motion_data[i].back_vert_f_code>4 && level==10) || (motion_data[i].back_vermpeg2/src/mpeg2enc/Makefile 640 270 132 4400 5564704656 11100 # Makefile for mpeg2encode # Copyright (C) 1994, 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. # # # # GNU gcc # CC = gcc CFLAGS = -O2 # # SPARCworks acc # #CC = acc #CFLAGS = -fast # # SUN cc # #CC = cc #CFLAGS = -O3 -DNON_ANSI_COMPILER OBJ = mpeg2enc.o putseq.o putpic.o puthdr.o putmpg.o putvlc.o putbits.o motion.o predict.o readpic.o writepic.o transfrm.o fdctref.o idct.o quantize.o ratectl.o stats.o all: mpeg2encode pc: mpeg2enc.exe clean: rm -f *.o *% core mpeg2encode mpeg2enc.exe: mpeg2encode coff2exe mpeg2enc mpeg2encode: $(OBJ) $(CC) $(CFLAGS) -o mpeg2encode $(OBJ) -lm fdctref.o: config.h idct.o: config.h motion.o: config.h mpeg2enc.h global.h mpeg2enc.o: config.h mpeg2enc.h global.h predict.o: config.h mpeg2enc.h global.h putbits.o: config.h puthdr.o: config.h mpeg2enc.h global.h putmpg.o: config.h mpeg2enc.h global.h putpic.o: config.h mpeg2enc.h global.h putseq.o: config.h mpeg2enc.h global.h putvlc.o: config.h mpeg2enc.h global.h vlc.h quantize.o: config.h mpeg2enc.h global.h ratectl.o: config.h mpeg2enc.h global.h readpic.o: config.h mpeg2enc.h global.h stats.o: config.h mpeg2enc.h global.h transfrm.o: config.h mpeg2enc.h global.h writepic.o: config.h mpeg2enc.h global.h oad_iquant = 0; for (i=0; i<64; i++) intra_q[i] = default_intra_quantizer_matrix[i]; } else { /* read customized intra matrix */ load_iquant = 1; if (!(fd = fopen(iqname,"r"))) { sprintf(errortext,"Couldn't open quant mpeg2/src/mpeg2dec/ 750 270 132 0 5565721042 7327 mpeg2/src/mpeg2dec/getbits.c 640 270 132 6456 5565443120 11233 /* getbits.c, bit level routines */ /* Copyright (C) 1994, 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" /* to mask the n least significant bits of an integer */ static unsigned long msk[33] = { 0x00000000,0x00000001,0x00000003,0x00000007, 0x0000000f,0x0000001f,0x0000003f,0x0000007f, 0x000000ff,0x000001ff,0x000003ff,0x000007ff, 0x00000fff,0x00001fff,0x00003fff,0x00007fff, 0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, 0x000fffff,0x001fffff,0x003fffff,0x007fffff, 0x00ffffff,0x01ffffff,0x03ffffff,0x07ffffff, 0x0fffffff,0x1fffffff,0x3fffffff,0x7fffffff, 0xffffffff }; /* initialize buffer, call once before first getbits or showbits */ void initbits() { ld->incnt = 0; ld->rdptr = ld->rdbfr + 2048; ld->bitcnt = 0; } void fillbfr() { int l; ld->inbfr[0] = ld->inbfr[8]; ld->inbfr[1] = ld->inbfr[9]; ld->inbfr[2] = ld->inbfr[10]; ld->inbfr[3] = ld->inbfr[11]; if (ld->rdptr>=ld->rdbfr+2048) { l = read(ld->infile,ld->rdbfr,2048); ld->rdptr = ld->rdbfr; if (l<2048) { if (l<0) l = 0; while (l & 3) ld->rdbfr[l++] = 0; while (l<2048) { ld->rdbfr[l++] = SEQ_END_CODE>>24; ld->rdbfr[l++] = SEQ_END_CODE>>16; ld->rdbfr[l++] = SEQ_END_CODE>>8; ld->rdbfr[l++] = SEQ_END_CODE&0xff; } } } for (l=0; l<8; l++) ld->inbfr[l+4] = ld->rdptr[l]; ld->rdptr+= 8; ld->incnt+= 64; } /* return next n bits (right adjusted) without advancing */ unsigned long showbits(n) int n; { unsigned char *v; unsigned int b; int c; if (ld->incntinbfr + ((96 - ld->incnt)>>3); b = (v[0]<<24) | (v[1]<<16) | (v[2]<<8) | v[3]; c = ((ld->incnt-1) & 7) + 25; return (b>>(c-n)) & msk[n]; } /* return next bit (could be made faster than getbits(1)) */ unsigned long getbits1() { return getbits(1); } /* advance by n bits */ void flushbits(n) int n; { ld->bitcnt+= n; ld->incnt-= n; if (ld->incnt < 0) fillbfr(); } /* return next n bits (right adjusted) */ unsigned long getbits(n) int n; { unsigned long l; l = showbits(n); flushbits(n); return l; } load_niquant = 0; for (i=0; i<64; i++) inter_q[i] = 16; } else { /* read customized non-intra matrix */ load_niquant = 1; if (!(fd = fopen(niqname,"r"))) { sprintf(errormpeg2/src/mpeg2dec/getblk.c 640 270 132 22744 5565457040 11066 /* getblk.c, DCT block decoding */ /* Copyright (C) 1994, 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 getintrablock(comp,dc_dct_pred) int comp; int dc_dct_pred[]; { int val, i, j, sign; unsigned int code; int tval; DCTtab *tab; short *bp; bp = ld->block[comp]; /* decode DC coefficients */ if (comp<4) bp[0] = (dc_dct_pred[0]+=getDClum()) << 3; else if (comp==4) bp[0] = (dc_dct_pred[1]+=getDCchrom()) << 3; else bp[0] = (dc_dct_pred[2]+=getDCchrom()) << 3; if (fault) return; /* decode AC coefficients */ for (i=1; ; i++) { code = showbits(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) fprintf(stderr,"invalid Huffman code in getintrablock()\n"); fault = 1; return; } flushbits(tab->len); if (tab->run==64) /* end_of_block */ return; if (tab->run==65) /* escape */ { i+= getbits(6); if ((tval = getbits(8))==0) val = getbits(8); else if (tval==128) val = getbits(8) - 256; else val = (char)tval; if (sign = (val<0)) val = -val; } else { i+= tab->run; val = tab->level; sign = getbits(1); } if (i>=64) { if (!quiet) fprintf(stderr,"DCT coeff index (i) out of bounds (intra)\n"); fault = 1; return; } j = zig_zag_scan[i]; val = (val*ld->quant_scale*ld->intra_quantizer_matrix[j]) >> 3; if (val!=0) /* should always be true */ val = (val-1) | 1; bp[j] = sign ? -val : val; } } /* decode one non-intra coded MPEG-1 block */ void getinterblock(comp) int comp; { int val, i, j, sign; unsigned int code; int tval; DCTtab *tab; short *bp; bp = ld->block[comp]; /* decode AC coefficients */ for (i=0; ; i++) { code = showbits(16); if (code>=16384) tab = &((i==0) ? DCTtabfirst : 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) fprintf(stderr,"invalid Huffman code in getinterblock()\n"); fault = 1; return; } flushbits(tab->len); if (tab->run==64) /* end_of_block */ return; if (tab->run==65) /* escape */ { i+= getbits(6); if ((tval = getbits(8))==0) val = getbits(8); else if (tval==128) val = getbits(8) - 256; else val = (char)tval; if (sign = (val<0)) val = -val; } else { i+= tab->run; val = tab->level; sign = getbits(1); } if (i>=64) { if (!quiet) fprintf(stderr,"DCT coeff index (i) out of bounds (inter)\n"); fault = 1; return; } j = zig_zag_scan[i]; val = (((val<<1)+1)*ld->quant_scale*ld->non_intra_quantizer_matrix[j]) >> 4; if (val!=0) /* should always be true */ val = (val-1) | 1; bp[j] = sign ? -val : val; } } /* decode one intra coded MPEG-2 block */ void getmpg2intrablock(comp,dc_dct_pred) int comp; int dc_dct_pred[]; { int val, i, j, sign, nc; unsigned int code; DCTtab *tab; short *bp; 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.pri_brk<64) ld = &enhan; else ld = &base; /* decode DC coefficients */ if (comp<4) val = (dc_dct_pred[0]+= getDClum()); else if (comp==4) val = (dc_dct_pred[1]+= getDCchrom()); else val = (dc_dct_pred[2]+= getDCchrom()); if (fault) return; bp[0] = val << (3-dcprec); nc=0; /* decode AC coefficients */ for (i=1; ; i++) { code = showbits(16); if (code>=16384 && !intravlc) tab = &DCTtabnext[(code>>12)-4]; else if (code>=1024) tab = &(intravlc ? DCTtab0a : DCTtab0)[(code>>8)-4]; else if (code>=512) tab = &(intravlc ? DCTtab1a : 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) fprintf(stderr,"invalid Huffman code in getmpg2intrablock()\n"); fault = 1; return; } flushbits(tab->len); if (tab->run==64) /* end_of_block */ return; if (tab->run==65) /* escape */ { i+= getbits(6); val = getbits(12); if ((val&2047)==0) { if (!quiet) fprintf(stderr,"invalid signed_level (escape) in getmpg2intrablock()\n"); fault = 1; return; } if (sign = (val>=2048)) val = 4096 - val; } else { i+= tab->run; val = tab->level; sign = getbits(1); } if (i>=64) { if (!quiet) fprintf(stderr,"DCT coeff index (i) out of bounds (intra2)\n"); fault = 1; return; } j = (ld1->altscan ? alternate_scan : zig_zag_scan)[i]; val = (val*ld1->quant_scale*ld1->intra_quantizer_matrix[j]) >> 4; bp[j] = sign ? -val : val; nc++; if (base.scalable_mode==SC_DP && nc==base.pri_brk-63) ld = &enhan; } } /* decode one non-intra coded MPEG-2 block */ void getmpg2interblock(comp) int comp; { int val, i, j, sign, nc; unsigned int code; DCTtab *tab; short *bp; 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.pri_brk<64) ld = &enhan; else ld = &base; nc = 0; /* decode AC coefficients */ for (i=0; ; i++) { code = showbits(16); if (code>=16384) tab = &((i==0) ? DCTtabfirst : 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) fprintf(stderr,"invalid Huffman code in getmpg2interblock()\n"); fault = 1; return; } flushbits(tab->len); if (tab->run==64) /* end_of_block */ return; if (tab->run==65) /* escape */ { i+= getbits(6); val = getbits(12); if ((val&2047)==0) { if (!quiet) fprintf(stderr,"invalid signed_level (escape) in getmpg2intrablock()\n"); fault = 1; return; } if (sign = (val>=2048)) val = 4096 - val; } else { i+= tab->run; val = tab->level; sign = getbits(1); } if (i>=64) { if (!quiet) fprintf(stderr,"DCT coeff index (i) out of bounds (inter2)\n"); fault = 1; return; } j = (ld1->altscan ? alternate_scan : zig_zag_scan)[i]; val = (((val<<1)+1)*ld1->quant_scale*ld1->non_intra_quantizer_matrix[j]) >> 5; bp[j] = sign ? -val : val; nc++; if (base.scalable_mode==SC_DP && nc==base.pri_brk-63) ld = &enhan; } } ); /* need to add checks fompeg2/src/mpeg2dec/getvlc.c 640 270 132 16113 5565633574 11103 /* getvlc.c, variable length decoding */ /* Copyright (C) 1994, 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 */ static int getIMBtype _ANSI_ARGS_((void)); static int getPMBtype _ANSI_ARGS_((void)); static int getBMBtype _ANSI_ARGS_((void)); static int getDMBtype _ANSI_ARGS_((void)); static int getspIMBtype _ANSI_ARGS_((void)); static int getspPMBtype _ANSI_ARGS_((void)); static int getspBMBtype _ANSI_ARGS_((void)); static int getSNRMBtype _ANSI_ARGS_((void)); int getMBtype() { int mb_type; if (ld->scalable_mode==SC_SNR) mb_type = getSNRMBtype(); else { switch (pict_type) { case I_TYPE: mb_type = ld->pict_scal ? getspIMBtype() : getIMBtype(); break; case P_TYPE: mb_type = ld->pict_scal ? getspPMBtype() : getPMBtype(); break; case B_TYPE: mb_type = ld->pict_scal ? getspBMBtype() : getBMBtype(); break; case D_TYPE: /* MPEG-1 only, not implemented */ mb_type = getDMBtype(); break; } } return mb_type; } static int getIMBtype() { if (getbits1()) return 1; if (!getbits1()) { if (!quiet) printf("Invalid macroblock_type code\n"); fault = 1; } return 17; } static int getPMBtype() { int code; if ((code = showbits(6))>=8) { code >>= 3; flushbits(PMBtab0[code].len); return PMBtab0[code].val; } if (code==0) { if (!quiet) printf("Invalid macroblock_type code\n"); fault = 1; return 0; } flushbits(PMBtab1[code].len); return PMBtab1[code].val; } static int getBMBtype() { int code; if ((code = showbits(6))>=8) { code >>= 2; flushbits(BMBtab0[code].len); return BMBtab0[code].val; } if (code==0) { if (!quiet) printf("Invalid macroblock_type code\n"); fault = 1; return 0; } flushbits(BMBtab1[code].len); return BMBtab1[code].val; } static int getDMBtype() { if (!getbits1()) { if (!quiet) printf("Invalid macroblock_type code\n"); fault=1; } return 1; } /* macroblock_type for pictures with spatial scalability */ static int getspIMBtype() { int code; code = showbits(4); if (code==0) { if (!quiet) printf("Invalid macroblock_type code\n"); fault = 1; return 0; } flushbits(spIMBtab[code].len); return spIMBtab[code].val; } static int getspPMBtype() { int code; code = showbits(7); if (code<2) { if (!quiet) printf("Invalid macroblock_type code\n"); fault = 1; return 0; } if (code>=16) { code >>= 3; flushbits(spPMBtab0[code].len); return spPMBtab0[code].val; } flushbits(spPMBtab1[code].len); return spPMBtab1[code].val; } static int getspBMBtype() { int code; VLCtab *p; code = showbits(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) printf("Invalid macroblock_type code\n"); fault = 1; return 0; } flushbits(p->len); return p->val; } static int getSNRMBtype() { int code; code = showbits(3); if (code==0) { if (!quiet) printf("Invalid macroblock_type code\n"); fault = 1; return 0; } flushbits(SNRMBtab[code].len); return SNRMBtab[code].val; } int getMV() { int code; if (getbits1()) return 0; if ((code = showbits(9))>=64) { code >>= 6; flushbits(MVtab0[code].len); return getbits1()?-MVtab0[code].val:MVtab0[code].val; } if (code>=24) { code >>= 3; flushbits(MVtab1[code].len); return getbits1()?-MVtab1[code].val:MVtab1[code].val; } if ((code-=12)<0) { if (!quiet) printf("Invalid motion_vector code\n"); fault=1; return 0; } flushbits(MVtab2[code].len); return getbits1() ? -MVtab2[code].val : MVtab2[code].val; } /* get differential motion vector (for dual prime prediction) */ int getDMV() { if (getbits(1)) return getbits(1) ? -1 : 1; else return 0; } int getCBP() { int code; if ((code = showbits(9))>=128) { code >>= 4; flushbits(CBPtab0[code].len); return CBPtab0[code].val; } if (code>=8) { code >>= 1; flushbits(CBPtab1[code].len); return CBPtab1[code].val; } if (code<2) { if (!quiet) printf("Invalid coded_block_pattern code\n"); fault = 1; return 0; } flushbits(CBPtab2[code].len); return CBPtab2[code].val; } int getMBA() { int code, val; val = 0; while ((code = showbits(11))<24) { if (code!=15) /* if not macroblock_stuffing */ { if (code==8) /* if macroblock_escape */ val+= 33; else { if (!quiet) printf("Invalid macroblock_address_increment code\n"); fault = 1; return 1; } } flushbits(11); } if (code>=1024) { flushbits(1); return val + 1; } if (code>=128) { code >>= 6; flushbits(MBAtab1[code].len); return val + MBAtab1[code].val; } code-= 24; flushbits(MBAtab2[code].len); return val + MBAtab2[code].val; } int getDClum() { int code, size, val; /* decode length */ code = showbits(5); if (code<31) { size = DClumtab0[code].val; flushbits(DClumtab0[code].len); } else { code = showbits(9) - 0x1f0; size = DClumtab1[code].val; flushbits(DClumtab1[code].len); } if (size==0) val = 0; else { val = getbits(size); if ((val & (1<<(size-1)))==0) val-= (1<=64) { if (!quiet) fprintf(stderr,"DCT coeff index (i) out of bounds (inter2)\n"); fault = 1; return; } j = (ld1->altscan ? alternate_scan : zig_zag_scan)[i]; val = (((val<<1)+1)*ld1->quant_scale*ld1->non_intra_quantizer_matrix[j]) >> 5; bp[j] = sign ? -val : val; nc++; if (base.scalable_mode==SC_DP && nc==base.pri_brk-63) ld = &enhan; } } ); /* need to add checks fompeg2/src/mpeg2dec/getvlc.h 640 270 132 37337 5565644370 11117 /* getvlc.h, variable length code tables */ /* Copyright (C) 1994, 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. * */ typedef struct { char val, len; } VLCtab; typedef struct { char run, level, len; } DCTtab; /* Table B-3, mb_type in P-pictures, codes 001..1xx */ static VLCtab PMBtab0[8] = { {ERROR,0}, {MB_FORWARD,3}, {MB_PATTERN,2}, {MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1} }; /* Table B-3, mb_type in P-pictures, codes 000001..00011x */ static VLCtab PMBtab1[8] = { {ERROR,0}, {MB_QUANT|MB_INTRA,6}, {MB_QUANT|MB_PATTERN,5}, {MB_QUANT|MB_PATTERN,5}, {MB_QUANT|MB_FORWARD|MB_PATTERN,5}, {MB_QUANT|MB_FORWARD|MB_PATTERN,5}, {MB_INTRA,5}, {MB_INTRA,5} }; /* Table B-4, mb_type in B-pictures, codes 0010..11xx */ static VLCtab BMBtab0[16] = { {ERROR,0}, {ERROR,0}, {MB_FORWARD,4}, {MB_FORWARD|MB_PATTERN,4}, {MB_BACKWARD,3}, {MB_BACKWARD,3}, {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3}, {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2} }; /* Table B-4, mb_type in B-pictures, codes 000001..00011x */ static VLCtab BMBtab1[8] = { {ERROR,0}, {MB_QUANT|MB_INTRA,6}, {MB_QUANT|MB_BACKWARD|MB_PATTERN,6}, {MB_QUANT|MB_FORWARD|MB_PATTERN,6}, {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5}, {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5}, {MB_INTRA,5}, {MB_INTRA,5} }; /* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */ static VLCtab spIMBtab[16] = { {ERROR,0}, {MB_CLASS4,4}, {MB_QUANT|MB_INTRA,4}, {MB_INTRA,4}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1} }; /* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */ static VLCtab spPMBtab0[16] = { {ERROR,0},{ERROR,0}, {MB_FORWARD,4}, {MB_WEIGHT|MB_FORWARD,4}, {MB_QUANT|MB_FORWARD|MB_PATTERN,3}, {MB_QUANT|MB_FORWARD|MB_PATTERN,3}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3}, {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2}, {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}, {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}, {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}, {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2} }; /* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */ static VLCtab spPMBtab1[16] = { {ERROR,0},{ERROR,0}, {MB_CLASS4|MB_QUANT|MB_PATTERN,7}, {MB_CLASS4,7}, {MB_PATTERN,7}, {MB_CLASS4|MB_PATTERN,7}, {MB_QUANT|MB_INTRA,7}, {MB_INTRA,7}, {MB_QUANT|MB_PATTERN,6}, {MB_QUANT|MB_PATTERN,6}, {MB_WEIGHT|MB_QUANT|MB_PATTERN,6}, {MB_WEIGHT|MB_QUANT|MB_PATTERN,6}, {MB_WEIGHT,6}, {MB_WEIGHT,6}, {MB_WEIGHT|MB_PATTERN,6}, {MB_WEIGHT|MB_PATTERN,6} }; /* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */ static VLCtab spBMBtab0[14] = { {MB_FORWARD,4}, {MB_FORWARD|MB_PATTERN,4}, {MB_BACKWARD,3}, {MB_BACKWARD,3}, {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3}, {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}, {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2} }; /* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */ static VLCtab spBMBtab1[12] = { {MB_QUANT|MB_FORWARD|MB_PATTERN,7}, {MB_QUANT|MB_BACKWARD|MB_PATTERN,7}, {MB_INTRA,7}, {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,7}, {MB_WEIGHT|MB_FORWARD,6}, {MB_WEIGHT|MB_FORWARD,6}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_BACKWARD,6}, {MB_WEIGHT|MB_BACKWARD,6}, {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6} }; /* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */ static VLCtab spBMBtab2[8] = { {MB_QUANT|MB_INTRA,8}, {MB_QUANT|MB_INTRA,8}, {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8}, {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8}, {MB_WEIGHT|MB_QUANT|MB_BACKWARD|MB_PATTERN,9}, {MB_CLASS4|MB_QUANT|MB_PATTERN,9}, {MB_CLASS4,9}, {MB_CLASS4|MB_PATTERN,9} }; /* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */ static VLCtab SNRMBtab[8] = { {ERROR,0}, {0,3}, {MB_QUANT|MB_PATTERN,2}, {MB_QUANT|MB_PATTERN,2}, {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1} }; /* Table B-10, motion_code, codes 0001 ... 01xx */ static VLCtab MVtab0[8] = { {ERROR,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1} }; /* Table B-10, motion_code, codes 0000011 ... 000011x */ static VLCtab MVtab1[8] = { {ERROR,0}, {ERROR,0}, {ERROR,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5} }; /* Table B-10, motion_code, codes 0000001100 ... 000001011x */ static VLCtab MVtab2[12] = { {16,9}, {15,9}, {14,9}, {13,9}, {12,9}, {11,9}, {10,8}, {10,8}, {9,8}, {9,8}, {8,8}, {8,8} }; /* Table B-9, coded_block_pattern, codes 01000 ... 111xx */ static VLCtab CBPtab0[32] = { {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, {62,5}, {2,5}, {61,5}, {1,5}, {56,5}, {52,5}, {44,5}, {28,5}, {40,5}, {20,5}, {48,5}, {12,5}, {32,4}, {32,4}, {16,4}, {16,4}, {8,4}, {8,4}, {4,4}, {4,4}, {60,3}, {60,3}, {60,3}, {60,3} }; /* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */ static VLCtab CBPtab1[64] = { {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, {58,8}, {54,8}, {46,8}, {30,8}, {57,8}, {53,8}, {45,8}, {29,8}, {38,8}, {26,8}, {37,8}, {25,8}, {43,8}, {23,8}, {51,8}, {15,8}, {42,8}, {22,8}, {50,8}, {14,8}, {41,8}, {21,8}, {49,8}, {13,8}, {35,8}, {19,8}, {11,8}, {7,8}, {34,7}, {34,7}, {18,7}, {18,7}, {10,7}, {10,7}, {6,7}, {6,7}, {33,7}, {33,7}, {17,7}, {17,7}, {9,7}, {9,7}, {5,7}, {5,7}, {63,6}, {63,6}, {63,6}, {63,6}, {3,6}, {3,6}, {3,6}, {3,6}, {36,6}, {36,6}, {36,6}, {36,6}, {24,6}, {24,6}, {24,6}, {24,6} }; /* Table B-9, coded_block_pattern, codes 000000010 ... 000000111 */ static VLCtab CBPtab2[8] = { {ERROR,0}, {ERROR,0}, {39,9}, {27,9}, {59,9}, {55,9}, {47,9}, {31,9} }; /* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */ static VLCtab MBAtab1[16] = { {ERROR,0}, {ERROR,0}, {7,5}, {6,5}, {5,4}, {5,4}, {4,4}, {4,4}, {3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3} }; /* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */ static VLCtab MBAtab2[104] = { {33,11}, {32,11}, {31,11}, {30,11}, {29,11}, {28,11}, {27,11}, {26,11}, {25,11}, {24,11}, {23,11}, {22,11}, {21,10}, {21,10}, {20,10}, {20,10}, {19,10}, {19,10}, {18,10}, {18,10}, {17,10}, {17,10}, {16,10}, {16,10}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7} }; /* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */ static VLCtab DClumtab0[32] = { {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {ERROR, 0} }; /* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */ static VLCtab DClumtab1[16] = { {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9} }; /* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */ static VLCtab DCchromtab0[32] = { {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {ERROR, 0} }; /* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */ static VLCtab DCchromtab1[32] = { {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10} }; /* Table B-14, DCT coefficients table zero, * codes 0100 ... 1xxx (used for first (DC) coefficient) */ DCTtab DCTtabfirst[12] = { {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1} }; /* Table B-14, DCT coefficients table zero, * codes 0100 ... 1xxx (used for all other coefficients) */ DCTtab DCTtabnext[12] = { {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, {64,0,2}, {64,0,2}, {64,0,2}, {64,0,2}, /* EOB */ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2} }; /* Table B-14, DCT coefficients table zero, * codes 000001xx ... 00111xxx */ DCTtab DCTtab0[60] = { {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ {2,2,7}, {2,2,7}, {9,1,7}, {9,1,7}, {0,4,7}, {0,4,7}, {8,1,7}, {8,1,7}, {7,1,6}, {7,1,6}, {7,1,6}, {7,1,6}, {6,1,6}, {6,1,6}, {6,1,6}, {6,1,6}, {1,2,6}, {1,2,6}, {1,2,6}, {1,2,6}, {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, {13,1,8}, {0,6,8}, {12,1,8}, {11,1,8}, {3,2,8}, {1,3,8}, {0,5,8}, {10,1,8}, {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5} }; /* Table B-15, DCT coefficients table one, * codes 000001xx ... 11111111 */ DCTtab DCTtab0a[252] = { {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ {7,1,7}, {7,1,7}, {8,1,7}, {8,1,7}, {6,1,7}, {6,1,7}, {2,2,7}, {2,2,7}, {0,7,6}, {0,7,6}, {0,7,6}, {0,7,6}, {0,6,6}, {0,6,6}, {0,6,6}, {0,6,6}, {4,1,6}, {4,1,6}, {4,1,6}, {4,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, {1,5,8}, {11,1,8}, {0,11,8}, {0,10,8}, {13,1,8}, {12,1,8}, {3,2,8}, {1,4,8}, {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */ {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, {9,1,7}, {9,1,7}, {1,3,7}, {1,3,7}, {10,1,7}, {10,1,7}, {0,8,7}, {0,8,7}, {0,9,7}, {0,9,7}, {0,12,8}, {0,13,8}, {2,3,8}, {4,2,8}, {0,14,8}, {0,15,8} }; /* Table B-14, DCT coefficients table zero, * codes 0000001000 ... 0000001111 */ DCTtab DCTtab1[8] = { {16,1,10}, {5,2,10}, {0,7,10}, {2,3,10}, {1,4,10}, {15,1,10}, {14,1,10}, {4,2,10} }; /* Table B-15, DCT coefficients table one, * codes 000000100x ... 000000111x */ DCTtab DCTtab1a[8] = { {5,2,9}, {5,2,9}, {14,1,9}, {14,1,9}, {2,4,10}, {16,1,10}, {15,1,9}, {15,1,9} }; /* Table B-14/15, DCT coefficients table zero / one, * codes 000000010000 ... 000000011111 */ DCTtab DCTtab2[16] = { {0,11,12}, {8,2,12}, {4,3,12}, {0,10,12}, {2,4,12}, {7,2,12}, {21,1,12}, {20,1,12}, {0,9,12}, {19,1,12}, {18,1,12}, {1,5,12}, {3,3,12}, {0,8,12}, {6,2,12}, {17,1,12} }; /* Table B-14/15, DCT coefficients table zero / one, * codes 0000000010000 ... 0000000011111 */ DCTtab DCTtab3[16] = { {10,2,13}, {9,2,13}, {5,3,13}, {3,4,13}, {2,5,13}, {1,7,13}, {1,6,13}, {0,15,13}, {0,14,13}, {0,13,13}, {0,12,13}, {26,1,13}, {25,1,13}, {24,1,13}, {23,1,13}, {22,1,13} }; /* Table B-14/15, DCT coefficients table zero / one, * codes 00000000010000 ... 00000000011111 */ DCTtab DCTtab4[16] = { {0,31,14}, {0,30,14}, {0,29,14}, {0,28,14}, {0,27,14}, {0,26,14}, {0,25,14}, {0,24,14}, {0,23,14}, {0,22,14}, {0,21,14}, {0,20,14}, {0,19,14}, {0,18,14}, {0,17,14}, {0,16,14} }; /* Table B-14/15, DCT coefficients table zero / one, * codes 000000000010000 ... 000000000011111 */ DCTtab DCTtab5[16] = { {0,40,15}, {0,39,15}, {0,38,15}, {0,37,15}, {0,36,15}, {0,35,15}, {0,34,15}, {0,33,15}, {0,32,15}, {1,14,15}, {1,13,15}, {1,12,15}, {1,11,15}, {1,10,15}, {1,9,15}, {1,8,15} }; /* Table B-14/15, DCT coefficients table zero / one, * codes 0000000000010000 ... 0000000000011111 */ DCTtab DCTtab6[16] = { {1,18,16}, {1,17,16}, {1,16,16}, {1,15,16}, {6,3,16}, {16,2,16}, {15,2,16}, {14,2,16}, {13,2,16}, {12,2,16}, {11,2,16}, {31,1,16}, {30,1,16}, {29,1,16}, {28,1,16}, {27,1,16} }; ,5}, {6,5}, {5,4}, {5,4}, {4,4}, {4,4}, {3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3} }; /* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */ static VLCtab MBAtab2[104] = { {33,11}, {32,11}, {31,11}, {30,11}, {29,11}, {28,11}, {27,11}, {26,11}, mpeg2/src/mpeg2dec/getpic.c 640 270 132 44531 5565632357 11075 /* getpict.c, picture decoding */ /* Copyright (C) 1994, 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 getMBs _ANSI_ARGS_((void)); static void macroblock_modes _ANSI_ARGS_((int *pmb_type, int *pstwtype, int *pstwclass, int *pmotion_type, int *pmv_count, int *pmv_format, int *pdmv, int *pmvscale, int *pdct_type)); static void clearblock _ANSI_ARGS_((int comp)); static void sumblock _ANSI_ARGS_((int comp)); static void saturate _ANSI_ARGS_((short *bp)); static void addblock _ANSI_ARGS_((int comp, int bx, int by, int dct_type, int addflag)); /* private data */ static int framenum; /* decode one frame or field picture */ void getpicture() { int i; unsigned char *tmp; if (pict_struct==FRAME_PICTURE && secondfield) { printf("odd number of field pictures\n"); secondfield = 0; } for (i=0; i<3; i++) { if (pict_type==B_TYPE) { newframe[i] = auxframe[i]; } else { if (!secondfield) { tmp = oldrefframe[i]; oldrefframe[i] = refframe[i]; refframe[i] = tmp; } newframe[i] = refframe[i]; } if (pict_struct==BOTTOM_FIELD) newframe[i]+= (i==0) ? coded_picture_width : (coded_picture_width>>1); } if (base.pict_scal && !secondfield) getspatref(); getMBs(); if (pict_struct==FRAME_PICTURE || secondfield) { if (framenum!=0) { if (pict_type==B_TYPE) storeframe(auxframe,framenum-1); else storeframe(oldrefframe,framenum-1); } framenum++; } if (pict_struct!=FRAME_PICTURE) secondfield = !secondfield; } /* store last frame */ void putlast() { if (secondfield) printf("last frame incomplete, not stored\n"); else storeframe(refframe,framenum-1); } /* decode all macroblocks of the current picture */ static void getMBs() { int comp; int MBA, MBAmax, MBAinc, mb_type, cbp, motion_type, dct_type; int slice_vert_pos_ext; int bx, by; unsigned long code; int dc_dct_pred[3]; int mv_count, mv_format, mvscale; int PMV[2][2][2], mv_field_sel[2][2]; int dmv, dmvector[2]; int qs; int stwtype, stwclass; int SNRMBA, SNRMBAinc, SNRmb_type, SNRcbp, SNRdct_type, dummy; /* SNR scal. */ /* number of macroblocks per picture */ MBAmax = mb_width*mb_height; if (pict_struct!=FRAME_PICTURE) MBAmax>>=1; /* field picture */ MBA = 0; /* macroblock address */ MBAinc = 0; if (twostreams && enhan.scalable_mode==SC_SNR) { SNRMBA=0; SNRMBAinc=0; } fault=0; for (;;) { ld = &base; if (MBAinc==0) { if (base.scalable_mode==SC_DP && base.pri_brk==1) ld = &enhan; if (!showbits(23) || fault) /* startcode or fault */ { resync: /* if fault: resynchronize to next startcode */ fault = 0; ld = &base; if (MBA>=MBAmax) return; /* all macroblocks decoded */ startcode(); code = showbits(32); if (codeSLICE_MAX_START) { /* only slice headers are allowed in picture_data */ if (!quiet) printf("Premature end of picture\n"); return; } flushbits(32); /* decode slice header (may change quant_scale) */ slice_vert_pos_ext = getslicehdr(); if (base.scalable_mode==SC_DP) { ld = &enhan; startcode(); code = showbits(32); if (codeSLICE_MAX_START) { /* only slice headers are allowed in picture_data */ if (!quiet) printf("Premature end of picture\n"); return; } flushbits(32); /* decode slice header (may change quant_scale) */ slice_vert_pos_ext = getslicehdr(); if (base.pri_brk!=1) ld = &base; } /* decode macroblock address increment */ MBAinc = getMBA(); if (fault) goto resync; /* set current location */ 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 */ dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; 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; } else /* neither startcode nor fault */ { if (MBA>=MBAmax) { if (!quiet) printf("Too many macroblocks in picture\n"); return; } if (base.scalable_mode==SC_DP && base.pri_brk==1) ld = &enhan; /* decode macroblock address increment */ MBAinc = getMBA(); if (fault) goto resync; } } if (MBA>=MBAmax) { /* MBAinc points beyond picture dimensions */ if (!quiet) printf("Too many macroblocks in picture\n"); return; } if (MBAinc==1) /* not skipped */ { if (base.scalable_mode==SC_DP) { if (base.pri_brk<=2) ld = &enhan; else ld = &base; } macroblock_modes(&mb_type, &stwtype, &stwclass, &motion_type, &mv_count, &mv_format, &dmv, &mvscale, &dct_type); if (fault) goto resync; if (mb_type & MB_QUANT) { qs = getbits(5); if (ld->mpeg2) ld->quant_scale = ld->qscale_type ? non_linear_mquant_table[qs] : (qs << 1); else ld->quant_scale = qs; if (base.scalable_mode==SC_DP) /* make sure base.quant_scale is valid */ base.quant_scale = ld->quant_scale; } /* motion vectors */ /* decode forward motion vectors */ if ((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && conceal_mv)) { if (ld->mpeg2) motion_vectors(PMV,dmvector,mv_field_sel, 0,mv_count,mv_format,h_forw_r_size,v_forw_r_size,dmv,mvscale); else motion_vector(PMV[0][0],dmvector, forw_r_size,forw_r_size,0,0,full_forw); } if (fault) goto resync; /* decode backward motion vectors */ if (mb_type & MB_BACKWARD) { if (ld->mpeg2) motion_vectors(PMV,dmvector,mv_field_sel, 1,mv_count,mv_format,h_back_r_size,v_back_r_size,0,mvscale); else motion_vector(PMV[0][1],dmvector, back_r_size,back_r_size,0,0,full_back); } if (fault) goto resync; if ((mb_type & MB_INTRA) && conceal_mv) flushbits(1); /* remove marker_bit */ if (base.scalable_mode==SC_DP && base.pri_brk==3) ld = &enhan; /* macroblock_pattern */ if (mb_type & MB_PATTERN) cbp = getCBP(); else cbp = (mb_type & MB_INTRA) ? 63 : 0; if (fault) goto resync; /* decode blocks */ for (comp=0; comp<6; comp++) { if (base.scalable_mode==SC_DP) ld = &base; clearblock(comp); if (cbp & (32>>comp)) { if (mb_type & MB_INTRA) { if (ld->mpeg2) getmpg2intrablock(comp,dc_dct_pred); else getintrablock(comp,dc_dct_pred); } else { if (ld->mpeg2) getmpg2interblock(comp); else getinterblock(comp); } if (fault) goto resync; } } /* reset intra_dc predictors */ if (!(mb_type & MB_INTRA)) dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; /* reset motion vector predictors */ if ((mb_type & MB_INTRA) && !conceal_mv) { /* intra mb without concealment motion vectors */ 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; } if ((pict_type==P_TYPE) && !(mb_type & (MB_FORWARD|MB_INTRA))) { /* non-intra mb without forward mv in a P picture */ PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; /* derive motion_type */ if (pict_struct==FRAME_PICTURE) motion_type = MC_FRAME; else { motion_type = MC_FIELD; /* predict from field of same parity */ mv_field_sel[0][0] = (pict_struct==BOTTOM_FIELD); } } if (stwclass==4) { /* purely spatially predicted macroblock */ 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; } } else /* MBAinc!=1: skipped macroblock */ { if (base.scalable_mode==SC_DP) ld = &base; for (comp=0; comp<6; comp++) clearblock(comp); /* reset intra_dc predictors */ dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; /* reset motion vector predictors */ if (pict_type==P_TYPE) PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; /* derive motion_type */ if (pict_struct==FRAME_PICTURE) motion_type = MC_FRAME; else { motion_type = MC_FIELD; /* predict from field of same parity */ mv_field_sel[0][0]=mv_field_sel[0][1] = (pict_struct==BOTTOM_FIELD); } /* skipped I are spatial-only predicted, */ /* skipped P and B are temporal-only predicted */ stwtype = (pict_type==I_TYPE) ? 8 : 0; /* clear MB_INTRA */ mb_type&= ~MB_INTRA; } if (twostreams && enhan.scalable_mode==SC_SNR) { ld = &enhan; if (SNRMBAinc==0) { if (!showbits(23)) /* startcode */ { startcode(); code = showbits(32); if (codeSLICE_MAX_START) { /* only slice headers are allowed in picture_data */ if (!quiet) printf("Premature end of picture\n"); return; } flushbits(32); /* decode slice header (may change quant_scale) */ slice_vert_pos_ext = getslicehdr(); /* decode macroblock address increment */ SNRMBAinc = getMBA(); /* 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 startcode */ { if (SNRMBA>=MBAmax) { if (!quiet) printf("Too many macroblocks in picture\n"); return; } /* decode macroblock address increment */ SNRMBAinc = getMBA(); } } if (SNRMBA!=MBA) { /* streams out of sync */ if (!quiet) printf("Cant't synchronize streams\n"); return; } if (SNRMBAinc==1) /* not skipped */ { macroblock_modes(&SNRmb_type, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &SNRdct_type); if (SNRmb_type & MB_PATTERN) dct_type = SNRdct_type; if (SNRmb_type & MB_QUANT) { qs = getbits(5); ld->quant_scale = ld->qscale_type ? non_linear_mquant_table[qs] : qs<<1; } /* macroblock_pattern */ if (SNRmb_type & MB_PATTERN) SNRcbp = getCBP(); else SNRcbp = 0; /* decode blocks */ for (comp=0; comp<6; comp++) { clearblock(comp); if (SNRcbp & (32>>comp)) getmpg2interblock(comp); } } else /* SNRMBAinc!=1: skipped macroblock */ { for (comp=0; comp<6; comp++) clearblock(comp); } ld = &base; } /* pixel coordinates of top left corner of current macroblock */ bx = 16*(MBA%mb_width); by = 16*(MBA/mb_width); /* motion compensation */ if (!(mb_type & MB_INTRA)) reconstruct(bx,by,mb_type,motion_type,PMV,mv_field_sel,dmvector, stwtype); if (base.scalable_mode==SC_DP) ld = &base; /* copy or add block data into picture */ for (comp=0; comp<6; comp++) { if (twostreams && enhan.scalable_mode==SC_SNR) sumblock(comp); /* add SNR enhancement layer data to base layer */ /* MPEG-2 saturation and mismatch control */ if ((twostreams && enhan.scalable_mode==SC_SNR) || ld->mpeg2) saturate(ld->block[comp]); /* inverse DCT */ if (refidct) idctref(ld->block[comp]); else idct(ld->block[comp]); addblock(comp,bx,by,dct_type,(mb_type & MB_INTRA)==0); } /* advance to next macroblock */ MBA++; MBAinc--; if (twostreams && enhan.scalable_mode==SC_SNR) { SNRMBA++; SNRMBAinc--; } } } static void macroblock_modes(pmb_type,pstwtype,pstwclass, pmotion_type,pmv_count,pmv_format,pdmv,pmvscale,pdct_type) int *pmb_type, *pstwtype, *pstwclass; int *pmotion_type, *pmv_count, *pmv_format, *pdmv, *pmvscale; int *pdct_type; { int mb_type; int stwtype, stwcode, stwclass; int motion_type, mv_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 */ mb_type = getMBtype(); if (fault) return; /* get spatial_temporal_weight_code */ if (mb_type & MB_WEIGHT) { if (stwc_table_index==0) stwtype = 4; else { stwcode = getbits(2); stwtype = stwc_table[stwc_table_index-1][stwcode]; } } else stwtype = (mb_type & MB_CLASS4) ? 8 : 0; /* derive spatial_temporal_weight_class (Table 7-18) */ stwclass = stwclass_table[stwtype]; /* get frame/field motion type */ if (mb_type & (MB_FORWARD|MB_BACKWARD)) { if (pict_struct==FRAME_PICTURE) /* frame_motion_type */ motion_type = frame_pred_dct ? MC_FRAME : getbits(2); else /* field_motion_type */ motion_type = getbits(2); } else if ((mb_type & MB_INTRA) && conceal_mv) { /* concealment motion vectors */ motion_type = (pict_struct==FRAME_PICTURE) ? MC_FRAME : MC_FIELD; } /* derive mv_count, mv_format and dmv, (table 6-17, 6-18) */ if (pict_struct==FRAME_PICTURE) { mv_count = (motion_type==MC_FIELD && stwclass<2) ? 2 : 1; mv_format = (motion_type==MC_FRAME) ? MV_FRAME : MV_FIELD; } else { mv_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 */ mvscale = ((mv_format==MV_FIELD) && (pict_struct==FRAME_PICTURE)); /* get dct_type (frame DCT / field DCT) */ dct_type = (pict_struct==FRAME_PICTURE) && (!frame_pred_dct) && (mb_type & (MB_PATTERN|MB_INTRA)) ? getbits(1) : 0; /* return values */ *pmb_type = mb_type; *pstwtype = stwtype; *pstwclass = stwclass; *pmotion_type = motion_type; *pmv_count = mv_count; *pmv_format = mv_format; *pdmv = dmv; *pmvscale = mvscale; *pdct_type = dct_type; } /* set block to zero */ static void clearblock(comp) int comp; { short *bp; int i; bp = ld->block[comp]; for (i=0; i<64; i++) *bp++ = 0; } /* add SNR enhancement layer block data to base layer */ static void sumblock(comp) int comp; { short *bp1, *bp2; int i; bp1 = base.block[comp]; bp2 = enhan.block[comp]; for (i=0; i<64; i++) *bp1++ += *bp2++; } /* limit coefficients to -2048..2047 */ static void saturate(bp) short *bp; { int i, sum, val; sum = 0; /* saturation */ for (i=0; i<64; i++) { val = bp[i]; if (val>2047) val = 2047; else if (val<-2048) val = -2048; bp[i] = val; sum+= val; } /* mismatch control */ if ((sum&1)==0) bp[63]^= 1; } /* move/add 8x8-Block from block[comp] to refframe */ static void addblock(comp,bx,by,dct_type,addflag) int comp, bx, by, dct_type, addflag; { int i, j, iincr; unsigned char *rfp; short *bp; if (comp<4) { if (pict_struct==FRAME_PICTURE) if (dct_type) { /* field DCT coding */ rfp = newframe[0] + coded_picture_width*(by+((comp&2)>>1)) + bx + ((comp&1)<<3); iincr = (coded_picture_width<<1) - 8; } else { /* frame DCT coding */ rfp = newframe[0] + coded_picture_width*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); iincr = coded_picture_width - 8; } else { /* field picture */ rfp = newframe[0] + (coded_picture_width<<1)*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); iincr = (coded_picture_width<<1) - 8; } } else { if (pict_struct==FRAME_PICTURE) { rfp = newframe[comp-3] + (coded_picture_width>>2)*by + (bx>>1); iincr = (coded_picture_width>>1) - 8; } else { /* field picture */ rfp = newframe[comp-3] + (coded_picture_width>>1)*by + (bx>>1); iincr = coded_picture_width - 8; } } bp = ld->block[comp]; if (addflag) { for (i=0; i<8; i++) { for (j=0; j<8; j++) { *rfp = clp[*bp++ + *rfp]; rfp++; } rfp+= iincr; } } else { for (i=0; i<8; i++) { for (j=0; j<8; j++) *rfp++ = clp[*bp++ + 128]; rfp+= iincr; } } } /* skipped I are spatial-only predicted, */ /* skipped P and B are temporal-only predicted */ stwtype = (pict_type==I_TYPE) ? 8 : 0; /* clear MB_INmpeg2/src/mpeg2dec/idct.c 640 270 132 13240 5565420602 10522 /* idct.c, inverse fast discrete cosine transform */ /* Copyright (C) 1994, 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 5681 /* 4096*sqrt(2)*cos(1*pi/16) */ #define W2 5352 /* 4096*sqrt(2)*cos(2*pi/16) */ #define W3 4816 /* 4096*sqrt(2)*cos(3*pi/16) */ #define W5 3218 /* 4096*sqrt(2)*cos(5*pi/16) */ #define W6 2217 /* 4096*sqrt(2)*cos(6*pi/16) */ #define W7 1130 /* 4096*sqrt(2)*cos(7*pi/16) */ /* global declarations */ void init_idct _ANSI_ARGS_((void)); void idct _ANSI_ARGS_((short *block)); /* private data */ static long temp[64]; /* intermediate storage for 1D transform */ static short iclip[1024]; /* clipping table */ static short *iclp; /* private prototypes */ static void idctrow _ANSI_ARGS_((short *src, long *dst)); static void idctcol _ANSI_ARGS_((long *src, short *dst)); /* row (horizontal) IDCT * * 7 pi 1 * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l ) * l=0 8 2 * * where: c[0] = 256*sqrt(0.5) * c[1..7] = 256 */ static void idctrow(src,dst) short *src; long *dst; { long x0, x1, x2, x3, x4, x5, x6, x7, x8; /* shortcut */ if (!src[0] && !src[1] && !src[2] && !src[3] && !src[4] && !src[5] && !src[6] && !src[7]) { dst[0]=dst[1]=dst[2]=dst[3]=dst[4]=dst[5]=dst[6]=dst[7]=0; return; } /* first stage */ x0 = src[0]; x1 = src[4]; x2 = src[6]; x3 = src[2]; x4 = src[1]; x5 = src[7]; x6 = src[5]; x7 = src[3]; 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)<<12) + 16; /* +16 for proper rounding in the fourth stage */ x0 = ((x0-x1)<<12) + 16; 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 */ dst[0] = (x7+x1)>>5; dst[1] = (x3+x2)>>5; dst[2] = (x0+x4)>>5; dst[3] = (x8+x6)>>5; dst[4] = (x8-x6)>>5; dst[5] = (x0-x4)>>5; dst[6] = (x3-x2)>>5; dst[7] = (x7-x1)>>5; } /* 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*sqrt(0.5) * c[1..7] = 1/1024 */ static void idctcol(src,dst) long *src; short *dst; { long x0, x1, x2, x3, x4, x5, x6, x7, x8; /* first stage */ x0 = src[8*0]; x1 = src[8*4]; x2 = src[8*6]; x3 = src[8*2]; x4 = src[8*1]; x5 = src[8*7]; x6 = src[8*5]; x7 = src[8*3]; x8 = W7*(x4+x5) + 2048; x4 = (x8+(W1-W7)*x4)>>12; x5 = (x8-(W1+W7)*x5)>>12; x8 = W3*(x6+x7) + 2048; x6 = (x8-(W3-W5)*x6)>>12; x7 = (x8-(W3+W5)*x7)>>12; /* second stage */ x8 = x0 + x1; x0 -= x1; x1 = W6*(x3+x2) + 2048; x2 = (x1-(W2+W6)*x2)>>12; x3 = (x1+(W2-W6)*x3)>>12; x1 = x4 + x6; x4 -= x6; x6 = x5 + x7; x5 -= x7; /* third stage */ x7 = x8 + x3 + 512; x8 += -x3 + 512; x3 = x0 + x2 + 512; x0 += -x2 + 512; x2 = (181*(x4+x5)+128)>>8; x4 = (181*(x4-x5)+128)>>8; /* fourth stage */ dst[8*0] = iclp[(x7+x1)>>10]; dst[8*1] = iclp[(x3+x2)>>10]; dst[8*2] = iclp[(x0+x4)>>10]; dst[8*3] = iclp[(x8+x6)>>10]; dst[8*4] = iclp[(x8-x6)>>10]; dst[8*5] = iclp[(x0-x4)>>10]; dst[8*6] = iclp[(x3-x2)>>10]; dst[8*7] = iclp[(x7-x1)>>10]; } /* two dimensional inverse discrete cosine transform */ void idct(block) short *block; { int i; for (i=0; i<8; i++) idctrow(block+8*i, temp+8*i); for (i=0; i<8; i++) idctcol(temp+i, block+i); } void init_idct() { int i; iclp = iclip+512; for (i= -512; i<512; i++) iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i); } PICTURE)); /* get dct_type (frame DCT / field DCT) */ dct_type = (pict_struct==FRAME_PICTURE) && (!frame_pred_dct) && (mb_type & (MB_PATTERN|MB_INTRA)) ? getbits(1) : 0; /* return values */ *pmb_type = mb_type; *pstwtype = stwtype; *pstwclass = stwclass; *pmotion_type = motion_type; mpeg2/src/mpeg2dec/motion.c 640 270 132 11517 5565635265 11126 /* motion.c, motion vector decoding */ /* Copyright (C) 1994, 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 calcMV _ANSI_ARGS_((int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector)); void motion_vectors(PMV,dmvector, mv_field_sel,s,mv_count,mv_format,h_r_size,v_r_size,dmv,mvscale) int PMV[2][2][2]; int dmvector[2]; int mv_field_sel[2][2]; int s, mv_count, mv_format, h_r_size, v_r_size, dmv, mvscale; { if (mv_count==1) { if (mv_format==MV_FIELD && !dmv) mv_field_sel[1][s] = mv_field_sel[0][s] = getbits(1); 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 { mv_field_sel[0][s] = getbits(1); motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); mv_field_sel[1][s] = getbits(1); motion_vector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); } } /* get and decode motion vector and differential motion vector */ 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_r; motion_code = getMV(); motion_r = (h_r_size!=0 && motion_code!=0) ? getbits(h_r_size) : 0; calcMV(&PMV[0],h_r_size,motion_code,motion_r,full_pel_vector); if (dmv) dmvector[0] = getDMV(); motion_code = getMV(); motion_r = (v_r_size!=0 && motion_code!=0) ? getbits(v_r_size) : 0; if (mvscale) PMV[1] >>= 1; /* DIV 2 */ calcMV(&PMV[1],v_r_size,motion_code,motion_r,full_pel_vector); if (mvscale) PMV[1] <<= 1; if (dmv) dmvector[1] = getDMV(); } /* calculate motion vector component */ static void calcMV(pred,r_size,motion_code,motion_r,full_pel_vector) int *pred; int r_size, motion_code, motion_r, full_pel_vector; { 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 (pict_struct==TOP_FIELD) DMV[0][1]--; else DMV[0][1]++; } } ong *src; short *dst; { long x0, x1, x2, x3, x4, x5, x6, x7, x8; /* first stage */ x0 = src[8*0]; x1 = src[8*4]; x2 = src[8*6]; x3 = src[8*2]; x4 = src[8*1]; x5mpeg2/src/mpeg2dec/mpeg2dec.c 640 270 132 13141 5565712731 11274 /* mpeg2dec.c, main(), initialization, option processing */ /* Copyright (C) 1994, 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 void initdecoder _ANSI_ARGS_((void)); static void options _ANSI_ARGS_((int *argcp, char **argvp[])); static int getval _ANSI_ARGS_((char *argv[])); int main(argc,argv) int argc; char *argv[]; { int first, picture; options(&argc,&argv); /* pointer to name of output files */ outputname = argv[argc-1]; ld = &base; /* select base layer context */ /* open MPEG input file(s) */ if ((base.infile=open(argv[1],O_RDONLY|O_BINARY))<0) { sprintf(errortext,"Input file %s not found\n",argv[1]); error(errortext); } initbits(); if (argc==4) { ld = &enhan; /* select enhancement layer context */ if ((enhan.infile = open(argv[2],O_RDONLY|O_BINARY))<0) { sprintf(errortext,"Input file %s not found\n",argv[2]); error(errortext); } twostreams = 1; initbits(); ld = &base; } first = 1; picture = 0; while (getheader()) { if (first) { initdecoder(); first = 0; } getpicture(); picture++; } if (!first) { /* put last frame */ putlast(); } close(base.infile); if (twostreams) close(enhan.infile); return 0; } static void initdecoder() { int i, size; /* check scalability mode of enhancement layer */ if (twostreams && enhan.scalable_mode!=SC_SNR && !(base.scalable_mode==SC_DP && base.scalable_mode==SC_DP)) error("unsupported scalability mode\n"); /* clip table */ if (!(clp=(unsigned char *)malloc(1024))) error("malloc failed\n"); clp += 384; for (i=-384; i<640; i++) clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i); mb_width = (horizontal_size+15)/16; mb_height = (base.mpeg2 && !prog_seq) ? 2*((vertical_size+31)/32) : (vertical_size+15)/16; coded_picture_width = 16*mb_width; coded_picture_height = 16*mb_height; if (!base.mpeg2) { prog_seq = 1; prog_frame = 1; pict_struct = FRAME_PICTURE; frame_pred_dct = 1; matrix_coefficients = 5; } for (i=0; i<3; i++) { size = coded_picture_width*coded_picture_height/(i?4:1); if (!(refframe[i] = (unsigned char *)malloc(size))) error("malloc failed\n"); if (!(oldrefframe[i] = (unsigned char *)malloc(size))) error("malloc failed\n"); if (!(auxframe[i] = (unsigned char *)malloc(size))) error("malloc failed\n"); if (base.scalable_mode==SC_SPAT) { if (!(llframe0[i] = (unsigned char *)malloc((llw*llh)/(i?4:1)))) error("malloc failed\n"); if (!(llframe1[i] = (unsigned char *)malloc((llw*llh)/(i?4:1)))) error("malloc failed\n"); } } if (base.scalable_mode==SC_SPAT) { if (!(lltmp = (short *)malloc(llw*((llh*vn)/vm)*sizeof(short)))) error("malloc failed\n"); } /* IDCT */ if (refidct) init_idctref(); else init_idct(); } void error(text) char *text; { fprintf(stderr,text); exit(1); } /* option processing */ static void options(argcp,argvp) int *argcp; char **argvp[]; { while (*argcp>1 && (*argvp)[1][0]=='-') { while ((*argvp)[1][1]) { switch (toupper((*argvp)[1][1])) { case 'V': verbose = getval(*argvp); break; case 'O': outtype = getval(*argvp); break; case 'F': framestoreflag = 1; break; case 'S': sflag = 1; break; case 'R': refidct = 1; break; default: fprintf(stderr,"undefined option -%c ignored\n",(*argvp)[1][1]); } (*argvp)[1]++; } (*argvp)++; (*argcp)--; } if (sflag) { /* input file for spatial prediction */ llinputname = (*argvp)[1]; (*argvp)++; (*argcp)--; } if (*argcp!=3 && *argcp!=4) { printf("\n%s, %s\n",version,author); printf("Usage: mpeg2decode {options} input.m2v {snr.m2v} outfile\n\ Options: -vn verbose output (n: level)\n\ -on output format (0: YUV, 1: SIF, 2: TGA, 3:PPM)\n\ -f store interlaced video in frame format\n\ -r use double precision reference IDCT\n\ -s infile spatial scalable sequence\n"); exit(0); } } static int getval(argv) char *argv[]; { int val; if (sscanf(argv[1]+2,"%d",&val)!=1) return 0; while (isdigit(argv[1][2])) argv[1]++; return val; } nhancement layer */ if (twostreams && enhan.scalable_mode!=SC_SNR && !(base.scalable_mode==SC_DP && base.scalable_mode==SC_DP)) error("unsupported scalability mode\n"); /* clip table */ if (!(clp=(unsigned char *)malloc(1024))) error("malloc failed\n"); clp += 384; for (i=-384; i<640; i++) clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i); mb_width = (horizontal_size+15)/16; mb_height =mpeg2/src/mpeg2dec/recon.c 640 270 132 26447 5565640017 10726 /* recon.c, motion compensation routines */ /* Copyright (C) 1994, 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 recon _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 addflag)); static void recon_comp _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 addflag)); void reconstruct(bx,by,mb_type,motion_type,PMV,mv_field_sel,dmvector,stwtype) int bx, by; int mb_type; int motion_type; int PMV[2][2][2], mv_field_sel[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 ((mb_type & MB_FORWARD) || (pict_type==P_TYPE)) { if (pict_struct==FRAME_PICTURE) { if ((motion_type==MC_FRAME) || !(mb_type & MB_FORWARD)) { /* frame-based prediction */ if (stwtop<2) recon(oldrefframe,0,newframe,0, coded_picture_width,coded_picture_width<<1,16,8,bx,by, PMV[0][0][0],PMV[0][0][1],stwtop); if (stwbot<2) recon(oldrefframe,1,newframe,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) recon(oldrefframe,mv_field_sel[0][0],newframe,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) recon(oldrefframe,mv_field_sel[1][0],newframe,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 */ calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]>>1); if (stwtop<2) { /* predict top field from top field */ recon(oldrefframe,0,newframe,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 */ recon(oldrefframe,1,newframe,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 */ recon(oldrefframe,1,newframe,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 */ recon(oldrefframe,0,newframe,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 = (pict_struct==BOTTOM_FIELD); /* determine which frame to use for prediction */ if ((pict_type==P_TYPE) && secondfield && (currentfield!=mv_field_sel[0][0])) predframe = refframe; /* same frame */ else predframe = oldrefframe; /* previous frame */ if ((motion_type==MC_FIELD) || !(mb_type & MB_FORWARD)) { /* field-based prediction */ recon(predframe,mv_field_sel[0][0],newframe,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) { recon(predframe,mv_field_sel[0][0],newframe,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 ((pict_type==P_TYPE) && secondfield && (currentfield!=mv_field_sel[1][0])) predframe = refframe; /* same frame */ else predframe = oldrefframe; /* previous frame */ recon(predframe,mv_field_sel[1][0],newframe,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 (secondfield) predframe = refframe; /* same frame */ else predframe = oldrefframe; /* previous frame */ /* calculate derived motion vectors */ calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]); /* predict from field of same parity */ recon(oldrefframe,currentfield,newframe,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 */ recon(predframe,!currentfield,newframe,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 (mb_type & MB_BACKWARD) { if (pict_struct==FRAME_PICTURE) { if (motion_type==MC_FRAME) { /* frame-based prediction */ if (stwtop<2) recon(refframe,0,newframe,0, coded_picture_width,coded_picture_width<<1,16,8,bx,by, PMV[0][1][0],PMV[0][1][1],stwtop); if (stwbot<2) recon(refframe,1,newframe,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) recon(refframe,mv_field_sel[0][1],newframe,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) recon(refframe,mv_field_sel[1][1],newframe,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 */ recon(refframe,mv_field_sel[0][1],newframe,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) { recon(refframe,mv_field_sel[0][1],newframe,0, coded_picture_width<<1,coded_picture_width<<1,16,8,bx,by, PMV[0][1][0],PMV[0][1][1],stwtop); recon(refframe,mv_field_sel[1][1],newframe,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 recon(src,sfield,dst,dfield,lx,lx2,w,h,x,y,dx,dy,addflag) 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; /* horizontal offsets */ 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 motion vector */ int addflag; /* add prediction error to prediction ? */ { /* Y */ recon_comp(src[0]+(sfield?lx2>>1:0),dst[0]+(dfield?lx2>>1:0), lx,lx2,w,h,x,y,dx,dy,addflag); /* Cb */ recon_comp(src[1]+(sfield?lx2>>2:0),dst[1]+(dfield?lx2>>2:0), lx>>1,lx2>>1,w>>1,h>>1,x>>1,y>>1,dx/2,dy/2,addflag); /* Cr */ recon_comp(src[2]+(sfield?lx2>>2:0),dst[2]+(dfield?lx2>>2:0), lx>>1,lx2>>1,w>>1,h>>1,x>>1,y>>1,dx/2,dy/2,addflag); } static void recon_comp(src,dst,lx,lx2,w,h,x,y,dx,dy,addflag) unsigned char *src; unsigned char *dst; int lx,lx2; int w,h; int x,y; int dx,dy; int addflag; { int xint, xh, yint, yh; int i, j, v; unsigned char *s, *d; /* half pel scaling */ xint = dx>>1; xh = dx & 1; yint = dy>>1; yh = dy & 1; /* origins */ s = src + lx*(y+yint) + x + xint; d = dst + lx*y + x; if (!xh && !yh) if (addflag) 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) if (addflag) 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) */ if (addflag) 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; } } tch control */ if ((sum&1)==0) bp[63]^= 1; } /* move/add 8x8-Block from block[comp] to refframe */ static void addblock(comp,bx,by,dct_type,addflag) int comp, bx, by, dct_type, addflag; { int i, j, iincr; mpeg2/src/mpeg2dec/config.h 640 270 132 3003 5565644213 11033 /* config.h, configuration defines */ /* Copyright (C) 1994, 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 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 (secondfield) predframe = refframe; /* same frame */ else predframe = oldrefframe; /* previous frame */ /* calculate derived motion vectors */ calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]); /* predict from field of same parity */ recon(oldmpeg2/src/mpeg2dec/idctref.c 640 270 132 5423 5565634374 11220 /* idctref.c, Inverse Discrete Fourier Transform, double precision */ /* Copyright (C) 1994, 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 init_idctref _ANSI_ARGS_((void)); void idctref _ANSI_ARGS_((short *block)); /* private data */ /* cosine transform matrix for 8x1 IDCT */ static double c[8][8]; /* initialize DCT coefficient matrix */ void init_idctref() { 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 idctref(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 = floor(partial_product+0.5); block[8*i+j] = (v<-256) ? -256 : ((v>255) ? 255 : v); } } prediction */ if (stwbot<2) recon(refframe,mv_field_sel[1][1],newframe,1, coded_picture_width<<1,coded_picture_width<<1,16,8,bx,by>>1, PMV[1][1][0],PMV[1][1][1]>>1,stwbot); } } elsmpeg2/src/mpeg2dec/spatscal.c 640 270 132 16747 5565641276 11444 /* spatscal.c, spatial scalability decoding */ /* Copyright (C) 1994, 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 spatpred _ANSI_ARGS_((int prog_frame, int llprog_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 chromflag)); static void deinterlace _ANSI_ARGS_((unsigned char *fld0, unsigned char *fld1, int j0, int lx, int ly, int chromflag)); static void subv _ANSI_ARGS_((unsigned char *s, short *d, int lx, int lys, int lyd, int m, int n, int j0, int dj)); static void subh _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 getspatref() { int i, j, llw2, llh2; FILE *fd; char fname[80]; llw2 = llw>>1; llh2 = llh>>1; sprintf(fname,llinputname,lltempref,'a'); strcat(fname,".Y"); if (verbose>1) printf("reading %s\n",fname); fd=fopen(fname,"rb"); for (j=0; j1) printf("reading %s\n",fname); fd=fopen(fname,"rb"); for (j=1; j1) printf("reading %s\n",fname); fd=fopen(fname,"rb"); for (j=0; j1) printf("reading %s\n",fname); fd=fopen(fname,"rb"); for (j=1; j1) printf("reading %s\n",fname); fd=fopen(fname,"rb"); for (j=0; j1) printf("reading %s\n",fname); fd=fopen(fname,"rb"); for (j=1; j>1,vertical_size>>1,vm,vn,hm,hn,1); spatpred(prog_frame,llprog_frame,llframe0[2],llframe1[2],lltmp,newframe[2], llx0/2,lly0/2,llw2,llh2,horizontal_size>>1,vertical_size>>1,vm,vn,hm,hn,1); } /* form spatial prediction */ static void spatpred(prog_frame,llprog_frame, fld0,fld1,tmp,dst,llx0,lly0,llw,llh,horizontal_size,vertical_size, vm,vn,hm,hn,chromflag) int prog_frame,llprog_frame; unsigned char *fld0,*fld1; short *tmp; unsigned char *dst; int llx0,lly0,llw,llh,horizontal_size,vertical_size,vm,vn,hm,hn,chromflag; { int w, h, x0, llw2, llh2; #if 0 if (llprog_frame) { /* progressive -> progressive / interlaced */ subv(fld0,tmp,horizontal_sizell,vertical_sizell,vertical_size,m,n,0,1); subh(tmp,dst,0,horizontal_size,horizontal_sizell,horizontal_size,vertical_size,m,n); } else if (prog_frame) { /* interlaced -> progressive */ if (ll_fldsel) { deinterlace(fld1,fld0); subv(fld1,tmp); subh(tmp,dst); } else { deinterlace(fld0,fld1); subv(fld0,tmp); subh(tmp,dst); } } else { #endif /* interlaced -> interlaced */ llw2 = (llw*hn)/hm; llh2 = (llh*vn)/vm; deinterlace(fld0,fld1,1,llw,llh,chromflag); deinterlace(fld1,fld0,0,llw,llh,chromflag); subv(fld0,tmp,llw,llh,llh2,vm,vn,0,2); subv(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; } subh(tmp,dst,x0,w,llw,horizontal_size,h,hm,hn); #if 0 } #endif } static void deinterlace(fld0,fld1,j0,lx,ly,chromflag) unsigned char *fld0,*fld1; int j0,lx,ly; /* ly has to be even */ int chromflag; { 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 subv(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; } } } i, j, v; unsigned char mpeg2/src/mpeg2dec/global.h 640 270 132 14566 5565647254 11076 /* global.h, global variables */ /* Copyright (C) 1994, 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 "mpeg2dec.h" /* choose between declaration (GLOBAL undefined) * and definition (GLOBAL defined) * GLOBAL is defined in exactly one file (mpeg2dec.c) */ #ifndef GLOBAL #define EXTERN extern #else #define EXTERN #endif /* prototypes of global functions */ /* getbits.c */ void initbits _ANSI_ARGS_((void)); void fillbfr _ANSI_ARGS_((void)); unsigned long showbits _ANSI_ARGS_((int n)); unsigned long getbits1 _ANSI_ARGS_((void)); void flushbits _ANSI_ARGS_((int n)); unsigned long getbits _ANSI_ARGS_((int n)); /* getblk.c */ void getintrablock _ANSI_ARGS_((int comp, int dc_dct_pred[])); void getinterblock _ANSI_ARGS_((int comp)); void getmpg2intrablock _ANSI_ARGS_((int comp, int dc_dct_pred[])); void getmpg2interblock _ANSI_ARGS_((int comp)); /* gethdr.c */ int getheader _ANSI_ARGS_((void)); void startcode _ANSI_ARGS_((void)); int getslicehdr _ANSI_ARGS_((void)); /* getpict.c */ void getpicture _ANSI_ARGS_((void)); void putlast _ANSI_ARGS_((void)); /* getvlc.c */ int getMBtype _ANSI_ARGS_((void)); int getMV _ANSI_ARGS_((void)); int getDMV _ANSI_ARGS_((void)); int getCBP _ANSI_ARGS_((void)); int getMBA _ANSI_ARGS_((void)); int getDClum _ANSI_ARGS_((void)); int getDCchrom _ANSI_ARGS_((void)); /* idct.c */ void idct _ANSI_ARGS_((short *block)); void init_idct _ANSI_ARGS_((void)); /* idctref.c */ void init_idctref _ANSI_ARGS_((void)); void idctref _ANSI_ARGS_((short *block)); /* motion.c */ void motion_vectors _ANSI_ARGS_((int PMV[2][2][2], int dmvector[2], int mv_field_sel[2][2], int s, int mv_count, int mv_format, int h_r_size, int v_r_size, int dmv, int mvscale)); void motion_vector _ANSI_ARGS_((int *PMV, int *dmvector, int h_r_size, int v_r_size, int dmv, int mvscale, int full_pel_vector)); void calc_DMV _ANSI_ARGS_((int DMV[][2], int *dmvector, int mvx, int mvy)); /* mpeg2dec.c */ void error _ANSI_ARGS_((char *text)); /* recon.c */ void reconstruct _ANSI_ARGS_((int bx, int by, int mb_type, int motion_type, int PMV[2][2][2], int mv_field_sel[2][2], int dmvector[2], int stwtype)); /* spatscal.c */ void getspatref _ANSI_ARGS_((void)); /* store.c */ void storeframe _ANSI_ARGS_((unsigned char *src[], int frame)); /* global variables */ EXTERN char version[] #ifdef GLOBAL ="mpeg2decode V1.0, 94/05/16" #endif ; EXTERN char author[] #ifdef GLOBAL ="(C) 1994, MPEG Software Simulation Group" #endif ; /* zig-zag scan */ EXTERN unsigned char zig_zag_scan[64] #ifdef GLOBAL = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5, 12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28, 35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51, 58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 } #endif ; /* alternate scan */ EXTERN unsigned char alternate_scan[64] #ifdef GLOBAL = { 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49, 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43, 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45, 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63 } #endif ; /* default intra quantization matrix */ EXTERN unsigned char default_intra_quantizer_matrix[64] #ifdef GLOBAL = { 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83 } #endif ; /* non-linear quantization coefficient table */ EXTERN unsigned char non_linear_mquant_table[32] #ifdef GLOBAL = { 0, 1, 2, 3, 4, 5, 6, 7, 8,10,12,14,16,18,20,22, 24,28,32,36,40,44,48,52, 56,64,72,80,88,96,104,112 } #endif ; EXTERN int quiet; EXTERN char errortext[256]; EXTERN unsigned char *refframe[3],*oldrefframe[3],*auxframe[3],*newframe[3]; EXTERN unsigned char *clp; EXTERN int horizontal_size,vertical_size,mb_width,mb_height; EXTERN int coded_picture_width, coded_picture_height; EXTERN int pict_type; EXTERN int forw_r_size,back_r_size; EXTERN int full_forw,full_back; EXTERN int fault; EXTERN int verbose; EXTERN int prog_seq; EXTERN int h_forw_r_size,v_forw_r_size,h_back_r_size,v_back_r_size; EXTERN int dcprec,pict_struct,topfirst,frame_pred_dct,conceal_mv; EXTERN int intravlc,repeatfirst,prog_frame; EXTERN int secondfield; EXTERN int stwc_table_index,llw,llh,hm,hn,vm,vn; EXTERN int lltempref,llx0,lly0,llprog_frame,llfieldsel; EXTERN unsigned char *llframe0[3],*llframe1[3]; EXTERN short *lltmp; EXTERN char *llinputname; EXTERN int twostreams,sflag; EXTERN int refidct; EXTERN int matrix_coefficients; /* output */ EXTERN int framestoreflag; EXTERN char *outputname; EXTERN int outtype; #define T_NONE -1 #define T_YUV 0 #define T_SIF 1 #define T_TGA 2 #define T_PPM 3 /* 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]; int incnt; int bitcnt; /* sequence header */ int intra_quantizer_matrix[64],non_intra_quantizer_matrix[64]; int mpeg2; /* sequence scalable extension */ int scalable_mode; /* picture coding extension */ int qscale_type,altscan; /* picture spatial scalable extension */ int pict_scal; /* slice/macroblock */ int pri_brk; int quant_scale; short block[6][64]; } base, enhan, *ld; ; i++) { v = 8*(p0m1[i]+p0p1[i]) + 2*p1[i] - p1m2[i] - p1p2[i]; p0[i] = clp[(v + ((v>=0) ? 8 : 7))>>4]; } mpeg2/src/mpeg2dec/gethdr.c 640 270 132 44443 5565457030 11072 /* gethdr.c, header decoding */ /* Copyright (C) 1994, 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 int gethdr _ANSI_ARGS_((void)); static void getseqhdr _ANSI_ARGS_((void)); static void getgophdr _ANSI_ARGS_((void)); static void getpicturehdr _ANSI_ARGS_((void)); static void ext_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 void ext_bit_info _ANSI_ARGS_((void)); /* decode headers from all input streams */ int getheader() { int ret; ld = &base; ret = gethdr(); if (twostreams) { ld = &enhan; if (gethdr()!=ret && !quiet) fprintf(stderr,"streams out of sync\n"); ld = &base; } return ret; } /* * decode headers from one input stream * until an End of Sequence or picture start code * is found */ static int gethdr() { unsigned long code; for (;;) { /* look for startcode */ startcode(); code = getbits(32); switch (code) { case SEQ_START_CODE: getseqhdr(); break; case GOP_START_CODE: getgophdr(); break; case PICTURE_START_CODE: getpicturehdr(); return 1; break; case SEQ_END_CODE: return 0; break; default: if (!quiet) fprintf(stderr,"Unexpected startcode %08x (ignored)\n",code); break; } } } /* align to start of next startcode */ void startcode() { /* byte align */ flushbits(ld->incnt&7); while (showbits(24)!=1l) flushbits(8); } /* decode sequence header */ static void getseqhdr() { int i; int aspect_ratio, picture_rate, vbv_buffer_size; int constrained_parameters_flag; int load_intra_quantizer_matrix, load_non_intra_quantizer_matrix; long bit_rate; int pos; pos = ld->bitcnt; horizontal_size = getbits(12); vertical_size = getbits(12); aspect_ratio = getbits(4); picture_rate = getbits(4); bit_rate = getbits(18); flushbits(1); /* marker bit (=1) */ vbv_buffer_size = getbits(10); constrained_parameters_flag = getbits(1); if (load_intra_quantizer_matrix = getbits(1)) { for (i=0; i<64; i++) ld->intra_quantizer_matrix[zig_zag_scan[i]] = getbits(8); } else { for (i=0; i<64; i++) ld->intra_quantizer_matrix[i] = default_intra_quantizer_matrix[i]; } if (load_non_intra_quantizer_matrix=getbits(1)) { for (i=0; i<64; i++) ld->non_intra_quantizer_matrix[zig_zag_scan[i]] = getbits(8); } else { for (i=0; i<64; i++) ld->non_intra_quantizer_matrix[i] = 16; } if (verbose>0) { printf("sequence header (byte %d)\n",(pos>>3)-4); if (verbose>1) { printf(" horizontal_size=%d\n",horizontal_size); printf(" vertical_size=%d\n",vertical_size); printf(" aspect_ratio=%d\n",aspect_ratio); printf(" picture_rate=%d\n",picture_rate); printf(" bit_rate=%d\n",bit_rate); 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",load_intra_quantizer_matrix); printf(" load_non_intra_quantizer_matrix=%d\n",load_non_intra_quantizer_matrix); } } ext_user_data(); } /* decode group of pictures header */ static void getgophdr() { int drop_flag, hour, minute, sec, frame, closed_gop, broken_link; int pos; pos = ld->bitcnt; drop_flag = getbits(1); hour = getbits(5); minute = getbits(6); flushbits(1); sec = getbits(6); frame = getbits(6); closed_gop = getbits(1); broken_link = getbits(1); if (verbose>0) { printf("group of pictures (byte %d)\n",(pos>>3)-4); if (verbose>1) { 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); } } ext_user_data(); } /* decode picture header */ static void getpicturehdr() { int temp_ref, vbv_delay; int pos; ld->pict_scal = 0; /* unless overwritten by pict. spat. scal. ext. */ pos = ld->bitcnt; temp_ref = getbits(10); pict_type = getbits(3); vbv_delay = getbits(16); if (pict_type==P_TYPE || pict_type==B_TYPE) { full_forw = getbits(1); forw_r_size = getbits(3) - 1; } if (pict_type==B_TYPE) { full_back = getbits(1); back_r_size = getbits(3) - 1; } if (verbose>0) { printf("picture header (byte %d)\n",(pos>>3)-4); if (verbose>1) { printf(" temp_ref=%d\n",temp_ref); printf(" pict_type=%d\n",pict_type); printf(" vbv_delay=%d\n",vbv_delay); if (pict_type==P_TYPE || pict_type==B_TYPE) { printf(" full_forw=%d\n",full_forw); printf(" forw_r_size=%d\n",forw_r_size); } if (pict_type==B_TYPE) { printf(" full_back=%d\n",full_back); printf(" back_r_size=%d\n",back_r_size); } } } ext_bit_info(); ext_user_data(); } /* decode slice header */ int getslicehdr() { int slice_vertical_position_extension, intra_slice; int qs; int pos; pos = ld->bitcnt; slice_vertical_position_extension = (ld->mpeg2 && vertical_size>2800) ? getbits(3) : 0; if (ld->scalable_mode==SC_DP) ld->pri_brk = getbits(7); qs = getbits(5); ld->quant_scale = ld->mpeg2 ? (ld->qscale_type ? non_linear_mquant_table[qs] : qs<<1) : qs; if (getbits(1)) { intra_slice = getbits(1); flushbits(7); ext_bit_info(); } else intra_slice = 0; if (verbose>2) { printf("slice header (byte %d)\n",(pos>>3)-4); if (verbose>3) { if (ld->mpeg2 && 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->pri_brk); printf(" quantizer_scale_code=%d\n",qs); } } return slice_vertical_position_extension; } /* decode extension and user data */ static void ext_user_data() { int code,ext_ID; startcode(); while ((code = showbits(32))==EXT_START_CODE || code==USER_START_CODE) { if (code==EXT_START_CODE) { flushbits(32); ext_ID = getbits(4); switch (ext_ID) { case SEQ_ID: sequence_extension(); break; case DISP_ID: sequence_display_extension(); break; case QUANT_ID: quant_matrix_extension(); break; case SEQSCAL_ID: sequence_scalable_extension(); break; case PANSCAN_ID: picture_display_extension(); break; case CODING_ID: picture_coding_extension(); break; case SPATSCAL_ID: picture_spatial_scalable_extension(); break; case TEMPSCAL_ID: picture_temporal_scalable_extension(); break; default: fprintf(stderr,"reserved extension start code ID %d\n",ext_ID); break; } startcode(); } else { if (verbose) printf("user data\n"); flushbits(32); startcode(); } } } /* decode sequence extension */ static void sequence_extension() { int prof_lev, chroma_format; int horizontal_size_extension, vertical_size_extension; int bit_rate_extension, vbv_buffer_size_extension, low_delay; int frame_rate_extension_n, frame_rate_extension_d; int pos; pos = ld->bitcnt; ld->mpeg2 = 1; ld->scalable_mode = SC_NONE; /* unless overwritten by seq. scal. ext. */ prof_lev = getbits(8); prog_seq = getbits(1); chroma_format = getbits(2); horizontal_size_extension = getbits(2); vertical_size_extension = getbits(2); bit_rate_extension = getbits(12); flushbits(1); vbv_buffer_size_extension = getbits(8); low_delay = getbits(1); frame_rate_extension_n = getbits(2); frame_rate_extension_d = getbits(5); horizontal_size = (horizontal_size_extension<<12) | (horizontal_size&0x0fff); vertical_size = (vertical_size_extension<<12) | (vertical_size&0x0fff); if (verbose>0) { printf("sequence extension (byte %d)\n",(pos>>3)-4); if (verbose>1) { printf(" profile_and_level_indication=%d\n",prof_lev); if (prof_lev<128) { printf(" profile=%d, level=%d\n",prof_lev>>4,prof_lev&15); } printf(" progressive_sequence=%d\n",prog_seq); 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); } } } /* decode sequence display extension */ static void sequence_display_extension() { int video_format, colour_description; int colour_primaries, transfer_characteristics; int display_horizontal_size, display_vertical_size; int pos; pos = ld->bitcnt; video_format = getbits(3); colour_description = getbits(1); if (colour_description) { colour_primaries = getbits(8); transfer_characteristics = getbits(8); matrix_coefficients = getbits(8); } display_horizontal_size = getbits(14); flushbits(1); display_vertical_size = getbits(14); if (verbose>0) { printf("sequence display extension (byte %d)\n",(pos>>3)-4); if (verbose>1) { printf(" video_format=%d\n",video_format); printf(" colour_description=%d\n",colour_description); if (colour_description) { printf(" colour_primaries=%d\n",colour_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); } } } /* decode quant matrix entension */ static void quant_matrix_extension() { int i; int load_intra_quantiser_matrix, load_non_intra_quantiser_matrix; int load_chroma_intra_quantiser_matrix; int load_chroma_non_intra_quantiser_matrix; int pos; pos = ld->bitcnt; if (load_intra_quantiser_matrix=getbits(1)) { for (i=0; i<64; i++) ld->intra_quantizer_matrix[zig_zag_scan[i]]=getbits(8); } if (load_non_intra_quantiser_matrix=getbits(1)) { for (i=0; i<64; i++) ld->non_intra_quantizer_matrix[zig_zag_scan[i]]=getbits(8); } if (load_chroma_intra_quantiser_matrix=getbits(1)) { for (i=0; i<64; i++) flushbits(8); } if (load_chroma_non_intra_quantiser_matrix=getbits(1)) { for (i=0; i<64; i++) flushbits(8); } if (verbose>0) { printf("quant matrix extension (byte %d)\n",(pos>>3)-4); printf(" load_intra_quantiser_matrix=%d\n", load_intra_quantiser_matrix); printf(" load_non_intra_quantiser_matrix=%d\n", load_non_intra_quantiser_matrix); printf(" load_chroma_intra_quantiser_matrix=%d\n", load_chroma_intra_quantiser_matrix); printf(" load_chroma_non_intra_quantiser_matrix=%d\n", load_chroma_non_intra_quantiser_matrix); } } /* decode sequence scalable extension */ static void sequence_scalable_extension() { int layer_id; int pos; pos = ld->bitcnt; ld->scalable_mode = getbits(2) + 1; /* add 1 to make SC_DP != SC_NONE */ layer_id = getbits(4); if (ld->scalable_mode==SC_SPAT) { llw = getbits(14); /* lower_layer_prediction_horizontal_size */ flushbits(1); llh = getbits(14); /* lower_layer_prediction_vertical_size */ hm = getbits(5); hn = getbits(5); vm = getbits(5); vn = getbits(5); } if (ld->scalable_mode==SC_TEMP) error("temporal scalability not implemented\n"); if (verbose>0) { printf("sequence scalable extension (byte %d)\n",(pos>>3)-4); if (verbose>1) { 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",llw); printf(" lower_layer_prediction_vertical_size=%d\n",llh); printf(" horizontal_subsampling_factor_m=%d\n",hm); printf(" horizontal_subsampling_factor_n=%d\n",hn); printf(" vertical_subsampling_factor_m=%d\n",vm); printf(" vertical_subsampling_factor_n=%d\n",vn); } } } } /* decode picture display extension */ static void picture_display_extension() { int i,n; short frame_centre_horizontal_offset[3]; short frame_centre_vertical_offset[3]; int pos; pos=ld->bitcnt; if (prog_seq || pict_struct!=FRAME_PICTURE) n = 1; else n = repeatfirst ? 3 : 2; for (i=0; i0) { printf("picture display extension (byte %d)\n",(pos>>3)-4); if (verbose>1) { for (i=0; ibitcnt; h_forw_r_size = getbits(4) - 1; v_forw_r_size = getbits(4) - 1; h_back_r_size = getbits(4) - 1; v_back_r_size = getbits(4) - 1; dcprec = getbits(2); pict_struct = getbits(2); topfirst = getbits(1); frame_pred_dct = getbits(1); conceal_mv = getbits(1); ld->qscale_type = getbits(1); intravlc = getbits(1); ld->altscan = getbits(1); repeatfirst = getbits(1); chroma_420_type = getbits(1); prog_frame = getbits(1); composite_display_flag = getbits(1); if (composite_display_flag) { v_axis = getbits(1); field_sequence = getbits(3); sub_carrier = getbits(1); burst_amplitude = getbits(7); sub_carrier_phase = getbits(8); } if (verbose>0) { printf("picture coding extension (byte %d)\n",(pos>>3)-4); if (verbose>1) { printf(" forward_horizontal_f_code=%d\n",h_forw_r_size+1); printf(" forward_vertical_f_code=%d\n",v_forw_r_size+1); printf(" backward_horizontal_f_code=%d\n",h_back_r_size+1); printf(" backward_vertical_f_code=%d\n",v_back_r_size+1); printf(" intra_dc_precision=%d\n",dcprec); printf(" picture_structure=%d\n",pict_struct); printf(" top_field_first=%d\n",topfirst); printf(" frame_pred_frame_dct=%d\n",frame_pred_dct); printf(" concealment_motion_vectors=%d\n",conceal_mv); printf(" q_scale_type=%d\n",ld->qscale_type); printf(" intra_vlc_format=%d\n",intravlc); printf(" alternate_scan=%d\n",ld->altscan); printf(" repeat_first_field=%d\n",repeatfirst); printf(" chroma_420_type=%d\n",chroma_420_type); printf(" progressive_frame=%d\n",prog_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); } } } } /* decode picture spatial scalable extension */ static void picture_spatial_scalable_extension() { int pos; pos = ld->bitcnt; ld->pict_scal = 1; /* use spatial scalability in this picture */ lltempref = getbits(10); flushbits(1); llx0 = getbits(15); if (llx0>=16384) llx0-= 32768; flushbits(1); lly0 = getbits(15); if (lly0>=16384) lly0-= 32768; stwc_table_index = getbits(2); llprog_frame = getbits(1); llfieldsel = getbits(1); if (verbose>0) { printf("picture spatial scalable extension (byte %d)\n",(pos>>3)-4); if (verbose>1) { printf(" lower_layer_temporal_reference=%d\n",lltempref); printf(" lower_layer_horizontal_offset=%d\n",llx0); printf(" lower_layer_vertical_offset=%d\n",lly0); printf(" spatial_temporal_weight_code_table_index=%d\n", stwc_table_index); printf(" lower_layer_progressive_frame=%d\n",llprog_frame); printf(" lower_layer_deinterlaced_field_select=%d\n",llfieldsel); } } } /* decode picture temporal scalable extension * * not implemented */ static void picture_temporal_scalable_extension() { error("temporal scalability not supported\n"); } /* decode extra bit information */ static void ext_bit_info() { while (getbits1()) flushbits(8); } } } /* decode sequence display extension */ static void sequence_display_extension() { int video_format, colour_description; int colour_primaries, transfer_characteristics; int display_horizontal_size, displaympeg2/src/mpeg2dec/store.c 640 270 132 36627 5565720556 10764 /* store.c, picture output routines */ /* Copyright (C) 1994, 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_tga _ANSI_ARGS_((char *outname, unsigned char *src[], int offset, int incr, int height)); static void store_ppm _ANSI_ARGS_((char *outname, unsigned char *src[], int offset, int incr, int height)); 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 putlong _ANSI_ARGS_((long l)); 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; /* color space conversion coefficients * * 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) */ static int convmat[8][4] = { {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) */ }; /* * store a picture as either one frame or two fields */ void storeframe(src,frame) unsigned char *src[]; int frame; { char outname[32]; if (prog_seq || prog_frame || framestoreflag) { /* progressive */ sprintf(outname,outputname,frame,'f'); store_one(outname,src,0,coded_picture_width,vertical_size); } else { /* interlaced */ sprintf(outname,outputname,frame,'a'); store_one(outname,src,0,coded_picture_width<<1,vertical_size>>1); sprintf(outname,outputname,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 (outtype) { 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_tga(outname,src,offset,incr,height); break; case T_PPM: store_ppm(outname,src,offset,incr,height); break; 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; { char tmpname[32]; sprintf(tmpname,"%s.Y",outname); store_yuv1(tmpname,src[0],offset,incr,horizontal_size,height); sprintf(tmpname,"%s.U",outname); store_yuv1(tmpname,src[1],offset>>1,incr>>1,horizontal_size>>1,height>>1); sprintf(tmpname,"%s.V",outname); store_yuv1(tmpname,src[2],offset>>1,incr>>1,horizontal_size>>1,height>>1); } /* 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 (verbose>1) printf("saving %s\n",name); if ((outfile = open(name,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1) { sprintf(errortext,"Couldn't create %s\n",name); error(errortext); } optr=obfr; for (i=0; i>1) *coded_picture_height); v422 = (unsigned char *)malloc((coded_picture_width>>1) *coded_picture_height); } conv420to422(src[1],u422); conv420to422(src[2],v422); strcat(outname,".SIF"); if (verbose>1) printf("saving %s\n",outname); if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1) { sprintf(errortext,"Couldn't create %s\n",outname); error(errortext); } 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); v422 = (unsigned char *)malloc((coded_picture_width>>1) *coded_picture_height); u444 = (unsigned char *)malloc(coded_picture_width*coded_picture_height); v444 = (unsigned char *)malloc(coded_picture_width*coded_picture_height); } conv420to422(src[1],u422); conv420to422(src[2],v422); conv422to444(u422,u444); conv422to444(v422,v444); strcat(outname,".tga"); if (verbose>1) printf("saving %s\n",outname); if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1) { sprintf(errortext,"Couldn't create %s\n",outname); error(errortext); } optr = obfr; /* TGA header */ for (i=0; i<12; i++) putbyte(tga24[i]); putword(horizontal_size); putword(height); putbyte(tga24[12]); putbyte(tga24[13]); /* matrix coefficients */ crv = convmat[matrix_coefficients][0]; cbu = convmat[matrix_coefficients][1]; cgu = convmat[matrix_coefficients][2]; cgv = convmat[matrix_coefficients][3]; for (i=0; i>16]; g = clp[(y - cgu*u -cgv*v + 32768)>>16]; b = clp[(y + cbu*u + 32786)>>16]; putbyte(b); putbyte(g); putbyte(r); } } if (optr!=obfr) write(outfile,obfr,optr-obfr); close(outfile); } /* * store as PPM (PBMPLUS) file */ static void store_ppm(outname,src,offset,incr,height) char *outname; unsigned char *src[]; int offset, incr, height; { int i, j; int y, u, v, r, g, b; int crv, cbu, cgu, cgv; unsigned char *py, *pu, *pv; char header[32]; static unsigned char *u422, *v422, *u444, *v444; if (!u422) { u422 = (unsigned char *)malloc((coded_picture_width>>1) *coded_picture_height); v422 = (unsigned char *)malloc((coded_picture_width>>1) *coded_picture_height); u444 = (unsigned char *)malloc(coded_picture_width*coded_picture_height); v444 = (unsigned char *)malloc(coded_picture_width*coded_picture_height); } conv420to422(src[1],u422); conv420to422(src[2],v422); conv422to444(u422,u444); conv422to444(v422,v444); strcat(outname,".ppm"); if (verbose>1) printf("saving %s\n",outname); if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1) { sprintf(errortext,"Couldn't create %s\n",outname); error(errortext); } optr = obfr; /* 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 = convmat[matrix_coefficients][0]; cbu = convmat[matrix_coefficients][1]; cgu = convmat[matrix_coefficients][2]; cgv = convmat[matrix_coefficients][3]; for (i=0; i>16]; g = clp[(y - cgu*u - cgv*v + 32768)>>16]; b = clp[(y + cbu*u + 32786)>>16]; 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); } static void putlong(l) long l; { putword((int)l); putword((int)(l>>16)); } /* 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) { for (j=0; j>8]; } src+= w; dst+= coded_picture_width; } } else { for (j=0; j>8]; dst[i2+1] = clp[(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 (prog_frame) { /* intra frame */ for (i=0; i>8]; dst[w*(j2+1)] = clp[(int)( 5*src[w*jp3] -21*src[w*jp2] +70*src[w*jp1] +228*src[w*j] -37*src[w*jm1] +11*src[w*jm2]+128)>>8]; } src++; dst++; } } else { /* intra field */ for (i=0; i>8]; dst[w*(j2+2)] = clp[(int)( 11*src[w*jm4] -38*src[w*jm2] +192*src[w*j] +113*src[w*jp2] -30*src[w*jp4] +8*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)] = clp[(int)( 2*src[w*jp7] -10*src[w*jp5] +35*src[w*jp3] +242*src[w*jp1] -18*src[w*jm1] +5*src[w*jm3]+128)>>8]; } src++; dst++; } } } ,".tga"); if (verbose>1) printf("saving %s\n",outname); if ((outfile = open(outname,O_CREAT|O_Tmpeg2/src/mpeg2dec/mpeg2dec.h 640 270 132 4541 5565644476 11277 /* mpeg2dec.h, MPEG specific defines */ /* Copyright (C) 1994, 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_MIN_START 0x101 #define SLICE_MAX_START 0x1AF #define USER_START_CODE 0x1B2 #define SEQ_START_CODE 0x1B3 #define EXT_START_CODE 0x1B5 #define SEQ_END_CODE 0x1B7 #define GOP_START_CODE 0x1B8 /* 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 MB_INTRA 1 #define MB_PATTERN 2 #define MB_BACKWARD 4 #define MB_FORWARD 8 #define MB_QUANT 16 #define MB_WEIGHT 32 #define MB_CLASS4 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 /* extension start code IDs */ #define SEQ_ID 1 #define DISP_ID 2 #define QUANT_ID 3 #define SEQSCAL_ID 5 #define PANSCAN_ID 7 #define CODING_ID 8 #define SPATSCAL_ID 9 #define TEMPSCAL_ID 10 } if (optr!=obfr) write(outfile,obfr,optr-obfr); close(outfile); } static void putbyte(c) int c; { *optr++ = c; if (optr == obfr+OBFRSIZE) { mpeg2/src/mpeg2dec/Makefile 640 270 132 4024 5564702006 11053 # Makefile for mpeg2decode # Copyright (C) 1994, 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. # # # # GNU gcc # CC = gcc CFLAGS = -O2 # # SPARCworks acc # #CC = acc #CFLAGS = -fast # # SUN cc # #CC = cc #CFLAGS = -O3 -DNON_ANSI_COMPILER 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 all: mpeg2decode pc: mpeg2dec.exe clean: rm -f *.o *% core mpeg2decode mpeg2dec.exe: mpeg2decode coff2exe mpeg2dec mpeg2decode: $(OBJ) $(CC) $(CFLAGS) -o mpeg2decode $(OBJ) -lm getbits.o: config.h global.h mpeg2dec.h getblk.o: config.h global.h mpeg2dec.h gethdr.o: config.h global.h mpeg2dec.h getpic.o: config.h global.h mpeg2dec.h getvlc.o: config.h global.h mpeg2dec.h getvlc.h idct.o: config.h idctref.o: config.h motion.o: config.h global.h mpeg2dec.h mpeg2dec.o: config.h global.h mpeg2dec.h recon.o: config.h global.h mpeg2dec.h spatscal.o: config.h global.h mpeg2dec.h store.o: config.h global.h mpeg2dec.h fr,OBFRSIZE); optr = obfr; } } static void putword(w) int w; { putbyte(w); putbyte(w>>8); } static void putlong(l) long l; { putword((int)l); putword((int)(l>>16)); } /* 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) { for (j=0; j 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 -------------------- If you have downloaded and unarchived 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.mpg and new.mpg, caused by floating point accuracy dependencies in the encoder rate control. 6. Acknowledgements =================== Authors of the current release are: Stefan Eckart (stefan@lis.e-technik.tu-muenchen.de) Chad Fogg (cfogg@netcom.com) Cheung Auyeung (auyeung@mot.com) 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. - A reference tool for implementors - Aid in understanding the MPEG specification MPEG would like to especially thank Dr. Stefan Eckart for his contributions have greatly helped the MPEG-2 Technical Report project start onto a successful path towards the final 13818-5 document. MPEG lends a kind acknowledgement to Arian Koster (PTT) for initiating the MPEG-1 technical report project in Autumn 1992, and Leonardo Chiariglione (Chairman of MPEG) and Didier Le Gall (Chairman of MPEG Video) for support throughout both projects. Also many thanks to MPEG-1 project contributors Peter Au (Hughes Aircraft), Ron Burns (Hughes Aircraft), Stefan Eckart (Technical University of Munich), Chad Fogg, Tsuyoshi Hanamura (Waseda University), Kinya Oosa (Nippon Steel), Brian Quandt (Heuris Logic) and Hiroshi Watanabe (NTT). Regards, Chad Fogg MPEG Chair for Software Simulation, Jan 1993 - +1 415 254 5818 cfogg@netcom.com ---- End of Readme file erstanding 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 on on-going development. Since the current version of the encoder already employs a reasonable (and the most popular) subset of the MPEG-2 simpeg2/Makefile 640 270 132 3175 5564711476 6617 # Makefile for mpeg2decode / mpeg2encode # Copyright (C) 1994, 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. # # # # GNU gcc # CC = gcc CFLAGS = -O2 # # SPARCompiler # #CC = acc #CFLAGS = -fast # # SUN cc # #CC = cc #CFLAGS = -O3 -DNON_ANSI_COMPILER all: cd src/mpeg2dec; make 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 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 as initiated by the MPEG committee to: - Provide an example of MPEG video syntax being intelligently employed to generate good quality video. - A reference tool for implementors - Aid in understanding the MPEG specification MPEG would like to especially thank Dr. Stefan Eckart for his contributions have greatly helped the MPEG-2 Technical Report project start onto a success mpeg2v10.zip MS-DOS executable archive tennis.m2v sample MPEG-2 video sequence (8 frames 704x576) tennis.par, tennis.stat.gz parameter file and statistics output for tennis.m2v You need gunzip (GNU zip/unzip) to uncompress the .gz archives. Alternatively, the files may be retrieved by sending E-mail to: ftp-request@netcom.com ... with the following line in the body of the message: SEND cfogg/mpeg2/mpeg2codec_v1.0.tar.gz You can retrieve the directory listings by sending the following command to ftp-request@netcom.com: DIR cfogg/mpeg2 General information can be retrieved with the command: HELP 5. Installation =============== mpeg2decode and mpeg2encode have been compiled successfully on the following platforms: - SUN SPARCstation 10, SunOS 4.1.3, cc / gcc / acc - '386-PC, MSDOS 5.0, djgpp v1.11, gcc v2.5.7 The source code should compile without major modifications on other 32 bit systems using both K&R and ANSI C 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 MPEG-L@netcom.com. 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 ---------------------