/*
* 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 parse 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 Parser.str.pre
* @version 1.0
*/
/**
* Performs variable length decoding on an MPEG-2 compliant bit stream in accordance
* with the IEEE MPEG-2 specification.
* @param UpdatePortal_quantiser_data_ac The portal that recieves AC quantiser coefficient table data
* @param UpdatePortal_quantiser_data_dc The portal that recieves DC quantiser coefficient table data
* @param UpdatePortal_macroblock_intra The portal that receives intra macroblock information
* @param UpdatePortal_picture_type The portal that receives picture type information
* @param UpdatePortal_mvd The portal that needs to be notified about motion vector resets
* @param UpdatePortal_picture_type2 The portal that receives picture type information
* @input An MPEG-2 variable length encoded bitstream
* @output A series of variable length decoded macroblocks with associated motion vectors
* and messages interleaved on parser phase boundaries with updates to the state of
* the decoded data.
*/
bit->int filter MPEGStreamParser(portal UpdatePortal_quantiser_data_ac,
portal UpdatePortal_quantiser_data_dc,
portal UpdatePortal_macroblock_intra,
portal UpdatePortal_picture_type,
portal UpdatePortal_mvd,
portal UpdatePortal_picture_type2,
portal UpdatePortal_picture_type3,
int width,
int height,
int the_chroma_format) {
// FEATURETODO
// When helper functions can express their I/O rates as a function
// of their parameters, get rid of this definition and uncomment
// the definition in the filter work function, and change the
// phase PushMacroblock() to use the parameter.
int b_per_m = blocks_per_macroblock[the_chroma_format];
int[12][64] QFS; // Should be b_per_m, but b_per_m gets assigned later for some reason.
int picture_coding_type;
int macroblock_intra;
int macroblock_motion_forward;
int macroblock_motion_backward;
int[2][2][2] motion_code;
int[2][2][2] motion_residual;
int next_cfg_node;
int extension_start_code_identifier;
int chroma_format;
int block_count;
int mb_width;
int vertical_size;
boolean sequence_end_code_not_found;
boolean picture_or_group_start_code_found;
int[2][2] f_code;
int frame_pred_frame_dct;
int picture_structure;
int concealment_motion_vectors;
int intra_vlc_format;
boolean slice_start_code_follows;
int previous_macroblock_address;
int quantiser_scale_code;
int[3] dc_dct_pred; // (cite 1, P.64-65)
boolean macroblock_next;
int macroblock_address_increment;
int num_skipped_macroblocks;
int i;
int j;
int k;
init {
next_cfg_node = 0;
}
void PushMacroblock() push (b_per_m*64+19) {
for (int i = 0; i < blocks_per_macroblock[the_chroma_format]; i++) {
for (int j = 0; j < 64; j++) {
push(QFS[i][j]);
}
}
for (int r = 0; r < 2; r++)
for (int s = 0; s < 2; s++)
for (int t = 0; t < 2; t++) {
push(motion_code[r][s][t]);
}
for (int r = 0; r < 2; r++)
for (int s = 0; s < 2; s++)
for (int t = 0; t < 2; t++) {
push(motion_residual[r][s][t]);
}
push(macroblock_intra);
push(macroblock_motion_forward);
push(macroblock_motion_backward);
}
work pop * push (b_per_m*64+19) { // Actually unknown pop/push rate
int tempval = 0;
boolean pushedMacroblock = false;
while (pushedMacroblock == false) {
if (next_cfg_node == 0) {
println("Parsing M2V File...");
// video_sequence() (cite 1, P. 25)
{
int nsc_tempval;
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
while (nsc_tempval != 1) {
nsc_tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
nsc_tempval += pop();
nsc_tempval <<= 1;
}
nsc_tempval += pop();
// print("....looking for next_start_code....");
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
}
}
// sequence_header() (cite 1, P. 26)
tempval = 0;
for (int pops_i = 0; pops_i < (32-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval != 0x000001B3)
println("Error - Expected Video Sequence Start Code, Found " + tempval);
// Reading Sequence Header
int horizontal_size_value;
int vertical_size_value;
int aspect_ratio_information;
int frame_rate_code;
int bit_rate_value;
int vbv_buffer_size_value;
int constrained_parameters_flag;
int load_intra_quantiser_matrix;
int load_non_intra_quantiser_matrix;
float frame_rate_value;
int[64] intra_quantiser_matrix;
int[64] non_intra_quantiser_matrix;
// (cite 1, P.55)
horizontal_size_value = 0;
for (int pops_i = 0; pops_i < (12-1); pops_i++) {
horizontal_size_value += pop();
horizontal_size_value <<= 1;
}
horizontal_size_value += pop();
vertical_size_value = 0;
for (int pops_i = 0; pops_i < (12-1); pops_i++) {
vertical_size_value += pop();
vertical_size_value <<= 1;
}
vertical_size_value += pop();
aspect_ratio_information = 0;
for (int pops_i = 0; pops_i < (4-1); pops_i++) {
aspect_ratio_information += pop();
aspect_ratio_information <<= 1;
}
aspect_ratio_information += pop();
// (cite 1, P.41 Table 6-3)
if (aspect_ratio_information == 0)
println("Error - Forbidden Aspect Ratio");
else if (aspect_ratio_information == 1) {
// aspect_ratio_information == 1 -> aspect ratio is 1:1, this case is handled
} else {
println("Error - Program Limitation: Don't Know How to Handle Other Aspect Ratios");
println(" correct mpeg2enc parameter: 1 /* aspect_ratio_information 1=square pel, 2=4:3, 3=16:9, 4=2.11:1 */");
}
frame_rate_code = 0;
for (int pops_i = 0; pops_i < (4-1); pops_i++) {
frame_rate_code += pop();
frame_rate_code <<= 1;
}
frame_rate_code += pop();
// (cite 1, P.41-42 Table 6-4)
frame_rate_value = 0;
if (frame_rate_code == 0)
println("Error - Forbidden Frame Rate Code");
else if (frame_rate_code == 4) {
// frame_rate_code 4
frame_rate_value = 30000.0/1001.0;
}
else {
println("Error - Program Limitation: Don't Know How to Handle Other Frame Rate Codes");
println(" correct mpeg2enc parameter: 4 /* frame_rate_code 1=23.976, 2=24, 3=25, 4=29.97, 5=30 frames/sec. */");
}
bit_rate_value = 0;
for (int pops_i = 0; pops_i < (18-1); pops_i++) {
bit_rate_value += pop();
bit_rate_value <<= 1;
}
bit_rate_value += pop();
{
int marker_bit;
marker_bit = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
marker_bit += pop();
marker_bit <<= 1;
}
marker_bit += pop();
if (marker_bit != 1)
print("Error - Expected Marker Bit To Be Set");
}
vbv_buffer_size_value = 0;
for (int pops_i = 0; pops_i < (10-1); pops_i++) {
vbv_buffer_size_value += pop();
vbv_buffer_size_value <<= 1;
}
vbv_buffer_size_value += pop();
constrained_parameters_flag = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
constrained_parameters_flag += pop();
constrained_parameters_flag <<= 1;
}
constrained_parameters_flag += pop();
// (cite 1, P. 43)
if (constrained_parameters_flag != 0) {
println("Error - Expected Constrained Parameters Flag To Be 0");
println(" correct mpeg2enc parameter: 0 /* constrained_parameters_flag */");
}
// Default Values for the quantiser_matrices
// Assumes no alternate_scan TODO
load_intra_quantiser_matrix = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
load_intra_quantiser_matrix += pop();
load_intra_quantiser_matrix <<= 1;
}
load_intra_quantiser_matrix += pop();
if (load_intra_quantiser_matrix == 1) {
// println(" Loading Intra Quantiser Matrix from File");
int[64] tempOrder;
for (int i = 0; i < 64; i++) {
tempOrder[i] = 0;
for (int pops_i = 0; pops_i < (8-1); pops_i++) {
tempOrder[i] += pop();
tempOrder[i] <<= 1;
}
tempOrder[i] += pop();
}
for (int i = 0; i < 64; i++) {
// Assumes no alternate_scan TODO
intra_quantiser_matrix[i] = tempOrder[ZigZagUnorder[i]];
}
} else {
// println(" Using Default Intra Quantiser Matrix");
for (int i = 0; i < 64; i++) {
intra_quantiser_matrix[i] = default_intra_quantiser_matrix[i];
}
}
load_non_intra_quantiser_matrix = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
load_non_intra_quantiser_matrix += pop();
load_non_intra_quantiser_matrix <<= 1;
}
load_non_intra_quantiser_matrix += pop();
if (load_non_intra_quantiser_matrix == 1) {
// println(" Loading Non Intra Quantiser Matrix from File");
int[64] tempOrder;
for (int i = 0; i < 64; i++) {
tempOrder[i] = 0;
for (int pops_i = 0; pops_i < (8-1); pops_i++) {
tempOrder[i] += pop();
tempOrder[i] <<= 1;
}
tempOrder[i] += pop();
}
for (int i = 0; i < 64; i++) {
// Assumes no alternate_scan
non_intra_quantiser_matrix[i] = tempOrder[ZigZagUnorder[i]];
}
} else {
// println(" Using Default Non Intra Quantiser Matrix");
for (int i = 0; i < 64; i++) {
non_intra_quantiser_matrix[i] = default_non_intra_quantiser_matrix[i];
}
}
UpdatePortal_quantiser_data_ac.setQuantiserMatrices(intra_quantiser_matrix,
non_intra_quantiser_matrix) [0:0];
{
int nsc_tempval;
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
while (nsc_tempval != 1) {
nsc_tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
nsc_tempval += pop();
nsc_tempval <<= 1;
}
nsc_tempval += pop();
// print("....looking for next_start_code....");
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
}
}
// sequence_extension() (cite 1, P. 28)
tempval = 0;
for (int pops_i = 0; pops_i < (32-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval != 0x000001B5) {
println("Error - Expected Extension Start Code, File is MPEG-1, not MPEG-2 ");
println(" correct mpeg2enc parameter: 0 /* ISO/IEC 11172-2 stream */");
}
extension_start_code_identifier = 0;
for (int pops_i = 0; pops_i < (4-1); pops_i++) {
extension_start_code_identifier += pop();
extension_start_code_identifier <<= 1;
}
extension_start_code_identifier += pop();
if (extension_start_code_identifier != 0x1)
println("Error - Expected Sequence Extension Identifier " + extension_start_code_identifier);
int profile_and_level_indication;
profile_and_level_indication = 0;
for (int pops_i = 0; pops_i < (8-1); pops_i++) {
profile_and_level_indication += pop();
profile_and_level_indication <<= 1;
}
profile_and_level_indication += pop();
// We don't really care about the profile_and_level indicator - this matters if this implementation
// were fully MPEG2 compliant to some profile/level, but it isn't.
int progressive_sequence;
progressive_sequence = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
progressive_sequence += pop();
progressive_sequence <<= 1;
}
progressive_sequence += pop();
if (progressive_sequence == 1) {
// progressive_sequence 1: allows only progressive frames
} else {
// progressive_sequence 0: allows interlaced and progressive frames
println("Error - Program Limitation: Don't handle interlaced frames");
println(" correct mpeg2enc parameter: 1 /* progressive_sequence */");
}
chroma_format = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
chroma_format += pop();
chroma_format <<= 1;
}
chroma_format += pop();
block_count = blocks_per_macroblock[the_chroma_format]; // (cite 1, P. 62)
if (chroma_format != the_chroma_format) {
println("Error - Program specified with chroma " + the_chroma_format);
println(" File has chroma " + chroma_format);
}
int horizontal_size_extension;
int vertical_size_extension;
int bit_rate_extension;
int vbv_buffer_size_extension;
int low_delay;
int bit_rate;
int vbv_buffer_size;
float frame_rate;
int mb_height;
int horizontal_size;
horizontal_size_extension = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
horizontal_size_extension += pop();
horizontal_size_extension <<= 1;
}
horizontal_size_extension += pop();
horizontal_size = horizontal_size_value + (horizontal_size_extension << 12);
mb_width = (horizontal_size + 15) / 16;
vertical_size_extension = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
vertical_size_extension += pop();
vertical_size_extension <<= 1;
}
vertical_size_extension += pop();
vertical_size = vertical_size_value + (vertical_size_extension << 12);
mb_height = (vertical_size + 15) / 16;
bit_rate_extension = 0;
for (int pops_i = 0; pops_i < (12-1); pops_i++) {
bit_rate_extension += pop();
bit_rate_extension <<= 1;
}
bit_rate_extension += pop();
// (cite 1, P.42)
bit_rate = 400 * (bit_rate_value + (bit_rate_extension << 18));
{
int marker_bit;
marker_bit = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
marker_bit += pop();
marker_bit <<= 1;
}
marker_bit += pop();
if (marker_bit != 1)
print("Error - Expected Marker Bit To Be Set");
}
vbv_buffer_size_extension = 0;
for (int pops_i = 0; pops_i < (8-1); pops_i++) {
vbv_buffer_size_extension += pop();
vbv_buffer_size_extension <<= 1;
}
vbv_buffer_size_extension += pop();
vbv_buffer_size = vbv_buffer_size_value + (vbv_buffer_size_extension << 10);
low_delay = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
low_delay += pop();
low_delay <<= 1;
}
low_delay += pop();
if (low_delay == 1) {
// low_delay 1 indicates that sequence contains no B-pictures
println("Error - Program Limitation: Can't Handle This Case Yet");
println(" correct mpeg2enc parameter: 0 /* low_delay */");
} else {
// low_delay 0 indicates that sequence is allowed to contain B-pictures
}
int frame_rate_extension_n;
int frame_rate_extension_d;
frame_rate_extension_n = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
frame_rate_extension_n += pop();
frame_rate_extension_n <<= 1;
}
frame_rate_extension_n += pop();
frame_rate_extension_d = 0;
for (int pops_i = 0; pops_i < (5-1); pops_i++) {
frame_rate_extension_d += pop();
frame_rate_extension_d <<= 1;
}
frame_rate_extension_d += pop();
// (cite 1, P. P.41)
frame_rate = frame_rate_value *
((float) (frame_rate_extension_n + 1)) / ((float) (frame_rate_extension_d + 1));
{
int nsc_tempval;
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
while (nsc_tempval != 1) {
nsc_tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
nsc_tempval += pop();
nsc_tempval <<= 1;
}
nsc_tempval += pop();
// print("....looking for next_start_code....");
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
}
}
sequence_end_code_not_found = true;
next_cfg_node = 1;
}
else if (next_cfg_node == 1) {
// assert: sequence_end_code_not_found == true
// extension_and_user_data(0) (cite 1, P.26)
tempval = 0;
for (int peeks_i = 0; peeks_i < (32-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(32-1);
while (tempval == 0x000001B5 || tempval == 0x000001B2) {
tempval = 0;
for (int pops_i = 0; pops_i < (32-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval == 0x000001B5) {
// extension_data(0) (cite 1, P.27)
tempval = 0;
for (int peeks_i = 0; peeks_i < (4-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(4-1);
if (tempval == 2) { // extension_start_code_identifier
int video_format;
int color_description;
int color_primaries;
int transfer_characteristics;
int matrix_coefficients;
int display_horizontal_size;
int display_vertical_size;
tempval = 0;
for (int pops_i = 0; pops_i < (4-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
video_format = 0;
for (int pops_i = 0; pops_i < (3-1); pops_i++) {
video_format += pop();
video_format <<= 1;
}
video_format += pop();
color_description = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
color_description += pop();
color_description <<= 1;
}
color_description += pop();
if (color_description == 1) {
color_primaries = 0;
for (int pops_i = 0; pops_i < (8-1); pops_i++) {
color_primaries += pop();
color_primaries <<= 1;
}
color_primaries += pop();
transfer_characteristics = 0;
for (int pops_i = 0; pops_i < (8-1); pops_i++) {
transfer_characteristics += pop();
transfer_characteristics <<= 1;
}
transfer_characteristics += pop();
matrix_coefficients = 0;
for (int pops_i = 0; pops_i < (8-1); pops_i++) {
matrix_coefficients += pop();
matrix_coefficients <<= 1;
}
matrix_coefficients += pop();
}
display_horizontal_size = 0;
for (int pops_i = 0; pops_i < (14-1); pops_i++) {
display_horizontal_size += pop();
display_horizontal_size <<= 1;
}
display_horizontal_size += pop();
{
int marker_bit;
marker_bit = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
marker_bit += pop();
marker_bit <<= 1;
}
marker_bit += pop();
if (marker_bit != 1)
print("Error - Expected Marker Bit To Be Set");
}
display_vertical_size = 0;
for (int pops_i = 0; pops_i < (14-1); pops_i++) {
display_vertical_size += pop();
display_vertical_size <<= 1;
}
display_vertical_size += pop();
// TODO - we don't do anything with this extra data we get out. Eventually we should.
{
int nsc_tempval;
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
while (nsc_tempval != 1) {
nsc_tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
nsc_tempval += pop();
nsc_tempval <<= 1;
}
nsc_tempval += pop();
// print("....looking for next_start_code....");
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
}
}
} else {
println("Error - Program Limitation: Not Yet Support for Sequence Scalable Extension()");
}
} else { // user_data() (cite 1, P.27)
if (tempval != 0x000001B2) {
println("Error - Program Limitation: Not Yet Support for User_Data()");
}
tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(24-1);
while (tempval != 0x000001) {
int user_data;
user_data = 0;
for (int pops_i = 0; pops_i < (8-1); pops_i++) {
user_data += pop();
user_data <<= 1;
}
user_data += pop();
// TODO we should probably do something with this data
tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(24-1);
}
{
int nsc_tempval;
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
while (nsc_tempval != 1) {
nsc_tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
nsc_tempval += pop();
nsc_tempval <<= 1;
}
nsc_tempval += pop();
// print("....looking for next_start_code....");
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
}
}
}
tempval = 0;
for (int peeks_i = 0; peeks_i < (32-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(32-1);
}
picture_or_group_start_code_found = true;
next_cfg_node = 3;
}
else if (next_cfg_node == 3) {
// assert: picture_or_group_start_code_found == true
tempval = 0;
for (int peeks_i = 0; peeks_i < (32-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(32-1);
if (tempval == 0x000001B8) {
// group_of_pictures_header() (cite 1, P.29)
tempval = 0;
for (int pops_i = 0; pops_i < (32-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
// -- Time Code - Not Used in Decoding Process --
// (cite 1, P.49)
int drop_frame_flag;
int time_code_hours;
int time_code_minutes;
int time_code_seconds;
int time_code_pictures;
int closed_gop;
int broken_link;
drop_frame_flag = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
drop_frame_flag += pop();
drop_frame_flag <<= 1;
}
drop_frame_flag += pop();
time_code_hours = 0;
for (int pops_i = 0; pops_i < (5-1); pops_i++) {
time_code_hours += pop();
time_code_hours <<= 1;
}
time_code_hours += pop();
time_code_minutes = 0;
for (int pops_i = 0; pops_i < (6-1); pops_i++) {
time_code_minutes += pop();
time_code_minutes <<= 1;
}
time_code_minutes += pop();
{
int marker_bit;
marker_bit = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
marker_bit += pop();
marker_bit <<= 1;
}
marker_bit += pop();
if (marker_bit != 1)
print("Error - Expected Marker Bit To Be Set");
}
time_code_seconds = 0;
for (int pops_i = 0; pops_i < (6-1); pops_i++) {
time_code_seconds += pop();
time_code_seconds <<= 1;
}
time_code_seconds += pop();
time_code_pictures = 0;
for (int pops_i = 0; pops_i < (6-1); pops_i++) {
time_code_pictures += pop();
time_code_pictures <<= 1;
}
time_code_pictures += pop();
// -- End of Time Code
closed_gop = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
closed_gop += pop();
closed_gop <<= 1;
}
closed_gop += pop();
broken_link = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
broken_link += pop();
broken_link <<= 1;
}
broken_link += pop();
if (broken_link == 1)
println("Error - Program Limitation: broken_link = 1");
{
int nsc_tempval;
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
while (nsc_tempval != 1) {
nsc_tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
nsc_tempval += pop();
nsc_tempval <<= 1;
}
nsc_tempval += pop();
// print("....looking for next_start_code....");
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
}
}
// extension_and_user_data(1) (cite 1, P.26)
tempval = 0;
for (int peeks_i = 0; peeks_i < (32-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(32-1);
if (tempval == 0x000001B5 || tempval == 0x000001B2)
println("Error - Program Limitation: Not Yet Support for extension_and_user_data(1)");
}
// picture_header() (cite 1, P.30)
tempval = 0;
for (int pops_i = 0; pops_i < (32-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval != 0x00000100) {
println("Error - Picture Start Code Expected, " + tempval);
}
// (cite 1, P.50) for interpretation of the following fields
int temporal_reference;
temporal_reference = 0;
for (int pops_i = 0; pops_i < (10-1); pops_i++) {
temporal_reference += pop();
temporal_reference <<= 1;
}
temporal_reference += pop();
picture_coding_type = 0;
for (int pops_i = 0; pops_i < (3-1); pops_i++) {
picture_coding_type += pop();
picture_coding_type <<= 1;
}
picture_coding_type += pop();
if (picture_coding_type == 1) {
// picture_coding_type = I-picture
} else if (picture_coding_type == 2) {
// picture_coding_type = P-picture
} else if (picture_coding_type == 3) {
// picture_coding_type = B-picture
} else {
println(" Error: Forbidden picture_coding_type " + picture_coding_type);
}
UpdatePortal_picture_type.setPictureType(picture_coding_type) [0:0];
UpdatePortal_picture_type2.setPictureType(picture_coding_type) [0:0];
UpdatePortal_picture_type3.setPictureType(picture_coding_type) [0:0];
int vbv_delay;
vbv_delay = 0;
for (int pops_i = 0; pops_i < (16-1); pops_i++) {
vbv_delay += pop();
vbv_delay <<= 1;
}
vbv_delay += pop();
int full_pel_forward_vector;
int forward_f_code;
int full_pel_backward_vector;
int backward_f_code;
// TODO unknown interpretation for vbv_delay, (cite 1, P.50)
// The following is not used by the MPEG-2 specification (cite 1, P.51)
// Supposed to have certain values, but not guaranteed for most files.
if (picture_coding_type == 2 || picture_coding_type == 3) {
full_pel_forward_vector = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
full_pel_forward_vector += pop();
full_pel_forward_vector <<= 1;
}
full_pel_forward_vector += pop();
forward_f_code = 0;
for (int pops_i = 0; pops_i < (3-1); pops_i++) {
forward_f_code += pop();
forward_f_code <<= 1;
}
forward_f_code += pop();
}
if (picture_coding_type == 3) {
full_pel_backward_vector = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
full_pel_backward_vector += pop();
full_pel_backward_vector <<= 1;
}
full_pel_backward_vector += pop();
backward_f_code = 0;
for (int pops_i = 0; pops_i < (3-1); pops_i++) {
backward_f_code += pop();
backward_f_code <<= 1;
}
backward_f_code += pop();
}
tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval == 1)
println("Error: File conforms to some superset of the MPEG-2 specification");
{
int nsc_tempval;
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
while (nsc_tempval != 1) {
nsc_tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
nsc_tempval += pop();
nsc_tempval <<= 1;
}
nsc_tempval += pop();
// print("....looking for next_start_code....");
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
}
}
// picture_coding_extension() (cite 1, P.30)
tempval = 0;
for (int pops_i = 0; pops_i < (32-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval != 0x000001B5)
println("Error - Expecting extension start code " + tempval);
extension_start_code_identifier = 0;
for (int pops_i = 0; pops_i < (4-1); pops_i++) {
extension_start_code_identifier += pop();
extension_start_code_identifier <<= 1;
}
extension_start_code_identifier += pop();
if (extension_start_code_identifier != 0x8)
println("Error - Expecting picture coding extension ID " + extension_start_code_identifier);
f_code[0][0] = 0;
for (int pops_i = 0; pops_i < (4-1); pops_i++) {
f_code[0][0] += pop();
f_code[0][0] <<= 1;
}
f_code[0][0] += pop();
f_code[0][1] = 0;
for (int pops_i = 0; pops_i < (4-1); pops_i++) {
f_code[0][1] += pop();
f_code[0][1] <<= 1;
}
f_code[0][1] += pop();
f_code[1][0] = 0;
for (int pops_i = 0; pops_i < (4-1); pops_i++) {
f_code[1][0] += pop();
f_code[1][0] <<= 1;
}
f_code[1][0] += pop();
f_code[1][1] = 0;
for (int pops_i = 0; pops_i < (4-1); pops_i++) {
f_code[1][1] += pop();
f_code[1][1] <<= 1;
}
f_code[1][1] += pop();
UpdatePortal_mvd.setFCode(f_code) [0:0];
// (cite 1, P.51)
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
if (f_code[i][j] == 0 || (f_code[i][j] >= 10 && f_code[i][j] <= 14))
println("Error - Invalid f_code");
if (picture_coding_type == 1 && f_code[i][j] != 0xF)
println("Error - Program Limitation: I-frame has motion prediction");
if (picture_coding_type == 2 && f_code[1][j] != 0xF)
println("Error - Program Limitation: P-frame has backward motion prediction");
}
}
int intra_dc_precision;
int top_field_first;
int q_scale_type;
int alternate_scan;
int repeat_first_field;
int chroma_420_type;
int progressive_frame;
int composite_display_flag;
int actual_intra_dc_precision;
intra_dc_precision = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
intra_dc_precision += pop();
intra_dc_precision <<= 1;
}
intra_dc_precision += pop();
UpdatePortal_quantiser_data_dc.setIntraDCPrecision(intra_dc_precision);
actual_intra_dc_precision = intra_dc_precision + 8;
picture_structure = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
picture_structure += pop();
picture_structure <<= 1;
}
picture_structure += pop();
if (picture_structure != 3)
println("Error - Program Limitation: Interlaced or bad picture structure");
top_field_first = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
top_field_first += pop();
top_field_first <<= 1;
}
top_field_first += pop(); // Interpreted Later
frame_pred_frame_dct = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
frame_pred_frame_dct += pop();
frame_pred_frame_dct <<= 1;
}
frame_pred_frame_dct += pop();
if (frame_pred_frame_dct != 1)
println("Error - Program Limitation or Bad Syntax: frame_pred_frame_dct must be 1");
concealment_motion_vectors = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
concealment_motion_vectors += pop();
concealment_motion_vectors <<= 1;
}
concealment_motion_vectors += pop();
q_scale_type = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
q_scale_type += pop();
q_scale_type <<= 1;
}
q_scale_type += pop();
UpdatePortal_quantiser_data_ac.setQScaleType(q_scale_type) [0:0];
intra_vlc_format = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
intra_vlc_format += pop();
intra_vlc_format <<= 1;
}
intra_vlc_format += pop();
alternate_scan = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
alternate_scan += pop();
alternate_scan <<= 1;
}
alternate_scan += pop();
if (alternate_scan == 1)
println("Error - Program Limitation - Doesn't handle alternate_scan right now");
repeat_first_field = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
repeat_first_field += pop();
repeat_first_field <<= 1;
}
repeat_first_field += pop();
// TODO Assumes progressive_sequence = 1
if (repeat_first_field == 0) {
// repeat_first_field = 0, one frame output
}
else {
if (top_field_first == 0)
println(" repeat_first_field = 1, top_field_first = 0, two frames output");
else
println(" repeat_first_field = 1, top_field_first = 1, three frames output");
}
chroma_420_type = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
chroma_420_type += pop();
chroma_420_type <<= 1;
}
chroma_420_type += pop();
// We don't really care about this, although it should be 1 for 4:2:0 chroma.
// (cite 1, P.53)
progressive_frame = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
progressive_frame += pop();
progressive_frame <<= 1;
}
progressive_frame += pop();
// Again, I don't think we care too much about this value, since we assume only a
// base stream exists.
composite_display_flag = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
composite_display_flag += pop();
composite_display_flag <<= 1;
}
composite_display_flag += pop();
if (composite_display_flag == 1) {
println("Error - Program Limitation: Assumes no composite display information");
} else {
// composite_display_flag - not present
}
{
int nsc_tempval;
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
while (nsc_tempval != 1) {
nsc_tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
nsc_tempval += pop();
nsc_tempval <<= 1;
}
nsc_tempval += pop();
// print("....looking for next_start_code....");
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
}
}
// extension_and_user_data(2)
tempval = 0;
for (int peeks_i = 0; peeks_i < (32-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(32-1);
if (tempval == 0x000001B5 || tempval == 0x000001B2)
println("Error - Program Limitation: Not Yet Support for extension_and_user_data(2)");
// picture_data() (cite 1, P.34)
slice_start_code_follows = true;
previous_macroblock_address = -1;
next_cfg_node = 5;
}
else if (next_cfg_node == 5) {
// assert: slice_start_code_follows == true
// slice() (cite 1, P.34)
// Reset motion vector predictors, (cite 1, P.77-80)
UpdatePortal_mvd.resetPredictors() [0:0];
tempval = 0;
for (int pops_i = 0; pops_i < (24-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval != 0x000001)
println("Error - Expecting slice_start_code " + tempval);
int slice_vertical_position;
slice_vertical_position = 0;
for (int pops_i = 0; pops_i < (8-1); pops_i++) {
slice_vertical_position += pop();
slice_vertical_position <<= 1;
}
slice_vertical_position += pop();
if (slice_vertical_position < 0x01 || slice_vertical_position > 0xAF)
println("Error - Invalid slice_vertical_position" + slice_vertical_position);
if (vertical_size > 2800)
println("Error - Program Limitation: Doesn't handle vertical_sizes > 2800");
int mb_row;
mb_row = slice_vertical_position - 1;
previous_macroblock_address = (mb_row * mb_width) - 1;
quantiser_scale_code = 0;
for (int pops_i = 0; pops_i < (5-1); pops_i++) {
quantiser_scale_code += pop();
quantiser_scale_code <<= 1;
}
quantiser_scale_code += pop();
UpdatePortal_quantiser_data_ac.setQuantiserScaleCode(quantiser_scale_code) [0:0];
tempval = 0;
for (int peeks_i = 0; peeks_i < (1-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(1-1);
if (tempval == 1)
println("Error - Program Limitation: Doesn't handle intra_slice_flag");
tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval == 1)
println("Error - Extra_bit_slice must be 0");
// I'm not sure about this - see P. 64 and getpic.c Line 1180
// they disagree TODO
dc_dct_pred[0] = 0; // (int) pow(2,actual_intra_dc_precision - 1);
dc_dct_pred[1] = 0; // (int) pow(2,actual_intra_dc_precision - 1);
dc_dct_pred[2] = 0; // (int) pow(2,actual_intra_dc_precision - 1);
macroblock_next = true;
next_cfg_node = 7;
}
else if (next_cfg_node == 7) {
// assert: macroblock_next == true
// macroblock() (cite 1, P.35)
int macroblock_escape;
macroblock_escape = 0;
tempval = 0;
for (int peeks_i = 0; peeks_i < (11-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(11-1);
while (tempval == 8) {
tempval = 0;
for (int pops_i = 0; pops_i < (11-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
macroblock_escape += 33;
tempval = 0;
for (int peeks_i = 0; peeks_i < (11-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(11-1);
}
{
boolean found = false;
int guesslength = 1;
int tablepos = 0;
while (!found) {
tempval = 0;
for (int peeks_i = 0; peeks_i < (guesslength-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(guesslength-1);
tablepos = 0;
while (!found && tablepos < const_macroblock_address_inc_len) {
if (tempval == const_macroblock_address_inc[tablepos].code && guesslength == const_macroblock_address_inc[tablepos].len) {
found = true;
tempval = 0;
for (int pops_i = 0; pops_i < (guesslength-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
} else {
tablepos++;
}
}
guesslength++;
}
tempval = const_macroblock_address_inc[tablepos].value;
}
macroblock_address_increment = tempval + macroblock_escape;
if (macroblock_address_increment > 1)
next_cfg_node = 8;
else
next_cfg_node = 12;
}
else if (next_cfg_node == 8) {
num_skipped_macroblocks = macroblock_address_increment - 1;
for (int i = 0; i < blocks_per_macroblock[the_chroma_format]; i++) {
for (int j = 0; j < 64; j++) {
QFS[i][j] = 0;
}
}
for (int r = 0; r < 2; r++)
for (int s = 0; s < 2; s++)
for (int t = 0; t < 2; t++) {
motion_code[r][s][t] = 0;
}
for (int r = 0; r < 2; r++)
for (int s = 0; s < 2; s++)
for (int t = 0; t < 2; t++) {
motion_residual[r][s][t] = 0;
}
if (picture_coding_type == 2) { // [cite 1, P. 80]
// UpdatePortal_mvd.resetPredictors() [0:0];
}
macroblock_intra = 0;
macroblock_motion_forward = 0;
macroblock_motion_backward = 0;
k = 0;
next_cfg_node = 9;
}
else if (next_cfg_node == 9) {
// assert: k < num_skipped_macroblocks
PushMacroblock();
pushedMacroblock = true;
k++;
if (k < num_skipped_macroblocks)
next_cfg_node = 9;
else
next_cfg_node = 12;
}
else if (next_cfg_node == 12) {
int macroblock_address;
macroblock_address = previous_macroblock_address + macroblock_address_increment;
previous_macroblock_address = macroblock_address;
int mb_column;
mb_column = macroblock_address % mb_width;
// TODO - Don't actually check to make sure that macroblocks are skipped which aren't
// allowed to be skipped - this should be done, the rules are on (cite 1, P.60)
// macroblock_modes, (cite 1, P.36)
// TODO - If a sequence_scalable_extension present in bitstream, then may possibly
// need to use tables B5,6,7,8 as well.
if (picture_coding_type == 1) { // I-picture
{
boolean found = false;
int guesslength = 1;
int tablepos = 0;
while (!found) {
tempval = 0;
for (int peeks_i = 0; peeks_i < (guesslength-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(guesslength-1);
tablepos = 0;
while (!found && tablepos < const_macroblock_type_Ipictures_len) {
if (tempval == const_macroblock_type_Ipictures[tablepos].code && guesslength == const_macroblock_type_Ipictures[tablepos].len) {
found = true;
tempval = 0;
for (int pops_i = 0; pops_i < (guesslength-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
} else {
tablepos++;
}
}
guesslength++;
}
tempval = const_macroblock_type_Ipictures[tablepos].value;
}
} else if (picture_coding_type == 2) { // P-picture
{
boolean found = false;
int guesslength = 1;
int tablepos = 0;
while (!found) {
tempval = 0;
for (int peeks_i = 0; peeks_i < (guesslength-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(guesslength-1);
tablepos = 0;
while (!found && tablepos < const_macroblock_type_Ppictures_len) {
if (tempval == const_macroblock_type_Ppictures[tablepos].code && guesslength == const_macroblock_type_Ppictures[tablepos].len) {
found = true;
tempval = 0;
for (int pops_i = 0; pops_i < (guesslength-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
} else {
tablepos++;
}
}
guesslength++;
}
tempval = const_macroblock_type_Ppictures[tablepos].value;
}
} else if (picture_coding_type == 3) { // B-picture
{
boolean found = false;
int guesslength = 1;
int tablepos = 0;
while (!found) {
tempval = 0;
for (int peeks_i = 0; peeks_i < (guesslength-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(guesslength-1);
tablepos = 0;
while (!found && tablepos < const_macroblock_type_Bpictures_len) {
if (tempval == const_macroblock_type_Bpictures[tablepos].code && guesslength == const_macroblock_type_Bpictures[tablepos].len) {
found = true;
tempval = 0;
for (int pops_i = 0; pops_i < (guesslength-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
} else {
tablepos++;
}
}
guesslength++;
}
tempval = const_macroblock_type_Bpictures[tablepos].value;
}
}
int spatial_temporal_weight_code_flag;
int macroblock_quant;
int macroblock_pattern;
spatial_temporal_weight_code_flag = tempval & 0x01;
tempval >>= 1;
macroblock_intra = tempval & 0x01;
UpdatePortal_macroblock_intra.setMacroblockIntra(macroblock_intra) [0:0];
tempval >>= 1;
macroblock_pattern = tempval & 0x01;
tempval >>= 1;
macroblock_motion_backward = tempval & 0x01;
tempval >>= 1;
macroblock_motion_forward = tempval & 0x01;
tempval >>= 1;
macroblock_quant = tempval & 0x01;
if (spatial_temporal_weight_code_flag == 1)
println("Error - Program Limitation - Expects spatial_temporal_weight_code_flag to be 0");
// (cite 1, P.60, Table 6-17)
int prediction_type;
prediction_type = 0; // 0 = reserved, 1 = field-based, 2=frame-based, 3=dual-prime
int motion_vector_count;
motion_vector_count = 0;
int mv_format;
mv_format = 0; // 0 = field, 1 = frame
int dmv;
dmv = 0;
if (frame_pred_frame_dct == 1) {
// See comments on P.60 regarding what happens if frame_motion_type
// is omitted.
prediction_type = 2;
motion_vector_count = 1;
mv_format = 1;
dmv = 0;
}
if (macroblock_motion_forward == 1 || macroblock_motion_backward == 1) {
if (picture_structure == 3) {
if (frame_pred_frame_dct == 0) {
// (cite 1, P.60, Table 6-17)
tempval = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval == 0) {
println("Error - Invalid frame_motion_type code");
} else if (tempval == 1) {
if (spatial_temporal_weight_code_flag < 2) {
println("Error - Don't handle this case of frame_motion_type");
} else {
println("Error - Don't handle this case of frame_motion_type");
}
} else if (tempval == 2) {
prediction_type = 2;
motion_vector_count = 1;
mv_format = 1;
dmv = 0;
} else if (tempval == 3) {
prediction_type = 3;
motion_vector_count = 1;
mv_format = 0;
dmv = 1;
}
if (prediction_type == 0)
println("Error - Invalid prediction_type");
else if (prediction_type == 1)
println(" prediction_type field-based");
else if (prediction_type == 2)
println(" prediction_type frame-based");
else if (prediction_type == 3)
println(" prediction_type dual-prime");
println(" motion_vector_count " + motion_vector_count);
if (mv_format == 0)
println(" mv_format field");
else
println(" mv_format frame");
println(" dmv " + dmv);
}
} else {
println("Error - Program Limitation: Doesn't handle this case");
}
}
if ((picture_structure == 3) && (frame_pred_frame_dct == 0) && ((macroblock_intra == 1) || (macroblock_pattern == 1)))
println("Error - Program Limitation, Doesn't Handle This Particular Case");
if (macroblock_quant == 1) {
quantiser_scale_code = 0;
for (int pops_i = 0; pops_i < (5-1); pops_i++) {
quantiser_scale_code += pop();
quantiser_scale_code <<= 1;
}
quantiser_scale_code += pop();
UpdatePortal_quantiser_data_ac.setQuantiserScaleCode(quantiser_scale_code) [0:0];
}
/* int[2][2][2] motion_code;
int[2][2][2] motion_residual; FEATURETODO */
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++) {
motion_code[i][j][k] = 0;
motion_residual[i][j][k] = 0;
}
// Motion Vector Predictor Reset, (cite 1, P.80)
if ((macroblock_intra == 1 && concealment_motion_vectors == 0) ||
(macroblock_intra == 0 && macroblock_motion_forward == 0 &&
picture_coding_type == 2)) {
UpdatePortal_mvd.resetPredictors() [0:0];
}
if (macroblock_motion_forward == 1 ||
(macroblock_intra == 1 && concealment_motion_vectors == 1)) {
// motion_vectors(0); (cite 1, P.36, 61)
if (motion_vector_count == 1) {
if ((mv_format == 0) && (dmv != 1)) {
println("Error - Program Limitation: Don't handle this case with mv_format and dmv.");
println("mv_format " + mv_format + " dmv " + dmv);
}
// motion_vector(0,0);
// (cite 1, P.61)
for (int t = 0; t < 2; t++) {
{
boolean found = false;
int guesslength = 1;
int tablepos = 0;
while (!found) {
motion_code[0][0][t] = 0;
for (int peeks_i = 0; peeks_i < (guesslength-1); peeks_i++) {
motion_code[0][0][t] += peek(peeks_i);
motion_code[0][0][t] <<= 1;
}
motion_code[0][0][t] += peek(guesslength-1);
tablepos = 0;
while (!found && tablepos < const_motion_code_len) {
if (motion_code[0][0][t] == const_motion_code[tablepos].code && guesslength == const_motion_code[tablepos].len) {
found = true;
motion_code[0][0][t] = 0;
for (int pops_i = 0; pops_i < (guesslength-1); pops_i++) {
motion_code[0][0][t] += pop();
motion_code[0][0][t] <<= 1;
}
motion_code[0][0][t] += pop();
} else {
tablepos++;
}
}
guesslength++;
}
motion_code[0][0][t] = const_motion_code[tablepos].value;
}
if ((f_code[0][t] != 1) && (motion_code[0][0][t] != 0)) {
int r_size = f_code[0][t]-1;
motion_residual[0][0][t] = 0;
for (int pops_i = 0; pops_i < (r_size-1); pops_i++) {
motion_residual[0][0][t] += pop();
motion_residual[0][0][t] <<= 1;
}
motion_residual[0][0][t] += pop();
}
if (dmv == 1) {
println("Error - Program Limitation: Don't handle case of dmv = 1");
}
}
} else {
println("Error - Program Limitation: Don't handle field motion vectors");
}
}
if (macroblock_motion_backward == 1) {
// motion_vectors(1); (cite 1, P.36, 61)
if (motion_vector_count == 1) {
if ((mv_format == 0) && (dmv != 1)) {
println("Error - Program Limitation: Don't handle this case with mv_format and dmv.");
println("mv_format " + mv_format + " dmv " + dmv);
}
// motion_vector(0,1);
// (cite 1, P.61)
for (int t = 0; t < 2; t++) {
{
boolean found = false;
int guesslength = 1;
int tablepos = 0;
while (!found) {
motion_code[0][1][t] = 0;
for (int peeks_i = 0; peeks_i < (guesslength-1); peeks_i++) {
motion_code[0][1][t] += peek(peeks_i);
motion_code[0][1][t] <<= 1;
}
motion_code[0][1][t] += peek(guesslength-1);
tablepos = 0;
while (!found && tablepos < const_motion_code_len) {
if (motion_code[0][1][t] == const_motion_code[tablepos].code && guesslength == const_motion_code[tablepos].len) {
found = true;
motion_code[0][1][t] = 0;
for (int pops_i = 0; pops_i < (guesslength-1); pops_i++) {
motion_code[0][1][t] += pop();
motion_code[0][1][t] <<= 1;
}
motion_code[0][1][t] += pop();
} else {
tablepos++;
}
}
guesslength++;
}
motion_code[0][1][t] = const_motion_code[tablepos].value;
}
if ((f_code[1][t] != 1) && (motion_code[0][1][t] != 0)) {
int r_size = f_code[1][t]-1;
motion_residual[0][1][t] = 0;
for (int pops_i = 0; pops_i < (r_size-1); pops_i++) {
motion_residual[0][1][t] += pop();
motion_residual[0][1][t] <<= 1;
}
motion_residual[0][1][t] += pop();
}
if (dmv == 1) {
println("Error - Program Limitation: Don't handle the case of dmv = 1");
}
}
}
}
if (macroblock_intra == 1 && concealment_motion_vectors == 1) {
{
int marker_bit;
marker_bit = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
marker_bit += pop();
marker_bit <<= 1;
}
marker_bit += pop();
if (marker_bit != 1)
print("Error - Expected Marker Bit To Be Set");
}
}
// The meaning of pattern_code is defined somewhat poorly
// on (cite 1, P.62) in the code block
int[12] pattern_code;
for (int i = 0; i < 12; i++) {
if (macroblock_intra == 1) {
pattern_code[i] = 1;
} else {
pattern_code[i] = 0;
}
}
if (macroblock_pattern == 1) {
// coded_block_pattern() (cite 1, P.37, 62)
int cbp;
{
boolean found = false;
int guesslength = 1;
int tablepos = 0;
while (!found) {
cbp = 0;
for (int peeks_i = 0; peeks_i < (guesslength-1); peeks_i++) {
cbp += peek(peeks_i);
cbp <<= 1;
}
cbp += peek(guesslength-1);
tablepos = 0;
while (!found && tablepos < const_coded_block_patterns_len) {
if (cbp == const_coded_block_patterns[tablepos].code && guesslength == const_coded_block_patterns[tablepos].len) {
found = true;
cbp = 0;
for (int pops_i = 0; pops_i < (guesslength-1); pops_i++) {
cbp += pop();
cbp <<= 1;
}
cbp += pop();
} else {
tablepos++;
}
}
guesslength++;
}
cbp = const_coded_block_patterns[tablepos].value;
}
for (int i = 0; i < 6; i++) {
if ((cbp & (1 << (5-i))) > 0)
pattern_code[i] = 1;
}
if (chroma_format == 1 && cbp == 0) {
println("Error - cbp not allowed to be zero in 4:2:0 format");
}
if (chroma_format == 2) {
int coded_block_pattern_1;
coded_block_pattern_1 = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
coded_block_pattern_1 += pop();
coded_block_pattern_1 <<= 1;
}
coded_block_pattern_1 += pop();
for (int i = 6; i < 8; i++) {
if ((coded_block_pattern_1 & (1<< (7-i))) > 0)
pattern_code[i] = 1;
}
}
if (chroma_format == 3) {
println("Error - Program Limitation: Doesn't handle 4:4:4 format");
}
}
for (int i = 0; i < block_count; i++) {
int QFS_current;
QFS_current = 0;
for (int j = 0; j < 64; j++) {
QFS[i][j] = 0;
}
// block(i) (cite 1, P.38)
// if macroblocks are skipped, predictor is reset
if (pattern_code[i] == 1) {
if (macroblock_intra == 1) {
int dct_diff;
int half_range;
if (i < 4) {
int dc_dct_size_luminance;
int dc_dct_differential_luminance;
int dc_dct_luminance;
{
boolean found = false;
int guesslength = 1;
int tablepos = 0;
while (!found) {
dc_dct_size_luminance = 0;
for (int peeks_i = 0; peeks_i < (guesslength-1); peeks_i++) {
dc_dct_size_luminance += peek(peeks_i);
dc_dct_size_luminance <<= 1;
}
dc_dct_size_luminance += peek(guesslength-1);
tablepos = 0;
while (!found && tablepos < const_dct_dc_size_luminance_len) {
if (dc_dct_size_luminance == const_dct_dc_size_luminance[tablepos].code && guesslength == const_dct_dc_size_luminance[tablepos].len) {
found = true;
dc_dct_size_luminance = 0;
for (int pops_i = 0; pops_i < (guesslength-1); pops_i++) {
dc_dct_size_luminance += pop();
dc_dct_size_luminance <<= 1;
}
dc_dct_size_luminance += pop();
} else {
tablepos++;
}
}
guesslength++;
}
dc_dct_size_luminance = const_dct_dc_size_luminance[tablepos].value;
}
// This next section from (cite 1, P.65)
if (dc_dct_size_luminance == 0) {
dct_diff = 0;
} else {
dc_dct_differential_luminance = 0;
for (int pops_i = 0; pops_i < (dc_dct_size_luminance-1); pops_i++) {
dc_dct_differential_luminance += pop();
dc_dct_differential_luminance <<= 1;
}
dc_dct_differential_luminance += pop();
half_range = (int) pow(2,dc_dct_size_luminance-1);
if (dc_dct_differential_luminance >= half_range) {
dct_diff = dc_dct_differential_luminance;
} else {
dct_diff = (dc_dct_differential_luminance + 1) - (2*half_range);
}
}
dc_dct_luminance = dc_dct_pred[0] + dct_diff;
dc_dct_pred[0] = dc_dct_luminance;
QFS[i][0] = dc_dct_luminance;
QFS_current = 1;
} else {
int dc_dct_size_chrominance;
int dc_dct_differential_chrominance;
int dc_dct_chrominance;
// Other ones
{
boolean found = false;
int guesslength = 1;
int tablepos = 0;
while (!found) {
dc_dct_size_chrominance = 0;
for (int peeks_i = 0; peeks_i < (guesslength-1); peeks_i++) {
dc_dct_size_chrominance += peek(peeks_i);
dc_dct_size_chrominance <<= 1;
}
dc_dct_size_chrominance += peek(guesslength-1);
tablepos = 0;
while (!found && tablepos < const_dct_dc_size_chrominance_len) {
if (dc_dct_size_chrominance == const_dct_dc_size_chrominance[tablepos].code && guesslength == const_dct_dc_size_chrominance[tablepos].len) {
found = true;
dc_dct_size_chrominance = 0;
for (int pops_i = 0; pops_i < (guesslength-1); pops_i++) {
dc_dct_size_chrominance += pop();
dc_dct_size_chrominance <<= 1;
}
dc_dct_size_chrominance += pop();
} else {
tablepos++;
}
}
guesslength++;
}
dc_dct_size_chrominance = const_dct_dc_size_chrominance[tablepos].value;
}
if (dc_dct_size_chrominance == 0) {
dct_diff = 0;
} else {
dc_dct_differential_chrominance = 0;
for (int pops_i = 0; pops_i < (dc_dct_size_chrominance-1); pops_i++) {
dc_dct_differential_chrominance += pop();
dc_dct_differential_chrominance <<= 1;
}
dc_dct_differential_chrominance += pop();
half_range = (int) pow(2,dc_dct_size_chrominance-1);
if (dc_dct_differential_chrominance >= half_range) {
dct_diff = dc_dct_differential_chrominance;
} else {
dct_diff = (dc_dct_differential_chrominance + 1) - (2*half_range);
}
}
// Blocks 4, 6, 8, and 10 go into [1]
// Blocks 5, 7, 9, 11 go into [2]
int temp_index;
temp_index = (i % 2) + 1;
dc_dct_chrominance = dc_dct_pred[temp_index] + dct_diff;
dc_dct_pred[temp_index] = dc_dct_chrominance;
QFS[i][0] = dc_dct_chrominance;
QFS_current = 1;
}
} else {
// I don't think we really need to do anything here... if we let this just
// fall through it should get handled in the next section, right?
// Reset predictors, (cite 1, P. 64)
dc_dct_pred[0] = 0;
dc_dct_pred[1] = 0;
dc_dct_pred[2] = 0;
}
if (intra_vlc_format == 1 && macroblock_intra == 1)
println("Error - Program Limitation: Need to use B15 to decode DCT coefficients instead of B14");
while (QFS_current < 64) {
if (macroblock_intra == 0 && QFS_current == 0) {
// This section here from end of Table B.14 and 7.2.2.2 (cite 1, P.66)
tempval = 0;
for (int peeks_i = 0; peeks_i < (1-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(1-1);
if (tempval == 1) {
tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval == 0)
QFS[i][0] = 1;
else
QFS[i][0] = -1;
QFS_current += 1;
}
}
tempval = 0;
for (int peeks_i = 0; peeks_i < (2-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(2-1);
if (tempval == 2) {
tempval = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
QFS_current = 64;
} else {
int signed_level;
int run;
int level;
int sign;
signed_level = 0;
run = 0;
tempval = 0;
for (int peeks_i = 0; peeks_i < (6-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(6-1);
if (tempval == 1) {
// Escape Code
tempval = 0;
for (int pops_i = 0; pops_i < (6-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
level = 0;
sign = 0;
run = 0;
for (int pops_i = 0; pops_i < (6-1); pops_i++) {
run += pop();
run <<= 1;
}
run += pop();
sign = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
sign += pop();
sign <<= 1;
}
sign += pop();
level = 0;
for (int pops_i = 0; pops_i < (11-1); pops_i++) {
level += pop();
level <<= 1;
}
level += pop();
if (sign == 0) {
signed_level = level;
} else {
signed_level = level - 2048;
}
} else {
// Regular Code
level = 0;
sign = 0;
// The old. inefficient way: v ariable_length_code_dct(run,level,const_dct_coefficients_table_zero);
// begin variable length code
tempval = 0;
for (int peeks_i = 0; peeks_i < (16-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(16-1);
// if (tempval >= 49152 && tempval <= 65535) { // 2
if (tempval >= 49152) {
tempval = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len2[0].run;
level = const_dct_coefficients_table_zero_len2[0].level;
// } else if (tempval >= 24576 && tempval <= 32767) { // 3
} else if (tempval >= 24576) {
tempval = 0;
for (int pops_i = 0; pops_i < (3-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len3[0].run;
level = const_dct_coefficients_table_zero_len3[0].level;
// } else if (tempval >= 16384 && tempval <= 24575) { // 4
} else if (tempval >= 16384) {
tempval = 0;
for (int pops_i = 0; pops_i < (4-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len4[tempval-4].run;
level = const_dct_coefficients_table_zero_len4[tempval-4].level;
// } else if (tempval >= 10240 && tempval <= 16383) { // 5
} else if (tempval >= 10240) {
tempval = 0;
for (int pops_i = 0; pops_i < (5-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len5[tempval-5].run;
level = const_dct_coefficients_table_zero_len5[tempval-5].level;
// } else if (tempval >= 8192 && tempval <= 10239) { // 8
} else if ( tempval >= 8192) {
tempval = 0;
for (int pops_i = 0; pops_i < (8-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len8[tempval-32].run;
level = const_dct_coefficients_table_zero_len8[tempval-32].level;
// } else if (tempval >= 4096 && tempval <= 8191) { // 6
} else if (tempval >= 4096) {
tempval = 0;
for (int pops_i = 0; pops_i < (6-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len6[tempval-4].run;
level = const_dct_coefficients_table_zero_len6[tempval-4].level;
// } else if (tempval >= 2048 && tempval <= 4095) { // 7
} else if (tempval >= 2048) {
tempval = 0;
for (int pops_i = 0; pops_i < (7-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len7[tempval-4].run;
level = const_dct_coefficients_table_zero_len7[tempval-4].level;
// } else if (tempval >= 512 && tempval <= 1023) { // 10
} else if (tempval >= 512) {
tempval = 0;
for (int pops_i = 0; pops_i < (10-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len10[tempval-8].run;
level = const_dct_coefficients_table_zero_len10[tempval-8].level;
// } else if (tempval >= 256 && tempval <= 511) { // 12
} else if (tempval >= 256) {
tempval = 0;
for (int pops_i = 0; pops_i < (12-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len12[tempval-16].run;
level = const_dct_coefficients_table_zero_len12[tempval-16].level;
// } else if (tempval >= 128 && tempval <= 255) { // 13
} else if (tempval >= 128) {
tempval = 0;
for (int pops_i = 0; pops_i < (13-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len13[tempval-16].run;
level = const_dct_coefficients_table_zero_len13[tempval-16].level;
// } else if (tempval >= 64 && tempval <= 127) { // 14
} else if (tempval >= 64) {
tempval = 0;
for (int pops_i = 0; pops_i < (14-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len14[tempval-16].run;
level = const_dct_coefficients_table_zero_len14[tempval-16].level;
// } else if (tempval >= 32 && tempval <= 63) { // 15
} else if (tempval >= 32) {
tempval = 0;
for (int pops_i = 0; pops_i < (15-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len15[tempval-16].run;
level = const_dct_coefficients_table_zero_len15[tempval-16].level;
// } else if (tempval >= 16 && tempval <= 31) { // 16
} else if (tempval >= 16) {
tempval = 0;
for (int pops_i = 0; pops_i < (16-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
run = const_dct_coefficients_table_zero_len16[tempval-16].run;
level = const_dct_coefficients_table_zero_len16[tempval-16].level;
} else {
print("Error - Unknown Huffman Symbol");
}
// end variable length code
sign = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
sign += pop();
sign <<= 1;
}
sign += pop();
if (sign == 0) {
signed_level = level;
} else {
signed_level = -level;
}
}
QFS_current += run;
if (QFS_current == 63) {
tempval = 0;
for (int pops_i = 0; pops_i < (2-1); pops_i++) {
tempval += pop();
tempval <<= 1;
}
tempval += pop();
if (tempval != 2) {
println("Error - Reached End of Block, Expecting End of Block Code");
}
}
QFS[i][QFS_current] = signed_level;
QFS_current++;
}
if (QFS_current > 64)
println("Error - QFS_current > 64 " + QFS_current);
}
} else {
// Skipped block
// This indicates a skipped block, but not a skipped macroblock.
for (int index = 0; index < 64; index++) {
QFS[i][index] = 0;
}
}
}
PushMacroblock();
pushedMacroblock = true;
tempval = 0;
for (int peeks_i = 0; peeks_i < (23-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(23-1);
if (tempval == 0) {
macroblock_next = false;
next_cfg_node = 13;
} else {
macroblock_next = true;
next_cfg_node = 7;
}
}
else if (next_cfg_node == 13) {
{
int nsc_tempval;
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
while (nsc_tempval != 1) {
nsc_tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
nsc_tempval += pop();
nsc_tempval <<= 1;
}
nsc_tempval += pop();
// print("....looking for next_start_code....");
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
}
}
tempval = 0;
for (int peeks_i = 0; peeks_i < (32-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(32-1);
if (tempval > 0x000001AF || tempval < 0x00000101) {
slice_start_code_follows = false;
next_cfg_node = 15;
} else {
slice_start_code_follows = true;
next_cfg_node = 5;
}
}
else if (next_cfg_node == 15) {
{
int nsc_tempval;
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
while (nsc_tempval != 1) {
nsc_tempval = 0;
for (int pops_i = 0; pops_i < (1-1); pops_i++) {
nsc_tempval += pop();
nsc_tempval <<= 1;
}
nsc_tempval += pop();
// print("....looking for next_start_code....");
nsc_tempval = 0;
for (int peeks_i = 0; peeks_i < (24-1); peeks_i++) {
nsc_tempval += peek(peeks_i);
nsc_tempval <<= 1;
}
nsc_tempval += peek(24-1);
}
}
tempval = 0;
for (int peeks_i = 0; peeks_i < (32-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(32-1);
if (tempval == 0x00000100 || tempval == 0x000001B8) {
picture_or_group_start_code_found = true;
next_cfg_node = 3;
} else {
picture_or_group_start_code_found = false;
next_cfg_node = 17;
}
}
else if (next_cfg_node == 17) {
tempval = 0;
for (int peeks_i = 0; peeks_i < (32-1); peeks_i++) {
tempval += peek(peeks_i);
tempval <<= 1;
}
tempval += peek(32-1);
if (tempval != 0x000001B7) {
println("Error - Program Limitation: Don't handle repeated sequence headers and sequence extensions");
}
if (tempval != 0x000001B7) {
sequence_end_code_not_found = true;
next_cfg_node = 1;
} else {
sequence_end_code_not_found = false;
next_cfg_node = 18;
}
}
else if (next_cfg_node == 18) {
println("Done Parsing M2V File...");
println("Generating fake last frame to push out last real frame of video.");
UpdatePortal_picture_type.setPictureType(1) [0:0];
UpdatePortal_picture_type2.setPictureType(1) [0:0];
UpdatePortal_picture_type3.setPictureType(1) [0:0];
UpdatePortal_macroblock_intra.setMacroblockIntra(1);
for (int i = 0; i < blocks_per_macroblock[the_chroma_format]; i++) {
for (int j = 0; j < 64; j++) {
QFS[i][j] = 0;
}
}
for (int r = 0; r < 2; r++)
for (int s = 0; s < 2; s++)
for (int t = 0; t < 2; t++) {
motion_code[r][s][t] = 0;
}
for (int r = 0; r < 2; r++)
for (int s = 0; s < 2; s++)
for (int t = 0; t < 2; t++) {
motion_residual[r][s][t] = 0;
}
macroblock_intra = 1;
macroblock_motion_forward = 0;
macroblock_motion_backward = 0;
int i = 0;
next_cfg_node = 21;
}
else if (next_cfg_node == 21) {
// assert: i < width/16
int j = 0;
next_cfg_node = 22;
}
else if (next_cfg_node == 22) {
// assert: j < height/16
PushMacroblock();
pushedMacroblock = true;
j++;
if (j < height/16)
next_cfg_node = 22;
else
next_cfg_node = 27;
}
else if (next_cfg_node == 27) {
i++;
if (i < width/16)
next_cfg_node = 21;
else
next_cfg_node = 29;
}
else if (next_cfg_node == 29) {
println("Done generating fake frame");
next_cfg_node = 30;
}
else if (next_cfg_node == 30) {
// println("Error - Trying to parse M2V file for a second time...");
pushedMacroblock = true;
}
}
}
}