Ap4AtomSampleTable.cpp

00001 /*****************************************************************
00002 |
00003 |    AP4 - Atom Based Sample Tables
00004 |
00005 |    Copyright 2003 Gilles Boccon-Gibod & Julien Boeuf
00006 |
00007 |
00008 |    This atom is part of AP4 (MP4 Audio Proatom Library).
00009 |
00010 |    Unless you have obtained Bento4 under a difference license,
00011 |    this version of Bento4 is Bento4|GPL.
00012 |    Bento4|GPL is free software; you can redistribute it and/or modify
00013 |    it under the terms of the GNU General Public License as published by
00014 |    the Free Software Foundation; either version 2, or (at your option)
00015 |    any later version.
00016 |
00017 |    Bento4|GPL is distributed in the hope that it will be useful,
00018 |    but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 |    GNU General Public License for more details.
00021 |
00022 |    You should have received a copy of the GNU General Public License
00023 |    along with Bento4|GPL; see the atom COPYING.  If not, write to the
00024 |    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
00025 |    02111-1307, USA.
00026 |
00027  ****************************************************************/
00028 
00029 /*----------------------------------------------------------------------
00030 |       includes
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 |       AP4_AtomSampleTable::AP4_AtomSampleTable
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     // keep a reference to the sample stream
00062     m_SampleStream.AddReference();
00063 }
00064 
00065 /*----------------------------------------------------------------------
00066 |       AP4_AtomSampleTable::~AP4_AtomSampleTable
00067 +---------------------------------------------------------------------*/
00068 AP4_AtomSampleTable::~AP4_AtomSampleTable()
00069 {
00070     m_SampleStream.Release();
00071 }
00072 
00073 /*----------------------------------------------------------------------
00074 |       AP4_AtomSampleTable::GetSample
00075 +---------------------------------------------------------------------*/
00076 AP4_Result
00077 AP4_AtomSampleTable::GetSample(AP4_Ordinal index, 
00078                                AP4_Sample& sample)
00079 {
00080     AP4_Result result;
00081 
00082     // MP4 uses 1-based indexes internally, so adjust by one
00083     index++;
00084 
00085         // find out in which chunk this sample is located
00086     AP4_Ordinal chunk, skip, desc;
00087     result = m_StscAtom->GetChunkForSample(index, chunk, skip, desc);
00088     if (AP4_FAILED(result)) return result;
00089     
00090     // check that the result is within bounds
00091     if (skip > index) return AP4_ERROR_INTERNAL;
00092 
00093     // get the atom offset for this chunk
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     // compute the additional offset inside the chunk
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     // set the description index
00109     sample.SetDescriptionIndex(desc-1); // adjust for 0-based indexes
00110 
00111     // set the dts and cts
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     // set the size
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     // set the offset
00131     sample.SetOffset(offset);
00132 
00133     // set the data stream
00134     sample.SetDataStream(m_SampleStream);
00135 
00136     return AP4_SUCCESS;
00137 }
00138 
00139 /*----------------------------------------------------------------------
00140 |       AP4_AtomSampleTable::GetSampleCount
00141 +---------------------------------------------------------------------*/
00142 AP4_Cardinal
00143 AP4_AtomSampleTable::GetSampleCount()
00144 {
00145     return m_StszAtom ? m_StszAtom->GetSampleCount() : 0;
00146 }
00147 
00148 /*----------------------------------------------------------------------
00149 |       AP4_AtomSampleTable::GetSampleDescription
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 |       AP4_AtomSampleTable::GetSampleDescriptionCount
00159 +---------------------------------------------------------------------*/
00160 AP4_Cardinal
00161 AP4_AtomSampleTable::GetSampleDescriptionCount()
00162 {
00163     return m_StsdAtom ? m_StsdAtom->GetSampleDescriptionCount() : 0;
00164 }
00165 
00166 /*----------------------------------------------------------------------
00167 |       AP4_AtomSampleTable::GetChunkForSample
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 |       AP4_AtomSampleTable::GetChunkOffset
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 |       AP4_AtomSampleTable::SetChunkOffset
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 |       AP4_AtomSampleTable::SetSampleSize
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 |       AP4_AtomSampleTable::GetSample
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 }

Generated on Tue Dec 13 14:47:19 2005 for guliverkli by  doxygen 1.4.5