]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / ffmpeg.c
index 4ae194e5e8a65af118260d2ed503fbe385b15c40..d6a243d8db408f04a77a5cc25603832a5583065d 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -298,6 +298,7 @@ typedef struct OutputStream {
 
 /* init terminal so that we can grab keys */
 static struct termios oldtty;
+static int restore_tty;
 #endif
 
 typedef struct OutputFile {
@@ -696,7 +697,7 @@ static void term_exit(void)
 {
     av_log(NULL, AV_LOG_QUIET, "%s", "");
 #if HAVE_TERMIOS_H
-    if(!run_as_daemon)
+    if(restore_tty)
         tcsetattr (0, TCSANOW, &oldtty);
 #endif
 }
@@ -718,8 +719,9 @@ static void term_init(void)
     if(!run_as_daemon){
     struct termios tty;
 
-    tcgetattr (0, &tty);
+    if (tcgetattr (0, &tty) == 0) {
     oldtty = tty;
+    restore_tty = 1;
     atexit(term_exit);
 
     tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
@@ -732,6 +734,7 @@ static void term_init(void)
     tty.c_cc[VTIME] = 0;
 
     tcsetattr (0, TCSANOW, &tty);
+    }
     signal(SIGQUIT, sigterm_handler); /* Quit (POSIX).  */
     }
 #endif
@@ -984,6 +987,19 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
     AVCodecContext          *avctx = ost->st->codec;
     int ret;
 
+    /*
+     * Audio encoders may split the packets --  #frames in != #packets out.
+     * But there is no reordering, so we can limit the number of output packets
+     * by simply dropping them here.
+     * Counting encoded video frames needs to be done separately because of
+     * reordering, see do_video_out()
+     */
+    if (!(avctx->codec_type == AVMEDIA_TYPE_VIDEO && avctx->codec)) {
+        if (ost->frame_number >= ost->max_frames)
+            return;
+        ost->frame_number++;
+    }
+
     while (bsfc) {
         AVPacket new_pkt = *pkt;
         int a = av_bitstream_filter_filter(bsfc, avctx, NULL,
@@ -1011,7 +1027,6 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
         print_error("av_interleaved_write_frame()", ret);
         exit_program(1);
     }
-    ost->frame_number++;
 }
 
 static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_t size)
@@ -1062,6 +1077,8 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost,
         exit_program(1);
     }
 
+    ret = pkt.size;
+
     if (got_packet) {
         pkt.stream_index = ost->index;
         if (pkt.pts != AV_NOPTS_VALUE)
@@ -1072,12 +1089,14 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost,
         write_frame(s, &pkt, ost);
 
         audio_size += pkt.size;
+
+        av_free_packet(&pkt);
     }
 
     if (frame)
         ost->sync_opts += frame->nb_samples;
 
-    return pkt.size;
+    return ret;
 }
 
 static void do_audio_out(AVFormatContext *s, OutputStream *ost,
@@ -1561,6 +1580,12 @@ static void do_video_out(AVFormatContext *s,
             }
         }
         ost->sync_opts++;
+        /*
+         * For video, number of frames in == number of packets out.
+         * But there may be reordering, so we can't throw away frames on encoder
+         * flush, we need to limit them here, before they go into encoder.
+         */
+        ost->frame_number++;
     }
 }