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/pixdesc.h" | ||
34 | #include "libavutil/rational.h" | ||
35 | #include "libavutil/timestamp.h" | ||
36 | |||
37 | #include "libavcodec/avcodec.h" | ||
38 | |||
39 | #include "libavformat/avformat.h" | ||
40 | |||
41 | struct Encoder { | ||
42 | AVFrame *sq_frame; | ||
43 | |||
44 | // packet for receiving encoded output | ||
45 | AVPacket *pkt; | ||
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 | }; | ||
55 | |||
56 | 6968 | void enc_free(Encoder **penc) | |
57 | { | ||
58 | 6968 | Encoder *enc = *penc; | |
59 | |||
60 |
2/2✓ Branch 0 taken 568 times.
✓ Branch 1 taken 6400 times.
|
6968 | if (!enc) |
61 | 568 | return; | |
62 | |||
63 | 6400 | av_frame_free(&enc->sq_frame); | |
64 | |||
65 | 6400 | av_packet_free(&enc->pkt); | |
66 | |||
67 | 6400 | av_freep(penc); | |
68 | } | ||
69 | |||
70 | 6400 | int enc_alloc(Encoder **penc, const AVCodec *codec) | |
71 | { | ||
72 | Encoder *enc; | ||
73 | |||
74 | 6400 | *penc = NULL; | |
75 | |||
76 | 6400 | enc = av_mallocz(sizeof(*enc)); | |
77 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
|
6400 | if (!enc) |
78 | ✗ | return AVERROR(ENOMEM); | |
79 | |||
80 | 6400 | enc->pkt = av_packet_alloc(); | |
81 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
|
6400 | if (!enc->pkt) |
82 | ✗ | goto fail; | |
83 | |||
84 | 6400 | *penc = enc; | |
85 | |||
86 | 6400 | return 0; | |
87 | ✗ | fail: | |
88 | ✗ | enc_free(&enc); | |
89 | ✗ | return AVERROR(ENOMEM); | |
90 | } | ||
91 | |||
92 | 6400 | static int hw_device_setup_for_encode(OutputStream *ost, AVBufferRef *frames_ref) | |
93 | { | ||
94 | const AVCodecHWConfig *config; | ||
95 | 6400 | HWDevice *dev = NULL; | |
96 | int i; | ||
97 | |||
98 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
|
6400 | if (frames_ref && |
99 | ✗ | ((AVHWFramesContext*)frames_ref->data)->format == | |
100 | ✗ | ost->enc_ctx->pix_fmt) { | |
101 | // Matching format, will try to use hw_frames_ctx. | ||
102 | } else { | ||
103 | 6400 | frames_ref = NULL; | |
104 | } | ||
105 | |||
106 | 6400 | for (i = 0;; i++) { | |
107 | 6400 | config = avcodec_get_hw_config(ost->enc_ctx->codec, i); | |
108 |
1/2✓ Branch 0 taken 6400 times.
✗ Branch 1 not taken.
|
6400 | if (!config) |
109 | 6400 | break; | |
110 | |||
111 | ✗ | if (frames_ref && | |
112 | ✗ | config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX && | |
113 | ✗ | (config->pix_fmt == AV_PIX_FMT_NONE || | |
114 | ✗ | config->pix_fmt == ost->enc_ctx->pix_fmt)) { | |
115 | ✗ | av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using input " | |
116 | "frames context (format %s) with %s encoder.\n", | ||
117 | ✗ | av_get_pix_fmt_name(ost->enc_ctx->pix_fmt), | |
118 | ✗ | ost->enc_ctx->codec->name); | |
119 | ✗ | ost->enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref); | |
120 | ✗ | if (!ost->enc_ctx->hw_frames_ctx) | |
121 | ✗ | return AVERROR(ENOMEM); | |
122 | ✗ | return 0; | |
123 | } | ||
124 | |||
125 | ✗ | if (!dev && | |
126 | ✗ | config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) | |
127 | ✗ | dev = hw_device_get_by_type(config->device_type); | |
128 | } | ||
129 | |||
130 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
|
6400 | if (dev) { |
131 | ✗ | av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using device %s " | |
132 | "(type %s) with %s encoder.\n", dev->name, | ||
133 | ✗ | av_hwdevice_get_type_name(dev->type), ost->enc_ctx->codec->name); | |
134 | ✗ | ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref); | |
135 | ✗ | if (!ost->enc_ctx->hw_device_ctx) | |
136 | ✗ | return AVERROR(ENOMEM); | |
137 | } else { | ||
138 | // No device required, or no device available. | ||
139 | } | ||
140 | 6400 | return 0; | |
141 | } | ||
142 | |||
143 | 6400 | static int set_encoder_id(OutputFile *of, OutputStream *ost) | |
144 | { | ||
145 | 6400 | const char *cname = ost->enc_ctx->codec->name; | |
146 | uint8_t *encoder_string; | ||
147 | int encoder_string_len; | ||
148 | |||
149 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6400 times.
|
6400 | if (av_dict_get(ost->st->metadata, "encoder", NULL, 0)) |
150 | ✗ | return 0; | |
151 | |||
152 | 6400 | encoder_string_len = sizeof(LIBAVCODEC_IDENT) + strlen(cname) + 2; | |
153 | 6400 | encoder_string = av_mallocz(encoder_string_len); | |
154 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
|
6400 | if (!encoder_string) |
155 | ✗ | return AVERROR(ENOMEM); | |
156 | |||
157 |
4/4✓ Branch 0 taken 841 times.
✓ Branch 1 taken 5559 times.
✓ Branch 2 taken 834 times.
✓ Branch 3 taken 7 times.
|
6400 | if (!of->bitexact && !ost->bitexact) |
158 | 834 | av_strlcpy(encoder_string, LIBAVCODEC_IDENT " ", encoder_string_len); | |
159 | else | ||
160 | 5566 | av_strlcpy(encoder_string, "Lavc ", encoder_string_len); | |
161 | 6400 | av_strlcat(encoder_string, cname, encoder_string_len); | |
162 | 6400 | av_dict_set(&ost->st->metadata, "encoder", encoder_string, | |
163 | AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_OVERWRITE); | ||
164 | |||
165 | 6400 | return 0; | |
166 | } | ||
167 | |||
168 | 406268 | int enc_open(OutputStream *ost, const AVFrame *frame) | |
169 | { | ||
170 | 406268 | InputStream *ist = ost->ist; | |
171 | 406268 | Encoder *e = ost->enc; | |
172 | 406268 | AVCodecContext *enc_ctx = ost->enc_ctx; | |
173 | 406268 | AVCodecContext *dec_ctx = NULL; | |
174 | 406268 | const AVCodec *enc = enc_ctx->codec; | |
175 | 406268 | OutputFile *of = output_files[ost->file_index]; | |
176 | FrameData *fd; | ||
177 | int ret; | ||
178 | |||
179 |
2/2✓ Branch 0 taken 399868 times.
✓ Branch 1 taken 6400 times.
|
406268 | if (e->opened) |
180 | 399868 | return 0; | |
181 | |||
182 | // frame is always non-NULL for audio and video | ||
183 |
4/6✓ Branch 0 taken 38 times.
✓ Branch 1 taken 6362 times.
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 38 times.
|
6400 | av_assert0(frame || (enc->type != AVMEDIA_TYPE_VIDEO && enc->type != AVMEDIA_TYPE_AUDIO)); |
184 | |||
185 |
2/2✓ Branch 0 taken 6362 times.
✓ Branch 1 taken 38 times.
|
6400 | if (frame) { |
186 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6362 times.
|
6362 | av_assert0(frame->opaque_ref); |
187 | 6362 | fd = (FrameData*)frame->opaque_ref->data; | |
188 | } | ||
189 | |||
190 | 6400 | ret = set_encoder_id(output_files[ost->file_index], ost); | |
191 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
|
6400 | if (ret < 0) |
192 | ✗ | return ret; | |
193 | |||
194 |
2/2✓ Branch 0 taken 6272 times.
✓ Branch 1 taken 128 times.
|
6400 | if (ist) { |
195 | 6272 | dec_ctx = ist->dec_ctx; | |
196 | } | ||
197 | |||
198 | // the timebase is chosen by filtering code | ||
199 |
4/4✓ Branch 0 taken 5190 times.
✓ Branch 1 taken 1210 times.
✓ Branch 2 taken 5152 times.
✓ Branch 3 taken 38 times.
|
6400 | if (ost->type == AVMEDIA_TYPE_AUDIO || ost->type == AVMEDIA_TYPE_VIDEO) { |
200 | 6362 | enc_ctx->time_base = frame->time_base; | |
201 | 6362 | enc_ctx->framerate = fd->frame_rate_filter; | |
202 | 6362 | ost->st->avg_frame_rate = fd->frame_rate_filter; | |
203 | } | ||
204 | |||
205 |
3/4✓ Branch 0 taken 1210 times.
✓ Branch 1 taken 5152 times.
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
|
6400 | switch (enc_ctx->codec_type) { |
206 | 1210 | case AVMEDIA_TYPE_AUDIO: | |
207 | 1210 | enc_ctx->sample_fmt = frame->format; | |
208 | 1210 | enc_ctx->sample_rate = frame->sample_rate; | |
209 | 1210 | ret = av_channel_layout_copy(&enc_ctx->ch_layout, &frame->ch_layout); | |
210 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1210 times.
|
1210 | if (ret < 0) |
211 | ✗ | return ret; | |
212 | |||
213 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1210 times.
|
1210 | if (ost->bits_per_raw_sample) |
214 | ✗ | enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample; | |
215 | else | ||
216 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1210 times.
|
1210 | enc_ctx->bits_per_raw_sample = FFMIN(fd->bits_per_raw_sample, |
217 | av_get_bytes_per_sample(enc_ctx->sample_fmt) << 3); | ||
218 | 1210 | break; | |
219 | |||
220 | 5152 | case AVMEDIA_TYPE_VIDEO: { | |
221 | 5152 | enc_ctx->width = frame->width; | |
222 | 5152 | enc_ctx->height = frame->height; | |
223 | 10304 | enc_ctx->sample_aspect_ratio = ost->st->sample_aspect_ratio = | |
224 | 5152 | ost->frame_aspect_ratio.num ? // overridden by the -aspect cli option | |
225 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5152 times.
|
5152 | av_mul_q(ost->frame_aspect_ratio, (AVRational){ enc_ctx->height, enc_ctx->width }) : |
226 | frame->sample_aspect_ratio; | ||
227 | |||
228 | 5152 | enc_ctx->pix_fmt = frame->format; | |
229 | |||
230 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5151 times.
|
5152 | if (ost->bits_per_raw_sample) |
231 | 1 | enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample; | |
232 | else | ||
233 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5151 times.
|
5151 | enc_ctx->bits_per_raw_sample = FFMIN(fd->bits_per_raw_sample, |
234 | av_pix_fmt_desc_get(enc_ctx->pix_fmt)->comp[0].depth); | ||
235 | |||
236 | 5152 | enc_ctx->color_range = frame->color_range; | |
237 | 5152 | enc_ctx->color_primaries = frame->color_primaries; | |
238 | 5152 | enc_ctx->color_trc = frame->color_trc; | |
239 | 5152 | enc_ctx->colorspace = frame->colorspace; | |
240 | 5152 | enc_ctx->chroma_sample_location = frame->chroma_location; | |
241 | |||
242 |
1/2✓ Branch 0 taken 5152 times.
✗ Branch 1 not taken.
|
5152 | if (enc_ctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) || |
243 |
2/2✓ Branch 0 taken 4745 times.
✓ Branch 1 taken 407 times.
|
5152 | (frame->flags & AV_FRAME_FLAG_INTERLACED) |
244 | #if FFMPEG_OPT_TOP | ||
245 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4745 times.
|
4745 | || ost->top_field_first >= 0 |
246 | #endif | ||
247 | 407 | ) { | |
248 | 407 | int top_field_first = | |
249 | #if FFMPEG_OPT_TOP | ||
250 | 407 | ost->top_field_first >= 0 ? | |
251 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
|
407 | ost->top_field_first : |
252 | #endif | ||
253 | 407 | !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST); | |
254 | |||
255 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 406 times.
|
407 | if (enc->id == AV_CODEC_ID_MJPEG) |
256 |
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; |
257 | else | ||
258 |
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; |
259 | } else | ||
260 | 4745 | enc_ctx->field_order = AV_FIELD_PROGRESSIVE; | |
261 | |||
262 | 5152 | break; | |
263 | } | ||
264 | 38 | case AVMEDIA_TYPE_SUBTITLE: | |
265 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
|
38 | if (ost->enc_timebase.num) |
266 | ✗ | av_log(ost, AV_LOG_WARNING, | |
267 | "-enc_time_base not supported for subtitles, ignoring\n"); | ||
268 | 38 | enc_ctx->time_base = AV_TIME_BASE_Q; | |
269 | |||
270 |
1/2✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
|
38 | if (!enc_ctx->width) { |
271 | 38 | enc_ctx->width = ost->ist->par->width; | |
272 | 38 | enc_ctx->height = ost->ist->par->height; | |
273 | } | ||
274 |
3/4✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 2 times.
|
38 | if (dec_ctx && dec_ctx->subtitle_header) { |
275 | /* ASS code assumes this buffer is null terminated so add extra byte. */ | ||
276 | 36 | enc_ctx->subtitle_header = av_mallocz(dec_ctx->subtitle_header_size + 1); | |
277 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
|
36 | if (!enc_ctx->subtitle_header) |
278 | ✗ | return AVERROR(ENOMEM); | |
279 | 36 | memcpy(enc_ctx->subtitle_header, dec_ctx->subtitle_header, | |
280 | 36 | dec_ctx->subtitle_header_size); | |
281 | 36 | enc_ctx->subtitle_header_size = dec_ctx->subtitle_header_size; | |
282 | } | ||
283 | |||
284 | 38 | break; | |
285 | ✗ | default: | |
286 | ✗ | av_assert0(0); | |
287 | break; | ||
288 | } | ||
289 | |||
290 |
2/2✓ Branch 0 taken 5516 times.
✓ Branch 1 taken 884 times.
|
6400 | if (ost->bitexact) |
291 | 5516 | enc_ctx->flags |= AV_CODEC_FLAG_BITEXACT; | |
292 | |||
293 |
2/2✓ Branch 1 taken 2610 times.
✓ Branch 2 taken 3790 times.
|
6400 | if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0)) |
294 | 2610 | av_dict_set(&ost->encoder_opts, "threads", "auto", 0); | |
295 | |||
296 |
2/2✓ Branch 0 taken 6337 times.
✓ Branch 1 taken 63 times.
|
6400 | if (enc->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE) { |
297 | 6337 | ret = av_dict_set(&ost->encoder_opts, "flags", "+copy_opaque", AV_DICT_MULTIKEY); | |
298 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6337 times.
|
6337 | if (ret < 0) |
299 | ✗ | return ret; | |
300 | } | ||
301 | |||
302 | 6400 | av_dict_set(&ost->encoder_opts, "flags", "+frame_duration", AV_DICT_MULTIKEY); | |
303 | |||
304 |
2/2✓ Branch 0 taken 6362 times.
✓ Branch 1 taken 38 times.
|
6400 | ret = hw_device_setup_for_encode(ost, frame ? frame->hw_frames_ctx : NULL); |
305 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
|
6400 | if (ret < 0) { |
306 | ✗ | av_log(ost, AV_LOG_ERROR, | |
307 | ✗ | "Encoding hardware device setup failed: %s\n", av_err2str(ret)); | |
308 | ✗ | return ret; | |
309 | } | ||
310 | |||
311 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6400 times.
|
6400 | if ((ret = avcodec_open2(ost->enc_ctx, enc, &ost->encoder_opts)) < 0) { |
312 | ✗ | if (ret != AVERROR_EXPERIMENTAL) | |
313 | ✗ | av_log(ost, AV_LOG_ERROR, "Error while opening encoder - maybe " | |
314 | "incorrect parameters such as bit_rate, rate, width or height.\n"); | ||
315 | ✗ | return ret; | |
316 | } | ||
317 | |||
318 | 6400 | e->opened = 1; | |
319 | |||
320 |
2/2✓ Branch 0 taken 2782 times.
✓ Branch 1 taken 3618 times.
|
6400 | if (ost->sq_idx_encode >= 0) { |
321 | 2782 | e->sq_frame = av_frame_alloc(); | |
322 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2782 times.
|
2782 | if (!e->sq_frame) |
323 | ✗ | return AVERROR(ENOMEM); | |
324 | } | ||
325 | |||
326 |
2/2✓ Branch 0 taken 120 times.
✓ Branch 1 taken 6280 times.
|
6400 | if (ost->enc_ctx->frame_size) { |
327 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
|
120 | av_assert0(ost->sq_idx_encode >= 0); |
328 | 120 | sq_frame_samples(output_files[ost->file_index]->sq_encode, | |
329 | 120 | ost->sq_idx_encode, ost->enc_ctx->frame_size); | |
330 | } | ||
331 | |||
332 | 6400 | ret = check_avoptions(ost->encoder_opts); | |
333 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
|
6400 | if (ret < 0) |
334 | ✗ | return ret; | |
335 | |||
336 |
4/4✓ Branch 0 taken 6361 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 6360 times.
|
6400 | if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000 && |
337 |
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 */) |
338 | 1 | av_log(ost, AV_LOG_WARNING, "The bitrate parameter is set too low." | |
339 | " It takes bits/s as argument, not kbits/s\n"); | ||
340 | |||
341 | 6400 | ret = avcodec_parameters_from_context(ost->par_in, ost->enc_ctx); | |
342 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
|
6400 | if (ret < 0) { |
343 | ✗ | av_log(ost, AV_LOG_FATAL, | |
344 | "Error initializing the output stream codec context.\n"); | ||
345 | ✗ | return ret; | |
346 | } | ||
347 | |||
348 | /* | ||
349 | * Add global input side data. For now this is naive, and copies it | ||
350 | * from the input stream's global side data. All side data should | ||
351 | * really be funneled over AVFrame and libavfilter, then added back to | ||
352 | * packet side data, and then potentially using the first packet for | ||
353 | * global side data. | ||
354 | */ | ||
355 |
2/2✓ Branch 0 taken 6272 times.
✓ Branch 1 taken 128 times.
|
6400 | if (ist) { |
356 | int i; | ||
357 |
2/2✓ Branch 0 taken 283 times.
✓ Branch 1 taken 6272 times.
|
6555 | for (i = 0; i < ist->st->codecpar->nb_coded_side_data; i++) { |
358 | 283 | AVPacketSideData *sd_src = &ist->st->codecpar->coded_side_data[i]; | |
359 |
2/2✓ Branch 0 taken 214 times.
✓ Branch 1 taken 69 times.
|
283 | if (sd_src->type != AV_PKT_DATA_CPB_PROPERTIES) { |
360 | 214 | AVPacketSideData *sd_dst = av_packet_side_data_new(&ost->par_in->coded_side_data, | |
361 | 214 | &ost->par_in->nb_coded_side_data, | |
362 | sd_src->type, sd_src->size, 0); | ||
363 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 214 times.
|
214 | if (!sd_dst) |
364 | ✗ | return AVERROR(ENOMEM); | |
365 | 214 | memcpy(sd_dst->data, sd_src->data, sd_src->size); | |
366 |
3/4✓ Branch 0 taken 214 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 213 times.
|
214 | if (ist->autorotate && sd_src->type == AV_PKT_DATA_DISPLAYMATRIX) |
367 | 1 | av_display_rotation_set((int32_t *)sd_dst->data, 0); | |
368 | } | ||
369 | } | ||
370 | } | ||
371 | |||
372 | // copy timebase while removing common factors | ||
373 |
3/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6398 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
6400 | if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) |
374 | 6398 | ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1}); | |
375 | |||
376 | 6400 | ret = of_stream_init(of, ost); | |
377 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
|
6400 | if (ret < 0) |
378 | ✗ | return ret; | |
379 | |||
380 | 6400 | return 0; | |
381 | } | ||
382 | |||
383 | 407055 | static int check_recording_time(OutputStream *ost, int64_t ts, AVRational tb) | |
384 | { | ||
385 | 407055 | OutputFile *of = output_files[ost->file_index]; | |
386 | |||
387 |
4/4✓ Branch 0 taken 8182 times.
✓ Branch 1 taken 398873 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 8181 times.
|
415237 | if (of->recording_time != INT64_MAX && |
388 | 8182 | av_compare_ts(ts, tb, of->recording_time, AV_TIME_BASE_Q) >= 0) { | |
389 | 1 | close_output_stream(ost); | |
390 | 1 | return 0; | |
391 | } | ||
392 | 407054 | return 1; | |
393 | } | ||
394 | |||
395 | 792 | int enc_subtitle(OutputFile *of, OutputStream *ost, const AVSubtitle *sub) | |
396 | { | ||
397 | 792 | Encoder *e = ost->enc; | |
398 | 792 | int subtitle_out_max_size = 1024 * 1024; | |
399 | int subtitle_out_size, nb, i, ret; | ||
400 | AVCodecContext *enc; | ||
401 | 792 | AVPacket *pkt = e->pkt; | |
402 | int64_t pts; | ||
403 | |||
404 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 792 times.
|
792 | if (sub->pts == AV_NOPTS_VALUE) { |
405 | ✗ | av_log(ost, AV_LOG_ERROR, "Subtitle packets must have a pts\n"); | |
406 | ✗ | return exit_on_error ? AVERROR(EINVAL) : 0; | |
407 | } | ||
408 |
1/2✓ Branch 0 taken 792 times.
✗ Branch 1 not taken.
|
792 | if (ost->finished || |
409 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 792 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
792 | (of->start_time != AV_NOPTS_VALUE && sub->pts < of->start_time)) |
410 | ✗ | return 0; | |
411 | |||
412 | 792 | enc = ost->enc_ctx; | |
413 | |||
414 | /* Note: DVB subtitle need one packet to draw them and one other | ||
415 | packet to clear them */ | ||
416 | /* XXX: signal it in the codec context ? */ | ||
417 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 756 times.
|
792 | if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) |
418 | 36 | nb = 2; | |
419 |
2/2✓ Branch 0 taken 450 times.
✓ Branch 1 taken 306 times.
|
756 | else if (enc->codec_id == AV_CODEC_ID_ASS) |
420 | 450 | nb = FFMAX(sub->num_rects, 1); | |
421 | else | ||
422 | 306 | nb = 1; | |
423 | |||
424 | /* shift timestamp to honor -ss and make check_recording_time() work with -t */ | ||
425 | 792 | pts = sub->pts; | |
426 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 792 times.
|
792 | if (output_files[ost->file_index]->start_time != AV_NOPTS_VALUE) |
427 | ✗ | pts -= output_files[ost->file_index]->start_time; | |
428 |
2/2✓ Branch 0 taken 828 times.
✓ Branch 1 taken 792 times.
|
1620 | for (i = 0; i < nb; i++) { |
429 | 828 | AVSubtitle local_sub = *sub; | |
430 | |||
431 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 828 times.
|
828 | if (!check_recording_time(ost, pts, AV_TIME_BASE_Q)) |
432 | ✗ | return 0; | |
433 | |||
434 | 828 | ret = av_new_packet(pkt, subtitle_out_max_size); | |
435 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 828 times.
|
828 | if (ret < 0) |
436 | ✗ | return AVERROR(ENOMEM); | |
437 | |||
438 | 828 | local_sub.pts = pts; | |
439 | // start_display_time is required to be 0 | ||
440 | 828 | local_sub.pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); | |
441 | 828 | local_sub.end_display_time -= sub->start_display_time; | |
442 | 828 | local_sub.start_display_time = 0; | |
443 | |||
444 |
4/4✓ Branch 0 taken 72 times.
✓ Branch 1 taken 756 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 36 times.
|
828 | if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE && i == 1) |
445 | 36 | local_sub.num_rects = 0; | |
446 |
3/4✓ Branch 0 taken 450 times.
✓ Branch 1 taken 342 times.
✓ Branch 2 taken 450 times.
✗ Branch 3 not taken.
|
792 | else if (enc->codec_id == AV_CODEC_ID_ASS && sub->num_rects > 0) { |
447 | 450 | local_sub.num_rects = 1; | |
448 | 450 | local_sub.rects += i; | |
449 | } | ||
450 | |||
451 | 828 | ost->frames_encoded++; | |
452 | |||
453 | 828 | subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, &local_sub); | |
454 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 828 times.
|
828 | if (subtitle_out_size < 0) { |
455 | ✗ | av_log(ost, AV_LOG_FATAL, "Subtitle encoding failed\n"); | |
456 | ✗ | return subtitle_out_size; | |
457 | } | ||
458 | |||
459 | 828 | av_shrink_packet(pkt, subtitle_out_size); | |
460 | 828 | pkt->time_base = AV_TIME_BASE_Q; | |
461 | 828 | pkt->pts = sub->pts; | |
462 | 828 | pkt->duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, pkt->time_base); | |
463 |
2/2✓ Branch 0 taken 72 times.
✓ Branch 1 taken 756 times.
|
828 | if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { |
464 | /* XXX: the pts correction is handled here. Maybe handling | ||
465 | it in the codec would be better */ | ||
466 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 36 times.
|
72 | if (i == 0) |
467 | 36 | pkt->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, pkt->time_base); | |
468 | else | ||
469 | 36 | pkt->pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, pkt->time_base); | |
470 | } | ||
471 | 828 | pkt->dts = pkt->pts; | |
472 | |||
473 | 828 | ret = of_output_packet(of, ost, pkt); | |
474 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 828 times.
|
828 | if (ret < 0) |
475 | ✗ | return ret; | |
476 | } | ||
477 | |||
478 | 792 | return 0; | |
479 | } | ||
480 | |||
481 | ✗ | void enc_stats_write(OutputStream *ost, EncStats *es, | |
482 | const AVFrame *frame, const AVPacket *pkt, | ||
483 | uint64_t frame_num) | ||
484 | { | ||
485 | ✗ | Encoder *e = ost->enc; | |
486 | ✗ | AVIOContext *io = es->io; | |
487 | ✗ | AVRational tb = frame ? frame->time_base : pkt->time_base; | |
488 | ✗ | int64_t pts = frame ? frame->pts : pkt->pts; | |
489 | |||
490 | ✗ | AVRational tbi = (AVRational){ 0, 1}; | |
491 | ✗ | int64_t ptsi = INT64_MAX; | |
492 | |||
493 | const FrameData *fd; | ||
494 | |||
495 | ✗ | if ((frame && frame->opaque_ref) || (pkt && pkt->opaque_ref)) { | |
496 | ✗ | fd = (const FrameData*)(frame ? frame->opaque_ref->data : pkt->opaque_ref->data); | |
497 | ✗ | tbi = fd->dec.tb; | |
498 | ✗ | ptsi = fd->dec.pts; | |
499 | } | ||
500 | |||
501 | ✗ | for (size_t i = 0; i < es->nb_components; i++) { | |
502 | ✗ | const EncStatsComponent *c = &es->components[i]; | |
503 | |||
504 | ✗ | switch (c->type) { | |
505 | ✗ | case ENC_STATS_LITERAL: avio_write (io, c->str, c->str_len); continue; | |
506 | ✗ | case ENC_STATS_FILE_IDX: avio_printf(io, "%d", ost->file_index); continue; | |
507 | ✗ | case ENC_STATS_STREAM_IDX: avio_printf(io, "%d", ost->index); continue; | |
508 | ✗ | case ENC_STATS_TIMEBASE: avio_printf(io, "%d/%d", tb.num, tb.den); continue; | |
509 | ✗ | case ENC_STATS_TIMEBASE_IN: avio_printf(io, "%d/%d", tbi.num, tbi.den); continue; | |
510 | ✗ | case ENC_STATS_PTS: avio_printf(io, "%"PRId64, pts); continue; | |
511 | ✗ | case ENC_STATS_PTS_IN: avio_printf(io, "%"PRId64, ptsi); continue; | |
512 | ✗ | case ENC_STATS_PTS_TIME: avio_printf(io, "%g", pts * av_q2d(tb)); continue; | |
513 | ✗ | case ENC_STATS_PTS_TIME_IN: avio_printf(io, "%g", ptsi == INT64_MAX ? | |
514 | ✗ | INFINITY : ptsi * av_q2d(tbi)); continue; | |
515 | ✗ | case ENC_STATS_FRAME_NUM: avio_printf(io, "%"PRIu64, frame_num); continue; | |
516 | ✗ | case ENC_STATS_FRAME_NUM_IN: avio_printf(io, "%"PRIu64, fd ? fd->dec.frame_num : -1); continue; | |
517 | } | ||
518 | |||
519 | ✗ | if (frame) { | |
520 | ✗ | switch (c->type) { | |
521 | ✗ | case ENC_STATS_SAMPLE_NUM: avio_printf(io, "%"PRIu64, ost->samples_encoded); continue; | |
522 | ✗ | case ENC_STATS_NB_SAMPLES: avio_printf(io, "%d", frame->nb_samples); continue; | |
523 | ✗ | default: av_assert0(0); | |
524 | } | ||
525 | } else { | ||
526 | ✗ | switch (c->type) { | |
527 | ✗ | case ENC_STATS_DTS: avio_printf(io, "%"PRId64, pkt->dts); continue; | |
528 | ✗ | case ENC_STATS_DTS_TIME: avio_printf(io, "%g", pkt->dts * av_q2d(tb)); continue; | |
529 | ✗ | case ENC_STATS_PKT_SIZE: avio_printf(io, "%d", pkt->size); continue; | |
530 | ✗ | case ENC_STATS_BITRATE: { | |
531 | ✗ | double duration = FFMAX(pkt->duration, 1) * av_q2d(tb); | |
532 | ✗ | avio_printf(io, "%g", 8.0 * pkt->size / duration); | |
533 | ✗ | continue; | |
534 | } | ||
535 | ✗ | case ENC_STATS_AVG_BITRATE: { | |
536 | ✗ | double duration = pkt->dts * av_q2d(tb); | |
537 | ✗ | avio_printf(io, "%g", duration > 0 ? 8.0 * e->data_size / duration : -1.); | |
538 | ✗ | continue; | |
539 | } | ||
540 | ✗ | default: av_assert0(0); | |
541 | } | ||
542 | } | ||
543 | } | ||
544 | ✗ | avio_w8(io, '\n'); | |
545 | ✗ | avio_flush(io); | |
546 | ✗ | } | |
547 | |||
548 | ✗ | static inline double psnr(double d) | |
549 | { | ||
550 | ✗ | return -10.0 * log10(d); | |
551 | } | ||
552 | |||
553 | 107113 | static int update_video_stats(OutputStream *ost, const AVPacket *pkt, int write_vstats) | |
554 | { | ||
555 | 107113 | Encoder *e = ost->enc; | |
556 | 107113 | const uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, | |
557 | NULL); | ||
558 | 107113 | AVCodecContext *enc = ost->enc_ctx; | |
559 | enum AVPictureType pict_type; | ||
560 | int64_t frame_number; | ||
561 | double ti1, bitrate, avg_bitrate; | ||
562 | 107113 | double psnr_val = -1; | |
563 | |||
564 |
2/2✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 95968 times.
|
107113 | ost->quality = sd ? AV_RL32(sd) : -1; |
565 |
2/2✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 95968 times.
|
107113 | pict_type = sd ? sd[4] : AV_PICTURE_TYPE_NONE; |
566 | |||
567 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 107113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
107113 | if ((enc->flags & AV_CODEC_FLAG_PSNR) && sd && sd[5]) { |
568 | // FIXME the scaling assumes 8bit | ||
569 | ✗ | double error = AV_RL64(sd + 8) / (enc->width * enc->height * 255.0 * 255.0); | |
570 | ✗ | if (error >= 0 && error <= 1) | |
571 | ✗ | psnr_val = psnr(error); | |
572 | } | ||
573 | |||
574 |
1/2✓ Branch 0 taken 107113 times.
✗ Branch 1 not taken.
|
107113 | if (!write_vstats) |
575 | 107113 | return 0; | |
576 | |||
577 | /* this is executed just the first time update_video_stats is called */ | ||
578 | ✗ | if (!vstats_file) { | |
579 | ✗ | vstats_file = fopen(vstats_filename, "w"); | |
580 | ✗ | if (!vstats_file) { | |
581 | ✗ | perror("fopen"); | |
582 | ✗ | return AVERROR(errno); | |
583 | } | ||
584 | } | ||
585 | |||
586 | ✗ | frame_number = e->packets_encoded; | |
587 | ✗ | if (vstats_version <= 1) { | |
588 | ✗ | fprintf(vstats_file, "frame= %5"PRId64" q= %2.1f ", frame_number, | |
589 | ✗ | ost->quality / (float)FF_QP2LAMBDA); | |
590 | } else { | ||
591 | ✗ | fprintf(vstats_file, "out= %2d st= %2d frame= %5"PRId64" q= %2.1f ", ost->file_index, ost->index, frame_number, | |
592 | ✗ | ost->quality / (float)FF_QP2LAMBDA); | |
593 | } | ||
594 | |||
595 | ✗ | if (psnr_val >= 0) | |
596 | ✗ | fprintf(vstats_file, "PSNR= %6.2f ", psnr_val); | |
597 | |||
598 | ✗ | fprintf(vstats_file,"f_size= %6d ", pkt->size); | |
599 | /* compute pts value */ | ||
600 | ✗ | ti1 = pkt->dts * av_q2d(pkt->time_base); | |
601 | ✗ | if (ti1 < 0.01) | |
602 | ✗ | ti1 = 0.01; | |
603 | |||
604 | ✗ | bitrate = (pkt->size * 8) / av_q2d(enc->time_base) / 1000.0; | |
605 | ✗ | avg_bitrate = (double)(e->data_size * 8) / ti1 / 1000.0; | |
606 | ✗ | fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ", | |
607 | ✗ | (double)e->data_size / 1024, ti1, bitrate, avg_bitrate); | |
608 | ✗ | fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(pict_type)); | |
609 | |||
610 | ✗ | return 0; | |
611 | } | ||
612 | |||
613 | 437828 | static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame) | |
614 | { | ||
615 | 437828 | Encoder *e = ost->enc; | |
616 | 437828 | AVCodecContext *enc = ost->enc_ctx; | |
617 | 437828 | AVPacket *pkt = e->pkt; | |
618 | 437828 | const char *type_desc = av_get_media_type_string(enc->codec_type); | |
619 |
2/2✓ Branch 0 taken 428817 times.
✓ Branch 1 taken 9011 times.
|
437828 | const char *action = frame ? "encode" : "flush"; |
620 | int ret; | ||
621 | |||
622 |
2/2✓ Branch 0 taken 428817 times.
✓ Branch 1 taken 9011 times.
|
437828 | if (frame) { |
623 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 428817 times.
|
428817 | if (ost->enc_stats_pre.io) |
624 | ✗ | enc_stats_write(ost, &ost->enc_stats_pre, frame, NULL, | |
625 | ost->frames_encoded); | ||
626 | |||
627 | 428817 | ost->frames_encoded++; | |
628 | 428817 | ost->samples_encoded += frame->nb_samples; | |
629 | |||
630 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 428817 times.
|
428817 | if (debug_ts) { |
631 | ✗ | av_log(ost, AV_LOG_INFO, "encoder <- type:%s " | |
632 | "frame_pts:%s frame_pts_time:%s time_base:%d/%d\n", | ||
633 | type_desc, | ||
634 | ✗ | av_ts2str(frame->pts), av_ts2timestr(frame->pts, &enc->time_base), | |
635 | enc->time_base.num, enc->time_base.den); | ||
636 | } | ||
637 | |||
638 |
3/4✓ Branch 0 taken 15113 times.
✓ Branch 1 taken 413704 times.
✓ Branch 2 taken 15113 times.
✗ Branch 3 not taken.
|
428817 | if (frame->sample_aspect_ratio.num && !ost->frame_aspect_ratio.num) |
639 | 15113 | enc->sample_aspect_ratio = frame->sample_aspect_ratio; | |
640 | } | ||
641 | |||
642 | 437828 | update_benchmark(NULL); | |
643 | |||
644 | 437828 | ret = avcodec_send_frame(enc, frame); | |
645 |
4/6✓ Branch 0 taken 435179 times.
✓ Branch 1 taken 2649 times.
✓ Branch 2 taken 2649 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2649 times.
✗ Branch 5 not taken.
|
437828 | if (ret < 0 && !(ret == AVERROR_EOF && !frame)) { |
646 | ✗ | av_log(ost, AV_LOG_ERROR, "Error submitting %s frame to the encoder\n", | |
647 | type_desc); | ||
648 | ✗ | return ret; | |
649 | } | ||
650 | |||
651 | while (1) { | ||
652 | 860533 | av_packet_unref(pkt); | |
653 | |||
654 | 860533 | ret = avcodec_receive_packet(enc, pkt); | |
655 | 860533 | update_benchmark("%s_%s %d.%d", action, type_desc, | |
656 | ost->file_index, ost->index); | ||
657 | |||
658 | 860533 | pkt->time_base = enc->time_base; | |
659 | |||
660 | /* if two pass, output log on success and EOF */ | ||
661 |
7/8✓ Branch 0 taken 437828 times.
✓ Branch 1 taken 422705 times.
✓ Branch 2 taken 9011 times.
✓ Branch 3 taken 428817 times.
✓ Branch 4 taken 204 times.
✓ Branch 5 taken 431512 times.
✓ Branch 6 taken 204 times.
✗ Branch 7 not taken.
|
860533 | if ((ret >= 0 || ret == AVERROR_EOF) && ost->logfile && enc->stats_out) |
662 | 204 | fprintf(ost->logfile, "%s", enc->stats_out); | |
663 | |||
664 |
2/2✓ Branch 0 taken 428817 times.
✓ Branch 1 taken 431716 times.
|
860533 | if (ret == AVERROR(EAGAIN)) { |
665 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 428817 times.
|
428817 | av_assert0(frame); // should never happen during flushing |
666 | 428817 | return 0; | |
667 |
2/2✓ Branch 0 taken 9011 times.
✓ Branch 1 taken 422705 times.
|
431716 | } else if (ret == AVERROR_EOF) { |
668 | 9011 | ret = of_output_packet(of, ost, NULL); | |
669 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9011 times.
|
9011 | return ret < 0 ? ret : AVERROR_EOF; |
670 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 422705 times.
|
422705 | } else if (ret < 0) { |
671 | ✗ | av_log(ost, AV_LOG_ERROR, "%s encoding failed\n", type_desc); | |
672 | ✗ | return ret; | |
673 | } | ||
674 | |||
675 |
2/2✓ Branch 0 taken 107113 times.
✓ Branch 1 taken 315592 times.
|
422705 | if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { |
676 | 107113 | ret = update_video_stats(ost, pkt, !!vstats_filename); | |
677 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 107113 times.
|
107113 | if (ret < 0) |
678 | ✗ | return ret; | |
679 | } | ||
680 | |||
681 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 422705 times.
|
422705 | if (ost->enc_stats_post.io) |
682 | ✗ | enc_stats_write(ost, &ost->enc_stats_post, NULL, pkt, | |
683 | e->packets_encoded); | ||
684 | |||
685 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 422705 times.
|
422705 | if (debug_ts) { |
686 | ✗ | av_log(ost, AV_LOG_INFO, "encoder -> type:%s " | |
687 | "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s " | ||
688 | "duration:%s duration_time:%s\n", | ||
689 | type_desc, | ||
690 | ✗ | av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base), | |
691 | ✗ | av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base), | |
692 | ✗ | av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base)); | |
693 | } | ||
694 | |||
695 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 422705 times.
|
422705 | if ((ret = trigger_fix_sub_duration_heartbeat(ost, pkt)) < 0) { |
696 | ✗ | av_log(NULL, AV_LOG_ERROR, | |
697 | "Subtitle heartbeat logic failed in %s! (%s)\n", | ||
698 | ✗ | __func__, av_err2str(ret)); | |
699 | ✗ | return ret; | |
700 | } | ||
701 | |||
702 | 422705 | e->data_size += pkt->size; | |
703 | |||
704 | 422705 | e->packets_encoded++; | |
705 | |||
706 | 422705 | ret = of_output_packet(of, ost, pkt); | |
707 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 422705 times.
|
422705 | if (ret < 0) |
708 | ✗ | return ret; | |
709 | } | ||
710 | |||
711 | av_assert0(0); | ||
712 | } | ||
713 | |||
714 | 412588 | static int submit_encode_frame(OutputFile *of, OutputStream *ost, | |
715 | AVFrame *frame) | ||
716 | { | ||
717 | 412588 | Encoder *e = ost->enc; | |
718 | int ret; | ||
719 | |||
720 |
2/2✓ Branch 0 taken 350958 times.
✓ Branch 1 taken 61630 times.
|
412588 | if (ost->sq_idx_encode < 0) |
721 | 350958 | return encode_frame(of, ost, frame); | |
722 | |||
723 |
2/2✓ Branch 0 taken 58848 times.
✓ Branch 1 taken 2782 times.
|
61630 | if (frame) { |
724 | 58848 | ret = av_frame_ref(e->sq_frame, frame); | |
725 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58848 times.
|
58848 | if (ret < 0) |
726 | ✗ | return ret; | |
727 | 58848 | frame = e->sq_frame; | |
728 | } | ||
729 | |||
730 | 61630 | ret = sq_send(of->sq_encode, ost->sq_idx_encode, | |
731 | 61630 | SQFRAME(frame)); | |
732 |
2/2✓ Branch 0 taken 61629 times.
✓ Branch 1 taken 1 times.
|
61630 | if (ret < 0) { |
733 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (frame) |
734 | 1 | av_frame_unref(frame); | |
735 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ret != AVERROR_EOF) |
736 | ✗ | return ret; | |
737 | } | ||
738 | |||
739 | 81439 | while (1) { | |
740 | 143069 | AVFrame *enc_frame = e->sq_frame; | |
741 | |||
742 | 143069 | ret = sq_receive(of->sq_encode, ost->sq_idx_encode, | |
743 | 143069 | SQFRAME(enc_frame)); | |
744 |
2/2✓ Branch 0 taken 5431 times.
✓ Branch 1 taken 137638 times.
|
143069 | if (ret == AVERROR_EOF) { |
745 | 5431 | enc_frame = NULL; | |
746 |
2/2✓ Branch 0 taken 56199 times.
✓ Branch 1 taken 81439 times.
|
137638 | } else if (ret < 0) { |
747 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56199 times.
|
61630 | return (ret == AVERROR(EAGAIN)) ? 0 : ret; |
748 | } | ||
749 | |||
750 | 86870 | ret = encode_frame(of, ost, enc_frame); | |
751 |
2/2✓ Branch 0 taken 81439 times.
✓ Branch 1 taken 5431 times.
|
86870 | if (enc_frame) |
752 | 81439 | av_frame_unref(enc_frame); | |
753 |
2/2✓ Branch 0 taken 5431 times.
✓ Branch 1 taken 81439 times.
|
86870 | if (ret < 0) { |
754 |
1/2✓ Branch 0 taken 5431 times.
✗ Branch 1 not taken.
|
5431 | if (ret == AVERROR_EOF) |
755 | 5431 | close_output_stream(ost); | |
756 | 5431 | return ret; | |
757 | } | ||
758 | } | ||
759 | } | ||
760 | |||
761 | 299113 | static int do_audio_out(OutputFile *of, OutputStream *ost, | |
762 | AVFrame *frame) | ||
763 | { | ||
764 | 299113 | AVCodecContext *enc = ost->enc_ctx; | |
765 | int ret; | ||
766 | |||
767 |
1/2✓ Branch 0 taken 299113 times.
✗ Branch 1 not taken.
|
299113 | if (!(enc->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE) && |
768 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 299113 times.
|
299113 | enc->ch_layout.nb_channels != frame->ch_layout.nb_channels) { |
769 | ✗ | av_log(ost, AV_LOG_ERROR, | |
770 | "Audio channel count changed and encoder does not support parameter changes\n"); | ||
771 | ✗ | return 0; | |
772 | } | ||
773 | |||
774 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 299113 times.
|
299113 | if (!check_recording_time(ost, frame->pts, frame->time_base)) |
775 | ✗ | return 0; | |
776 | |||
777 | 299113 | ret = submit_encode_frame(of, ost, frame); | |
778 |
3/4✓ Branch 0 taken 31 times.
✓ Branch 1 taken 299082 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 31 times.
|
299113 | return (ret < 0 && ret != AVERROR_EOF) ? ret : 0; |
779 | } | ||
780 | |||
781 | 107113 | static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf, | |
782 | AVRational tb, const AVFrame *in_picture) | ||
783 | { | ||
784 | double pts_time; | ||
785 | |||
786 |
2/2✓ Branch 0 taken 5151 times.
✓ Branch 1 taken 101962 times.
|
107113 | if (kf->ref_pts == AV_NOPTS_VALUE) |
787 | 5151 | kf->ref_pts = in_picture->pts; | |
788 | |||
789 | 107113 | pts_time = (in_picture->pts - kf->ref_pts) * av_q2d(tb); | |
790 |
4/4✓ Branch 0 taken 39 times.
✓ Branch 1 taken 107074 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 37 times.
|
107152 | if (kf->index < kf->nb_pts && |
791 | 39 | av_compare_ts(in_picture->pts, tb, kf->pts[kf->index], AV_TIME_BASE_Q) >= 0) { | |
792 | 2 | kf->index++; | |
793 | 11 | goto force_keyframe; | |
794 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 107111 times.
|
107111 | } else if (kf->pexpr) { |
795 | double res; | ||
796 | ✗ | kf->expr_const_values[FKF_T] = pts_time; | |
797 | ✗ | res = av_expr_eval(kf->pexpr, | |
798 | ✗ | kf->expr_const_values, NULL); | |
799 | ✗ | av_log(logctx, AV_LOG_TRACE, | |
800 | "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n", | ||
801 | kf->expr_const_values[FKF_N], | ||
802 | kf->expr_const_values[FKF_N_FORCED], | ||
803 | kf->expr_const_values[FKF_PREV_FORCED_N], | ||
804 | kf->expr_const_values[FKF_T], | ||
805 | kf->expr_const_values[FKF_PREV_FORCED_T], | ||
806 | res); | ||
807 | |||
808 | ✗ | kf->expr_const_values[FKF_N] += 1; | |
809 | |||
810 | ✗ | if (res) { | |
811 | ✗ | kf->expr_const_values[FKF_PREV_FORCED_N] = kf->expr_const_values[FKF_N] - 1; | |
812 | ✗ | kf->expr_const_values[FKF_PREV_FORCED_T] = kf->expr_const_values[FKF_T]; | |
813 | ✗ | kf->expr_const_values[FKF_N_FORCED] += 1; | |
814 | ✗ | goto force_keyframe; | |
815 | } | ||
816 |
4/4✓ Branch 0 taken 1021 times.
✓ Branch 1 taken 106090 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 1012 times.
|
107111 | } else if (kf->type == KF_FORCE_SOURCE && (in_picture->flags & AV_FRAME_FLAG_KEY)) { |
817 | 9 | goto force_keyframe; | |
818 | } | ||
819 | |||
820 | 107102 | return AV_PICTURE_TYPE_NONE; | |
821 | |||
822 | 11 | force_keyframe: | |
823 | 11 | av_log(logctx, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time); | |
824 | 11 | return AV_PICTURE_TYPE_I; | |
825 | } | ||
826 | |||
827 | /* May modify/reset frame */ | ||
828 | 107114 | static int do_video_out(OutputFile *of, OutputStream *ost, AVFrame *in_picture) | |
829 | { | ||
830 | int ret; | ||
831 | 107114 | AVCodecContext *enc = ost->enc_ctx; | |
832 | |||
833 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 107113 times.
|
107114 | if (!check_recording_time(ost, in_picture->pts, ost->enc_ctx->time_base)) |
834 | 1 | return 0; | |
835 | |||
836 | 107113 | in_picture->quality = enc->global_quality; | |
837 | 107113 | in_picture->pict_type = forced_kf_apply(ost, &ost->kf, enc->time_base, in_picture); | |
838 | |||
839 | #if FFMPEG_OPT_TOP | ||
840 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 107113 times.
|
107113 | if (ost->top_field_first >= 0) { |
841 | ✗ | in_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; | |
842 | ✗ | in_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * (!!ost->top_field_first); | |
843 | } | ||
844 | #endif | ||
845 | |||
846 | 107113 | ret = submit_encode_frame(of, ost, in_picture); | |
847 |
2/2✓ Branch 0 taken 104495 times.
✓ Branch 1 taken 2618 times.
|
107113 | return (ret == AVERROR_EOF) ? 0 : ret; |
848 | } | ||
849 | |||
850 | 406227 | int enc_frame(OutputStream *ost, AVFrame *frame) | |
851 | { | ||
852 | 406227 | OutputFile *of = output_files[ost->file_index]; | |
853 | int ret; | ||
854 | |||
855 | 406227 | ret = enc_open(ost, frame); | |
856 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 406227 times.
|
406227 | if (ret < 0) |
857 | ✗ | return ret; | |
858 | |||
859 | 406227 | return ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO ? | |
860 |
2/2✓ Branch 0 taken 107114 times.
✓ Branch 1 taken 299113 times.
|
406227 | do_video_out(of, ost, frame) : do_audio_out(of, ost, frame); |
861 | } | ||
862 | |||
863 | 6685 | int enc_flush(void) | |
864 | { | ||
865 | int ret; | ||
866 | |||
867 |
2/2✓ Branch 2 taken 6968 times.
✓ Branch 3 taken 6685 times.
|
13653 | for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { |
868 | 6968 | OutputFile *of = output_files[ost->file_index]; | |
869 |
2/2✓ Branch 0 taken 2782 times.
✓ Branch 1 taken 4186 times.
|
6968 | if (ost->sq_idx_encode >= 0) |
870 | 2782 | sq_send(of->sq_encode, ost->sq_idx_encode, SQFRAME(NULL)); | |
871 | } | ||
872 | |||
873 |
2/2✓ Branch 2 taken 6968 times.
✓ Branch 3 taken 6685 times.
|
13653 | for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { |
874 | 6968 | Encoder *e = ost->enc; | |
875 | 6968 | AVCodecContext *enc = ost->enc_ctx; | |
876 | 6968 | OutputFile *of = output_files[ost->file_index]; | |
877 | |||
878 |
3/4✓ Branch 0 taken 6400 times.
✓ Branch 1 taken 568 times.
✓ Branch 2 taken 6400 times.
✗ Branch 3 not taken.
|
6968 | if (!enc || !e->opened || |
879 |
4/4✓ Branch 0 taken 1248 times.
✓ Branch 1 taken 5152 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 1210 times.
|
6400 | (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO)) |
880 | 606 | continue; | |
881 | |||
882 | 6362 | ret = submit_encode_frame(of, ost, NULL); | |
883 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6362 times.
|
6362 | if (ret != AVERROR_EOF) |
884 | ✗ | return ret; | |
885 | } | ||
886 | |||
887 | 6685 | return 0; | |
888 | } | ||
889 |