- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 }