| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of FFmpeg. | ||
| 3 | * | ||
| 4 | * FFmpeg is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU Lesser General Public | ||
| 6 | * License as published by the Free Software Foundation; either | ||
| 7 | * version 2.1 of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * Lesser General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU Lesser General Public | ||
| 15 | * License along with FFmpeg; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <math.h> | ||
| 20 | #include <stdint.h> | ||
| 21 | |||
| 22 | #include "ffmpeg.h" | ||
| 23 | |||
| 24 | #include "libavutil/avassert.h" | ||
| 25 | #include "libavutil/avstring.h" | ||
| 26 | #include "libavutil/avutil.h" | ||
| 27 | #include "libavutil/dict.h" | ||
| 28 | #include "libavutil/display.h" | ||
| 29 | #include "libavutil/eval.h" | ||
| 30 | #include "libavutil/frame.h" | ||
| 31 | #include "libavutil/intreadwrite.h" | ||
| 32 | #include "libavutil/log.h" | ||
| 33 | #include "libavutil/mem.h" | ||
| 34 | #include "libavutil/pixdesc.h" | ||
| 35 | #include "libavutil/rational.h" | ||
| 36 | #include "libavutil/time.h" | ||
| 37 | #include "libavutil/timestamp.h" | ||
| 38 | |||
| 39 | #include "libavcodec/avcodec.h" | ||
| 40 | |||
| 41 | typedef struct EncoderPriv { | ||
| 42 | Encoder e; | ||
| 43 | |||
| 44 | void *log_parent; | ||
| 45 | char log_name[32]; | ||
| 46 | |||
| 47 | // combined size of all the packets received from the encoder | ||
| 48 | uint64_t data_size; | ||
| 49 | |||
| 50 | // number of packets received from the encoder | ||
| 51 | uint64_t packets_encoded; | ||
| 52 | |||
| 53 | int opened; | ||
| 54 | int attach_par; | ||
| 55 | |||
| 56 | Scheduler *sch; | ||
| 57 | unsigned sch_idx; | ||
| 58 | } EncoderPriv; | ||
| 59 | |||
| 60 | 623247 | static EncoderPriv *ep_from_enc(Encoder *enc) | |
| 61 | { | ||
| 62 | 623247 | return (EncoderPriv*)enc; | |
| 63 | } | ||
| 64 | |||
| 65 | // data that is local to the decoder thread and not visible outside of it | ||
| 66 | typedef struct EncoderThread { | ||
| 67 | AVFrame *frame; | ||
| 68 | AVPacket *pkt; | ||
| 69 | } EncoderThread; | ||
| 70 | |||
| 71 | 8979 | void enc_free(Encoder **penc) | |
| 72 | { | ||
| 73 | 8979 | Encoder *enc = *penc; | |
| 74 | |||
| 75 |
2/2✓ Branch 0 taken 747 times.
✓ Branch 1 taken 8232 times.
|
8979 | if (!enc) |
| 76 | 747 | return; | |
| 77 | |||
| 78 |
1/2✓ Branch 0 taken 8232 times.
✗ Branch 1 not taken.
|
8232 | if (enc->enc_ctx) |
| 79 | 8232 | av_freep(&enc->enc_ctx->stats_in); | |
| 80 | 8232 | avcodec_free_context(&enc->enc_ctx); | |
| 81 | |||
| 82 | 8232 | av_freep(penc); | |
| 83 | } | ||
| 84 | |||
| 85 | 3 | static const char *enc_item_name(void *obj) | |
| 86 | { | ||
| 87 | 3 | const EncoderPriv *ep = obj; | |
| 88 | |||
| 89 | 3 | return ep->log_name; | |
| 90 | } | ||
| 91 | |||
| 92 | static const AVClass enc_class = { | ||
| 93 | .class_name = "Encoder", | ||
| 94 | .version = LIBAVUTIL_VERSION_INT, | ||
| 95 | .parent_log_context_offset = offsetof(EncoderPriv, log_parent), | ||
| 96 | .item_name = enc_item_name, | ||
| 97 | }; | ||
| 98 | |||
| 99 | 8232 | int enc_alloc(Encoder **penc, const AVCodec *codec, | |
| 100 | Scheduler *sch, unsigned sch_idx, void *log_parent) | ||
| 101 | { | ||
| 102 | EncoderPriv *ep; | ||
| 103 | 8232 | int ret = 0; | |
| 104 | |||
| 105 | 8232 | *penc = NULL; | |
| 106 | |||
| 107 | 8232 | ep = av_mallocz(sizeof(*ep)); | |
| 108 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8232 times.
|
8232 | if (!ep) |
| 109 | ✗ | return AVERROR(ENOMEM); | |
| 110 | |||
| 111 | 8232 | ep->e.class = &enc_class; | |
| 112 | 8232 | ep->log_parent = log_parent; | |
| 113 | |||
| 114 | 8232 | ep->sch = sch; | |
| 115 | 8232 | ep->sch_idx = sch_idx; | |
| 116 | |||
| 117 | 8232 | snprintf(ep->log_name, sizeof(ep->log_name), "enc:%s", codec->name); | |
| 118 | |||
| 119 | 8232 | ep->e.enc_ctx = avcodec_alloc_context3(codec); | |
| 120 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8232 times.
|
8232 | if (!ep->e.enc_ctx) { |
| 121 | ✗ | ret = AVERROR(ENOMEM); | |
| 122 | ✗ | goto fail; | |
| 123 | } | ||
| 124 | |||
| 125 | 8232 | *penc = &ep->e; | |
| 126 | |||
| 127 | 8232 | return 0; | |
| 128 | ✗ | fail: | |
| 129 | ✗ | enc_free((Encoder**)&ep); | |
| 130 | ✗ | return ret; | |
| 131 | } | ||
| 132 | |||
| 133 | 8232 | static int hw_device_setup_for_encode(Encoder *e, AVCodecContext *enc_ctx, | |
| 134 | AVBufferRef *frames_ref) | ||
| 135 | { | ||
| 136 | const AVCodecHWConfig *config; | ||
| 137 | 8232 | HWDevice *dev = NULL; | |
| 138 | |||
| 139 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8232 times.
|
8232 | if (frames_ref && |
| 140 | ✗ | ((AVHWFramesContext*)frames_ref->data)->format == | |
| 141 | ✗ | enc_ctx->pix_fmt) { | |
| 142 | // Matching format, will try to use hw_frames_ctx. | ||
| 143 | } else { | ||
| 144 | 8232 | frames_ref = NULL; | |
| 145 | } | ||
| 146 | |||
| 147 | 8232 | for (int i = 0;; i++) { | |
| 148 | 8232 | config = avcodec_get_hw_config(enc_ctx->codec, i); | |
| 149 |
1/2✓ Branch 0 taken 8232 times.
✗ Branch 1 not taken.
|
8232 | if (!config) |
| 150 | 8232 | break; | |
| 151 | |||
| 152 | ✗ | if (frames_ref && | |
| 153 | ✗ | config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX && | |
| 154 | ✗ | (config->pix_fmt == AV_PIX_FMT_NONE || | |
| 155 | ✗ | config->pix_fmt == enc_ctx->pix_fmt)) { | |
| 156 | ✗ | av_log(e, AV_LOG_VERBOSE, "Using input " | |
| 157 | "frames context (format %s) with %s encoder.\n", | ||
| 158 | av_get_pix_fmt_name(enc_ctx->pix_fmt), | ||
| 159 | ✗ | enc_ctx->codec->name); | |
| 160 | ✗ | enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref); | |
| 161 | ✗ | if (!enc_ctx->hw_frames_ctx) | |
| 162 | ✗ | return AVERROR(ENOMEM); | |
| 163 | ✗ | return 0; | |
| 164 | } | ||
| 165 | |||
| 166 | ✗ | if (!dev && | |
| 167 | ✗ | config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) | |
| 168 | ✗ | dev = hw_device_get_by_type(config->device_type); | |
| 169 | } | ||
| 170 | |||
| 171 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8232 times.
|
8232 | if (dev) { |
| 172 | ✗ | av_log(e, AV_LOG_VERBOSE, "Using device %s " | |
| 173 | "(type %s) with %s encoder.\n", dev->name, | ||
| 174 | ✗ | av_hwdevice_get_type_name(dev->type), enc_ctx->codec->name); | |
| 175 | ✗ | enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref); | |
| 176 | ✗ | if (!enc_ctx->hw_device_ctx) | |
| 177 | ✗ | return AVERROR(ENOMEM); | |
| 178 | } else { | ||
| 179 | // No device required, or no device available. | ||
| 180 | } | ||
| 181 | 8232 | return 0; | |
| 182 | } | ||
| 183 | |||
| 184 | 8232 | int enc_open(void *opaque, const AVFrame *frame) | |
| 185 | { | ||
| 186 | 8232 | OutputStream *ost = opaque; | |
| 187 | 8232 | InputStream *ist = ost->ist; | |
| 188 | 8232 | Encoder *e = ost->enc; | |
| 189 | 8232 | EncoderPriv *ep = ep_from_enc(e); | |
| 190 | 8232 | AVCodecContext *enc_ctx = e->enc_ctx; | |
| 191 | 8232 | Decoder *dec = NULL; | |
| 192 | 8232 | const AVCodec *enc = enc_ctx->codec; | |
| 193 | 8232 | OutputFile *of = ost->file; | |
| 194 | FrameData *fd; | ||
| 195 | 8232 | int frame_samples = 0; | |
| 196 | int ret; | ||
| 197 | |||
| 198 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8232 times.
|
8232 | if (ep->opened) |
| 199 | ✗ | return 0; | |
| 200 | |||
| 201 | // frame is always non-NULL for audio and video | ||
| 202 |
4/6✓ Branch 0 taken 42 times.
✓ Branch 1 taken 8190 times.
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 42 times.
|
8232 | av_assert0(frame || (enc->type != AVMEDIA_TYPE_VIDEO && enc->type != AVMEDIA_TYPE_AUDIO)); |
| 203 | |||
| 204 |
2/2✓ Branch 0 taken 8190 times.
✓ Branch 1 taken 42 times.
|
8232 | if (frame) { |
| 205 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8190 times.
|
8190 | av_assert0(frame->opaque_ref); |
| 206 | 8190 | fd = (FrameData*)frame->opaque_ref->data; | |
| 207 | |||
| 208 | 8190 | ret = clone_side_data(&enc_ctx->decoded_side_data, &enc_ctx->nb_decoded_side_data, | |
| 209 | 8190 | fd->side_data, fd->nb_side_data, AV_FRAME_SIDE_DATA_FLAG_UNIQUE); | |
| 210 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8190 times.
|
8190 | if (ret < 0) |
| 211 | ✗ | return ret; | |
| 212 | } | ||
| 213 | |||
| 214 |
2/2✓ Branch 0 taken 6842 times.
✓ Branch 1 taken 1390 times.
|
8232 | if (ist) |
| 215 | 6842 | dec = ist->decoder; | |
| 216 | |||
| 217 | // the timebase is chosen by filtering code | ||
| 218 |
4/4✓ Branch 0 taken 6889 times.
✓ Branch 1 taken 1343 times.
✓ Branch 2 taken 6847 times.
✓ Branch 3 taken 42 times.
|
8232 | if (ost->type == AVMEDIA_TYPE_AUDIO || ost->type == AVMEDIA_TYPE_VIDEO) { |
| 219 | 8190 | enc_ctx->time_base = frame->time_base; | |
| 220 | 8190 | enc_ctx->framerate = fd->frame_rate_filter; | |
| 221 | } | ||
| 222 | |||
| 223 |
3/4✓ Branch 0 taken 1343 times.
✓ Branch 1 taken 6847 times.
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
|
8232 | switch (enc_ctx->codec_type) { |
| 224 | 1343 | case AVMEDIA_TYPE_AUDIO: | |
| 225 |
3/6✓ Branch 0 taken 1343 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1343 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1343 times.
|
1343 | av_assert0(frame->format != AV_SAMPLE_FMT_NONE && |
| 226 | frame->sample_rate > 0 && | ||
| 227 | frame->ch_layout.nb_channels > 0); | ||
| 228 | 1343 | enc_ctx->sample_fmt = frame->format; | |
| 229 | 1343 | enc_ctx->sample_rate = frame->sample_rate; | |
| 230 | 1343 | ret = av_channel_layout_copy(&enc_ctx->ch_layout, &frame->ch_layout); | |
| 231 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1343 times.
|
1343 | if (ret < 0) |
| 232 | ✗ | return ret; | |
| 233 | |||
| 234 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1343 times.
|
1343 | if (ost->bits_per_raw_sample) |
| 235 | ✗ | enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample; | |
| 236 | else | ||
| 237 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1343 times.
|
1343 | enc_ctx->bits_per_raw_sample = FFMIN(fd->bits_per_raw_sample, |
| 238 | av_get_bytes_per_sample(enc_ctx->sample_fmt) << 3); | ||
| 239 | 1343 | break; | |
| 240 | |||
| 241 | 6847 | case AVMEDIA_TYPE_VIDEO: { | |
| 242 |
3/6✓ Branch 0 taken 6847 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6847 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6847 times.
|
6847 | av_assert0(frame->format != AV_PIX_FMT_NONE && |
| 243 | frame->width > 0 && | ||
| 244 | frame->height > 0); | ||
| 245 | 6847 | enc_ctx->width = frame->width; | |
| 246 | 6847 | enc_ctx->height = frame->height; | |
| 247 | 6847 | enc_ctx->sample_aspect_ratio = | |
| 248 | 6847 | ost->frame_aspect_ratio.num ? // overridden by the -aspect cli option | |
| 249 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6847 times.
|
6847 | av_mul_q(ost->frame_aspect_ratio, (AVRational){ enc_ctx->height, enc_ctx->width }) : |
| 250 | frame->sample_aspect_ratio; | ||
| 251 | |||
| 252 | 6847 | enc_ctx->pix_fmt = frame->format; | |
| 253 | |||
| 254 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6846 times.
|
6847 | if (ost->bits_per_raw_sample) |
| 255 | 1 | enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample; | |
| 256 | else | ||
| 257 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6846 times.
|
6846 | enc_ctx->bits_per_raw_sample = FFMIN(fd->bits_per_raw_sample, |
| 258 | av_pix_fmt_desc_get(enc_ctx->pix_fmt)->comp[0].depth); | ||
| 259 | |||
| 260 | /** | ||
| 261 | * The video color properties should always be in sync with the user- | ||
| 262 | * requested values, since we forward them to the filter graph. | ||
| 263 | */ | ||
| 264 | 6847 | enc_ctx->color_range = frame->color_range; | |
| 265 | 6847 | enc_ctx->color_primaries = frame->color_primaries; | |
| 266 | 6847 | enc_ctx->color_trc = frame->color_trc; | |
| 267 | 6847 | enc_ctx->colorspace = frame->colorspace; | |
| 268 | 6847 | enc_ctx->alpha_mode = frame->alpha_mode; | |
| 269 | |||
| 270 | /* Video properties which are not part of filter graph negotiation */ | ||
| 271 |
1/2✓ Branch 0 taken 6847 times.
✗ Branch 1 not taken.
|
6847 | if (enc_ctx->chroma_sample_location == AVCHROMA_LOC_UNSPECIFIED) { |
| 272 | 6847 | enc_ctx->chroma_sample_location = frame->chroma_location; | |
| 273 | ✗ | } else if (enc_ctx->chroma_sample_location != frame->chroma_location && | |
| 274 | ✗ | frame->chroma_location != AVCHROMA_LOC_UNSPECIFIED) { | |
| 275 | ✗ | av_log(e, AV_LOG_WARNING, | |
| 276 | "Requested chroma sample location '%s' does not match the " | ||
| 277 | "frame tagged sample location '%s'; result may be incorrect.\n", | ||
| 278 | av_chroma_location_name(enc_ctx->chroma_sample_location), | ||
| 279 | ✗ | av_chroma_location_name(frame->chroma_location)); | |
| 280 | } | ||
| 281 | |||
| 282 |
2/2✓ Branch 0 taken 6811 times.
✓ Branch 1 taken 36 times.
|
6847 | if (enc_ctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) || |
| 283 |
2/2✓ Branch 0 taken 6377 times.
✓ Branch 1 taken 434 times.
|
6811 | (frame->flags & AV_FRAME_FLAG_INTERLACED) |
| 284 | #if FFMPEG_OPT_TOP | ||
| 285 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6377 times.
|
6377 | || ost->top_field_first >= 0 |
| 286 | #endif | ||
| 287 | 470 | ) { | |
| 288 | 470 | int top_field_first = | |
| 289 | #if FFMPEG_OPT_TOP | ||
| 290 | 470 | ost->top_field_first >= 0 ? | |
| 291 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 470 times.
|
470 | ost->top_field_first : |
| 292 | #endif | ||
| 293 | 470 | !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST); | |
| 294 | |||
| 295 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 469 times.
|
470 | if (enc->id == AV_CODEC_ID_MJPEG) |
| 296 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | enc_ctx->field_order = top_field_first ? AV_FIELD_TT : AV_FIELD_BB; |
| 297 | else | ||
| 298 |
2/2✓ Branch 0 taken 361 times.
✓ Branch 1 taken 108 times.
|
469 | enc_ctx->field_order = top_field_first ? AV_FIELD_TB : AV_FIELD_BT; |
| 299 | } else | ||
| 300 | 6377 | enc_ctx->field_order = AV_FIELD_PROGRESSIVE; | |
| 301 | |||
| 302 | 6847 | break; | |
| 303 | } | ||
| 304 | 42 | case AVMEDIA_TYPE_SUBTITLE: | |
| 305 | 42 | enc_ctx->time_base = AV_TIME_BASE_Q; | |
| 306 | |||
| 307 |
1/2✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
|
42 | if (!enc_ctx->width) { |
| 308 | 42 | enc_ctx->width = ost->ist->par->width; | |
| 309 | 42 | enc_ctx->height = ost->ist->par->height; | |
| 310 | } | ||
| 311 | |||
| 312 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
|
42 | av_assert0(dec); |
| 313 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 2 times.
|
42 | if (dec->subtitle_header) { |
| 314 | /* ASS code assumes this buffer is null terminated so add extra byte. */ | ||
| 315 | 40 | enc_ctx->subtitle_header = av_mallocz(dec->subtitle_header_size + 1); | |
| 316 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | if (!enc_ctx->subtitle_header) |
| 317 | ✗ | return AVERROR(ENOMEM); | |
| 318 | 40 | memcpy(enc_ctx->subtitle_header, dec->subtitle_header, | |
| 319 | 40 | dec->subtitle_header_size); | |
| 320 | 40 | enc_ctx->subtitle_header_size = dec->subtitle_header_size; | |
| 321 | } | ||
| 322 | |||
| 323 | 42 | break; | |
| 324 | ✗ | default: | |
| 325 | ✗ | av_assert0(0); | |
| 326 | break; | ||
| 327 | } | ||
| 328 | |||
| 329 |
2/2✓ Branch 0 taken 7346 times.
✓ Branch 1 taken 886 times.
|
8232 | if (ost->bitexact) |
| 330 | 7346 | enc_ctx->flags |= AV_CODEC_FLAG_BITEXACT; | |
| 331 | |||
| 332 |
2/2✓ Branch 0 taken 8165 times.
✓ Branch 1 taken 67 times.
|
8232 | if (enc->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE) |
| 333 | 8165 | enc_ctx->flags |= AV_CODEC_FLAG_COPY_OPAQUE; | |
| 334 | |||
| 335 | 8232 | enc_ctx->flags |= AV_CODEC_FLAG_FRAME_DURATION; | |
| 336 | |||
| 337 |
2/2✓ Branch 0 taken 8190 times.
✓ Branch 1 taken 42 times.
|
8232 | ret = hw_device_setup_for_encode(e, enc_ctx, frame ? frame->hw_frames_ctx : NULL); |
| 338 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8232 times.
|
8232 | if (ret < 0) { |
| 339 | ✗ | av_log(e, AV_LOG_ERROR, | |
| 340 | ✗ | "Encoding hardware device setup failed: %s\n", av_err2str(ret)); | |
| 341 | ✗ | return ret; | |
| 342 | } | ||
| 343 | |||
| 344 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8232 times.
|
8232 | if ((ret = avcodec_open2(enc_ctx, enc, NULL)) < 0) { |
| 345 | ✗ | if (ret != AVERROR_EXPERIMENTAL) | |
| 346 | ✗ | av_log(e, AV_LOG_ERROR, "Error while opening encoder - maybe " | |
| 347 | "incorrect parameters such as bit_rate, rate, width or height.\n"); | ||
| 348 | ✗ | return ret; | |
| 349 | } | ||
| 350 | |||
| 351 | 8232 | ep->opened = 1; | |
| 352 | |||
| 353 |
2/2✓ Branch 0 taken 178 times.
✓ Branch 1 taken 8054 times.
|
8232 | if (enc_ctx->frame_size) |
| 354 | 178 | frame_samples = enc_ctx->frame_size; | |
| 355 | |||
| 356 |
4/4✓ Branch 0 taken 8189 times.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 8188 times.
|
8232 | if (enc_ctx->bit_rate && enc_ctx->bit_rate < 1000 && |
| 357 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | enc_ctx->codec_id != AV_CODEC_ID_CODEC2 /* don't complain about 700 bit/s modes */) |
| 358 | 1 | av_log(e, AV_LOG_WARNING, "The bitrate parameter is set too low." | |
| 359 | " It takes bits/s as argument, not kbits/s\n"); | ||
| 360 | |||
| 361 | 8232 | ret = of_stream_init(of, ost, enc_ctx); | |
| 362 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8232 times.
|
8232 | if (ret < 0) |
| 363 | ✗ | return ret; | |
| 364 | |||
| 365 | 8232 | return frame_samples; | |
| 366 | } | ||
| 367 | |||
| 368 | 455661 | static int check_recording_time(OutputStream *ost, int64_t ts, AVRational tb) | |
| 369 | { | ||
| 370 | 455661 | OutputFile *of = ost->file; | |
| 371 | |||
| 372 |
4/4✓ Branch 0 taken 35050 times.
✓ Branch 1 taken 420611 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 35049 times.
|
490711 | if (of->recording_time != INT64_MAX && |
| 373 | 35050 | av_compare_ts(ts, tb, of->recording_time, AV_TIME_BASE_Q) >= 0) { | |
| 374 | 1 | return 0; | |
| 375 | } | ||
| 376 | 455660 | return 1; | |
| 377 | } | ||
| 378 | |||
| 379 | 946 | static int do_subtitle_out(OutputFile *of, OutputStream *ost, const AVSubtitle *sub, | |
| 380 | AVPacket *pkt) | ||
| 381 | { | ||
| 382 | 946 | Encoder *e = ost->enc; | |
| 383 | 946 | EncoderPriv *ep = ep_from_enc(e); | |
| 384 | 946 | int subtitle_out_max_size = 1024 * 1024; | |
| 385 | int subtitle_out_size, nb, i, ret; | ||
| 386 | AVCodecContext *enc; | ||
| 387 | int64_t pts; | ||
| 388 | |||
| 389 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
|
946 | if (sub->pts == AV_NOPTS_VALUE) { |
| 390 | ✗ | av_log(e, AV_LOG_ERROR, "Subtitle packets must have a pts\n"); | |
| 391 | ✗ | return exit_on_error ? AVERROR(EINVAL) : 0; | |
| 392 | } | ||
| 393 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
946 | if ((of->start_time != AV_NOPTS_VALUE && sub->pts < of->start_time)) |
| 394 | ✗ | return 0; | |
| 395 | |||
| 396 | 946 | enc = e->enc_ctx; | |
| 397 | |||
| 398 | /* Note: DVB subtitle need one packet to draw them and one other | ||
| 399 | packet to clear them */ | ||
| 400 | /* XXX: signal it in the codec context ? */ | ||
| 401 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 910 times.
|
946 | if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) |
| 402 | 36 | nb = 2; | |
| 403 |
2/2✓ Branch 0 taken 450 times.
✓ Branch 1 taken 460 times.
|
910 | else if (enc->codec_id == AV_CODEC_ID_ASS) |
| 404 | 450 | nb = FFMAX(sub->num_rects, 1); | |
| 405 | else | ||
| 406 | 460 | nb = 1; | |
| 407 | |||
| 408 | /* shift timestamp to honor -ss and make check_recording_time() work with -t */ | ||
| 409 | 946 | pts = sub->pts; | |
| 410 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
|
946 | if (of->start_time != AV_NOPTS_VALUE) |
| 411 | ✗ | pts -= of->start_time; | |
| 412 |
2/2✓ Branch 0 taken 982 times.
✓ Branch 1 taken 946 times.
|
1928 | for (i = 0; i < nb; i++) { |
| 413 | 982 | AVSubtitle local_sub = *sub; | |
| 414 | |||
| 415 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 982 times.
|
982 | if (!check_recording_time(ost, pts, AV_TIME_BASE_Q)) |
| 416 | ✗ | return AVERROR_EOF; | |
| 417 | |||
| 418 | 982 | ret = av_new_packet(pkt, subtitle_out_max_size); | |
| 419 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 982 times.
|
982 | if (ret < 0) |
| 420 | ✗ | return AVERROR(ENOMEM); | |
| 421 | |||
| 422 | 982 | local_sub.pts = pts; | |
| 423 | // start_display_time is required to be 0 | ||
| 424 | 982 | local_sub.pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); | |
| 425 | 982 | local_sub.end_display_time -= sub->start_display_time; | |
| 426 | 982 | local_sub.start_display_time = 0; | |
| 427 | |||
| 428 |
4/4✓ Branch 0 taken 72 times.
✓ Branch 1 taken 910 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 36 times.
|
982 | if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE && i == 1) |
| 429 | 36 | local_sub.num_rects = 0; | |
| 430 |
3/4✓ Branch 0 taken 450 times.
✓ Branch 1 taken 496 times.
✓ Branch 2 taken 450 times.
✗ Branch 3 not taken.
|
946 | else if (enc->codec_id == AV_CODEC_ID_ASS && sub->num_rects > 0) { |
| 431 | 450 | local_sub.num_rects = 1; | |
| 432 | 450 | local_sub.rects += i; | |
| 433 | } | ||
| 434 | |||
| 435 | 982 | e->frames_encoded++; | |
| 436 | |||
| 437 | 982 | subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, &local_sub); | |
| 438 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 982 times.
|
982 | if (subtitle_out_size < 0) { |
| 439 | ✗ | av_log(e, AV_LOG_FATAL, "Subtitle encoding failed\n"); | |
| 440 | ✗ | return subtitle_out_size; | |
| 441 | } | ||
| 442 | |||
| 443 | 982 | av_shrink_packet(pkt, subtitle_out_size); | |
| 444 | 982 | pkt->time_base = AV_TIME_BASE_Q; | |
| 445 | 982 | pkt->pts = sub->pts; | |
| 446 | 982 | pkt->duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, pkt->time_base); | |
| 447 |
2/2✓ Branch 0 taken 72 times.
✓ Branch 1 taken 910 times.
|
982 | if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { |
| 448 | /* XXX: the pts correction is handled here. Maybe handling | ||
| 449 | it in the codec would be better */ | ||
| 450 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 36 times.
|
72 | if (i == 0) |
| 451 | 36 | pkt->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, pkt->time_base); | |
| 452 | else | ||
| 453 | 36 | pkt->pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, pkt->time_base); | |
| 454 | } | ||
| 455 | 982 | pkt->dts = pkt->pts; | |
| 456 | |||
| 457 | 982 | ret = sch_enc_send(ep->sch, ep->sch_idx, pkt); | |
| 458 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 982 times.
|
982 | if (ret < 0) { |
| 459 | ✗ | av_packet_unref(pkt); | |
| 460 | ✗ | return ret; | |
| 461 | } | ||
| 462 | } | ||
| 463 | |||
| 464 | 946 | return 0; | |
| 465 | } | ||
| 466 | |||
| 467 | ✗ | void enc_stats_write(OutputStream *ost, EncStats *es, | |
| 468 | const AVFrame *frame, const AVPacket *pkt, | ||
| 469 | uint64_t frame_num) | ||
| 470 | { | ||
| 471 | ✗ | Encoder *e = ost->enc; | |
| 472 | ✗ | EncoderPriv *ep = ep_from_enc(e); | |
| 473 | ✗ | AVIOContext *io = es->io; | |
| 474 | ✗ | AVRational tb = frame ? frame->time_base : pkt->time_base; | |
| 475 | ✗ | int64_t pts = frame ? frame->pts : pkt->pts; | |
| 476 | |||
| 477 | ✗ | AVRational tbi = (AVRational){ 0, 1}; | |
| 478 | ✗ | int64_t ptsi = INT64_MAX; | |
| 479 | |||
| 480 | ✗ | const FrameData *fd = NULL; | |
| 481 | |||
| 482 | ✗ | if (frame ? frame->opaque_ref : pkt->opaque_ref) { | |
| 483 | ✗ | fd = (const FrameData*)(frame ? frame->opaque_ref->data : pkt->opaque_ref->data); | |
| 484 | ✗ | tbi = fd->dec.tb; | |
| 485 | ✗ | ptsi = fd->dec.pts; | |
| 486 | } | ||
| 487 | |||
| 488 | ✗ | pthread_mutex_lock(&es->lock); | |
| 489 | |||
| 490 | ✗ | for (size_t i = 0; i < es->nb_components; i++) { | |
| 491 | ✗ | const EncStatsComponent *c = &es->components[i]; | |
| 492 | |||
| 493 | ✗ | switch (c->type) { | |
| 494 | ✗ | case ENC_STATS_LITERAL: avio_write (io, c->str, c->str_len); continue; | |
| 495 | ✗ | case ENC_STATS_FILE_IDX: avio_printf(io, "%d", ost->file->index); continue; | |
| 496 | ✗ | case ENC_STATS_STREAM_IDX: avio_printf(io, "%d", ost->index); continue; | |
| 497 | ✗ | case ENC_STATS_TIMEBASE: avio_printf(io, "%d/%d", tb.num, tb.den); continue; | |
| 498 | ✗ | case ENC_STATS_TIMEBASE_IN: avio_printf(io, "%d/%d", tbi.num, tbi.den); continue; | |
| 499 | ✗ | case ENC_STATS_PTS: avio_printf(io, "%"PRId64, pts); continue; | |
| 500 | ✗ | case ENC_STATS_PTS_IN: avio_printf(io, "%"PRId64, ptsi); continue; | |
| 501 | ✗ | case ENC_STATS_PTS_TIME: avio_printf(io, "%g", pts * av_q2d(tb)); continue; | |
| 502 | ✗ | case ENC_STATS_PTS_TIME_IN: avio_printf(io, "%g", ptsi == INT64_MAX ? | |
| 503 | ✗ | INFINITY : ptsi * av_q2d(tbi)); continue; | |
| 504 | ✗ | case ENC_STATS_FRAME_NUM: avio_printf(io, "%"PRIu64, frame_num); continue; | |
| 505 | ✗ | case ENC_STATS_FRAME_NUM_IN: avio_printf(io, "%"PRIu64, fd ? fd->dec.frame_num : -1); continue; | |
| 506 | } | ||
| 507 | |||
| 508 | ✗ | if (frame) { | |
| 509 | ✗ | switch (c->type) { | |
| 510 | ✗ | case ENC_STATS_SAMPLE_NUM: avio_printf(io, "%"PRIu64, e->samples_encoded); continue; | |
| 511 | ✗ | case ENC_STATS_NB_SAMPLES: avio_printf(io, "%d", frame->nb_samples); continue; | |
| 512 | ✗ | default: av_assert0(0); | |
| 513 | } | ||
| 514 | } else { | ||
| 515 | ✗ | switch (c->type) { | |
| 516 | ✗ | case ENC_STATS_DTS: avio_printf(io, "%"PRId64, pkt->dts); continue; | |
| 517 | ✗ | case ENC_STATS_DTS_TIME: avio_printf(io, "%g", pkt->dts * av_q2d(tb)); continue; | |
| 518 | ✗ | case ENC_STATS_PKT_SIZE: avio_printf(io, "%d", pkt->size); continue; | |
| 519 | ✗ | case ENC_STATS_KEYFRAME: avio_write(io, (pkt->flags & AV_PKT_FLAG_KEY) ? | |
| 520 | ✗ | "K" : "N", 1); continue; | |
| 521 | ✗ | case ENC_STATS_BITRATE: { | |
| 522 | ✗ | double duration = FFMAX(pkt->duration, 1) * av_q2d(tb); | |
| 523 | ✗ | avio_printf(io, "%g", 8.0 * pkt->size / duration); | |
| 524 | ✗ | continue; | |
| 525 | } | ||
| 526 | ✗ | case ENC_STATS_AVG_BITRATE: { | |
| 527 | ✗ | double duration = pkt->dts * av_q2d(tb); | |
| 528 | ✗ | avio_printf(io, "%g", duration > 0 ? 8.0 * ep->data_size / duration : -1.); | |
| 529 | ✗ | continue; | |
| 530 | } | ||
| 531 | ✗ | default: av_assert0(0); | |
| 532 | } | ||
| 533 | } | ||
| 534 | } | ||
| 535 | ✗ | avio_w8(io, '\n'); | |
| 536 | ✗ | avio_flush(io); | |
| 537 | |||
| 538 | ✗ | pthread_mutex_unlock(&es->lock); | |
| 539 | ✗ | } | |
| 540 | |||
| 541 | ✗ | static inline double psnr(double d) | |
| 542 | { | ||
| 543 | ✗ | return -10.0 * log10(d); | |
| 544 | } | ||
| 545 | |||
| 546 | 142968 | static int update_video_stats(OutputStream *ost, const AVPacket *pkt, int write_vstats) | |
| 547 | { | ||
| 548 | 142968 | Encoder *e = ost->enc; | |
| 549 | 142968 | EncoderPriv *ep = ep_from_enc(e); | |
| 550 | 142968 | const uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, | |
| 551 | NULL); | ||
| 552 | 142968 | AVCodecContext *enc = e->enc_ctx; | |
| 553 | enum AVPictureType pict_type; | ||
| 554 | int64_t frame_number; | ||
| 555 | double ti1, bitrate, avg_bitrate; | ||
| 556 | 142968 | double psnr_val = -1; | |
| 557 | int quality; | ||
| 558 | |||
| 559 |
2/2✓ Branch 0 taken 12838 times.
✓ Branch 1 taken 130130 times.
|
142968 | quality = sd ? AV_RL32(sd) : -1; |
| 560 |
2/2✓ Branch 0 taken 12838 times.
✓ Branch 1 taken 130130 times.
|
142968 | pict_type = sd ? sd[4] : AV_PICTURE_TYPE_NONE; |
| 561 | |||
| 562 | 142968 | atomic_store(&ost->quality, quality); | |
| 563 | |||
| 564 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 142968 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
142968 | if ((enc->flags & AV_CODEC_FLAG_PSNR) && sd && sd[5]) { |
| 565 | // FIXME the scaling assumes 8bit | ||
| 566 | ✗ | double error = AV_RL64(sd + 8) / (enc->width * enc->height * 255.0 * 255.0); | |
| 567 | ✗ | if (error >= 0 && error <= 1) | |
| 568 | ✗ | psnr_val = psnr(error); | |
| 569 | } | ||
| 570 | |||
| 571 |
1/2✓ Branch 0 taken 142968 times.
✗ Branch 1 not taken.
|
142968 | if (!write_vstats) |
| 572 | 142968 | return 0; | |
| 573 | |||
| 574 | /* this is executed just the first time update_video_stats is called */ | ||
| 575 | ✗ | if (!vstats_file) { | |
| 576 | ✗ | vstats_file = fopen(vstats_filename, "w"); | |
| 577 | ✗ | if (!vstats_file) { | |
| 578 | ✗ | perror("fopen"); | |
| 579 | ✗ | return AVERROR(errno); | |
| 580 | } | ||
| 581 | } | ||
| 582 | |||
| 583 | ✗ | frame_number = ep->packets_encoded; | |
| 584 | ✗ | if (vstats_version <= 1) { | |
| 585 | ✗ | fprintf(vstats_file, "frame= %5"PRId64" q= %2.1f ", frame_number, | |
| 586 | ✗ | quality / (float)FF_QP2LAMBDA); | |
| 587 | } else { | ||
| 588 | ✗ | fprintf(vstats_file, "out= %2d st= %2d frame= %5"PRId64" q= %2.1f ", | |
| 589 | ✗ | ost->file->index, ost->index, frame_number, | |
| 590 | ✗ | quality / (float)FF_QP2LAMBDA); | |
| 591 | } | ||
| 592 | |||
| 593 | ✗ | if (psnr_val >= 0) | |
| 594 | ✗ | fprintf(vstats_file, "PSNR= %6.2f ", psnr_val); | |
| 595 | |||
| 596 | ✗ | fprintf(vstats_file,"f_size= %6d ", pkt->size); | |
| 597 | /* compute pts value */ | ||
| 598 | ✗ | ti1 = pkt->dts * av_q2d(pkt->time_base); | |
| 599 | ✗ | if (ti1 < 0.01) | |
| 600 | ✗ | ti1 = 0.01; | |
| 601 | |||
| 602 | ✗ | bitrate = (pkt->size * 8) / av_q2d(enc->time_base) / 1000.0; | |
| 603 | ✗ | avg_bitrate = (double)(ep->data_size * 8) / ti1 / 1000.0; | |
| 604 | ✗ | fprintf(vstats_file, "s_size= %8.0fKiB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ", | |
| 605 | ✗ | (double)ep->data_size / 1024, ti1, bitrate, avg_bitrate); | |
| 606 | ✗ | fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(pict_type)); | |
| 607 | |||
| 608 | ✗ | return 0; | |
| 609 | } | ||
| 610 | |||
| 611 | 462868 | static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame, | |
| 612 | AVPacket *pkt) | ||
| 613 | { | ||
| 614 | 462868 | Encoder *e = ost->enc; | |
| 615 | 462868 | EncoderPriv *ep = ep_from_enc(e); | |
| 616 | 462868 | AVCodecContext *enc = e->enc_ctx; | |
| 617 | 462868 | const char *type_desc = av_get_media_type_string(enc->codec_type); | |
| 618 |
2/2✓ Branch 0 taken 454678 times.
✓ Branch 1 taken 8190 times.
|
462868 | const char *action = frame ? "encode" : "flush"; |
| 619 | int ret; | ||
| 620 | |||
| 621 |
2/2✓ Branch 0 taken 454678 times.
✓ Branch 1 taken 8190 times.
|
462868 | if (frame) { |
| 622 | 454678 | FrameData *fd = frame_data(frame); | |
| 623 | |||
| 624 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 454678 times.
|
454678 | if (!fd) |
| 625 | ✗ | return AVERROR(ENOMEM); | |
| 626 | |||
| 627 | 454678 | fd->wallclock[LATENCY_PROBE_ENC_PRE] = av_gettime_relative(); | |
| 628 | |||
| 629 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 454678 times.
|
454678 | if (ost->enc_stats_pre.io) |
| 630 | ✗ | enc_stats_write(ost, &ost->enc_stats_pre, frame, NULL, | |
| 631 | e->frames_encoded); | ||
| 632 | |||
| 633 | 454678 | e->frames_encoded++; | |
| 634 | 454678 | e->samples_encoded += frame->nb_samples; | |
| 635 | |||
| 636 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 454678 times.
|
454678 | if (debug_ts) { |
| 637 | ✗ | av_log(e, AV_LOG_INFO, "encoder <- type:%s " | |
| 638 | "frame_pts:%s frame_pts_time:%s time_base:%d/%d\n", | ||
| 639 | type_desc, | ||
| 640 | ✗ | av_ts2str(frame->pts), av_ts2timestr(frame->pts, &enc->time_base), | |
| 641 | enc->time_base.num, enc->time_base.den); | ||
| 642 | } | ||
| 643 | |||
| 644 |
3/4✓ Branch 0 taken 44857 times.
✓ Branch 1 taken 409821 times.
✓ Branch 2 taken 44857 times.
✗ Branch 3 not taken.
|
454678 | if (frame->sample_aspect_ratio.num && !ost->frame_aspect_ratio.num) |
| 645 | 44857 | enc->sample_aspect_ratio = frame->sample_aspect_ratio; | |
| 646 | } | ||
| 647 | |||
| 648 | 462868 | update_benchmark(NULL); | |
| 649 | |||
| 650 | 462868 | ret = avcodec_send_frame(enc, frame); | |
| 651 |
1/6✓ Branch 0 taken 462868 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
462868 | if (ret < 0 && !(ret == AVERROR_EOF && !frame)) { |
| 652 | ✗ | av_log(e, AV_LOG_ERROR, "Error submitting %s frame to the encoder\n", | |
| 653 | type_desc); | ||
| 654 | ✗ | return ret; | |
| 655 | } | ||
| 656 | |||
| 657 | 448622 | while (1) { | |
| 658 | FrameData *fd; | ||
| 659 | |||
| 660 | 911490 | av_packet_unref(pkt); | |
| 661 | |||
| 662 | 911490 | ret = avcodec_receive_packet(enc, pkt); | |
| 663 | 911490 | update_benchmark("%s_%s %d.%d", action, type_desc, | |
| 664 | of->index, ost->index); | ||
| 665 | |||
| 666 | 911490 | pkt->time_base = enc->time_base; | |
| 667 | |||
| 668 | /* if two pass, output log on success and EOF */ | ||
| 669 |
7/8✓ Branch 0 taken 462868 times.
✓ Branch 1 taken 448622 times.
✓ Branch 2 taken 8190 times.
✓ Branch 3 taken 454678 times.
✓ Branch 4 taken 408 times.
✓ Branch 5 taken 456404 times.
✓ Branch 6 taken 408 times.
✗ Branch 7 not taken.
|
911490 | if ((ret >= 0 || ret == AVERROR_EOF) && ost->logfile && enc->stats_out) |
| 670 | 408 | fprintf(ost->logfile, "%s", enc->stats_out); | |
| 671 | |||
| 672 |
2/2✓ Branch 0 taken 454678 times.
✓ Branch 1 taken 456812 times.
|
911490 | if (ret == AVERROR(EAGAIN)) { |
| 673 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 454678 times.
|
454678 | av_assert0(frame); // should never happen during flushing |
| 674 | 454678 | return 0; | |
| 675 |
2/2✓ Branch 0 taken 8190 times.
✓ Branch 1 taken 448622 times.
|
456812 | } else if (ret < 0) { |
| 676 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8190 times.
|
8190 | if (ret != AVERROR_EOF) |
| 677 | ✗ | av_log(e, AV_LOG_ERROR, "%s encoding failed\n", type_desc); | |
| 678 | 8190 | return ret; | |
| 679 | } | ||
| 680 | |||
| 681 | 448622 | fd = packet_data(pkt); | |
| 682 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 448622 times.
|
448622 | if (!fd) |
| 683 | ✗ | return AVERROR(ENOMEM); | |
| 684 | 448622 | fd->wallclock[LATENCY_PROBE_ENC_POST] = av_gettime_relative(); | |
| 685 | |||
| 686 | // attach stream parameters to first packet if requested | ||
| 687 | 448622 | avcodec_parameters_free(&fd->par_enc); | |
| 688 |
4/4✓ Branch 0 taken 50 times.
✓ Branch 1 taken 448572 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 49 times.
|
448622 | if (ep->attach_par && !ep->packets_encoded) { |
| 689 | 1 | fd->par_enc = avcodec_parameters_alloc(); | |
| 690 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!fd->par_enc) |
| 691 | ✗ | return AVERROR(ENOMEM); | |
| 692 | |||
| 693 | 1 | ret = avcodec_parameters_from_context(fd->par_enc, enc); | |
| 694 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (ret < 0) |
| 695 | ✗ | return ret; | |
| 696 | } | ||
| 697 | |||
| 698 | 448622 | pkt->flags |= AV_PKT_FLAG_TRUSTED; | |
| 699 | |||
| 700 |
2/2✓ Branch 0 taken 142968 times.
✓ Branch 1 taken 305654 times.
|
448622 | if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { |
| 701 | 142968 | ret = update_video_stats(ost, pkt, !!vstats_filename); | |
| 702 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 142968 times.
|
142968 | if (ret < 0) |
| 703 | ✗ | return ret; | |
| 704 | } | ||
| 705 | |||
| 706 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 448622 times.
|
448622 | if (ost->enc_stats_post.io) |
| 707 | ✗ | enc_stats_write(ost, &ost->enc_stats_post, NULL, pkt, | |
| 708 | ep->packets_encoded); | ||
| 709 | |||
| 710 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 448622 times.
|
448622 | if (debug_ts) { |
| 711 | ✗ | av_log(e, AV_LOG_INFO, "encoder -> type:%s " | |
| 712 | "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s " | ||
| 713 | "duration:%s duration_time:%s\n", | ||
| 714 | type_desc, | ||
| 715 | ✗ | av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base), | |
| 716 | ✗ | av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base), | |
| 717 | ✗ | av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base)); | |
| 718 | } | ||
| 719 | |||
| 720 | 448622 | ep->data_size += pkt->size; | |
| 721 | |||
| 722 | 448622 | ep->packets_encoded++; | |
| 723 | |||
| 724 | 448622 | ret = sch_enc_send(ep->sch, ep->sch_idx, pkt); | |
| 725 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 448622 times.
|
448622 | if (ret < 0) { |
| 726 | ✗ | av_packet_unref(pkt); | |
| 727 | ✗ | return ret; | |
| 728 | } | ||
| 729 | } | ||
| 730 | |||
| 731 | av_unreachable("encode_frame() loop should return"); | ||
| 732 | } | ||
| 733 | |||
| 734 | 142968 | static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf, | |
| 735 | const AVFrame *frame) | ||
| 736 | { | ||
| 737 | double pts_time; | ||
| 738 | |||
| 739 |
2/2✓ Branch 0 taken 6846 times.
✓ Branch 1 taken 136122 times.
|
142968 | if (kf->ref_pts == AV_NOPTS_VALUE) |
| 740 | 6846 | kf->ref_pts = frame->pts; | |
| 741 | |||
| 742 | 142968 | pts_time = (frame->pts - kf->ref_pts) * av_q2d(frame->time_base); | |
| 743 |
4/4✓ Branch 0 taken 39 times.
✓ Branch 1 taken 142929 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 37 times.
|
143007 | if (kf->index < kf->nb_pts && |
| 744 | 39 | av_compare_ts(frame->pts, frame->time_base, kf->pts[kf->index], AV_TIME_BASE_Q) >= 0) { | |
| 745 | 2 | kf->index++; | |
| 746 | 16 | goto force_keyframe; | |
| 747 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 142966 times.
|
142966 | } else if (kf->pexpr) { |
| 748 | double res; | ||
| 749 | ✗ | kf->expr_const_values[FKF_T] = pts_time; | |
| 750 | ✗ | res = av_expr_eval(kf->pexpr, | |
| 751 | ✗ | kf->expr_const_values, NULL); | |
| 752 | ✗ | av_log(logctx, AV_LOG_TRACE, | |
| 753 | "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n", | ||
| 754 | kf->expr_const_values[FKF_N], | ||
| 755 | kf->expr_const_values[FKF_N_FORCED], | ||
| 756 | kf->expr_const_values[FKF_PREV_FORCED_N], | ||
| 757 | kf->expr_const_values[FKF_T], | ||
| 758 | kf->expr_const_values[FKF_PREV_FORCED_T], | ||
| 759 | res); | ||
| 760 | |||
| 761 | ✗ | kf->expr_const_values[FKF_N] += 1; | |
| 762 | |||
| 763 | ✗ | if (res) { | |
| 764 | ✗ | kf->expr_const_values[FKF_PREV_FORCED_N] = kf->expr_const_values[FKF_N] - 1; | |
| 765 | ✗ | kf->expr_const_values[FKF_PREV_FORCED_T] = kf->expr_const_values[FKF_T]; | |
| 766 | ✗ | kf->expr_const_values[FKF_N_FORCED] += 1; | |
| 767 | ✗ | goto force_keyframe; | |
| 768 | } | ||
| 769 |
4/4✓ Branch 0 taken 1021 times.
✓ Branch 1 taken 141945 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 1012 times.
|
142966 | } else if (kf->type == KF_FORCE_SOURCE && (frame->flags & AV_FRAME_FLAG_KEY)) { |
| 770 | 9 | goto force_keyframe; | |
| 771 |
4/4✓ Branch 0 taken 392 times.
✓ Branch 1 taken 142565 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 387 times.
|
143349 | } else if (kf->type == KF_FORCE_SCD_METADATA && |
| 772 | 392 | av_dict_get(frame->metadata, "lavfi.scd.time", NULL, 0)) { | |
| 773 | 5 | goto force_keyframe; | |
| 774 | } | ||
| 775 | |||
| 776 | 142952 | return AV_PICTURE_TYPE_NONE; | |
| 777 | |||
| 778 | 16 | force_keyframe: | |
| 779 | 16 | av_log(logctx, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time); | |
| 780 | 16 | return AV_PICTURE_TYPE_I; | |
| 781 | } | ||
| 782 | |||
| 783 | 463954 | static int frame_encode(OutputStream *ost, AVFrame *frame, AVPacket *pkt) | |
| 784 | { | ||
| 785 | 463954 | Encoder *e = ost->enc; | |
| 786 | 463954 | OutputFile *of = ost->file; | |
| 787 | 463954 | enum AVMediaType type = ost->type; | |
| 788 | |||
| 789 |
2/2✓ Branch 0 taken 1085 times.
✓ Branch 1 taken 462869 times.
|
463954 | if (type == AVMEDIA_TYPE_SUBTITLE) { |
| 790 |
2/2✓ Branch 0 taken 955 times.
✓ Branch 1 taken 88 times.
|
1043 | const AVSubtitle *subtitle = frame && frame->buf[0] ? |
| 791 |
2/2✓ Branch 0 taken 1043 times.
✓ Branch 1 taken 42 times.
|
2128 | (AVSubtitle*)frame->buf[0]->data : NULL; |
| 792 | |||
| 793 | // no flushing for subtitles | ||
| 794 |
2/2✓ Branch 0 taken 946 times.
✓ Branch 1 taken 9 times.
|
955 | return subtitle && subtitle->num_rects ? |
| 795 |
2/2✓ Branch 0 taken 955 times.
✓ Branch 1 taken 130 times.
|
2040 | do_subtitle_out(of, ost, subtitle, pkt) : 0; |
| 796 | } | ||
| 797 | |||
| 798 |
2/2✓ Branch 0 taken 454679 times.
✓ Branch 1 taken 8190 times.
|
462869 | if (frame) { |
| 799 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 454678 times.
|
454679 | if (!check_recording_time(ost, frame->pts, frame->time_base)) |
| 800 | 1 | return AVERROR_EOF; | |
| 801 | |||
| 802 |
2/2✓ Branch 0 taken 142968 times.
✓ Branch 1 taken 311710 times.
|
454678 | if (type == AVMEDIA_TYPE_VIDEO) { |
| 803 | 142968 | frame->quality = e->enc_ctx->global_quality; | |
| 804 | 142968 | frame->pict_type = forced_kf_apply(e, &ost->kf, frame); | |
| 805 | |||
| 806 | #if FFMPEG_OPT_TOP | ||
| 807 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 142968 times.
|
142968 | if (ost->top_field_first >= 0) { |
| 808 | ✗ | frame->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; | |
| 809 | ✗ | frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * (!!ost->top_field_first); | |
| 810 | } | ||
| 811 | #endif | ||
| 812 | } else { | ||
| 813 |
1/2✓ Branch 0 taken 311710 times.
✗ Branch 1 not taken.
|
311710 | if (!(e->enc_ctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE) && |
| 814 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 311710 times.
|
311710 | e->enc_ctx->ch_layout.nb_channels != frame->ch_layout.nb_channels) { |
| 815 | ✗ | av_log(e, AV_LOG_ERROR, | |
| 816 | "Audio channel count changed and encoder does not support parameter changes\n"); | ||
| 817 | ✗ | return 0; | |
| 818 | } | ||
| 819 | } | ||
| 820 | } | ||
| 821 | |||
| 822 | 462868 | return encode_frame(of, ost, frame, pkt); | |
| 823 | } | ||
| 824 | |||
| 825 | 8229 | static void enc_thread_set_name(const OutputStream *ost) | |
| 826 | { | ||
| 827 | char name[16]; | ||
| 828 | 8229 | snprintf(name, sizeof(name), "enc%d:%d:%s", ost->file->index, ost->index, | |
| 829 | 8229 | ost->enc->enc_ctx->codec->name); | |
| 830 | 8229 | ff_thread_setname(name); | |
| 831 | 8229 | } | |
| 832 | |||
| 833 | 8232 | static void enc_thread_uninit(EncoderThread *et) | |
| 834 | { | ||
| 835 | 8232 | av_packet_free(&et->pkt); | |
| 836 | 8232 | av_frame_free(&et->frame); | |
| 837 | |||
| 838 | 8232 | memset(et, 0, sizeof(*et)); | |
| 839 | 8232 | } | |
| 840 | |||
| 841 | 8232 | static int enc_thread_init(EncoderThread *et) | |
| 842 | { | ||
| 843 | 8232 | memset(et, 0, sizeof(*et)); | |
| 844 | |||
| 845 | 8232 | et->frame = av_frame_alloc(); | |
| 846 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8232 times.
|
8232 | if (!et->frame) |
| 847 | ✗ | goto fail; | |
| 848 | |||
| 849 | 8232 | et->pkt = av_packet_alloc(); | |
| 850 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8232 times.
|
8232 | if (!et->pkt) |
| 851 | ✗ | goto fail; | |
| 852 | |||
| 853 | 8232 | return 0; | |
| 854 | |||
| 855 | ✗ | fail: | |
| 856 | ✗ | enc_thread_uninit(et); | |
| 857 | ✗ | return AVERROR(ENOMEM); | |
| 858 | } | ||
| 859 | |||
| 860 | 8232 | int encoder_thread(void *arg) | |
| 861 | { | ||
| 862 | 8232 | OutputStream *ost = arg; | |
| 863 | 8232 | Encoder *e = ost->enc; | |
| 864 | 8232 | EncoderPriv *ep = ep_from_enc(e); | |
| 865 | EncoderThread et; | ||
| 866 | 8232 | int ret = 0, input_status = 0; | |
| 867 | 8232 | int name_set = 0; | |
| 868 | |||
| 869 | 8232 | ret = enc_thread_init(&et); | |
| 870 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8232 times.
|
8232 | if (ret < 0) |
| 871 | ✗ | goto finish; | |
| 872 | |||
| 873 | /* Open the subtitle encoders immediately. AVFrame-based encoders | ||
| 874 | * are opened through a callback from the scheduler once they get | ||
| 875 | * their first frame | ||
| 876 | * | ||
| 877 | * N.B.: because the callback is called from a different thread, | ||
| 878 | * enc_ctx MUST NOT be accessed before sch_enc_receive() returns | ||
| 879 | * for the first time for audio/video. */ | ||
| 880 |
4/4✓ Branch 0 taken 1385 times.
✓ Branch 1 taken 6847 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 1343 times.
|
8232 | if (ost->type != AVMEDIA_TYPE_VIDEO && ost->type != AVMEDIA_TYPE_AUDIO) { |
| 881 | 42 | ret = enc_open(ost, NULL); | |
| 882 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
|
42 | if (ret < 0) |
| 883 | ✗ | goto finish; | |
| 884 | } | ||
| 885 | |||
| 886 |
1/2✓ Branch 0 taken 463953 times.
✗ Branch 1 not taken.
|
463953 | while (!input_status) { |
| 887 | 463953 | input_status = sch_enc_receive(ep->sch, ep->sch_idx, et.frame); | |
| 888 |
2/2✓ Branch 0 taken 8231 times.
✓ Branch 1 taken 455722 times.
|
463953 | if (input_status < 0) { |
| 889 |
1/2✓ Branch 0 taken 8231 times.
✗ Branch 1 not taken.
|
8231 | if (input_status == AVERROR_EOF) { |
| 890 | 8231 | av_log(e, AV_LOG_VERBOSE, "Encoder thread received EOF\n"); | |
| 891 |
1/2✓ Branch 0 taken 8231 times.
✗ Branch 1 not taken.
|
8231 | if (ep->opened) |
| 892 | 8231 | break; | |
| 893 | |||
| 894 | ✗ | av_log(e, AV_LOG_ERROR, "Could not open encoder before EOF\n"); | |
| 895 | ✗ | ret = AVERROR(EINVAL); | |
| 896 | } else { | ||
| 897 | ✗ | av_log(e, AV_LOG_ERROR, "Error receiving a frame for encoding: %s\n", | |
| 898 | ✗ | av_err2str(ret)); | |
| 899 | ✗ | ret = input_status; | |
| 900 | } | ||
| 901 | ✗ | goto finish; | |
| 902 | } | ||
| 903 | |||
| 904 |
2/2✓ Branch 0 taken 8229 times.
✓ Branch 1 taken 447493 times.
|
455722 | if (!name_set) { |
| 905 | 8229 | enc_thread_set_name(ost); | |
| 906 | 8229 | name_set = 1; | |
| 907 | } | ||
| 908 | |||
| 909 | 455722 | ret = frame_encode(ost, et.frame, et.pkt); | |
| 910 | |||
| 911 | 455722 | av_packet_unref(et.pkt); | |
| 912 | 455722 | av_frame_unref(et.frame); | |
| 913 | |||
| 914 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 455721 times.
|
455722 | if (ret < 0) { |
| 915 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ret == AVERROR_EOF) |
| 916 | 1 | av_log(e, AV_LOG_VERBOSE, "Encoder returned EOF, finishing\n"); | |
| 917 | else | ||
| 918 | ✗ | av_log(e, AV_LOG_ERROR, "Error encoding a frame: %s\n", | |
| 919 | ✗ | av_err2str(ret)); | |
| 920 | 1 | break; | |
| 921 | } | ||
| 922 | } | ||
| 923 | |||
| 924 | // flush the encoder | ||
| 925 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8231 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
8232 | if (ret == 0 || ret == AVERROR_EOF) { |
| 926 | 8232 | ret = frame_encode(ost, NULL, et.pkt); | |
| 927 |
3/4✓ Branch 0 taken 8190 times.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8190 times.
|
8232 | if (ret < 0 && ret != AVERROR_EOF) |
| 928 | ✗ | av_log(e, AV_LOG_ERROR, "Error flushing encoder: %s\n", | |
| 929 | ✗ | av_err2str(ret)); | |
| 930 | } | ||
| 931 | |||
| 932 | // EOF is normal thread termination | ||
| 933 |
2/2✓ Branch 0 taken 42 times.
✓ Branch 1 taken 8190 times.
|
8232 | if (ret == AVERROR_EOF) |
| 934 | 8190 | ret = 0; | |
| 935 | |||
| 936 | 42 | finish: | |
| 937 | 8232 | enc_thread_uninit(&et); | |
| 938 | |||
| 939 | 8232 | return ret; | |
| 940 | } | ||
| 941 | |||
| 942 | 1 | int enc_loopback(Encoder *enc) | |
| 943 | { | ||
| 944 | 1 | EncoderPriv *ep = ep_from_enc(enc); | |
| 945 | 1 | ep->attach_par = 1; | |
| 946 | 1 | return ep->sch_idx; | |
| 947 | } | ||
| 948 |