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