/*
* @(#)GOPEditor
*
* Copyright (c) 2008 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.
*
*
* 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.gui;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.table.TableModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import net.sourceforge.dvb.projectx.common.Common;
public class GOPEditor extends JDialog {
private StreamObject streamobject;
private ArrayList sourcedata = new ArrayList();
private ArrayList sinkdata = new ArrayList();
private JList sourcelist = new JList();
private JList sinklist = new JList();
private JTable tableView;
private JTextField textField;
private Thread thread;
private byte[] data = null;
private long[][] pts_indices = null;
private int s1 = 12, s2 = 9;
private boolean stopCount = false;
private int cnt = 0;
private final int FRAME = 0;
private final int SEQUENCE = 0xB3;
private final int SEQUENCE_END = 0xB7;
private final int GOP = 0xB8;
private final int USER_DATA = 0xB2;
private final int EXTENSION = 0xB5;
private double lastFrameRate = -1;
private Object[][] ObjectTable = new Object[s1][s2];
/**
*
*/
public GOPEditor(JFrame frame)
{
super(frame, "GOP Editor", true);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
close();
}
});
JPanel container = new JPanel();
container.setLayout(new GridLayout(1,2));
setBounds(200, 100, 770, 500);
container.add(buildPanel1());
getContentPane().add(container);
}
/**
*
*/
protected JPanel buildPanel1()
{
JPanel panel1 = new JPanel();
panel1.setLayout(new BoxLayout(panel1, BoxLayout.X_AXIS));
JButton undoButton = new JButton("Reset All");
undoButton.setMnemonic('o');
undoButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e)
{
reload();
}
});
JButton moveButton = new JButton("copy chunk");
moveButton.setMnemonic('c');
moveButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e)
{
copy();
}
});
JButton removeButton = new JButton("remove chunk(s)");
removeButton.setMnemonic('r');
removeButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e)
{
remove();
}
});
JButton checkButton = new JButton("check changes");
checkButton.setMnemonic('e');
checkButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e)
{
check();
}
});
JButton saveButton = new JButton("save & close");
saveButton.setMnemonic('a');
saveButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e)
{
save();
}
});
JButton closeButton = new JButton("close unchanged");
closeButton.setMnemonic('u');
closeButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e)
{
close();
}
});
panel1.add(undoButton);
panel1.add(Box.createRigidArea(new Dimension(10, 1)));
panel1.add(moveButton);
panel1.add(Box.createRigidArea(new Dimension(10, 1)));
panel1.add(removeButton);
panel1.add(Box.createRigidArea(new Dimension(10, 1)));
panel1.add(checkButton);
panel1.add(Box.createRigidArea(new Dimension(10, 1)));
panel1.add(saveButton);
panel1.add(Box.createRigidArea(new Dimension(10, 1)));
panel1.add(closeButton);
JScrollPane scroll = new JScrollPane();
scroll.setViewportView(sourcelist);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(createTable(), BorderLayout.CENTER);
panel.add(textField = new JTextField());
panel.add(panel1);
return panel;
}
/**
*
*/
protected JScrollPane createTable()
{
JScrollPane scrollpane;
// final
final String[] names = {
"Chunk", "Start", "End", "t.Ref", "Delta(ms)", "ind.PTS", "Timecode", "Type", "ErrID"
};
DefaultTableCellRenderer renderer_1 = new DefaultTableCellRenderer();
DefaultTableCellRenderer renderer_2 = new DefaultTableCellRenderer();
renderer_1.setHorizontalAlignment(JLabel.RIGHT);
renderer_2.setHorizontalAlignment(JLabel.CENTER);
// Show colors by rendering them in their own color.
DefaultTableCellRenderer colorRenderer1 = new DefaultTableCellRenderer() {
Color redColor = new Color(255, 180, 180);
String str;
public void setValue(Object value)
{
setBackground(Color.white);
setText("");
if (value == null)
return;
str = value.toString();
if (!str.equals("0")) //errID
{
setText(Integer.toHexString(Integer.parseInt(str)));
setBackground(redColor);
}
}
};
colorRenderer1.setHorizontalAlignment(JLabel.CENTER);
// Show colors by rendering them in their own color.
DefaultTableCellRenderer colorRenderer2 = new DefaultTableCellRenderer() {
Color cyanColor = new Color(220, 255, 255);
Color greenColor = new Color(220, 255, 220);
Color blueColor = new Color(220, 220, 255);
Color yellowColor = new Color(255, 255, 220);
Color magentaColor = new Color(255, 220, 255);
Color redColor = new Color(255, 180, 180);
String str;
public void setValue(Object value)
{
setBackground(Color.white);
if (value == null)
{
setText("");
return;
}
str = value.toString();
setText(str);
if (str.indexOf("Frame I") >= 0)
setBackground(greenColor);
else if (str.indexOf("Frame P") >= 0)
setBackground(blueColor);
else if (str.indexOf("Frame B") >= 0)
setBackground(yellowColor);
else if (str.indexOf("Sequence") >= 0)
setBackground(cyanColor);
else if (str.indexOf("GOP") >= 0)
setBackground(magentaColor);
if (str.indexOf("!") >= 0) //error
setBackground(redColor);
// else if (str.indexOf("Frame D") >= 0)
// setBackground(whiteColor);
}
};
colorRenderer2.setHorizontalAlignment(JLabel.LEFT);
// Show colors by rendering them in their own color.
DefaultTableCellRenderer colorRenderer3 = new DefaultTableCellRenderer() {
Color redColor = new Color(255, 180, 180);
String str;
double val;
public void setValue(Object value)
{
setBackground(Color.white);
if (value == null)
{
setText("");
return;
}
str = value.toString();
setText(str);
val = Double.parseDouble(str);
if (Math.abs(val * 90.0) > getLastFrameRate() / 2.0)
setBackground(redColor);
}
};
colorRenderer3.setHorizontalAlignment(JLabel.CENTER);
// Show colors by rendering them in their own color.
DefaultTableCellRenderer colorRenderer4 = new DefaultTableCellRenderer() {
Color redColor = new Color(255, 180, 180);
String str;
public void setValue(Object value)
{
setBackground(Color.white);
setText("");
if (value == null)
return;
str = value.toString();
setText(str);
if (str.indexOf("e") >= 0) //tRef
setBackground(redColor);
}
};
colorRenderer4.setHorizontalAlignment(JLabel.CENTER);
// Create a model of the data.
TableModel dataModel = new AbstractTableModel() {
String str;
public int getColumnCount()
{
return names.length;
}
public int getRowCount()
{
return ObjectTable.length;
}
public Object getValueAt(int row, int col)
{
return ObjectTable[row][col];
}
public String getColumnName(int column)
{
return names[column];
}
public Class getColumnClass(int c)
{
Object obj = getValueAt(0, c);
if (obj == null)
return String.class;
return obj.getClass();
}
public boolean isCellEditable(int row, int col)
{
//return false;
return getColumnClass(col) == String.class;
}
public void setValueAt(Object aValue, int row, int column)
{
ObjectTable[row][column] = aValue;
}
};
// Create the table
tableView = new JTable(dataModel);
tableView.setRowHeight(20);
tableView.setGridColor(new Color(220, 220, 220));
tableView.setSelectionBackground(new Color(220, 220, 255));
tableView.setSelectionForeground(Color.black);
tableView.getColumn(names[0]).setCellRenderer(renderer_2);
tableView.getColumn(names[0]).setMaxWidth(45);
tableView.getColumn(names[1]).setCellRenderer(renderer_1);
tableView.getColumn(names[1]).setMaxWidth(70);
tableView.getColumn(names[2]).setCellRenderer(renderer_1);
tableView.getColumn(names[2]).setMaxWidth(70);
tableView.getColumn(names[3]).setMaxWidth(50);
tableView.getColumn(names[3]).setCellRenderer(colorRenderer4);
tableView.getColumn(names[4]).setCellRenderer(colorRenderer3);
tableView.getColumn(names[4]).setMaxWidth(70);
tableView.getColumn(names[5]).setCellRenderer(renderer_2);
tableView.getColumn(names[5]).setMaxWidth(100);
tableView.getColumn(names[6]).setCellRenderer(renderer_2);
tableView.getColumn(names[6]).setMaxWidth(100);
tableView.getColumn(names[7]).setMaxWidth(280);
tableView.getColumn(names[7]).setCellRenderer(colorRenderer2);
tableView.getColumn(names[8]).setMaxWidth(50);
tableView.getColumn(names[8]).setCellRenderer(colorRenderer1);
tableView.sizeColumnsToFit(JTable.AUTO_RESIZE_LAST_COLUMN);
tableView.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() < 1)
return;
int row = tableView.getSelectedRow();
// empty row
if (row >= 0 && tableView.getValueAt(row, 0) == null)
row = -1;
}
});
scrollpane = new JScrollPane(tableView);
return scrollpane;
}
/**
*
*/
private void close()
{
dispose();
}
/**
*
*/
private void remove()
{
int[] rows = tableView.getSelectedRows();
for (int i = rows.length - 1; i >= 0; i--)
sourcedata.remove(rows[i]);
setSourceTable();
}
/**
*
*/
private void copy()
{
int row = tableView.getSelectedRow();
if (row < 0)
return;
streamobject = (StreamObject) sourcedata.get(row);
if (streamobject instanceof Frame)
{
Frame frame1 = (Frame) streamobject;
Frame frame2 = new Frame();
frame2.copy(frame1.getType(), frame1.getDataType(), frame1.getOffset(), frame1.getLength(), frame1.getChunk() + 1000);
frame2.copy2(frame1.getFrameType(), frame1.getTempRef());
sourcedata.add(row + 1, frame2);
setSourceTable();
}
}
/**
*
*/
private void reload()
{
editGOP(data, pts_indices);
}
/**
*
*/
private void check()
{
}
/**
*
*/
private byte[] save()
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
int pos, len;
for (int i = 0, j = sinkdata.size(); i < j; i++)
{
streamobject = (StreamObject) sinkdata.get(i);
pos = streamobject.getOffset();
len = streamobject.getLength();
if (streamobject instanceof Frame)
{
Frame frame = (Frame) streamobject;
int val = frame.getTempRef();
if (val >= 0)
setTempRef(data, pos, val);
}
out.write(data, pos, len);
}
out.flush();
out.close();
JOptionPane.showMessageDialog(this, "export done..");
} catch (Exception e) {
System.out.println("error");
}
return out.toByteArray();
}
/**
*
*/
private void setTempRef(byte[] array, int offs, int val)
{
array[offs + 4] = (byte)(0xFF & val>>2);
array[offs + 5] = (byte)((0xC0 & val<<6) | (0x3F & array[offs + 5]));
}
/**
*
*/
private void updateTable(Object[][] objects)
{
ObjectTable = objects == null ? new Object[s1][s2] : objects;
tableView.clearSelection();
tableView.revalidate();
tableView.repaint();
}
/**
*
*/
private void setTextField(String str)
{
textField.setText(str);
}
/**
*
*/
private String getTextField()
{
return textField.getText();
}
/**
*
*/
private void setSourceTable()
{
int size = sourcedata.size();
ObjectTable = new Object[size][s2];
StreamObject obj;
for (int i = 0; i < size; i++)
{
obj = (StreamObject) sourcedata.get(i);
ObjectTable[i] = obj.getObjectTable();
}
tableView.clearSelection();
tableView.revalidate();
tableView.repaint();
}
/**
* entry point
*/
public byte[] editGOP(byte[] _data, long[][] _pts_indices)
{
int pos = 0;
int chunk = 0;
int last_id = -1;
int lastSelect = -1;
int sliceCount = 0;
data = _data;
pts_indices = _pts_indices;
setTextField("");
sourcedata.clear();
sinkdata.clear();
for (int i = 0, j = 0, slice_id = -1, k = data.length - 3, id; i < k; i++)
{
if (data[i] != 0 || data[i + 1] != 0 || data[i + 2] != 1)
continue;
id = 0xFF & data[i + 3];
if (id > FRAME && id < 0xB0)
{
if (id == slice_id)
sliceCount |= 0x10000;
else if (id < slice_id)
sliceCount |= 0x20000;
else if (id > slice_id + 1)
sliceCount |= 0x40000;
sliceCount++;
}
switch (id) //include extensions 0xB5 in main header length
{
case FRAME:
case SEQUENCE:
case SEQUENCE_END:
case GOP:
// case USER_DATA:
setSliceInfo(sliceCount);
if (id == FRAME)
{
sliceCount = 0;
slice_id = id;
}
if (last_id < 0)
{
last_id = id;
j = i;
continue;
}
streamobject = setObject(last_id, pos, data, j, i - j, chunk++);
for (int p = pts_indices[0].length - 1; p >= 0; p--)
{
if (lastSelect != p && pts_indices[1][p] <= j && streamobject != null)
{
streamobject.setPTSValue(pts_indices[0][p]);
lastSelect = p;
break;
}
}
last_id = id;
j = i;
break;
default:
if (id > FRAME && id < 0xB0)
slice_id = id;
continue;
}
}
setSliceInfo(sliceCount); //last frame update
updatePTSInfo();
validatePTSInfo();
validateSequence();
getErrors();
setSourceTable();
setSourceList();
setSinkList();
// edit here - modal dialog
this.show();
return data;
}
/**
*
*/
private void setSliceInfo(int val)
{
if (streamobject != null && streamobject.getType() == 0) // is next frame
{
String str = streamobject.getDataType() + " - Slices: " + String.valueOf(0xFFFF & val);
if ((0x10000 & val) != 0)
str += " dupl! ";
if ((0x20000 & val) != 0)
str += " sequ! ";
if ((0x40000 & val) != 0)
str += " miss! ";
streamobject.setError(streamobject.getError() | val>>>16);
streamobject.setDataType(str);
}
}
/**
*
*/
private void updatePTSInfo()
{
long pts = -1;
// set PTS of first frame if it's empty
for (int i = 0, j = sourcedata.size(); i < j; i++)
{
streamobject = (StreamObject) sourcedata.get(i);
if (streamobject.getPTSValue() != -1)
pts = streamobject.getPTSValue();
if (streamobject instanceof Frame)
{
if (streamobject.getPTSValue() == -1 && pts != -1)
streamobject.setPTSValue(pts);
break;
}
}
}
/**
*
*/
private void validatePTSInfo()
{
Frame frame;
double zero_pts = -1, pts;
int tRef;
double tmp1, tmp2, framerate = getLastFrameRate();
if (framerate < 0)
return;
for (int i = 0, j = sourcedata.size(); i < j; i++)
{
streamobject = (StreamObject) sourcedata.get(i);
if (streamobject instanceof Frame)
{
frame = (Frame) streamobject;
tRef = frame.getTempRef();
pts = frame.getPTSValue();
tmp1 = pts - (tRef * framerate);
if (zero_pts < 0)
zero_pts = tmp1;
tmp2 = (pts - (tRef * framerate)) - zero_pts;
if (Math.abs(tmp2) > framerate / 2.0)
frame.setError(frame.getError() | 0x10);
frame.setDelta(tmp2);
continue;
}
}
}
/**
*
*/
private void validateSequence()
{
Frame frame;
double framerate = getLastFrameRate();
int tRef, tmp;
int[] list = new int[sourcedata.size()];
boolean b = false;
Arrays.fill(list, -1);
for (int i = 0, j = sourcedata.size(); i < j; i++)
{
streamobject = (StreamObject) sourcedata.get(i);
if (streamobject instanceof Frame)
{
frame = (Frame) streamobject;
tRef = frame.getTempRef();
list[i] = tRef<<16 | i;
continue;
}
}
Arrays.sort(list);
for (int i = 0, lastRef = -1, j = list.length; i < j; i++)
{
if (list[i] < 0)
continue;
tmp = 0xFFFF & list[i];
tRef = list[i]>>>16;
if (lastRef < 0)
lastRef = tRef;
else if (tRef != lastRef)
{
streamobject = (StreamObject) sourcedata.get(tmp);
streamobject.setError(streamobject.getError() | 0x20);
}
lastRef++;
}
}
/**
*
*/
public void getErrors()
{
int errors = 0;
for (int i = 0, j = sourcedata.size(); i < j; i++)
{
streamobject = (StreamObject) sourcedata.get(i);
errors |= streamobject.getError();
}
if ((0x7 & errors) != 0)
setTextField(getTextField() + "Error Frame; ");
if ((0x10 & errors) != 0)
setTextField(getTextField() + "Error PTS Indication; ");
if ((0x20 & errors) != 0)
setTextField(getTextField() + "Error tRef's; ");
}
/**
*
*/
private void setLastFrameRate(double val)
{
lastFrameRate = val;
}
/**
*
*/
private double getLastFrameRate()
{
return lastFrameRate;
}
/**
*
*/
private void setSourceList()
{
sourcelist.setListData(sourcedata.toArray());
}
/**
*
*/
private void setSinkList()
{
sinklist.setListData(sinkdata.toArray());
}
/**
*
*/
private StreamObject setObject(int last_id, int pos, byte[] buf, int offs, int len, int chunk)
{
switch (last_id)
{
case FRAME:
streamobject = new Frame();
streamobject.set(pos, buf, offs, len, chunk);
break;
case SEQUENCE:
streamobject = new SequenceHeader();
streamobject.set(pos, buf, offs, len, chunk);
break;
case SEQUENCE_END:
streamobject = new SequenceEnd();
streamobject.set(pos, buf, offs, len, chunk);
break;
case GOP:
streamobject = new GOPHeader();
streamobject.set(pos, buf, offs, len, chunk);
break;
case USER_DATA:
streamobject = new UserData();
streamobject.set(pos, buf, offs, len, chunk);
break;
default:
return null;
}
sourcedata.add(streamobject);
return streamobject;
}
class Frame extends StreamObject {
private int frametype = 0;
private int tempref = -1;
private String[] types = { "-", "I", "P", "B", "D", "-", "-", "-" };
public Frame()
{
type = FRAME;
datatype = "Frame ";
setDataType(datatype);
}
public void copy2(int _frametype, int _tempref)
{
frametype = _frametype;
tempref = _tempref;
objecttable[3] = String.valueOf(getTempRef());
}
public void set(int pos, byte[] array, int offs, int len, int _chunk)
{
frametype = 7 & array[offs + 5]>>3;
tempref = (0xFF & array[offs + 4])<<2 | (3 & array[offs + 5]>>6);
setDataType(getDataType() + types[getFrameType()]);
objecttable[3] = String.valueOf(getTempRef());
setOffsets(pos, offs, len, _chunk);
}
public int getFrameType()
{
return frametype;
}
public int getTempRef()
{
return tempref;
}
public String toString()
{
return ("#" + chunk + " (" + getOffset() + "->" + (getOffset() + getLength()) + ")" + datatype + types[frametype] + " - tref: " + String.valueOf(tempref));
}
}
class SequenceHeader extends StreamObject {
private String[] aspratio = {"res.","1.000 (1:1)","0.6735 (4:3)","0.7031 (16:9)","0.7615 (2.21:1)","0.8055","0.8437","0.9375","0.9815","1.0255","1.0695","1.1250","1.1575","1.2015","res." };
private String[] fps_table_str = {"forbidden fps","23.976fps","24fps","25fps","29.97fps","30fps","50fps","59.94fps","60fps","n.def.","n.def.","n.def.","n.def.","n.def.","n.def.","n.def."};
private double[] fps_table = { -1, 90000.0 / 23.976, 90000.0 / 24.0, 90000.0 / 25.0, 90000.0 / 29.97, 90000.0 / 30.0, 90000.0 / 50.0, 90000.0 / 59.94, 90000.0 / 60.0, -1, -1, -1, -1, -1, -1, -1 };
public SequenceHeader()
{
type = SEQUENCE;
datatype = "SequenceHeader";
setDataType(datatype);
}
public void set(int pos, byte[] array, int offs, int len, int _chunk)
{
String str = " ";
str += String.valueOf((0xFF & array[offs + 4])<<4 | (0xF0 & array[offs + 5])>>>4);
str += "*";
str += String.valueOf((0xF & array[offs + 5])<<8 | (0xFF & array[offs + 6]));
str += ", ";
str += fps_table_str[0xF & array[offs + 7]];
str += ", ";
str += aspratio[0xF & array[offs + 7]>>>4];
datatype += str;
setDataType(datatype);
setOffsets(pos, offs, len, _chunk);
setLastFrameRate(fps_table[0xF & array[offs + 7]]);
}
}
class GOPHeader extends StreamObject {
private String[] drop = { "--,", "drop," };
private String[] closed = { "--,", "closed," };
private String[] broken = { "--", "broken" };
public GOPHeader()
{
type = GOP;
datatype = "GOPHeader";
setDataType(datatype);
}
public void set(int pos, byte[] array, int offs, int len, int _chunk)
{
String str = " ";
str += drop[1 & array[offs + 4]>>7];
str += closed[1 & array[offs + 7]>>6];
str += broken[1 & array[offs + 7]>>5];
str += " ";
str += String.valueOf((0x7C & array[offs + 4])>>>2);
str += ":";
str += String.valueOf((3 & array[offs + 4])<<4 | (0xF0 & array[offs + 5])>>>4);
str += ":";
str += String.valueOf((7 & array[offs + 5])<<3 | (0xE0 & array[offs + 6])>>>5);
str += ":";
str += String.valueOf((0x1F & array[offs + 6])<<1 | (0x80 & array[offs + 7])>>>7);
datatype += str;
setDataType(datatype);
setOffsets(pos, offs, len, _chunk);
}
}
class UserData extends StreamObject {
public UserData()
{
type = USER_DATA;
datatype = "UserData";
setDataType(datatype);
}
public void set(int pos, byte[] array, int offs, int len, int _chunk)
{
String str = new String(array, offs + 4, len - 4);
datatype += " '" + str + "'";
setDataType(datatype);
setOffsets(pos, offs, len, _chunk);
}
}
class SequenceEnd extends StreamObject {
public SequenceEnd()
{
type = SEQUENCE_END;
datatype = "SequenceEnd";
setDataType(datatype);
}
}
class StreamObject {
public int chunk = -1;
public int type = -1;
public int offset = -1;
public int length = -1;
public int error = 0;
public Object[] objecttable = new Object[s2];
public long pts = -1;
public double delta = -1;
public String datatype = "StreamObject";
public StreamObject()
{}
public void copy(int _type, String _datatype, int _offset, int _length, int _chunk)
{
type = _type;
offset = _offset;
length = _length;
chunk = _chunk;
setDataType(_datatype);
objecttable[0] = String.valueOf(chunk);
objecttable[1] = String.valueOf(offset);
objecttable[2] = String.valueOf(offset + length);
}
public void set(int pos, byte[] array, int offs, int len, int _chunk)
{
setOffsets(pos, offs, len, _chunk);
}
public void setOffsets(int pos, int offs, int len, int _chunk)
{
offset = pos + offs;
length = len;
chunk = _chunk;
objecttable[0] = String.valueOf(chunk);
objecttable[1] = String.valueOf(offset);
objecttable[2] = String.valueOf(offset + length);
}
public void setPTSValue(long val)
{
pts = val;
objecttable[5] = String.valueOf(pts);
objecttable[6] = Common.formatTime_1(pts / 90L);
}
public long getPTSValue()
{
return pts;
}
public int getOffset()
{
return offset;
}
public int getLength()
{
return length;
}
public int getType()
{
return type;
}
public void setDelta(double val)
{
delta = val;
double tmp = (delta / 90.0) * 1000.0;
tmp = Math.round(tmp) / 1000.0;
objecttable[4] = String.valueOf(tmp); // in millisec
}
public int getError()
{
return error;
}
public void setError(int val)
{
error = val;
objecttable[8] = String.valueOf(error);
if ((val & 0x20) != 0) //tref error
objecttable[3] = objecttable[3].toString() + "e";
}
public void setDataType(String str)
{
datatype = str;
objecttable[7] = datatype;
}
public String getDataType()
{
return datatype;
}
public int getChunk()
{
return chunk;
}
public String toString()
{
return ("#" + getChunk() + " (" + getOffset() + "->" + (getOffset() + getLength()) + ")" + datatype);
}
public Object[] getObjectTable()
{
return objecttable;
}
}
}