flac: Use a local cache for decode_residual()
[ffmpeg.git] / avtools / avconv.c
index 5c36761..8dd11bb 100644 (file)
@@ -359,7 +359,8 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
     }
 }
 
-static void output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
+static void output_packet(OutputFile *of, AVPacket *pkt,
+                          OutputStream *ost, int eof)
 {
     int ret = 0;
 
@@ -367,10 +368,11 @@ static void output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
     if (ost->nb_bitstream_filters) {
         int idx;
 
-        ret = av_bsf_send_packet(ost->bsf_ctx[0], pkt);
+        ret = av_bsf_send_packet(ost->bsf_ctx[0], eof ? NULL : pkt);
         if (ret < 0)
             goto finish;
 
+        eof = 0;
         idx = 1;
         while (idx) {
             /* get a packet from the previous filter up the chain */
@@ -379,19 +381,24 @@ static void output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
                 ret = 0;
                 idx--;
                 continue;
+            } else if (ret == AVERROR_EOF) {
+                eof = 1;
             } else if (ret < 0)
                 goto finish;
 
             /* send it to the next filter down the chain or to the muxer */
             if (idx < ost->nb_bitstream_filters) {
-                ret = av_bsf_send_packet(ost->bsf_ctx[idx], pkt);
+                ret = av_bsf_send_packet(ost->bsf_ctx[idx], eof ? NULL : pkt);
                 if (ret < 0)
                     goto finish;
                 idx++;
-            } else
+                eof = 0;
+            } else if (eof)
+                goto finish;
+            else
                 write_packet(of, pkt, ost);
         }
-    } else
+    } else if (!eof)
         write_packet(of, pkt, ost);
 
 finish:
@@ -444,7 +451,7 @@ static void do_audio_out(OutputFile *of, OutputStream *ost,
         if (ret < 0)
             goto error;
 
-        output_packet(of, &pkt, ost);
+        output_packet(of, &pkt, ost, 0);
     }
 
     return;
@@ -518,7 +525,7 @@ static void do_subtitle_out(OutputFile *of,
             else
                 pkt.pts += 90 * sub->end_display_time;
         }
-        output_packet(of, &pkt, ost);
+        output_packet(of, &pkt, ost, 0);
     }
 }
 
@@ -594,7 +601,7 @@ static void do_video_out(OutputFile *of,
         if (ret < 0)
             goto error;
 
-        output_packet(of, &pkt, ost);
+        output_packet(of, &pkt, ost, 0);
         *frame_size = pkt.size;
 
         /* if two pass, output log */
@@ -1082,11 +1089,11 @@ static void flush_encoders(void)
                 if (ost->logfile && enc->stats_out) {
                     fprintf(ost->logfile, "%s", enc->stats_out);
                 }
+                output_packet(of, &pkt, ost, ret == AVERROR_EOF);
                 if (ret == AVERROR_EOF) {
                     stop_encoding = 1;
                     break;
                 }
-                output_packet(of, &pkt, ost);
             }
 
             if (stop_encoding)
@@ -1118,10 +1125,16 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
     InputFile   *f = input_files [ist->file_index];
     int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
     int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->mux_timebase);
-    AVPacket opkt;
+    AVPacket opkt = { 0 };
 
     av_init_packet(&opkt);
 
+    // EOF: flush output bitstream filters.
+    if (!pkt) {
+        output_packet(of, &opkt, ost, 1);
+        return;
+    }
+
     if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) &&
         !ost->copy_initial_nonkeyframes)
         return;
@@ -1179,7 +1192,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
         opkt.size = pkt->size;
     }
 
-    output_packet(of, &opkt, ost);
+    output_packet(of, &opkt, ost, 0);
 }
 
 static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
@@ -1583,7 +1596,7 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e
             break;
         }
     }
-    for (i = 0; pkt && i < nb_output_streams; i++) {
+    for (i = 0; i < nb_output_streams; i++) {
         OutputStream *ost = output_streams[i];
 
         if (!check_output_constraints(ist, ost) || ost->encoding_needed)
@@ -1704,6 +1717,17 @@ static int init_input_stream(int ist_index, char *error, int error_len)
 
         if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0))
             av_dict_set(&ist->decoder_opts, "threads", "auto", 0);
+
+        ret = hw_device_setup_for_decode(ist);
+        if (ret < 0) {
+            char errbuf[128];
+            av_strerror(ret, errbuf, sizeof(errbuf));
+            snprintf(error, error_len, "Device setup failed for "
+                     "decoder on input stream #%d:%d : %s",
+                     ist->file_index, ist->st->index, errbuf);
+            return ret;
+        }
+
         if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) {
             char errbuf[128];
             if (ret == AVERROR_EXPERIMENTAL)
@@ -2046,6 +2070,16 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
             ost->enc_ctx->hw_frames_ctx = av_buffer_ref(ost->filter->filter->inputs[0]->hw_frames_ctx);
             if (!ost->enc_ctx->hw_frames_ctx)
                 return AVERROR(ENOMEM);
+        } else {
+            ret = hw_device_setup_for_encode(ost);
+            if (ret < 0) {
+                char errbuf[128];
+                av_strerror(ret, errbuf, sizeof(errbuf));
+                snprintf(error, error_len, "Device setup failed for "
+                         "encoder on output stream #%d:%d : %s",
+                     ost->file_index, ost->index, errbuf);
+                return ret;
+            }
         }
 
         if ((ret = avcodec_open2(ost->enc_ctx, codec, &ost->encoder_opts)) < 0) {
@@ -2751,7 +2785,7 @@ static int transcode(void)
     /* at the end of stream, we must flush the decoder buffers */
     for (i = 0; i < nb_input_streams; i++) {
         ist = input_streams[i];
-        if (!input_files[ist->file_index]->eof_reached && ist->decoding_needed) {
+        if (!input_files[ist->file_index]->eof_reached) {
             process_input_packet(ist, NULL, 0);
         }
     }
@@ -2795,6 +2829,7 @@ static int transcode(void)
     }
 
     av_buffer_unref(&hw_device_ctx);
+    hw_device_free_all();
 
     /* finished ! */
     ret = 0;