[gegl] ff-save: flush encoders before closing



commit ca0e753365f9c6ad1ef498df5b9cef59ac9ee182
Author: Øyvind Kolås <pippin gimp org>
Date:   Mon Nov 23 07:16:42 2015 +0100

    ff-save: flush encoders before closing

 operations/external/ff-save.c |   70 ++++++++++++++++++++++++++++++++++------
 1 files changed, 59 insertions(+), 11 deletions(-)
---
diff --git a/operations/external/ff-save.c b/operations/external/ff-save.c
index 3cd841b..79d44af 100644
--- a/operations/external/ff-save.c
+++ b/operations/external/ff-save.c
@@ -424,11 +424,13 @@ write_audio_frame (GeglProperties *o, AVFormatContext * oc, AVStream * st)
         fprintf (stderr, "eeeek unhandled audio format\n");
         break;
     }
-    frame->pts = av_rescale_q (p->next_apts, (AVRational){1, c->sample_rate}, st->time_base);
+    frame->pts = p->next_apts;
     p->next_apts += sample_count;
 
     av_frame_make_writable (frame);
     ret = avcodec_encode_audio2 (c, &pkt, frame, &got_packet);
+
+    av_packet_rescale_ts (&pkt, st->codec->time_base, st->time_base);
     if (ret < 0) {
       fprintf (stderr, "Error encoding audio frame: %s\n", av_err2str (ret));
     }
@@ -815,6 +817,53 @@ process (GeglOperation       *operation,
   return  TRUE;
 }
 
+static void flush_audio (GeglProperties *o)
+{
+  Priv *p = (Priv*)o->user_data;
+
+  int got_packet;
+  do
+  {
+    AVPacket  pkt = { 0 };
+    int ret;
+    got_packet = 0;
+    av_init_packet (&pkt);
+    ret = avcodec_encode_audio2 (p->audio_st->codec, &pkt, NULL, &got_packet);
+    if (ret < 0)
+      break;
+    if (got_packet)
+      {
+        pkt.stream_index = p->audio_st->index;
+        av_packet_rescale_ts (&pkt, p->audio_st->codec->time_base, p->audio_st->time_base);
+        av_interleaved_write_frame (p->oc, &pkt);
+        av_free_packet (&pkt);
+      }
+  } while (got_packet);
+}
+
+static void flush_video (GeglProperties *o)
+{
+  Priv *p = (Priv*)o->user_data;
+  int got_packet = 0;
+  do {
+    AVPacket  pkt = { 0 };
+    int ret;
+    got_packet = 0;
+    av_init_packet (&pkt);
+    ret = avcodec_encode_video2 (p->video_st->codec, &pkt, NULL, &got_packet);
+    if (ret < 0)
+      return;
+      
+     if (got_packet)
+     {
+       pkt.stream_index = p->video_st->index;
+       av_packet_rescale_ts (&pkt, p->video_st->codec->time_base, p->video_st->time_base);
+       av_interleaved_write_frame (p->oc, &pkt);
+       av_free_packet (&pkt);
+     }
+  } while (got_packet);
+}
+
 static void
 finalize (GObject *object)
 {
@@ -822,19 +871,18 @@ finalize (GObject *object)
   if (o->user_data)
     {
       Priv *p = (Priv*)o->user_data;
+      flush_audio (o);
+      flush_video (o);
 
-    if (p->oc)
-      {
-        av_write_trailer (p->oc);
+      av_write_trailer (p->oc);
 
-        if (p->video_st)
-          close_video (p, p->oc, p->video_st);
-        if (p->audio_st)
-          close_audio (p, p->oc, p->audio_st);
+      if (p->video_st)
+        close_video (p, p->oc, p->video_st);
+      if (p->audio_st)
+        close_audio (p, p->oc, p->audio_st);
 
-        avio_closep (&p->oc->pb);
-        avformat_free_context (p->oc);
-      }
+      avio_closep (&p->oc->pb);
+      avformat_free_context (p->oc);
 
       g_free (o->user_data);
       o->user_data = NULL;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]