Пример #1
0
 bool TimeSeek(double pts, bool preceeding)
 {
   AP4_Ordinal sampleIndex;
   if (AP4_SUCCEEDED(SeekSample(m_Track->GetId(), static_cast<AP4_UI64>(pts*(double)m_Track->GetMediaTimeScale()), sampleIndex, preceeding)))
   {
     if (m_Decrypter)
       m_Decrypter->SetSampleIndex(sampleIndex);
     m_started = true;
     return AP4_SUCCEEDED(ReadSample());
   }
   return false;
 };
/*----------------------------------------------------------------------
|   main
+---------------------------------------------------------------------*/
int
main(int argc, char** argv)
{
    if (argc != 2) {
        PrintUsageAndExit();
    }
    const char* input_filename  = argv[1];
    
    // open the input
    AP4_ByteStream* input = NULL;
    AP4_Result result = AP4_FileByteStream::Create(input_filename, AP4_FileByteStream::STREAM_MODE_READ, input);
    if (AP4_FAILED(result)) {
        fprintf(stderr, "ERROR: cannot open input file (%s)\n", input_filename);
        return 1;
    }
        
    // get the movie
    AP4_File* file = new AP4_File(*input, AP4_DefaultAtomFactory::Instance, true);
    AP4_Movie* movie = file->GetMovie();
    
    AP4_Atom* atom = NULL;
    do {
        // process the next atom
        result = AP4_DefaultAtomFactory::Instance.CreateAtomFromStream(*input, atom);
        if (AP4_SUCCEEDED(result)) {
            printf("atom size=%lld\n", atom->GetSize());
            if (atom->GetType() == AP4_ATOM_TYPE_MOOF) {
                AP4_ContainerAtom* moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
                if (moof) {
                    // remember where we are in the stream
                    AP4_Position position = 0;
                    input->Tell(position);
        
                    // process the movie fragment
                    ProcessMoof(movie, moof, input, position-atom->GetSize(), position+8);

                    // go back to where we were before processing the fragment
                    input->Seek(position);
                }
            } else {
                delete atom;
            }            
        }
    } while (AP4_SUCCEEDED(result));
    
    // cleanup
    delete file;
    input->Release();

    return 0;                                            
}
Пример #3
0
/*----------------------------------------------------------------------
|   AP4_AtomFactory::CreateAtomsFromStream
+---------------------------------------------------------------------*/
AP4_Result
AP4_AtomFactory::CreateAtomsFromStream(AP4_ByteStream& stream, 
                                       AP4_AtomParent& atoms)
{
    AP4_LargeSize stream_size     = 0;
    AP4_Position  stream_position = 0;
    AP4_LargeSize bytes_available = (AP4_LargeSize)(-1);
    if (AP4_SUCCEEDED(stream.GetSize(stream_size)) && 
        stream_size != 0 &&
        AP4_SUCCEEDED(stream.Tell(stream_position)) &&
        stream_position <= stream_size) {
        bytes_available = stream_size-stream_position;
    }
    return CreateAtomsFromStream(stream, bytes_available, atoms);
}
Пример #4
0
/*----------------------------------------------------------------------
|       AP4_File::AP4_File
+---------------------------------------------------------------------*/
AP4_File::AP4_File(AP4_ByteStream& stream, AP4_AtomFactory& atom_factory) :
    m_Movie(NULL)
{
    // get all atoms
    AP4_Atom* atom;
    while (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream, atom))) {
        switch (atom->GetType()) {
        case AP4_ATOM_TYPE_MOOV:
            m_Movie = new AP4_Movie(dynamic_cast<AP4_MoovAtom*>(atom),
                                    stream);
            break;
        case AP4_ATOM_TYPE_MOOF:
            if (m_Movie) {
                m_Movie->ProcessMoof(AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom),
                                     stream);
            }
            delete atom;
            break;
        case AP4_ATOM_TYPE_FTYP:
            //m_Movie = new AP4_Movie(dynamic_cast<AP4_FtypAtom*>(atom),  stream);
            m_FileType = dynamic_cast<AP4_FtypAtom*>(atom);
        default:
            m_OtherAtoms.Add(atom);
        }
    }
}
Пример #5
0
/*----------------------------------------------------------------------
|   AP4_TrackSampleSource::ReadNextSample
+---------------------------------------------------------------------*/
AP4_Result  
AP4_TrackSampleSource::ReadNextSample(AP4_Sample& sample, AP4_DataBuffer& buffer)
{
    AP4_Result result = m_Track->ReadSample(m_SampleIndex, sample, buffer);
    if (AP4_SUCCEEDED(result)) ++m_SampleIndex;
    return result;
}
Пример #6
0
/*----------------------------------------------------------------------
|   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);
    }
}
Пример #7
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);
    }
}
Пример #8
0
/*----------------------------------------------------------------------
|       AP4_IsmaDecryptingProcessor:CreateTrackHandler
+---------------------------------------------------------------------*/
AP4_Processor::TrackHandler* 
AP4_IsmaDecryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak)
{
    // find the stsd atom
    AP4_StsdAtom* stsd = dynamic_cast<AP4_StsdAtom*>(
        trak->FindChild("mdia/minf/stbl/stsd"));

    // avoid tracks with no stsd atom (should not happen)
    if (stsd == NULL) return NULL;

    // we only look at the first sample description
    AP4_SampleDescription* desc = stsd->GetSampleDescription(0);
    AP4_SampleEntry* entry = stsd->GetSampleEntry(0);
    if (desc == NULL || entry == NULL) return NULL;
    if (desc->GetType() == AP4_SampleDescription::TYPE_ISMACRYP) {
        // create a handler for this track
        AP4_IsmaCrypSampleDescription* ismacryp_desc = 
            static_cast<AP4_IsmaCrypSampleDescription*>(desc);
        if (ismacryp_desc->GetSchemeType() == AP4_ISMACRYP_SCHEME_TYPE_IAEC) {
            const AP4_UI08* key;
            const AP4_UI08* salt;
            if (AP4_SUCCEEDED(m_KeyMap.GetKey(trak->GetId(), key, salt))) {
                return new AP4_IsmaTrackDecrypter(key, salt, ismacryp_desc, entry);
            }
        }
    }

    return NULL;
}
Пример #9
0
/*----------------------------------------------------------------------
|   AP4_AtomFactory::CreateAtomsFromStream
+---------------------------------------------------------------------*/
AP4_Result
AP4_AtomFactory::CreateAtomsFromStream(AP4_ByteStream& stream, 
                                       AP4_LargeSize   bytes_available,
                                       AP4_AtomParent& atoms)
{
    AP4_Result result;
    do {
        AP4_Atom* atom = NULL;
        result = CreateAtomFromStream(stream, bytes_available, atom);
        if (AP4_SUCCEEDED(result) && atom != NULL) {
            atoms.AddChild(atom);
        }
    } while (AP4_SUCCEEDED(result));
    
    return AP4_SUCCESS;
}
Пример #10
0
/*----------------------------------------------------------------------
|   AP4_SubStream::WritePartial
+---------------------------------------------------------------------*/
AP4_Result 
AP4_SubStream::WritePartial(const void* buffer, 
                            AP4_Size    bytes_to_write, 
                            AP4_Size&   bytes_written)
{
    // default values
    bytes_written = 0;

    // shortcut
    if (bytes_to_write == 0) {
        return AP4_SUCCESS;
    }

    // clamp to range
    if (m_Position+bytes_to_write > m_Size) {
        bytes_to_write = (AP4_Size)(m_Size - m_Position);
    }

    // check for en of substream
    if (bytes_to_write == 0) {
        return AP4_ERROR_EOS;
    }

    // seek inside container
    AP4_Result result;
    result = m_Container.Seek(m_Offset+m_Position);
    if (AP4_FAILED(result)) return result;

    // write to container
    result = m_Container.WritePartial(buffer, bytes_to_write, bytes_written);
    if (AP4_SUCCEEDED(result)) {
        m_Position += bytes_written;
    }
    return result;
}
Пример #11
0
/*----------------------------------------------------------------------
|       DumpRtpPackets
+---------------------------------------------------------------------*/
static AP4_Result
DumpRtpPackets(AP4_HintTrackReader& reader, const char* file_name)
{
    // create the output stream
    AP4_ByteStream* output;
    try {
        output = new AP4_FileByteStream(file_name,
            AP4_FileByteStream::STREAM_MODE_WRITE);
    } catch (AP4_Exception) {
        fprintf(stderr, "ERROR: cannot open output file (%s)\n", file_name);
        return AP4_FAILURE;
    }

    // read the packets from the reader and write them in the output stream
    AP4_DataBuffer data(1500);
    AP4_TimeStamp ts;
    while(AP4_SUCCEEDED(reader.GetNextPacket(data, ts))) {
        output->Write(data.GetData(), data.GetDataSize());
        AP4_Debug("#########\n\tpacket contains %d bytes\n", data.GetDataSize());
        AP4_Debug("\tsent at time stamp %d\n\n", ts);
    }
    
    output->Release();

    return AP4_SUCCESS;
}
Пример #12
0
/*----------------------------------------------------------------------
|   AP4_DefaultAtomFactory::Initialize
+---------------------------------------------------------------------*/
AP4_Result
AP4_DefaultAtomFactory::Initialize()
{
    // register built-in type handlers
    AP4_Result result = AddTypeHandler(new AP4_MetaDataAtomTypeHandler(this));
    if (AP4_SUCCEEDED(result)) m_Initialized = true;
    return result;
}
Пример #13
0
 virtual AP4_Result GetSample(AP4_Ordinal index, AP4_Sample& sample) {
     AP4_Result result = m_Track->GetSample(index, sample);
     if (AP4_SUCCEEDED(result)) {
         if (m_ForcedSync[index]) {
             sample.SetSync(true);
         }
     }
     return result;
 }
