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