/*----------------------------------------------------------------------
|   AP4_StsdAtom::AP4_StsdAtom
+---------------------------------------------------------------------*/
AP4_StsdAtom::AP4_StsdAtom(AP4_UI32         size,
                           AP4_UI08         version,
                           AP4_UI32         flags,
                           AP4_ByteStream&  stream,
                           AP4_AtomFactory& atom_factory) :
    AP4_ContainerAtom(AP4_ATOM_TYPE_STSD, size, false, version, flags)
{
    // read the number of entries
    AP4_UI32 entry_count;
    stream.ReadUI32(entry_count);

    // save and switch the factory's context
    atom_factory.PushContext(m_Type);

    // read all entries
    AP4_LargeSize bytes_available = size-AP4_FULL_ATOM_HEADER_SIZE-4;
    for (unsigned int i=0; i<entry_count; i++) {
        AP4_Atom* atom;
        if (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream, 
                                                            bytes_available,
                                                            atom))) {
            atom->SetParent(this);
            m_Children.Add(atom);
        }
    }

    // restore the saved context
    atom_factory.PopContext();

    // initialize the sample description cache
    m_SampleDescriptions.EnsureCapacity(m_Children.ItemCount());
    for (AP4_Ordinal i=0; i<m_Children.ItemCount(); i++) {
        m_SampleDescriptions.Append(NULL);
    }
}
Exemple #2
0
/*----------------------------------------------------------------------
|       AP4_StsdAtom::AP4_StsdAtom
+---------------------------------------------------------------------*/
AP4_StsdAtom::AP4_StsdAtom(AP4_Size         size,
                           AP4_ByteStream&  stream,
                           AP4_AtomFactory& atom_factory) :
    AP4_ContainerAtom(AP4_ATOM_TYPE_STSD, size, true, stream)
{
    // read the number of entries
    AP4_UI32 entry_count;
    stream.ReadUI32(entry_count);

    // read all entries
    AP4_Size bytes_available = size-AP4_FULL_ATOM_HEADER_SIZE-4;

	m_Data.SetDataSize(bytes_available);
	stream.Read(m_Data.UseData(), m_Data.GetDataSize());

	AP4_ByteStream* s = DNew AP4_MemoryByteStream(m_Data.UseData(), m_Data.GetDataSize());
    for (unsigned int i=0; i<entry_count; i++) {
        AP4_Atom* atom;
        if (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(*s, 
                                                            bytes_available,
                                                            atom,
															this))) {
            atom->SetParent(this);
            m_Children.Add(atom);
        }
    }
	s->Release();

    // initialize the sample description cache
    m_SampleDescriptions.EnsureCapacity(m_Children.ItemCount());
    for (AP4_Ordinal i=0; i<m_Children.ItemCount(); i++) {
        m_SampleDescriptions.Append(NULL);
    }
}
/*----------------------------------------------------------------------
|       AP4_ContainerAtom::ReadChildren
+---------------------------------------------------------------------*/
void
AP4_ContainerAtom::ReadChildren(AP4_AtomFactory& atom_factory,
                                AP4_ByteStream&  stream, 
                                AP4_Size         size)
{
    AP4_Atom* atom;
    AP4_Size  bytes_available = size;
    while (AP4_SUCCEEDED(
        atom_factory.CreateAtomFromStream(stream, bytes_available, atom, this))) {
        atom->SetParent(this);
        m_Children.Add(atom);
    }
}
Exemple #4
0
/*----------------------------------------------------------------------
|       AP4_MoovAtom::AP4_MoovAtom
+---------------------------------------------------------------------*/
AP4_MoovAtom::AP4_MoovAtom(AP4_Size         size,
                           AP4_ByteStream&  stream,
                           AP4_AtomFactory& atom_factory) :
    AP4_ContainerAtom(AP4_ATOM_TYPE_MOOV, size, false, stream, atom_factory),
    m_TimeScale(0)
{
	if(AP4_ContainerAtom* cmov = dynamic_cast<AP4_ContainerAtom*>(GetChild(AP4_ATOM_TYPE_CMOV)))
	{
		AP4_DcomAtom* dcom = dynamic_cast<AP4_DcomAtom*>(cmov->GetChild(AP4_ATOM_TYPE_DCOM));
		AP4_CmvdAtom* cmvd = dynamic_cast<AP4_CmvdAtom*>(cmov->GetChild(AP4_ATOM_TYPE_CMVD));

		if(dcom && dcom->GetCompressorSubType() == AP4_ATOM_TYPE('z','l','i','b') && cmvd)
		{
			const AP4_DataBuffer& data = cmvd->GetDataBuffer();

			z_stream d_stream;
			d_stream.zalloc = (alloc_func)0;
			d_stream.zfree = (free_func)0;
			d_stream.opaque = (voidpf)0;

			int res;

			if(Z_OK == (res = inflateInit(&d_stream)))
			{
				d_stream.next_in = (Bytef*)data.GetData();
				d_stream.avail_in = data.GetDataSize();

				unsigned char* dst = NULL;
				int n = 0;
				
				do
				{
					dst = (unsigned char*)realloc(dst, ++n*1000);
					d_stream.next_out = &dst[(n-1)*1000];
					d_stream.avail_out = 1000;

					if(Z_OK != (res = inflate(&d_stream, Z_NO_FLUSH)) && Z_STREAM_END != res)
					{
						free(dst);
						dst = NULL;
						break;
					}
				}
				while(0 == d_stream.avail_out && 0 != d_stream.avail_in && Z_STREAM_END != res);

				inflateEnd(&d_stream);

				if(dst)
				{
					AP4_ByteStream* s = new AP4_MemoryByteStream(dst, d_stream.total_out);
					ReadChildren(atom_factory, *s, d_stream.total_out);
					s->Release();
					free(dst);
				}

				if(AP4_MoovAtom* moov = dynamic_cast<AP4_MoovAtom*>(GetChild(AP4_ATOM_TYPE_MOOV)))
				{
					AP4_List<AP4_Atom> Children;

					for(AP4_List<AP4_Atom>::Item* item = moov->GetChildren().FirstItem(); 
						item; 
						item = item->GetNext())
					{
						Children.Add(item->GetData());
					}

					for(AP4_List<AP4_Atom>::Item* item = Children.FirstItem(); 
						item; 
						item = item->GetNext())
					{
						AP4_Atom* atom = item->GetData();
						atom->Detach();
						atom->SetParent(this);
						m_Children.Add(atom);
					}

					moov->Detach();
					delete moov;
				}
			}
		}
	}

    // collect all trak atoms
    m_Children.Apply(AP4_TrakAtomCollector(&m_TrakAtoms));    
}