root/trunk/Source/C++/Core/Ap4SampleEntry.cpp

Revision 379, 36.8 kB (checked in by bok, 7 weeks ago)

Changed AP4_Size from unsigned long to AP4_UI32

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*****************************************************************
2|
3|    AP4 - sample entries
4|
5|    Copyright 2002-2008 Axiomatic Systems, LLC
6|
7|
8|    This file is part of Bento4/AP4 (MP4 Atom Processing Library).
9|
10|    Unless you have obtained Bento4 under a difference license,
11|    this version of Bento4 is Bento4|GPL.
12|    Bento4|GPL is free software; you can redistribute it and/or modify
13|    it under the terms of the GNU General Public License as published by
14|    the Free Software Foundation; either version 2, or (at your option)
15|    any later version.
16|
17|    Bento4|GPL is distributed in the hope that it will be useful,
18|    but WITHOUT ANY WARRANTY; without even the implied warranty of
19|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20|    GNU General Public License for more details.
21|
22|    You should have received a copy of the GNU General Public License
23|    along with Bento4|GPL; see the file COPYING.  If not, write to the
24|    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25|    02111-1307, USA.
26|
27 ****************************************************************/
28
29/*----------------------------------------------------------------------
30|   includes
31+---------------------------------------------------------------------*/
32#include "Ap4SampleEntry.h"
33#include "Ap4Utils.h"
34#include "Ap4AtomFactory.h"
35#include "Ap4TimsAtom.h"
36#include "Ap4SampleDescription.h"
37#include "Ap4AvccAtom.h"
38
39/*----------------------------------------------------------------------
40|   dynamic cast support
41+---------------------------------------------------------------------*/
42AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_SampleEntry)
43
44/*----------------------------------------------------------------------
45|   AP4_SampleEntry::AP4_SampleEntry
46+---------------------------------------------------------------------*/
47AP4_SampleEntry::AP4_SampleEntry(AP4_Atom::Type format,
48                                 AP4_UI16       data_reference_index) :
49    AP4_ContainerAtom(format),
50    m_DataReferenceIndex(data_reference_index)
51{
52    m_Reserved1[0] = 0;
53    m_Reserved1[1] = 0;
54    m_Reserved1[2] = 0;
55    m_Reserved1[3] = 0;
56    m_Reserved1[4] = 0;
57    m_Reserved1[5] = 0;
58    m_Size32 += 8;
59}
60
61/*----------------------------------------------------------------------
62|   AP4_SampleEntry::AP4_SampleEntry
63+---------------------------------------------------------------------*/
64AP4_SampleEntry::AP4_SampleEntry(AP4_Atom::Type format,
65                                 AP4_Size       size) :
66    AP4_ContainerAtom(format, (AP4_UI64)size, false)
67{
68}
69
70/*----------------------------------------------------------------------
71|   AP4_SampleEntry::AP4_SampleEntry
72+---------------------------------------------------------------------*/
73AP4_SampleEntry::AP4_SampleEntry(AP4_Atom::Type   format,
74                                 AP4_Size         size,
75                                 AP4_ByteStream&  stream,
76                                 AP4_AtomFactory& atom_factory) :
77    AP4_ContainerAtom(format, (AP4_UI64)size, false)
78{
79    Read(stream, atom_factory);
80}
81
82/*----------------------------------------------------------------------
83|   AP4_SampleEntry::Read
84+---------------------------------------------------------------------*/
85void
86AP4_SampleEntry::Read(AP4_ByteStream& stream, AP4_AtomFactory& atom_factory)
87{
88    // read the fields before the children atoms
89    ReadFields(stream);
90
91    // read children atoms (ex: esds and maybe others)
92    // NOTE: not all sample entries have children atoms
93    AP4_Size payload_size = (AP4_Size)(GetSize()-GetHeaderSize());
94    AP4_Size fields_size = GetFieldsSize();
95    if (payload_size > fields_size) {
96        ReadChildren(atom_factory, stream, payload_size-fields_size);
97    }
98}
99
100/*----------------------------------------------------------------------
101|   AP4_SampleEntry::GetFieldsSize
102+---------------------------------------------------------------------*/
103AP4_Size
104AP4_SampleEntry::GetFieldsSize()
105{
106    return 8;
107}
108
109/*----------------------------------------------------------------------
110|   AP4_SampleEntry::ReadFields
111+---------------------------------------------------------------------*/
112AP4_Result
113AP4_SampleEntry::ReadFields(AP4_ByteStream& stream)
114{
115    stream.Read(m_Reserved1, sizeof(m_Reserved1));
116    stream.ReadUI16(m_DataReferenceIndex);
117
118    return AP4_SUCCESS;
119}
120
121/*----------------------------------------------------------------------
122|   AP4_SampleEntry::WriteFields
123+---------------------------------------------------------------------*/
124AP4_Result
125AP4_SampleEntry::WriteFields(AP4_ByteStream& stream)
126{
127    AP4_Result result;
128   
129    // reserved1
130    result = stream.Write(m_Reserved1, sizeof(m_Reserved1));
131    if (AP4_FAILED(result)) return result;
132
133    // data reference index
134    result = stream.WriteUI16(m_DataReferenceIndex);
135    if (AP4_FAILED(result)) return result;
136   
137    return result;
138}
139
140/*----------------------------------------------------------------------
141|   AP4_SampleEntry::Write
142+---------------------------------------------------------------------*/
143AP4_Result
144AP4_SampleEntry::Write(AP4_ByteStream& stream)
145{
146    AP4_Result result;
147
148    // write the header
149    result = WriteHeader(stream);
150    if (AP4_FAILED(result)) return result;
151
152    // write the fields
153    result = WriteFields(stream);
154    if (AP4_FAILED(result)) return result;
155
156    // write the children atoms
157    return m_Children.Apply(AP4_AtomListWriter(stream));
158}
159
160/*----------------------------------------------------------------------
161|   AP4_SampleEntry::InspectFields
162+---------------------------------------------------------------------*/
163AP4_Result
164AP4_SampleEntry::InspectFields(AP4_AtomInspector& inspector)
165{
166    inspector.AddField("data_reference_index", m_DataReferenceIndex);
167
168    return AP4_SUCCESS;
169}
170
171/*----------------------------------------------------------------------
172|   AP4_SampleEntry::Inspect
173+---------------------------------------------------------------------*/
174AP4_Result
175AP4_SampleEntry::Inspect(AP4_AtomInspector& inspector)
176{
177    // inspect the header
178    InspectHeader(inspector);
179
180    // inspect the fields
181    InspectFields(inspector);
182
183    // inspect children
184    m_Children.Apply(AP4_AtomListInspector(inspector));
185
186    // finish
187    inspector.EndElement();
188
189    return AP4_SUCCESS;
190}
191
192/*----------------------------------------------------------------------
193|   AP4_SampleEntry::OnChildChanged
194+---------------------------------------------------------------------*/
195void
196AP4_SampleEntry::OnChildChanged(AP4_Atom*)
197{
198    // recompute our size
199    AP4_UI64 size = GetHeaderSize()+GetFieldsSize();
200    m_Children.Apply(AP4_AtomSizeAdder(size));
201    m_Size32 = (AP4_UI32)size;
202
203    // update our parent
204    if (m_Parent) m_Parent->OnChildChanged(this);
205}
206
207/*----------------------------------------------------------------------
208|   AP4_SampleEntry::ToSampleDescription
209+---------------------------------------------------------------------*/
210AP4_SampleDescription*
211AP4_SampleEntry::ToSampleDescription()
212{
213    return new AP4_SampleDescription(AP4_SampleDescription::TYPE_UNKNOWN, m_Type, this);
214}
215
216/*----------------------------------------------------------------------
217|   AP4_UnknownSampleEntry::AP4_UnknownSampleEntry
218+---------------------------------------------------------------------*/
219AP4_UnknownSampleEntry::AP4_UnknownSampleEntry(AP4_Atom::Type  type, 
220                                               AP4_Size        size, 
221                                               AP4_ByteStream& stream) :
222    AP4_SampleEntry(type, size)
223{
224    if (size > AP4_ATOM_HEADER_SIZE+AP4_SampleEntry::GetFieldsSize()) {
225        m_Payload.SetDataSize(size-(AP4_ATOM_HEADER_SIZE+AP4_SampleEntry::GetFieldsSize()));
226        ReadFields(stream);
227    }
228}
229
230/*----------------------------------------------------------------------
231|   AP4_UnknownSampleEntry::ToSampleDescription
232+---------------------------------------------------------------------*/
233AP4_SampleDescription* 
234AP4_UnknownSampleEntry::ToSampleDescription()
235{
236    return new AP4_UnknownSampleDescription(this);
237}
238
239/*----------------------------------------------------------------------
240|   AP4_UnknownSampleEntry::GetFieldsSize
241+---------------------------------------------------------------------*/
242AP4_Size   
243AP4_UnknownSampleEntry::GetFieldsSize()
244{
245    return AP4_SampleEntry::GetFieldsSize()+m_Payload.GetDataSize();
246}
247
248/*----------------------------------------------------------------------
249|   AP4_UnknownSampleEntry::ReadFields
250+---------------------------------------------------------------------*/
251AP4_Result
252AP4_UnknownSampleEntry::ReadFields(AP4_ByteStream& stream)
253{
254    // sample entry
255    AP4_Result result = AP4_SampleEntry::ReadFields(stream);
256    if (AP4_FAILED(result)) return result;
257   
258    // read the payload
259    return stream.Read(m_Payload.UseData(), m_Payload.GetDataSize());
260}
261
262/*----------------------------------------------------------------------
263|   AP4_UnknownSampleEntry::WriteFields
264+---------------------------------------------------------------------*/
265AP4_Result
266AP4_UnknownSampleEntry::WriteFields(AP4_ByteStream& stream)
267{
268    AP4_Result result;
269   
270    // write the fields of the base class
271    result = AP4_SampleEntry::WriteFields(stream);
272    if (AP4_FAILED(result)) return result;
273   
274    // write the payload
275    return stream.Write(m_Payload.GetData(), m_Payload.GetDataSize());
276}
277
278/*----------------------------------------------------------------------
279|   AP4_MpegSystemSampleEntry::AP4_MpegSystemSampleEntry
280+---------------------------------------------------------------------*/
281AP4_MpegSystemSampleEntry::AP4_MpegSystemSampleEntry(
282    AP4_UI32          type,
283    AP4_EsDescriptor* descriptor) :
284    AP4_SampleEntry(type)
285{
286    if (descriptor) AddChild(new AP4_EsdsAtom(descriptor));
287}
288
289/*----------------------------------------------------------------------
290|   AP4_MpegSystemSampleEntry::AP4_MpegSystemSampleEntry
291+---------------------------------------------------------------------*/
292AP4_MpegSystemSampleEntry::AP4_MpegSystemSampleEntry(
293    AP4_UI32         type,
294    AP4_Size         size,
295    AP4_ByteStream&  stream,
296    AP4_AtomFactory& atom_factory) :
297    AP4_SampleEntry(type, size, stream, atom_factory)
298{
299}
300
301/*----------------------------------------------------------------------
302|   AP4_MpegSystemSampleEntry::ToSampleDescription
303+---------------------------------------------------------------------*/
304AP4_SampleDescription*
305AP4_MpegSystemSampleEntry::ToSampleDescription()
306{
307    return new AP4_MpegSystemSampleDescription(
308        AP4_DYNAMIC_CAST(AP4_EsdsAtom, GetChild(AP4_ATOM_TYPE_ESDS)));
309}
310
311/*----------------------------------------------------------------------
312|   AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry
313+---------------------------------------------------------------------*/
314AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry(AP4_EsDescriptor* descriptor) :
315    AP4_MpegSystemSampleEntry(AP4_ATOM_TYPE_MP4S, descriptor)
316{
317}
318
319/*----------------------------------------------------------------------
320|   AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry
321+---------------------------------------------------------------------*/
322AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry(AP4_Size         size,
323                                         AP4_ByteStream&  stream,
324                                         AP4_AtomFactory& atom_factory) :
325    AP4_MpegSystemSampleEntry(AP4_ATOM_TYPE_MP4S, size, stream, atom_factory)
326{
327}
328
329/*----------------------------------------------------------------------
330|   AP4_Mp4sSampleEntry::ToSampleDescription
331+---------------------------------------------------------------------*/
332AP4_SampleDescription*
333AP4_Mp4sSampleEntry::ToSampleDescription()
334{
335    // create a sample description
336    return new AP4_MpegSystemSampleDescription(
337        AP4_DYNAMIC_CAST(AP4_EsdsAtom, GetChild(AP4_ATOM_TYPE_ESDS)));
338}
339
340/*----------------------------------------------------------------------
341|   AP4_AudioSampleEntry::AP4_AudioSampleEntry
342+---------------------------------------------------------------------*/
343AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type format,
344                                           AP4_UI32       sample_rate,
345                                           AP4_UI16       sample_size,
346                                           AP4_UI16       channel_count) :
347    AP4_SampleEntry(format),
348    m_QtVersion(0),
349    m_QtRevision(0),
350    m_QtVendor(0),
351    m_ChannelCount(channel_count),
352    m_SampleSize(sample_size),
353    m_QtCompressionId(0),
354    m_QtPacketSize(0),
355    m_SampleRate(sample_rate),
356    m_QtV1SamplesPerPacket(0),
357    m_QtV1BytesPerPacket(0),
358    m_QtV1BytesPerFrame(0),
359    m_QtV1BytesPerSample(0),
360    m_QtV2StructSize(0),
361    m_QtV2SampleRate64(0.0),
362    m_QtV2ChannelCount(0),
363    m_QtV2Reserved(0),
364    m_QtV2BitsPerChannel(0),
365    m_QtV2FormatSpecificFlags(0),
366    m_QtV2BytesPerAudioPacket(0),
367    m_QtV2LPCMFramesPerAudioPacket(0)   
368{
369    m_Size32 += 20;
370}
371
372/*----------------------------------------------------------------------
373|   AP4_AudioSampleEntry::AP4_AudioSampleEntry
374+---------------------------------------------------------------------*/
375AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type   format,
376                                           AP4_Size         size,
377                                           AP4_ByteStream&  stream,
378                                           AP4_AtomFactory& atom_factory) :
379    AP4_SampleEntry(format, size)
380{
381    Read(stream, atom_factory);
382}
383   
384/*----------------------------------------------------------------------
385|   AP4_AudioSampleEntry::GetFieldsSize
386+---------------------------------------------------------------------*/
387AP4_Size
388AP4_AudioSampleEntry::GetFieldsSize()
389{
390    AP4_Size size = AP4_SampleEntry::GetFieldsSize()+20;
391    if (m_QtVersion == 1) {
392        size += 16;
393    } else if (m_QtVersion == 2) {
394        size += 36+m_QtV2Extension.GetDataSize();
395    }
396   
397    return size;
398}
399
400/*----------------------------------------------------------------------
401|   AP4_AudioSampleEntry::GetSampleRate
402+---------------------------------------------------------------------*/
403AP4_UI32
404AP4_AudioSampleEntry::GetSampleRate()
405{
406    if (m_QtVersion == 2) {
407        return (AP4_UI32)(m_QtV2SampleRate64);
408    } else {
409        return m_SampleRate>>16;
410    }
411}
412
413/*----------------------------------------------------------------------
414|   AP4_AudioSampleEntry::GetChannelCount
415+---------------------------------------------------------------------*/
416AP4_UI16
417AP4_AudioSampleEntry::GetChannelCount()
418{
419    if (m_QtVersion == 2) {
420        return m_QtV2ChannelCount;
421    } else {
422        return m_ChannelCount;
423    }
424}
425
426/*----------------------------------------------------------------------
427|   AP4_AudioSampleEntry::ReadFields
428+---------------------------------------------------------------------*/
429AP4_Result
430AP4_AudioSampleEntry::ReadFields(AP4_ByteStream& stream)
431{
432    // sample entry
433    AP4_Result result = AP4_SampleEntry::ReadFields(stream);
434    if (result < 0) return result;
435
436    // read the fields of this class
437    stream.ReadUI16(m_QtVersion);
438    stream.ReadUI16(m_QtRevision);
439    stream.ReadUI32(m_QtVendor);
440    stream.ReadUI16(m_ChannelCount);
441    stream.ReadUI16(m_SampleSize);
442    stream.ReadUI16(m_QtCompressionId);
443    stream.ReadUI16(m_QtPacketSize);
444    stream.ReadUI32(m_SampleRate);
445
446    // if this is a QT V1 entry, read the extension
447    if (m_QtVersion == 1) {
448        stream.ReadUI32(m_QtV1SamplesPerPacket);
449        stream.ReadUI32(m_QtV1BytesPerPacket);
450        stream.ReadUI32(m_QtV1BytesPerFrame);
451        stream.ReadUI32(m_QtV1BytesPerSample);
452    } else if (m_QtVersion == 2) {
453        stream.ReadUI32(m_QtV2StructSize);
454        stream.ReadDouble(m_QtV2SampleRate64);
455        stream.ReadUI32(m_QtV2ChannelCount);
456        stream.ReadUI32(m_QtV2Reserved);
457        stream.ReadUI32(m_QtV2BitsPerChannel);
458        stream.ReadUI32(m_QtV2FormatSpecificFlags);
459        stream.ReadUI32(m_QtV2BytesPerAudioPacket);
460        stream.ReadUI32(m_QtV2LPCMFramesPerAudioPacket);
461        if (m_QtV2StructSize > 72) {
462            unsigned int ext_size = m_QtV2StructSize-72;
463            m_QtV2Extension.SetDataSize(ext_size);
464            stream.Read(m_QtV2Extension.UseData(), ext_size);
465        }
466        m_QtV1SamplesPerPacket =
467        m_QtV1BytesPerPacket   =
468        m_QtV1BytesPerFrame    =
469        m_QtV1BytesPerSample   = 0;
470    } else {
471        m_QtV1SamplesPerPacket         = 0;
472        m_QtV1BytesPerPacket           = 0;
473        m_QtV1BytesPerFrame            = 0;
474        m_QtV1BytesPerSample           = 0;
475        m_QtV2StructSize               = 0;
476        m_QtV2SampleRate64             = 0.0;
477        m_QtV2ChannelCount             = 0;
478        m_QtV2Reserved                 = 0;
479        m_QtV2BitsPerChannel           = 0;
480        m_QtV2FormatSpecificFlags      = 0;
481        m_QtV2BytesPerAudioPacket      = 0;
482        m_QtV2LPCMFramesPerAudioPacket = 0;
483    }
484   
485    return AP4_SUCCESS;
486}
487
488/*----------------------------------------------------------------------
489|   AP4_AudioSampleEntry::WriteFields
490+---------------------------------------------------------------------*/
491AP4_Result
492AP4_AudioSampleEntry::WriteFields(AP4_ByteStream& stream)
493{
494    AP4_Result result;
495   
496    // write the fields of the base class
497    result = AP4_SampleEntry::WriteFields(stream);
498
499    // QT version
500    result = stream.WriteUI16(m_QtVersion);
501    if (AP4_FAILED(result)) return result;
502
503    // QT revision
504    result = stream.WriteUI16(m_QtRevision);
505    if (AP4_FAILED(result)) return result;
506
507    // QT vendor
508    result = stream.WriteUI32(m_QtVendor);
509    if (AP4_FAILED(result)) return result;
510
511    // channel count
512    result = stream.WriteUI16(m_ChannelCount);
513    if (AP4_FAILED(result)) return result;
514   
515    // sample size
516    result = stream.WriteUI16(m_SampleSize);
517    if (AP4_FAILED(result)) return result;
518
519    // QT compression ID
520    result = stream.WriteUI16(m_QtCompressionId);
521    if (AP4_FAILED(result)) return result;
522
523    // QT packet size
524    result = stream.WriteUI16(m_QtPacketSize);
525    if (AP4_FAILED(result)) return result;
526
527    // sample rate
528    result = stream.WriteUI32(m_SampleRate);
529    if (AP4_FAILED(result)) return result;
530
531    if (m_QtVersion == 1) {
532        result = stream.WriteUI32(m_QtV1SamplesPerPacket);
533        if (AP4_FAILED(result)) return result;
534        result = stream.WriteUI32(m_QtV1BytesPerPacket);
535        if (AP4_FAILED(result)) return result;
536        result = stream.WriteUI32(m_QtV1BytesPerFrame);
537        if (AP4_FAILED(result)) return result;
538        result = stream.WriteUI32(m_QtV1BytesPerSample);
539        if (AP4_FAILED(result)) return result;
540    } else if (m_QtVersion == 2) {
541        stream.WriteUI32(m_QtV2StructSize);
542        stream.WriteDouble(m_QtV2SampleRate64);
543        stream.WriteUI32(m_QtV2ChannelCount);
544        stream.WriteUI32(m_QtV2Reserved);
545        stream.WriteUI32(m_QtV2BitsPerChannel);
546        stream.WriteUI32(m_QtV2FormatSpecificFlags);
547        stream.WriteUI32(m_QtV2BytesPerAudioPacket);
548        stream.WriteUI32(m_QtV2LPCMFramesPerAudioPacket);
549        if (m_QtV2Extension.GetDataSize()) {
550            stream.Write(m_QtV2Extension.GetData(),
551                         m_QtV2Extension.GetDataSize());
552        }
553    }
554   
555    return result;
556}
557
558/*----------------------------------------------------------------------
559|   AP4_AudioSampleEntry::InspectFields
560+---------------------------------------------------------------------*/
561AP4_Result
562AP4_AudioSampleEntry::InspectFields(AP4_AtomInspector& inspector)
563{
564    // dump the fields from the base class
565    AP4_SampleEntry::InspectFields(inspector);
566
567    // fields
568    inspector.AddField("channel_count", GetChannelCount());
569    inspector.AddField("sample_size", GetSampleSize());
570    inspector.AddField("sample_rate", GetSampleRate());
571    if (m_QtVersion) {
572        inspector.AddField("qt_version", m_QtVersion);
573    }
574   
575    return AP4_SUCCESS;
576}
577
578/*----------------------------------------------------------------------
579|   AP4_AudioSampleEntry::ToSampleDescription
580+---------------------------------------------------------------------*/
581AP4_SampleDescription*
582AP4_AudioSampleEntry::ToSampleDescription()
583{
584    // create a sample description
585    return new AP4_GenericAudioSampleDescription(
586        m_Type,
587        GetSampleRate(),
588        GetSampleSize(),
589        GetChannelCount(),
590        this);
591}
592
593/*----------------------------------------------------------------------
594|   AP4_MpegAudioSampleEntry::AP4_MpegAudioSampleEntry
595+---------------------------------------------------------------------*/
596AP4_MpegAudioSampleEntry::AP4_MpegAudioSampleEntry(
597    AP4_UI32          type,
598    AP4_UI32          sample_rate, 
599    AP4_UI16          sample_size,
600    AP4_UI16          channel_count,
601    AP4_EsDescriptor* descriptor) :
602    AP4_AudioSampleEntry(type, sample_rate, sample_size, channel_count)
603{
604    if (descriptor) AddChild(new AP4_EsdsAtom(descriptor));
605}
606
607/*----------------------------------------------------------------------
608|   AP4_MpegAudioSampleEntry::AP4_MpegAudioSampleEntry
609+---------------------------------------------------------------------*/
610AP4_MpegAudioSampleEntry::AP4_MpegAudioSampleEntry(
611    AP4_UI32         type,
612    AP4_Size         size,
613    AP4_ByteStream&  stream,
614    AP4_AtomFactory& atom_factory) :
615    AP4_AudioSampleEntry(type, size, stream, atom_factory)
616{
617}
618
619/*----------------------------------------------------------------------
620|   AP4_MpegAudioSampleEntry::ToSampleDescription
621+---------------------------------------------------------------------*/
622AP4_SampleDescription*
623AP4_MpegAudioSampleEntry::ToSampleDescription()
624{
625    // find the esds atom
626    AP4_EsdsAtom* esds = AP4_DYNAMIC_CAST(AP4_EsdsAtom, GetChild(AP4_ATOM_TYPE_ESDS));
627    if (esds == NULL) {
628        // check if this is a quicktime style sample description
629        if (m_QtVersion > 0) {
630            esds = AP4_DYNAMIC_CAST(AP4_EsdsAtom, FindChild("wave/esds"));
631        }
632    }
633   
634    // create a sample description
635    return new AP4_MpegAudioSampleDescription(GetSampleRate(),
636                                              GetSampleSize(),
637                                              GetChannelCount(),
638                                              esds);
639}
640
641/*----------------------------------------------------------------------
642|   AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry
643+---------------------------------------------------------------------*/
644AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry(AP4_UI32          sample_rate, 
645                                         AP4_UI16          sample_size,
646                                         AP4_UI16          channel_count,
647                                         AP4_EsDescriptor* descriptor) :
648    AP4_MpegAudioSampleEntry(AP4_ATOM_TYPE_MP4A, 
649                             sample_rate, 
650                             sample_size, 
651                             channel_count,
652                             descriptor)
653{
654}
655
656/*----------------------------------------------------------------------
657|   AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry
658+---------------------------------------------------------------------*/
659AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry(AP4_Size         size,
660                                         AP4_ByteStream&  stream,
661                                         AP4_AtomFactory& atom_factory) :
662    AP4_MpegAudioSampleEntry(AP4_ATOM_TYPE_MP4A, size, stream, atom_factory)
663{
664}
665
666/*----------------------------------------------------------------------
667|   AP4_VisualSampleEntry::AP4_VisualSampleEntry
668+---------------------------------------------------------------------*/
669AP4_VisualSampleEntry::AP4_VisualSampleEntry(
670    AP4_Atom::Type    format, 
671    AP4_UI16          width,
672    AP4_UI16          height,
673    AP4_UI16          depth,
674    const char*       compressor_name) :
675    AP4_SampleEntry(format),
676    m_Predefined1(0),
677    m_Reserved2(0),
678    m_Width(width),
679    m_Height(height),
680    m_HorizResolution(0x00480000),
681    m_VertResolution(0x00480000),
682    m_Reserved3(0),
683    m_FrameCount(1),
684    m_CompressorName(compressor_name),
685    m_Depth(depth),
686    m_Predefined3(0xFFFF)
687{
688    memset(m_Predefined2, 0, sizeof(m_Predefined2));
689    m_Size32 += 70;
690}
691
692/*----------------------------------------------------------------------
693|   AP4_VisualSampleEntry::AP4_VisualSampleEntry
694+---------------------------------------------------------------------*/
695AP4_VisualSampleEntry::AP4_VisualSampleEntry(AP4_Atom::Type   format,
696                                             AP4_Size         size, 
697                                             AP4_ByteStream&  stream,
698                                             AP4_AtomFactory& atom_factory) :
699    AP4_SampleEntry(format, size)
700{
701    Read(stream, atom_factory);
702}
703
704/*----------------------------------------------------------------------
705|   AP4_VisualSampleEntry::GetFieldsSize
706+---------------------------------------------------------------------*/
707AP4_Size
708AP4_VisualSampleEntry::GetFieldsSize()
709{
710    return AP4_SampleEntry::GetFieldsSize()+70;
711}
712
713/*----------------------------------------------------------------------
714|   AP4_VisualSampleEntry::ReadFields
715+---------------------------------------------------------------------*/
716AP4_Result
717AP4_VisualSampleEntry::ReadFields(AP4_ByteStream& stream)
718{
719    // sample entry
720    AP4_Result result = AP4_SampleEntry::ReadFields(stream);
721    if (result < 0) return result;
722
723    // read fields from this class
724    stream.ReadUI16(m_Predefined1);
725    stream.ReadUI16(m_Reserved2);
726    stream.Read(m_Predefined2, sizeof(m_Predefined2));
727    stream.ReadUI16(m_Width);
728    stream.ReadUI16(m_Height);
729    stream.ReadUI32(m_HorizResolution);
730    stream.ReadUI32(m_VertResolution);
731    stream.ReadUI32(m_Reserved3);
732    stream.ReadUI16(m_FrameCount);
733
734    char compressor_name[33];
735    stream.Read(compressor_name, 32);
736    int name_length = compressor_name[0];
737    if (name_length < 32) {
738        compressor_name[name_length+1] = 0; // force null termination
739        m_CompressorName = &compressor_name[1];
740    }
741
742    stream.ReadUI16(m_Depth);
743    stream.ReadUI16(m_Predefined3);
744
745    return AP4_SUCCESS;
746}
747
748/*----------------------------------------------------------------------
749|   AP4_VisualSampleEntry::WriteFields
750+---------------------------------------------------------------------*/
751AP4_Result
752AP4_VisualSampleEntry::WriteFields(AP4_ByteStream& stream)
753{
754    AP4_Result result;
755       
756    // write the fields of the base class
757    result = AP4_SampleEntry::WriteFields(stream);
758    if (AP4_FAILED(result)) return result;
759
760    // predefined1
761    result = stream.WriteUI16(m_Predefined1);
762    if (AP4_FAILED(result)) return result;
763   
764    // reserved2
765    result = stream.WriteUI16(m_Reserved2);
766    if (AP4_FAILED(result)) return result;
767   
768    // predefined2
769    result = stream.Write(m_Predefined2, sizeof(m_Predefined2));
770    if (AP4_FAILED(result)) return result;
771   
772    // width
773    result = stream.WriteUI16(m_Width);
774    if (AP4_FAILED(result)) return result;
775   
776    // height
777    result = stream.WriteUI16(m_Height);
778    if (AP4_FAILED(result)) return result;
779   
780    // horizontal resolution
781    result = stream.WriteUI32(m_HorizResolution);
782    if (AP4_FAILED(result)) return result;
783   
784    // vertical resolution
785    result = stream.WriteUI32(m_VertResolution);
786    if (AP4_FAILED(result)) return result;
787   
788    // reserved3
789    result = stream.WriteUI32(m_Reserved3);
790    if (AP4_FAILED(result)) return result;
791   
792    // frame count
793    result = stream.WriteUI16(m_FrameCount);
794    if (AP4_FAILED(result)) return result;
795   
796    // compressor name
797    unsigned char compressor_name[32];
798    unsigned int name_length = m_CompressorName.GetLength();
799    if (name_length > 31) name_length = 31;
800    compressor_name[0] = name_length;
801    for (unsigned int i=0; i<name_length; i++) {
802        compressor_name[i+1] = m_CompressorName[i];
803    }
804    for (unsigned int i=name_length+1; i<32; i++) {
805        compressor_name[i] = 0;
806    }
807    result = stream.Write(compressor_name, 32);
808    if (AP4_FAILED(result)) return result;
809   
810    // depth
811    result = stream.WriteUI16(m_Depth);
812    if (AP4_FAILED(result)) return result;
813   
814    // predefined3
815    result = stream.WriteUI16(m_Predefined3);
816    if (AP4_FAILED(result)) return result;
817   
818    return result;
819}
820
821/*----------------------------------------------------------------------
822|   AP4_VisualSampleEntry::InspectFields
823+---------------------------------------------------------------------*/
824AP4_Result
825AP4_VisualSampleEntry::InspectFields(AP4_AtomInspector& inspector)
826{
827    // dump the fields of the base class
828    AP4_SampleEntry::InspectFields(inspector);
829
830    // fields
831    inspector.AddField("width", m_Width);
832    inspector.AddField("height", m_Height);
833    inspector.AddField("compressor", m_CompressorName.GetChars());
834
835    return AP4_SUCCESS;
836}
837
838/*----------------------------------------------------------------------
839|   AP4_VisualSampleEntry::ToSampleDescription
840+---------------------------------------------------------------------*/
841AP4_SampleDescription*
842AP4_VisualSampleEntry::ToSampleDescription()
843{
844    // create a sample description
845    return new AP4_GenericVideoSampleDescription(
846        m_Type,
847        m_Width,
848        m_Height,
849        m_Depth,
850        m_CompressorName.GetChars(),
851        this);
852}
853
854/*----------------------------------------------------------------------
855|   AP4_MpegVideoSampleEntry::AP4_MpegVideoSampleEntry
856+---------------------------------------------------------------------*/
857AP4_MpegVideoSampleEntry::AP4_MpegVideoSampleEntry(
858    AP4_UI32          type,
859    AP4_UI16          width,
860    AP4_UI16          height,
861    AP4_UI16          depth,
862    const char*       compressor_name,
863    AP4_EsDescriptor* descriptor) :
864    AP4_VisualSampleEntry(type, 
865                          width, 
866                          height, 
867                          depth, 
868                          compressor_name)
869{
870    if (descriptor) AddChild(new AP4_EsdsAtom(descriptor));
871}
872
873/*----------------------------------------------------------------------
874|   AP4_MpegVideoSampleEntry::AP4_MpegVideoSampleEntry
875+---------------------------------------------------------------------*/
876AP4_MpegVideoSampleEntry::AP4_MpegVideoSampleEntry(
877    AP4_UI32         type,
878    AP4_Size         size,
879    AP4_ByteStream&  stream,
880    AP4_AtomFactory& atom_factory) :
881    AP4_VisualSampleEntry(type, size, stream, atom_factory)
882{
883}
884
885/*----------------------------------------------------------------------
886|   AP4_MpegVideoSampleEntry::ToSampleDescription
887+---------------------------------------------------------------------*/
888AP4_SampleDescription*
889AP4_MpegVideoSampleEntry::ToSampleDescription()
890{
891    // create a sample description
892    return new AP4_MpegVideoSampleDescription(
893        m_Width,
894        m_Height,
895        m_Depth,
896        m_CompressorName.GetChars(),
897        AP4_DYNAMIC_CAST(AP4_EsdsAtom, GetChild(AP4_ATOM_TYPE_ESDS)));
898}
899
900/*----------------------------------------------------------------------
901|   AP4_Mp4vSampleEntry::AP4_Mp4vSampleEntry
902+---------------------------------------------------------------------*/
903AP4_Mp4vSampleEntry::AP4_Mp4vSampleEntry(AP4_UI16          width,
904                                         AP4_UI16          height,
905                                         AP4_UI16          depth,
906                                         const char*       compressor_name,
907                                         AP4_EsDescriptor* descriptor) :
908    AP4_MpegVideoSampleEntry(AP4_ATOM_TYPE_MP4V, 
909                             width, 
910                             height, 
911                             depth, 
912                             compressor_name,
913                             descriptor)
914{
915}
916
917/*----------------------------------------------------------------------
918|   AP4_Mp4vSampleEntry::AP4_Mp4aSampleEntry
919+---------------------------------------------------------------------*/
920AP4_Mp4vSampleEntry::AP4_Mp4vSampleEntry(AP4_Size         size,
921                                         AP4_ByteStream&  stream,
922                                         AP4_AtomFactory& atom_factory) :
923    AP4_MpegVideoSampleEntry(AP4_ATOM_TYPE_MP4V, size, stream, atom_factory)
924{
925}
926
927/*----------------------------------------------------------------------
928|   AP4_Avc1SampleEntry::AP4_Avc1SampleEntry
929+---------------------------------------------------------------------*/
930AP4_Avc1SampleEntry::AP4_Avc1SampleEntry(AP4_UI16             width,
931                                         AP4_UI16             height,
932                                         AP4_UI16             depth,
933                                         const char*          compressor_name,
934                                         const AP4_AvccAtom&  avcc) :
935    AP4_VisualSampleEntry(AP4_ATOM_TYPE_AVC1, 
936                          width, 
937                          height, 
938                          depth, 
939                          compressor_name)
940{
941    AddChild(new AP4_AvccAtom(avcc));   
942}
943
944/*----------------------------------------------------------------------
945|   AP4_Avc1SampleEntry::AP4_Avc1SampleEntry
946+---------------------------------------------------------------------*/
947AP4_Avc1SampleEntry::AP4_Avc1SampleEntry(AP4_Size         size,
948                                         AP4_ByteStream&  stream,
949                                         AP4_AtomFactory& atom_factory) :
950    AP4_VisualSampleEntry(AP4_ATOM_TYPE_AVC1, size, stream, atom_factory)
951{
952}
953
954/*----------------------------------------------------------------------
955|   AP4_Avc1SampleEntry::ToSampleDescription
956+---------------------------------------------------------------------*/
957AP4_SampleDescription*
958AP4_Avc1SampleEntry::ToSampleDescription()
959{
960    return new AP4_AvcSampleDescription(
961        m_Width,
962        m_Height,
963        m_Depth,
964        m_CompressorName.GetChars(),
965        AP4_DYNAMIC_CAST(AP4_AvccAtom, GetChild(AP4_ATOM_TYPE_AVCC)));
966}
967
968/*----------------------------------------------------------------------
969|   AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry
970+---------------------------------------------------------------------*/
971AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry(AP4_UI16 hint_track_version,
972                                               AP4_UI16 highest_compatible_version,
973                                               AP4_UI32 max_packet_size,
974                                               AP4_UI32 timescale):
975    AP4_SampleEntry(AP4_ATOM_TYPE_RTP_),
976    m_HintTrackVersion(hint_track_version),
977    m_HighestCompatibleVersion(highest_compatible_version),
978    m_MaxPacketSize(max_packet_size)
979{
980    // build an atom for timescale
981    AddChild(new AP4_TimsAtom(timescale));
982}
983
984/*----------------------------------------------------------------------
985|   AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry
986+---------------------------------------------------------------------*/
987AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry(AP4_Size         size,
988                                               AP4_ByteStream&  stream,
989                                               AP4_AtomFactory& atom_factory): 
990    AP4_SampleEntry(AP4_ATOM_TYPE_RTP_, size)
991{
992    Read(stream, atom_factory);
993}
994
995/*----------------------------------------------------------------------
996|   AP4_RtpHintSampleEntry::GetFieldsSize
997+---------------------------------------------------------------------*/
998AP4_Size
999AP4_RtpHintSampleEntry::GetFieldsSize()
1000{
1001    return AP4_SampleEntry::GetFieldsSize()+8;
1002}
1003
1004/*----------------------------------------------------------------------
1005|   AP4_RtpHintSampleEntry::ReadFields
1006+---------------------------------------------------------------------*/
1007AP4_Result
1008AP4_RtpHintSampleEntry::ReadFields(AP4_ByteStream& stream)
1009{
1010    // sample entry
1011    AP4_Result result = AP4_SampleEntry::ReadFields(stream);
1012    if (result < 0) return result;
1013
1014    // data
1015    result = stream.ReadUI16(m_HintTrackVersion);
1016    if (AP4_FAILED(result)) return result;
1017    result = stream.ReadUI16(m_HighestCompatibleVersion);
1018    if (AP4_FAILED(result)) return result;
1019    result = stream.ReadUI32(m_MaxPacketSize);
1020    if (AP4_FAILED(result)) return result;
1021
1022    return AP4_SUCCESS;
1023}
1024
1025/*----------------------------------------------------------------------
1026|   AP4_RtpHintSampleEntry::WriteFields
1027+---------------------------------------------------------------------*/
1028AP4_Result
1029AP4_RtpHintSampleEntry::WriteFields(AP4_ByteStream& stream)
1030{
1031    // sample entry
1032    AP4_Result result = AP4_SampleEntry::WriteFields(stream);
1033    if (AP4_FAILED(result)) return result;
1034   
1035    // data
1036    result = stream.WriteUI16(m_HintTrackVersion);
1037    if (AP4_FAILED(result)) return result;
1038    result = stream.WriteUI16(m_HighestCompatibleVersion);
1039    if (AP4_FAILED(result)) return result;
1040    result = stream.WriteUI32(m_MaxPacketSize);
1041    if (AP4_FAILED(result)) return result;
1042
1043    return result;
1044}
1045
1046/*----------------------------------------------------------------------
1047|   AP4_RtpHintSampleEntry::InspectFields
1048+---------------------------------------------------------------------*/
1049AP4_Result
1050AP4_RtpHintSampleEntry::InspectFields(AP4_AtomInspector& inspector)
1051{
1052    // sample entry
1053    AP4_SampleEntry::InspectFields(inspector);
1054   
1055    // fields
1056    inspector.AddField("hint_track_version", m_HintTrackVersion);
1057    inspector.AddField("highest_compatible_version", m_HighestCompatibleVersion);
1058    inspector.AddField("max_packet_size", m_MaxPacketSize);
1059   
1060    return AP4_SUCCESS;
1061}
Note: See TracBrowser for help on using the browser.