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 "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
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
00067 unsigned int volume = 0;
00068 if (type == TYPE_AUDIO) volume = 0x100;
00069
00070
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
00096 AP4_UI32 track_duration = AP4_ConvertTime(media_duration,
00097 media_time_scale,
00098 movie_time_scale);
00099
00100
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
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
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
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
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
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
00178
00179 AP4_UI32
00180 AP4_Track::GetId()
00181 {
00182 return m_TrakAtom->GetId();
00183 }
00184
00185
00186
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
00198
00199 AP4_UI32
00200 AP4_Track::GetDuration()
00201 {
00202 return m_TrakAtom->GetDuration();
00203 }
00204
00205
00206
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
00217
00218 AP4_Cardinal
00219 AP4_Track::GetSampleCount()
00220 {
00221
00222 return m_SampleTable ? m_SampleTable->GetSampleCount() : 0;
00223 }
00224
00225
00226
00227
00228 AP4_Result
00229 AP4_Track::GetSample(AP4_Ordinal index, AP4_Sample& sample)
00230 {
00231
00232 return m_SampleTable ? m_SampleTable->GetSample(index, sample) : AP4_FAILURE;
00233 }
00234
00235
00236
00237
00238 AP4_SampleDescription*
00239 AP4_Track::GetSampleDescription(AP4_Ordinal index)
00240 {
00241
00242 return m_SampleTable ? m_SampleTable->GetSampleDescription(index) : NULL;
00243 }
00244
00245
00246
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
00256 result = GetSample(index, sample);
00257 if (AP4_FAILED(result)) return result;
00258
00259
00260 return sample.ReadData(data);
00261 }
00262
00263
00264
00265
00266 AP4_Result
00267 AP4_Track::GetSampleIndexForTimeStampMs(AP4_TimeStamp ts, AP4_Ordinal& index)
00268 {
00269
00270 ts = AP4_ConvertTime(ts, 1000, m_MediaTimeScale);
00271
00272 return m_SampleTable->GetSampleIndexForTimeStamp(ts, index);
00273 }
00274
00275
00276
00277
00278 AP4_Result
00279 AP4_Track::SetMovieTimeScale(AP4_UI32 time_scale)
00280 {
00281
00282 if (m_MovieTimeScale == 0) return AP4_FAILURE;
00283
00284
00285 m_TrakAtom->SetDuration(AP4_ConvertTime(m_TrakAtom->GetDuration(),
00286 m_MovieTimeScale,
00287 time_scale));
00288
00289
00290 m_MovieTimeScale = time_scale;
00291
00292 return AP4_SUCCESS;
00293 }
00294
00295
00296
00297
00298 AP4_UI32
00299 AP4_Track::GetMediaTimeScale()
00300 {
00301 return m_MediaTimeScale;
00302 }
00303
00304
00305 #if 0
00306
00307
00308
00309 void
00310 AP4_HintTrack::SetSdpText(const char* text)
00311 {
00312
00313 AP4_SdpAtom* sdp = new AP4_SdpAtom(text);
00314
00315
00316 AP4_ContainerAtom* hnti = new AP4_ContainerAtom(AP4_ATOM_TYPE_HNTI);
00317 hnti->AddChild(sdp);
00318
00319
00320 AP4_ContainerAtom* udta = dynamic_cast<AP4_ContainerAtom*>(m_TrakAtom->FindChild("udta"));
00321 if (udta == NULL) {
00322
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
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
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 }