]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
flush audio encoder buffers at the end
[ffmpeg] / ffmpeg.c
index 4023ebf84b9ef99c20fd8d2a8a4fd7e8c6384744..0ff5ddc9e409ac22f6121702cc9114d8316ac1cc 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -225,6 +225,7 @@ static int64_t audio_size = 0;
 static int64_t extra_size = 0;
 static int nb_frames_dup = 0;
 static int nb_frames_drop = 0;
+static int input_sync;
 
 #define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
 
@@ -581,6 +582,7 @@ static void fill_pad_region(AVPicture* img, int height, int width,
     }
 }
 
+static uint8_t *video_buffer= NULL; //FIXME rename, its used for audio too at the end
 
 static void do_video_out(AVFormatContext *s, 
                          AVOutputStream *ost, 
@@ -591,7 +593,6 @@ static void do_video_out(AVFormatContext *s,
     int nb_frames, i, ret;
     AVFrame *final_picture, *formatted_picture;
     AVFrame picture_format_temp, picture_crop_temp;
-    static uint8_t *video_buffer= NULL;
     uint8_t *buf = NULL, *buf1 = NULL;
     AVCodecContext *enc, *dec;
     enum PixelFormat target_pixfmt;
@@ -1205,6 +1206,58 @@ static int output_packet(AVInputStream *ist, int ist_index,
             av_free(buffer_to_free);
         }
  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];
+                
+                if(ost->st->codec.codec_type == CODEC_TYPE_AUDIO && enc->frame_size <=1)
+                    continue;
+                if(ost->st->codec.codec_type == CODEC_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE))
+                    continue;
+
+                if (ost->encoding_needed) {
+                    for(;;) {
+                        AVPacket pkt;
+                        av_init_packet(&pkt);
+                        pkt.stream_index= ost->index;
+                        switch(ost->st->codec.codec_type) {
+                        case CODEC_TYPE_AUDIO:        
+                            ret = avcodec_encode_audio(enc, video_buffer, VIDEO_BUFFER_SIZE, NULL);
+                            audio_size += ret;
+                            pkt.flags |= PKT_FLAG_KEY;
+                            break;
+                        case CODEC_TYPE_VIDEO:
+                            ret = avcodec_encode_video(enc, video_buffer, VIDEO_BUFFER_SIZE, NULL);
+                            video_size += ret;
+                            if(enc->coded_frame && enc->coded_frame->key_frame)
+                                pkt.flags |= 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= video_buffer;
+                        pkt.size= ret;
+                        if(enc->coded_frame)
+                            pkt.pts= enc->coded_frame->pts;
+                        av_interleaved_write_frame(os, &pkt);
+                    }
+                }
+            }
+        }
+    }
     return 0;
  fail_decode:
     return -1;
@@ -1655,16 +1708,20 @@ static int av_encode(AVFormatContext **output_files,
         /* select the stream that we must read now by looking at the
            smallest output pts */
         file_index = -1;
-        pts_min = 1e10;
+        pts_min = 1e100;
         for(i=0;i<nb_ostreams;i++) {
             double pts;
             ost = ost_table[i];
             os = output_files[ost->file_index];
             ist = ist_table[ost->source_index];
-            if(ost->st->codec.codec_type == CODEC_TYPE_VIDEO)
-                pts = (double)ost->sync_opts * ost->st->codec.frame_rate_base / ost->st->codec.frame_rate;
-            else
-                pts = (double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den;
+            if (input_sync == 0) {
+                if(ost->st->codec.codec_type == CODEC_TYPE_VIDEO)
+                    pts = (double)ost->sync_opts * ost->st->codec.frame_rate_base / ost->st->codec.frame_rate;
+                else
+                    pts = (double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den;
+            } else {
+                pts = (double)ist->pts;
+            }
             if (!file_table[ist->file_index].eof_reached && 
                 pts < pts_min) {
                 pts_min = pts;
@@ -3034,6 +3091,7 @@ static void opt_output_file(const char *filename)
                 audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
             if (audio_stream_copy) {
                 st->stream_copy = 1;
+               audio_enc->channels = audio_channels;
             } else {
                 codec_id = file_oformat->audio_codec;
                 if (audio_codec_id != CODEC_ID_NONE)
@@ -3041,7 +3099,6 @@ static void opt_output_file(const char *filename)
                 audio_enc->codec_id = codec_id;
                 
                 audio_enc->bit_rate = audio_bit_rate;
-                audio_enc->sample_rate = audio_sample_rate;
                 audio_enc->strict_std_compliance = strict;
                 audio_enc->thread_count = thread_count;
                 /* For audio codecs other than AC3 we limit */
@@ -3051,6 +3108,7 @@ static void opt_output_file(const char *filename)
                 } else
                     audio_enc->channels = audio_channels;
             }
+           audio_enc->sample_rate = audio_sample_rate;
         }
 
         oc->nb_streams = nb_streams;
@@ -3792,6 +3850,7 @@ int main(int argc, char **argv)
     }
     
     if (nb_input_files == 0) {
+        input_sync = 1;
         prepare_grab();
     }