/*
* Copyright 2005 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
/**
* @description
* This file contains functions that allow one to decode MPEG-2 compliant video.
* The code is based on the MPEG-2 specification (ISO/IEC 13818-2). The MPEG-2 decoding
* is a work in progress, although it works within a limited test range. Throughout the
* source code, citations are made in cases where an understanding of the code would be
* helped by looking at an outside source. The format I have chosen is
* (cite NUM#, LOOKUP_INFO). NUM=1 refers to ISO/IEC: 13818-2, and NUM=2 refers to the reference
* MPEG implementation written in C, available at [www.mpeg.org].
*
* @author Matthew Drake
* @file MPEGdecoder.str.pre
* @version 1.0
*/
// Comments for readers of the StreamIt MPEG specification:
//
// TODO notes refer to parts of the MPEG-2 specification which this
// program does not yet handle, or assumptions made by the program.
// FEATURETODO notes refer to changes that ought to be made to the program,
// or support which can be added for more of the MPEG-2 specification, which
// is pending the addition of features to the StreamIt language compiler.
// In general I have tried to document my code, and refer to the MPEG-2
// specification whenever I used it. If you are looking at any particular
// block of code and aren't sure what it is doing, find the previous citation
// comment, and refer to the corresponding page in the MPEG 2 spec.
/**
* Interprets and decodes a compressed MPEG-2 compliant bit stream, in accordance
* with the IEEE MPEG-2 specification.
* @param width The resolution width of the video. This variable is only needed until the StreamIt
* language supports dynamically reconfiguring splijtoins.
* @param height The resolution height of the video. This variable is only needed until the StreamIt
* language supports dynamically reconfiguring splitjoins.
* @input An MPEG-2 compliant bit stream of variable length.
* @output Outputs a series of images representing the frames of the video. Each image
* consists of 3 integers for each pixel, with the number of pixels per image
* equalling the width * height of the video. Frames are output in time order,
* top to bottom, left to right, and RGB color order.
*/
bit->int pipeline MPEGStream_to_rawImageStream(int width, int height,
int the_chroma_format) {
// width, height, chroma: Hacked till we have reprogrammable splitjoins FEATURETODO
portal UpdatePortal_quantiser_data_ac;
portal UpdatePortal_macroblock_intra;
portal UpdatePortal_quantiser_data_dc;
portal UpdatePortal_picture_type;
portal UpdatePortal_mvd;
portal UpdatePortal_picture_type2;
portal UpdatePortal_picture_type3;
add MPEGStreamParser(UpdatePortal_quantiser_data_ac,
UpdatePortal_quantiser_data_dc,
UpdatePortal_macroblock_intra,
UpdatePortal_picture_type,
UpdatePortal_mvd,
UpdatePortal_picture_type2,
UpdatePortal_picture_type3,
width,
height,
the_chroma_format
);
add int->int splitjoin {
split roundrobin(64*blocks_per_macroblock[the_chroma_format], 16, 3);
add BlockDecode(UpdatePortal_quantiser_data_ac,
UpdatePortal_macroblock_intra,
UpdatePortal_quantiser_data_dc);
add int->int pipeline {
add MotionVectorDecode() to UpdatePortal_mvd;
add Repeat(8, blocks_per_macroblock[the_chroma_format]);
}
add Repeat(3, blocks_per_macroblock[the_chroma_format]); // macroblock_intra
join roundrobin(64, 8, 3);
}
// Each output channel is ordered left to right, top to bottom
add ColorChannelProcessing(width,
height,
UpdatePortal_picture_type,
the_chroma_format,
UpdatePortal_picture_type3);
// FEATURETODO This next component should also use the UpdatePortal_picture_type
// but it doesn't because of messaging limitations.
add PictureReorder(width, height) to UpdatePortal_picture_type2;
// This function assumes that no sequence display extension was ever
// encountered in the data stream, and the default colorspace transformations
// apply.
// (cite 1, P. 47, Table 6-9): Refer to entry 1, which is
// Recommendation ITU-R BT.709 for transformations.
add ColorSpaceConversion_YCbCrtoRGB;
}
/**
* @internal
*/
int->int pipeline LuminanceChannelProcessing(int width,
int height,
portal UpdatePortal_picture_type,
int the_chroma_format,
portal UpdatePortal_picture_type3) {
add MacroBlockDescrambler(width, 64+11, 2);
add DescrambleAndMotionCompensate(width,
height,
1,
1,
UpdatePortal_picture_type,
1,
the_chroma_format,
UpdatePortal_picture_type3);
}
/**
* @internal
*/
int->int pipeline ChrominanceChannelProcessing(int width,
int height,
portal UpdatePortal_picture_type,
int the_chroma_format,
portal UpdatePortal_picture_type3) {
// Assumes 4:2:0 to 4:4:4 or 4:2:2 to 4:4:4
// Adding 4:4:4 support requires some additional block reordering.
if (the_chroma_format == 2) {
add MacroBlockDescrambler(width/2, 64+11, 1);
}
int vertical_upsample_factor;
if (the_chroma_format == 1) {
vertical_upsample_factor = 2;
} else {
vertical_upsample_factor = 1;
}
add DescrambleAndMotionCompensate(width,
height,
vertical_upsample_factor,
2,
UpdatePortal_picture_type,
0,
the_chroma_format,
UpdatePortal_picture_type3);
if (the_chroma_format == 1) {
add ChannelUpsample_Vert_and_Horz(width/2, height/2);
} else {
add ChannelUpsample_Horizontal(width/2, height);
}
}