Пример #14
0
/*----------------------------------------------------------------------
|   AP4_TrefTypeAtom::AddTrackId
+---------------------------------------------------------------------*/
AP4_Result
AP4_TrefTypeAtom::AddTrackId(AP4_UI32 track_id)
{
    AP4_Result result = m_TrackIds.Append(track_id);
    if (AP4_SUCCEEDED(result)) {
        m_Size32 += 4;
    }
    return result;
}
Пример #15
0
/*----------------------------------------------------------------------
|   AP4_OmaDcfAtomDecrypter::DecryptAtoms
+---------------------------------------------------------------------*/
AP4_Result
AP4_OmaDcfAtomDecrypter::DecryptAtoms(AP4_AtomParent&                  atoms,
                                      AP4_Processor::ProgressListener* /*listener*/,
                                      AP4_BlockCipherFactory*          block_cipher_factory,
                                      AP4_ProtectionKeyMap&            key_map)
{
    // default factory
    if (block_cipher_factory == NULL) {
        block_cipher_factory = &AP4_DefaultBlockCipherFactory::Instance;
    }

    unsigned int index = 1;
    for (AP4_List<AP4_Atom>::Item* item = atoms.GetChildren().FirstItem();
            item;
            item = item->GetNext()) {
        AP4_Atom* atom = item->GetData();
        if (atom->GetType() != AP4_ATOM_TYPE_ODRM) continue;

        // check that we have the key
        const AP4_DataBuffer* key = key_map.GetKey(index++);
        if (key == NULL) return AP4_ERROR_INVALID_PARAMETERS;

        // check that we have all the atoms we need
        AP4_ContainerAtom* odrm = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
        if (odrm == NULL) continue; // not enough info
        AP4_OdheAtom* odhe = AP4_DYNAMIC_CAST(AP4_OdheAtom, odrm->GetChild(AP4_ATOM_TYPE_ODHE));
        if (odhe == NULL) continue; // not enough info
        AP4_OddaAtom* odda = AP4_DYNAMIC_CAST(AP4_OddaAtom, odrm->GetChild(AP4_ATOM_TYPE_ODDA));;
        if (odda == NULL) continue; // not enough info
        AP4_OhdrAtom* ohdr = AP4_DYNAMIC_CAST(AP4_OhdrAtom, odhe->GetChild(AP4_ATOM_TYPE_OHDR));
        if (ohdr == NULL) continue; // not enough info

        // do nothing if the atom is not encrypted
        if (ohdr->GetEncryptionMethod() == AP4_OMA_DCF_ENCRYPTION_METHOD_NULL) {
            continue;
        }

        // create the byte stream
        AP4_ByteStream* cipher_stream = NULL;
        AP4_Result result = CreateDecryptingStream(*odrm,
                            key->GetData(),
                            key->GetDataSize(),
                            block_cipher_factory,
                            cipher_stream);
        if (AP4_SUCCEEDED(result)) {
            // replace the odda atom's payload with the decrypted stream
            odda->SetEncryptedPayload(*cipher_stream, ohdr->GetPlaintextLength());
            cipher_stream->Release();

            // the atom will now be in the clear
            ohdr->SetEncryptionMethod(AP4_OMA_DCF_ENCRYPTION_METHOD_NULL);
            ohdr->SetPaddingScheme(AP4_OMA_DCF_PADDING_SCHEME_NONE);
        }
    }

    return AP4_SUCCESS;
}
Пример #16
0
/*----------------------------------------------------------------------
|   AP4_KodiFileByteStream::Flush
+---------------------------------------------------------------------*/
AP4_Result
AP4_KodiFileByteStream::Flush()
{
    int ret_val = 0;
    xbmc->FlushFile(m_File);
	AP4_Result result((ret_val > 0) ? AP4_FAILURE : AP4_SUCCESS);
	if (AP4_SUCCEEDED(result) && GetObserver())
		return GetObserver()->OnFlush(this);
	return result;
}
Пример #17
0
/*----------------------------------------------------------------------
|   AP4_Movie::GetTrack
+---------------------------------------------------------------------*/
AP4_Track*
AP4_Movie::GetTrack(AP4_Track::Type track_type, AP4_Ordinal index)
{
    AP4_Track* track = NULL;
    if (AP4_SUCCEEDED(m_Tracks.Find(AP4_TrackFinderByType(track_type, index), track))) {
        return track;
    } else {
        return NULL;
    }
}
Пример #18
0
/*----------------------------------------------------------------------
|   AP4_Movie::GetTrack
+---------------------------------------------------------------------*/
AP4_Track*
AP4_Movie::GetTrack(AP4_UI32 track_id)
{
    AP4_Track* track = NULL;
    if (AP4_SUCCEEDED(m_Tracks.Find(AP4_TrackFinderById(track_id), track))) {
        return track;
    } else {
        return NULL;
    }
}
Пример #19
0
/*----------------------------------------------------------------------
|   AP4_SyntheticSampleTable::GetSampleDescription
+---------------------------------------------------------------------*/
AP4_SampleDescription* 
AP4_SyntheticSampleTable::GetSampleDescription(AP4_Ordinal index)
{
    SampleDescriptionHolder* holder;
    if (AP4_SUCCEEDED(m_SampleDescriptions.Get(index, holder))) {
        return holder->m_SampleDescription;
    } else {
        return NULL;
    }
}
Пример #20
0
/*----------------------------------------------------------------------
|       AP4_SyntheticSampleTable::GetSampleDescription
+---------------------------------------------------------------------*/
AP4_SampleDescription* 
AP4_SyntheticSampleTable::GetSampleDescription(AP4_Ordinal index)
{
    AP4_SampleDescription* description;
    if (AP4_SUCCEEDED(m_SampleDescriptions.Get(index, description))) {
        return description;
    } else {
        return NULL;
    }
}
Пример #21
0
/*----------------------------------------------------------------------
|       AP4_SubStream::Seek
+---------------------------------------------------------------------*/
AP4_Result 
AP4_SubStream::Seek(AP4_Offset offset)
{
    if (offset > m_Size) return AP4_FAILURE;
    AP4_Result result;
    result = m_Container.Seek(m_Offset+offset);
    if (AP4_SUCCEEDED(result)) {
        m_Position = offset;
    }
    return result;
}
Пример #22
0
/*----------------------------------------------------------------------
|   AP4_TrackSampleSource::ReadNextSample
+---------------------------------------------------------------------*/
AP4_Result  
AP4_TrackSampleSource::ReadNextSample(AP4_Sample& sample, AP4_DataBuffer& buffer, AP4_UI32& track_id)
{
    AP4_Result result = m_Track->ReadSample(m_SampleIndex, sample, buffer);
    if (AP4_SUCCEEDED(result)) {
        ++m_SampleIndex;
        track_id = m_Track->GetId();
    } else {
        track_id = 0;
    }
    return result;
}
Пример #23
0
/*----------------------------------------------------------------------
|       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);
    }
}
Пример #24
0
/*----------------------------------------------------------------------
|   AutoDetectAudioFragmentDuration
+---------------------------------------------------------------------*/
static unsigned int 
AutoDetectAudioFragmentDuration(AP4_ByteStream& stream, TrackCursor* cursor)
{
    // remember where we are in the stream
    AP4_Position where = 0;
    stream.Tell(where);
    AP4_LargeSize stream_size = 0;
    stream.GetSize(stream_size);
    AP4_LargeSize bytes_available = stream_size-where;
    
    AP4_UI64  fragment_count = 0;
    AP4_UI32  last_fragment_size = 0;
    AP4_Atom* atom = NULL;
    while (AP4_SUCCEEDED(AP4_DefaultAtomFactory::Instance.CreateAtomFromStream(stream, bytes_available, atom))) {
        if (atom && atom->GetType() == AP4_ATOM_TYPE_MOOF) {
            AP4_ContainerAtom* moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
            AP4_TfhdAtom* tfhd = AP4_DYNAMIC_CAST(AP4_TfhdAtom, moof->FindChild("traf/tfhd"));
            if (tfhd && tfhd->GetTrackId() == cursor->m_Track->GetId()) {
                ++fragment_count;
                AP4_TrunAtom* trun = AP4_DYNAMIC_CAST(AP4_TrunAtom, moof->FindChild("traf/trun"));
                if (trun) {
                    last_fragment_size = trun->GetEntries().ItemCount();
                }
            }
        }
        delete atom;
        atom = NULL;
    }
    
    // restore the stream to its original position
    stream.Seek(where);
    
    // decide if we can infer an fragment size
    if (fragment_count == 0 || cursor->m_Samples->GetSampleCount() == 0) {
        return 0;
    }
    // don't count the last fragment if we have more than one
    if (fragment_count > 1 && last_fragment_size) {
        --fragment_count;
    }
    if (fragment_count <= 1 || cursor->m_Samples->GetSampleCount() < last_fragment_size) {
        last_fragment_size = 0;
    }
    AP4_Sample sample;
    AP4_UI64 total_duration = 0;
    for (unsigned int i=0; i<cursor->m_Samples->GetSampleCount()-last_fragment_size; i++) {
        cursor->m_Samples->GetSample(i, sample);
        total_duration += sample.GetDuration();
    }
    return (unsigned int)AP4_ConvertTime(total_duration/fragment_count, cursor->m_Track->GetMediaTimeScale(), 1000);
}
Пример #25
0
AP4_ByteStream*
AP4_FileByteStream_Create(const char* name, int mode, AP4_Result* result)
{
    AP4_Result      local_result;
    AP4_ByteStream* stream;
    
    local_result = AP4_FileByteStream::Create(name, 
                                              (AP4_FileByteStream::Mode)mode, 
                                              stream);
    if (result) *result = local_result;
    if (AP4_SUCCEEDED(local_result)) {
        return stream;
    } else {
        return NULL;
    }
}
Пример #26
0
/*----------------------------------------------------------------------
|   AP4_MarlinIpmpEncryptingProcessor::CreateTrackHandler
+---------------------------------------------------------------------*/
AP4_Processor::TrackHandler* 
AP4_MarlinIpmpEncryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak)
{
    // create a handler for this track if we have a key for it
    const AP4_UI08* key;
    const AP4_UI08* iv;
    if (AP4_SUCCEEDED(m_KeyMap.GetKeyAndIv(trak->GetId(), key, iv))) {
        // create the track handler
        AP4_MarlinIpmpTrackEncrypter* handler = NULL;
        AP4_Result result = AP4_MarlinIpmpTrackEncrypter::Create(*m_BlockCipherFactory, key, iv, handler);
        if (AP4_FAILED(result)) return NULL;
        return handler;
    }
    
    // not encrypted
    return NULL;
}
Пример #27
0
/*----------------------------------------------------------------------
|   AP4_Track::Clone
+---------------------------------------------------------------------*/
AP4_Track* 
AP4_Track::Clone(AP4_Result* result)
{
    AP4_SyntheticSampleTable* sample_table = new AP4_SyntheticSampleTable();
    
    // default return value
    if (result) *result = AP4_SUCCESS;
    
    // add clones of the sample descriptions to the new sample table
    for (unsigned int i=0; ;i++) {
        AP4_SampleDescription* sample_description = GetSampleDescription(i);
        if (sample_description == NULL) break;
        sample_table->AddSampleDescription(sample_description->Clone());
    }

    AP4_Sample  sample;
    AP4_Ordinal index = 0;
    while (AP4_SUCCEEDED(GetSample(index, sample))) {
        AP4_ByteStream* data_stream;
        data_stream = sample.GetDataStream();
        sample_table->AddSample(*data_stream,
                                sample.GetOffset(),
                                sample.GetSize(),
                                sample.GetDuration(),
                                sample.GetDescriptionIndex(),
                                sample.GetDts(),
                                sample.GetCtsDelta(),
                                sample.IsSync());
        AP4_RELEASE(data_stream); // release our ref, the table has kept its own ref.
        index++;
    }    
    
    // create the cloned track
    AP4_Track* clone = new AP4_Track(GetType(),
                                     sample_table,
                                     GetId(),
                                     GetMovieTimeScale(),
                                     GetDuration(),
                                     GetMediaTimeScale(),
                                     GetMediaDuration(),
                                     GetTrackLanguage(),
                                     GetWidth(),
                                     GetHeight());
                                     
    return clone;
}
/*----------------------------------------------------------------------
|   ProcessMoof
+---------------------------------------------------------------------*/
static int
ProcessMoof(AP4_Movie*         movie, 
            AP4_ContainerAtom* moof, 
            AP4_ByteStream*    sample_stream, 
            AP4_Position       moof_offset, 
            AP4_Position       mdat_payload_offset)
{
    AP4_Result result;
    
    AP4_MovieFragment* fragment = new AP4_MovieFragment(moof);
    printf("fragment sequence number=%d\n", fragment->GetSequenceNumber());
    
    AP4_FragmentSampleTable* sample_table = NULL;
    
    // get all track IDs in this fragment
    AP4_Array<AP4_UI32> ids;
    fragment->GetTrackIds(ids);
    printf("Found %d tracks in fragment: ", ids.ItemCount());
    for (unsigned int i=0; i<ids.ItemCount(); i++) {
        printf("%d ", ids[i]);
    }
    printf("\n");
    
    for (unsigned int i=0; i<ids.ItemCount(); i++) {
        AP4_Track* track = NULL;
        if (movie) {
            track = movie->GetTrack(ids[i]);
        }
        AP4_ContainerAtom* traf = NULL;
        fragment->GetTrafAtom(ids[i], traf);
        
        printf("processing moof for track id %d\n", ids[i]);
        result = fragment->CreateSampleTable(movie, ids[i], sample_stream, moof_offset, mdat_payload_offset, sample_table);
        CHECK(result == AP4_SUCCESS || result == AP4_ERROR_NO_SUCH_ITEM);
        if (AP4_SUCCEEDED(result) ) {
            ProcessSamples(track, traf, sample_table);
            delete sample_table;
        } else {
            printf("no sample table for this track\n");
        }
    }
    
    delete fragment;
    return 0;
}
Пример #29
0
/*----------------------------------------------------------------------
|   AP4_LinearReader::PopSample
+---------------------------------------------------------------------*/
bool
AP4_LinearReader::PopSample(Tracker*        tracker,
                            AP4_Sample&     sample,
                            AP4_DataBuffer& sample_data)
{
    SampleBuffer* head = NULL;
    if (AP4_SUCCEEDED(tracker->m_Samples.PopHead(head))) {
        assert(head->m_Sample);
        sample = *head->m_Sample;
        sample_data.SetData(head->m_Data.GetData(), head->m_Data.GetDataSize());
        assert(m_BufferFullness >= sample.GetSize());
        m_BufferFullness -= sample.GetSize();
        delete head;
        return true;
    }

    return false;
}
Пример #30
0
/*----------------------------------------------------------------------
|   AP4_MemoryByteStream::WritePartial
+---------------------------------------------------------------------*/
AP4_Result 
AP4_MemoryByteStream::WritePartial(const void* buffer, 
                                   AP4_Size    bytes_to_write, 
                                   AP4_Size&   bytes_written)
{
    // default values
    bytes_written = 0;

    // shortcut
    if (bytes_to_write == 0) {
        return AP4_SUCCESS;
    }

    // check that we don't exceed the max
    if (m_Position+bytes_to_write > (AP4_Position)AP4_MEMORY_BYTE_STREAM_MAX_SIZE) {
        return AP4_ERROR_OUT_OF_RANGE;
    }

    // reserve space in the buffer
    AP4_Result result = m_Buffer->Reserve((AP4_Size)(m_Position+bytes_to_write));
    if (AP4_SUCCEEDED(result)) {
        m_Buffer->SetDataSize((AP4_Size)(m_Position+bytes_to_write));
    } else {
        // failed to reserve, most likely caused by a buffer that has
        // external storage
        if (m_Position+bytes_to_write > m_Buffer->GetDataSize()) {
            bytes_to_write = (AP4_Size)(m_Buffer->GetDataSize() - m_Position);
        }
    } 

    // check for en of stream
    if (bytes_to_write == 0) {
        return AP4_ERROR_EOS;
    }

    // write to memory
    AP4_CopyMemory((void*)(m_Buffer->UseData()+m_Position), buffer, bytes_to_write);
    m_Position += bytes_to_write;

    bytes_written = bytes_to_write;

    return AP4_SUCCESS;
}