aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-07-16 20:20:25 -0700
committerChris Robinson <[email protected]>2019-07-16 20:20:25 -0700
commit2b21a08f89bbf5ccff935ada6b5bbe42501f18c4 (patch)
treeb86b94cebd4e8223a5f0c8de9019cbb2893e61b2 /examples
parent101e6412887c539b7409fdb016012900c18f5daf (diff)
Receive video frames in a loop
Diffstat (limited to 'examples')
-rw-r--r--examples/alffplay.cpp90
1 files changed, 50 insertions, 40 deletions
diff --git a/examples/alffplay.cpp b/examples/alffplay.cpp
index ccdfd51f..466c4576 100644
--- a/examples/alffplay.cpp
+++ b/examples/alffplay.cpp
@@ -552,19 +552,21 @@ int AudioState::decodeFrame()
AVPacket *lastpkt{};
while((lastpkt=mPackets.getPacket(lock)) != nullptr)
{
- int ret{avcodec_send_packet(mCodecCtx.get(), lastpkt)};
+ const int ret{avcodec_send_packet(mCodecCtx.get(), lastpkt)};
if(ret == AVERROR(EAGAIN)) break;
+ if(ret < 0)
+ std::cerr<< "Failed to send packet: "<<ret <<std::endl;
mPackets.pop();
}
if(!lastpkt)
avcodec_send_packet(mCodecCtx.get(), nullptr);
}
- int ret{avcodec_receive_frame(mCodecCtx.get(), mDecodedFrame.get())};
+ const int ret{avcodec_receive_frame(mCodecCtx.get(), mDecodedFrame.get())};
if(ret == AVERROR_EOF) break;
if(ret < 0)
{
- std::cerr<< "Failed to decode frame: "<<ret <<std::endl;
- return 0;
+ std::cerr<< "Failed to receive frame: "<<ret <<std::endl;
+ break;
}
if(mDecodedFrame->nb_samples <= 0)
@@ -1179,7 +1181,7 @@ void VideoState::updateVideo(SDL_Window *screen, SDL_Renderer *renderer)
mFinalUpdate = true;
mPictQRead.store(read_idx, std::memory_order_release);
std::unique_lock<std::mutex>{mPictQMutex}.unlock();
- mPictQCond.notify_all();
+ mPictQCond.notify_one();
return;
}
@@ -1187,7 +1189,7 @@ void VideoState::updateVideo(SDL_Window *screen, SDL_Renderer *renderer)
{
mPictQRead.store(read_idx, std::memory_order_release);
std::unique_lock<std::mutex>{mPictQMutex}.unlock();
- mPictQCond.notify_all();
+ mPictQCond.notify_one();
/* allocate or resize the buffer! */
bool fmt_updated{false};
@@ -1287,7 +1289,7 @@ void VideoState::updateVideo(SDL_Window *screen, SDL_Renderer *renderer)
{
mFinalUpdate = true;
std::unique_lock<std::mutex>{mPictQMutex}.unlock();
- mPictQCond.notify_all();
+ mPictQCond.notify_one();
}
}
}
@@ -1305,57 +1307,65 @@ int VideoState::handler()
while(!mMovie.mQuit.load(std::memory_order_relaxed))
{
- size_t write_idx{mPictQWrite.load(std::memory_order_relaxed)};
- Picture *vp{&mPictQ[write_idx]};
-
{
std::unique_lock<std::mutex> lock{mPackets.getMutex()};
AVPacket *lastpkt{};
while((lastpkt=mPackets.getPacket(lock)) != nullptr)
{
- int ret{avcodec_send_packet(mCodecCtx.get(), lastpkt)};
+ const int ret{avcodec_send_packet(mCodecCtx.get(), lastpkt)};
if(ret == AVERROR(EAGAIN)) break;
+ if(ret < 0)
+ std::cerr<< "Failed to send packet: "<<ret <<std::endl;
mPackets.pop();
}
if(!lastpkt)
avcodec_send_packet(mCodecCtx.get(), nullptr);
}
- /* Decode video frame */
- AVFrame *decoded_frame{vp->mFrame.get()};
- int ret{avcodec_receive_frame(mCodecCtx.get(), decoded_frame)};
- if(ret == AVERROR_EOF) break;
- if(ret < 0)
+
+ while(!mMovie.mQuit.load(std::memory_order_relaxed))
{
- std::cerr<< "Failed to decode frame: "<<ret <<std::endl;
- continue;
- }
+ size_t write_idx{mPictQWrite.load(std::memory_order_relaxed)};
+ Picture *vp{&mPictQ[write_idx]};
+
+ /* Decode video frame. */
+ AVFrame *decoded_frame{vp->mFrame.get()};
+ const int ret{avcodec_receive_frame(mCodecCtx.get(), decoded_frame)};
+ if(ret == AVERROR_EOF) goto finished;
+ if(ret == AVERROR(EAGAIN)) break;
+ if(ret < 0)
+ {
+ std::cerr<< "Failed to receive frame: "<<ret <<std::endl;
+ break;
+ }
- /* Get the PTS for this frame. */
- if(decoded_frame->best_effort_timestamp != AV_NOPTS_VALUE)
- mCurrentPts = std::chrono::duration_cast<nanoseconds>(
- seconds_d64{av_q2d(mStream->time_base)*decoded_frame->best_effort_timestamp});
- vp->mPts = mCurrentPts;
+ /* Get the PTS for this frame. */
+ if(decoded_frame->best_effort_timestamp != AV_NOPTS_VALUE)
+ mCurrentPts = std::chrono::duration_cast<nanoseconds>(
+ seconds_d64{av_q2d(mStream->time_base)*decoded_frame->best_effort_timestamp});
+ vp->mPts = mCurrentPts;
- /* Update the video clock to the next expected PTS. */
- auto frame_delay = av_q2d(mCodecCtx->time_base);
- frame_delay += decoded_frame->repeat_pict * (frame_delay * 0.5);
- mCurrentPts += std::chrono::duration_cast<nanoseconds>(seconds_d64{frame_delay});
+ /* Update the video clock to the next expected PTS. */
+ auto frame_delay = av_q2d(mCodecCtx->time_base);
+ frame_delay += decoded_frame->repeat_pict * (frame_delay * 0.5);
+ mCurrentPts += std::chrono::duration_cast<nanoseconds>(seconds_d64{frame_delay});
- /* Put the frame in the queue to be loaded into a texture and displayed
- * by the rendering thread.
- */
- write_idx = (write_idx+1)%mPictQ.size();
- mPictQWrite.store(write_idx, std::memory_order_release);
+ /* Put the frame in the queue to be loaded into a texture and
+ * displayed by the rendering thread.
+ */
+ write_idx = (write_idx+1)%mPictQ.size();
+ mPictQWrite.store(write_idx, std::memory_order_release);
- if(write_idx == mPictQRead.load(std::memory_order_acquire))
- {
- /* Wait until we have space for a new pic */
- std::unique_lock<std::mutex> lock{mPictQMutex};
- while(write_idx == mPictQRead.load(std::memory_order_acquire) &&
- !mMovie.mQuit.load(std::memory_order_relaxed))
- mPictQCond.wait(lock);
+ if(write_idx == mPictQRead.load(std::memory_order_acquire))
+ {
+ /* Wait until we have space for a new pic */
+ std::unique_lock<std::mutex> lock{mPictQMutex};
+ while(write_idx == mPictQRead.load(std::memory_order_acquire) &&
+ !mMovie.mQuit.load(std::memory_order_relaxed))
+ mPictQCond.wait(lock);
+ }
}
}
+finished:
mEOS = true;
std::unique_lock<std::mutex> lock{mPictQMutex};