X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffmpeg.c;h=1dd4e3b924841554fc3eb9e20b7278f8146befb8;hb=677911ad8153d10056e7078f66bc1924616c2d30;hp=a80b632cc547c0ada650e2cd344ab9f251249d0e;hpb=e7f4de34ad442ae91671e8288724b2e63a81072f;p=ffmpeg diff --git a/ffmpeg.c b/ffmpeg.c index a80b632cc54..1dd4e3b9248 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -210,9 +210,8 @@ typedef struct InputStream { /* dts of the last packet read for this stream */ int64_t dts; - int64_t next_pts; /* synthetic pts for cases where pkt.pts - is not defined */ - int64_t pts; /* current pts */ + int64_t next_pts; ///< synthetic pts for the next decode frame + int64_t pts; ///< current pts of the decoded frame double ts_scale; int is_start; /* is 1 at the start and after a discontinuity */ int showed_multi_packet_warning; @@ -1078,6 +1077,8 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost, av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n"); exit_program(1); } + + ost->sync_opts += frame->nb_samples; } got_packet = 0; @@ -1101,9 +1102,6 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost, av_free_packet(&pkt); } - if (frame) - ost->sync_opts += frame->nb_samples; - return ret; } @@ -1356,6 +1354,8 @@ static void do_subtitle_out(AVFormatContext *s, nb = 1; for (i = 0; i < nb; i++) { + ost->sync_opts = av_rescale_q(pts, ist->st->time_base, enc->time_base); + sub->pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q); // start_display_time is required to be 0 sub->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); @@ -1384,9 +1384,6 @@ static void do_subtitle_out(AVFormatContext *s, } } -static int bit_buffer_size = 1024 * 256; -static uint8_t *bit_buffer = NULL; - static void do_video_resample(OutputStream *ost, InputStream *ist, AVFrame *in_picture, @@ -1512,6 +1509,8 @@ static void do_video_out(AVFormatContext *s, for (i = 0; i < nb_frames; i++) { AVPacket pkt; av_init_packet(&pkt); + pkt.data = NULL; + pkt.size = 0; if (s->oformat->flags & AVFMT_RAWPICTURE && enc->codec->id == CODEC_ID_RAWVIDEO) { @@ -1527,6 +1526,7 @@ static void do_video_out(AVFormatContext *s, write_frame(s, &pkt, ost); } else { + int got_packet; AVFrame big_picture; big_picture = *final_picture; @@ -1551,29 +1551,27 @@ static void do_video_out(AVFormatContext *s, big_picture.pict_type = AV_PICTURE_TYPE_I; ost->forced_kf_index++; } - ret = avcodec_encode_video(enc, - bit_buffer, bit_buffer_size, - &big_picture); + ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n"); exit_program(1); } - if (ret > 0) { - pkt.data = bit_buffer; - pkt.size = ret; - if (!(enc->codec->capabilities & CODEC_CAP_DELAY)) - pkt.pts = av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base); - if (enc->coded_frame->pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); + if (got_packet) { + if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & CODEC_CAP_DELAY)) + pkt.pts = ost->sync_opts; + + if (pkt.pts != AV_NOPTS_VALUE) + pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base); + if (pkt.dts != AV_NOPTS_VALUE) + pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base); - if (enc->coded_frame->key_frame) - pkt.flags |= AV_PKT_FLAG_KEY; if (format_video_sync == VSYNC_DROP) pkt.pts = pkt.dts = AV_NOPTS_VALUE; + write_frame(s, &pkt, ost); - *frame_size = ret; - video_size += ret; + *frame_size = pkt.size; + video_size += pkt.size; /* if two pass, output log */ if (ost->logfile && enc->stats_out) { @@ -1788,7 +1786,7 @@ static void flush_encoders(OutputStream *ost_table, int nb_ostreams) for (;;) { AVPacket pkt; - int fifo_bytes; + int fifo_bytes, got_packet; av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; @@ -1821,25 +1819,23 @@ static void flush_encoders(OutputStream *ost_table, int nb_ostreams) } break; case AVMEDIA_TYPE_VIDEO: - ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL); + ret = avcodec_encode_video2(enc, &pkt, NULL, &got_packet); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "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; + video_size += pkt.size; if (ost->logfile && enc->stats_out) { fprintf(ost->logfile, "%s", enc->stats_out); } - if (ret <= 0) { + if (!got_packet) { stop_encoding = 1; 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); + if (pkt.pts != AV_NOPTS_VALUE) + pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base); + if (pkt.dts != AV_NOPTS_VALUE) + pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base); write_frame(os, &pkt, ost); break; default: @@ -1937,7 +1933,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p static void rate_emu_sleep(InputStream *ist) { if (input_files[ist->file_index].rate_emu) { - int64_t pts = av_rescale(ist->pts, 1000000, AV_TIME_BASE); + int64_t pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE); int64_t now = av_gettime() - ist->start; if (pts > now) usleep(pts - now); @@ -2318,6 +2314,8 @@ static int output_packet(InputStream *ist, } break; } + ist->pts = ist->dts; + ist->next_pts = ist->next_dts; } for (i = 0; pkt && i < nb_ostreams; i++) { OutputStream *ost = &ost_table[i]; @@ -2665,19 +2663,6 @@ static int transcode_init(OutputFile *output_files, int nb_output_files, } } } - if (codec->codec_type == AVMEDIA_TYPE_VIDEO) { - /* maximum video buffer size is 8-bytes per pixel, plus DPX header size (1664)*/ - int size = codec->width * codec->height; - bit_buffer_size = FFMAX(bit_buffer_size, 9*size + 10000); - } - } - - if (!bit_buffer) - bit_buffer = av_malloc(bit_buffer_size); - if (!bit_buffer) { - av_log(NULL, AV_LOG_ERROR, "Cannot allocate %d bytes output buffer\n", - bit_buffer_size); - return AVERROR(ENOMEM); } /* open each encoder */ @@ -3115,7 +3100,6 @@ static int transcode(OutputFile *output_files, int nb_output_files, ret = 0; fail: - av_freep(&bit_buffer); av_freep(&no_packet); if (output_streams) {