1 /*****************************************************************
2 |
3 | AP4 - DecoderConfig Descriptors
4 |
5 | Copyright 2002-2008 Axiomatic Systems, LLC
6 |
7 |
8 | This file is part of Bento4/AP4 (MP4 Atom Processing Library).
9 |
10 | Unless you have obtained Bento4 under a difference license,
11 | this version of Bento4 is Bento4|GPL.
12 | Bento4|GPL is free software; you can redistribute it and/or modify
13 | it under the terms of the GNU General Public License as published by
14 | the Free Software Foundation; either version 2, or (at your option)
15 | any later version.
16 |
17 | Bento4|GPL is distributed in the hope that it will be useful,
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | GNU General Public License for more details.
21 |
22 | You should have received a copy of the GNU General Public License
23 | along with Bento4|GPL; see the file COPYING. If not, write to the
24 | Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 | 02111-1307, USA.
26 |
27 ****************************************************************/
28
29 /*----------------------------------------------------------------------
30 | includes
31 +---------------------------------------------------------------------*/
32 #include "Ap4DecoderConfigDescriptor.h"
33 #include "Ap4DescriptorFactory.h"
34 #include "Ap4Utils.h"
35 #include "Ap4ByteStream.h"
36 #include "Ap4Atom.h"
37
38 /*----------------------------------------------------------------------
39 | dynamic cast support
40 +---------------------------------------------------------------------*/
AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_DecoderConfigDescriptor)41 AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_DecoderConfigDescriptor)
42
43 /*----------------------------------------------------------------------
44 | AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor
45 +---------------------------------------------------------------------*/
46 AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor(
47 AP4_UI08 stream_type,
48 AP4_UI08 oti,
49 AP4_UI32 buffer_size,
50 AP4_UI32 max_bitrate,
51 AP4_UI32 avg_bitrate,
52 AP4_DecoderSpecificInfoDescriptor* dsi) :
53 AP4_Descriptor(AP4_DESCRIPTOR_TAG_DECODER_CONFIG, 2, 13),
54 m_StreamType(stream_type),
55 m_ObjectTypeIndication(oti),
56 m_UpStream(false),
57 m_BufferSize(buffer_size),
58 m_MaxBitrate(max_bitrate),
59 m_AverageBitrate(avg_bitrate)
60 {
61 if (dsi) {
62 m_SubDescriptors.Add(dsi);
63 m_PayloadSize += dsi->GetSize();
64 m_HeaderSize = MinHeaderSize(m_PayloadSize);
65 }
66 }
67
68 /*----------------------------------------------------------------------
69 | AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor
70 +---------------------------------------------------------------------*/
AP4_DecoderConfigDescriptor(AP4_ByteStream & stream,AP4_Size header_size,AP4_Size payload_size)71 AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor(
72 AP4_ByteStream& stream, AP4_Size header_size, AP4_Size payload_size) :
73 AP4_Descriptor(AP4_DESCRIPTOR_TAG_DECODER_CONFIG,
74 header_size,
75 payload_size)
76 {
77 // read descriptor fields
78 if (payload_size < 13) return;
79 stream.ReadUI08(m_ObjectTypeIndication);
80 unsigned char bits;
81 stream.ReadUI08(bits);
82 m_StreamType = (bits>>2)&0x3F;
83 m_UpStream = bits&2 ? true:false;
84 stream.ReadUI24(m_BufferSize);
85 stream.ReadUI32(m_MaxBitrate);
86 stream.ReadUI32(m_AverageBitrate);
87 payload_size -= 13;
88
89 // read other descriptors
90 AP4_Position offset;
91 stream.Tell(offset);
92 AP4_SubStream* substream = new AP4_SubStream(stream, offset, payload_size);
93 AP4_Descriptor* descriptor = NULL;
94 while (AP4_DescriptorFactory::CreateDescriptorFromStream(*substream,
95 descriptor)
96 == AP4_SUCCESS) {
97 m_SubDescriptors.Add(descriptor);
98 }
99 substream->Release();
100 }
101
102 /*----------------------------------------------------------------------
103 | AP4_DecoderConfigDescriptor::~AP4_DecoderConfigDescriptor
104 +---------------------------------------------------------------------*/
~AP4_DecoderConfigDescriptor()105 AP4_DecoderConfigDescriptor::~AP4_DecoderConfigDescriptor()
106 {
107 m_SubDescriptors.DeleteReferences();
108 }
109
110 /*----------------------------------------------------------------------
111 | AP4_DecoderConfigDescriptor::WriteFields
112 +---------------------------------------------------------------------*/
113 AP4_Result
WriteFields(AP4_ByteStream & stream)114 AP4_DecoderConfigDescriptor::WriteFields(AP4_ByteStream& stream)
115 {
116 stream.WriteUI08(m_ObjectTypeIndication);
117 AP4_UI08 bits = (m_StreamType<<2) | (m_UpStream? 2 : 0) | 1;
118 stream.WriteUI08(bits);
119 stream.WriteUI24(m_BufferSize);
120 stream.WriteUI32(m_MaxBitrate);
121 stream.WriteUI32(m_AverageBitrate);
122
123 m_SubDescriptors.Apply(AP4_DescriptorListWriter(stream));
124
125 return AP4_SUCCESS;
126 }
127
128 /*----------------------------------------------------------------------
129 | AP4_DecoderConfigDescriptor::Inspect
130 +---------------------------------------------------------------------*/
131 AP4_Result
Inspect(AP4_AtomInspector & inspector)132 AP4_DecoderConfigDescriptor::Inspect(AP4_AtomInspector& inspector)
133 {
134 inspector.StartDescriptor("DecoderConfig", GetHeaderSize(), GetSize());
135 inspector.AddField("stream_type", m_StreamType);
136 inspector.AddField("object_type", m_ObjectTypeIndication);
137 inspector.AddField("up_stream", m_UpStream);
138 inspector.AddField("buffer_size", m_BufferSize);
139 inspector.AddField("max_bitrate", m_MaxBitrate);
140 inspector.AddField("avg_bitrate", m_AverageBitrate);
141
142 // inspect children
143 m_SubDescriptors.Apply(AP4_DescriptorListInspector(inspector));
144
145 inspector.EndDescriptor();
146
147 return AP4_SUCCESS;
148 }
149
150 /*----------------------------------------------------------------------
151 | AP4_DecoderConfigDescriptor::GetDecoderSpecificInfoDescriptor
152 +---------------------------------------------------------------------*/
153 const AP4_DecoderSpecificInfoDescriptor*
GetDecoderSpecificInfoDescriptor() const154 AP4_DecoderConfigDescriptor::GetDecoderSpecificInfoDescriptor() const
155 {
156 // find the decoder specific info
157 AP4_Descriptor* descriptor = NULL;
158 AP4_Result result =
159 m_SubDescriptors.Find(AP4_DescriptorFinder(AP4_DESCRIPTOR_TAG_DECODER_SPECIFIC_INFO),
160 descriptor);
161
162 // return it
163 if (AP4_SUCCEEDED(result)) {
164 return AP4_DYNAMIC_CAST(AP4_DecoderSpecificInfoDescriptor, descriptor);
165 } else {
166 return NULL;
167 }
168 }
169