+static void flush_encoders(OutputStream *ost_table, int nb_ostreams)
+{
+ int i, ret;
+
+ for (i = 0; i < nb_ostreams; i++) {
+ OutputStream *ost = &ost_table[i];
+ AVCodecContext *enc = ost->st->codec;
+ AVFormatContext *os = output_files[ost->file_index].ctx;
+
+ if (!ost->encoding_needed)
+ continue;
+
+ 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;
+
+ 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);
+ }
+ }
+}
+