00001 #ifndef Impala_Core_Stream_Lavc_VideoIndex_h
00002 #define Impala_Core_Stream_Lavc_VideoIndex_h
00003
00004 #include "Core/Table/TableTem.h"
00005
00006 namespace Impala
00007 {
00008 namespace Core
00009 {
00010 namespace Stream
00011 {
00012 namespace Lavc
00013 {
00014
00015 class VideoIndex
00016 {
00017
00018 private:
00019
00020
00021 typedef Table::TableTem< Column::ColumnTem<Int32>,
00022 Column::ColumnTem<Int32>,
00023 Column::ColumnTem<UInt64> > SeekTable;
00024
00025 public:
00026
00027 VideoIndex() : mSeekTable(1000)
00028 {
00029 }
00030
00034 void
00035 AddFrame(int frameNr, bool isSeekable, const UInt64& seekPosition)
00036 {
00037 mSeekTable.Add(frameNr, (isSeekable ? 1 : 0), seekPosition);
00038 }
00039
00040 int
00041 NrOfEntries() const
00042 {
00043 return mSeekTable.Size();
00044 }
00045
00046 UInt64
00047 SeekTarget(int frameNr) const
00048 {
00049 const int entryNr = EntryNr(frameNr);
00050 if (entryNr >= 0)
00051 return mSeekTable.Get3(entryNr);
00052
00053 ILOG_ERROR("Unknown frame nr: " << frameNr);
00054 return -1;
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 bool
00070 SetNotSeekable(int frameNr)
00071 {
00072 const int entryNr = EntryNr(frameNr);
00073 if (entryNr < 0)
00074 {
00075 ILOG_ERROR("Unknown frame nr: " << frameNr);
00076 return false;
00077 }
00078
00079 mSeekTable.Set2(entryNr, 0);
00080 return true;
00081 }
00082
00083 int
00084 NrOfSeekableFrames() const
00085 {
00086 int nrOfSeekableFrames = 0;
00087 const int nrOfEntries = NrOfEntries();
00088 for (int i = 0; i < nrOfEntries; i++)
00089 if (mSeekTable.Get2(i) != 0)
00090 nrOfSeekableFrames++;
00091 return nrOfSeekableFrames;
00092 }
00093
00100 int
00101 MaxNonTargetFrameReads() const
00102 {
00103 int maxReads = 0;
00104 int prevSeekableFrameNr = -1;
00105 const int nrOfEntries = NrOfEntries();
00106 for (int i = 0; i < nrOfEntries; i++)
00107 {
00108 if (mSeekTable.Get2(i) != 0)
00109 {
00110 int frameNr = mSeekTable.Get1(i);
00111 int curReads = (frameNr - 1) - prevSeekableFrameNr;
00112 maxReads = Impala::Max(maxReads, curReads);
00113 prevSeekableFrameNr = frameNr;
00114 }
00115 }
00116 const int trailingNonSeekableFrames =
00117 (nrOfEntries - 1) - prevSeekableFrameNr;
00118 maxReads = Impala::Max(maxReads, trailingNonSeekableFrames);
00119 return maxReads;
00120 }
00121
00122 bool
00123 IsSeekable(int frameNr) const
00124 {
00125 const int entryNr = EntryNr(frameNr);
00126 if (entryNr < 0)
00127 return false;
00128 return mSeekTable.Get2(entryNr) != 0;
00129 }
00130
00131 void
00132 GetSeekInfo(int frameNr, int* seekableFrameNr, UInt64* seekableFramePos) const
00133 {
00134 const int nrOfEntries = NrOfEntries();
00135 for (int i = nrOfEntries; i > 0; )
00136 {
00137 i--;
00138 if (mSeekTable.Get1(i) > frameNr)
00139 continue;
00140 const bool seekable = mSeekTable.Get2(i) != 0;
00141 if (!seekable)
00142 continue;
00143
00144 *seekableFrameNr = mSeekTable.Get1(i);
00145 *seekableFramePos = mSeekTable.Get3(i);
00146 return;
00147 }
00148
00149 ILOG_WARN("No seek info for frame " << frameNr);
00150 *seekableFrameNr = -1;
00151 *seekableFramePos = -1;
00152 }
00153
00154
00155 private:
00156
00157 int
00158 EntryNr(int frameNr) const
00159 {
00160 const int maxIndex = Impala::Min(NrOfEntries() - 1, frameNr);
00161 for (int i = 0; i <= maxIndex; i++)
00162 if (mSeekTable.Get1(i) == frameNr)
00163 return i;
00164 return -1;
00165 }
00166
00167
00168 SeekTable mSeekTable;
00169
00170 ILOG_VAR_DECL;
00171
00172 };
00173
00174 ILOG_VAR_INIT(VideoIndex, Impala.Core.Stream.Lavc);
00175
00176 }}}}
00177
00178 #endif