| 1 | static double get_sync_ipts(const OutputStream *ost)
|
|---|
| 2 | {
|
|---|
| 3 | const InputStream *ist = ost->sync_ist;
|
|---|
| 4 | OutputFile *of = &output_files[ost->file_index];
|
|---|
| 5 |
|
|---|
| 6 | ost->sync_ist->pts = fabs(ost->sync_ist->pts);
|
|---|
| 7 |
|
|---|
| 8 | fprintf(stderr, "ist->pts:%ld, of->start_time:%ld, [ost->file_index]: %d, AV_TIME_BASE:%d\n", ist->pts, of->start_time, ost->file_index, AV_TIME_BASE);
|
|---|
| 9 | return (double)(ist->pts - of->start_time) / AV_TIME_BASE;
|
|---|
| 10 | }
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 | static void do_video_out(AVFormatContext *s,
|
|---|
| 14 | OutputStream *ost,
|
|---|
| 15 | InputStream *ist,
|
|---|
| 16 | AVFrame *in_picture,
|
|---|
| 17 | int *frame_size, float quality)
|
|---|
| 18 | {
|
|---|
| 19 | int nb_frames, i, ret, format_video_sync;
|
|---|
| 20 | AVFrame *final_picture;
|
|---|
| 21 | AVCodecContext *enc;
|
|---|
| 22 | double sync_ipts;
|
|---|
| 23 | double duration = 0;
|
|---|
| 24 |
|
|---|
| 25 | enc = ost->st->codec;
|
|---|
| 26 |
|
|---|
| 27 | if (ist->st->start_time != AV_NOPTS_VALUE && ist->st->first_dts != AV_NOPTS_VALUE) {
|
|---|
| 28 | duration = FFMAX(av_q2d(ist->st->time_base), av_q2d(ist->st->codec->time_base));
|
|---|
| 29 | if(ist->st->avg_frame_rate.num)
|
|---|
| 30 | duration= FFMAX(duration, 1/av_q2d(ist->st->avg_frame_rate));
|
|---|
| 31 |
|
|---|
| 32 | duration /= av_q2d(enc->time_base);
|
|---|
| 33 | }
|
|---|
| 34 |
|
|---|
| 35 | double tmpSync_ipts = get_sync_ipts(ost);
|
|---|
| 36 | sync_ipts = tmpSync_ipts / av_q2d(enc->time_base);
|
|---|
| 37 | fprintf(stderr, "sync_ipts:%f, get_sync_ipts(ost):%f, av_q2d(enc->time_base):%f\n", sync_ipts, tmpSync_ipts, av_q2d(enc->time_base));
|
|---|
| 38 |
|
|---|
| 39 | /* by default, we output a single frame */
|
|---|
| 40 | nb_frames = 1;
|
|---|
| 41 |
|
|---|
| 42 | *frame_size = 0;
|
|---|
| 43 |
|
|---|
| 44 | format_video_sync = video_sync_method;
|
|---|
| 45 | if (format_video_sync == VSYNC_AUTO)
|
|---|
| 46 | format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : 1;
|
|---|
| 47 |
|
|---|
| 48 | if (format_video_sync != VSYNC_PASSTHROUGH) {
|
|---|
| 49 | double vdelta = sync_ipts - ost->sync_opts + duration;
|
|---|
| 50 | // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
|
|---|
| 51 | if (vdelta < -1.1)
|
|---|
| 52 | nb_frames = 0;
|
|---|
| 53 | else if (format_video_sync == VSYNC_VFR) {
|
|---|
| 54 | if (vdelta <= -0.6) {
|
|---|
| 55 | nb_frames = 0;
|
|---|
| 56 | } else if (vdelta > 0.6)
|
|---|
| 57 | ost->sync_opts = lrintf(sync_ipts);
|
|---|
| 58 | } /*else if (fabs(vdelta) > 1.1)
|
|---|
| 59 | nb_frames = lrintf(vdelta);
|
|---|
| 60 | fprintf(stderr, "vdelta:%f = sync_ipts:%f, ost->sync_opts:%"PRId64", duration:%f nb_frames:%d\n", vdelta, sync_ipts, ost->sync_opts, duration, nb_frames);
|
|---|
| 61 | //av_log(NULL, AV_LOG_VERBOSE, "vdelta [ffmpeg]\n");
|
|---|
| 62 | if (nb_frames == 0) {
|
|---|
| 63 | ++nb_frames_drop;
|
|---|
| 64 | av_log(NULL, AV_LOG_VERBOSE, "*** drop! [ffmpeg]\n");
|
|---|
| 65 | } else if (nb_frames > 1) {
|
|---|
| 66 | nb_frames_dup += nb_frames - 1;
|
|---|
| 67 | av_log(NULL, AV_LOG_VERBOSE, "*** %d dup! [ffmpeg]\n", nb_frames - 1);
|
|---|
| 68 | }*/nb_frames = 1;
|
|---|
| 69 | } else
|
|---|
| 70 | ost->sync_opts = lrintf(sync_ipts);
|
|---|
| 71 |
|
|---|
| 72 | nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);
|
|---|
| 73 | if (nb_frames <= 0)
|
|---|
| 74 | return;
|
|---|
| 75 |
|
|---|
| 76 | do_video_resample(ost, ist, in_picture, &final_picture);
|
|---|
| 77 |
|
|---|
| 78 | /* duplicates frame if needed */
|
|---|
| 79 | for (i = 0; i < nb_frames; i++) {
|
|---|
| 80 | AVPacket pkt;
|
|---|
| 81 | av_init_packet(&pkt);
|
|---|
| 82 | pkt.stream_index = ost->index;
|
|---|
| 83 |
|
|---|
| 84 | if (s->oformat->flags & AVFMT_RAWPICTURE &&
|
|---|
| 85 | enc->codec->id == CODEC_ID_RAWVIDEO) {
|
|---|
| 86 | /* raw pictures are written as AVPicture structure to
|
|---|
| 87 | avoid any copies. We support temporarily the older
|
|---|
| 88 | method. */
|
|---|
| 89 | enc->coded_frame->interlaced_frame = in_picture->interlaced_frame;
|
|---|
| 90 | enc->coded_frame->top_field_first = in_picture->top_field_first;
|
|---|
| 91 | pkt.data = (uint8_t *)final_picture;
|
|---|
| 92 | pkt.size = sizeof(AVPicture);
|
|---|
| 93 | pkt.pts = av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base);
|
|---|
| 94 | pkt.flags |= AV_PKT_FLAG_KEY;
|
|---|
| 95 |
|
|---|
| 96 | write_frame(s, &pkt, ost);
|
|---|
| 97 | } else {
|
|---|
| 98 | AVFrame big_picture;
|
|---|
| 99 |
|
|---|
| 100 | big_picture = *final_picture;
|
|---|
| 101 | /* better than nothing: use input picture interlaced
|
|---|
| 102 | settings */
|
|---|
| 103 | big_picture.interlaced_frame = in_picture->interlaced_frame;
|
|---|
| 104 | if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)) {
|
|---|
| 105 | if (ost->top_field_first == -1)
|
|---|
| 106 | big_picture.top_field_first = in_picture->top_field_first;
|
|---|
| 107 | else
|
|---|
| 108 | big_picture.top_field_first = !!ost->top_field_first;
|
|---|
| 109 | }
|
|---|
| 110 |
|
|---|
| 111 | /* handles same_quant here. This is not correct because it may
|
|---|
| 112 | not be a global option */
|
|---|
| 113 | big_picture.quality = quality;
|
|---|
| 114 | if (!enc->me_threshold)
|
|---|
| 115 | big_picture.pict_type = 0;
|
|---|
| 116 | // big_picture.pts = AV_NOPTS_VALUE;
|
|---|
| 117 | big_picture.pts = ost->sync_opts;
|
|---|
| 118 | // big_picture.pts= av_rescale(ost->sync_opts, AV_TIME_BASE*(int64_t)enc->time_base.num, enc->time_base.den);
|
|---|
| 119 | // av_log(NULL, AV_LOG_DEBUG, "%"PRId64" -> encoder\n", ost->sync_opts);
|
|---|
| 120 | if (ost->forced_kf_index < ost->forced_kf_count &&
|
|---|
| 121 | big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
|
|---|
| 122 | big_picture.pict_type = AV_PICTURE_TYPE_I;
|
|---|
| 123 | ost->forced_kf_index++;
|
|---|
| 124 | }
|
|---|
| 125 | ret = avcodec_encode_video(enc,
|
|---|
| 126 | bit_buffer, bit_buffer_size,
|
|---|
| 127 | &big_picture);
|
|---|
| 128 | if (ret < 0) {
|
|---|
| 129 | av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
|
|---|
| 130 | exit_program(1);
|
|---|
| 131 | }
|
|---|
| 132 |
|
|---|
| 133 | if (ret > 0) {
|
|---|
| 134 | pkt.data = bit_buffer;
|
|---|
| 135 | pkt.size = ret;
|
|---|
| 136 | if (enc->coded_frame->pts != AV_NOPTS_VALUE)
|
|---|
| 137 | pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
|
|---|
| 138 | /*av_log(NULL, AV_LOG_DEBUG, "encoder -> %"PRId64"/%"PRId64"\n",
|
|---|
| 139 | pkt.pts != AV_NOPTS_VALUE ? av_rescale(pkt.pts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1,
|
|---|
| 140 | pkt.dts != AV_NOPTS_VALUE ? av_rescale(pkt.dts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1);*/
|
|---|
| 141 |
|
|---|
| 142 | if (enc->coded_frame->key_frame)
|
|---|
| 143 | pkt.flags |= AV_PKT_FLAG_KEY;
|
|---|
| 144 | write_frame(s, &pkt, ost);
|
|---|
| 145 | *frame_size = ret;
|
|---|
| 146 | video_size += ret;
|
|---|
| 147 | // fprintf(stderr,"\nFrame: %3d size: %5d type: %d",
|
|---|
| 148 | // enc->frame_number-1, ret, enc->pict_type);
|
|---|
| 149 | /* if two pass, output log */
|
|---|
| 150 | if (ost->logfile && enc->stats_out) {
|
|---|
| 151 | fprintf(ost->logfile, "%s", enc->stats_out);
|
|---|
| 152 | }
|
|---|
| 153 | }
|
|---|
| 154 | }
|
|---|
| 155 | ost->sync_opts++;
|
|---|
| 156 | /*
|
|---|
| 157 | * For video, number of frames in == number of packets out.
|
|---|
| 158 | * But there may be reordering, so we can't throw away frames on encoder
|
|---|
| 159 | * flush, we need to limit them here, before they go into encoder.
|
|---|
| 160 | */
|
|---|
| 161 | ost->frame_number++;
|
|---|
| 162 | }
|
|---|
| 163 | }
|
|---|