avconv: factor flushing encoders out of output_packet().
authorAnton Khirnov <anton@khirnov.net>
Thu, 18 Aug 2011 06:55:29 +0000 (08:55 +0200)
committerAnton Khirnov <anton@khirnov.net>
Thu, 18 Aug 2011 09:22:12 +0000 (11:22 +0200)
avconv.c

index fb0871743b70416b0ddf6c438eb42fc3c3a07bb1..432f5d619716be30b61a8993637753abe624cb5e 100644 (file)
--- a/avconv.c
+++ b/avconv.c
@@ -1396,6 +1396,93 @@ static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_
     memset(buf, fill_char, size);
 }
 
     memset(buf, fill_char, size);
 }
 
+static void flush_encoders(int ist_index, OutputStream *ost_table, int nb_ostreams)
+{
+    int i, ret;
+
+    for (i = 0; i < nb_ostreams; i++) {
+        OutputStream *ost = &ost_table[i];
+
+        if (ost->source_index == ist_index) {
+            AVCodecContext *enc = ost->st->codec;
+            AVFormatContext *os = output_files[ost->file_index].ctx;
+
+            if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1)
+                continue;
+            if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE))
+                continue;
+
+            if (ost->encoding_needed) {
+                for(;;) {
+                    AVPacket pkt;
+                    int fifo_bytes;
+                    av_init_packet(&pkt);
+                    pkt.stream_index= ost->index;
+
+                    switch (ost->st->codec->codec_type) {
+                    case AVMEDIA_TYPE_AUDIO:
+                        fifo_bytes = av_fifo_size(ost->fifo);
+                        ret = 0;
+                        /* encode any samples remaining in fifo */
+                        if (fifo_bytes > 0) {
+                            int osize = av_get_bytes_per_sample(enc->sample_fmt);
+                            int fs_tmp = enc->frame_size;
+
+                            av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL);
+                            if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
+                                enc->frame_size = fifo_bytes / (osize * enc->channels);
+                            } else { /* pad */
+                                int frame_bytes = enc->frame_size*osize*enc->channels;
+                                if (allocated_audio_buf_size < frame_bytes)
+                                    exit_program(1);
+                                generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes);
+                            }
+
+                            ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf);
+                            pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den,
+                                                      ost->st->time_base.num, enc->sample_rate);
+                            enc->frame_size = fs_tmp;
+                        }
+                        if (ret <= 0) {
+                            ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL);
+                        }
+                        if (ret < 0) {
+                            fprintf(stderr, "Audio encoding failed\n");
+                            exit_program(1);
+                        }
+                        audio_size += ret;
+                        pkt.flags |= AV_PKT_FLAG_KEY;
+                        break;
+                    case AVMEDIA_TYPE_VIDEO:
+                        ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL);
+                        if (ret < 0) {
+                            fprintf(stderr, "Video encoding failed\n");
+                            exit_program(1);
+                        }
+                        video_size += ret;
+                        if(enc->coded_frame && enc->coded_frame->key_frame)
+                            pkt.flags |= AV_PKT_FLAG_KEY;
+                        if (ost->logfile && enc->stats_out) {
+                            fprintf(ost->logfile, "%s", enc->stats_out);
+                        }
+                        break;
+                    default:
+                        ret=-1;
+                    }
+
+                    if (ret <= 0)
+                        break;
+                    pkt.data = bit_buffer;
+                    pkt.size = ret;
+                    if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
+                        pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
+                    write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters);
+                }
+            }
+        }
+    }
+}
+
 /* pkt = NULL means EOF (needed to flush decoder buffers) */
 static int output_packet(InputStream *ist, int ist_index,
                          OutputStream *ost_table, int nb_ostreams,
 /* pkt = NULL means EOF (needed to flush decoder buffers) */
 static int output_packet(InputStream *ist, int ist_index,
                          OutputStream *ost_table, int nb_ostreams,
@@ -1713,87 +1800,7 @@ static int output_packet(InputStream *ist, int ist_index,
  discard_packet:
     if (pkt == NULL) {
         /* EOF handling */
  discard_packet:
     if (pkt == NULL) {
         /* EOF handling */
-
-        for(i=0;i<nb_ostreams;i++) {
-            ost = &ost_table[i];
-            if (ost->source_index == ist_index) {
-                AVCodecContext *enc= ost->st->codec;
-                os = output_files[ost->file_index].ctx;
-
-                if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1)
-                    continue;
-                if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE))
-                    continue;
-
-                if (ost->encoding_needed) {
-                    for(;;) {
-                        AVPacket pkt;
-                        int fifo_bytes;
-                        av_init_packet(&pkt);
-                        pkt.stream_index= ost->index;
-
-                        switch(ost->st->codec->codec_type) {
-                        case AVMEDIA_TYPE_AUDIO:
-                            fifo_bytes = av_fifo_size(ost->fifo);
-                            ret = 0;
-                            /* encode any samples remaining in fifo */
-                            if (fifo_bytes > 0) {
-                                int osize = av_get_bytes_per_sample(enc->sample_fmt);
-                                int fs_tmp = enc->frame_size;
-
-                                av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL);
-                                if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
-                                    enc->frame_size = fifo_bytes / (osize * enc->channels);
-                                } else { /* pad */
-                                    int frame_bytes = enc->frame_size*osize*enc->channels;
-                                    if (allocated_audio_buf_size < frame_bytes)
-                                        exit_program(1);
-                                    generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes);
-                                }
-
-                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf);
-                                pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den,
-                                                          ost->st->time_base.num, enc->sample_rate);
-                                enc->frame_size = fs_tmp;
-                            }
-                            if(ret <= 0) {
-                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL);
-                            }
-                            if (ret < 0) {
-                                fprintf(stderr, "Audio encoding failed\n");
-                                exit_program(1);
-                            }
-                            audio_size += ret;
-                            pkt.flags |= AV_PKT_FLAG_KEY;
-                            break;
-                        case AVMEDIA_TYPE_VIDEO:
-                            ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL);
-                            if (ret < 0) {
-                                fprintf(stderr, "Video encoding failed\n");
-                                exit_program(1);
-                            }
-                            video_size += ret;
-                            if(enc->coded_frame && enc->coded_frame->key_frame)
-                                pkt.flags |= AV_PKT_FLAG_KEY;
-                            if (ost->logfile && enc->stats_out) {
-                                fprintf(ost->logfile, "%s", enc->stats_out);
-                            }
-                            break;
-                        default:
-                            ret=-1;
-                        }
-
-                        if(ret<=0)
-                            break;
-                        pkt.data= bit_buffer;
-                        pkt.size= ret;
-                        if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
-                            pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
-                        write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters);
-                    }
-                }
-            }
-        }
+        flush_encoders(ist_index, ost_table, nb_ostreams);
     }
 
     return 0;
     }
 
     return 0;