/* | |
* Copyright 2011 castLabs, Berlin | |
* | |
* Licensed under the Apache License, Version 2.0 (the License); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an AS IS BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.googlecode.mp4parser.boxes.mp4.objectdescriptors; | |
import com.coremedia.iso.IsoTypeReader; | |
import com.coremedia.iso.IsoTypeWriter; | |
import java.io.IOException; | |
import java.nio.ByteBuffer; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.logging.Logger; | |
/* | |
class ES_Descriptor extends BaseDescriptor : bit(8) tag=ES_DescrTag { | |
bit(16) ES_ID; | |
bit(1) streamDependenceFlag; | |
bit(1) URL_Flag; | |
bit(1) OCRstreamFlag; | |
bit(5) streamPriority; | |
if (streamDependenceFlag) | |
bit(16) dependsOn_ES_ID; | |
if (URL_Flag) { | |
bit(8) URLlength; | |
bit(8) URLstring[URLlength]; | |
} | |
if (OCRstreamFlag) | |
bit(16) OCR_ES_Id; | |
DecoderConfigDescriptor decConfigDescr; | |
if (ODProfileLevelIndication==0x01) //no SL extension. | |
{ | |
SLConfigDescriptor slConfigDescr; | |
} | |
else // SL extension is possible. | |
{ | |
SLConfigDescriptor slConfigDescr; | |
} | |
IPI_DescrPointer ipiPtr[0 .. 1]; | |
IP_IdentificationDataSet ipIDS[0 .. 255]; | |
IPMP_DescriptorPointer ipmpDescrPtr[0 .. 255]; | |
LanguageDescriptor langDescr[0 .. 255]; | |
QoS_Descriptor qosDescr[0 .. 1]; | |
RegistrationDescriptor regDescr[0 .. 1]; | |
ExtensionDescriptor extDescr[0 .. 255]; | |
} | |
*/ | |
@Descriptor(tags = {0x03}) | |
public class ESDescriptor extends BaseDescriptor { | |
private static Logger log = Logger.getLogger(ESDescriptor.class.getName()); | |
int esId; | |
int streamDependenceFlag; | |
int URLFlag; | |
int oCRstreamFlag; | |
int streamPriority; | |
int URLLength = 0; | |
String URLString; | |
int remoteODFlag; | |
int dependsOnEsId; | |
int oCREsId; | |
DecoderConfigDescriptor decoderConfigDescriptor; | |
SLConfigDescriptor slConfigDescriptor; | |
List<BaseDescriptor> otherDescriptors = new ArrayList<BaseDescriptor>(); | |
@Override | |
public void parseDetail(ByteBuffer bb) throws IOException { | |
esId = IsoTypeReader.readUInt16(bb); | |
int data = IsoTypeReader.readUInt8(bb); | |
streamDependenceFlag = data >>> 7; | |
URLFlag = (data >>> 6) & 0x1; | |
oCRstreamFlag = (data >>> 5) & 0x1; | |
streamPriority = data & 0x1f; | |
if (streamDependenceFlag == 1) { | |
dependsOnEsId = IsoTypeReader.readUInt16(bb); | |
} | |
if (URLFlag == 1) { | |
URLLength = IsoTypeReader.readUInt8(bb); | |
URLString = IsoTypeReader.readString(bb, URLLength); | |
} | |
if (oCRstreamFlag == 1) { | |
oCREsId = IsoTypeReader.readUInt16(bb); | |
} | |
int baseSize = 1 /*tag*/ + getSizeBytes() + 2 + 1 + (streamDependenceFlag == 1 ? 2 : 0) + (URLFlag == 1 ? 1 + URLLength : 0) + (oCRstreamFlag == 1 ? 2 : 0); | |
int begin = bb.position(); | |
if (getSize() > baseSize + 2) { | |
BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb); | |
final long read = bb.position() - begin; | |
log.finer(descriptor + " - ESDescriptor1 read: " + read + ", size: " + (descriptor != null ? descriptor.getSize() : null)); | |
if (descriptor != null) { | |
final int size = descriptor.getSize(); | |
bb.position(begin + size); | |
baseSize += size; | |
} else { | |
baseSize += read; | |
} | |
if (descriptor instanceof DecoderConfigDescriptor) { | |
decoderConfigDescriptor = (DecoderConfigDescriptor) descriptor; | |
} | |
} | |
begin = bb.position(); | |
if (getSize() > baseSize + 2) { | |
BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb); | |
final long read = bb.position() - begin; | |
log.finer(descriptor + " - ESDescriptor2 read: " + read + ", size: " + (descriptor != null ? descriptor.getSize() : null)); | |
if (descriptor != null) { | |
final int size = descriptor.getSize(); | |
bb.position(begin + size); | |
baseSize += size; | |
} else { | |
baseSize += read; | |
} | |
if (descriptor instanceof SLConfigDescriptor) { | |
slConfigDescriptor = (SLConfigDescriptor) descriptor; | |
} | |
} else { | |
log.warning("SLConfigDescriptor is missing!"); | |
} | |
while (getSize() - baseSize > 2) { | |
begin = bb.position(); | |
BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb); | |
final long read = bb.position() - begin; | |
log.finer(descriptor + " - ESDescriptor3 read: " + read + ", size: " + (descriptor != null ? descriptor.getSize() : null)); | |
if (descriptor != null) { | |
final int size = descriptor.getSize(); | |
bb.position(begin + size); | |
baseSize += size; | |
} else { | |
baseSize += read; | |
} | |
otherDescriptors.add(descriptor); | |
} | |
} | |
public int serializedSize() { | |
int out = 5; | |
if (streamDependenceFlag > 0) { | |
out += 2; | |
} | |
if (URLFlag > 0) { | |
out += 1 + URLLength; | |
} | |
if (oCRstreamFlag > 0) { | |
out += 2; | |
} | |
out += decoderConfigDescriptor.serializedSize(); | |
out += slConfigDescriptor.serializedSize(); | |
// Doesn't handle other descriptors yet | |
return out; | |
} | |
public ByteBuffer serialize() { | |
ByteBuffer out = ByteBuffer.allocate(serializedSize()); // Usually is around 30 bytes, so 200 should be enough... | |
IsoTypeWriter.writeUInt8(out, 3); | |
IsoTypeWriter.writeUInt8(out, serializedSize() - 2); // Not OK for longer sizes! | |
IsoTypeWriter.writeUInt16(out, esId); | |
int flags = (streamDependenceFlag << 7) | (URLFlag << 6) | (oCRstreamFlag << 5) | (streamPriority & 0x1f); | |
IsoTypeWriter.writeUInt8(out, flags); | |
if (streamDependenceFlag > 0) { | |
IsoTypeWriter.writeUInt16(out, dependsOnEsId); | |
} | |
if (URLFlag > 0) { | |
IsoTypeWriter.writeUInt8(out, URLLength); | |
IsoTypeWriter.writeUtf8String(out, URLString); | |
} | |
if (oCRstreamFlag > 0) { | |
IsoTypeWriter.writeUInt16(out, oCREsId); | |
} | |
ByteBuffer dec = decoderConfigDescriptor.serialize(); | |
ByteBuffer sl = slConfigDescriptor.serialize(); | |
out.put(dec.array()); | |
out.put(sl.array()); | |
// Doesn't handle other descriptors yet | |
return out; | |
} | |
// @Override | |
// public int getSize() { | |
// return 3 + (streamDependenceFlag == 1 ? 2 : 0) + | |
// (URLFlag == 1 ? 1 + 8 * URLLength : 0) + | |
// (oCRstreamFlag == 1 ? 2 : 0); | |
// } | |
public DecoderConfigDescriptor getDecoderConfigDescriptor() { | |
return decoderConfigDescriptor; | |
} | |
public SLConfigDescriptor getSlConfigDescriptor() { | |
return slConfigDescriptor; | |
} | |
public void setDecoderConfigDescriptor(DecoderConfigDescriptor decoderConfigDescriptor) { | |
this.decoderConfigDescriptor = decoderConfigDescriptor; | |
} | |
public void setSlConfigDescriptor(SLConfigDescriptor slConfigDescriptor) { | |
this.slConfigDescriptor = slConfigDescriptor; | |
} | |
public List<BaseDescriptor> getOtherDescriptors() { | |
return otherDescriptors; | |
} | |
public int getoCREsId() { | |
return oCREsId; | |
} | |
public void setoCREsId(int oCREsId) { | |
this.oCREsId = oCREsId; | |
} | |
public int getEsId() { | |
return esId; | |
} | |
public void setEsId(int esId) { | |
this.esId = esId; | |
} | |
public int getStreamDependenceFlag() { | |
return streamDependenceFlag; | |
} | |
public void setStreamDependenceFlag(int streamDependenceFlag) { | |
this.streamDependenceFlag = streamDependenceFlag; | |
} | |
public int getURLFlag() { | |
return URLFlag; | |
} | |
public void setURLFlag(int URLFlag) { | |
this.URLFlag = URLFlag; | |
} | |
public int getoCRstreamFlag() { | |
return oCRstreamFlag; | |
} | |
public void setoCRstreamFlag(int oCRstreamFlag) { | |
this.oCRstreamFlag = oCRstreamFlag; | |
} | |
public int getStreamPriority() { | |
return streamPriority; | |
} | |
public void setStreamPriority(int streamPriority) { | |
this.streamPriority = streamPriority; | |
} | |
public int getURLLength() { | |
return URLLength; | |
} | |
public void setURLLength(int URLLength) { | |
this.URLLength = URLLength; | |
} | |
public String getURLString() { | |
return URLString; | |
} | |
public void setURLString(String URLString) { | |
this.URLString = URLString; | |
} | |
public int getRemoteODFlag() { | |
return remoteODFlag; | |
} | |
public void setRemoteODFlag(int remoteODFlag) { | |
this.remoteODFlag = remoteODFlag; | |
} | |
public int getDependsOnEsId() { | |
return dependsOnEsId; | |
} | |
public void setDependsOnEsId(int dependsOnEsId) { | |
this.dependsOnEsId = dependsOnEsId; | |
} | |
@Override | |
public String toString() { | |
final StringBuilder sb = new StringBuilder(); | |
sb.append("ESDescriptor"); | |
sb.append("{esId=").append(esId); | |
sb.append(", streamDependenceFlag=").append(streamDependenceFlag); | |
sb.append(", URLFlag=").append(URLFlag); | |
sb.append(", oCRstreamFlag=").append(oCRstreamFlag); | |
sb.append(", streamPriority=").append(streamPriority); | |
sb.append(", URLLength=").append(URLLength); | |
sb.append(", URLString='").append(URLString).append('\''); | |
sb.append(", remoteODFlag=").append(remoteODFlag); | |
sb.append(", dependsOnEsId=").append(dependsOnEsId); | |
sb.append(", oCREsId=").append(oCREsId); | |
sb.append(", decoderConfigDescriptor=").append(decoderConfigDescriptor); | |
sb.append(", slConfigDescriptor=").append(slConfigDescriptor); | |
sb.append('}'); | |
return sb.toString(); | |
} | |
@Override | |
public boolean equals(Object o) { | |
if (this == o) return true; | |
if (o == null || getClass() != o.getClass()) return false; | |
ESDescriptor that = (ESDescriptor) o; | |
if (URLFlag != that.URLFlag) return false; | |
if (URLLength != that.URLLength) return false; | |
if (dependsOnEsId != that.dependsOnEsId) return false; | |
if (esId != that.esId) return false; | |
if (oCREsId != that.oCREsId) return false; | |
if (oCRstreamFlag != that.oCRstreamFlag) return false; | |
if (remoteODFlag != that.remoteODFlag) return false; | |
if (streamDependenceFlag != that.streamDependenceFlag) return false; | |
if (streamPriority != that.streamPriority) return false; | |
if (URLString != null ? !URLString.equals(that.URLString) : that.URLString != null) return false; | |
if (decoderConfigDescriptor != null ? !decoderConfigDescriptor.equals(that.decoderConfigDescriptor) : that.decoderConfigDescriptor != null) | |
return false; | |
if (otherDescriptors != null ? !otherDescriptors.equals(that.otherDescriptors) : that.otherDescriptors != null) | |
return false; | |
if (slConfigDescriptor != null ? !slConfigDescriptor.equals(that.slConfigDescriptor) : that.slConfigDescriptor != null) | |
return false; | |
return true; | |
} | |
@Override | |
public int hashCode() { | |
int result = esId; | |
result = 31 * result + streamDependenceFlag; | |
result = 31 * result + URLFlag; | |
result = 31 * result + oCRstreamFlag; | |
result = 31 * result + streamPriority; | |
result = 31 * result + URLLength; | |
result = 31 * result + (URLString != null ? URLString.hashCode() : 0); | |
result = 31 * result + remoteODFlag; | |
result = 31 * result + dependsOnEsId; | |
result = 31 * result + oCREsId; | |
result = 31 * result + (decoderConfigDescriptor != null ? decoderConfigDescriptor.hashCode() : 0); | |
result = 31 * result + (slConfigDescriptor != null ? slConfigDescriptor.hashCode() : 0); | |
result = 31 * result + (otherDescriptors != null ? otherDescriptors.hashCode() : 0); | |
return result; | |
} | |
} |