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