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