mirror of https://git.ffmpeg.org/ffmpeg.git
avconv: factor flushing encoders out of output_packet().
This commit is contained in:
parent
630902a1e1
commit
4a4ce2e743
169
avconv.c
169
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) */
|
/* pkt = NULL means EOF (needed to flush decoder buffers) */
|
||||||
static int output_packet(InputStream *ist, int ist_index,
|
static int output_packet(InputStream *ist, int ist_index,
|
||||||
OutputStream *ost_table, int nb_ostreams,
|
OutputStream *ost_table, int nb_ostreams,
|
||||||
|
@ -1713,87 +1800,7 @@ static int output_packet(InputStream *ist, int ist_index,
|
||||||
discard_packet:
|
discard_packet:
|
||||||
if (pkt == NULL) {
|
if (pkt == NULL) {
|
||||||
/* EOF handling */
|
/* EOF handling */
|
||||||
|
flush_encoders(ist_index, ost_table, nb_ostreams);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue