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