00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "Ap4AtomSampleTable.h"
00033 #include "Ap4ByteStream.h"
00034 #include "Ap4StsdAtom.h"
00035 #include "Ap4StscAtom.h"
00036 #include "Ap4StcoAtom.h"
00037 #include "Ap4Co64Atom.h"
00038 #include "Ap4StszAtom.h"
00039 #include "Ap4SttsAtom.h"
00040 #include "Ap4CttsAtom.h"
00041 #include "Ap4StssAtom.h"
00042 #include "Ap4Sample.h"
00043 #include "Ap4Atom.h"
00044
00045
00046
00047
00048 AP4_AtomSampleTable::AP4_AtomSampleTable(AP4_ContainerAtom* stbl,
00049 AP4_ByteStream& sample_stream) :
00050 m_SampleStream(sample_stream)
00051 {
00052 m_StscAtom = dynamic_cast<AP4_StscAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STSC));
00053 m_StcoAtom = dynamic_cast<AP4_StcoAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STCO));
00054 m_Co64Atom = dynamic_cast<AP4_Co64Atom*>(stbl->GetChild(AP4_ATOM_TYPE_CO64));
00055 m_StszAtom = dynamic_cast<AP4_StszAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STSZ));
00056 m_CttsAtom = dynamic_cast<AP4_CttsAtom*>(stbl->GetChild(AP4_ATOM_TYPE_CTTS));
00057 m_SttsAtom = dynamic_cast<AP4_SttsAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STTS));
00058 m_StssAtom = dynamic_cast<AP4_StssAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STSS));
00059 m_StsdAtom = dynamic_cast<AP4_StsdAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STSD));
00060
00061
00062 m_SampleStream.AddReference();
00063 }
00064
00065
00066
00067
00068 AP4_AtomSampleTable::~AP4_AtomSampleTable()
00069 {
00070 m_SampleStream.Release();
00071 }
00072
00073
00074
00075
00076 AP4_Result
00077 AP4_AtomSampleTable::GetSample(AP4_Ordinal index,
00078 AP4_Sample& sample)
00079 {
00080 AP4_Result result;
00081
00082
00083 index++;
00084
00085
00086 AP4_Ordinal chunk, skip, desc;
00087 result = m_StscAtom->GetChunkForSample(index, chunk, skip, desc);
00088 if (AP4_FAILED(result)) return result;
00089
00090
00091 if (skip > index) return AP4_ERROR_INTERNAL;
00092
00093
00094 AP4_Offset offset;
00095 if (m_StcoAtom) result = m_StcoAtom->GetChunkOffset(chunk, offset);
00096 else if (m_Co64Atom) result = m_Co64Atom->GetChunkOffset(chunk, offset);
00097 else result = AP4_ERROR_INTERNAL;
00098 if (AP4_FAILED(result)) return result;
00099
00100
00101 for (unsigned int i = index-skip; i < index; i++) {
00102 AP4_Size size;
00103 result = m_StszAtom->GetSampleSize(i, size);
00104 if (AP4_FAILED(result)) return result;
00105 offset += size;
00106 }
00107
00108
00109 sample.SetDescriptionIndex(desc-1);
00110
00111
00112 AP4_TimeStamp cts_offset, dts;
00113 result = m_SttsAtom->GetDts(index, dts);
00114 if (AP4_FAILED(result)) return result;
00115 sample.SetDts(dts);
00116 if (m_CttsAtom == NULL) {
00117 sample.SetCts(dts);
00118 } else {
00119 result = m_CttsAtom->GetCtsOffset(index, cts_offset);
00120 if (AP4_FAILED(result)) return result;
00121 sample.SetCts(dts + cts_offset);
00122 }
00123
00124
00125 AP4_Size sample_size;
00126 result = m_StszAtom->GetSampleSize(index, sample_size);
00127 if (AP4_FAILED(result)) return result;
00128 sample.SetSize(sample_size);
00129
00130
00131 sample.SetOffset(offset);
00132
00133
00134 sample.SetDataStream(m_SampleStream);
00135
00136 return AP4_SUCCESS;
00137 }
00138
00139
00140
00141
00142 AP4_Cardinal
00143 AP4_AtomSampleTable::GetSampleCount()
00144 {
00145 return m_StszAtom ? m_StszAtom->GetSampleCount() : 0;
00146 }
00147
00148
00149
00150
00151 AP4_SampleDescription*
00152 AP4_AtomSampleTable::GetSampleDescription(AP4_Ordinal index)
00153 {
00154 return m_StsdAtom ? m_StsdAtom->GetSampleDescription(index) : NULL;
00155 }
00156
00157
00158
00159
00160 AP4_Cardinal
00161 AP4_AtomSampleTable::GetSampleDescriptionCount()
00162 {
00163 return m_StsdAtom ? m_StsdAtom->GetSampleDescriptionCount() : 0;
00164 }
00165
00166
00167
00168
00169 AP4_Result
00170 AP4_AtomSampleTable::GetChunkForSample(AP4_Ordinal sample,
00171 AP4_Ordinal& chunk,
00172 AP4_Ordinal& skip,
00173 AP4_Ordinal& sample_description)
00174 {
00175 return m_StscAtom ? m_StscAtom->GetChunkForSample(sample, chunk, skip, sample_description) : AP4_FAILURE;
00176 }
00177
00178
00179
00180
00181 AP4_Result
00182 AP4_AtomSampleTable::GetChunkOffset(AP4_Ordinal chunk, AP4_Offset& offset)
00183 {
00184 return
00185 m_StcoAtom ? m_StcoAtom->GetChunkOffset(chunk, offset) :
00186 m_Co64Atom ? m_Co64Atom->GetChunkOffset(chunk, offset) :
00187 AP4_FAILURE;
00188 }
00189
00190
00191
00192
00193 AP4_Result
00194 AP4_AtomSampleTable::SetChunkOffset(AP4_Ordinal chunk, AP4_Offset offset)
00195 {
00196 return
00197 m_StcoAtom ? m_StcoAtom->SetChunkOffset(chunk, offset) :
00198 m_Co64Atom ? m_Co64Atom->SetChunkOffset(chunk, offset) :
00199 AP4_FAILURE;
00200 }
00201
00202
00203
00204
00205 AP4_Result
00206 AP4_AtomSampleTable::SetSampleSize(AP4_Ordinal sample, AP4_Size size)
00207 {
00208 return m_StszAtom ? m_StszAtom->SetSampleSize(sample, size) : AP4_FAILURE;
00209 }
00210
00211
00212
00213
00214 AP4_Result
00215 AP4_AtomSampleTable::GetSampleIndexForTimeStamp(AP4_TimeStamp ts,
00216 AP4_Ordinal& index)
00217 {
00218 return m_SttsAtom ? m_SttsAtom->GetSampleIndexForTimeStamp(ts, index)
00219 : AP4_FAILURE;
00220 }