Ap4Track.cpp

00001 /*****************************************************************
00002 |
00003 |    AP4 - Track Objects
00004 |
00005 |    Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
00006 |
00007 |
00008 |    This file is part of Bento4/AP4 (MP4 Atom Processing 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 file 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 "Ap4ByteStream.h"
00033 #include "Ap4HdlrAtom.h"
00034 #include "Ap4MvhdAtom.h"
00035 #include "Ap4Track.h"
00036 #include "Ap4Utils.h"
00037 #include "Ap4Sample.h"
00038 #include "Ap4DataBuffer.h"
00039 #include "Ap4TrakAtom.h"
00040 #include "Ap4MoovAtom.h"
00041 #include "Ap4AtomSampleTable.h"
00042 #include "Ap4SdpAtom.h"
00043 #include "Ap4MdhdAtom.h"
00044 
00045 /*----------------------------------------------------------------------
00046 |       AP4_Track::AP4_Track
00047 +---------------------------------------------------------------------*/
00048 AP4_Track::AP4_Track(Type             type,
00049                      AP4_SampleTable* sample_table,
00050                      AP4_UI32         track_id, 
00051                      AP4_UI32         movie_time_scale,
00052                      AP4_UI32         media_time_scale,
00053                      AP4_UI32         media_duration,
00054                      const char*      language,
00055                      AP4_UI32         width,
00056                      AP4_UI32         height) :
00057     m_TrakAtomIsOwned(true),
00058     m_Type(type),
00059     m_SampleTable(sample_table),
00060     m_SampleTableIsOwned(false),
00061     m_MovieTimeScale(movie_time_scale ? 
00062                      movie_time_scale : 
00063                      AP4_TRACK_DEFAULT_MOVIE_TIMESCALE),
00064     m_MediaTimeScale(media_time_scale)
00065 {
00066     // compute the default volume value
00067     unsigned int volume = 0;
00068     if (type == TYPE_AUDIO) volume = 0x100;
00069 
00070     // compute the handler type and name
00071     AP4_Atom::Type hdlr_type;
00072     const char* hdlr_name;
00073     switch (type) {
00074         case TYPE_AUDIO:
00075             hdlr_type = AP4_HANDLER_TYPE_SOUN;
00076             hdlr_name = "Bento4 Sound Handler";
00077             break;
00078 
00079         case TYPE_VIDEO:
00080             hdlr_type = AP4_HANDLER_TYPE_VIDE;
00081             hdlr_name = "Bento4 Video Handler";
00082             break;
00083 
00084         case TYPE_HINT:
00085             hdlr_type = AP4_HANDLER_TYPE_HINT;
00086             hdlr_name = "Bento4 Hint Handler";
00087             break;
00088 
00089         default:
00090             hdlr_type = 0;
00091             hdlr_name = NULL;
00092             break;
00093     }
00094 
00095     // compute the track duration in units of the movie time scale
00096     AP4_UI32 track_duration = AP4_ConvertTime(media_duration,
00097                                               media_time_scale,
00098                                               movie_time_scale);
00099 
00100     // create a trak atom
00101     m_TrakAtom = new AP4_TrakAtom(sample_table,
00102                                   hdlr_type, 
00103                                   hdlr_name,
00104                                   track_id, 
00105                                   0, 
00106                                   0, 
00107                                   track_duration,
00108                                   media_time_scale,
00109                                   media_duration,
00110                                   volume, 
00111                                   language,
00112                                   width, 
00113                                   height);
00114 }
00115 
00116 /*----------------------------------------------------------------------
00117 |       AP4_Track::AP4_Track
00118 +---------------------------------------------------------------------*/
00119 AP4_Track::AP4_Track(AP4_TrakAtom&   atom, 
00120                      AP4_ByteStream& sample_stream, 
00121                      AP4_UI32        movie_time_scale) :
00122     m_TrakAtom(&atom),
00123     m_TrakAtomIsOwned(false),
00124     m_Type(TYPE_UNKNOWN),
00125     m_SampleTable(NULL),
00126     m_SampleTableIsOwned(true),
00127     m_MovieTimeScale(movie_time_scale),
00128     m_MediaTimeScale(0)
00129 {
00130     // find the handler type
00131     AP4_Atom* sub = atom.FindChild("mdia/hdlr");
00132     if (sub) {
00133         AP4_HdlrAtom* hdlr = dynamic_cast<AP4_HdlrAtom*>(sub);
00134         if (hdlr) {
00135             AP4_Atom::Type type = hdlr->GetHandlerType();
00136             if (type == AP4_HANDLER_TYPE_SOUN) {
00137                 m_Type = TYPE_AUDIO;
00138             } else if (type == AP4_HANDLER_TYPE_VIDE) {
00139                 m_Type = TYPE_VIDEO;
00140             } else if (type == AP4_HANDLER_TYPE_TEXT) {
00141                 m_Type = TYPE_TEXT;
00142             } else if (type == AP4_HANDLER_TYPE_TX3G) {
00143                 m_Type = TYPE_TEXT;
00144             } else if (type == AP4_HANDLER_TYPE_HINT) {
00145                 m_Type = TYPE_HINT;
00146             }
00147         }
00148     }
00149 
00150     // get the media time scale
00151     sub = atom.FindChild("mdia/mdhd");
00152     if (sub) {
00153         AP4_MdhdAtom* mdhd = dynamic_cast<AP4_MdhdAtom*>(sub);
00154         if (mdhd) {
00155             m_MediaTimeScale = mdhd->GetTimeScale();
00156         }
00157     }
00158 
00159     // create a facade for the stbl atom
00160     AP4_ContainerAtom* stbl = dynamic_cast<AP4_ContainerAtom*>(
00161         atom.FindChild("mdia/minf/stbl"));
00162     if (stbl) {
00163         m_SampleTable = new AP4_AtomSampleTable(stbl, sample_stream);
00164     }
00165 }
00166 
00167 /*----------------------------------------------------------------------
00168 |       AP4_Track::~AP4_Track
00169 +---------------------------------------------------------------------*/
00170 AP4_Track::~AP4_Track()
00171 {
00172     if (m_TrakAtomIsOwned) delete m_TrakAtom;
00173     if (m_SampleTableIsOwned) delete m_SampleTable;
00174 }
00175 
00176 /*----------------------------------------------------------------------
00177 |       AP4_Track::GetId
00178 +---------------------------------------------------------------------*/
00179 AP4_UI32
00180 AP4_Track::GetId()
00181 {
00182     return m_TrakAtom->GetId();
00183 }
00184 
00185 /*----------------------------------------------------------------------
00186 |       AP4_Track::SetId
00187 +---------------------------------------------------------------------*/
00188 AP4_Result
00189 AP4_Track::SetId(AP4_UI32 id)
00190 {
00191     m_TrakAtom->SetId(id);
00192 
00193     return AP4_SUCCESS;
00194 }
00195 
00196 /*----------------------------------------------------------------------
00197 |       AP4_Track::GetDuration
00198 +---------------------------------------------------------------------*/
00199 AP4_UI32
00200 AP4_Track::GetDuration()
00201 {
00202     return m_TrakAtom->GetDuration();
00203 }
00204 
00205 /*----------------------------------------------------------------------
00206 |       AP4_Track::GetDurationMs
00207 +---------------------------------------------------------------------*/
00208 AP4_Duration
00209 AP4_Track::GetDurationMs()
00210 {
00211     AP4_UI32 duration = m_TrakAtom->GetDuration();
00212     return AP4_DurationMsFromUnits(duration, m_MovieTimeScale);
00213 }
00214 
00215 /*----------------------------------------------------------------------
00216 |       AP4_Track::GetSampleCount
00217 +---------------------------------------------------------------------*/
00218 AP4_Cardinal
00219 AP4_Track::GetSampleCount()
00220 {
00221     // delegate to the sample table
00222     return m_SampleTable ? m_SampleTable->GetSampleCount() : 0;
00223 }
00224 
00225 /*----------------------------------------------------------------------
00226 |       AP4_Track::GetSample
00227 +---------------------------------------------------------------------*/
00228 AP4_Result 
00229 AP4_Track::GetSample(AP4_Ordinal index, AP4_Sample& sample)
00230 {
00231     // delegate to the sample table
00232     return m_SampleTable ? m_SampleTable->GetSample(index, sample) : AP4_FAILURE;
00233 }
00234 
00235 /*----------------------------------------------------------------------
00236 |       AP4_Track::GetSampleDescription
00237 +---------------------------------------------------------------------*/
00238 AP4_SampleDescription*
00239 AP4_Track::GetSampleDescription(AP4_Ordinal index)
00240 {
00241     // delegate to the sample table
00242     return m_SampleTable ? m_SampleTable->GetSampleDescription(index) : NULL;
00243 }
00244 
00245 /*----------------------------------------------------------------------
00246 |       AP4_Track::ReadSample
00247 +---------------------------------------------------------------------*/
00248 AP4_Result   
00249 AP4_Track::ReadSample(AP4_Ordinal     index, 
00250                       AP4_Sample&     sample,
00251                       AP4_DataBuffer& data)
00252 {
00253     AP4_Result result;
00254 
00255     // get the sample
00256     result = GetSample(index, sample);
00257     if (AP4_FAILED(result)) return result;
00258 
00259     // read the data
00260     return sample.ReadData(data);
00261 }
00262 
00263 /*----------------------------------------------------------------------
00264 |       AP4_Track::GetSampleIndexForTimeStampMs
00265 +---------------------------------------------------------------------*/
00266 AP4_Result  
00267 AP4_Track::GetSampleIndexForTimeStampMs(AP4_TimeStamp ts, AP4_Ordinal& index)
00268 {
00269     // convert the ts in the timescale of the track's media
00270     ts = AP4_ConvertTime(ts, 1000, m_MediaTimeScale);
00271 
00272     return m_SampleTable->GetSampleIndexForTimeStamp(ts, index);
00273 }
00274 
00275 /*----------------------------------------------------------------------
00276 |       AP4_Track::SetMovieTimeScale
00277 +---------------------------------------------------------------------*/
00278 AP4_Result
00279 AP4_Track::SetMovieTimeScale(AP4_UI32 time_scale)
00280 {
00281     // check that we can convert
00282     if (m_MovieTimeScale == 0) return AP4_FAILURE;
00283 
00284     // convert from one time scale to the other
00285     m_TrakAtom->SetDuration(AP4_ConvertTime(m_TrakAtom->GetDuration(), 
00286                                             m_MovieTimeScale,
00287                                             time_scale));
00288     
00289     // keep the new movie timescale
00290     m_MovieTimeScale = time_scale;
00291 
00292     return AP4_SUCCESS;
00293 }
00294 
00295 /*----------------------------------------------------------------------
00296 |       AP4_Track::GetMediaTimeScale
00297 +---------------------------------------------------------------------*/
00298 AP4_UI32
00299 AP4_Track::GetMediaTimeScale()
00300 {
00301     return m_MediaTimeScale;
00302 }
00303 
00304 // save the implementation for later
00305 #if 0 
00306 /*----------------------------------------------------------------------
00307 |       AP4_HintTrack::SetSdpText
00308 +---------------------------------------------------------------------*/
00309 void
00310 AP4_HintTrack::SetSdpText(const char* text)
00311 {
00312     // build an sdp atom
00313     AP4_SdpAtom* sdp = new AP4_SdpAtom(text);
00314 
00315     // build the hnti
00316     AP4_ContainerAtom* hnti = new AP4_ContainerAtom(AP4_ATOM_TYPE_HNTI);
00317     hnti->AddChild(sdp);
00318 
00319     // check if there's already a user data atom
00320     AP4_ContainerAtom* udta = dynamic_cast<AP4_ContainerAtom*>(m_TrakAtom->FindChild("udta"));
00321     if (udta == NULL) {
00322         // otherwise create it
00323         udta = new AP4_ContainerAtom(AP4_ATOM_TYPE_UDTA);
00324         m_TrakAtom->AddChild(udta);
00325     }
00326     udta->AddChild(hnti);
00327 }
00328 
00329 #endif
00330 
00331 /*----------------------------------------------------------------------
00332 |       AP4_Track::GetTrackName
00333 +---------------------------------------------------------------------*/
00334 
00335 AP4_String
00336 AP4_Track::GetTrackName()
00337 {
00338         AP4_String TrackName;
00339         if(AP4_HdlrAtom* hdlr = dynamic_cast<AP4_HdlrAtom*>(m_TrakAtom->FindChild("mdia/hdlr")))
00340                 TrackName = hdlr->GetHandlerName();
00341         return TrackName;
00342 }
00343 
00344 /*----------------------------------------------------------------------
00345 |       AP4_Track::GetTrackLanguage
00346 +---------------------------------------------------------------------*/
00347 
00348 AP4_String
00349 AP4_Track::GetTrackLanguage()
00350 {
00351         AP4_String TrackLanguage;
00352         if(AP4_MdhdAtom* mdhd = dynamic_cast<AP4_MdhdAtom*>(m_TrakAtom->FindChild("mdia/mdhd")))
00353                 TrackLanguage = mdhd->GetLanguage().c_str();
00354         return TrackLanguage;
00355 }

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