1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/*
19    This PVA_FF_ESDescriptor Class contains information on the Elementary Stream
20*/
21
22
23#define IMPLEMENT_ESDescriptor
24
25#include "esdescriptor.h"
26#include "atomutils.h"
27#include "a_atomdefs.h"
28
29// Constructor - used for a NEW stream (i.e. a new track)
30PVA_FF_ESDescriptor::PVA_FF_ESDescriptor(int32 streamType, int32 codecType)
31        : PVA_FF_BaseDescriptor(0x03)
32{
33    PV_MP4_FF_NEW(fp->auditCB, PVA_FF_DecoderConfigDescriptor, (streamType, codecType), _pdcd);
34    PV_MP4_FF_NEW(fp->auditCB, PVA_FF_SLConfigDescriptor, (), _pslcd);
35
36    _ESID = 0; // Initialize the ESID, will be set later
37    init();
38
39    recomputeSize();
40
41    _pdcd->setParent(this);
42    _pslcd->setParent(this);
43}
44
45// Destructor
46PVA_FF_ESDescriptor::~PVA_FF_ESDescriptor()
47{
48    // Cleanup descriptors
49    PV_MP4_FF_DELETE(NULL, PVA_FF_DecoderConfigDescriptor, _pdcd);
50    PV_MP4_FF_DELETE(NULL, PVA_FF_SLConfigDescriptor, _pslcd);
51}
52
53void
54PVA_FF_ESDescriptor::init()
55{
56    _streamDependenceFlag = false;
57    _urlFlag = false;
58    _reserved = 1;
59    _streamPriority = 0;
60    _dependsOnESID = 0;
61    _urlLength = 0;
62}
63
64void
65PVA_FF_ESDescriptor::recomputeSize()
66{
67    _urlLength = (uint8)(_urlString.get_size());
68
69    int32 contents = 0;
70
71    contents += 2; //(16 bits for ESID)
72    contents += 1; //(8 bits for packed SDF, UF, reserved, and stream Priority)
73    if (_streamDependenceFlag)  // If this stream depends on another ES
74    {
75        contents += 2; // depends on ESID
76    }
77    if (_urlFlag)  // URL only present fp flag set
78    {
79        contents += 1; // URL length stored in 1 byte
80        contents += _urlLength; // length of actual URL string
81    }
82    contents += _pdcd->getSizeOfDescriptorObject();
83    contents += _pslcd->getSizeOfDescriptorObject();
84
85    // Setting actual size of this descriptor class
86    _sizeOfClass = contents;
87    _sizeOfSizeField = PVA_FF_AtomUtils::getNumberOfBytesUsedToStoreSizeOfClass(contents);
88
89    // Have the parent descriptor recompute its size based on this update
90    if (_pparent != NULL)
91    {
92        _pparent->recomputeSize();
93    }
94}
95
96
97// Rendering the Descriptor in proper format (bitlengths, etc.) to an ostream
98bool
99PVA_FF_ESDescriptor::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp)
100{
101    int32 rendered = 0; // Keep track of number of bytes rendered
102
103    // Render attributes of the PVA_FF_BaseDescriptor class
104    int32 numBytes = renderBaseDescriptorMembers(fp);
105
106    if (numBytes == 0)
107    {
108        return false;
109    }
110    rendered += numBytes; // (1 + variable for _sizeOfClass)
111
112    if (!PVA_FF_AtomUtils::render16(fp, 0))
113    {
114        return false;
115    }
116    rendered += 2;
117
118    // Pack and render SDF, UF, reserved, and stream Priority
119
120    uint8 data = 0x00; // OCRstreamFlag set to 0
121
122    if (_streamDependenceFlag)
123    {
124        // If this stream depends on another ES
125        data |= 0x80; //data = 1000 0000
126    }
127    if (_urlFlag)
128    {
129        // If URL present in this descriptor
130        data |= 0x40; //data = 1100 0000
131    }
132
133    // OCRStreamFlag defaults to ZERO - Bit 3 from MSB
134
135    data |= (_streamPriority & 0x1f); // LS 5 bits for stream priority
136    if (!PVA_FF_AtomUtils::render8(fp, data))
137    {
138        return false;
139    }
140    rendered += 1;
141
142    if (_streamDependenceFlag)
143    {
144        // If this stream depends on another ES
145        if (!PVA_FF_AtomUtils::render16(fp, _dependsOnESID))
146        {
147            return false;
148        }
149        rendered += 2;
150    }
151    if (_urlFlag)
152    {
153        //If URL present in this descriptor
154        if (!PVA_FF_AtomUtils::render8(fp, _urlLength))
155        {
156            return false;
157        }
158        if (!PVA_FF_AtomUtils::renderString(fp, _urlString))
159        {
160            return false;
161        }
162        rendered += _urlLength + 1;
163    }
164
165    // Render PVA_FF_DecoderConfigDescriptor
166    if (!_pdcd->renderToFileStream(fp))
167    {
168        return false;
169    }
170    rendered += _pdcd->getSizeOfDescriptorObject();
171
172    // Render PVA_FF_SLConfigDescriptor
173    if (!_pslcd->renderToFileStream(fp))
174    {
175        return false;
176    }
177    rendered += _pslcd->getSizeOfDescriptorObject();
178
179    return true;
180}
181
182