annotate Input/aac/libmp4v2/mp4track.cpp @ 38:4e0397865a31 trunk

[svn] Regenerate a bunch of stuff :)
author nenolod
date Wed, 26 Oct 2005 10:57:27 -0700
parents 6a86fdd4dea4
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1 /*
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
2 * The contents of this file are subject to the Mozilla Public
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
3 * License Version 1.1 (the "License"); you may not use this file
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
4 * except in compliance with the License. You may obtain a copy of
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
5 * the License at http://www.mozilla.org/MPL/
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
6 *
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
7 * Software distributed under the License is distributed on an "AS
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
9 * implied. See the License for the specific language governing
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
10 * rights and limitations under the License.
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
11 *
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
12 * The Original Code is MPEG4IP.
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
13 *
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
14 * The Initial Developer of the Original Code is Cisco Systems Inc.
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
15 * Portions created by Cisco Systems Inc. are
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
16 * Copyright (C) Cisco Systems Inc. 2001 - 2004. All Rights Reserved.
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
17 *
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
18 * 3GPP features implementation is based on 3GPP's TS26.234-v5.60,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
19 * and was contributed by Ximpo Group Ltd.
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
20 *
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
21 * Portions created by Ximpo Group Ltd. are
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
22 * Copyright (C) Ximpo Group Ltd. 2003, 2004. All Rights Reserved.
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
23 *
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
24 * Contributor(s):
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
25 * Dave Mackie dmackie@cisco.com
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
26 * Alix Marchandise-Franquet alix@cisco.com
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
27 * Ximpo Group Ltd. mp4v2@ximpo.com
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
28 */
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
29
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
30 #include "mp4common.h"
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
31
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
32 #define AMR_UNINITIALIZED -1
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
33 #define AMR_TRUE 0
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
34 #define AMR_FALSE 1
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
35
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
36 MP4Track::MP4Track(MP4File* pFile, MP4Atom* pTrakAtom)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
37 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
38 m_pFile = pFile;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
39 m_pTrakAtom = pTrakAtom;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
40
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
41 m_lastStsdIndex = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
42 m_lastSampleFile = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
43
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
44 m_cachedReadSampleId = MP4_INVALID_SAMPLE_ID;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
45 m_pCachedReadSample = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
46 m_cachedReadSampleSize = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
47
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
48 m_writeSampleId = 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
49 m_fixedSampleDuration = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
50 m_pChunkBuffer = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
51 m_chunkBufferSize = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
52 m_chunkSamples = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
53 m_chunkDuration = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
54
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
55 // m_bytesPerSample should be set to 1, except for the
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
56 // quicktime audio constant bit rate samples, which have non-1 values
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
57 m_bytesPerSample = 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
58 m_samplesPerChunk = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
59 m_durationPerChunk = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
60 m_isAmr = AMR_UNINITIALIZED;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
61 m_curMode = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
62
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
63 bool success = true;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
64
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
65 MP4Integer32Property* pTrackIdProperty;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
66 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
67 "trak.tkhd.trackId",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
68 (MP4Property**)&pTrackIdProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
69 if (success) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
70 m_trackId = pTrackIdProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
71 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
72
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
73 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
74 "trak.mdia.mdhd.timeScale",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
75 (MP4Property**)&m_pTimeScaleProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
76 if (success) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
77 // default chunking is 1 second of samples
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
78 m_durationPerChunk = m_pTimeScaleProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
79 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
80
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
81 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
82 "trak.tkhd.duration",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
83 (MP4Property**)&m_pTrackDurationProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
84
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
85 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
86 "trak.mdia.mdhd.duration",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
87 (MP4Property**)&m_pMediaDurationProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
88
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
89 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
90 "trak.tkhd.modificationTime",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
91 (MP4Property**)&m_pTrackModificationProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
92
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
93 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
94 "trak.mdia.mdhd.modificationTime",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
95 (MP4Property**)&m_pMediaModificationProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
96
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
97 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
98 "trak.mdia.hdlr.handlerType",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
99 (MP4Property**)&m_pTypeProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
100
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
101 // get handles on sample size information
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
102
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
103 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
104 "trak.mdia.minf.stbl.stsz.sampleSize",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
105 (MP4Property**)&m_pStszFixedSampleSizeProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
106
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
107 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
108 "trak.mdia.minf.stbl.stsz.sampleCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
109 (MP4Property**)&m_pStszSampleCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
110
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
111 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
112 "trak.mdia.minf.stbl.stsz.entries.sampleSize",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
113 (MP4Property**)&m_pStszSampleSizeProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
114
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
115 // get handles on information needed to map sample id's to file offsets
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
116
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
117 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
118 "trak.mdia.minf.stbl.stsc.entryCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
119 (MP4Property**)&m_pStscCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
120
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
121 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
122 "trak.mdia.minf.stbl.stsc.entries.firstChunk",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
123 (MP4Property**)&m_pStscFirstChunkProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
124
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
125 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
126 "trak.mdia.minf.stbl.stsc.entries.samplesPerChunk",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
127 (MP4Property**)&m_pStscSamplesPerChunkProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
128
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
129 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
130 "trak.mdia.minf.stbl.stsc.entries.sampleDescriptionIndex",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
131 (MP4Property**)&m_pStscSampleDescrIndexProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
132
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
133 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
134 "trak.mdia.minf.stbl.stsc.entries.firstSample",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
135 (MP4Property**)&m_pStscFirstSampleProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
136
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
137 bool haveStco = m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
138 "trak.mdia.minf.stbl.stco.entryCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
139 (MP4Property**)&m_pChunkCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
140
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
141 if (haveStco) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
142 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
143 "trak.mdia.minf.stbl.stco.entries.chunkOffset",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
144 (MP4Property**)&m_pChunkOffsetProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
145 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
146 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
147 "trak.mdia.minf.stbl.co64.entryCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
148 (MP4Property**)&m_pChunkCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
149
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
150 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
151 "trak.mdia.minf.stbl.co64.entries.chunkOffset",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
152 (MP4Property**)&m_pChunkOffsetProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
153 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
154
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
155 // get handles on sample timing info
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
156
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
157 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
158 "trak.mdia.minf.stbl.stts.entryCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
159 (MP4Property**)&m_pSttsCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
160
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
161 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
162 "trak.mdia.minf.stbl.stts.entries.sampleCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
163 (MP4Property**)&m_pSttsSampleCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
164
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
165 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
166 "trak.mdia.minf.stbl.stts.entries.sampleDelta",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
167 (MP4Property**)&m_pSttsSampleDeltaProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
168
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
169 // get handles on rendering offset info if it exists
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
170
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
171 m_pCttsCountProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
172 m_pCttsSampleCountProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
173 m_pCttsSampleOffsetProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
174
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
175 bool haveCtts = m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
176 "trak.mdia.minf.stbl.ctts.entryCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
177 (MP4Property**)&m_pCttsCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
178
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
179 if (haveCtts) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
180 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
181 "trak.mdia.minf.stbl.ctts.entries.sampleCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
182 (MP4Property**)&m_pCttsSampleCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
183
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
184 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
185 "trak.mdia.minf.stbl.ctts.entries.sampleOffset",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
186 (MP4Property**)&m_pCttsSampleOffsetProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
187 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
188
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
189 // get handles on sync sample info if it exists
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
190
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
191 m_pStssCountProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
192 m_pStssSampleProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
193
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
194 bool haveStss = m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
195 "trak.mdia.minf.stbl.stss.entryCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
196 (MP4Property**)&m_pStssCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
197
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
198 if (haveStss) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
199 success &= m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
200 "trak.mdia.minf.stbl.stss.entries.sampleNumber",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
201 (MP4Property**)&m_pStssSampleProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
202 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
203
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
204 // edit list
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
205 InitEditListProperties();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
206
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
207 // was everything found?
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
208 if (!success) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
209 throw new MP4Error("invalid track", "MP4Track::MP4Track");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
210 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
211 CalculateBytesPerSample();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
212 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
213
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
214 MP4Track::~MP4Track()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
215 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
216 MP4Free(m_pCachedReadSample);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
217 MP4Free(m_pChunkBuffer);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
218 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
219
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
220 const char* MP4Track::GetType()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
221 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
222 return m_pTypeProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
223 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
224
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
225 void MP4Track::SetType(const char* type)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
226 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
227 m_pTypeProperty->SetValue(MP4NormalizeTrackType(type,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
228 m_pFile->GetVerbosity()));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
229 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
230
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
231 void MP4Track::ReadSample(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
232 MP4SampleId sampleId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
233 u_int8_t** ppBytes,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
234 u_int32_t* pNumBytes,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
235 MP4Timestamp* pStartTime,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
236 MP4Duration* pDuration,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
237 MP4Duration* pRenderingOffset,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
238 bool* pIsSyncSample)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
239 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
240 if (sampleId == MP4_INVALID_SAMPLE_ID) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
241 throw new MP4Error("sample id can't be zero",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
242 "MP4Track::ReadSample");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
243 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
244
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
245 // handle unusual case of wanting to read a sample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
246 // that is still sitting in the write chunk buffer
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
247 if (m_pChunkBuffer && sampleId >= m_writeSampleId - m_chunkSamples) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
248 WriteChunkBuffer();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
249 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
250
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
251 FILE* pFile = GetSampleFile(sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
252
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
253 if (pFile == (FILE*)-1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
254 throw new MP4Error("sample is located in an inaccessible file",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
255 "MP4Track::ReadSample");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
256 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
257
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
258 u_int64_t fileOffset = GetSampleFileOffset(sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
259
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
260 u_int32_t sampleSize = GetSampleSize(sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
261 if (*ppBytes != NULL && *pNumBytes < sampleSize) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
262 throw new MP4Error("sample buffer is too small",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
263 "MP4Track::ReadSample");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
264 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
265 *pNumBytes = sampleSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
266
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
267 VERBOSE_READ_SAMPLE(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
268 printf("ReadSample: track %u id %u offset 0x"X64" size %u (0x%x)\n",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
269 m_trackId, sampleId, fileOffset, *pNumBytes, *pNumBytes));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
270
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
271 bool bufferMalloc = false;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
272 if (*ppBytes == NULL) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
273 *ppBytes = (u_int8_t*)MP4Malloc(*pNumBytes);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
274 bufferMalloc = true;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
275 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
276
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
277 u_int64_t oldPos = m_pFile->GetPosition(pFile); // only used in mode == 'w'
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
278 try {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
279 m_pFile->SetPosition(fileOffset, pFile);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
280 m_pFile->ReadBytes(*ppBytes, *pNumBytes, pFile);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
281
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
282 if (pStartTime || pDuration) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
283 GetSampleTimes(sampleId, pStartTime, pDuration);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
284
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
285 VERBOSE_READ_SAMPLE(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
286 printf("ReadSample: start "U64" duration "D64"\n",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
287 (pStartTime ? *pStartTime : 0),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
288 (pDuration ? *pDuration : 0)));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
289 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
290 if (pRenderingOffset) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
291 *pRenderingOffset = GetSampleRenderingOffset(sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
292
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
293 VERBOSE_READ_SAMPLE(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
294 printf("ReadSample: renderingOffset "D64"\n",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
295 *pRenderingOffset));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
296 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
297 if (pIsSyncSample) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
298 *pIsSyncSample = IsSyncSample(sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
299
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
300 VERBOSE_READ_SAMPLE(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
301 printf("ReadSample: isSyncSample %u\n",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
302 *pIsSyncSample));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
303 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
304 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
305
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
306 catch (MP4Error* e) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
307 if (bufferMalloc) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
308 // let's not leak memory
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
309 MP4Free(*ppBytes);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
310 *ppBytes = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
311 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
312 if (m_pFile->GetMode() == 'w') {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
313 m_pFile->SetPosition(oldPos, pFile);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
314 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
315 throw e;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
316 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
317
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
318 if (m_pFile->GetMode() == 'w') {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
319 m_pFile->SetPosition(oldPos, pFile);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
320 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
321 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
322
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
323 void MP4Track::ReadSampleFragment(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
324 MP4SampleId sampleId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
325 u_int32_t sampleOffset,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
326 u_int16_t sampleLength,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
327 u_int8_t* pDest)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
328 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
329 if (sampleId == MP4_INVALID_SAMPLE_ID) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
330 throw new MP4Error("invalid sample id",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
331 "MP4Track::ReadSampleFragment");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
332 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
333
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
334 if (sampleId != m_cachedReadSampleId) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
335 MP4Free(m_pCachedReadSample);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
336 m_pCachedReadSample = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
337 m_cachedReadSampleSize = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
338 m_cachedReadSampleId = MP4_INVALID_SAMPLE_ID;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
339
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
340 ReadSample(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
341 sampleId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
342 &m_pCachedReadSample,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
343 &m_cachedReadSampleSize);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
344
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
345 m_cachedReadSampleId = sampleId;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
346 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
347
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
348 if (sampleOffset + sampleLength > m_cachedReadSampleSize) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
349 throw new MP4Error("offset and/or length are too large",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
350 "MP4Track::ReadSampleFragment");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
351 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
352
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
353 memcpy(pDest, &m_pCachedReadSample[sampleOffset], sampleLength);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
354 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
355
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
356 void MP4Track::WriteSample(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
357 const u_int8_t* pBytes,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
358 u_int32_t numBytes,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
359 MP4Duration duration,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
360 MP4Duration renderingOffset,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
361 bool isSyncSample)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
362 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
363 u_int8_t curMode = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
364
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
365 VERBOSE_WRITE_SAMPLE(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
366 printf("WriteSample: track %u id %u size %u (0x%x) ",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
367 m_trackId, m_writeSampleId, numBytes, numBytes));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
368
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
369 if (pBytes == NULL && numBytes > 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
370 throw new MP4Error("no sample data", "MP4WriteSample");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
371 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
372
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
373 if (m_isAmr == AMR_UNINITIALIZED ) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
374 // figure out if this is an AMR audio track
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
375 if (m_pTrakAtom->FindAtom("trak.mdia.minf.stbl.stsd.samr") ||
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
376 m_pTrakAtom->FindAtom("trak.mdia.minf.stbl.stsd.sawb")) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
377 m_isAmr = AMR_TRUE;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
378 m_curMode = (pBytes[0] >> 3) & 0x000F;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
379 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
380 m_isAmr = AMR_FALSE;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
381 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
382 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
383
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
384 if (m_isAmr == AMR_TRUE) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
385 curMode = (pBytes[0] >> 3) &0x000F; // The mode is in the first byte
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
386 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
387
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
388 if (duration == MP4_INVALID_DURATION) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
389 duration = GetFixedSampleDuration();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
390 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
391
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
392 VERBOSE_WRITE_SAMPLE(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
393 printf("duration "U64"\n", duration));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
394
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
395 if ((m_isAmr == AMR_TRUE) &&
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
396 (m_curMode != curMode)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
397 WriteChunkBuffer();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
398 m_curMode = curMode;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
399 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
400
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
401 // append sample bytes to chunk buffer
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
402 m_pChunkBuffer = (u_int8_t*)MP4Realloc(m_pChunkBuffer,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
403 m_chunkBufferSize + numBytes);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
404 memcpy(&m_pChunkBuffer[m_chunkBufferSize], pBytes, numBytes);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
405 m_chunkBufferSize += numBytes;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
406 m_chunkSamples++;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
407 m_chunkDuration += duration;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
408
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
409 UpdateSampleSizes(m_writeSampleId, numBytes);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
410
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
411 UpdateSampleTimes(duration);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
412
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
413 UpdateRenderingOffsets(m_writeSampleId, renderingOffset);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
414
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
415 UpdateSyncSamples(m_writeSampleId, isSyncSample);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
416
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
417 if (IsChunkFull(m_writeSampleId)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
418 WriteChunkBuffer();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
419 m_curMode = curMode;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
420 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
421
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
422 UpdateDurations(duration);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
423
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
424 UpdateModificationTimes();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
425
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
426 m_writeSampleId++;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
427 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
428
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
429 void MP4Track::WriteChunkBuffer()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
430 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
431 if (m_chunkBufferSize == 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
432 return;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
433 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
434
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
435 u_int64_t chunkOffset = m_pFile->GetPosition();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
436
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
437 // write chunk buffer
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
438 m_pFile->WriteBytes(m_pChunkBuffer, m_chunkBufferSize);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
439
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
440 VERBOSE_WRITE_SAMPLE(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
441 printf("WriteChunk: track %u offset 0x"X64" size %u (0x%x) numSamples %u\n",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
442 m_trackId, chunkOffset, m_chunkBufferSize,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
443 m_chunkBufferSize, m_chunkSamples));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
444
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
445 UpdateSampleToChunk(m_writeSampleId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
446 m_pChunkCountProperty->GetValue() + 1,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
447 m_chunkSamples);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
448
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
449 UpdateChunkOffsets(chunkOffset);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
450
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
451 // clean up chunk buffer
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
452 MP4Free(m_pChunkBuffer);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
453 m_pChunkBuffer = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
454 m_chunkBufferSize = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
455 m_chunkSamples = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
456 m_chunkDuration = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
457 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
458
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
459 void MP4Track::FinishWrite()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
460 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
461 // write out any remaining samples in chunk buffer
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
462 WriteChunkBuffer();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
463
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
464 // record buffer size and bitrates
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
465 MP4BitfieldProperty* pBufferSizeProperty;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
466
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
467 if (m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
468 "trak.mdia.minf.stbl.stsd.*.esds.decConfigDescr.bufferSizeDB",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
469 (MP4Property**)&pBufferSizeProperty)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
470 pBufferSizeProperty->SetValue(GetMaxSampleSize());
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
471 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
472
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
473 MP4Integer32Property* pBitrateProperty;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
474
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
475 if (m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
476 "trak.mdia.minf.stbl.stsd.*.esds.decConfigDescr.maxBitrate",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
477 (MP4Property**)&pBitrateProperty)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
478 pBitrateProperty->SetValue(GetMaxBitrate());
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
479 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
480
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
481 if (m_pTrakAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
482 "trak.mdia.minf.stbl.stsd.*.esds.decConfigDescr.avgBitrate",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
483 (MP4Property**)&pBitrateProperty)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
484 pBitrateProperty->SetValue(GetAvgBitrate());
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
485 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
486 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
487
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
488 bool MP4Track::IsChunkFull(MP4SampleId sampleId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
489 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
490 if (m_samplesPerChunk) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
491 return m_chunkSamples >= m_samplesPerChunk;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
492 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
493
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
494 ASSERT(m_durationPerChunk);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
495 return m_chunkDuration >= m_durationPerChunk;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
496 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
497
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
498 u_int32_t MP4Track::GetNumberOfSamples()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
499 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
500 return m_pStszSampleCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
501 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
502
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
503 u_int32_t MP4Track::GetSampleSize(MP4SampleId sampleId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
504 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
505 u_int32_t fixedSampleSize =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
506 m_pStszFixedSampleSizeProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
507
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
508 if (fixedSampleSize != 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
509 return fixedSampleSize * m_bytesPerSample;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
510 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
511 return m_bytesPerSample *
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
512 m_pStszSampleSizeProperty->GetValue(sampleId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
513 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
514
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
515 u_int32_t MP4Track::GetMaxSampleSize()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
516 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
517 u_int32_t fixedSampleSize =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
518 m_pStszFixedSampleSizeProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
519
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
520 if (fixedSampleSize != 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
521 return fixedSampleSize * m_bytesPerSample;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
522 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
523
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
524 u_int32_t maxSampleSize = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
525 u_int32_t numSamples = m_pStszSampleSizeProperty->GetCount();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
526 for (MP4SampleId sid = 1; sid <= numSamples; sid++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
527 u_int32_t sampleSize =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
528 m_pStszSampleSizeProperty->GetValue(sid - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
529 if (sampleSize > maxSampleSize) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
530 maxSampleSize = sampleSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
531 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
532 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
533 return maxSampleSize * m_bytesPerSample;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
534 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
535
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
536 u_int64_t MP4Track::GetTotalOfSampleSizes()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
537 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
538 uint64_t retval;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
539 u_int32_t fixedSampleSize =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
540 m_pStszFixedSampleSizeProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
541
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
542 // if fixed sample size, just need to multiply by number of samples
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
543 if (fixedSampleSize != 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
544 retval = m_bytesPerSample;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
545 retval *= fixedSampleSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
546 retval *= GetNumberOfSamples();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
547 return retval;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
548 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
549
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
550 // else non-fixed sample size, sum them
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
551 u_int64_t totalSampleSizes = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
552 u_int32_t numSamples = m_pStszSampleSizeProperty->GetCount();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
553 for (MP4SampleId sid = 1; sid <= numSamples; sid++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
554 u_int32_t sampleSize =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
555 m_pStszSampleSizeProperty->GetValue(sid - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
556 totalSampleSizes += sampleSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
557 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
558 return totalSampleSizes * m_bytesPerSample;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
559 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
560
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
561 void MP4Track::UpdateSampleSizes(MP4SampleId sampleId, u_int32_t numBytes)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
562 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
563 if (m_bytesPerSample > 1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
564 if ((numBytes % m_bytesPerSample) != 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
565 // error
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
566 VERBOSE_ERROR(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
567 printf("UpdateSampleSize: numBytes %u not divisible by bytesPerSample %u sampleId %u\n",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
568 numBytes, m_bytesPerSample, sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
569 );
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
570 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
571 numBytes /= m_bytesPerSample;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
572 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
573 // for first sample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
574 if (sampleId == 1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
575 if (numBytes > 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
576 // presume sample size is fixed
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
577 m_pStszFixedSampleSizeProperty->SetValue(numBytes);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
578 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
579 // special case of first sample is zero bytes in length
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
580 // leave m_pStszFixedSampleSizeProperty at 0
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
581 // start recording variable sample sizes
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
582 m_pStszSampleSizeProperty->AddValue(0);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
583 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
584
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
585 } else { // sampleId > 1
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
586 u_int32_t fixedSampleSize =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
587 m_pStszFixedSampleSizeProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
588
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
589 if (fixedSampleSize == 0 || numBytes != fixedSampleSize) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
590 // sample size is not fixed
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
591
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
592 if (fixedSampleSize) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
593 // need to clear fixed sample size
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
594 m_pStszFixedSampleSizeProperty->SetValue(0);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
595
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
596 // and create sizes for all previous samples
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
597 for (MP4SampleId sid = 1; sid < sampleId; sid++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
598 m_pStszSampleSizeProperty->AddValue(fixedSampleSize);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
599 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
600 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
601
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
602 // add size value for this sample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
603 m_pStszSampleSizeProperty->AddValue(numBytes);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
604 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
605 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
606
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
607 m_pStszSampleCountProperty->IncrementValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
608 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
609
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
610 u_int32_t MP4Track::GetAvgBitrate()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
611 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
612 if (GetDuration() == 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
613 return 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
614 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
615
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
616 double calc = (double) (GetTotalOfSampleSizes());
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
617 // this is a bit better - we use the whole duration
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
618 calc *= 8.0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
619 calc *= GetTimeScale();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
620 calc /= (double) (GetDuration());
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
621 // we might want to think about rounding to the next 100 or 1000
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
622 return (uint32_t) ceil(calc);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
623 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
624
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
625 u_int32_t MP4Track::GetMaxBitrate()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
626 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
627 u_int32_t timeScale = GetTimeScale();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
628 MP4SampleId numSamples = GetNumberOfSamples();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
629 u_int32_t maxBytesPerSec = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
630 u_int32_t bytesThisSec = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
631 MP4Timestamp thisSecStart = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
632 MP4Timestamp lastSampleTime = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
633 uint32_t lastSampleSize = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
634
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
635 MP4SampleId thisSecStartSid = 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
636 for (MP4SampleId sid = 1; sid <= numSamples; sid++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
637 uint32_t sampleSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
638 MP4Timestamp sampleTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
639
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
640 sampleSize = GetSampleSize(sid);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
641 GetSampleTimes(sid, &sampleTime, NULL);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
642
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
643 if (sampleTime < thisSecStart + timeScale) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
644 bytesThisSec += sampleSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
645 lastSampleSize = sampleSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
646 lastSampleTime = sampleTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
647 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
648 // we've already written the last sample and sampleSize.
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
649 // this means that we've probably overflowed the last second
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
650 // calculate the time we've overflowed
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
651 MP4Duration overflow_dur =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
652 (thisSecStart + timeScale) - lastSampleTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
653 // calculate the duration of the last sample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
654 MP4Duration lastSampleDur = sampleTime - lastSampleTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
655 uint32_t overflow_bytes;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
656 // now, calculate the number of bytes we overflowed. Round up.
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
657 overflow_bytes =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
658 ((lastSampleSize * overflow_dur) + (lastSampleDur - 1)) / lastSampleDur;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
659
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
660 if (bytesThisSec - overflow_bytes > maxBytesPerSec) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
661 maxBytesPerSec = bytesThisSec - overflow_bytes;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
662 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
663
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
664 // now adjust the values for this sample. Remove the bytes
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
665 // from the first sample in this time frame
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
666 lastSampleTime = sampleTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
667 lastSampleSize = sampleSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
668 bytesThisSec += sampleSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
669 bytesThisSec -= GetSampleSize(thisSecStartSid);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
670 thisSecStartSid++;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
671 GetSampleTimes(thisSecStartSid, &thisSecStart, NULL);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
672 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
673 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
674
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
675 return maxBytesPerSec * 8;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
676 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
677
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
678 u_int32_t MP4Track::GetSampleStscIndex(MP4SampleId sampleId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
679 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
680 u_int32_t stscIndex;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
681 u_int32_t numStscs = m_pStscCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
682
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
683 if (numStscs == 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
684 throw new MP4Error("No data chunks exist", "GetSampleStscIndex");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
685 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
686
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
687 for (stscIndex = 0; stscIndex < numStscs; stscIndex++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
688 if (sampleId < m_pStscFirstSampleProperty->GetValue(stscIndex)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
689 ASSERT(stscIndex != 0);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
690 stscIndex -= 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
691 break;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
692 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
693 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
694 if (stscIndex == numStscs) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
695 ASSERT(stscIndex != 0);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
696 stscIndex -= 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
697 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
698
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
699 return stscIndex;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
700 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
701
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
702 FILE* MP4Track::GetSampleFile(MP4SampleId sampleId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
703 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
704 u_int32_t stscIndex =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
705 GetSampleStscIndex(sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
706
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
707 u_int32_t stsdIndex =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
708 m_pStscSampleDescrIndexProperty->GetValue(stscIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
709
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
710 // check if the answer will be the same as last time
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
711 if (m_lastStsdIndex && stsdIndex == m_lastStsdIndex) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
712 return m_lastSampleFile;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
713 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
714
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
715 MP4Atom* pStsdAtom =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
716 m_pTrakAtom->FindAtom("trak.mdia.minf.stbl.stsd");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
717 ASSERT(pStsdAtom);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
718
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
719 MP4Atom* pStsdEntryAtom =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
720 pStsdAtom->GetChildAtom(stsdIndex - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
721 ASSERT(pStsdEntryAtom);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
722
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
723 MP4Integer16Property* pDrefIndexProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
724 pStsdEntryAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
725 "*.dataReferenceIndex",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
726 (MP4Property**)&pDrefIndexProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
727
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
728 if (pDrefIndexProperty == NULL) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
729 throw new MP4Error("invalid stsd entry", "GetSampleFile");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
730 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
731
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
732 u_int32_t drefIndex =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
733 pDrefIndexProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
734
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
735 MP4Atom* pDrefAtom =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
736 m_pTrakAtom->FindAtom("trak.mdia.minf.dinf.dref");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
737 ASSERT(pDrefAtom);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
738
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
739 MP4Atom* pUrlAtom =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
740 pDrefAtom->GetChildAtom(drefIndex - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
741 ASSERT(pUrlAtom);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
742
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
743 FILE* pFile;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
744
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
745 if (pUrlAtom->GetFlags() & 1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
746 pFile = NULL; // self-contained
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
747 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
748 MP4StringProperty* pLocationProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
749 pUrlAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
750 "*.location",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
751 (MP4Property**)&pLocationProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
752 ASSERT(pLocationProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
753
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
754 const char* url = pLocationProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
755
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
756 VERBOSE_READ_SAMPLE(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
757 printf("dref url = %s\n", url));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
758
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
759 pFile = (FILE*)-1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
760
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
761 // attempt to open url if it's a file url
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
762 // currently this is the only thing we understand
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
763 if (!strncmp(url, "file:", 5)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
764 const char* fileName = url + 5;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
765 if (!strncmp(fileName, "//", 2)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
766 fileName = strchr(fileName + 2, '/');
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
767 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
768 if (fileName) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
769 pFile = fopen(fileName, "rb");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
770 if (!pFile) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
771 pFile = (FILE*)-1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
772 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
773 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
774 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
775 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
776
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
777 if (m_lastSampleFile) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
778 fclose(m_lastSampleFile);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
779 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
780
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
781 // cache the answer
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
782 m_lastStsdIndex = stsdIndex;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
783 m_lastSampleFile = pFile;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
784
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
785 return pFile;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
786 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
787
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
788 u_int64_t MP4Track::GetSampleFileOffset(MP4SampleId sampleId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
789 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
790 u_int32_t stscIndex =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
791 GetSampleStscIndex(sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
792
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
793 // firstChunk is the chunk index of the first chunk with
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
794 // samplesPerChunk samples in the chunk. There may be multiples -
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
795 // ie: several chunks with the same number of samples per chunk.
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
796 u_int32_t firstChunk =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
797 m_pStscFirstChunkProperty->GetValue(stscIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
798
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
799 MP4SampleId firstSample =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
800 m_pStscFirstSampleProperty->GetValue(stscIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
801
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
802 u_int32_t samplesPerChunk =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
803 m_pStscSamplesPerChunkProperty->GetValue(stscIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
804
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
805 // chunkId tells which is the absolute chunk number that this sample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
806 // is stored in.
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
807 MP4ChunkId chunkId = firstChunk +
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
808 ((sampleId - firstSample) / samplesPerChunk);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
809
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
810 // chunkOffset is the file offset (absolute) for the start of the chunk
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
811 u_int64_t chunkOffset = m_pChunkOffsetProperty->GetValue(chunkId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
812
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
813 MP4SampleId firstSampleInChunk =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
814 sampleId - ((sampleId - firstSample) % samplesPerChunk);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
815
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
816 // need cumulative samples sizes from firstSample to sampleId - 1
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
817 u_int32_t sampleOffset = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
818 for (MP4SampleId i = firstSampleInChunk; i < sampleId; i++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
819 sampleOffset += GetSampleSize(i);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
820 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
821
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
822 return chunkOffset + sampleOffset;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
823 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
824
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
825 void MP4Track::UpdateSampleToChunk(MP4SampleId sampleId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
826 MP4ChunkId chunkId, u_int32_t samplesPerChunk)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
827 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
828 u_int32_t numStsc = m_pStscCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
829
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
830 // if samplesPerChunk == samplesPerChunk of last entry
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
831 if (numStsc && samplesPerChunk ==
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
832 m_pStscSamplesPerChunkProperty->GetValue(numStsc-1)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
833
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
834 // nothing to do
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
835
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
836 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
837 // add stsc entry
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
838 m_pStscFirstChunkProperty->AddValue(chunkId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
839 m_pStscSamplesPerChunkProperty->AddValue(samplesPerChunk);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
840 m_pStscSampleDescrIndexProperty->AddValue(1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
841 m_pStscFirstSampleProperty->AddValue(sampleId - samplesPerChunk + 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
842
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
843 m_pStscCountProperty->IncrementValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
844 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
845 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
846
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
847 void MP4Track::UpdateChunkOffsets(u_int64_t chunkOffset)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
848 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
849 if (m_pChunkOffsetProperty->GetType() == Integer32Property) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
850 ((MP4Integer32Property*)m_pChunkOffsetProperty)->AddValue(chunkOffset);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
851 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
852 ((MP4Integer64Property*)m_pChunkOffsetProperty)->AddValue(chunkOffset);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
853 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
854 m_pChunkCountProperty->IncrementValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
855 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
856
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
857 MP4Duration MP4Track::GetFixedSampleDuration()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
858 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
859 u_int32_t numStts = m_pSttsCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
860
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
861 if (numStts == 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
862 return m_fixedSampleDuration;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
863 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
864 if (numStts != 1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
865 return MP4_INVALID_DURATION; // sample duration is not fixed
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
866 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
867 return m_pSttsSampleDeltaProperty->GetValue(0);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
868 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
869
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
870 bool MP4Track::SetFixedSampleDuration(MP4Duration duration)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
871 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
872 u_int32_t numStts = m_pSttsCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
873
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
874 // setting this is only allowed before samples have been written
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
875 if (numStts != 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
876 return false;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
877 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
878 m_fixedSampleDuration = duration;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
879 return true;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
880 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
881
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
882 void MP4Track::GetSampleTimes(MP4SampleId sampleId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
883 MP4Timestamp* pStartTime, MP4Duration* pDuration)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
884 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
885 u_int32_t numStts = m_pSttsCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
886 MP4SampleId sid = 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
887 MP4Duration elapsed = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
888
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
889 for (u_int32_t sttsIndex = 0; sttsIndex < numStts; sttsIndex++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
890 u_int32_t sampleCount =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
891 m_pSttsSampleCountProperty->GetValue(sttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
892 u_int32_t sampleDelta =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
893 m_pSttsSampleDeltaProperty->GetValue(sttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
894
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
895 if (sampleId <= sid + sampleCount - 1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
896 if (pStartTime) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
897 *pStartTime = (sampleId - sid);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
898 *pStartTime *= sampleDelta;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
899 *pStartTime += elapsed;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
900 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
901 if (pDuration) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
902 *pDuration = sampleDelta;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
903 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
904 return;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
905 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
906 sid += sampleCount;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
907 elapsed += sampleCount * sampleDelta;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
908 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
909
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
910 throw new MP4Error("sample id out of range",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
911 "MP4Track::GetSampleTimes");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
912 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
913
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
914 MP4SampleId MP4Track::GetSampleIdFromTime(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
915 MP4Timestamp when,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
916 bool wantSyncSample)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
917 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
918 u_int32_t numStts = m_pSttsCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
919 MP4SampleId sid = 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
920 MP4Duration elapsed = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
921
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
922 for (u_int32_t sttsIndex = 0; sttsIndex < numStts; sttsIndex++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
923 u_int32_t sampleCount =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
924 m_pSttsSampleCountProperty->GetValue(sttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
925 u_int32_t sampleDelta =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
926 m_pSttsSampleDeltaProperty->GetValue(sttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
927
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
928 if (sampleDelta == 0 && sttsIndex < numStts - 1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
929 VERBOSE_READ(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
930 printf("Warning: Zero sample duration, stts entry %u\n",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
931 sttsIndex));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
932 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
933
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
934 MP4Duration d = when - elapsed;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
935
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
936 if (d <= sampleCount * sampleDelta) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
937 MP4SampleId sampleId = sid;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
938 if (sampleDelta) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
939 sampleId += (d / sampleDelta);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
940 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
941
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
942 if (wantSyncSample) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
943 return GetNextSyncSample(sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
944 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
945 return sampleId;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
946 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
947
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
948 sid += sampleCount;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
949 elapsed += sampleCount * sampleDelta;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
950 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
951
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
952 throw new MP4Error("time out of range",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
953 "MP4Track::GetSampleIdFromTime");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
954
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
955 return 0; // satisfy MS compiler
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
956 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
957
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
958 void MP4Track::UpdateSampleTimes(MP4Duration duration)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
959 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
960 u_int32_t numStts = m_pSttsCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
961
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
962 // if duration == duration of last entry
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
963 if (numStts
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
964 && duration == m_pSttsSampleDeltaProperty->GetValue(numStts-1)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
965 // increment last entry sampleCount
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
966 m_pSttsSampleCountProperty->IncrementValue(1, numStts-1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
967
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
968 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
969 // add stts entry, sampleCount = 1, sampleDuration = duration
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
970 m_pSttsSampleCountProperty->AddValue(1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
971 m_pSttsSampleDeltaProperty->AddValue(duration);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
972 m_pSttsCountProperty->IncrementValue();;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
973 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
974 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
975
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
976 u_int32_t MP4Track::GetSampleCttsIndex(MP4SampleId sampleId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
977 MP4SampleId* pFirstSampleId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
978 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
979 u_int32_t numCtts = m_pCttsCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
980
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
981 MP4SampleId sid = 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
982
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
983 for (u_int32_t cttsIndex = 0; cttsIndex < numCtts; cttsIndex++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
984 u_int32_t sampleCount =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
985 m_pCttsSampleCountProperty->GetValue(cttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
986
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
987 if (sampleId <= sid + sampleCount - 1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
988 if (pFirstSampleId) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
989 *pFirstSampleId = sid;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
990 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
991 return cttsIndex;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
992 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
993 sid += sampleCount;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
994 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
995
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
996 throw new MP4Error("sample id out of range",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
997 "MP4Track::GetSampleCttsIndex");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
998 return 0; // satisfy MS compiler
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
999 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1000
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1001 MP4Duration MP4Track::GetSampleRenderingOffset(MP4SampleId sampleId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1002 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1003 if (m_pCttsCountProperty == NULL) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1004 return 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1005 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1006 if (m_pCttsCountProperty->GetValue() == 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1007 return 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1008 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1009
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1010 u_int32_t cttsIndex = GetSampleCttsIndex(sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1011
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1012 return m_pCttsSampleOffsetProperty->GetValue(cttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1013 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1014
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1015 void MP4Track::UpdateRenderingOffsets(MP4SampleId sampleId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1016 MP4Duration renderingOffset)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1017 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1018 // if ctts atom doesn't exist
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1019 if (m_pCttsCountProperty == NULL) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1020
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1021 // no rendering offset, so nothing to do
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1022 if (renderingOffset == 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1023 return;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1024 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1025
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1026 // else create a ctts atom
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1027 MP4Atom* pCttsAtom = AddAtom("trak.mdia.minf.stbl", "ctts");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1028
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1029 // and get handles on the properties
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1030 pCttsAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1031 "ctts.entryCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1032 (MP4Property**)&m_pCttsCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1033
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1034 pCttsAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1035 "ctts.entries.sampleCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1036 (MP4Property**)&m_pCttsSampleCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1037
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1038 pCttsAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1039 "ctts.entries.sampleOffset",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1040 (MP4Property**)&m_pCttsSampleOffsetProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1041
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1042 // if this is not the first sample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1043 if (sampleId > 1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1044 // add a ctts entry for all previous samples
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1045 // with rendering offset equal to zero
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1046 m_pCttsSampleCountProperty->AddValue(sampleId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1047 m_pCttsSampleOffsetProperty->AddValue(0);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1048 m_pCttsCountProperty->IncrementValue();;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1049 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1050 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1051
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1052 // ctts atom exists (now)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1053
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1054 u_int32_t numCtts = m_pCttsCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1055
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1056 // if renderingOffset == renderingOffset of last entry
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1057 if (numCtts && renderingOffset
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1058 == m_pCttsSampleOffsetProperty->GetValue(numCtts-1)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1059
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1060 // increment last entry sampleCount
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1061 m_pCttsSampleCountProperty->IncrementValue(1, numCtts-1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1062
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1063 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1064 // add ctts entry, sampleCount = 1, sampleOffset = renderingOffset
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1065 m_pCttsSampleCountProperty->AddValue(1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1066 m_pCttsSampleOffsetProperty->AddValue(renderingOffset);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1067 m_pCttsCountProperty->IncrementValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1068 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1069 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1070
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1071 void MP4Track::SetSampleRenderingOffset(MP4SampleId sampleId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1072 MP4Duration renderingOffset)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1073 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1074 // check if any ctts entries exist
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1075 if (m_pCttsCountProperty == NULL
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1076 || m_pCttsCountProperty->GetValue() == 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1077 // if not then Update routine can be used
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1078 // to create a ctts entry for samples before this one
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1079 // and a ctts entry for this sample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1080 UpdateRenderingOffsets(sampleId, renderingOffset);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1081
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1082 // but we also need a ctts entry
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1083 // for all samples after this one
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1084 u_int32_t afterSamples = GetNumberOfSamples() - sampleId;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1085
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1086 if (afterSamples) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1087 m_pCttsSampleCountProperty->AddValue(afterSamples);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1088 m_pCttsSampleOffsetProperty->AddValue(0);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1089 m_pCttsCountProperty->IncrementValue();;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1090 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1091
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1092 return;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1093 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1094
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1095 MP4SampleId firstSampleId;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1096 u_int32_t cttsIndex = GetSampleCttsIndex(sampleId, &firstSampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1097
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1098 // do nothing in the degenerate case
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1099 if (renderingOffset ==
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1100 m_pCttsSampleOffsetProperty->GetValue(cttsIndex)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1101 return;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1102 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1103
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1104 u_int32_t sampleCount =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1105 m_pCttsSampleCountProperty->GetValue(cttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1106
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1107 // if this sample has it's own ctts entry
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1108 if (sampleCount == 1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1109 // then just set the value,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1110 // note we don't attempt to collapse entries
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1111 m_pCttsSampleOffsetProperty->SetValue(renderingOffset, cttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1112 return;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1113 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1114
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1115 MP4SampleId lastSampleId = firstSampleId + sampleCount - 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1116
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1117 // else we share this entry with other samples
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1118 // we need to insert our own entry
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1119 if (sampleId == firstSampleId) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1120 // our sample is the first one
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1121 m_pCttsSampleCountProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1122 InsertValue(1, cttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1123 m_pCttsSampleOffsetProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1124 InsertValue(renderingOffset, cttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1125
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1126 m_pCttsSampleCountProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1127 SetValue(sampleCount - 1, cttsIndex + 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1128
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1129 m_pCttsCountProperty->IncrementValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1130
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1131 } else if (sampleId == lastSampleId) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1132 // our sample is the last one
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1133 m_pCttsSampleCountProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1134 InsertValue(1, cttsIndex + 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1135 m_pCttsSampleOffsetProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1136 InsertValue(renderingOffset, cttsIndex + 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1137
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1138 m_pCttsSampleCountProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1139 SetValue(sampleCount - 1, cttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1140
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1141 m_pCttsCountProperty->IncrementValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1142
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1143 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1144 // our sample is in the middle, UGH!
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1145
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1146 // insert our new entry
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1147 m_pCttsSampleCountProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1148 InsertValue(1, cttsIndex + 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1149 m_pCttsSampleOffsetProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1150 InsertValue(renderingOffset, cttsIndex + 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1151
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1152 // adjust count of previous entry
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1153 m_pCttsSampleCountProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1154 SetValue(sampleId - firstSampleId, cttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1155
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1156 // insert new entry for those samples beyond our sample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1157 m_pCttsSampleCountProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1158 InsertValue(lastSampleId - sampleId, cttsIndex + 2);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1159 u_int32_t oldRenderingOffset =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1160 m_pCttsSampleOffsetProperty->GetValue(cttsIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1161 m_pCttsSampleOffsetProperty->
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1162 InsertValue(oldRenderingOffset, cttsIndex + 2);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1163
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1164 m_pCttsCountProperty->IncrementValue(2);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1165 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1166 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1167
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1168 bool MP4Track::IsSyncSample(MP4SampleId sampleId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1169 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1170 if (m_pStssCountProperty == NULL) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1171 return true;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1172 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1173
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1174 u_int32_t numStss = m_pStssCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1175
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1176 for (u_int32_t stssIndex = 0; stssIndex < numStss; stssIndex++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1177 MP4SampleId syncSampleId =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1178 m_pStssSampleProperty->GetValue(stssIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1179
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1180 if (sampleId == syncSampleId) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1181 return true;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1182 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1183 if (sampleId < syncSampleId) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1184 break;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1185 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1186 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1187
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1188 return false;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1189 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1190
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1191 // N.B. "next" is inclusive of this sample id
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1192 MP4SampleId MP4Track::GetNextSyncSample(MP4SampleId sampleId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1193 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1194 if (m_pStssCountProperty == NULL) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1195 return sampleId;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1196 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1197
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1198 u_int32_t numStss = m_pStssCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1199
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1200 for (u_int32_t stssIndex = 0; stssIndex < numStss; stssIndex++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1201 MP4SampleId syncSampleId =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1202 m_pStssSampleProperty->GetValue(stssIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1203
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1204 if (sampleId > syncSampleId) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1205 continue;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1206 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1207 return syncSampleId;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1208 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1209
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1210 // LATER check stsh for alternate sample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1211
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1212 return MP4_INVALID_SAMPLE_ID;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1213 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1214
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1215 void MP4Track::UpdateSyncSamples(MP4SampleId sampleId, bool isSyncSample)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1216 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1217 if (isSyncSample) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1218 // if stss atom exists, add entry
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1219 if (m_pStssCountProperty) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1220 m_pStssSampleProperty->AddValue(sampleId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1221 m_pStssCountProperty->IncrementValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1222 } // else nothing to do (yet)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1223
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1224 } else { // !isSyncSample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1225 // if stss atom doesn't exist, create one
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1226 if (m_pStssCountProperty == NULL) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1227
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1228 MP4Atom* pStssAtom = AddAtom("trak.mdia.minf.stbl", "stss");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1229
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1230 pStssAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1231 "stss.entryCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1232 (MP4Property**)&m_pStssCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1233
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1234 pStssAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1235 "stss.entries.sampleNumber",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1236 (MP4Property**)&m_pStssSampleProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1237
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1238 // set values for all samples that came before this one
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1239 for (MP4SampleId sid = 1; sid < sampleId; sid++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1240 m_pStssSampleProperty->AddValue(sid);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1241 m_pStssCountProperty->IncrementValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1242 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1243 } // else nothing to do
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1244 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1245 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1246
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1247 MP4Atom* MP4Track::AddAtom(char* parentName, char* childName)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1248 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1249 MP4Atom* pChildAtom = MP4Atom::CreateAtom(childName);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1250
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1251 MP4Atom* pParentAtom = m_pTrakAtom->FindAtom(parentName);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1252 ASSERT(pParentAtom);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1253
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1254 pParentAtom->AddChildAtom(pChildAtom);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1255
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1256 pChildAtom->Generate();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1257
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1258 return pChildAtom;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1259 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1260
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1261 u_int64_t MP4Track::GetDuration()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1262 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1263 return m_pMediaDurationProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1264 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1265
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1266 u_int32_t MP4Track::GetTimeScale()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1267 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1268 return m_pTimeScaleProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1269 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1270
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1271 void MP4Track::UpdateDurations(MP4Duration duration)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1272 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1273 // update media, track, and movie durations
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1274 m_pMediaDurationProperty->SetValue(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1275 m_pMediaDurationProperty->GetValue() + duration);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1276
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1277 MP4Duration movieDuration = ToMovieDuration(duration);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1278 m_pTrackDurationProperty->SetValue(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1279 m_pTrackDurationProperty->GetValue() + movieDuration);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1280
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1281 m_pFile->UpdateDuration(m_pTrackDurationProperty->GetValue());
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1282 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1283
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1284 MP4Duration MP4Track::ToMovieDuration(MP4Duration trackDuration)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1285 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1286 return (trackDuration * m_pFile->GetTimeScale())
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1287 / m_pTimeScaleProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1288 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1289
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1290 void MP4Track::UpdateModificationTimes()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1291 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1292 // update media and track modification times
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1293 MP4Timestamp now = MP4GetAbsTimestamp();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1294 m_pMediaModificationProperty->SetValue(now);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1295 m_pTrackModificationProperty->SetValue(now);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1296 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1297
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1298 u_int32_t MP4Track::GetNumberOfChunks()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1299 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1300 return m_pChunkOffsetProperty->GetCount();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1301 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1302
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1303 u_int32_t MP4Track::GetChunkStscIndex(MP4ChunkId chunkId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1304 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1305 u_int32_t stscIndex;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1306 u_int32_t numStscs = m_pStscCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1307
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1308 ASSERT(chunkId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1309 ASSERT(numStscs > 0);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1310
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1311 for (stscIndex = 0; stscIndex < numStscs; stscIndex++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1312 if (chunkId < m_pStscFirstChunkProperty->GetValue(stscIndex)) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1313 ASSERT(stscIndex != 0);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1314 break;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1315 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1316 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1317 return stscIndex - 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1318 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1319
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1320 MP4Timestamp MP4Track::GetChunkTime(MP4ChunkId chunkId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1321 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1322 u_int32_t stscIndex = GetChunkStscIndex(chunkId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1323
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1324 MP4ChunkId firstChunkId =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1325 m_pStscFirstChunkProperty->GetValue(stscIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1326
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1327 MP4SampleId firstSample =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1328 m_pStscFirstSampleProperty->GetValue(stscIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1329
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1330 u_int32_t samplesPerChunk =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1331 m_pStscSamplesPerChunkProperty->GetValue(stscIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1332
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1333 MP4SampleId firstSampleInChunk =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1334 firstSample + ((chunkId - firstChunkId) * samplesPerChunk);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1335
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1336 MP4Timestamp chunkTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1337
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1338 GetSampleTimes(firstSampleInChunk, &chunkTime, NULL);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1339
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1340 return chunkTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1341 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1342
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1343 u_int32_t MP4Track::GetChunkSize(MP4ChunkId chunkId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1344 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1345 u_int32_t stscIndex = GetChunkStscIndex(chunkId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1346
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1347 MP4ChunkId firstChunkId =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1348 m_pStscFirstChunkProperty->GetValue(stscIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1349
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1350 MP4SampleId firstSample =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1351 m_pStscFirstSampleProperty->GetValue(stscIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1352
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1353 u_int32_t samplesPerChunk =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1354 m_pStscSamplesPerChunkProperty->GetValue(stscIndex);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1355
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1356 MP4SampleId firstSampleInChunk =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1357 firstSample + ((chunkId - firstChunkId) * samplesPerChunk);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1358
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1359 // need cumulative sizes of samples in chunk
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1360 u_int32_t chunkSize = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1361 for (u_int32_t i = 0; i < samplesPerChunk; i++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1362 chunkSize += GetSampleSize(firstSampleInChunk + i);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1363 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1364
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1365 return chunkSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1366 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1367
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1368 void MP4Track::ReadChunk(MP4ChunkId chunkId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1369 u_int8_t** ppChunk, u_int32_t* pChunkSize)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1370 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1371 ASSERT(chunkId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1372 ASSERT(ppChunk);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1373 ASSERT(pChunkSize);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1374
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1375 u_int64_t chunkOffset =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1376 m_pChunkOffsetProperty->GetValue(chunkId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1377
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1378 *pChunkSize = GetChunkSize(chunkId);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1379 *ppChunk = (u_int8_t*)MP4Malloc(*pChunkSize);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1380
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1381 VERBOSE_READ_SAMPLE(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1382 printf("ReadChunk: track %u id %u offset 0x"X64" size %u (0x%x)\n",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1383 m_trackId, chunkId, chunkOffset, *pChunkSize, *pChunkSize));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1384
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1385 u_int64_t oldPos = m_pFile->GetPosition(); // only used in mode == 'w'
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1386 try {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1387 m_pFile->SetPosition(chunkOffset);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1388 m_pFile->ReadBytes(*ppChunk, *pChunkSize);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1389 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1390 catch (MP4Error* e) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1391 // let's not leak memory
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1392 MP4Free(*ppChunk);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1393 *ppChunk = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1394
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1395 if (m_pFile->GetMode() == 'w') {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1396 m_pFile->SetPosition(oldPos);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1397 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1398 throw e;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1399 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1400
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1401 if (m_pFile->GetMode() == 'w') {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1402 m_pFile->SetPosition(oldPos);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1403 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1404 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1405
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1406 void MP4Track::RewriteChunk(MP4ChunkId chunkId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1407 u_int8_t* pChunk, u_int32_t chunkSize)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1408 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1409 u_int64_t chunkOffset = m_pFile->GetPosition();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1410
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1411 m_pFile->WriteBytes(pChunk, chunkSize);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1412
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1413 m_pChunkOffsetProperty->SetValue(chunkOffset, chunkId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1414
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1415 VERBOSE_WRITE_SAMPLE(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1416 printf("RewriteChunk: track %u id %u offset 0x"X64" size %u (0x%x)\n",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1417 m_trackId, chunkId, chunkOffset, chunkSize, chunkSize));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1418 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1419
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1420 // map track type name aliases to official names
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1421
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1422
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1423 bool MP4Track::InitEditListProperties()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1424 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1425 m_pElstCountProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1426 m_pElstMediaTimeProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1427 m_pElstDurationProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1428 m_pElstRateProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1429 m_pElstReservedProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1430
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1431 MP4Atom* pElstAtom =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1432 m_pTrakAtom->FindAtom("trak.edts.elst");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1433
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1434 if (!pElstAtom) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1435 return false;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1436 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1437
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1438 pElstAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1439 "elst.entryCount",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1440 (MP4Property**)&m_pElstCountProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1441
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1442 pElstAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1443 "elst.entries.mediaTime",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1444 (MP4Property**)&m_pElstMediaTimeProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1445
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1446 pElstAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1447 "elst.entries.segmentDuration",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1448 (MP4Property**)&m_pElstDurationProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1449
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1450 pElstAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1451 "elst.entries.mediaRate",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1452 (MP4Property**)&m_pElstRateProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1453
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1454 pElstAtom->FindProperty(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1455 "elst.entries.reserved",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1456 (MP4Property**)&m_pElstReservedProperty);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1457
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1458 return m_pElstCountProperty
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1459 && m_pElstMediaTimeProperty
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1460 && m_pElstDurationProperty
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1461 && m_pElstRateProperty
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1462 && m_pElstReservedProperty;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1463 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1464
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1465 MP4EditId MP4Track::AddEdit(MP4EditId editId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1466 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1467 if (!m_pElstCountProperty) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1468 m_pFile->AddDescendantAtoms(m_pTrakAtom, "edts.elst");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1469 InitEditListProperties();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1470 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1471
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1472 if (editId == MP4_INVALID_EDIT_ID) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1473 editId = m_pElstCountProperty->GetValue() + 1;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1474 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1475
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1476 m_pElstMediaTimeProperty->InsertValue(0, editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1477 m_pElstDurationProperty->InsertValue(0, editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1478 m_pElstRateProperty->InsertValue(1, editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1479 m_pElstReservedProperty->InsertValue(0, editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1480
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1481 m_pElstCountProperty->IncrementValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1482
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1483 return editId;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1484 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1485
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1486 void MP4Track::DeleteEdit(MP4EditId editId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1487 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1488 if (editId == MP4_INVALID_EDIT_ID) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1489 throw new MP4Error("edit id can't be zero",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1490 "MP4Track::DeleteEdit");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1491 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1492
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1493 if (!m_pElstCountProperty
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1494 || m_pElstCountProperty->GetValue() == 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1495 throw new MP4Error("no edits exist",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1496 "MP4Track::DeleteEdit");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1497 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1498
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1499 m_pElstMediaTimeProperty->DeleteValue(editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1500 m_pElstDurationProperty->DeleteValue(editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1501 m_pElstRateProperty->DeleteValue(editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1502 m_pElstReservedProperty->DeleteValue(editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1503
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1504 m_pElstCountProperty->IncrementValue(-1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1505
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1506 // clean up if last edit is deleted
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1507 if (m_pElstCountProperty->GetValue() == 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1508 m_pElstCountProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1509 m_pElstMediaTimeProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1510 m_pElstDurationProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1511 m_pElstRateProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1512 m_pElstReservedProperty = NULL;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1513
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1514 m_pTrakAtom->DeleteChildAtom(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1515 m_pTrakAtom->FindAtom("trak.edts"));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1516 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1517 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1518
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1519 MP4Timestamp MP4Track::GetEditStart(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1520 MP4EditId editId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1521 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1522 if (editId == MP4_INVALID_EDIT_ID) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1523 return MP4_INVALID_TIMESTAMP;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1524 } else if (editId == 1) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1525 return 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1526 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1527 return (MP4Timestamp)GetEditTotalDuration(editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1528 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1529
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1530 MP4Duration MP4Track::GetEditTotalDuration(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1531 MP4EditId editId)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1532 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1533 u_int32_t numEdits = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1534
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1535 if (m_pElstCountProperty) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1536 numEdits = m_pElstCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1537 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1538
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1539 if (editId == MP4_INVALID_EDIT_ID) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1540 editId = numEdits;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1541 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1542
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1543 if (numEdits == 0 || editId > numEdits) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1544 return MP4_INVALID_DURATION;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1545 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1546
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1547 MP4Duration totalDuration = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1548
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1549 for (MP4EditId eid = 1; eid <= editId; eid++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1550 totalDuration +=
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1551 m_pElstDurationProperty->GetValue(eid - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1552 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1553
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1554 return totalDuration;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1555 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1556
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1557 MP4SampleId MP4Track::GetSampleIdFromEditTime(
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1558 MP4Timestamp editWhen,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1559 MP4Timestamp* pStartTime,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1560 MP4Duration* pDuration)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1561 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1562 MP4SampleId sampleId = MP4_INVALID_SAMPLE_ID;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1563 u_int32_t numEdits = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1564
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1565 if (m_pElstCountProperty) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1566 numEdits = m_pElstCountProperty->GetValue();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1567 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1568
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1569 if (numEdits) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1570 MP4Duration editElapsedDuration = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1571
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1572 for (MP4EditId editId = 1; editId <= numEdits; editId++) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1573 // remember edit segment's start time (in edit timeline)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1574 MP4Timestamp editStartTime =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1575 (MP4Timestamp)editElapsedDuration;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1576
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1577 // accumulate edit segment's duration
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1578 editElapsedDuration +=
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1579 m_pElstDurationProperty->GetValue(editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1580
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1581 // calculate difference between the specified edit time
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1582 // and the end of this edit segment
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1583 if (editElapsedDuration - editWhen <= 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1584 // the specified time has not yet been reached
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1585 continue;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1586 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1587
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1588 // 'editWhen' is within this edit segment
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1589
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1590 // calculate the specified edit time
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1591 // relative to just this edit segment
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1592 MP4Duration editOffset =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1593 editWhen - editStartTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1594
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1595 // calculate the media (track) time that corresponds
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1596 // to the specified edit time based on the edit list
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1597 MP4Timestamp mediaWhen =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1598 m_pElstMediaTimeProperty->GetValue(editId - 1)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1599 + editOffset;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1600
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1601 // lookup the sample id for the media time
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1602 sampleId = GetSampleIdFromTime(mediaWhen, false);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1603
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1604 // lookup the sample's media start time and duration
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1605 MP4Timestamp sampleStartTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1606 MP4Duration sampleDuration;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1607
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1608 GetSampleTimes(sampleId, &sampleStartTime, &sampleDuration);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1609
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1610 // calculate the difference if any between when the sample
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1611 // would naturally start and when it starts in the edit timeline
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1612 MP4Duration sampleStartOffset =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1613 mediaWhen - sampleStartTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1614
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1615 // calculate the start time for the sample in the edit time line
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1616 MP4Timestamp editSampleStartTime =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1617 editWhen - MIN(editOffset, sampleStartOffset);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1618
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1619 MP4Duration editSampleDuration = 0;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1620
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1621 // calculate how long this sample lasts in the edit list timeline
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1622 if (m_pElstRateProperty->GetValue(editId - 1) == 0) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1623 // edit segment is a "dwell"
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1624 // so sample duration is that of the edit segment
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1625 editSampleDuration =
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1626 m_pElstDurationProperty->GetValue(editId - 1);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1627
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1628 } else {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1629 // begin with the natural sample duration
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1630 editSampleDuration = sampleDuration;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1631
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1632 // now shorten that if the edit segment starts
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1633 // after the sample would naturally start
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1634 if (editOffset < sampleStartOffset) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1635 editSampleDuration -= sampleStartOffset - editOffset;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1636 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1637
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1638 // now shorten that if the edit segment ends
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1639 // before the sample would naturally end
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1640 if (editElapsedDuration
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1641 < editSampleStartTime + sampleDuration) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1642 editSampleDuration -= (editSampleStartTime + sampleDuration)
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1643 - editElapsedDuration;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1644 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1645 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1646
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1647 if (pStartTime) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1648 *pStartTime = editSampleStartTime;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1649 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1650
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1651 if (pDuration) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1652 *pDuration = editSampleDuration;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1653 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1654
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1655 VERBOSE_EDIT(m_pFile->GetVerbosity(),
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1656 printf("GetSampleIdFromEditTime: when "U64" "
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1657 "sampleId %u start "U64" duration "D64"\n",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1658 editWhen, sampleId,
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1659 editSampleStartTime, editSampleDuration));
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1660
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1661 return sampleId;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1662 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1663
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1664 throw new MP4Error("time out of range",
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1665 "MP4Track::GetSampleIdFromEditTime");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1666
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1667 } else { // no edit list
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1668 sampleId = GetSampleIdFromTime(editWhen, false);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1669
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1670 if (pStartTime || pDuration) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1671 GetSampleTimes(sampleId, pStartTime, pDuration);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1672 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1673 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1674
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1675 return sampleId;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1676 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1677
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1678 void MP4Track::CalculateBytesPerSample ()
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1679 {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1680 MP4Atom *pMedia = m_pTrakAtom->FindAtom("trak.mdia.minf.stbl.stsd");
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1681 MP4Atom *pMediaData;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1682 const char *media_data_name;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1683 if (pMedia == NULL) return;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1684
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1685 if (pMedia->GetNumberOfChildAtoms() != 1) return;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1686
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1687 pMediaData = pMedia->GetChildAtom(0);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1688 media_data_name = pMediaData->GetType();
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1689 if ((ATOMID(media_data_name) == ATOMID("twos")) ||
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1690 (ATOMID(media_data_name) == ATOMID("sowt"))) {
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1691 MP4IntegerProperty *chan, *sampleSize;
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1692 chan = (MP4IntegerProperty *)pMediaData->GetProperty(4);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1693 sampleSize = (MP4IntegerProperty *)pMediaData->GetProperty(5);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1694 m_bytesPerSample = chan->GetValue() * (sampleSize->GetValue() / 8);
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1695 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1696 }
6a86fdd4dea4 [svn] Replacement libmp4v2.
nenolod
parents:
diff changeset
1697