Advertisement
Guest User

Untitled

a guest
Apr 27th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.66 KB | None | 0 0
  1. /*----------------------------------------------------------------------
  2. |   AP4_Processor::MuxStream
  3. +---------------------------------------------------------------------*/
  4. AP4_Result
  5. AP4_Processor::MuxStream(
  6.     AP4_Array<AP4_ByteStream *> &input,
  7.     AP4_ByteStream& output,
  8.     AP4_UI08        partitions,
  9.     AP4_AtomFactory& atom_factory)
  10. {
  11.     AP4_Result      result;
  12.     AP4_UI64        stream_offset = 0;
  13.  
  14.     if (partitions & 1)
  15.     {
  16.         // read all atoms.
  17.         // keep all atoms except [mdat]
  18.         // keep a ref to [moov]
  19.         // put [moof] atoms in a separate list
  20.         AP4_AtomParent              top_level;
  21.         AP4_Array<AP4_MoovAtom*>    moov;
  22.         AP4_Size                    track_count(0);
  23.  
  24.         for(AP4_Size streamid(0); streamid < input.ItemCount(); ++streamid)
  25.         {
  26.             for (AP4_Atom* atom = NULL; AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(*input[streamid], atom)); input[streamid]->Tell(stream_offset))
  27.             {
  28.                 if (atom->GetType() == AP4_ATOM_TYPE_MFRA) {
  29.                     delete atom;
  30.                     continue;
  31.                 }
  32.                 else if (atom->GetType() == AP4_ATOM_TYPE_SIDX) {
  33.                     delete atom;
  34.                     continue;
  35.                 }
  36.                 else if (atom->GetType() == AP4_ATOM_TYPE_SSIX) {
  37.                     delete atom;
  38.                     continue;
  39.                 }
  40.                 if (streamid == 0)
  41.                     top_level.AddChild(atom);
  42.                 else if (atom->GetType() != AP4_ATOM_TYPE_MOOV)
  43.                     delete atom;
  44.                 if (atom->GetType() == AP4_ATOM_TYPE_MOOV)
  45.                 {
  46.                     moov.Append(AP4_DYNAMIC_CAST(AP4_MoovAtom,atom));
  47.                     break;
  48.                 }
  49.             }
  50.             if (moov.ItemCount() == streamid)
  51.                 return AP4_ERROR_INVALID_FORMAT;
  52.            
  53.             while (AP4_SUCCEEDED(moov[streamid]->DeleteChild(AP4_ATOM_TYPE_PSSH, 0)));
  54.  
  55.             // Remove tracks we cannot handle
  56.             for (AP4_List<AP4_TrakAtom>::Item *item(moov[streamid]->GetTrakAtoms().FirstItem()); item;)
  57.                 if (!item->GetData()->FindChild("mdia/minf/stbl"))
  58.                     moov[streamid]->GetTrakAtoms().Remove(item);
  59.                 else
  60.                     item = item->GetNext();
  61.             track_count += moov[streamid]->GetTrakAtoms().ItemCount();
  62.         }
  63.  
  64.         // initialize the processor
  65.         if (AP4_FAILED(result = Initialize(top_level, *input[0])))
  66.             return result;
  67.  
  68.         // process the tracks if we have a moov atom
  69.         m_TrackData.SetItemCount(track_count);
  70.         m_StreamData.SetItemCount(input.ItemCount());
  71.    
  72.         //NormalizeTREX(mvex, 0, m_TrackCounts[0], m_TrackCounts[1]);
  73.         AP4_Cardinal internal_index(0);
  74.         AP4_ContainerAtom *mvex_base(0);
  75.         AP4_List<AP4_TrakAtom>::Item *item = NULL;
  76.  
  77.         for (AP4_Size streamid(0); streamid < input.ItemCount(); ++streamid)
  78.         {
  79.             m_StreamData[streamid].trackStart = internal_index;
  80.             m_StreamData[streamid].stream = input[streamid];
  81.             if (streamid)
  82.                 moov[0]->AddTrakAtoms(moov[streamid]->GetTrakAtoms(), item);
  83.             else
  84.                 item = moov[streamid]->GetTrakAtoms().FirstItem();
  85.  
  86.             for (; item; item = item->GetNext())
  87.             {
  88.                 PERTRACK &track_data(m_TrackData[internal_index]);
  89.                 track_data.original_id = item->GetData()->GetId();
  90.                 item->GetData()->SetId(track_data.new_id = internal_index + 1);
  91.  
  92.         if (AP4_MdhdAtom* mdhd = AP4_DYNAMIC_CAST(AP4_MdhdAtom, item->GetData()->FindChild("mdia/mdhd")))
  93.           track_data.timescale = mdhd->GetTimeScale();
  94.         else
  95.           track_data.timescale = 1;
  96.        
  97.         AP4_ContainerAtom *mvex = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moov[streamid]->GetChild(AP4_ATOM_TYPE_MVEX, 0));
  98.                 if (!mvex)
  99.                     return AP4_ERROR_INVALID_FORMAT;
  100.                
  101.                 if (!item->GetData()->GetDuration())
  102.                 {
  103.                     AP4_MehdAtom *mehd(AP4_DYNAMIC_CAST(AP4_MehdAtom, mvex->GetChild(AP4_ATOM_TYPE_MEHD, 0)));
  104.                     item->GetData()->SetDuration(mehd? mehd->GetDuration():0);
  105.                 }
  106.                
  107.                 AP4_TrexAtom *trex(NULL);
  108.                 unsigned int index(0);
  109.                 for (; !trex && (trex = AP4_DYNAMIC_CAST(AP4_TrexAtom, mvex->GetChild(AP4_ATOM_TYPE_TREX, index++)));)
  110.                     if(trex->GetTrackId() != track_data.original_id)
  111.                         trex = NULL;
  112.                 if (!trex)
  113.                     return AP4_ERROR_INVALID_FORMAT;
  114.  
  115.                 if (mvex_base)
  116.                 {
  117.                     trex = AP4_DYNAMIC_CAST(AP4_TrexAtom, trex->Clone());
  118.                     mvex_base->AddChild(trex);
  119.                 }
  120.                 else
  121.                     mvex_base = mvex;
  122.                 trex->SetTrackId(track_data.new_id);
  123.  
  124.                 track_data.track_handler = CreateTrackHandler(item->GetData(), trex);
  125.                 track_data.track_handler->ProcessTrack();
  126.                 track_data.streamId = streamid;
  127.                 ++m_StreamData[streamid].trackCount;
  128.                 ++internal_index;
  129.             }
  130.         }
  131.         // We don't need the other moovs anymore.....
  132.         moov.SetItemCount(1);
  133.  
  134.         AP4_MvhdAtom *mvhd(AP4_DYNAMIC_CAST(AP4_MvhdAtom, moov[0]->GetChild(AP4_ATOM_TYPE_MVHD, 0)));
  135.         if (!mvhd->GetDuration())
  136.         {
  137.             AP4_MehdAtom *mehd(AP4_DYNAMIC_CAST(AP4_MehdAtom, mvex_base->GetChild(AP4_ATOM_TYPE_MEHD, 0)));
  138.             mvhd->SetDuration(mehd ? mehd->GetDuration() : 0);
  139.         }
  140.  
  141.         // finalize the processor
  142.         Finalize(top_level);
  143.  
  144.         // calculate the size of all atoms combined
  145.         AP4_UI64 atoms_size = 0;
  146.         top_level.GetChildren().Apply(AP4_AtomSizeAdder(atoms_size));
  147.  
  148.         // write all atoms
  149.         top_level.GetChildren().Apply(AP4_AtomListWriter(output));
  150.         m_MoovAtom = moov[0];
  151.         m_MoovAtom->Detach();
  152.     }
  153.  
  154.     if (partitions & 2)
  155.     {
  156.         // process the fragments, if any
  157.         result = AP4_SUCCESS;
  158.         AP4_Array<AP4_UI64> moof_positions, mdat_positions;
  159.         moof_positions.SetItemCount(input.ItemCount());
  160.         mdat_positions.SetItemCount(input.ItemCount());
  161.  
  162.         for (;;)
  163.         {
  164.             AP4_ContainerAtom *moof = NULL;
  165.             AP4_UI32 track_index(0);
  166.            
  167. #if 0          
  168.       for (AP4_Cardinal streamid(0); streamid < input.ItemCount(); ++streamid)
  169.             {
  170.                 AP4_Atom* atom = NULL;
  171.                 if (AP4_SUCCEEDED(input[streamid]->Tell(stream_offset)) && AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(*input[streamid], atom)))
  172.                 {
  173.                     if (atom->GetType() != AP4_ATOM_TYPE_MOOF)
  174.                         return AP4_ERROR_INVALID_FORMAT;
  175.                    
  176.                     moof_positions[streamid] = stream_offset;
  177.                     mdat_positions[streamid] = stream_offset + atom->GetSize() + +AP4_ATOM_HEADER_SIZE;
  178.                     if (moof)
  179.                     {
  180.                         int index(0);
  181.                         for (; AP4_Atom* child = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom)->GetChild(AP4_ATOM_TYPE_TRAF, index++);)
  182.                             moof->AddChild(child->Clone());
  183.                         delete atom;
  184.                     }
  185.                     else
  186.                         moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
  187.                     NormalizeTRAF(AP4_DYNAMIC_CAST(AP4_ContainerAtom, moof), m_StreamData[streamid].trackStart,
  188.                         m_StreamData[streamid].trackStart + m_StreamData[streamid].trackCount, track_index);
  189.                 }
  190.                 else
  191.                     delete atom;
  192.             }
  193. #else
  194.       double mindts(9999999999.0);
  195.       AP4_Cardinal nextStream(~0);
  196.       for (AP4_Cardinal track(0); track < m_TrackData.ItemCount(); ++track)
  197.         if ((double)m_TrackData[track].dts / m_TrackData[track].timescale  < mindts)
  198.         {
  199.           mindts = (double)m_TrackData[track].dts / m_TrackData[track].timescale;
  200.           nextStream = m_TrackData[track].streamId;
  201.         }
  202.      
  203.       AP4_Atom* atom = NULL;
  204.       if (AP4_SUCCEEDED(result = input[nextStream]->Tell(stream_offset)) && AP4_SUCCEEDED(result = atom_factory.CreateAtomFromStream(*input[nextStream], atom)))
  205.       {
  206.         if (atom->GetType() != AP4_ATOM_TYPE_MOOF)
  207.           return AP4_ERROR_INVALID_FORMAT;
  208.             } else if (atom)
  209.                 return result;
  210.  
  211.       moof_positions[nextStream] = stream_offset;
  212.       mdat_positions[nextStream] = stream_offset + atom->GetSize() + +AP4_ATOM_HEADER_SIZE;
  213.  
  214.       moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
  215.       NormalizeTRAF(AP4_DYNAMIC_CAST(AP4_ContainerAtom, moof), m_StreamData[nextStream].trackStart,
  216.         m_StreamData[nextStream].trackStart + m_StreamData[nextStream].trackCount, track_index);
  217. #endif
  218.             if (!moof)
  219.                 break;
  220.            
  221.             if (AP4_FAILED(result = ProcessFragment(moof, NULL, 0, output, moof_positions, mdat_positions)))
  222.                 return result;
  223.            
  224.             delete moof;
  225.             moof = NULL;
  226.         }
  227.  
  228.         // cleanup
  229.         m_TrackData.Clear();
  230.         m_StreamData.Clear();
  231.     }
  232.  
  233.     return AP4_SUCCESS;
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement