Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*----------------------------------------------------------------------
- | AP4_Processor::MuxStream
- +---------------------------------------------------------------------*/
- AP4_Result
- AP4_Processor::MuxStream(
- AP4_Array<AP4_ByteStream *> &input,
- AP4_ByteStream& output,
- AP4_UI08 partitions,
- AP4_AtomFactory& atom_factory)
- {
- AP4_Result result;
- AP4_UI64 stream_offset = 0;
- if (partitions & 1)
- {
- // read all atoms.
- // keep all atoms except [mdat]
- // keep a ref to [moov]
- // put [moof] atoms in a separate list
- AP4_AtomParent top_level;
- AP4_Array<AP4_MoovAtom*> moov;
- AP4_Size track_count(0);
- for(AP4_Size streamid(0); streamid < input.ItemCount(); ++streamid)
- {
- for (AP4_Atom* atom = NULL; AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(*input[streamid], atom)); input[streamid]->Tell(stream_offset))
- {
- if (atom->GetType() == AP4_ATOM_TYPE_MFRA) {
- delete atom;
- continue;
- }
- else if (atom->GetType() == AP4_ATOM_TYPE_SIDX) {
- delete atom;
- continue;
- }
- else if (atom->GetType() == AP4_ATOM_TYPE_SSIX) {
- delete atom;
- continue;
- }
- if (streamid == 0)
- top_level.AddChild(atom);
- else if (atom->GetType() != AP4_ATOM_TYPE_MOOV)
- delete atom;
- if (atom->GetType() == AP4_ATOM_TYPE_MOOV)
- {
- moov.Append(AP4_DYNAMIC_CAST(AP4_MoovAtom,atom));
- break;
- }
- }
- if (moov.ItemCount() == streamid)
- return AP4_ERROR_INVALID_FORMAT;
- while (AP4_SUCCEEDED(moov[streamid]->DeleteChild(AP4_ATOM_TYPE_PSSH, 0)));
- // Remove tracks we cannot handle
- for (AP4_List<AP4_TrakAtom>::Item *item(moov[streamid]->GetTrakAtoms().FirstItem()); item;)
- if (!item->GetData()->FindChild("mdia/minf/stbl"))
- moov[streamid]->GetTrakAtoms().Remove(item);
- else
- item = item->GetNext();
- track_count += moov[streamid]->GetTrakAtoms().ItemCount();
- }
- // initialize the processor
- if (AP4_FAILED(result = Initialize(top_level, *input[0])))
- return result;
- // process the tracks if we have a moov atom
- m_TrackData.SetItemCount(track_count);
- m_StreamData.SetItemCount(input.ItemCount());
- //NormalizeTREX(mvex, 0, m_TrackCounts[0], m_TrackCounts[1]);
- AP4_Cardinal internal_index(0);
- AP4_ContainerAtom *mvex_base(0);
- AP4_List<AP4_TrakAtom>::Item *item = NULL;
- for (AP4_Size streamid(0); streamid < input.ItemCount(); ++streamid)
- {
- m_StreamData[streamid].trackStart = internal_index;
- m_StreamData[streamid].stream = input[streamid];
- if (streamid)
- moov[0]->AddTrakAtoms(moov[streamid]->GetTrakAtoms(), item);
- else
- item = moov[streamid]->GetTrakAtoms().FirstItem();
- for (; item; item = item->GetNext())
- {
- PERTRACK &track_data(m_TrackData[internal_index]);
- track_data.original_id = item->GetData()->GetId();
- item->GetData()->SetId(track_data.new_id = internal_index + 1);
- if (AP4_MdhdAtom* mdhd = AP4_DYNAMIC_CAST(AP4_MdhdAtom, item->GetData()->FindChild("mdia/mdhd")))
- track_data.timescale = mdhd->GetTimeScale();
- else
- track_data.timescale = 1;
- AP4_ContainerAtom *mvex = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moov[streamid]->GetChild(AP4_ATOM_TYPE_MVEX, 0));
- if (!mvex)
- return AP4_ERROR_INVALID_FORMAT;
- if (!item->GetData()->GetDuration())
- {
- AP4_MehdAtom *mehd(AP4_DYNAMIC_CAST(AP4_MehdAtom, mvex->GetChild(AP4_ATOM_TYPE_MEHD, 0)));
- item->GetData()->SetDuration(mehd? mehd->GetDuration():0);
- }
- AP4_TrexAtom *trex(NULL);
- unsigned int index(0);
- for (; !trex && (trex = AP4_DYNAMIC_CAST(AP4_TrexAtom, mvex->GetChild(AP4_ATOM_TYPE_TREX, index++)));)
- if(trex->GetTrackId() != track_data.original_id)
- trex = NULL;
- if (!trex)
- return AP4_ERROR_INVALID_FORMAT;
- if (mvex_base)
- {
- trex = AP4_DYNAMIC_CAST(AP4_TrexAtom, trex->Clone());
- mvex_base->AddChild(trex);
- }
- else
- mvex_base = mvex;
- trex->SetTrackId(track_data.new_id);
- track_data.track_handler = CreateTrackHandler(item->GetData(), trex);
- track_data.track_handler->ProcessTrack();
- track_data.streamId = streamid;
- ++m_StreamData[streamid].trackCount;
- ++internal_index;
- }
- }
- // We don't need the other moovs anymore.....
- moov.SetItemCount(1);
- AP4_MvhdAtom *mvhd(AP4_DYNAMIC_CAST(AP4_MvhdAtom, moov[0]->GetChild(AP4_ATOM_TYPE_MVHD, 0)));
- if (!mvhd->GetDuration())
- {
- AP4_MehdAtom *mehd(AP4_DYNAMIC_CAST(AP4_MehdAtom, mvex_base->GetChild(AP4_ATOM_TYPE_MEHD, 0)));
- mvhd->SetDuration(mehd ? mehd->GetDuration() : 0);
- }
- // finalize the processor
- Finalize(top_level);
- // calculate the size of all atoms combined
- AP4_UI64 atoms_size = 0;
- top_level.GetChildren().Apply(AP4_AtomSizeAdder(atoms_size));
- // write all atoms
- top_level.GetChildren().Apply(AP4_AtomListWriter(output));
- m_MoovAtom = moov[0];
- m_MoovAtom->Detach();
- }
- if (partitions & 2)
- {
- // process the fragments, if any
- result = AP4_SUCCESS;
- AP4_Array<AP4_UI64> moof_positions, mdat_positions;
- moof_positions.SetItemCount(input.ItemCount());
- mdat_positions.SetItemCount(input.ItemCount());
- for (;;)
- {
- AP4_ContainerAtom *moof = NULL;
- AP4_UI32 track_index(0);
- #if 0
- for (AP4_Cardinal streamid(0); streamid < input.ItemCount(); ++streamid)
- {
- AP4_Atom* atom = NULL;
- if (AP4_SUCCEEDED(input[streamid]->Tell(stream_offset)) && AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(*input[streamid], atom)))
- {
- if (atom->GetType() != AP4_ATOM_TYPE_MOOF)
- return AP4_ERROR_INVALID_FORMAT;
- moof_positions[streamid] = stream_offset;
- mdat_positions[streamid] = stream_offset + atom->GetSize() + +AP4_ATOM_HEADER_SIZE;
- if (moof)
- {
- int index(0);
- for (; AP4_Atom* child = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom)->GetChild(AP4_ATOM_TYPE_TRAF, index++);)
- moof->AddChild(child->Clone());
- delete atom;
- }
- else
- moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
- NormalizeTRAF(AP4_DYNAMIC_CAST(AP4_ContainerAtom, moof), m_StreamData[streamid].trackStart,
- m_StreamData[streamid].trackStart + m_StreamData[streamid].trackCount, track_index);
- }
- else
- delete atom;
- }
- #else
- double mindts(9999999999.0);
- AP4_Cardinal nextStream(~0);
- for (AP4_Cardinal track(0); track < m_TrackData.ItemCount(); ++track)
- if ((double)m_TrackData[track].dts / m_TrackData[track].timescale < mindts)
- {
- mindts = (double)m_TrackData[track].dts / m_TrackData[track].timescale;
- nextStream = m_TrackData[track].streamId;
- }
- AP4_Atom* atom = NULL;
- if (AP4_SUCCEEDED(result = input[nextStream]->Tell(stream_offset)) && AP4_SUCCEEDED(result = atom_factory.CreateAtomFromStream(*input[nextStream], atom)))
- {
- if (atom->GetType() != AP4_ATOM_TYPE_MOOF)
- return AP4_ERROR_INVALID_FORMAT;
- } else if (atom)
- return result;
- moof_positions[nextStream] = stream_offset;
- mdat_positions[nextStream] = stream_offset + atom->GetSize() + +AP4_ATOM_HEADER_SIZE;
- moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
- NormalizeTRAF(AP4_DYNAMIC_CAST(AP4_ContainerAtom, moof), m_StreamData[nextStream].trackStart,
- m_StreamData[nextStream].trackStart + m_StreamData[nextStream].trackCount, track_index);
- #endif
- if (!moof)
- break;
- if (AP4_FAILED(result = ProcessFragment(moof, NULL, 0, output, moof_positions, mdat_positions)))
- return result;
- delete moof;
- moof = NULL;
- }
- // cleanup
- m_TrackData.Clear();
- m_StreamData.Clear();
- }
- return AP4_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement