[FFmpeg-cvslog] ffmpeg: factor flushing encoders out of output_packet().

Anton Khirnov git at videolan.org
Tue Aug 30 18:15:05 CEST 2011


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Tue Aug 30 15:55:25 2011 +0200| [a16f1afb1125b3fbb76f72438ecc6f1f3fe090fc] | committer: Michael Niedermayer

ffmpeg: factor flushing encoders out of output_packet().

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a16f1afb1125b3fbb76f72438ecc6f1f3fe090fc
---

 ffmpeg.c |  169 ++++++++++++++++++++++++++++++++------------------------------
 1 files changed, 88 insertions(+), 81 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index ad641bb..b32d517 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -1445,6 +1445,93 @@ static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, 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,
@@ -1779,87 +1866,7 @@ static int output_packet(InputStream *ist, int ist_index,
  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;



More information about the ffmpeg-cvslog mailing list