/*---------------------------------------------------------------------- | AP4_LinearReader::AdvanceFragment +---------------------------------------------------------------------*/ AP4_Result AP4_LinearReader::AdvanceFragment() { AP4_Result result; // go the the start of the next fragment result = m_FragmentStream->Seek(m_NextFragmentPosition); if (AP4_FAILED(result)) return result; // read atoms until we find a moof assert(m_HasFragments); if (!m_FragmentStream) return AP4_ERROR_INVALID_STATE; do { AP4_Atom* atom = NULL; result = AP4_DefaultAtomFactory::Instance.CreateAtomFromStream(*m_FragmentStream, atom); if (AP4_SUCCEEDED(result)) { 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; m_FragmentStream->Tell(position); // process the movie fragment result = ProcessMoof(moof, position-atom->GetSize(), position+8); if (AP4_FAILED(result)) return result; // compute where the next fragment will be AP4_UI32 size; AP4_UI32 type; m_FragmentStream->Tell(position); result = m_FragmentStream->ReadUI32(size); if (AP4_FAILED(result)) return AP4_SUCCESS; // can't read more result = m_FragmentStream->ReadUI32(type); if (AP4_FAILED(result)) return AP4_SUCCESS; // can't read more if (size == 0) { m_NextFragmentPosition = 0; } else if (size == 1) { AP4_UI64 size_64 = 0; result = m_FragmentStream->ReadUI64(size_64); if (AP4_FAILED(result)) return AP4_SUCCESS; // can't read more m_NextFragmentPosition = position+size_64; } else { m_NextFragmentPosition = position+size; } return AP4_SUCCESS; } else { delete atom; } } else { delete atom; } } } while (AP4_SUCCEEDED(result)); return AP4_ERROR_EOS; }
/*---------------------------------------------------------------------- | 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; }