• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 castLabs, Berlin
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 package com.googlecode.mp4parser.boxes.mp4.samplegrouping;
19 
20 import com.coremedia.iso.IsoTypeReader;
21 import com.coremedia.iso.IsoTypeWriter;
22 
23 import java.nio.ByteBuffer;
24 import java.util.LinkedList;
25 import java.util.List;
26 
27 import static com.googlecode.mp4parser.util.CastUtils.l2i;
28 
29 /**
30  * Each sample of a track may be associated to (zero or) one of a number of sample group descriptions, each of
31  * which defines a record of rate-share information. Typically the same rate-share information applies to many
32  * consecutive samples and it may therefore be enough to define two or three sample group descriptions that
33  * can be used at different time intervals.
34  * <p/>
35  * The grouping type 'rash' (short for rate share) is defined as the grouping criterion for rate share information.
36  * Zero or one sample-to-group box ('sbgp') for the grouping type 'rash' can be contained in the sample
37  * table box ('stbl') of a track. It shall reside in a hint track, if a hint track is used, otherwise in a media track.
38  * <p/>
39  * Target rate share may be specified for several operation points that are defined in terms of the total available
40  * bitrate, i.e., the bitrate that should be shared. If only one operation point is defined, the target rate share
41  * applies to all available bitrates. If several operation points are defined, then each operation point specifies a
42  * target rate share. Target rate share values specified for the first and the last operation points also specify the
43  * target rate share values at lower and higher available bitrates, respectively. The target rate share between two
44  * operation points is specified to be in the range between the target rate shares of those operation points. One
45  * possibility is to estimate with linear interpolation.
46  */
47 public class RateShareEntry extends GroupEntry {
48     public static final String TYPE = "rash";
49 
50     private short operationPointCut;
51     private short targetRateShare;
52     private List<Entry> entries = new LinkedList<Entry>();
53     private int maximumBitrate;
54     private int minimumBitrate;
55     private short discardPriority;
56 
57 
58     @Override
parse(ByteBuffer byteBuffer)59     public void parse(ByteBuffer byteBuffer) {
60         operationPointCut = byteBuffer.getShort();
61         if (operationPointCut == 1) {
62             targetRateShare = byteBuffer.getShort();
63         } else {
64             int entriesLeft = operationPointCut;
65             while (entriesLeft-- > 0) {
66                 entries.add(new Entry(l2i(IsoTypeReader.readUInt32(byteBuffer)), byteBuffer.getShort()));
67             }
68         }
69         maximumBitrate = l2i(IsoTypeReader.readUInt32(byteBuffer));
70         minimumBitrate = l2i(IsoTypeReader.readUInt32(byteBuffer));
71         discardPriority = (short) IsoTypeReader.readUInt8(byteBuffer);
72     }
73 
74     @Override
get()75     public ByteBuffer get() {
76         ByteBuffer buf = ByteBuffer.allocate(operationPointCut == 1?13:(operationPointCut * 6 + 11 ));
77         buf.putShort(operationPointCut);
78         if (operationPointCut == 1) {
79             buf.putShort(targetRateShare );
80         } else {
81             for (Entry entry : entries) {
82                 buf.putInt(entry.getAvailableBitrate());
83                 buf.putShort(entry.getTargetRateShare());
84             }
85         }
86         buf.putInt(maximumBitrate);
87         buf.putInt(minimumBitrate);
88         IsoTypeWriter.writeUInt8(buf, discardPriority);
89         buf.rewind();
90         return buf;
91     }
92 
93     public static class Entry {
Entry(int availableBitrate, short targetRateShare)94         public Entry(int availableBitrate, short targetRateShare) {
95             this.availableBitrate = availableBitrate;
96             this.targetRateShare = targetRateShare;
97         }
98 
99         int availableBitrate;
100         short targetRateShare;
101 
102         @Override
toString()103         public String toString() {
104             return "{" +
105                     "availableBitrate=" + availableBitrate +
106                     ", targetRateShare=" + targetRateShare +
107                     '}';
108         }
109 
getAvailableBitrate()110         public int getAvailableBitrate() {
111             return availableBitrate;
112         }
113 
setAvailableBitrate(int availableBitrate)114         public void setAvailableBitrate(int availableBitrate) {
115             this.availableBitrate = availableBitrate;
116         }
117 
getTargetRateShare()118         public short getTargetRateShare() {
119             return targetRateShare;
120         }
121 
setTargetRateShare(short targetRateShare)122         public void setTargetRateShare(short targetRateShare) {
123             this.targetRateShare = targetRateShare;
124         }
125 
126         @Override
equals(Object o)127         public boolean equals(Object o) {
128             if (this == o) {
129                 return true;
130             }
131             if (o == null || getClass() != o.getClass()) {
132                 return false;
133             }
134 
135             Entry entry = (Entry) o;
136 
137             if (availableBitrate != entry.availableBitrate) {
138                 return false;
139             }
140             if (targetRateShare != entry.targetRateShare) {
141                 return false;
142             }
143 
144             return true;
145         }
146 
147         @Override
hashCode()148         public int hashCode() {
149             int result = availableBitrate;
150             result = 31 * result + (int) targetRateShare;
151             return result;
152         }
153     }
154 
155     @Override
equals(Object o)156     public boolean equals(Object o) {
157         if (this == o) {
158             return true;
159         }
160         if (o == null || getClass() != o.getClass()) {
161             return false;
162         }
163 
164         RateShareEntry that = (RateShareEntry) o;
165 
166         if (discardPriority != that.discardPriority) {
167             return false;
168         }
169         if (maximumBitrate != that.maximumBitrate) {
170             return false;
171         }
172         if (minimumBitrate != that.minimumBitrate) {
173             return false;
174         }
175         if (operationPointCut != that.operationPointCut) {
176             return false;
177         }
178         if (targetRateShare != that.targetRateShare) {
179             return false;
180         }
181         if (entries != null ? !entries.equals(that.entries) : that.entries != null) {
182             return false;
183         }
184 
185         return true;
186     }
187 
188     @Override
hashCode()189     public int hashCode() {
190         int result = (int) operationPointCut;
191         result = 31 * result + (int) targetRateShare;
192         result = 31 * result + (entries != null ? entries.hashCode() : 0);
193         result = 31 * result + maximumBitrate;
194         result = 31 * result + minimumBitrate;
195         result = 31 * result + (int) discardPriority;
196         return result;
197     }
198 
getOperationPointCut()199     public short getOperationPointCut() {
200         return operationPointCut;
201     }
202 
setOperationPointCut(short operationPointCut)203     public void setOperationPointCut(short operationPointCut) {
204         this.operationPointCut = operationPointCut;
205     }
206 
getTargetRateShare()207     public short getTargetRateShare() {
208         return targetRateShare;
209     }
210 
setTargetRateShare(short targetRateShare)211     public void setTargetRateShare(short targetRateShare) {
212         this.targetRateShare = targetRateShare;
213     }
214 
getEntries()215     public List<Entry> getEntries() {
216         return entries;
217     }
218 
setEntries(List<Entry> entries)219     public void setEntries(List<Entry> entries) {
220         this.entries = entries;
221     }
222 
getMaximumBitrate()223     public int getMaximumBitrate() {
224         return maximumBitrate;
225     }
226 
setMaximumBitrate(int maximumBitrate)227     public void setMaximumBitrate(int maximumBitrate) {
228         this.maximumBitrate = maximumBitrate;
229     }
230 
getMinimumBitrate()231     public int getMinimumBitrate() {
232         return minimumBitrate;
233     }
234 
setMinimumBitrate(int minimumBitrate)235     public void setMinimumBitrate(int minimumBitrate) {
236         this.minimumBitrate = minimumBitrate;
237     }
238 
getDiscardPriority()239     public short getDiscardPriority() {
240         return discardPriority;
241     }
242 
setDiscardPriority(short discardPriority)243     public void setDiscardPriority(short discardPriority) {
244         this.discardPriority = discardPriority;
245     }
246 }
247