/* 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; } /// }