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