|
|
|
@ -1528,6 +1528,83 @@ static void flush_encoders(OutputStream *ost_table, int nb_ostreams) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Check whether a packet from ist should be written into ost at this time |
|
|
|
|
*/ |
|
|
|
|
static int check_output_constraints(InputStream *ist, OutputStream *ost) |
|
|
|
|
{ |
|
|
|
|
OutputFile *of = &output_files[ost->file_index]; |
|
|
|
|
int ist_index = ist - input_streams; |
|
|
|
|
|
|
|
|
|
if (ost->source_index != ist_index) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
if (of->start_time && ist->pts < of->start_time) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
if (of->recording_time != INT64_MAX && |
|
|
|
|
av_compare_ts(ist->pts, AV_TIME_BASE_Q, of->recording_time + of->start_time, |
|
|
|
|
(AVRational){1, 1000000}) >= 0) { |
|
|
|
|
ost->is_past_recording_time = 1; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *pkt) |
|
|
|
|
{ |
|
|
|
|
OutputFile *of = &output_files[ost->file_index]; |
|
|
|
|
int64_t ost_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); |
|
|
|
|
AVPacket opkt; |
|
|
|
|
|
|
|
|
|
av_init_packet(&opkt); |
|
|
|
|
|
|
|
|
|
if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && |
|
|
|
|
!ost->copy_initial_nonkeyframes) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
/* force the input stream PTS */ |
|
|
|
|
if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) |
|
|
|
|
audio_size += pkt->size; |
|
|
|
|
else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { |
|
|
|
|
video_size += pkt->size; |
|
|
|
|
ost->sync_opts++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
opkt.stream_index = ost->index; |
|
|
|
|
if (pkt->pts != AV_NOPTS_VALUE) |
|
|
|
|
opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time; |
|
|
|
|
else |
|
|
|
|
opkt.pts = AV_NOPTS_VALUE; |
|
|
|
|
|
|
|
|
|
if (pkt->dts == AV_NOPTS_VALUE) |
|
|
|
|
opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base); |
|
|
|
|
else |
|
|
|
|
opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base); |
|
|
|
|
opkt.dts -= ost_tb_start_time; |
|
|
|
|
|
|
|
|
|
opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base); |
|
|
|
|
opkt.flags = pkt->flags; |
|
|
|
|
|
|
|
|
|
//FIXME remove the following 2 lines they shall be replaced by the bitstream filters
|
|
|
|
|
if( ost->st->codec->codec_id != CODEC_ID_H264 |
|
|
|
|
&& ost->st->codec->codec_id != CODEC_ID_MPEG1VIDEO |
|
|
|
|
&& ost->st->codec->codec_id != CODEC_ID_MPEG2VIDEO |
|
|
|
|
) { |
|
|
|
|
if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) |
|
|
|
|
opkt.destruct = av_destruct_packet; |
|
|
|
|
} else { |
|
|
|
|
opkt.data = pkt->data; |
|
|
|
|
opkt.size = pkt->size; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
write_frame(of->ctx, &opkt, ost->st->codec, ost->bitstream_filters); |
|
|
|
|
ost->st->codec->frame_number++; |
|
|
|
|
ost->frame_number++; |
|
|
|
|
av_free_packet(&opkt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* pkt = NULL means EOF (needed to flush decoder buffers) */ |
|
|
|
|
static int output_packet(InputStream *ist, int ist_index, |
|
|
|
|
OutputStream *ost_table, int nb_ostreams, |
|
|
|
@ -1569,8 +1646,8 @@ static int output_packet(InputStream *ist, int ist_index, |
|
|
|
|
|
|
|
|
|
//while we have more to decode or while the decoder did output something on EOF
|
|
|
|
|
while (avpkt.size > 0 || (!pkt && got_output)) { |
|
|
|
|
uint8_t *data_buf, *decoded_data_buf; |
|
|
|
|
int data_size, decoded_data_size; |
|
|
|
|
uint8_t *decoded_data_buf; |
|
|
|
|
int decoded_data_size; |
|
|
|
|
AVFrame *decoded_frame, *filtered_frame; |
|
|
|
|
handle_eof: |
|
|
|
|
ist->pts= ist->next_pts; |
|
|
|
@ -1584,8 +1661,6 @@ static int output_packet(InputStream *ist, int ist_index, |
|
|
|
|
decoded_frame = filtered_frame = NULL; |
|
|
|
|
decoded_data_buf = NULL; /* fail safe */ |
|
|
|
|
decoded_data_size= 0; |
|
|
|
|
data_buf = avpkt.data; |
|
|
|
|
data_size = avpkt.size; |
|
|
|
|
subtitle_to_free = NULL; |
|
|
|
|
if (ist->decoding_needed) { |
|
|
|
|
switch(ist->st->codec->codec_type) { |
|
|
|
@ -1604,7 +1679,6 @@ static int output_packet(InputStream *ist, int ist_index, |
|
|
|
|
return ret; |
|
|
|
|
avpkt.data += ret; |
|
|
|
|
avpkt.size -= ret; |
|
|
|
|
data_size = ret; |
|
|
|
|
got_output = decoded_data_size > 0; |
|
|
|
|
/* Some bug in mpeg audio decoder gives */ |
|
|
|
|
/* decoded_data_size < 0, it seems they are overflows */ |
|
|
|
@ -1745,23 +1819,13 @@ static int output_packet(InputStream *ist, int ist_index, |
|
|
|
|
/* if output time reached then transcode raw format,
|
|
|
|
|
encode packets and output them */ |
|
|
|
|
for (i = 0; i < nb_ostreams; i++) { |
|
|
|
|
OutputFile *of = &output_files[ost_table[i].file_index]; |
|
|
|
|
int frame_size; |
|
|
|
|
|
|
|
|
|
ost = &ost_table[i]; |
|
|
|
|
if (ost->source_index != ist_index) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (of->start_time && ist->pts < of->start_time) |
|
|
|
|
if (!check_output_constraints(ist, ost) || !ost->encoding_needed) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (of->recording_time != INT64_MAX && |
|
|
|
|
av_compare_ts(ist->pts, AV_TIME_BASE_Q, of->recording_time + of->start_time, |
|
|
|
|
(AVRational){1, 1000000}) >= 0) { |
|
|
|
|
ost->is_past_recording_time = 1; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if CONFIG_AVFILTER |
|
|
|
|
if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && |
|
|
|
|
ost->input_video_filter) { |
|
|
|
@ -1815,64 +1879,8 @@ static int output_packet(InputStream *ist, int ist_index, |
|
|
|
|
default: |
|
|
|
|
abort(); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
AVPacket opkt; |
|
|
|
|
int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); |
|
|
|
|
|
|
|
|
|
av_init_packet(&opkt); |
|
|
|
|
|
|
|
|
|
if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && |
|
|
|
|
!ost->copy_initial_nonkeyframes) |
|
|
|
|
#if !CONFIG_AVFILTER |
|
|
|
|
continue; |
|
|
|
|
#else |
|
|
|
|
goto cont; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* no reencoding needed : output the packet directly */ |
|
|
|
|
/* force the input stream PTS */ |
|
|
|
|
|
|
|
|
|
if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) |
|
|
|
|
audio_size += data_size; |
|
|
|
|
else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { |
|
|
|
|
video_size += data_size; |
|
|
|
|
ost->sync_opts++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
opkt.stream_index= ost->index; |
|
|
|
|
if(pkt->pts != AV_NOPTS_VALUE) |
|
|
|
|
opkt.pts= av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time; |
|
|
|
|
else |
|
|
|
|
opkt.pts= AV_NOPTS_VALUE; |
|
|
|
|
|
|
|
|
|
if (pkt->dts == AV_NOPTS_VALUE) |
|
|
|
|
opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base); |
|
|
|
|
else |
|
|
|
|
opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base); |
|
|
|
|
opkt.dts -= ost_tb_start_time; |
|
|
|
|
|
|
|
|
|
opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base); |
|
|
|
|
opkt.flags= pkt->flags; |
|
|
|
|
|
|
|
|
|
//FIXME remove the following 2 lines they shall be replaced by the bitstream filters
|
|
|
|
|
if( ost->st->codec->codec_id != CODEC_ID_H264 |
|
|
|
|
&& ost->st->codec->codec_id != CODEC_ID_MPEG1VIDEO |
|
|
|
|
&& ost->st->codec->codec_id != CODEC_ID_MPEG2VIDEO |
|
|
|
|
) { |
|
|
|
|
if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & AV_PKT_FLAG_KEY)) |
|
|
|
|
opkt.destruct= av_destruct_packet; |
|
|
|
|
} else { |
|
|
|
|
opkt.data = data_buf; |
|
|
|
|
opkt.size = data_size; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
write_frame(os, &opkt, ost->st->codec, ost->bitstream_filters); |
|
|
|
|
ost->st->codec->frame_number++; |
|
|
|
|
ost->frame_number++; |
|
|
|
|
av_free_packet(&opkt); |
|
|
|
|
} |
|
|
|
|
#if CONFIG_AVFILTER |
|
|
|
|
cont: |
|
|
|
|
frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) && |
|
|
|
|
ost->output_video_filter && avfilter_poll_frame(ost->output_video_filter->inputs[0]); |
|
|
|
|
if (ost->picref) |
|
|
|
@ -1895,6 +1903,16 @@ fail: |
|
|
|
|
} |
|
|
|
|
discard_packet: |
|
|
|
|
|
|
|
|
|
/* handle stream copy */ |
|
|
|
|
for (i = 0; pkt && i < nb_ostreams; i++) { |
|
|
|
|
ost = &ost_table[i]; |
|
|
|
|
|
|
|
|
|
if (!check_output_constraints(ist, ost) || ost->encoding_needed) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
do_streamcopy(ist, ost, pkt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|