/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
/*
* Disclaimer of Warranty
*
* These software programs are available to the user without any license fee or
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
* any and all warranties, whether express, implied, or statuary, including any
* implied warranties or merchantability or of fitness for a particular
* purpose. In no event shall the copyright-holder be liable for any
* incidental, punitive, or consequential damages of any kind whatsoever
* arising from the use of these programs.
*
* This disclaimer of warranty extends to the user of these programs and user's
* customers, employees, agents, transferees, successors, and assigns.
*
* The MPEG Software Simulation Group does not represent or warrant that the
* programs furnished hereunder are free of infringement of any third-party
* patents.
*
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
* are subject to royalty fees to patent holders. Many of these patents are
* general enough such that they are unavoidable regardless of implementation
* design.
*
*/
/*
* @(#)MpvDecoder.java - still Picture Decoder
*
* Copyright (c) 2003-2010 by dvb.matt, All Rights Reserved.
*
* This file is part of ProjectX, a free Java based demux utility.
* By the authors, ProjectX is intended for educational purposes only,
* as a non-commercial test project.
*
* necessary codes are derived from the MSSG mpeg2dec
*
* display modifications: shows I-Frames only
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package net.sourceforge.dvb.projectx.video;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.sourceforge.dvb.projectx.common.Resource;
import net.sourceforge.dvb.projectx.common.Common;
import net.sourceforge.dvb.projectx.common.Keys;
import net.sourceforge.dvb.projectx.parser.CommonParsing;
public class MpvDecoder extends Object {
private IDCTRefNative idct;
private IDCTSseNative idctsse;
private int preview_horizontal_size = 512;
private int preview_vertical_size = 288;
private final int cutview_horizontal_size = 160;
private final int cutview_vertical_size = 90;
private int zoomMode = 0;
private int[] zoomArea = new int[4];
private int[] pixels2 = new int[preview_horizontal_size * preview_vertical_size];
private int[] pixels = new int[250]; //full pixel data
private int Fault_Flag = 0;
private int BitPos = 0;
private int BufferPos = 0;
private int SequenceHeader = 0;
private int YGain = 0;
private long StartPos = 0;
private boolean acceleration = false;
private boolean FAST = false;
private boolean PLAY = true;
private boolean DIRECTION = false;
private boolean ERROR1 = false;
private boolean ERROR2 = false;
private boolean ERROR3 = false;
private boolean ERROR4 = false;
private boolean ERROR5 = false;
private boolean ERROR6 = false;
private boolean viewGOP = true;
private String info_4 = "";
private String info_3 = "";
private String info_2 = "";
private String info_1 = "";
private String[] mpg_info = new String[18];
private String processedPidAndFile = Resource.getString("CollectionPanel.Preview.offline");
private ArrayList PositionList = new ArrayList();
private byte[] buf = new byte[0];
private int[] LastPosVal = new int[2];
/**
* integer matrix by dukios
*/
//
static int ref_dct_matrix_i[] = new int[64];
//
/**
*
*/
public MpvDecoder()
{
Arrays.fill(pixels2, 0xFF505050);
idct = new IDCTRefNative();
idctsse = new IDCTSseNative();
if (IDCTRefNative.isLibraryLoaded())
idct.init();
if (IDCTRefNative.isLibraryLoaded() || IDCTSseNative.isLibraryLoaded())
acceleration = true;
}
/**
*
*/
public boolean isAccelerated()
{
return acceleration;
}
/**
*
*/
public void setAcceleration(boolean b)
{
acceleration = b;
}
final int PICTURE_START_CODE=0x100;
final int SLICE_START_CODE_MIN=0x101;
final int SLICE_START_CODE_MAX=0x1AF;
final int USER_DATA_START_CODE=0x1B2;
final int SEQUENCE_HEADER_CODE=0x1B3;
final int EXTENSION_START_CODE=0x1B5;
final int SEQUENCE_END_CODE=0x1B7;
final int GROUP_START_CODE=0x1B8;
final int SYSTEM_END_CODE=0x1B9;
final int PACK_START_CODE=0x1BA;
final int SYSTEM_START_CODE=0x1BB;
private int File_Flag;
private int File_Limit;
private int FO_Flag;
private int IDCT_Flag;
private int Luminance_Flag;
private int Scale_Flag;
private int SystemStream_Flag;
private int ERROR_CODE=0;
private int ERROR_CODE1=0;
/* extension start code IDs */
final int SEQUENCE_EXTENSION_ID=1;
final int SEQUENCE_DISPLAY_EXTENSION_ID=2;
final int QUANT_MATRIX_EXTENSION_ID=3;
final int COPYRIGHT_EXTENSION_ID=4;
final int PICTURE_DISPLAY_EXTENSION_ID=7;
final int PICTURE_CODING_EXTENSION_ID=8;
final int ZIG_ZAG=0;
final int MB_WEIGHT=32;
final int MB_CLASS4=64;
final int MC_FIELD=1;
final int MC_FRAME=2;
final int MC_16X8=2;
final int MC_DMV=3;
final int MV_FIELD=0;
final int MV_FRAME=1;
final int I_TYPE=1;
final int P_TYPE=2;
final int B_TYPE=3;
final int TOP_FIELD=1;
final int BOTTOM_FIELD=2;
final int FRAME_PICTURE=3;
final int MACROBLOCK_INTRA=1;
final int MACROBLOCK_PATTERN=2;
final int MACROBLOCK_MOTION_BACKWARD=4;
final int MACROBLOCK_MOTION_FORWARD=8;
final int MACROBLOCK_QUANT=16;
final int CHROMA420=1;
final int CHROMA422=2;
final int CHROMA444=3;
final int IDCT_CLIP_TABLE_OFFSET=512;
private int q_scale_type=0; //1
private int quantizer_scale=0, alternate_scan=0;//1
private int Coded_Picture_Width=0, Coded_Picture_Height=0, Chroma_Width=0, Chroma_Height=0;
private int block_count=0, Second_Field=0;
private int horizontal_size=0, vertical_size=0, mb_width=0, mb_height=0;
/* ISO/IEC 13818-2 section 6.2.2.1: sequence_header() */
private int frame_rate_code=0;
private int aspect_ratio_information=0;
/* ISO/IEC 13818-2 section 6.2.2.3: sequence_extension() */
private int progressive_sequence=1; //prog.s std
private int chroma_format=1; //4:2:0std
private int profile_and_level_indication;
private int video_format;
private String video_format_S[] = { "comp","PAL","NTSC","SECAM","MAC","unspec","res","res" };
private String prof[] = { "res","HP","SS","SNR","MP","SP","res","res" };
private String lev[] = { "res","res","res","res","HL","res","HL1440","res","ML","res","LL","res","res","res","res" };
private String cf[] = { "res./monochrom","4:2:0","4:2:2","4:4:4" };
private String SH[] = { "GOP","Sequence" };
/* ISO/IEC 13818-2 section 6.2.3: picture_header() */
private int picture_coding_type=0;
private int temporal_reference=0;
/* ISO/IEC 13818-2 section 6.2.3.1: picture_coding_extension() header */
private int f_code[][] = new int[2][2];
private int picture_structure=3; //0
private int frame_pred_frame_dct=1; //0
private int progressive_frame=1; //0
private int concealment_motion_vectors=0;
private int intra_dc_precision=0; //8bit
private int top_field_first=0;
private int repeat_first_field=0;
private int intra_vlc_format=0; //
private int intra_quantizer_matrix[] = new int[64];
private int non_intra_quantizer_matrix[] = new int[64];
private int chroma_intra_quantizer_matrix[] = new int[64];
private int chroma_non_intra_quantizer_matrix[] = new int[64];
private int load_intra_quantizer_matrix=0;
private int load_non_intra_quantizer_matrix=0;
private int load_chroma_intra_quantizer_matrix=0;
private int load_chroma_non_intra_quantizer_matrix=0;
private short block[][]=new short[12][64]; //macroblocks
final String picture_coding_type_string[] = {
"bad","I","P","B","D"
};
final String progressive_string[] = {
"i","p"
};
final String aspect_ratio_string[] = {
"bad","1:1","4:3","16:9","2.21:1","0.8055","0.8437","0.9375","0.9815","1.0255","1.0695","1.1250","1.1575","1.2015"
};
/* cosine transform matrix for 8x1 IDCT */
//final float ref_dct_matrix[][] = {
final static float ref_dct_matrix[][] = {
{ // [0][0-7]
3.5355339059327379e-001f, 3.5355339059327379e-001f,
3.5355339059327379e-001f, 3.5355339059327379e-001f,
3.5355339059327379e-001f, 3.5355339059327379e-001f,
3.5355339059327379e-001f, 3.5355339059327379e-001f,
}, { // [1][0-7]
4.9039264020161522e-001f, 4.1573480615127262e-001f,
2.7778511650980114e-001f, 9.7545161008064166e-002f,
-9.7545161008064096e-002f, -2.7778511650980098e-001f,
-4.1573480615127267e-001f, -4.9039264020161522e-001f,
}, { // [2][0-7]
4.6193976625564337e-001f, 1.9134171618254492e-001f,
-1.9134171618254486e-001f, -4.6193976625564337e-001f,
-4.6193976625564342e-001f, -1.9134171618254517e-001f,
1.9134171618254500e-001f, 4.6193976625564326e-001f,
}, { // [3][0-7]
4.1573480615127262e-001f, -9.7545161008064096e-002f,
-4.9039264020161522e-001f, -2.7778511650980109e-001f,
2.7778511650980092e-001f, 4.9039264020161522e-001f,
9.7545161008064388e-002f, -4.1573480615127256e-001f,
}, { // [4][0-7]
3.5355339059327379e-001f, -3.5355339059327373e-001f,
-3.5355339059327384e-001f, 3.5355339059327368e-001f,
3.5355339059327384e-001f, -3.5355339059327334e-001f,
-3.5355339059327356e-001f, 3.5355339059327329e-001f,
}, { // [5][0-7]
2.7778511650980114e-001f, -4.9039264020161522e-001f,
9.7545161008064152e-002f, 4.1573480615127273e-001f,
-4.1573480615127256e-001f, -9.7545161008064013e-002f,
4.9039264020161533e-001f, -2.7778511650980076e-001f,
}, { // [6][0-7]
1.9134171618254492e-001f, -4.6193976625564342e-001f,
4.6193976625564326e-001f, -1.9134171618254495e-001f,
-1.9134171618254528e-001f, 4.6193976625564337e-001f,
-4.6193976625564320e-001f, 1.9134171618254478e-001f,
}, { // [7][0-7]
9.7545161008064166e-002f, -2.7778511650980109e-001f,
4.1573480615127273e-001f, -4.9039264020161533e-001f,
4.9039264020161522e-001f, -4.1573480615127251e-001f,
2.7778511650980076e-001f, -9.7545161008064291e-002f,
},
};
/**/
//dukios
static {
for(int i = 0; i < 8; i++)
{
for(int j = 0; j < 8; j++)
{
ref_dct_matrix_i[i * 8 + j] = Math.round(ref_dct_matrix[i][j] * 65536.0f);
}
}
}
/**/
final short idct_clip_table[] = {
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-256,-256,-256,-256,-256,-256,-256,
-256,-255,-254,-253,-252,-251,-250,-249,
-248,-247,-246,-245,-244,-243,-242,-241,
-240,-239,-238,-237,-236,-235,-234,-233,
-232,-231,-230,-229,-228,-227,-226,-225,
-224,-223,-222,-221,-220,-219,-218,-217,
-216,-215,-214,-213,-212,-211,-210,-209,
-208,-207,-206,-205,-204,-203,-202,-201,
-200,-199,-198,-197,-196,-195,-194,-193,
-192,-191,-190,-189,-188,-187,-186,-185,
-184,-183,-182,-181,-180,-179,-178,-177,
-176,-175,-174,-173,-172,-171,-170,-169,
-168,-167,-166,-165,-164,-163,-162,-161,
-160,-159,-158,-157,-156,-155,-154,-153,
-152,-151,-150,-149,-148,-147,-146,-145,
-144,-143,-142,-141,-140,-139,-138,-137,
-136,-135,-134,-133,-132,-131,-130,-129,
-128,-127,-126,-125,-124,-123,-122,-121,
-120,-119,-118,-117,-116,-115,-114,-113,
-112,-111,-110,-109,-108,-107,-106,-105,
-104,-103,-102,-101,-100, -99, -98, -97,
-96, -95, -94, -93, -92, -91, -90, -89,
-88, -87, -86, -85, -84, -83, -82, -81,
-80, -79, -78, -77, -76, -75, -74, -73,
-72, -71, -70, -69, -68, -67, -66, -65,
-64, -63, -62, -61, -60, -59, -58, -57,
-56, -55, -54, -53, -52, -51, -50, -49,
-48, -47, -46, -45, -44, -43, -42, -41,
-40, -39, -38, -37, -36, -35, -34, -33,
-32, -31, -30, -29, -28, -27, -26, -25,
-24, -23, -22, -21, -20, -19, -18, -17,
-16, -15, -14, -13, -12, -11, -10, -9,
-8, -7, -6, -5, -4, -3, -2, -1,
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127,
128, 129, 130, 131, 132, 133, 134, 135,
136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151,
152, 153, 154, 155, 156, 157, 158, 159,
160, 161, 162, 163, 164, 165, 166, 167,
168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183,
184, 185, 186, 187, 188, 189, 190, 191,
192, 193, 194, 195, 196, 197, 198, 199,
200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 215,
216, 217, 218, 219, 220, 221, 222, 223,
224, 225, 226, 227, 228, 229, 230, 231,
232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247,
248, 249, 250, 251, 252, 253, 254, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
};
final byte cc_table[] = {
0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2
};
final int ChromaFormat[] = {
0, 6, 8, 12
};
/* non-linear quantization coefficient table */
final byte Non_Linear_quantizer_scale[] = {
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
};
final byte MBAtab1[][] = { //VLCtab val,len
{-1,0}, {-1,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 */
final byte MBAtab2[][] = { //VLCtab val,len
{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}
};
/* default intra quantization matrix */
final int default_intra_quantizer_matrix[] = {
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
};
/* zig-zag and alternate scan patterns */
final byte scan[][] = {
{ /* Zig-Zag scan pattern */
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
}
,
{ /* Alternate scan pattern */
0, 8, 16, 24, 1, 9, 2, 10,
17, 25, 32, 40, 48, 56, 57, 49,
41, 33, 26, 18, 3, 11, 4, 12,
19, 27, 34, 42, 50, 58, 35, 43,
51, 59, 20, 28, 5, 13, 6, 14,
21, 29, 36, 44, 52, 60, 37, 45,
53, 61, 22, 30, 7, 15, 23, 31,
38, 46, 54, 62, 39, 47, 55, 63
}
};
/***
typedef struct {
char run, level, len;
} DCTtab;
typedef struct {
char val, len;
} VLCtab;
***/
/* Table B-14, DCT coefficients table zero,
* codes 000001xx ... 00111xxx */
final byte DCTtab0[][] = {
{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 */
final byte DCTtab0a[][] = {
{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 */
final byte DCTtab1[][] = {
{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 */
final byte DCTtab1a[][] = {
{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 */
final byte DCTtab2[][] = {
{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 */
final byte DCTtab3[][] = {
{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 */
final byte DCTtab4[][] = {
{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 */
final byte DCTtab5[][] = {
{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 */
final byte DCTtab6[][] = { //DCTtab run,level,len
{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}
};
/* Table B-14, DCT coefficients table zero,
* codes 0100 ... 1xxx (used for first (DC) coefficient) */
final byte DCTtabfirst[][] = {
{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) */
final byte DCTtabnext[][] = {
{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-9, coded_block_pattern, codes 01000 ... 111xx */
final byte CBPtab0[][] = {
{-1,0}, {-1,0}, {-1,0}, {-1,0}, {-1,0}, {-1,0}, {-1,0}, {-1,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 */
final byte CBPtab1[][] = {
{-1,0}, {-1,0}, {-1,0}, {-1,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 000000001 ... 000000111 */
final byte CBPtab2[][] = {
{-1,0}, {0,9}, {39,9}, {27,9}, {59,9}, {55,9}, {47,9}, {31,9}
};
/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */
final byte DClumtab0[][] = {
{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}, {-1, 0}
};
/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */
final byte DClumtab1[][] = {
{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 */
final byte DCchromtab0[][] = {
{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}, {-1, 0}
};
/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */
final byte DCchromtab1[][] = {
{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-10, motion_code, codes 0001 ... 01xx */
final byte MVtab0[][] = {
{-1,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1}
};
/* Table B-10, motion_code, codes 0000011 ... 000011x */
final byte MVtab1[][] = {
{-1,0}, {-1,0}, {-1,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5}
};
/* Table B-10, motion_code, codes 0000001100 ... 000001011x */
final byte MVtab2[][] = {
{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-3, macroblock_type in P-pictures, codes 001..1xx */
final byte PMBtab0[][] = {
{-1,0},
{MACROBLOCK_MOTION_FORWARD,3},
{MACROBLOCK_PATTERN,2}, {MACROBLOCK_PATTERN,2},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1}
};
/* Table B-3, macroblock_type in P-pictures, codes 000001..00011x */
final byte PMBtab1[][] = {
{-1,0},
{MACROBLOCK_QUANT|MACROBLOCK_INTRA,6},
{MACROBLOCK_QUANT|MACROBLOCK_PATTERN,5}, {MACROBLOCK_QUANT|MACROBLOCK_PATTERN,5},
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,5}, {MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,5},
{MACROBLOCK_INTRA,5}, {MACROBLOCK_INTRA,5}
};
/* Table B-4, macroblock_type in B-pictures, codes 0010..11xx */
final byte BMBtab0[][] = {
{-1,0},
{-1,0},
{MACROBLOCK_MOTION_FORWARD,4},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,4},
{MACROBLOCK_MOTION_BACKWARD,3},
{MACROBLOCK_MOTION_BACKWARD,3},
{MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,3},
{MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,3},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2},
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}
};
/* Table B-4, macroblock_type in B-pictures, codes 000001..00011x */
final byte BMBtab1[][] = {
{-1,0},
{MACROBLOCK_QUANT|MACROBLOCK_INTRA,6},
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,6},
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,6},
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,5},
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,5},
{MACROBLOCK_INTRA,5},
{MACROBLOCK_INTRA,5}
};
final double frame_rate_Table[] = {
0.0,
((24.0*1000.0)/1001.0),
24.0,
25.0,
((30.0*1000.0)/1001.0),
30.0,
50.0,
((60.0*1000.0)/1001.0),
60.0,
-1, // reserved
-1,
-1,
-1,
-1,
-1,
-1
};
/* global value */
private byte backward_reference_frame[] = new byte[3], forward_reference_frame[] = new byte[3];
private byte auxframe[] = new byte[3], current_frame[] = new byte[3];
private byte u422, v422, u444, v444, rgb24, lum;
private int pf_backward, pf_forward, pf_current;
private float frame_rate,Frame_Rate;
//from gopheader
private int gop_hour;
private int gop_minute;
private int gop_sec;
private int gop_frame;
private int drop_flag;
private int closed_gop;
private int broken_link;
/**
*
*/
private void Clear_Block(int comp) // assembler?
{
Arrays.fill(block[comp],(short)0); //clear macroblaock
}
/**
*
*/
private int Get_Bits(int N)
{
int Pos, Val, a;
Pos = BitPos>>>3;
a = Pos;
if (a >= buf.length)
ERROR3 = true;
if (a == LastPosVal[0])
Val = LastPosVal[1];
else
{
Val = (0xFF & buf[a++])<<24;
if (a < buf.length)
Val |= (0xFF & buf[a++])<<16;
if (a < buf.length)
Val |= (0xFF & buf[a++])<<8;
if (a < buf.length)
Val |= (0xFF & buf[a]);
}
LastPosVal[0] = Pos;
LastPosVal[1] = Val;
Val <<= BitPos & 7;
Val >>>= 32-N;
BitPos += N;
BufferPos = BitPos>>>3;
return Val;
}
/**
*
*/
private int Show_Bits(int N)
{
int Pos, Val, a;
Pos = BitPos>>>3;
a = Pos;
if (a >= buf.length)
ERROR3 = true;
if (a == LastPosVal[0])
Val = LastPosVal[1];
else
{
Val = (0xFF & buf[a++])<<24;
if (a < buf.length)
Val |= (0xFF & buf[a++])<<16;
if (a < buf.length)
Val |= (0xFF & buf[a++])<<8;
if (a < buf.length)
Val |= (0xFF & buf[a]);
}
LastPosVal[0] = Pos;
LastPosVal[1] = Val;
Val <<= BitPos & 7;
Val >>>= 32 - N;
return Val;
}
/**
*
*/
private void Flush_Bits(int N)
{
BitPos += N;
BufferPos = BitPos>>>3;
}
/* decode headers from one input stream */
public int extern_Get_Hdr() {
int start_code;
for (;;){
/* look for next_start_code */
if (DIRECTION)
previous_start_code();
else
next_start_code();
if ((start_code=Get_Bits(32))==SEQUENCE_HEADER_CODE){
resetDecoder(); //DM26112003 081.5++
StartPos=BufferPos-4;
sequence_header();
next_start_code();
if ((start_code=Get_Bits(32))==GROUP_START_CODE)
{
group_of_pictures_header();
next_start_code();
if ((start_code=Get_Bits(32))==PICTURE_START_CODE)
{
picture_header();
return 1;
}
}
else if (start_code==PICTURE_START_CODE) //decode pic even without gopheader
{
reset_group_of_pictures_header();
picture_header();
return 1;
}
}
else if (viewGOP && start_code==GROUP_START_CODE){
StartPos=BufferPos-4;
group_of_pictures_header();
next_start_code();
if ((start_code=Get_Bits(32))==PICTURE_START_CODE){
picture_header();
return 1;
}
}
else if (!viewGOP && start_code==GROUP_START_CODE){
if (DIRECTION)
Flush_Bits(-40);
ERROR5 = true;
}
//else if (start_code==SEQUENCE_END_CODE)
// return 2;
else if (DIRECTION)
Flush_Bits(-40);
}
}
/* decode headers from one input stream */
public int Get_Hdr() {
video_format=5;
for (;;){
/* look for next_start_code */
next_start_code();
switch (Get_Bits(32)){
case SEQUENCE_HEADER_CODE:
resetDecoder(); //DM26112003 081.5++
StartPos=BufferPos-4;
sequence_header();
break;
case GROUP_START_CODE:
group_of_pictures_header();
break;
case PICTURE_START_CODE:
picture_header();
return 1;
case SEQUENCE_END_CODE:
return 2;
}
}
}
/* align to start of next next_start_code */
private void next_start_code()
{
Flush_Bits((8 - (BitPos & 7)) & 7);
while (Show_Bits(24) != 1)
Flush_Bits(8);
}
/* align to start of next next_start_code */
private void previous_start_code()
{
Flush_Bits((8 - (BitPos & 7)) & 7);
while (Show_Bits(24) != 1)
Flush_Bits(-8);
}
/* decode sequence header */
private void sequence_header(){
int constrained_parameters_flag;
int bit_rate_value;
int vbv_buffer_size;
int i;
horizontal_size = Get_Bits(12);
vertical_size = Get_Bits(12);
aspect_ratio_information = Get_Bits(4);
frame_rate_code = Get_Bits(4);
bit_rate_value = Get_Bits(18);
Flush_Bits(1); // marker bit
vbv_buffer_size = Get_Bits(10);
constrained_parameters_flag = Get_Bits(1);
mpg_info[6] = "QMatrix:";
if ((load_intra_quantizer_matrix = Get_Bits(1))>0)
{
for (i=0; i<64; i++)
intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8);
mpg_info[6] += " iqm";
}
else
{
System.arraycopy(default_intra_quantizer_matrix,0,intra_quantizer_matrix,0,64);
}
if ((load_non_intra_quantizer_matrix = Get_Bits(1))>0)
{
for (i=0; i<64; i++)
non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8);
mpg_info[6] += " niqm";
}
else
{
Arrays.fill(non_intra_quantizer_matrix,16);
}
if (mpg_info[6].equals("Matrix:"))
mpg_info[6] = "Matrix: default";
/* copy luminance to chrominance matrices */
System.arraycopy(intra_quantizer_matrix,0,chroma_intra_quantizer_matrix,0,64);
System.arraycopy(non_intra_quantizer_matrix,0,chroma_non_intra_quantizer_matrix,0,64);
frame_rate = (float)frame_rate_Table[frame_rate_code]; //DM06022004 081.6 int15 add
extension_and_user_data();
mpg_info[2] = String.valueOf(bit_rate_value * 400) + " bps";
mpg_info[2] += " - vbv " + vbv_buffer_size + (constrained_parameters_flag > 0 ? ", cpf" : "");
Common.setLastPreviewBitrate(bit_rate_value * 400);
}
/* missing group of pictures header */
private void reset_group_of_pictures_header(){
drop_flag = 0;
gop_hour = -1;
gop_minute = -1;
gop_sec = -1;
gop_frame = -1;
closed_gop = 0;
broken_link = 0;
}
/* decode group of pictures header */
/* ISO/IEC 13818-2 section 6.2.2.6 */
private void group_of_pictures_header(){
drop_flag = Get_Bits(1);
gop_hour = Get_Bits(5);
gop_minute = Get_Bits(6);
Flush_Bits(1); // marker bit
gop_sec = Get_Bits(6);
gop_frame = Get_Bits(6);
closed_gop = Get_Bits(1);
broken_link = Get_Bits(1);
extension_and_user_data();
}
/* decode extension and user data */
/* ISO/IEC 13818-2 section 6.2.2.2 */
private void extension_and_user_data(){
int code, ext_ID;
next_start_code();
while ((code = Show_Bits(32))==EXTENSION_START_CODE || code==USER_DATA_START_CODE){
if (code==EXTENSION_START_CODE) {
Flush_Bits(32);
ext_ID = Get_Bits(4);
switch (ext_ID) {
case SEQUENCE_EXTENSION_ID:
sequence_extension();
break;
case SEQUENCE_DISPLAY_EXTENSION_ID:
sequence_display_extension();
break;
case QUANT_MATRIX_EXTENSION_ID:
quant_matrix_extension();
break;
case PICTURE_DISPLAY_EXTENSION_ID:
picture_display_extension();
break;
case PICTURE_CODING_EXTENSION_ID:
picture_coding_extension();
break;
case COPYRIGHT_EXTENSION_ID:
copyright_extension();
break;
}
next_start_code();
}else{
mpg_info[17] = "user_data";
Flush_Bits(32); // ISO/IEC 13818-2 sections 6.3.4.1 and 6.2.2.2.2
next_start_code(); // skip user data
}
}
}
/* decode picture header */
/* ISO/IEC 13818-2 section 6.2.3 */
private void picture_header(){
int vbv_delay;
int full_pel_forward_vector;
int forward_f_code;
int full_pel_backward_vector;
int backward_f_code;
int Extra_Information_Byte_Count;
temporal_reference = Get_Bits(10);
picture_coding_type = Get_Bits(3);
vbv_delay = Get_Bits(16);
if (picture_coding_type==P_TYPE || picture_coding_type==B_TYPE) {
full_pel_forward_vector = Get_Bits(1);
forward_f_code = Get_Bits(3);
}
if (picture_coding_type==B_TYPE){
full_pel_backward_vector = Get_Bits(1);
backward_f_code = Get_Bits(3);
}
Extra_Information_Byte_Count = extra_bit_information();
extension_and_user_data();
}
/* decode sequence extension */
/* ISO/IEC 13818-2 section 6.2.2.3 */
private void sequence_extension()
{
int low_delay;
int frame_rate_extension_n;
int frame_rate_extension_d;
int horizontal_size_extension;
int vertical_size_extension;
int bit_rate_extension;
int vbv_buffer_size_extension;
profile_and_level_indication = Get_Bits(8);
progressive_sequence = Get_Bits(1);
chroma_format = Get_Bits(2);
horizontal_size_extension = Get_Bits(2);
vertical_size_extension = Get_Bits(2);
bit_rate_extension = Get_Bits(12);
Flush_Bits(1); // marker bit
vbv_buffer_size_extension = Get_Bits(8);
low_delay = Get_Bits(1);
frame_rate_extension_n = Get_Bits(2);
frame_rate_extension_d = Get_Bits(5);
frame_rate = frame_rate * (frame_rate_extension_n+1) / (frame_rate_extension_d+1); //DM06022004 081.6 int15 changed
horizontal_size = (horizontal_size_extension<<12) | (horizontal_size&0xfff);
vertical_size = (vertical_size_extension<<12) | (vertical_size&0xfff);
info_4 = " ld=" + low_delay; //DM26052004 081.7 int03 add
}
/* decode sequence display extension */
private void sequence_display_extension()
{
int color_description;
int color_primaries;
int transfer_characteristics;
int matrix_coefficients;
int display_horizontal_size;
int display_vertical_size;
video_format = Get_Bits(3);
color_description = Get_Bits(1);
if (color_description>0)
{
color_primaries = Get_Bits(8);
transfer_characteristics = Get_Bits(8);
matrix_coefficients = Get_Bits(8);
}
display_horizontal_size = Get_Bits(14);
Flush_Bits(1); // marker bit
display_vertical_size = Get_Bits(14);
info_3 = " / " + display_horizontal_size + " * " + display_vertical_size;
}
/* decode quant matrix entension */
/* ISO/IEC 13818-2 section 6.2.3.2 */
private void quant_matrix_extension()
{
int i;
if ((load_intra_quantizer_matrix = Get_Bits(1))>0)
for (i=0; i<64; i++)
chroma_intra_quantizer_matrix[scan[ZIG_ZAG][i]]
= intra_quantizer_matrix[scan[ZIG_ZAG][i]]
= Get_Bits(8);
if ((load_non_intra_quantizer_matrix = Get_Bits(1))>0)
for (i=0; i<64; i++)
chroma_non_intra_quantizer_matrix[scan[ZIG_ZAG][i]]
= non_intra_quantizer_matrix[scan[ZIG_ZAG][i]]
= Get_Bits(8);
if ((load_chroma_intra_quantizer_matrix = Get_Bits(1))>0)
for (i=0; i<64; i++)
chroma_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8);
if ((load_chroma_non_intra_quantizer_matrix = Get_Bits(1))>0)
for (i=0; i<64; i++)
chroma_non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8);
}
/* decode picture display extension */
/* ISO/IEC 13818-2 section 6.2.3.3. */
private void picture_display_extension()
{
int frame_center_horizontal_offset[] = new int[3];
int frame_center_vertical_offset[] = new int[3];
int i;
int number_of_frame_center_offsets;
/* based on ISO/IEC 13818-2 section 6.3.12
(November 1994) Picture display extensions */
/* derive number_of_frame_center_offsets */
if (progressive_sequence>0)
{
if (repeat_first_field>0)
{
if (top_field_first>0)
number_of_frame_center_offsets = 3;
else
number_of_frame_center_offsets = 2;
}
else
number_of_frame_center_offsets = 1;
}
else
{
if (picture_structure!=FRAME_PICTURE)
number_of_frame_center_offsets = 1;
else
{
if (repeat_first_field>0)
number_of_frame_center_offsets = 3;
else
number_of_frame_center_offsets = 2;
}
}
mpg_info[15] = "Offs.: ";
/* now parse */
for (i=0; i<number_of_frame_center_offsets; i++)
{
frame_center_horizontal_offset[i] = Get_Bits(16);
Flush_Bits(1); // marker bit
frame_center_vertical_offset[i] = Get_Bits(16);
Flush_Bits(1); // marker bit
mpg_info[15] += "(" + frame_center_horizontal_offset[i] + "," + frame_center_vertical_offset[i] + ")";
}
}
/* decode picture coding extension */
private void picture_coding_extension()
{
int chroma_420_type;
int composite_display_flag;
int v_axis;
int field_sequence;
int sub_carrier;
int burst_amplitude;
int sub_carrier_phase;
f_code[0][0] = Get_Bits(4);
f_code[0][1] = Get_Bits(4);
f_code[1][0] = Get_Bits(4);
f_code[1][1] = Get_Bits(4);
intra_dc_precision = Get_Bits(2);
picture_structure = Get_Bits(2);
top_field_first = Get_Bits(1);
frame_pred_frame_dct = Get_Bits(1);
concealment_motion_vectors = Get_Bits(1);
q_scale_type = Get_Bits(1);
intra_vlc_format = Get_Bits(1);
alternate_scan = Get_Bits(1);
repeat_first_field = Get_Bits(1);
chroma_420_type = Get_Bits(1);
progressive_frame = Get_Bits(1);
composite_display_flag = Get_Bits(1);
mpg_info[13] = "iDC-Prec: " + (intra_dc_precision + 8);
if (composite_display_flag>0)
{
v_axis = Get_Bits(1);
field_sequence = Get_Bits(3);
sub_carrier = Get_Bits(1);
burst_amplitude = Get_Bits(7);
sub_carrier_phase = Get_Bits(8);
mpg_info[13] += " / cdf";
}
}
/* Copyright extension */
/* ISO/IEC 13818-2 section 6.2.3.6. */
/* (header added in November, 1994 to the IS document) */
private void copyright_extension()
{
int copyright_flag;
int copyright_identifier;
int original_or_copy;
int copyright_number_1;
int copyright_number_2;
int copyright_number_3;
int reserved_data;
copyright_flag = Get_Bits(1);
copyright_identifier = Get_Bits(8);
original_or_copy = Get_Bits(1);
/* reserved */
reserved_data = Get_Bits(7);
Flush_Bits(1); // marker bit
copyright_number_1 = Get_Bits(20);
Flush_Bits(1); // marker bit
copyright_number_2 = Get_Bits(22);
Flush_Bits(1); // marker bit
copyright_number_3 = Get_Bits(22);
}
/* set std for lower profiles as mpeg1 */
private void resetDecoder()
{
Fault_Flag=0; //DM14052004 081.7 int02 add,fix
picture_coding_type=0; //DM14052004 081.7 int02 add,fix
SequenceHeader=1;
video_format=5;
progressive_sequence=1;
chroma_format=1;
profile_and_level_indication=0;
Second_Field=0;
intra_dc_precision=0;
picture_structure=FRAME_PICTURE;
top_field_first=0;
frame_pred_frame_dct=1;
concealment_motion_vectors=0;
intra_vlc_format=0;
repeat_first_field=0;
progressive_frame=1;
q_scale_type=0;
quantizer_scale=0;
alternate_scan=0;
}
private void InitialDecoder()
{
mb_width = (horizontal_size + 15)>>>4;
mb_height = (progressive_sequence>0) ? (vertical_size+15)>>>4 : ((vertical_size + 31)>>>5)<<1;
Coded_Picture_Width = mb_width<<4;
Coded_Picture_Height = mb_height<<4;
Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width : Coded_Picture_Width>>1;
Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height : Coded_Picture_Height>>1;
block_count = ChromaFormat[chroma_format];
if (picture_coding_type==I_TYPE)
resizePixels(Coded_Picture_Width, Coded_Picture_Height, horizontal_size, vertical_size);
}
public void resizePixels(int cw, int ch, int hs, int vs)
{
//value set from outside
Coded_Picture_Width = cw;
Coded_Picture_Height = ch;
horizontal_size = hs;
vertical_size = vs;
if (pixels.length != Coded_Picture_Width * Coded_Picture_Height)
pixels = new int[Coded_Picture_Width * Coded_Picture_Height];
else
Arrays.fill(pixels, 0);
}
//public void Decode_Picture(int ref, byte dst, int pitch){
public void Decode_Picture(){
if (picture_structure==FRAME_PICTURE && Second_Field>0)
Second_Field = 0;
if (picture_coding_type!=B_TYPE){
pf_forward = pf_backward;
pf_backward = pf_current;
}
//moved
String fieldorder[] = {"bff","tff"}; //<==TheHorse 221003
String picture_struc[] = {"-","Top","Bottom","Frame"}; //DM08022004 081.6 int16 add
//DM26022004 081.6 int18 changed
//DM06052004 081.7 int02 changed
info_2 = Common.adaptString(gop_hour, 2) + ":" + Common.adaptString(gop_minute, 2) + ":" + Common.adaptString(gop_sec, 2) + ":" + Common.adaptString(gop_frame, 2) + " ";
info_2 += ", " + drop_flag + "/" + closed_gop + "/" + broken_link + " ";
info_2 += ", " + (Math.round(frame_rate * 1000) / 1000.0f) + "fps "; //DM06022004 081.6 int15 change
info_2 += ", " + SH[SequenceHeader] + " ";
info_2 += ", " + picture_struc[picture_structure]; //DM08022004 081.6 int16 add
info_2 += ", " + ((progressive_sequence==0) ? fieldorder[top_field_first] : "-") + " "; //<==TheHorse 221003
info_2 += ", " + cf[chroma_format];
info_2 += info_3;
mpg_info[4] = "Chroma: " + cf[chroma_format];
mpg_info[8] = "Main Header: " + SH[SequenceHeader];
mpg_info[9] = Common.adaptString(gop_hour, 2) + ":" + Common.adaptString(gop_minute, 2) + ":" + Common.adaptString(gop_sec, 2) + ":" + Common.adaptString(gop_frame, 2);
mpg_info[9] += " " + drop_flag + "/" + closed_gop + "/" + broken_link;
mpg_info[12] = "Pic.Struct.: " + picture_struc[picture_structure];
if (profile_and_level_indication != 0)
mpg_info[13] += " / " + ((progressive_sequence==0) ? fieldorder[top_field_first] : "-");
SequenceHeader=0;
Update_Picture_Buffers();
picture_data();
// scale_Picture();
/**
if (ref>0 && (picture_structure==FRAME_PICTURE || Second_Field>0)){
if (picture_coding_type==B_TYPE)
FrametoRGB(auxframe, pf_current, dst, pitch);
else
FrametoRGB(forward_reference_frame, pf_forward, dst, pitch);
}
**/
if (picture_structure!=FRAME_PICTURE)
Second_Field ^= Second_Field;
}
/* reuse old picture buffers as soon as they are no longer needed */
public void Update_Picture_Buffers(){
int cc; /* color component index */
byte tmp; /* temporary swap pointer */
for (cc=0; cc<3; cc++) {
/* B pictures do not need to be save for future reference */
if (picture_coding_type==B_TYPE)
current_frame[cc] = auxframe[cc];
else{
if (Second_Field<1){
/* only update at the beginning of the coded frame */
tmp = forward_reference_frame[cc];
/* the previously decoded reference frame is stored coincident with the
location where the backward reference frame is stored (backwards
prediction is not needed in P pictures) */
forward_reference_frame[cc] = backward_reference_frame[cc];
/* update pointer for potential future B pictures */
backward_reference_frame[cc] = tmp;
}
/* can erase over old backward reference frame since it is not used
in a P picture, and since any subsequent B pictures will use the
previously decoded I or P frame as the backward_reference_frame */
current_frame[cc] = backward_reference_frame[cc];
}
if (picture_structure==BOTTOM_FIELD)
current_frame[cc] += (cc==0) ? Coded_Picture_Width : Chroma_Width;
}
}
/* decode all macroblocks of the current picture */
/* stages described in ISO/IEC 13818-2 section 7 */
public void picture_data(){
int MBAmax;
int err=0;
/* number of macroblocks per picture */
MBAmax = mb_width*mb_height;
if (picture_structure!=FRAME_PICTURE)
MBAmax>>=1;
for (;;)
if (slice(MBAmax)<0)
return;
}
/* decode slice header */
/* ISO/IEC 13818-2 section 6.2.4 */
public int slice_header(){
int slice_picture_id_enable = 0;
int slice_picture_id = 0;
int extra_information_slice = 0;
int slice_vertical_position_extension = vertical_size>2800 ? Get_Bits(3) : 0;
int quantizer_scale_code = Get_Bits(5);
quantizer_scale = (q_scale_type>0) ? Non_Linear_quantizer_scale[quantizer_scale_code] : quantizer_scale_code<<1;
/* slice_id introduced in March 1995 as part of the video corridendum
(after the IS was drafted in November 1994) */
if (Get_Bits(1)>0){
Get_Bits(1); // intra slice
slice_picture_id_enable = Get_Bits(1);
slice_picture_id = Get_Bits(6);
extra_information_slice = extra_bit_information();
}
return slice_vertical_position_extension;
}
/* decode extra bit information */
/* ISO/IEC 13818-2 section 6.2.3.4. */
public int extra_bit_information(){
int Byte_Count = 0;
while (Get_Bits(1)>0){
Flush_Bits(8);
Byte_Count ++;
}
return Byte_Count;
}
/* decode all macroblocks of the current picture */
/* ISO/IEC 13818-2 section 6.3.16 */
/* return 0 : go to next slice */
/* return -1: go to next picture */
public int slice(int MBAmax){
int MBA[] = {0}, MBAinc[] ={0}, macroblock_type[]={0}, motion_type[]={0}, dct_type[]={0}, ret=0;
int dc_dct_pred[] = new int[3], PMV[][][] = new int[2][2][2],
motion_vertical_field_select[][] = new int[2][2], dmvector[] = new int[2];
if ((ret=start_of_slice(MBA, MBAinc, dc_dct_pred, PMV))!=1) return ret;
for (;;){
/* this is how we properly exit out of picture */
if (MBA[0]>=MBAmax) return -1; // all macroblocks decoded
if (MBAinc[0]==0) {
if (Show_Bits(23)<1 || Fault_Flag>0){ // next_start_code or fault
Fault_Flag = 0;
return 0; // trigger: go to next slice
}else{ /* neither next_start_code nor Fault_Flag */
/* decode macroblock address increment */
MBAinc[0] = Get_macroblock_address_increment();
if (Fault_Flag>0) {
Fault_Flag = 0;
return 0; // trigger: go to next slice
}
}
}
//test
//System.out.println("mba " + MBA[0]);
if (MBAinc[0]==1) { /* not skipped */
if (decode_macroblock(macroblock_type, motion_type, dct_type, PMV,
dc_dct_pred, motion_vertical_field_select, dmvector)<1) {
Fault_Flag = 0;
//DM14052004 081.7 int02 changed
return 0; //return -1; // return 0; // trigger: go to next slice
}
}else{ /* MBAinc[0]!=1: skipped macroblock */ /* ISO/IEC 13818-2 section 7.6.6 */
skipped_macroblock(dc_dct_pred, PMV, motion_type,
motion_vertical_field_select, macroblock_type);
}
/* ISO/IEC 13818-2 section 7.6 */
motion_compensation(MBA, macroblock_type, motion_type, PMV,
motion_vertical_field_select, dmvector, dct_type);
/* advance to next macroblock */
MBA[0]++; MBAinc[0]--;
if (MBA[0]>=MBAmax) return -1; // all macroblocks decoded
}
}
/* ISO/IEC 13818-2 section 7.6.6 */
public void skipped_macroblock(int dc_dct_pred[], int PMV[][][], int motion_type[],
int motion_vertical_field_select[][], int macroblock_type[]){
int comp;
for (comp=0; comp<block_count; comp++) Clear_Block(comp);
/* reset intra_dc predictors */
/* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
/* reset motion vector predictors */
/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */
if (picture_coding_type==P_TYPE) PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
/* derive motion_type */
if (picture_structure==FRAME_PICTURE) motion_type[0] = MC_FRAME;
else{
motion_type[0] = MC_FIELD;
motion_vertical_field_select[0][0] = motion_vertical_field_select[0][1] =
((picture_structure==BOTTOM_FIELD)?1:0);
}
/* clear MACROBLOCK_INTRA */
macroblock_type[0] &= ~MACROBLOCK_INTRA;
}
/* ISO/IEC 13818-2 sections 7.2 through 7.5 */
public int decode_macroblock(int macroblock_type[], int motion_type[], int dct_type[],
int PMV[][][], int dc_dct_pred[],
int motion_vertical_field_select[][], int dmvector[]){
int quantizer_scale_code, comp, motion_vector_count[]={0}, mv_format[]={0};
int dmv[]={0}, mvscale[]={0}, coded_block_pattern;
/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */
macroblock_modes(macroblock_type, motion_type, motion_vector_count, mv_format,
dmv, mvscale, dct_type);
if (Fault_Flag>0) return 0; // trigger: go to next slice
if ( (macroblock_type[0] & MACROBLOCK_QUANT)>0 ){
quantizer_scale_code = Get_Bits(5);
/* ISO/IEC 13818-2 section 7.4.2.2: Quantizer scale factor */
quantizer_scale = (q_scale_type>0) ?
Non_Linear_quantizer_scale[quantizer_scale_code] : (quantizer_scale_code << 1);
}
/* ISO/IEC 13818-2 section 6.3.17.2: Motion vectors */
/* decode forward motion vectors */
if ( ((macroblock_type[0] & MACROBLOCK_MOTION_FORWARD)>0)
|| (((macroblock_type[0] & MACROBLOCK_INTRA)>0) && (concealment_motion_vectors>0)))
motion_vectors(PMV, dmvector, motion_vertical_field_select, 0,
motion_vector_count, mv_format, f_code[0][0]-1, f_code[0][1]-1, dmv, mvscale);
if (Fault_Flag>0) return 0; // trigger: go to next slice
/* decode backward motion vectors */
if ((macroblock_type[0] & MACROBLOCK_MOTION_BACKWARD)>0)
motion_vectors(PMV, dmvector, motion_vertical_field_select, 1,
motion_vector_count,mv_format, f_code[1][0]-1, f_code[1][1]-1, new int[1], mvscale);
if (Fault_Flag>0) return 0; // trigger: go to next slice
if (((macroblock_type[0] & MACROBLOCK_INTRA)>0) && (concealment_motion_vectors>0))
Flush_Bits(1); // marker bit
/* macroblock_pattern */
/* ISO/IEC 13818-2 section 6.3.17.4: Coded block pattern */
if ((macroblock_type[0] & MACROBLOCK_PATTERN)>0) {
coded_block_pattern = Get_coded_block_pattern();
if (chroma_format==CHROMA422)
coded_block_pattern = (coded_block_pattern<<2) | Get_Bits(2);
else if (chroma_format==CHROMA444)
coded_block_pattern = (coded_block_pattern<<6) | Get_Bits(6);
}else
coded_block_pattern = ((macroblock_type[0] & MACROBLOCK_INTRA)>0) ? (1<<block_count)-1 : 0;
if (Fault_Flag>0) return 0; // trigger: go to next slice
//test
/**
System.out.println(
"ma " + macroblock_type[0] +
" /mt " + motion_type[0] +
" /mv " + motion_vector_count[0] +
" /mf " + mv_format[0] +
" /ms " + mvscale[0] +
" /dm " + dmv[0] +
" /dc " + dct_type[0] +
" /qs " + quantizer_scale +
" /qt " + q_scale_type +
" /cm " + concealment_motion_vectors
);
**/
/* decode blocks */
for (comp=0; comp<block_count; comp++) {
Clear_Block(comp);
if ((coded_block_pattern & (1<<(block_count-1-comp)))>0){
if ((macroblock_type[0] & MACROBLOCK_INTRA)>0)
Decode_MPEG2_Intra_Block(comp, dc_dct_pred);
else
Decode_MPEG2_Non_Intra_Block(comp);
if (Fault_Flag>0) return 0; // trigger: go to next slice
}
}
/* reset intra_dc predictors */
/* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */
if ((macroblock_type[0] & MACROBLOCK_INTRA)<1)
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
/* reset motion vector predictors */
if ((macroblock_type[0] & MACROBLOCK_INTRA)>0 && concealment_motion_vectors<1 ) {
/* intra mb without concealment motion vectors */
/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
}
/* special "No_MC" macroblock_type case */
/* ISO/IEC 13818-2 section 7.6.3.5: Prediction in P pictures */
if ((picture_coding_type==P_TYPE)
&& (macroblock_type[0] & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_INTRA))<1) {
/* non-intra mb without forward mv in a P picture */
/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
/* derive motion_type */
/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes, frame_motion_type */
if (picture_structure==FRAME_PICTURE) motion_type[0] = MC_FRAME;
else{
motion_type[0] = MC_FIELD;
motion_vertical_field_select[0][0] = (picture_structure==BOTTOM_FIELD)?1:0;
}
}
/* successfully decoded macroblock */
return 1 ;
}
/* decode one intra coded MPEG-2 block */
private void Decode_MPEG2_Intra_Block(int comp, int dc_dct_pred[])
{
int val=0, i, j, sign, qmat[]; //qmat woanders??
int code;
byte tab[];
short bp[]; //bp woanders array?
bp = block[comp]; //macroblock
qmat = (comp<4 || chroma_format==CHROMA420)
? intra_quantizer_matrix : chroma_intra_quantizer_matrix;
/* ISO/IEC 13818-2 section 7.2.1: decode DC coefficients */
switch (cc_table[comp])
{
case 0:
val = (dc_dct_pred[0]+= Get_Luma_DC_dct_diff());
break;
case 1:
val = (dc_dct_pred[1]+= Get_Chroma_DC_dct_diff());
break;
case 2:
val = (dc_dct_pred[2]+= Get_Chroma_DC_dct_diff());
break;
}
//test
/**
System.out.println("comp " + comp + " /dc " + val);
if (quantizer_scale > 4)
val -= 128;
**/
bp[0] = (short)(val << (3-intra_dc_precision)); //the top-left pixel value of block
/* decode AC coefficients */
for (i=1; ; i++)
{
code = Show_Bits(16);
if (code>=16384 && intra_vlc_format<1)
tab = DCTtabnext[(code>>12)-4];
else if (code>=1024)
{
if (intra_vlc_format>0)
tab = DCTtab0a[(code>>8)-4];
else
tab = DCTtab0[(code>>8)-4];
}
else if (code>=512)
{
if (intra_vlc_format>0)
tab = DCTtab1a[(code>>6)-8];
else
tab = DCTtab1[(code>>6)-8];
}
else if (code>=256)
tab = DCTtab2[(code>>4)-16];
else if (code>=128)
tab = DCTtab3[(code>>3)-16];
else if (code>=64)
tab = DCTtab4[(code>>2)-16];
else if (code>=32)
tab = DCTtab5[(code>>1)-16];
else if (code>=16)
tab = DCTtab6[code-16];
else
{
Fault_Flag = 1;
return;
}
Flush_Bits(tab[2]);
if (tab[0]<64)
{
i+= tab[0];
val = tab[1];
sign = Get_Bits(1);
}
else if (tab[0]==64) /* end_of_block */
return;
else
{ /* escape */
if (profile_and_level_indication==0)
{
//mpeg1 //DM28112003 081.5++
i+= Get_Bits(6);
val = Get_Bits(8);
if (val==0)
val = Get_Bits(8);
else if(val==128)
val = Get_Bits(8)-128;
else if(val>128)
val-=256;
sign = 0;
}
else
{
//mpeg2
i+= Get_Bits(6);
val = Get_Bits(12);
if ( (sign = (val>=2048)?1:0) >0)
val = 4096 - val;
}
}
//prevent outside index
i = i > 63 ? 63 : i;
j = scan[alternate_scan][i];
val = (val * quantizer_scale * qmat[j]) >> 4;
bp[j] = (short)((sign>0) ? -val : val);
}
}
/* decode one non-intra coded MPEG-2 block */
private void Decode_MPEG2_Non_Intra_Block(int comp)
{
int val, i, j, sign, qmat[];
int code;
byte tab[];
short bp[];
bp = block[comp];
qmat = (comp<4 || chroma_format==CHROMA420)
? non_intra_quantizer_matrix : chroma_non_intra_quantizer_matrix;
/* decode AC coefficients */
for (i=0; ; i++)
{
code = Show_Bits(16);
if (code>=16384)
{
if (i==0)
tab = DCTtabfirst[(code>>12)-4];
else
tab = DCTtabnext[(code>>12)-4];
}
else if (code>=1024)
tab = DCTtab0[(code>>8)-4];
else if (code>=512)
tab = DCTtab1[(code>>6)-8];
else if (code>=256)
tab = DCTtab2[(code>>4)-16];
else if (code>=128)
tab = DCTtab3[(code>>3)-16];
else if (code>=64)
tab = DCTtab4[(code>>2)-16];
else if (code>=32)
tab = DCTtab5[(code>>1)-16];
else if (code>=16)
tab = DCTtab6[code-16];
else
{
Fault_Flag = 1;
return;
}
Flush_Bits(tab[2]);
if (tab[0]<64)
{
i+= tab[0];
val = tab[1];
sign = Get_Bits(1);
}
else if (tab[0]==64) /* end_of_block */
return;
else
{ /* escape */
i+= Get_Bits(6);
val = Get_Bits(12);
if ( (sign = (val>=2048)?1:0)>0 )
val = 4096 - val;
}
j = scan[alternate_scan][i];
val = (((val<<1)+1) * quantizer_scale * qmat[j]) >> 5;
bp[j] = (short)((sign>0) ? -val : val);
}
}
/*
parse VLC and perform dct_diff arithmetic.
MPEG-2: ISO/IEC 13818-2 section 7.2.1
Note: the arithmetic here is presented more elegantly than
the spec, yet the results, dct_diff, are the same.
*/
private int Get_Luma_DC_dct_diff()
{
int code, size, dct_diff;
/* decode length */
code = Show_Bits(5);
if (code<31)
{
size = DClumtab0[code][0];
Flush_Bits(DClumtab0[code][1]);
}
else
{
code = Show_Bits(9) - 0x1f0;
size = DClumtab1[code][0];
Flush_Bits(DClumtab1[code][1]);
}
if (size==0)
dct_diff = 0;
else
{
dct_diff = Get_Bits(size);
if ((dct_diff & (1<<(size-1)))==0)
dct_diff-= (1<<size) - 1;
}
return dct_diff;
}
private int Get_Chroma_DC_dct_diff()
{
int code, size, dct_diff;
/* decode length */
code = Show_Bits(5);
if (code<31)
{
size = DCchromtab0[code][0];
Flush_Bits(DCchromtab0[code][1]);
}
else
{
code = Show_Bits(10) - 0x3e0;
size = DCchromtab1[code][0];
Flush_Bits(DCchromtab1[code][1]);
}
if (size==0)
dct_diff = 0;
else
{
dct_diff = Get_Bits(size);
if ((dct_diff & (1<<(size-1)))==0)
dct_diff-= (1<<size) - 1;
}
return dct_diff;
}
private int Get_coded_block_pattern()
{
int code;
if ((code = Show_Bits(9))>=128)
{
code >>= 4;
Flush_Bits(CBPtab0[code][1]);
return CBPtab0[code][0];
}
if (code>=8)
{
code >>= 1;
Flush_Bits(CBPtab1[code][1]);
return CBPtab1[code][0];
}
if (code<1)
{
Fault_Flag = 3;
return 0;
}
Flush_Bits(CBPtab2[code][1]);
return CBPtab2[code][0];
}
/* return==-1 means go to next picture */
/* the expression "start of slice" is used throughout the normative
body of the MPEG specification */
private int start_of_slice(int MBA[], int MBAinc[], int dc_dct_pred[], int PMV[][][])
{
next_start_code();
int code = Get_Bits(32);
if (code<SLICE_START_CODE_MIN || code>SLICE_START_CODE_MAX)
{
// only slice headers are allowed in picture_data
Fault_Flag = 10;
return -1;
}
/* decode slice header (may change quantizer_scale) */
int slice_vert_pos_ext = slice_header();
/* decode macroblock address increment */
MBAinc[0] = Get_macroblock_address_increment();
if (Fault_Flag>0)
return -1;
/* set current location */
/* NOTE: the arithmetic used to derive macroblock_address below is
equivalent to ISO/IEC 13818-2 section 6.3.17: Macroblock */
MBA[0] = ((slice_vert_pos_ext<<7) + (code&255) - 1) * mb_width + MBAinc[0] - 1;
MBAinc[0] = 1; // first macroblock in slice: not skipped
/* reset all DC coefficient and motion vector predictors */
/* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
/* successfull: trigger decode macroblocks in slice */
return 1;
}
private int Get_macroblock_address_increment()
{
int code=0, val=0;
while ((code = Show_Bits(11))<24)
{
if (code!=15)
{ /* if not macroblock_stuffing */
if (code==8) /* if macroblock_escape */
val+= 33;
else
{
Fault_Flag = 4;
return 1;
}
}
Flush_Bits(11);
}
/* macroblock_address_increment == 1 */
/* ('1' is in the MSB position of the lookahead) */
if (code>=1024)
{
Flush_Bits(1);
return (val + 1);
}
/* codes 00010 ... 011xx */
if (code>=128)
{
/* remove leading zeros */
code >>= 6;
Flush_Bits(MBAtab1[code][1]);
return (val + MBAtab1[code][0]);
}
/* codes 00000011000 ... 0000111xxxx */
code-= 24; /* remove common base */
Flush_Bits(MBAtab2[code][1]);
return (val + MBAtab2[code][0]);
}
/* ISO/IEC 13818-2 sections 6.2.5.2, 6.3.17.2, and 7.6.3: Motion vectors */
private void motion_vectors(int PMV[][][],int dmvector[],
int motion_vertical_field_select[][], int s,
int motion_vector_count[], int mv_format[], int h_r_size,
int v_r_size, int dmv[], int mvscale[])
{
if (motion_vector_count[0]==1)
{
if (mv_format[0]==MV_FIELD && dmv[0]<1)
motion_vertical_field_select[1][s] =
motion_vertical_field_select[0][s] = Get_Bits(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
{
motion_vertical_field_select[0][s] = Get_Bits(1);
motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
motion_vertical_field_select[1][s] = Get_Bits(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 for one prediction */
private void motion_vector(int PMV[], int dmvector[], int h_r_size, int v_r_size,
int dmv[], int mvscale[], int full_pel_vector)
{
int motion_code, motion_residual;
/* horizontal component */
/* ISO/IEC 13818-2 Table B-10 */
motion_code = Get_motion_code();
motion_residual = (h_r_size!=0 && motion_code!=0) ? Get_Bits(h_r_size) : 0;
decode_motion_vector(PMV[0],h_r_size,motion_code,motion_residual,full_pel_vector);
if (dmv[0]>0)
dmvector[0] = Get_dmvector();
/* vertical component */
motion_code = Get_motion_code();
motion_residual = (v_r_size!=0 && motion_code!=0) ? Get_Bits(v_r_size) : 0;
if (mvscale[0]>0)
PMV[1] >>= 1; /* DIV 2 */
decode_motion_vector(PMV[1],v_r_size,motion_code,motion_residual,full_pel_vector);
if (mvscale[0]>0)
PMV[1] <<= 1;
if (dmv[0]>0)
dmvector[1] = Get_dmvector();
}
/* calculate motion vector component */
/* ISO/IEC 13818-2 section 7.6.3.1: Decoding the motion vectors */
/* Note: the arithmetic here is more elegant than that which is shown
in 7.6.3.1. The end results (PMV[][][]) should, however, be the same. */
private void decode_motion_vector(int pred, int r_size, int motion_code,
int motion_residual, int full_pel_vector)
{
int lim, vec;
lim = 16<<r_size;
vec = (full_pel_vector>0) ? (pred >> 1) : (pred);
if (motion_code>0)
{
vec+= ((motion_code-1)<<r_size) + motion_residual + 1;
if (vec>=lim)
vec-= lim + lim;
}
else if (motion_code<0)
{
vec-= ((-motion_code-1)<<r_size) + motion_residual + 1;
if (vec<-lim)
vec+= lim + lim;
}
pred = (full_pel_vector>0) ? (vec<<1) : vec;
}
/* ISO/IEC 13818-2 section 7.6.3.6: Dual prime additional arithmetic */
private void Dual_Prime_Arithmetic(int DMV[][],int dmvector[], int mvx,int mvy)
{
if (picture_structure==FRAME_PICTURE)
{
if (top_field_first>0)
{
/* vector for prediction of top field from bottom field */
DMV[0][0] = ((mvx +((mvx>0)?1:0))>>1) + dmvector[0];
DMV[0][1] = ((mvy +((mvy>0)?1:0))>>1) + dmvector[1] - 1;
/* vector for prediction of bottom field from top field */
DMV[1][0] = ((3*mvx+((mvx>0)?1:0))>>1) + dmvector[0];
DMV[1][1] = ((3*mvy+((mvy>0)?1:0))>>1) + dmvector[1] + 1;
}
else
{
/* vector for prediction of top field from bottom field */
DMV[0][0] = ((3*mvx+((mvx>0)?1:0))>>1) + dmvector[0];
DMV[0][1] = ((3*mvy+((mvy>0)?1:0))>>1) + dmvector[1] - 1;
/* vector for prediction of bottom field from top field */
DMV[1][0] = ((mvx +((mvx>0)?1:0))>>1) + dmvector[0];
DMV[1][1] = ((mvy +((mvy>0)?1:0))>>1) + dmvector[1] + 1;
}
}
else
{
/* vector for prediction from field of opposite 'parity' */
DMV[0][0] = ((mvx+((mvx>0)?1:0))>>1) + dmvector[0];
DMV[0][1] = ((mvy+((mvy>0)?1:0))>>1) + dmvector[1];
/* correct for vertical field shift */
if (picture_structure==TOP_FIELD)
DMV[0][1]--;
else
DMV[0][1]++;
}
}
/* ISO/IEC 13818-2 section 7.6 */
private void motion_compensation(int MBA[], int macroblock_type[], int motion_type[],
int PMV[][][], int motion_vertical_field_select[][],
int dmvector[], int dct_type[])
{
int bx, by;
int comp;
/* derive current macroblock position within picture */
/* ISO/IEC 13818-2 section 6.3.1.6 and 6.3.1.7 */
bx = (MBA[0] % mb_width)<<4;
by = (MBA[0] / mb_width)<<4;
/* motion compensation */
//if ((macroblock_type[0] & MACROBLOCK_INTRA)<1)
//form_predictions(bx, by, macroblock_type, motion_type, PMV, motion_vertical_field_select, dmvector);
if (IDCTSseNative.isLibraryLoaded() && isAccelerated())
{
/* copy or add block data into picture */
for (comp=0; comp<block_count; comp++)
{
/* ISO/IEC 13818-2 section Annex A: inverse DCT */
idctsse.referenceIDCT(block[comp]);
/* ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data */
Add_Block(comp, bx, by, dct_type, (macroblock_type[0] & MACROBLOCK_INTRA)==0);
}
}
else if (IDCTRefNative.isLibraryLoaded() && isAccelerated())
{
/* copy or add block data into picture */
for (comp=0; comp<block_count; comp++)
{
/* ISO/IEC 13818-2 section Annex A: inverse DCT */
idct.referenceIDCT(block[comp]);
/* ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data */
Add_Block(comp, bx, by, dct_type, (macroblock_type[0] & MACROBLOCK_INTRA)==0);
}
}
else
{
/* copy or add block data into picture */
for (comp=0; comp<block_count; comp++)
{
/* ISO/IEC 13818-2 section Annex A: inverse DCT */
if (FAST)
IDCT_referenceFAST(block[comp]);
else
IDCT_reference1(block[comp]);
// IDCT_reference(block[comp], FAST ? 1 : 8);
/* ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data */
Add_Block(comp, bx, by, dct_type, (macroblock_type[0] & MACROBLOCK_INTRA)==0);
}
}
}
/* Perform IEEE 1180 reference (64-bit floating point, separable 8x1
* direct matrix multiply) Inverse Discrete Cosine Transform
*/
//DM08022004 081.6 int16 changed to float and first pixel only
private void IDCT_reference(short block[], int len)
{
int i, j, k, v;
float partial_product;
float tmp[] = new float[64];
try {
for (i = 0; i < len; i++)
{
for (j = 0; j < len; j++)
{
partial_product = 0.0f;
for (k = 0; k < 8; k++)
partial_product += ref_dct_matrix[k][j] * block[8 * i + k];
tmp[8 * i + j] = partial_product;
}
}
} catch (Exception e) {
//Common.setExceptionMessage(e);
}
try {
// Transpose operation is integrated into address mapping by switching loop order of i and j
for (j = 0; j < len; j++)
{
for (i = 0; i < len; i++){
partial_product = 0.0f;
for (k = 0; k < 8; k++)
partial_product += ref_dct_matrix[k][i] * tmp[8 * k + j];
v = (int) Math.floor(partial_product + 0.5);
block[8 * i + j] = idct_clip_table[IDCT_CLIP_TABLE_OFFSET + v];
}
}
} catch (Exception e) {
//Common.setExceptionMessage(e);
}
if (len == 1)
Arrays.fill(block, block[0]);
}
//dukios
/**
* integer matrix by dukios
*
static int ref_dct_matrix_i[] = new int[64];
static {
for(int i = 0; i < 8; i++)
{
for(int j = 0; j < 8; j++)
{
ref_dct_matrix_i[i * 8 + j] = Math.round(ref_dct_matrix[i][j] * 65536.0f);
}
}
}
**/
/**/
private void IDCT_referenceFAST(short block[])
{
int i, j, k, v;
long tmp0 = ref_dct_matrix_i[0] * block[0];
long partial_product = ref_dct_matrix_i[0] * tmp0;
v = (int) (partial_product >> 32);
block[0] = idct_clip_table[IDCT_CLIP_TABLE_OFFSET + v];
Arrays.fill(block,block[0]);
}
private void IDCT_reference1(short block[])
{
int i, j, k, v;
long tmp[] = new long[64];
int i8 = 0;
try{
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
tmp[i8 + j] = (
ref_dct_matrix_i[0 + j] * block[i8] +
ref_dct_matrix_i[8 + j] * block[i8 + 1] +
ref_dct_matrix_i[16 + j] * block[i8 + 2] +
ref_dct_matrix_i[24 + j] * block[i8 + 3] +
ref_dct_matrix_i[32 + j] * block[i8 + 4] +
ref_dct_matrix_i[40 + j] * block[i8 + 5] +
ref_dct_matrix_i[48 + j] * block[i8 + 6] +
ref_dct_matrix_i[56 + j] * block[i8 + 7]);
}
i8 += 8;
}
// 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++)
{
long partial_product = (
ref_dct_matrix_i[i] * tmp[j] +
ref_dct_matrix_i[8 + i] * tmp[8 + j] +
ref_dct_matrix_i[16 + i] * tmp[16 + j] +
ref_dct_matrix_i[24 + i] * tmp[24 + j] +
ref_dct_matrix_i[32 + i] * tmp[32 + j] +
ref_dct_matrix_i[40 + i] * tmp[40 + j] +
ref_dct_matrix_i[48 + i] * tmp[48 + j] +
ref_dct_matrix_i[56 + i] * tmp[56 + j]);
v = (int) (partial_product >> 32);
block[8 * i + j] = idct_clip_table[IDCT_CLIP_TABLE_OFFSET + v];
}
}
} catch (Exception e) {
//Common.setExceptionMessage(e);
}
}
/**/
//dukios end
/* move/add 8x8-Block from block[comp] to backward_reference_frame */
/* copy reconstructed 8x8 block from block[comp] to current_frame[]
ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data
This stage also embodies some of the operations implied by:
- ISO/IEC 13818-2 section 7.6.7: Combining predictions
- ISO/IEC 13818-2 section 6.1.3: Macroblock
*/
//DM02092003+ changed
//DM08022004 081.6 int16 changed to float
private void Add_Block(int comp, int bx, int by, int dct_type[], boolean addflag)
{
int cc, iincr;
int rfp;
short Block_Ptr[] = block[comp];
/* derive color component index */
/* equivalent to ISO/IEC 13818-2 Table 7-1 */
cc = cc_table[comp];
if (cc == 0)
{
if (picture_structure == FRAME_PICTURE)
{ //progressive
if (dct_type[0] > 0)
{
rfp = current_frame[0] + Coded_Picture_Width*(by+((comp&2)>>1)) + bx + ((comp&1)<<3);
iincr = (Coded_Picture_Width<<1) - 8;
}
else
{
rfp = current_frame[0] + Coded_Picture_Width*(by+((comp&2)<<2)) + bx + ((comp&1)<<3);
iincr = Coded_Picture_Width - 8;
}
}
else
{
rfp = current_frame[0] + (Coded_Picture_Width<<1)*(by+((comp&2)<<2)) + bx + ((comp&1)<<3);
iincr = (Coded_Picture_Width<<1) - 8;
}
}
else
{
// chrominance
// scale coordinates
if (chroma_format != CHROMA444)
bx >>= 1;
//if (chroma_format==CHROMA420) by >>= 1; // disabled
if (picture_structure == FRAME_PICTURE)
{ //two fields in one pic=std
if (dct_type[0] > 0 && chroma_format != CHROMA420)
{
// field DCT coding
rfp = current_frame[cc] + Chroma_Width*(by+((comp&2)>>1)) + bx + (comp&8);
iincr = (Chroma_Width<<1) - 8;
}
else
{
// frame DCT coding
rfp = current_frame[cc] + Chroma_Width*(by+((comp&2)<<2)) + bx + (comp&8);
iincr = Chroma_Width - 8;
}
}
else
{
// field picture, one field in one pic
rfp = current_frame[cc] + (Chroma_Width<<1)*(by+((comp&2)<<2)) + bx + (comp&8);
iincr = (Chroma_Width<<1) - 8;
}
}
iincr += 8;
//DM02092003+
int val, luma, pPos, r, g, b;
int gain = picture_coding_type == I_TYPE ? 128 : 0;
gain += YGain;
int chroma_value_444 = chroma_format == CHROMA444 ? 1 : 0;
int chroma_value_420 = chroma_format != CHROMA420 ? 1 : 0;
int cc_value = cc == 1 ? 8 : 0;
int x, y;
int tmp1, tmp2, tmp3;
//DM20082004 081.7 int10 changed
if (cc == 0) //lumi
{
// for (y = 0; y < 8; y++)
for (y = 8; --y >= 0; )
{
tmp1 = rfp + (y * iincr);
tmp2 = y<<3;
// for (x = 0; x < 8; x++)
for (x = 8; --x >= 0; )
{
pPos = x + tmp1;
val = Block_Ptr[x + tmp2] + gain;
val = val < 0 ? 0 : (val > 255 ? 255 : val);
pixels[pPos] |= val<<16; //Y
}
}
}
else
{ //chroma cc1 = Cb, cc2=Cr
if (chroma_format != CHROMA444)
{
rfp <<= 1;
iincr <<= 1;
}
for (y = 0; y < 16; y++)
{
tmp1 = rfp + (y >>(chroma_value_420)) * iincr;
tmp3 = y >>1;
tmp2 = (chroma_format != CHROMA420 ? tmp3 : ((y & 1) == 0 ? (tmp3 & ~dct_type[0]) : (tmp3 | dct_type[0])))<<3;
for (x = 0; x < 16; x++)
{
pPos = (x >> chroma_value_444) + tmp1;
val = 128 + Block_Ptr[(x >>1) + tmp2];
val = val < 0 ? 0 : (val > 255 ? 255 : val);
// cc==1 -> U else V
pixels[pPos] |= val << cc_value;
x += chroma_value_444;
}
y += chroma_value_420;
}
}
}
//DM02092003-
/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */
private void macroblock_modes(int pmacroblock_type[], int pmotion_type[],
int pmotion_vector_count[], int pmv_format[],
int pdmv[], int pmvscale[], int pdct_type[])
{
int macroblock_type, motion_type=0, motion_vector_count;
int mv_format, dmv, mvscale, dct_type;
/* get macroblock_type */
macroblock_type = Get_macroblock_type();
if (Fault_Flag > 0)
return;
/* get frame/field motion type */
if ((macroblock_type & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD)) > 0)
{
if (picture_structure==FRAME_PICTURE)
motion_type = (frame_pred_frame_dct>0) ? MC_FRAME : Get_Bits(2);
else
motion_type = Get_Bits(2);
}
else if ((macroblock_type & MACROBLOCK_INTRA) > 0 && concealment_motion_vectors > 0)
motion_type = (picture_structure==FRAME_PICTURE) ? MC_FRAME : MC_FIELD;
/* derive motion_vector_count, mv_format and dmv, (table 6-17, 6-18) */
if (picture_structure == FRAME_PICTURE)
{
motion_vector_count = (motion_type == MC_FIELD) ? 2 : 1;
mv_format = (motion_type == MC_FRAME) ? MV_FRAME : MV_FIELD;
}
else
{
motion_vector_count = (motion_type == MC_16X8) ? 2 : 1;
mv_format = MV_FIELD;
}
dmv = (motion_type == MC_DMV) ? 1 : 0; /* dual prime */
/*
field mv predictions in frame pictures have to be scaled
ISO/IEC 13818-2 section 7.6.3.1 Decoding the motion vectors
*/
mvscale = ((mv_format==MV_FIELD) && (picture_structure == FRAME_PICTURE)) ? 1 : 0;
/* get dct_type (frame DCT / field DCT) */
dct_type = (picture_structure == FRAME_PICTURE) && (frame_pred_frame_dct < 1)
&& ((macroblock_type & (MACROBLOCK_PATTERN|MACROBLOCK_INTRA)) > 0 )
? Get_Bits(1) : 0;
/* return values */
pmacroblock_type[0] = macroblock_type;
pmotion_type[0] = motion_type;
pmotion_vector_count[0] = motion_vector_count;
pmv_format[0] = mv_format;
pdmv[0] = dmv;
pmvscale[0] = mvscale;
pdct_type[0] = dct_type;
}
private int Get_macroblock_type()
{
int macroblock_type=0;
switch (picture_coding_type)
{
case I_TYPE:
macroblock_type = Get_I_macroblock_type();
break;
case P_TYPE:
macroblock_type = Get_P_macroblock_type();
break;
case B_TYPE:
macroblock_type = Get_B_macroblock_type();
break;
}
return macroblock_type;
}
private int Get_I_macroblock_type()
{
if (Get_Bits(1) > 0)
return 1;
if (Get_Bits(1) < 1)
Fault_Flag = 2;
return 17;
}
private int Get_P_macroblock_type()
{
int code;
if ((code = Show_Bits(6)) >= 8)
{
code >>= 3;
Flush_Bits(PMBtab0[code][1]);
return PMBtab0[code][0];
}
if (code == 0)
{
Fault_Flag = 2;
return 0;
}
Flush_Bits(PMBtab1[code][1]);
return PMBtab1[code][0];
}
private int Get_B_macroblock_type()
{
int code;
if ((code = Show_Bits(6)) >= 8)
{
code >>= 2;
Flush_Bits(BMBtab0[code][1]);
return BMBtab0[code][0];
}
if (code == 0)
{
Fault_Flag = 2;
return 0;
}
Flush_Bits(BMBtab1[code][1]);
return BMBtab1[code][0];
}
private int Get_motion_code()
{
int code;
if (Get_Bits(1) > 0)
return 0;
if ((code = Show_Bits(9)) >= 64)
{
code >>= 6;
Flush_Bits(MVtab0[code][1]);
return ((Get_Bits(1) > 0) ? -MVtab0[code][0] : MVtab0[code][0]);
}
if (code >= 24)
{
code >>= 3;
Flush_Bits(MVtab1[code][1]);
return ((Get_Bits(1) > 0) ? -MVtab1[code][0] : MVtab1[code][0]);
}
if ((code -= 12) < 0)
{
Fault_Flag = 10;
return 0;
}
Flush_Bits(MVtab2[code][1]);
return ((Get_Bits(1)>0) ? -MVtab2[code][0] : MVtab2[code][0]);
}
/**
* get differential motion vector (for dual prime prediction)
*/
private int Get_dmvector()
{
if (Get_Bits(1) > 0)
return ((Get_Bits(1) > 0) ? -1 : 1);
else
return 0;
}
/**
* performs YUV to RGB conversion
*/
private int YUVtoRGB(int YUV)
{
int T = 0xFF;
int Y = 0xFF & YUV>>>16;
int Cb = 0xFF & YUV>>>8;
int Cr = 0xFF & YUV;
if (Y == 0)
return 0;
int R = (int)((float)Y +1.402f * (Cr-128));
int G = (int)((float)Y -0.34414 * (Cb-128) -0.71414 * (Cr-128));
int B = (int)((float)Y +1.722 * (Cb-128));
R = R < 0 ? 0 : (R > 0xFF ? 0xFF : R);
G = G < 0 ? 0 : (G > 0xFF ? 0xFF : G);
B = B < 0 ? 0 : (B > 0xFF ? 0xFF : B);
return (T<<24 | R<<16 | G<<8 | B);
}
/**
* scales source picture to 2nd picture of memoryimagesource
* includes YUV to RGB conversion
*/
private void scale_Picture()
{
scale_Picture(0);
}
/**
* scales source picture to 2nd picture of memoryimagesource
* includes YUV to RGB conversion
*/
private void scale_Picture(int silent)
{
Arrays.fill(pixels2, 0xFF505050);
int x_offset = getMpg2AspectRatioOffset();
if (x_offset > 0 && preview_horizontal_size != 512)
x_offset = (int)((preview_horizontal_size - Math.round(preview_vertical_size * 1.33333)) / 2.0);
int z_horizontal_size = horizontal_size;
int z_vertical_size = vertical_size;
int new_x = zoomArea[0];
float Y = 0, X = 0, X_Off = 0;
switch (zoomMode)
{
case 1:
if (x_offset > 0) //LB zoom 4:3
{
x_offset = 0;
z_vertical_size = vertical_size - (vertical_size>>>2);
Y += vertical_size>>>3;
}
break;
case 2:
if (x_offset == 0) //zoom anamorphics
{
X_Off = (new_x * horizontal_size) / preview_horizontal_size;
X += X_Off;
Y += (zoomArea[1] * vertical_size) / preview_vertical_size;
z_horizontal_size = (zoomArea[2] * horizontal_size) / preview_horizontal_size;
z_vertical_size = (zoomArea[3] * vertical_size) / preview_vertical_size;
}
else //zoom 4:3
{
if (new_x < x_offset)
new_x = x_offset = 0;
else
new_x -= x_offset;
X_Off = (int) ((new_x * horizontal_size) / (preview_vertical_size * 1.33333));
X += X_Off;
Y += (zoomArea[1] * vertical_size) / preview_vertical_size;
z_horizontal_size = (int) ((zoomArea[2] * horizontal_size) / (preview_vertical_size * 1.33333));
z_vertical_size = (zoomArea[3] * vertical_size) / preview_vertical_size;
x_offset = 0;
}
}
int nx = preview_horizontal_size - x_offset;
float Xdecimate = z_horizontal_size / (float) (nx - x_offset);
float Ydecimate = z_vertical_size / (float) preview_vertical_size;
//~50ms
for (int y = 0, tmp1, tmp2; Coded_Picture_Width >= 0 && Y < vertical_size && y < preview_vertical_size; Y += Ydecimate, y++, X = X_Off)
{
tmp1 = y * preview_horizontal_size;
tmp2 = (int)Y * Coded_Picture_Width;
for (int x = x_offset; X < horizontal_size && x < nx; X += Xdecimate, x++)
pixels2[x + tmp1] = YUVtoRGB(pixels[(int)X + tmp2]);
}
//file props preview
if (silent == 1)
return;
if (silent == 2)
{
Common.getGuiInterface().updatePreviewPixel();
return;
}
//~100ms
Common.getGuiInterface().updatePreviewPixel();
messageStreamInfo();
/**
* expects pixels in YUV format for WSS recognition
*/
WSS.init(pixels, horizontal_size);
}
/**
* updates info field 1
*/
private void messageStreamInfo()
{
String prog[] = { "i", "p" };
info_1 = horizontal_size + "*" + vertical_size;
info_1 += prog[progressive_sequence] + " ";
info_1 += aspect_ratio_string[aspect_ratio_information] + " ";
info_1 += picture_coding_type_string[picture_coding_type];
info_1 += "(" + temporal_reference + ")";
info_1 += progressive_string[progressive_frame] + " ";
info_1 += ", " + video_format_S[video_format] + " ";
info_1 += ", " + (profile_and_level_indication==0 ? "MPEG1" : (1 & profile_and_level_indication>>>7) + "|" +
prof[7 & profile_and_level_indication>>>4] + "@" + lev[15 & profile_and_level_indication]);
info_1 += "(" + Coded_Picture_Width + "*" + Coded_Picture_Height + ") ";
info_1 += info_4;
mpg_info[1] = horizontal_size + " * " + vertical_size + prog[progressive_sequence];
mpg_info[1] += " @ " + String.valueOf((Math.round(frame_rate * 1000) / 1000.0f)) + " fps ";
mpg_info[3] = "DAR(PAR): " + aspect_ratio_string[aspect_ratio_information];
mpg_info[0] = (profile_and_level_indication == 0 ? "MPEG-1" : "MPEG-2 " + prof[7 & profile_and_level_indication>>>4] + "@" + lev[15 & profile_and_level_indication]) + " " + (1 & profile_and_level_indication>>>7);
if (profile_and_level_indication != 0)
mpg_info[0] += info_4;
mpg_info[5] = "SDE: " + video_format_S[video_format];
mpg_info[5] += info_3;
mpg_info[11] = "Pic.Type: " + picture_coding_type_string[picture_coding_type] + "-" + progressive_string[progressive_frame] + " t.Ref.: " + temporal_reference;
mpg_info[14] = "encod.Pixel: " + Coded_Picture_Width + " * " + Coded_Picture_Height;
}
/**
*
*/
public int[] getPixels()
{
return pixels;
}
/**
*
*/
public int[] getPreviewPixel()
{
return pixels2;
}
/**
*
*/
public void setPreviewSize(int w, int h)
{
preview_horizontal_size = w;
preview_vertical_size = h;
if (pixels2.length != preview_horizontal_size * preview_vertical_size)
pixels2 = new int[preview_horizontal_size * preview_vertical_size];
else
Arrays.fill(pixels2, 0);
scale_Picture(2);
}
/**
*
*/
public void clearPreviewPixel()
{
info_1 = "";
info_2 = "";
info_3 = "";
info_4 = "";
Arrays.fill(mpg_info, "");
Arrays.fill(pixels2, 0xFF505050);
WSS.init(new int[0], 0);
Common.getGuiInterface().updatePreviewPixel();
}
/**
*
*/
public int getWidth()
{
return horizontal_size;
}
/**
*
*/
public int getHeight()
{
return vertical_size;
}
/**
*
*/
public int getAspectRatio()
{
return aspect_ratio_information;
}
/**
*
*/
public int getMpg2AspectRatioOffset()
{
int value = ((getAspectRatio() == 3 || getAspectRatio() == 4) && profile_and_level_indication != 0) ? 0 : 64;
return value;
}
/**
*
*/
public String getInfo_1()
{
return info_1;
}
/**
*
*/
public String getInfo_2()
{
return info_2;
}
/**
*
*/
public String[] getMpgInfo()
{
return mpg_info;
}
/**
*
*/
public void resetProcessedPosition()
{
PositionList.clear();
}
/**
*
*/
public void setProcessedPosition(long value, List previewList)
{
resetProcessedPosition();
PositionList.add(new Long(value));
for (int i = 0, j = previewList.size(); i < j; i++)
PositionList.add(new Long(((PreviewObject) previewList.get(i)).getEnd()));
}
/**
*
*/
public List getPositions()
{
return PositionList;
}
/**
*
*/
public void setPidAndFileInfo(String str)
{
processedPidAndFile = str;
}
/**
*
*/
public String getPidAndFileInfo()
{
return processedPidAndFile;
}
/**
*
*/
public int getZoomMode()
{
return zoomMode;
}
/**
*
*/
public void setZoomMode(int value)
{
zoomMode = value;
if (info_2.length() > 0)
scale_Picture();
}
/**
*
*/
public void setZoomMode(int[] values)
{
System.arraycopy(values, 0, zoomArea, 0, zoomArea.length);
setZoomMode(2);
}
/**
*
*/
public String getZoomInfo()
{
if (zoomMode == 1 && getAspectRatio() != 3 && getAspectRatio() != 4)
return "LB Zoom";
else if (zoomMode == 2)
return ("Manual Zoom: x" + zoomArea[0] + ", y" + zoomArea[1] + " - " + zoomArea[2] + "*" + zoomArea[3]);
return "";
}
/**
*
*/
public String getWSSInfo()
{
return WSS.getWSS();
}
/**
*
*/
public boolean getPalPlusInfo()
{
return WSS.isPalPlus();
}
/**
*
*/
public String getWSSFormatInfo()
{
return WSS.getFormatInfo();
}
/**
*
*/
public int getErrors()
{
return (0 | (ERROR1 ? 1 : 0) | (ERROR2 ? 2 : 0) | (ERROR3 ? 4 : 0) | (ERROR4 ? 8 : 0) | (ERROR5 ? 0x10 : 0) | (ERROR6 ? 0x20 : 0));
}
/**
*
*/
private void repaint()
{
Common.getGuiInterface().repaintPicturePanel();
}
/**
* create new smaller cutimage pixel data
*/
public int[] getCutImage()
{
int[] cut_image = new int[pixels2.length];
System.arraycopy(pixels2, 0, cut_image, 0, pixels2.length);
return cut_image;
}
/**
* create new smaller cutimage pixel data
*/
public int[] getScaledCutImage()
{
int new_width = cutview_horizontal_size;
int new_height = cutview_vertical_size;
int source_width = preview_horizontal_size;
int source_height = preview_vertical_size;
float Y = 0;
float X = 0;
float decimate_height = (float)source_height / new_height;
float decimate_width = (float)source_width / new_width;
int[] cut_image = new int[new_width * new_height];
for (int y = 0; Y < source_height && y < new_height; Y += decimate_height, y++, X = 0)
for (int x = 0; X < source_width && x < new_width; X += decimate_width, x++)
cut_image[x + (y * new_width)] = pixels2[(int)X + ((int)Y * source_width)];
return cut_image;
}
/**
* add new smaller matrix cutimage pixel data
* the mixed overlay image will be partialy overridden, in a 5x5 matrix of 100*56 each (in 512*288)
*/
public void getScaledCutMatrixImage(int[] matrix_image, int new_width, int new_height, int matrix_x, int matrix_y)
{
int source_width = preview_horizontal_size;
int source_height = preview_vertical_size;
float Y = 0;
float X = 0;
float decimate_height = (float)source_height / new_height;
float decimate_width = (float)source_width / new_width;
int[] cut_image = new int[new_width * new_height];
for (int y = 0; Y < source_height && y < new_height; Y += decimate_height, y++, X = 0)
for (int x = 0; X < source_width && x < new_width; X += decimate_width, x++)
matrix_image[(matrix_x + x) + ((matrix_y + y) * source_width)] = pixels2[(int)X + ((int)Y * source_width)];
// matrix_image[x + (y * new_width)] = pixels2[(int)X + ((int)Y * source_width)];
}
/**
* returns arrays byteposition offset of 1st successful decoded GOP
* interface, entry point to decode picture for preview
*
* @param1 - ES byte array
* @param2 - search direction
* @param3 - enable GOPheader alignment
* @param4 - simple_fast decode
* @return
*/
public long decodeArray(byte array[], boolean direction, boolean _viewGOP, boolean fast, int yGain)
{
return decodeArray(array, 0, direction, _viewGOP, fast, yGain, false);
}
/**
* returns arrays byteposition offset of 1st successful decoded GOP
* interface, entry point to decode picture for preview
*
* @param1 - ES byte array
* @param2 - search direction
* @param3 - enable GOPheader alignment
* @param4 - simple_fast decode
* @return
*/
public long decodeArray(byte array[], boolean direction, boolean _viewGOP, boolean fast, int yGain, boolean silent)
{
return decodeArray(array, 0, direction, _viewGOP, fast, yGain, silent);
}
/**
* returns arrays byteposition offset of 1st successful decoded GOP
* interface, entry point to decode picture for preview
*
* @param1 - ES byte array
* @param2 - start index position
* @param3 - search direction
* @param4 - enable GOPheader alignment
* @param5 - simple_fast decode
* @return
*/
public long decodeArray(byte[] array, int start_position, boolean direction, boolean _viewGOP, boolean fast, int yGain, boolean silent)
{
setAcceleration(Common.getSettings().getBooleanProperty(Keys.KEY_Preview_fastDecode));
FAST = fast;
DIRECTION = direction;
YGain = yGain;
ERROR1 = false;
ERROR2 = false;
ERROR3 = false;
ERROR4 = false;
ERROR5 = false;
ERROR6 = false;
Arrays.fill(LastPosVal, -1);
buf = array;
BufferPos = start_position;
BitPos = BufferPos<<3;
StartPos = BufferPos;
viewGOP = _viewGOP;
if (DIRECTION)
{
StartPos = BufferPos = buf.length - 4;
BitPos = BufferPos<<3;
}
try {
while (BufferPos < buf.length && BufferPos >= 0)
{
ERROR_CODE1 = extern_Get_Hdr();
if ( ERROR_CODE1 == 1 )
{
if (picture_coding_type != I_TYPE)
{
BufferPos += 2048;
continue;
}
InitialDecoder();
Decode_Picture();
scale_Picture(silent ? 1 : 0);
return StartPos;
}
else if (ERROR_CODE1 == 2 )
{
return 0;
}
else
BufferPos++;
}
ERROR2 = true;
} catch (ArrayIndexOutOfBoundsException ae) {
ERROR1 = true;
} catch (Error ee) {
ERROR1 = true;
ERROR6 = ee.toString().indexOf("OutOfMemory") > 0;
}
if (ERROR1 && !ERROR6)
if (parseH264(buf, buf.length, mpg_info))
ERROR4 = true;
//H264Decoder h264 = new H264Decoder();
//ERROR4 = h264.parseStream(buf, start_position);
//H264Decoder1 h264 = new H264Decoder1();
//ERROR4 = h264.parseStream(buf, start_position);
scale_Picture(ERROR4 ? 2 : 1);
return 0;
}
////
/**
* short analysis of H.264
*/
public boolean parseH264(byte[] array, int length, String[] h264_info)
{
byte[] check = new byte[100];
boolean run_in = false;
boolean sequ_found = false;
int[] temp_values = new int[12];
int[] BitPosition = { 0 };
for (int i = 0, flag, nal_unit, nal_ref, profile_idc, zero, level_idc, hori, vert, j = length - 50; i < j; i++)
{
if (array[i] != 0 || array[1 + i] != 0 || array[2 + i] != 0 || array[3 + i] != 1)
continue;
BitPosition[0] = (4 + i)<<3;
zero = getBits(array, BitPosition, 1); //forb_zero = 0x80 & check[4 + i];
nal_ref = getBits(array, BitPosition, 2); //nal_ref = (0xE0 & check[4 + i])>>>5;
nal_unit = getBits(array, BitPosition, 5); //nal_unit = 0x1F & check[4 + i];
if (zero == 0 && nal_unit == 9) //run-in
{
run_in = true;
continue;
}
if (!run_in || zero != 0)
continue;
if (sequ_found && (nal_unit == 1 || nal_unit == 5))
return slice_wo_partitioning(array, i, nal_unit, temp_values);
else if (nal_unit != 7)
continue;
//emulation prevention
for (int m = i + 5, rbsp = 0; rbsp < 100 - 3; m++)
{
if (array[m] == 0 && array[m + 1] == 0 && array[m + 2] == 3)
{
rbsp += 2; //2 bytes value 0
m += 2; //emulation_prevention_three_byte /* equal to 0x03 */
}
else
check[rbsp++] = array[m];
}
//reset for check
BitPosition[0] = 0;
//seq_param
profile_idc = getBits(check, BitPosition, 8); //profile = 0xFF & check[5 + i];
getBits(check, BitPosition, 4); //constraint 0,1,2,3
zero = getBits(check, BitPosition, 4); //4 res zero_bits
if (zero != 0)
continue;
sequ_found = true;
level_idc = getBits(check, BitPosition, 8); //0xFF & check[7 + i];
flag = getCodeNum(check, BitPosition); // seq_parameter_set_id 0 ue(v)
int chroma_format_idc = 1; //dflt
if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 44 || profile_idc == 244)
{
chroma_format_idc = getCodeNum(check, BitPosition); //chroma_format_idc 0 ue(v)
if (chroma_format_idc == 3)
getBits(check, BitPosition, 1); //separate_colour_plane_flag 0 u(1)
getCodeNum(check, BitPosition); //bit_depth_luma_minus8 0 ue(v)
getCodeNum(check, BitPosition); //bit_depth_chroma_minus8 0 ue(v)
getBits(check, BitPosition, 1); //qpprime_y_zero_transform_bypass_flag 0 u(1)
flag = getBits(check, BitPosition, 1); //seq_scaling_matrix_present_flag 0 u(1)
if (flag == 1)
{
for (int l = 0; l < ((chroma_format_idc != 3) ? 8 : 12); l++)
{
flag = getBits(check, BitPosition, 1); //seq_scaling_list_present_flag[ i ] 0 u(1)
if (flag == 1)
if (l < 6)
scaling_list(check, BitPosition, null, 16, null); //scaling_list( ScalingList4x4[ i ], 16,
//UseDefaultScalingMatrix4x4Flag[ i ])
else
scaling_list(check, BitPosition, null, 64, null); //scaling_list( ScalingList8x8[ i � 6 ], 64,
//UseDefaultScalingMatrix8x8Flag[ i � 6 ] )
}
}
}
temp_values[0] = 4 + getCodeNum(check, BitPosition); // log2_max_frame_num_minus4 0 ue(v)
temp_values[2] = getCodeNum(check, BitPosition); // pic_order_cnt_type 0 ue(v)
if (temp_values[2] == 0)
temp_values[3] = 4 + getCodeNum(check, BitPosition); // log2_max_pic_order_cnt_lsb_minus4 0 ue(v)
else if (temp_values[2] == 1)
{
getBits(check, BitPosition, 1); //delta_pic_order_always_zero_flag 0 u(1)
getSignedCodeNum(check, BitPosition); //offset_for_non_ref_pic 0 se(v)
getSignedCodeNum(check, BitPosition); //offset_for_top_to_bottom_field 0 se(v)
flag = getCodeNum(check, BitPosition); // num_ref_frames_in_pic_order_cnt_cycle 0 ue(v)
for (int k = 0; k < flag; k++)
getSignedCodeNum(check, BitPosition); //offset_for_ref_frame[ i ] 0 se(v)
}
flag = getCodeNum(check, BitPosition); //num_ref_frames 0 ue(v)
getBits(check, BitPosition, 1); //gaps_in_frame_num_value_allowed_flag 0 u(1)
hori = 16 * (1 + getCodeNum(check, BitPosition)); //pic_width_in_mbs_minus1 0 ue(v)
vert = 16 * (1 + getCodeNum(check, BitPosition)); //pic_height_in_map_units_minus1 0 ue(v)
flag = getBits(check, BitPosition, 1); //frame_mbs_only_flag 0 u(1)
temp_values[5] = flag;
info_2 = "MPEG-4/H.264, " + hori + "*" + (flag == 0 ? vert<<1 : vert);
Arrays.fill(h264_info, "");
h264_info[1] = "" + hori + " * " + (flag == 0 ? vert<<1 : vert) + " @ ";
h264_info[16] = String.valueOf(hori);
h264_info[17] = String.valueOf(flag == 0 ? vert<<1 : vert);
h264_info[4] = "Chroma: " + cf[chroma_format_idc];
h264_info[0] = "MPEG-4/H.264 ";
if (profile_idc == 66)
h264_info[0] += "Base@";
else if (profile_idc == 77)
h264_info[0] += "Main@";
else if (profile_idc == 88)
h264_info[0] += "Ext@";
else if (profile_idc == 100)
h264_info[0] += "High@";
else if (profile_idc == 110)
h264_info[0] += "High10@";
else if (profile_idc == 122)
h264_info[0] += "High422";
else if (profile_idc == 144)
h264_info[0] += "High444@";
else if (profile_idc == 44)
h264_info[0] += "High444a@";
else if (profile_idc == 244)
h264_info[0] += "High444b@";
//else if (profile_idc == 166)
// vbasics[2] = "High@";
//else if (profile_idc == 188)
// vbasics[2] = "High@";
else
h264_info[0] += String.valueOf(profile_idc) + "@";
h264_info[0] += String.valueOf(level_idc / 10.0);
h264_info[8] = "Main Header: " + SH[1];
if (flag == 0) //if( !frame_mbs_only_flag )
getBits(check, BitPosition, 1); //mb_adaptive_frame_field_flag 0 u(1)
getBits(check, BitPosition, 1); //direct_8x8_inference_flag 0 u(1)
flag = getBits(check, BitPosition, 1); //frame_cropping_flag 0 u(1)
if (flag == 1) //if( frame_cropping_flag ) {
{
getCodeNum(check, BitPosition); //frame_crop_left_offset 0 ue(v)
getCodeNum(check, BitPosition); //frame_crop_right_offset 0 ue(v)
getCodeNum(check, BitPosition); //frame_crop_top_offset 0 ue(v)
getCodeNum(check, BitPosition); //frame_crop_bottom_offset 0 ue(v)
}
flag = getBits(check, BitPosition, 1); //vui_parameters_present_flag 0 u(1)
if (flag == 1) //if( vui_parameters_present_flag )
vui_parameters(check, BitPosition, h264_info); //vui_parameters( ) 0
//rbsp_trailing_bits( ) 0
continue;
//return true;
}
return false;
}
//
private int getSignedCodeNum(byte[] array, int[] BitPosition)
{
int codeNum = getCodeNum(array, BitPosition);
codeNum = (codeNum & 1) == 0 ? codeNum>>>1 : -(codeNum>>>1);
return codeNum;
}
//
private int getCodeNum(byte[] array, int[] BitPosition)
{
int leadingZeroBits = -1;
int codeNum;
for (int b = 0; b == 0; leadingZeroBits++)
b = getBits(array, BitPosition, 1);
codeNum = (1<<leadingZeroBits) - 1 + getBits(array, BitPosition, leadingZeroBits);
return codeNum;
}
// 7.3.2.1.1 Scaling list syntax
private void scaling_list(byte[] check, int[] BitPosition, int[] scalingList, int sizeOfScalingList, boolean[] useDefaultScalingMatrixFlag)
{
int lastScale = 8;
int nextScale = 8;
for (int j = 0; j < sizeOfScalingList; j++)
{
if (nextScale != 0)
{
int delta_scale = getSignedCodeNum(check, BitPosition); //delta_scale 0 | 1 se(v)
nextScale = (lastScale + delta_scale + 256) % 256;
//useDefaultScalingMatrixFlag = ( j == 0 && nextScale == 0 );
}
//scalingList[ j ] = ( nextScale = = 0 ) ? lastScale : nextScale
lastScale = (nextScale == 0 ) ? lastScale : nextScale; //lastScale = scalingList[ j ]
}
}
// E1.1 VUI parameters syntax
private void vui_parameters(byte[] check, int[] BitPosition, String[] h264_info)
{
String[] aspect_ratio_string_h264 = {
"Unspec.", "1:1", "12:11", "10:11", "16:11", "40:33", "24:11", "20:11",
"32:11", "80:33", "18:11", "15:11", "64:33", "160:99", "4:3", "3:2", "2:1"
};
double[] aspect_ratio_double_h264 = {
1.0, 1.0, 1.0909, 0.90909, 1.45454, 1.21212, 2.18181, 1.81818,
2.90909, 2.42424, 1.63636, 1.36364, 1.93939, 1.61616, 1.33333, 1.5, 2
};
int flag = getBits(check, BitPosition, 1); //aspect_ratio_info_present_flag 0 u(1)
if (flag == 1) //if( aspect_ratio_info_present_flag ) {
{
int aspect_ratio_idc = getBits(check, BitPosition, 8); //aspect_ratio_idc 0 u(8)
if (aspect_ratio_idc == 255) //if( aspect_ratio_idc = = Extended_SAR ) {
{
int sar_w = getBits(check, BitPosition, 16); //sar_width 0 u(16)
int sar_h = getBits(check, BitPosition, 16); //sar_height 0 u(16)
h264_info[3] = "SAR: " + sar_w + ":" + sar_h;
h264_info[3] += " >> " + String.valueOf((int)(Double.parseDouble(h264_info[16]) * sar_w / sar_h)) + "*" + h264_info[17];
}
else
{
h264_info[3] = "SAR: " + (aspect_ratio_idc < 17 ? aspect_ratio_string_h264[aspect_ratio_idc] : "res.");
h264_info[3] += " >> " + (aspect_ratio_idc < 17 ? String.valueOf(Math.round(Double.parseDouble(h264_info[16]) * aspect_ratio_double_h264[aspect_ratio_idc])) : "res.") + "*" + h264_info[17];
}
}
h264_info[16] = "";
h264_info[17] = "";
flag = getBits(check, BitPosition, 1); //overscan_info_present_flag 0 u(1)
if (flag == 1) //if( overscan_info_present_flag )
getBits(check, BitPosition, 1); //overscan_appropriate_flag 0 u(1)
flag = getBits(check, BitPosition, 1); //video_signal_type_present_flag 0 u(1)
if (flag == 1) //if( video_signal_type_present_flag ) {
{
flag = getBits(check, BitPosition, 3); //video_format 0 u(3)
h264_info[5] = "SDE: " + video_format_S[flag];
getBits(check, BitPosition, 1); //video_full_range_flag 0 u(1)
flag = getBits(check, BitPosition, 1); //colour_description_present_flag 0 u(1)
if (flag == 1) //if( colour_description_present_flag ) {
{
getBits(check, BitPosition, 8); //colour_primaries 0 u(8)
getBits(check, BitPosition, 8); //transfer_characteristics 0 u(8)
getBits(check, BitPosition, 8); //matrix_coefficients 0 u(8)
}
}
flag = getBits(check, BitPosition, 1); //chroma_loc_info_present_flag 0 u(1)
if (flag == 1) //if( chroma_loc_info_present_flag ) {
{
getCodeNum(check, BitPosition); //chroma_sample_loc_type_top_field 0 ue(v)
getCodeNum(check, BitPosition); //chroma_sample_loc_type_bottom_field 0 ue(v)
}
flag = getBits(check, BitPosition, 1); //timing_info_present_flag 0 u(1)
if (flag == 1) //if( timing_info_present_flag ) {
{
int num_units_ticks = getBits(check, BitPosition, 24)<<8 | getBits(check, BitPosition, 8); //num_units_in_tick 0 u(32)
int time_scale = getBits(check, BitPosition, 24)<<8 | getBits(check, BitPosition, 8); //time_scale 0 u(32)
int fixed_framerate = getBits(check, BitPosition, 1); //fixed_frame_rate_flag 0 u(1)
h264_info[1] += ((1000 * time_scale / (2 * num_units_ticks)) / 1000.0) + " fps (" + (fixed_framerate == 1 ? "f)" : "v)");
}
//getBits(check, BitPosition, 1); //nal_hrd_parameters_present_flag 0 u(1)
//if( nal_hrd_parameters_present_flag )
//hrd_parameters( )
//vcl_hrd_parameters_present_flag 0 u(1)
//if( vcl_hrd_parameters_present_flag )
//hrd_parameters( )
//if( nal_hrd_parameters_present_flag | | vcl_hrd_parameters_present_flag )
//low_delay_hrd_flag 0 u(1)
//pic_struct_present_flag 0 u(1)
//bitstream_restriction_flag 0 u(1)
//if( bitstream_restriction_flag ) {
//motion_vectors_over_pic_boundaries_flag 0 u(1)
//max_bytes_per_pic_denom 0 ue(v)
//max_bits_per_mb_denom 0 ue(v)
//log2_max_mv_length_horizontal 0 ue(v)
//log2_max_mv_length_vertical 0 ue(v)
//num_reorder_frames 0 ue(v)
//max_dec_frame_buffering 0 ue(v)
//}
}
// 7.3.2.8 + 7.3.3 slice w/o partitioning
private boolean slice_wo_partitioning(byte[] check, int offset, int unittype, int[] temp_values)
{
int flag;
int[] BitPosition = { 0 };
BitPosition[0] = (5 + offset)<<3;
flag = getCodeNum(check, BitPosition); //first_mb_in_slice 2 ue(v)
temp_values[11] = getCodeNum(check, BitPosition); //slice_type 2 ue(v)
flag = getCodeNum(check, BitPosition); //pic_parameter_set_id 2 ue(v)
temp_values[1] = getBits(check, BitPosition, temp_values[0]);//frame_num 2 u(v)
if (temp_values[5] == 0) //if( !frame_mbs_only_flag )
{
temp_values[6] = getBits(check, BitPosition, 1); //field_pic_flag 2 u(1)
if (temp_values[6] == 1) //if( field_pic_flag )
temp_values[7] = getBits(check, BitPosition, 1); //bottom_field_flag 2 u(1)
}
int pic_id = -1;
if (unittype == 5) //if( nal_unit_type = = 5 )
pic_id = getCodeNum(check, BitPosition); //idr_pic_id 2 ue(v)
if (temp_values[2] == 0) //if( pic_order_cnt_type = = 0 )
{
temp_values[4] = getBits(check, BitPosition, temp_values[3]); //pic_order_cnt_lsb 2 u(v)
//if( pic_order_present_flag && !field_pic_flag )
//delta_pic_order_cnt_bottom 2 se(v)
}
String picture_code1[] = { "P", "B", "I", "SP", "SI", "P", "B", "I", "SP", "SI", "", "", "", "" };
String picture_code2[] = { "P", "B", "I", "SP", "SI", "P+", "B+", "I+", "SP+", "SI+", "", "", "", "" };
String unit_code1[] = { "nonIDR", "IDR" }; //1 + 5 pre-filtered
mpg_info[11] = "Pic.Type: " + picture_code1[temp_values[11]] + "-" + progressive_string[1 - temp_values[6]] + " / " + unit_code1[unittype>>>2] + (pic_id != - 1 ? " / Id: " + pic_id : "");
String picture_struc[][] = {{ "Frame", "Frame" },{ "Top", "Bottom" }};
mpg_info[12] = "Pic.Struct.: " + picture_struc[temp_values[6]][temp_values[7]];
mpg_info[13] = "Pic.Ord.: " + temp_values[4] + " FrNum.: " + temp_values[1];
mpg_info[14] = "SliceType: " + picture_code2[temp_values[11]];
mpg_info[15] = "Ref.Idx: " + (7 & check[4 + offset]>>5);
//if( pic_order_cnt_type = = 1 && !delta_pic_order_always_zero_flag ) {
//delta_pic_order_cnt[ 0 ] 2 se(v)
//if( pic_order_present_flag && !field_pic_flag )
//delta_pic_order_cnt[ 1 ] 2 se(v)
//}
return true;
}
//
private int getBits(byte[] array, int[] BitPosition, int N)
{
int Pos, Val;
Pos = BitPosition[0]>>>3;
if (N == 0)
return 0;
if (Pos >= array.length - 4)
{
BitPosition[0] += N;
return -1;
}
Val = (0xFF & array[Pos])<<24 |
(0xFF & array[Pos + 1])<<16 |
(0xFF & array[Pos + 2])<<8 |
(0xFF & array[Pos + 3]);
Val <<= BitPosition[0] & 7;
Val >>>= 32 - N;
BitPosition[0] += N;
return Val;
}
///
}