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