@@ -224,6 +224,25 @@ static int SendFrameAndReceivePacket(AVCodecContext* avctx, AVPacket* pkt, AVFra
224224#endif
225225}
226226
227+ static void WritePacket (AVPacket& pkt)
228+ {
229+ // Write the compressed frame in the media file.
230+ if (pkt.pts != (s64)AV_NOPTS_VALUE)
231+ {
232+ pkt.pts = av_rescale_q (pkt.pts , s_codec_context->time_base , s_stream->time_base );
233+ }
234+ if (pkt.dts != (s64)AV_NOPTS_VALUE)
235+ {
236+ pkt.dts = av_rescale_q (pkt.dts , s_codec_context->time_base , s_stream->time_base );
237+ }
238+ #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56, 60, 100)
239+ if (s_codec_context->coded_frame ->key_frame )
240+ pkt.flags |= AV_PKT_FLAG_KEY;
241+ #endif
242+ pkt.stream_index = s_stream->index ;
243+ av_interleaved_write_frame (s_format_context, &pkt);
244+ }
245+
227246void AVIDump::AddFrame (const u8 * data, int width, int height, int stride, const Frame& state)
228247{
229248 // Assume that the timing is valid, if the savestate id of the new frame
@@ -284,34 +303,39 @@ void AVIDump::AddFrame(const u8* data, int width, int height, int stride, const
284303 s_last_pts = pts_in_ticks;
285304 error = SendFrameAndReceivePacket (s_codec_context, &pkt, s_scaled_frame, &got_packet);
286305 }
287- while (!error && got_packet)
306+ if (!error && got_packet)
288307 {
289- // Write the compressed frame in the media file.
290- if (pkt.pts != (s64)AV_NOPTS_VALUE)
291- {
292- pkt.pts = av_rescale_q (pkt.pts , s_codec_context->time_base , s_stream->time_base );
293- }
294- if (pkt.dts != (s64)AV_NOPTS_VALUE)
295- {
296- pkt.dts = av_rescale_q (pkt.dts , s_codec_context->time_base , s_stream->time_base );
297- }
298- #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56, 60, 100)
299- if (s_codec_context->coded_frame ->key_frame )
300- pkt.flags |= AV_PKT_FLAG_KEY;
301- #endif
302- pkt.stream_index = s_stream->index ;
303- av_interleaved_write_frame (s_format_context, &pkt);
304-
305- // Handle delayed frames.
306- PreparePacket (&pkt);
307- error = ReceivePacket (s_codec_context, &pkt, &got_packet);
308+ WritePacket (pkt);
308309 }
309310 if (error)
310311 ERROR_LOG (VIDEO, " Error while encoding video: %d" , error);
311312}
312313
314+ static void HandleDelayedPackets ()
315+ {
316+ AVPacket pkt;
317+
318+ while (true )
319+ {
320+ PreparePacket (&pkt);
321+ int got_packet;
322+ int error = ReceivePacket (s_codec_context, &pkt, &got_packet);
323+ if (error)
324+ {
325+ ERROR_LOG (VIDEO, " Error while stopping video: %d" , error);
326+ break ;
327+ }
328+
329+ if (!got_packet)
330+ break ;
331+
332+ WritePacket (pkt);
333+ }
334+ }
335+
313336void AVIDump::Stop ()
314337{
338+ HandleDelayedPackets ();
315339 av_write_trailer (s_format_context);
316340 CloseVideoFile ();
317341 s_file_index = 0 ;
0 commit comments