Determines a seek target for all valid, seekable key frames; seek targets are expressed in presentation timestamp (PTS) as used in the libavformat native index.
Implements Impala::Core::Stream::Lavc::VideoAccessStrategy. Definition at line 158 of file StrategyUsingNativeIndex.h. References Impala::Core::Stream::Lavc::VideoIndex::AddFrame(), Impala::Core::Stream::Lavc::VideoAccessStrategy::CurrentFrameMatchesFrame(), Impala::Core::Stream::Lavc::VideoAccessObject::CurrentFrameToRgb(), Impala::Core::Stream::Lavc::VideoAccessObject::CurrentHash(), Impala::Core::Stream::Lavc::VideoAccessStrategy::DecodeNextFrame(), Impala::Core::Stream::Lavc::VideoAccessStrategy::DecodeNextValidFrame(), Impala::Core::Stream::Lavc::VideoAccessStrategy::FrameIsKey(), Impala::Core::Stream::Lavc::VideoAccessStrategy::FrameIsValid(), Impala::Core::Stream::Lavc::VideoAccessObject::FrameType(), ILOG_DEBUG, ILOG_ERROR, ILOG_WARN, Impala::Core::Stream::Lavc::VideoAccessStrategy::mVao, Impala::Core::Stream::Lavc::VideoAccessObject::NativeIndexEntries(), Impala::Core::Stream::Lavc::VideoAccessObject::NativeIndexSize(), and Impala::Core::Stream::Lavc::VideoAccessObject::Seek(). 00159 { 00160 const AVIndexEntry* const idx = mVao->NativeIndexEntries(); 00161 const int nativeIndexSize = mVao->NativeIndexSize(); 00162 VideoIndex* videoIndex = new VideoIndex(); 00163 00164 //const static int MAX_SEEKABLE_FRAME_DISTANCE = 15; 00165 //int currentDistance = 0; 00166 int prevSeekableFrame = -1; 00167 for (int frameNr = 0; frameNr < nativeIndexSize; frameNr++) 00168 //int debugMax = 50; 00169 //for (int frameNr = 0; frameNr < debugMax; frameNr++) 00170 { 00171 // note that currently the external index may be bypassed when 00172 // navigating to a frame; but for PTS this may not work because 00173 // certain invalid frames will not be 'seen' by sequential reads, 00174 // while certain valid frames will not be recognized (matched) when 00175 // reading sequentially. And so I have to introduce restrictions for 00176 // reading sequentially i.e. in ~Lavc. 00177 00178 00179 if (!FrameIsValid(frameNr)) 00180 { 00181 // if invalidity followed from flags or size in the index, 00182 // I assume that the frame will not be 'seen' during sequential 00183 // reads?! 00184 00185 // if invalidity followed from reading a bad frame, the frame 00186 // *will* be 'seen' by sequential reads. 00187 00188 if (idx[frameNr].size > 0 && 00189 ((idx[frameNr].flags | AVINDEX_KEYFRAME) == AVINDEX_KEYFRAME)) 00190 { 00191 bool lookForKeyFrame = (idx[frameNr].flags == AVINDEX_KEYFRAME); 00192 //bool foundFrame = 00193 //mVao->DecodeNextValidFrame(lookForKeyFrame, 0); 00194 bool isValidFrame; 00195 bool isKeyFrame; 00196 int res = DecodeNextFrame(&isValidFrame, &isKeyFrame, 0); 00197 //if (foundFrame) 00198 if (res >= 0 && isValidFrame) 00199 { 00200 String hash = mVao->CurrentHash(); 00201 ILOG_WARN("Unexpectedly able to successfully read a (" << 00202 mVao->FrameType() << ") frame for (invalid) frame " << 00203 frameNr << ", having hash value " << hash << 00204 "; frame data will be ignored"); 00205 } 00206 00207 //currentDistance++; 00208 } 00209 00210 continue; 00211 } 00212 00213 const UInt64& pts = idx[frameNr].timestamp; 00214 bool isKeyFrame = FrameIsKey(frameNr); 00215 if (isKeyFrame) 00216 { 00217 if (!mVao->Seek(pts, AVSEEK_FLAG_ANY)) 00218 { 00219 ILOG_ERROR("Failed on PTS based seek for frame: " << 00220 frameNr << (isKeyFrame ? " (is key frame)" : "")); 00221 return 0; 00222 } 00223 } 00224 00225 // read next frame 00226 //bool lookForKeyFrame = false; 00227 //PacketTrace trace(10); 00228 //bool foundFrame = 00229 // mVao->DecodeNextValidFrame(lookForKeyFrame, 0); 00230 //bool isValidFrame; 00232 //int res = mVao->DecodeNextFrame(&isValidFrame, &isKeyFrame); 00233 //if (res < 0 || !isValidFrame) 00234 //{ 00235 // ILOG_ERROR("Unexpectedly unable to successfully read frame: " << 00236 // frameNr); 00237 // return 0; 00238 //} 00239 //mVao->CurrentFrameToRgb(); 00240 if (!DecodeNextValidFrame(isKeyFrame, 0)) 00241 { 00242 ILOG_ERROR("Failed to read valid frame " << frameNr); 00243 return 0; 00244 } 00245 00246 mVao->CurrentFrameToRgb(); 00247 00248 // if not a key frame, check whether the frame is reproducable 00249 // using sequential reading from previous seekable frame 00250 //if (!mScanner.FrameIsKey(frameNr)) 00251 if (!isKeyFrame) 00252 { 00253 if (prevSeekableFrame >= 0) 00254 { 00255 // kijk of dit frame via seq read vanaf laatste seek reprodbr is 00256 //if (foundFrame) 00257 00258 if (CurrentFrameMatchesFrame(frameNr, 0)) 00259 { 00260 //currentDistance++; 00261 continue; 00262 } 00263 else 00264 { 00265 ILOG_ERROR("Non-reproducable frame: " << frameNr << 00266 ", current hash value is " << mVao->CurrentHash()); 00267 return 0; 00268 } 00269 } 00270 } 00271 00272 if (!CurrentFrameMatchesFrame(frameNr, 0)) 00273 { 00274 ILOG_ERROR("Non-reproducable key frame: " << frameNr << 00275 ", current hash value is " << mVao->CurrentHash()); 00276 return 0; 00277 } 00278 00279 // add an entry to the external index for this key frame 00280 videoIndex->AddFrame(frameNr, true, pts); 00281 ILOG_DEBUG("Indexed frame: " << frameNr << " " << 00282 frameNr << " " << true << " " << pts); 00283 prevSeekableFrame = frameNr; 00284 //currentDistance = 0; 00285 } 00286 00287 return videoIndex; 00288 }
Here is the call graph for this function:
|