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 "libavutil/avassert.h" | ||
20 | #include "libavutil/dict.h" | ||
21 | #include "libavutil/error.h" | ||
22 | #include "libavutil/log.h" | ||
23 | #include "libavutil/pixdesc.h" | ||
24 | #include "libavutil/pixfmt.h" | ||
25 | #include "libavutil/timestamp.h" | ||
26 | |||
27 | #include "libavcodec/avcodec.h" | ||
28 | #include "libavcodec/codec.h" | ||
29 | |||
30 | #include "libavfilter/buffersrc.h" | ||
31 | |||
32 | #include "ffmpeg.h" | ||
33 | |||
34 | struct Decoder { | ||
35 | AVFrame *frame; | ||
36 | AVPacket *pkt; | ||
37 | |||
38 | // pts/estimated duration of the last decoded frame | ||
39 | // * in decoder timebase for video, | ||
40 | // * in last_frame_tb (may change during decoding) for audio | ||
41 | int64_t last_frame_pts; | ||
42 | int64_t last_frame_duration_est; | ||
43 | AVRational last_frame_tb; | ||
44 | int64_t last_filter_in_rescale_delta; | ||
45 | int last_frame_sample_rate; | ||
46 | }; | ||
47 | |||
48 | 7047 | void dec_free(Decoder **pdec) | |
49 | { | ||
50 | 7047 | Decoder *dec = *pdec; | |
51 | |||
52 |
2/2✓ Branch 0 taken 764 times.
✓ Branch 1 taken 6283 times.
|
7047 | if (!dec) |
53 | 764 | return; | |
54 | |||
55 | 6283 | av_frame_free(&dec->frame); | |
56 | 6283 | av_packet_free(&dec->pkt); | |
57 | |||
58 | 6283 | av_freep(pdec); | |
59 | } | ||
60 | |||
61 | 6283 | static int dec_alloc(Decoder **pdec) | |
62 | { | ||
63 | Decoder *dec; | ||
64 | |||
65 | 6283 | *pdec = NULL; | |
66 | |||
67 | 6283 | dec = av_mallocz(sizeof(*dec)); | |
68 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6283 times.
|
6283 | if (!dec) |
69 | ✗ | return AVERROR(ENOMEM); | |
70 | |||
71 | 6283 | dec->frame = av_frame_alloc(); | |
72 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6283 times.
|
6283 | if (!dec->frame) |
73 | ✗ | goto fail; | |
74 | |||
75 | 6283 | dec->pkt = av_packet_alloc(); | |
76 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6283 times.
|
6283 | if (!dec->pkt) |
77 | ✗ | goto fail; | |
78 | |||
79 | 6283 | dec->last_filter_in_rescale_delta = AV_NOPTS_VALUE; | |
80 | 6283 | dec->last_frame_pts = AV_NOPTS_VALUE; | |
81 | 6283 | dec->last_frame_tb = (AVRational){ 1, 1 }; | |
82 | |||
83 | 6283 | *pdec = dec; | |
84 | |||
85 | 6283 | return 0; | |
86 | ✗ | fail: | |
87 | ✗ | dec_free(&dec); | |
88 | ✗ | return AVERROR(ENOMEM); | |
89 | } | ||
90 | |||
91 | 398619 | static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame) | |
92 | { | ||
93 | int i, ret; | ||
94 | |||
95 | av_assert1(ist->nb_filters > 0); /* ensure ret is initialized */ | ||
96 |
2/2✓ Branch 0 taken 400451 times.
✓ Branch 1 taken 398619 times.
|
799070 | for (i = 0; i < ist->nb_filters; i++) { |
97 | 400451 | ret = ifilter_send_frame(ist->filters[i], decoded_frame, i < ist->nb_filters - 1); | |
98 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 400451 times.
|
400451 | if (ret == AVERROR_EOF) |
99 | ✗ | ret = 0; /* ignore */ | |
100 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 400451 times.
|
400451 | if (ret < 0) { |
101 | ✗ | av_log(NULL, AV_LOG_ERROR, | |
102 | ✗ | "Failed to inject frame into filter network: %s\n", av_err2str(ret)); | |
103 | ✗ | break; | |
104 | } | ||
105 | } | ||
106 | 398619 | return ret; | |
107 | } | ||
108 | |||
109 | 294842 | static AVRational audio_samplerate_update(void *logctx, Decoder *d, | |
110 | const AVFrame *frame) | ||
111 | { | ||
112 | 294842 | const int prev = d->last_frame_tb.den; | |
113 | 294842 | const int sr = frame->sample_rate; | |
114 | |||
115 | AVRational tb_new; | ||
116 | int64_t gcd; | ||
117 | |||
118 |
2/2✓ Branch 0 taken 293661 times.
✓ Branch 1 taken 1181 times.
|
294842 | if (frame->sample_rate == d->last_frame_sample_rate) |
119 | 293661 | goto finish; | |
120 | |||
121 | 1181 | gcd = av_gcd(prev, sr); | |
122 | |||
123 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1181 times.
|
1181 | if (prev / gcd >= INT_MAX / sr) { |
124 | ✗ | av_log(logctx, AV_LOG_WARNING, | |
125 | "Audio timestamps cannot be represented exactly after " | ||
126 | "sample rate change: %d -> %d\n", prev, sr); | ||
127 | |||
128 | // LCM of 192000, 44100, allows to represent all common samplerates | ||
129 | ✗ | tb_new = (AVRational){ 1, 28224000 }; | |
130 | } else | ||
131 | 1181 | tb_new = (AVRational){ 1, prev / gcd * sr }; | |
132 | |||
133 | // keep the frame timebase if it is strictly better than | ||
134 | // the samplerate-defined one | ||
135 |
4/4✓ Branch 0 taken 1165 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 108 times.
✓ Branch 3 taken 1057 times.
|
1181 | if (frame->time_base.num == 1 && frame->time_base.den > tb_new.den && |
136 |
2/2✓ Branch 0 taken 41 times.
✓ Branch 1 taken 67 times.
|
108 | !(frame->time_base.den % tb_new.den)) |
137 | 41 | tb_new = frame->time_base; | |
138 | |||
139 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1181 times.
|
1181 | if (d->last_frame_pts != AV_NOPTS_VALUE) |
140 | ✗ | d->last_frame_pts = av_rescale_q(d->last_frame_pts, | |
141 | d->last_frame_tb, tb_new); | ||
142 | 1181 | d->last_frame_duration_est = av_rescale_q(d->last_frame_duration_est, | |
143 | d->last_frame_tb, tb_new); | ||
144 | |||
145 | 1181 | d->last_frame_tb = tb_new; | |
146 | 1181 | d->last_frame_sample_rate = frame->sample_rate; | |
147 | |||
148 | 294842 | finish: | |
149 | 294842 | return d->last_frame_tb; | |
150 | } | ||
151 | |||
152 | 294842 | static void audio_ts_process(void *logctx, Decoder *d, AVFrame *frame) | |
153 | { | ||
154 | 294842 | AVRational tb_filter = (AVRational){1, frame->sample_rate}; | |
155 | AVRational tb; | ||
156 | int64_t pts_pred; | ||
157 | |||
158 | // on samplerate change, choose a new internal timebase for timestamp | ||
159 | // generation that can represent timestamps from all the samplerates | ||
160 | // seen so far | ||
161 | 294842 | tb = audio_samplerate_update(logctx, d, frame); | |
162 |
2/2✓ Branch 0 taken 293661 times.
✓ Branch 1 taken 1181 times.
|
294842 | pts_pred = d->last_frame_pts == AV_NOPTS_VALUE ? 0 : |
163 | 293661 | d->last_frame_pts + d->last_frame_duration_est; | |
164 | |||
165 |
2/2✓ Branch 0 taken 28703 times.
✓ Branch 1 taken 266139 times.
|
294842 | if (frame->pts == AV_NOPTS_VALUE) { |
166 | 28703 | frame->pts = pts_pred; | |
167 | 28703 | frame->time_base = tb; | |
168 |
2/2✓ Branch 0 taken 264964 times.
✓ Branch 1 taken 1175 times.
|
266139 | } else if (d->last_frame_pts != AV_NOPTS_VALUE && |
169 |
2/2✓ Branch 0 taken 597 times.
✓ Branch 1 taken 264367 times.
|
264964 | frame->pts > av_rescale_q_rnd(pts_pred, tb, frame->time_base, |
170 | AV_ROUND_UP)) { | ||
171 | // there was a gap in timestamps, reset conversion state | ||
172 | 597 | d->last_filter_in_rescale_delta = AV_NOPTS_VALUE; | |
173 | } | ||
174 | |||
175 | 294842 | frame->pts = av_rescale_delta(frame->time_base, frame->pts, | |
176 | tb, frame->nb_samples, | ||
177 | &d->last_filter_in_rescale_delta, tb); | ||
178 | |||
179 | 294842 | d->last_frame_pts = frame->pts; | |
180 | 294842 | d->last_frame_duration_est = av_rescale_q(frame->nb_samples, | |
181 | tb_filter, tb); | ||
182 | |||
183 | // finally convert to filtering timebase | ||
184 | 294842 | frame->pts = av_rescale_q(frame->pts, tb, tb_filter); | |
185 | 294842 | frame->duration = frame->nb_samples; | |
186 | 294842 | frame->time_base = tb_filter; | |
187 | 294842 | } | |
188 | |||
189 | 103777 | static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *frame) | |
190 | { | ||
191 | 103777 | const Decoder *d = ist->decoder; | |
192 | 103777 | const InputFile *ifile = input_files[ist->file_index]; | |
193 | 103777 | int64_t codec_duration = 0; | |
194 | |||
195 | // XXX lavf currently makes up frame durations when they are not provided by | ||
196 | // the container. As there is no way to reliably distinguish real container | ||
197 | // durations from the fake made-up ones, we use heuristics based on whether | ||
198 | // the container has timestamps. Eventually lavf should stop making up | ||
199 | // durations, then this should be simplified. | ||
200 | |||
201 | // prefer frame duration for containers with timestamps | ||
202 |
6/6✓ Branch 0 taken 102099 times.
✓ Branch 1 taken 1678 times.
✓ Branch 2 taken 32270 times.
✓ Branch 3 taken 69829 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 32263 times.
|
103777 | if (frame->duration > 0 && (!ifile->format_nots || ist->framerate.num)) |
203 | 69836 | return frame->duration; | |
204 | |||
205 |
3/4✓ Branch 0 taken 33446 times.
✓ Branch 1 taken 495 times.
✓ Branch 2 taken 33446 times.
✗ Branch 3 not taken.
|
33941 | if (ist->dec_ctx->framerate.den && ist->dec_ctx->framerate.num) { |
206 | 33446 | int fields = frame->repeat_pict + 2; | |
207 | 33446 | AVRational field_rate = av_mul_q(ist->dec_ctx->framerate, | |
208 | 33446 | (AVRational){ 2, 1 }); | |
209 | 33446 | codec_duration = av_rescale_q(fields, av_inv_q(field_rate), | |
210 | frame->time_base); | ||
211 | } | ||
212 | |||
213 | // prefer codec-layer duration for containers without timestamps | ||
214 |
4/4✓ Branch 0 taken 33446 times.
✓ Branch 1 taken 495 times.
✓ Branch 2 taken 32339 times.
✓ Branch 3 taken 1107 times.
|
33941 | if (codec_duration > 0 && ifile->format_nots) |
215 | 32339 | return codec_duration; | |
216 | |||
217 | // when timestamps are available, repeat last frame's actual duration | ||
218 | // (i.e. pts difference between this and last frame) | ||
219 |
3/4✓ Branch 0 taken 1602 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1526 times.
✓ Branch 3 taken 76 times.
|
1602 | if (frame->pts != AV_NOPTS_VALUE && d->last_frame_pts != AV_NOPTS_VALUE && |
220 |
1/2✓ Branch 0 taken 1526 times.
✗ Branch 1 not taken.
|
1526 | frame->pts > d->last_frame_pts) |
221 | 1526 | return frame->pts - d->last_frame_pts; | |
222 | |||
223 | // try frame/codec duration | ||
224 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 68 times.
|
76 | if (frame->duration > 0) |
225 | 8 | return frame->duration; | |
226 |
2/2✓ Branch 0 taken 43 times.
✓ Branch 1 taken 25 times.
|
68 | if (codec_duration > 0) |
227 | 43 | return codec_duration; | |
228 | |||
229 | // try average framerate | ||
230 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
25 | if (ist->st->avg_frame_rate.num && ist->st->avg_frame_rate.den) { |
231 | ✗ | int64_t d = av_rescale_q(1, av_inv_q(ist->st->avg_frame_rate), | |
232 | frame->time_base); | ||
233 | ✗ | if (d > 0) | |
234 | ✗ | return d; | |
235 | } | ||
236 | |||
237 | // last resort is last frame's estimated duration, and 1 | ||
238 | 25 | return FFMAX(d->last_frame_duration_est, 1); | |
239 | } | ||
240 | |||
241 | 103777 | static int video_frame_process(InputStream *ist, AVFrame *frame) | |
242 | { | ||
243 | 103777 | Decoder *d = ist->decoder; | |
244 | |||
245 | // The following line may be required in some cases where there is no parser | ||
246 | // or the parser does not has_b_frames correctly | ||
247 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 103776 times.
|
103777 | if (ist->par->video_delay < ist->dec_ctx->has_b_frames) { |
248 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ist->dec_ctx->codec_id == AV_CODEC_ID_H264) { |
249 | 1 | ist->par->video_delay = ist->dec_ctx->has_b_frames; | |
250 | } else | ||
251 | ✗ | av_log(ist->dec_ctx, AV_LOG_WARNING, | |
252 | "video_delay is larger in decoder than demuxer %d > %d.\n" | ||
253 | "If you want to help, upload a sample " | ||
254 | "of this file to https://streams.videolan.org/upload/ " | ||
255 | "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n", | ||
256 | ✗ | ist->dec_ctx->has_b_frames, | |
257 | ✗ | ist->par->video_delay); | |
258 | } | ||
259 | |||
260 |
2/2✓ Branch 0 taken 103766 times.
✓ Branch 1 taken 11 times.
|
103777 | if (ist->dec_ctx->width != frame->width || |
261 |
2/2✓ Branch 0 taken 103764 times.
✓ Branch 1 taken 2 times.
|
103766 | ist->dec_ctx->height != frame->height || |
262 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 103760 times.
|
103764 | ist->dec_ctx->pix_fmt != frame->format) { |
263 | 17 | av_log(NULL, AV_LOG_DEBUG, "Frame parameters mismatch context %d,%d,%d != %d,%d,%d\n", | |
264 | frame->width, | ||
265 | frame->height, | ||
266 | frame->format, | ||
267 | 17 | ist->dec_ctx->width, | |
268 | 17 | ist->dec_ctx->height, | |
269 | 17 | ist->dec_ctx->pix_fmt); | |
270 | } | ||
271 | |||
272 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 103777 times.
|
103777 | if(ist->top_field_first>=0) |
273 | ✗ | frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; | |
274 | |||
275 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 103777 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
103777 | if (ist->hwaccel_retrieve_data && frame->format == ist->hwaccel_pix_fmt) { |
276 | ✗ | int err = ist->hwaccel_retrieve_data(ist->dec_ctx, frame); | |
277 | ✗ | if (err < 0) | |
278 | ✗ | return err; | |
279 | } | ||
280 | |||
281 | 103777 | frame->pts = frame->best_effort_timestamp; | |
282 | |||
283 | // forced fixed framerate | ||
284 |
2/2✓ Branch 0 taken 112 times.
✓ Branch 1 taken 103665 times.
|
103777 | if (ist->framerate.num) { |
285 | 112 | frame->pts = AV_NOPTS_VALUE; | |
286 | 112 | frame->duration = 1; | |
287 | 112 | frame->time_base = av_inv_q(ist->framerate); | |
288 | } | ||
289 | |||
290 | // no timestamp available - extrapolate from previous frame duration | ||
291 |
2/2✓ Branch 0 taken 28096 times.
✓ Branch 1 taken 75681 times.
|
103777 | if (frame->pts == AV_NOPTS_VALUE) |
292 |
2/2✓ Branch 0 taken 27700 times.
✓ Branch 1 taken 396 times.
|
55796 | frame->pts = d->last_frame_pts == AV_NOPTS_VALUE ? 0 : |
293 | 27700 | d->last_frame_pts + d->last_frame_duration_est; | |
294 | |||
295 | // update timestamp history | ||
296 | 103777 | d->last_frame_duration_est = video_duration_estimate(ist, frame); | |
297 | 103777 | d->last_frame_pts = frame->pts; | |
298 | 103777 | d->last_frame_tb = frame->time_base; | |
299 | |||
300 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 103777 times.
|
103777 | if (debug_ts) { |
301 | ✗ | av_log(ist, AV_LOG_INFO, | |
302 | "decoder -> pts:%s pts_time:%s " | ||
303 | "pkt_dts:%s pkt_dts_time:%s " | ||
304 | "duration:%s duration_time:%s " | ||
305 | "keyframe:%d frame_type:%d time_base:%d/%d\n", | ||
306 | ✗ | av_ts2str(frame->pts), | |
307 | ✗ | av_ts2timestr(frame->pts, &frame->time_base), | |
308 | ✗ | av_ts2str(frame->pkt_dts), | |
309 | ✗ | av_ts2timestr(frame->pkt_dts, &frame->time_base), | |
310 | ✗ | av_ts2str(frame->duration), | |
311 | ✗ | av_ts2timestr(frame->duration, &frame->time_base), | |
312 | ✗ | !!(frame->flags & AV_FRAME_FLAG_KEY), frame->pict_type, | |
313 | frame->time_base.num, frame->time_base.den); | ||
314 | } | ||
315 | |||
316 |
2/2✓ Branch 0 taken 5272 times.
✓ Branch 1 taken 98505 times.
|
103777 | if (ist->st->sample_aspect_ratio.num) |
317 | 5272 | frame->sample_aspect_ratio = ist->st->sample_aspect_ratio; | |
318 | |||
319 | 103777 | return 0; | |
320 | } | ||
321 | |||
322 | 40 | static void sub2video_flush(InputStream *ist) | |
323 | { | ||
324 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 40 times.
|
44 | for (int i = 0; i < ist->nb_filters; i++) { |
325 | 4 | int ret = ifilter_sub2video(ist->filters[i], NULL); | |
326 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
4 | if (ret != AVERROR_EOF && ret < 0) |
327 | ✗ | av_log(NULL, AV_LOG_WARNING, "Flush the frame error.\n"); | |
328 | } | ||
329 | 40 | } | |
330 | |||
331 | 837 | int process_subtitle(InputStream *ist, AVSubtitle *subtitle, int *got_output) | |
332 | { | ||
333 | 837 | int ret = 0; | |
334 | |||
335 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 817 times.
|
837 | if (ist->fix_sub_duration) { |
336 | 20 | int end = 1; | |
337 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
|
20 | if (ist->prev_sub.got_output) { |
338 | 18 | end = av_rescale(subtitle->pts - ist->prev_sub.subtitle.pts, | |
339 | 1000, AV_TIME_BASE); | ||
340 |
1/2✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
|
18 | if (end < ist->prev_sub.subtitle.end_display_time) { |
341 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
|
18 | av_log(NULL, AV_LOG_DEBUG, |
342 | "Subtitle duration reduced from %"PRId32" to %d%s\n", | ||
343 | ist->prev_sub.subtitle.end_display_time, end, | ||
344 | end <= 0 ? ", dropping it" : ""); | ||
345 | 18 | ist->prev_sub.subtitle.end_display_time = end; | |
346 | } | ||
347 | } | ||
348 | 20 | FFSWAP(int, *got_output, ist->prev_sub.got_output); | |
349 | 20 | FFSWAP(int, ret, ist->prev_sub.ret); | |
350 | 20 | FFSWAP(AVSubtitle, *subtitle, ist->prev_sub.subtitle); | |
351 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | if (end <= 0) |
352 | ✗ | goto out; | |
353 | } | ||
354 | |||
355 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 835 times.
|
837 | if (!*got_output) |
356 | 2 | return ret; | |
357 | |||
358 |
2/2✓ Branch 0 taken 88 times.
✓ Branch 1 taken 835 times.
|
923 | for (int i = 0; i < ist->nb_filters; i++) { |
359 | 88 | ret = ifilter_sub2video(ist->filters[i], subtitle); | |
360 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
|
88 | if (ret < 0) { |
361 | ✗ | av_log(ist, AV_LOG_ERROR, "Error sending a subtitle for filtering: %s\n", | |
362 | ✗ | av_err2str(ret)); | |
363 | ✗ | goto out; | |
364 | } | ||
365 | } | ||
366 | |||
367 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 826 times.
|
835 | if (!subtitle->num_rects) |
368 | 9 | goto out; | |
369 | |||
370 |
2/2✓ Branch 0 taken 792 times.
✓ Branch 1 taken 826 times.
|
1618 | for (int oidx = 0; oidx < ist->nb_outputs; oidx++) { |
371 | 792 | OutputStream *ost = ist->outputs[oidx]; | |
372 |
2/4✓ Branch 0 taken 792 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 792 times.
|
792 | if (!ost->enc || ost->type != AVMEDIA_TYPE_SUBTITLE) |
373 | ✗ | continue; | |
374 | |||
375 | 792 | enc_subtitle(output_files[ost->file_index], ost, subtitle); | |
376 | } | ||
377 | |||
378 | 826 | out: | |
379 | 835 | avsubtitle_free(subtitle); | |
380 | 835 | return ret; | |
381 | } | ||
382 | |||
383 | 1702 | static int transcode_subtitles(InputStream *ist, const AVPacket *pkt) | |
384 | { | ||
385 | AVSubtitle subtitle; | ||
386 | int got_output; | ||
387 | 1702 | int ret = avcodec_decode_subtitle2(ist->dec_ctx, | |
388 | &subtitle, &got_output, pkt); | ||
389 | |||
390 |
2/2✓ Branch 0 taken 79 times.
✓ Branch 1 taken 1623 times.
|
1702 | if (ret < 0) { |
391 | 79 | av_log(ist, AV_LOG_ERROR, "Error decoding subtitles: %s\n", | |
392 | 79 | av_err2str(ret)); | |
393 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 79 times.
|
79 | if (exit_on_error) |
394 | ✗ | exit_program(1); | |
395 | 79 | ist->decode_errors++; | |
396 | } | ||
397 | |||
398 |
4/4✓ Branch 0 taken 1623 times.
✓ Branch 1 taken 79 times.
✓ Branch 2 taken 790 times.
✓ Branch 3 taken 833 times.
|
1702 | if (ret < 0 || !got_output) { |
399 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 829 times.
|
869 | if (!pkt->size) |
400 | 40 | sub2video_flush(ist); | |
401 |
2/2✓ Branch 0 taken 79 times.
✓ Branch 1 taken 790 times.
|
869 | return ret < 0 ? ret : AVERROR_EOF; |
402 | } | ||
403 | |||
404 | 833 | ist->frames_decoded++; | |
405 | |||
406 | 833 | return process_subtitle(ist, &subtitle, &got_output); | |
407 | } | ||
408 | |||
409 | 6243 | static int send_filter_eof(InputStream *ist) | |
410 | { | ||
411 | 6243 | Decoder *d = ist->decoder; | |
412 | int i, ret; | ||
413 | |||
414 |
2/2✓ Branch 0 taken 6259 times.
✓ Branch 1 taken 6243 times.
|
12502 | for (i = 0; i < ist->nb_filters; i++) { |
415 |
2/2✓ Branch 0 taken 6258 times.
✓ Branch 1 taken 1 times.
|
6259 | int64_t end_pts = d->last_frame_pts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE : |
416 | 6258 | d->last_frame_pts + d->last_frame_duration_est; | |
417 | 6259 | ret = ifilter_send_eof(ist->filters[i], end_pts, d->last_frame_tb); | |
418 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6259 times.
|
6259 | if (ret < 0) |
419 | ✗ | return ret; | |
420 | } | ||
421 | 6243 | return 0; | |
422 | } | ||
423 | |||
424 | 384797 | int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof) | |
425 | { | ||
426 | 384797 | Decoder *d = ist->decoder; | |
427 | 384797 | AVCodecContext *dec = ist->dec_ctx; | |
428 | 384797 | const char *type_desc = av_get_media_type_string(dec->codec_type); | |
429 | int ret; | ||
430 | |||
431 |
2/2✓ Branch 0 taken 1702 times.
✓ Branch 1 taken 383095 times.
|
384797 | if (dec->codec_type == AVMEDIA_TYPE_SUBTITLE) |
432 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 1662 times.
|
1702 | return transcode_subtitles(ist, pkt ? pkt : d->pkt); |
433 | |||
434 | // With fate-indeo3-2, we're getting 0-sized packets before EOF for some | ||
435 | // reason. This seems like a semi-critical bug. Don't trigger EOF, and | ||
436 | // skip the packet. | ||
437 |
4/4✓ Branch 0 taken 376851 times.
✓ Branch 1 taken 6244 times.
✓ Branch 2 taken 1480 times.
✓ Branch 3 taken 375371 times.
|
383095 | if (pkt && pkt->size == 0) |
438 | 1480 | return 0; | |
439 | |||
440 | 381615 | ret = avcodec_send_packet(dec, pkt); | |
441 |
5/6✓ Branch 0 taken 382 times.
✓ Branch 1 taken 381233 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 381 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
381615 | if (ret < 0 && !(ret == AVERROR_EOF && !pkt)) { |
442 | // In particular, we don't expect AVERROR(EAGAIN), because we read all | ||
443 | // decoded frames with avcodec_receive_frame() until done. | ||
444 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 381 times.
|
381 | if (ret == AVERROR(EAGAIN)) { |
445 | ✗ | av_log(ist, AV_LOG_FATAL, "A decoder returned an unexpected error code. " | |
446 | "This is a bug, please report it.\n"); | ||
447 | ✗ | exit_program(1); | |
448 | } | ||
449 |
1/2✓ Branch 0 taken 381 times.
✗ Branch 1 not taken.
|
381 | av_log(ist, AV_LOG_ERROR, "Error submitting %s to decoder: %s\n", |
450 | 381 | pkt ? "packet" : "EOF", av_err2str(ret)); | |
451 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 381 times.
|
381 | if (exit_on_error) |
452 | ✗ | exit_program(1); | |
453 | |||
454 |
1/2✓ Branch 0 taken 381 times.
✗ Branch 1 not taken.
|
381 | if (ret != AVERROR_EOF) |
455 | 381 | ist->decode_errors++; | |
456 | |||
457 | 381 | return ret; | |
458 | } | ||
459 | |||
460 | 398619 | while (1) { | |
461 | 779853 | AVFrame *frame = d->frame; | |
462 | |||
463 | 779853 | update_benchmark(NULL); | |
464 | 779853 | ret = avcodec_receive_frame(dec, frame); | |
465 | 779853 | update_benchmark("decode_%s %d.%d", type_desc, | |
466 | ist->file_index, ist->index); | ||
467 | |||
468 |
2/2✓ Branch 0 taken 374985 times.
✓ Branch 1 taken 404868 times.
|
779853 | if (ret == AVERROR(EAGAIN)) { |
469 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 374985 times.
|
374985 | av_assert0(pkt); // should never happen during flushing |
470 | 374985 | return 0; | |
471 |
2/2✓ Branch 0 taken 6243 times.
✓ Branch 1 taken 398625 times.
|
404868 | } else if (ret == AVERROR_EOF) { |
472 | /* after flushing, send an EOF on all the filter inputs attached to the stream */ | ||
473 | /* except when looping we need to flush but not to send an EOF */ | ||
474 |
1/2✓ Branch 0 taken 6243 times.
✗ Branch 1 not taken.
|
6243 | if (!no_eof) { |
475 | 6243 | ret = send_filter_eof(ist); | |
476 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6243 times.
|
6243 | if (ret < 0) { |
477 | ✗ | av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n"); | |
478 | ✗ | exit_program(1); | |
479 | } | ||
480 | } | ||
481 | |||
482 | 6243 | return AVERROR_EOF; | |
483 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 398619 times.
|
398625 | } else if (ret < 0) { |
484 | 6 | av_log(ist, AV_LOG_ERROR, "Decoding error: %s\n", av_err2str(ret)); | |
485 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (exit_on_error) |
486 | ✗ | exit_program(1); | |
487 | 6 | ist->decode_errors++; | |
488 | 6 | return ret; | |
489 | } | ||
490 | |||
491 |
3/4✓ Branch 0 taken 398583 times.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 398583 times.
|
398619 | if (frame->decode_error_flags || (frame->flags & AV_FRAME_FLAG_CORRUPT)) { |
492 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
|
36 | av_log(ist, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING, |
493 | "corrupt decoded frame\n"); | ||
494 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
|
36 | if (exit_on_error) |
495 | ✗ | exit_program(1); | |
496 | } | ||
497 | |||
498 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 398619 times.
|
398619 | if (ist->want_frame_data) { |
499 | FrameData *fd; | ||
500 | |||
501 | ✗ | av_assert0(!frame->opaque_ref); | |
502 | ✗ | frame->opaque_ref = av_buffer_allocz(sizeof(*fd)); | |
503 | ✗ | if (!frame->opaque_ref) { | |
504 | ✗ | av_frame_unref(frame); | |
505 | ✗ | report_and_exit(AVERROR(ENOMEM)); | |
506 | } | ||
507 | ✗ | fd = (FrameData*)frame->opaque_ref->data; | |
508 | ✗ | fd->pts = frame->pts; | |
509 | ✗ | fd->tb = dec->pkt_timebase; | |
510 | ✗ | fd->idx = dec->frame_num - 1; | |
511 | } | ||
512 | |||
513 | 398619 | frame->time_base = dec->pkt_timebase; | |
514 | |||
515 |
2/2✓ Branch 0 taken 294842 times.
✓ Branch 1 taken 103777 times.
|
398619 | if (dec->codec_type == AVMEDIA_TYPE_AUDIO) { |
516 | 294842 | ist->samples_decoded += frame->nb_samples; | |
517 | 294842 | ist->nb_samples = frame->nb_samples; | |
518 | |||
519 | 294842 | audio_ts_process(ist, ist->decoder, frame); | |
520 | } else { | ||
521 | 103777 | ret = video_frame_process(ist, frame); | |
522 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 103777 times.
|
103777 | if (ret < 0) { |
523 | ✗ | av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded " | |
524 | "data for stream #%d:%d\n", ist->file_index, ist->index); | ||
525 | ✗ | exit_program(1); | |
526 | } | ||
527 | } | ||
528 | |||
529 | 398619 | ist->frames_decoded++; | |
530 | |||
531 | 398619 | ret = send_frame_to_filters(ist, frame); | |
532 | 398619 | av_frame_unref(frame); | |
533 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 398619 times.
|
398619 | if (ret < 0) |
534 | ✗ | exit_program(1); | |
535 | } | ||
536 | } | ||
537 | |||
538 | 976 | static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts) | |
539 | { | ||
540 | 976 | InputStream *ist = s->opaque; | |
541 | const enum AVPixelFormat *p; | ||
542 | int ret; | ||
543 | |||
544 |
1/2✓ Branch 0 taken 2633 times.
✗ Branch 1 not taken.
|
2633 | for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) { |
545 | 2633 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p); | |
546 | 2633 | const AVCodecHWConfig *config = NULL; | |
547 | int i; | ||
548 | |||
549 |
2/2✓ Branch 0 taken 976 times.
✓ Branch 1 taken 1657 times.
|
2633 | if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) |
550 | 976 | break; | |
551 | |||
552 |
1/2✓ Branch 0 taken 1657 times.
✗ Branch 1 not taken.
|
1657 | if (ist->hwaccel_id == HWACCEL_GENERIC || |
553 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1657 times.
|
1657 | ist->hwaccel_id == HWACCEL_AUTO) { |
554 | ✗ | for (i = 0;; i++) { | |
555 | ✗ | config = avcodec_get_hw_config(s->codec, i); | |
556 | ✗ | if (!config) | |
557 | ✗ | break; | |
558 | ✗ | if (!(config->methods & | |
559 | AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) | ||
560 | ✗ | continue; | |
561 | ✗ | if (config->pix_fmt == *p) | |
562 | ✗ | break; | |
563 | } | ||
564 | } | ||
565 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1657 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1657 | if (config && config->device_type == ist->hwaccel_device_type) { |
566 | ✗ | ret = hwaccel_decode_init(s); | |
567 | ✗ | if (ret < 0) { | |
568 | ✗ | if (ist->hwaccel_id == HWACCEL_GENERIC) { | |
569 | ✗ | av_log(NULL, AV_LOG_FATAL, | |
570 | "%s hwaccel requested for input stream #%d:%d, " | ||
571 | "but cannot be initialized.\n", | ||
572 | ✗ | av_hwdevice_get_type_name(config->device_type), | |
573 | ist->file_index, ist->index); | ||
574 | ✗ | return AV_PIX_FMT_NONE; | |
575 | } | ||
576 | ✗ | continue; | |
577 | } | ||
578 | |||
579 | ✗ | ist->hwaccel_pix_fmt = *p; | |
580 | ✗ | break; | |
581 | } | ||
582 | } | ||
583 | |||
584 | 976 | return *p; | |
585 | } | ||
586 | |||
587 | 6283 | static HWDevice *hw_device_match_by_codec(const AVCodec *codec) | |
588 | { | ||
589 | const AVCodecHWConfig *config; | ||
590 | HWDevice *dev; | ||
591 | int i; | ||
592 | 6283 | for (i = 0;; i++) { | |
593 | 7924 | config = avcodec_get_hw_config(codec, i); | |
594 |
2/2✓ Branch 0 taken 6283 times.
✓ Branch 1 taken 1641 times.
|
7924 | if (!config) |
595 | 6283 | return NULL; | |
596 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1641 times.
|
1641 | if (!(config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) |
597 | ✗ | continue; | |
598 | 1641 | dev = hw_device_get_by_type(config->device_type); | |
599 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1641 times.
|
1641 | if (dev) |
600 | ✗ | return dev; | |
601 | } | ||
602 | } | ||
603 | |||
604 | 6283 | static int hw_device_setup_for_decode(InputStream *ist) | |
605 | { | ||
606 | const AVCodecHWConfig *config; | ||
607 | enum AVHWDeviceType type; | ||
608 | 6283 | HWDevice *dev = NULL; | |
609 | 6283 | int err, auto_device = 0; | |
610 | |||
611 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6283 times.
|
6283 | if (ist->hwaccel_device) { |
612 | ✗ | dev = hw_device_get_by_name(ist->hwaccel_device); | |
613 | ✗ | if (!dev) { | |
614 | ✗ | if (ist->hwaccel_id == HWACCEL_AUTO) { | |
615 | ✗ | auto_device = 1; | |
616 | ✗ | } else if (ist->hwaccel_id == HWACCEL_GENERIC) { | |
617 | ✗ | type = ist->hwaccel_device_type; | |
618 | ✗ | err = hw_device_init_from_type(type, ist->hwaccel_device, | |
619 | &dev); | ||
620 | } else { | ||
621 | // This will be dealt with by API-specific initialisation | ||
622 | // (using hwaccel_device), so nothing further needed here. | ||
623 | ✗ | return 0; | |
624 | } | ||
625 | } else { | ||
626 | ✗ | if (ist->hwaccel_id == HWACCEL_AUTO) { | |
627 | ✗ | ist->hwaccel_device_type = dev->type; | |
628 | ✗ | } else if (ist->hwaccel_device_type != dev->type) { | |
629 | ✗ | av_log(NULL, AV_LOG_ERROR, "Invalid hwaccel device " | |
630 | "specified for decoder: device %s of type %s is not " | ||
631 | ✗ | "usable with hwaccel %s.\n", dev->name, | |
632 | ✗ | av_hwdevice_get_type_name(dev->type), | |
633 | av_hwdevice_get_type_name(ist->hwaccel_device_type)); | ||
634 | ✗ | return AVERROR(EINVAL); | |
635 | } | ||
636 | } | ||
637 | } else { | ||
638 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6283 times.
|
6283 | if (ist->hwaccel_id == HWACCEL_AUTO) { |
639 | ✗ | auto_device = 1; | |
640 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6283 times.
|
6283 | } else if (ist->hwaccel_id == HWACCEL_GENERIC) { |
641 | ✗ | type = ist->hwaccel_device_type; | |
642 | ✗ | dev = hw_device_get_by_type(type); | |
643 | |||
644 | // When "-qsv_device device" is used, an internal QSV device named | ||
645 | // as "__qsv_device" is created. Another QSV device is created too | ||
646 | // if "-init_hw_device qsv=name:device" is used. There are 2 QSV devices | ||
647 | // if both "-qsv_device device" and "-init_hw_device qsv=name:device" | ||
648 | // are used, hw_device_get_by_type(AV_HWDEVICE_TYPE_QSV) returns NULL. | ||
649 | // To keep back-compatibility with the removed ad-hoc libmfx setup code, | ||
650 | // call hw_device_get_by_name("__qsv_device") to select the internal QSV | ||
651 | // device. | ||
652 | ✗ | if (!dev && type == AV_HWDEVICE_TYPE_QSV) | |
653 | ✗ | dev = hw_device_get_by_name("__qsv_device"); | |
654 | |||
655 | ✗ | if (!dev) | |
656 | ✗ | err = hw_device_init_from_type(type, NULL, &dev); | |
657 | } else { | ||
658 | 6283 | dev = hw_device_match_by_codec(ist->dec); | |
659 |
1/2✓ Branch 0 taken 6283 times.
✗ Branch 1 not taken.
|
6283 | if (!dev) { |
660 | // No device for this codec, but not using generic hwaccel | ||
661 | // and therefore may well not need one - ignore. | ||
662 | 6283 | return 0; | |
663 | } | ||
664 | } | ||
665 | } | ||
666 | |||
667 | ✗ | if (auto_device) { | |
668 | int i; | ||
669 | ✗ | if (!avcodec_get_hw_config(ist->dec, 0)) { | |
670 | // Decoder does not support any hardware devices. | ||
671 | ✗ | return 0; | |
672 | } | ||
673 | ✗ | for (i = 0; !dev; i++) { | |
674 | ✗ | config = avcodec_get_hw_config(ist->dec, i); | |
675 | ✗ | if (!config) | |
676 | ✗ | break; | |
677 | ✗ | type = config->device_type; | |
678 | ✗ | dev = hw_device_get_by_type(type); | |
679 | ✗ | if (dev) { | |
680 | ✗ | av_log(NULL, AV_LOG_INFO, "Using auto " | |
681 | "hwaccel type %s with existing device %s.\n", | ||
682 | ✗ | av_hwdevice_get_type_name(type), dev->name); | |
683 | } | ||
684 | } | ||
685 | ✗ | for (i = 0; !dev; i++) { | |
686 | ✗ | config = avcodec_get_hw_config(ist->dec, i); | |
687 | ✗ | if (!config) | |
688 | ✗ | break; | |
689 | ✗ | type = config->device_type; | |
690 | // Try to make a new device of this type. | ||
691 | ✗ | err = hw_device_init_from_type(type, ist->hwaccel_device, | |
692 | &dev); | ||
693 | ✗ | if (err < 0) { | |
694 | // Can't make a device of this type. | ||
695 | ✗ | continue; | |
696 | } | ||
697 | ✗ | if (ist->hwaccel_device) { | |
698 | ✗ | av_log(NULL, AV_LOG_INFO, "Using auto " | |
699 | "hwaccel type %s with new device created " | ||
700 | "from %s.\n", av_hwdevice_get_type_name(type), | ||
701 | ist->hwaccel_device); | ||
702 | } else { | ||
703 | ✗ | av_log(NULL, AV_LOG_INFO, "Using auto " | |
704 | "hwaccel type %s with new default device.\n", | ||
705 | av_hwdevice_get_type_name(type)); | ||
706 | } | ||
707 | } | ||
708 | ✗ | if (dev) { | |
709 | ✗ | ist->hwaccel_device_type = type; | |
710 | } else { | ||
711 | ✗ | av_log(NULL, AV_LOG_INFO, "Auto hwaccel " | |
712 | "disabled: no device found.\n"); | ||
713 | ✗ | ist->hwaccel_id = HWACCEL_NONE; | |
714 | ✗ | return 0; | |
715 | } | ||
716 | } | ||
717 | |||
718 | ✗ | if (!dev) { | |
719 | ✗ | av_log(NULL, AV_LOG_ERROR, "No device available " | |
720 | "for decoder: device type %s needed for codec %s.\n", | ||
721 | ✗ | av_hwdevice_get_type_name(type), ist->dec->name); | |
722 | ✗ | return err; | |
723 | } | ||
724 | |||
725 | ✗ | ist->dec_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref); | |
726 | ✗ | if (!ist->dec_ctx->hw_device_ctx) | |
727 | ✗ | return AVERROR(ENOMEM); | |
728 | |||
729 | ✗ | return 0; | |
730 | } | ||
731 | |||
732 | 6283 | int dec_open(InputStream *ist) | |
733 | { | ||
734 | 6283 | const AVCodec *codec = ist->dec; | |
735 | int ret; | ||
736 | |||
737 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6283 times.
|
6283 | if (!codec) { |
738 | ✗ | av_log(ist, AV_LOG_ERROR, | |
739 | "Decoding requested, but no decoder found for: %s\n", | ||
740 | ✗ | avcodec_get_name(ist->dec_ctx->codec_id)); | |
741 | ✗ | return AVERROR(EINVAL); | |
742 | } | ||
743 | |||
744 | 6283 | ret = dec_alloc(&ist->decoder); | |
745 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6283 times.
|
6283 | if (ret < 0) |
746 | ✗ | return ret; | |
747 | |||
748 | 6283 | ist->dec_ctx->opaque = ist; | |
749 | 6283 | ist->dec_ctx->get_format = get_format; | |
750 | |||
751 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6282 times.
|
6283 | if (ist->dec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE && |
752 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | (ist->decoding_needed & DECODING_FOR_OST)) { |
753 | 1 | av_dict_set(&ist->decoder_opts, "compute_edt", "1", AV_DICT_DONT_OVERWRITE); | |
754 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (ist->decoding_needed & DECODING_FOR_FILTER) |
755 | ✗ | av_log(NULL, AV_LOG_WARNING, "Warning using DVB subtitles for filtering and output at the same time is not fully supported, also see -compute_edt [0|1]\n"); | |
756 | } | ||
757 | |||
758 | /* Useful for subtitles retiming by lavf (FIXME), skipping samples in | ||
759 | * audio, and video decoders such as cuvid or mediacodec */ | ||
760 | 6283 | ist->dec_ctx->pkt_timebase = ist->st->time_base; | |
761 | |||
762 |
2/2✓ Branch 1 taken 57 times.
✓ Branch 2 taken 6226 times.
|
6283 | if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0)) |
763 | 57 | av_dict_set(&ist->decoder_opts, "threads", "auto", 0); | |
764 | /* Attached pics are sparse, therefore we would not want to delay their decoding till EOF. */ | ||
765 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6278 times.
|
6283 | if (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC) |
766 | 5 | av_dict_set(&ist->decoder_opts, "threads", "1", 0); | |
767 | |||
768 | 6283 | ret = hw_device_setup_for_decode(ist); | |
769 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6283 times.
|
6283 | if (ret < 0) { |
770 | ✗ | av_log(ist, AV_LOG_ERROR, | |
771 | "Hardware device setup failed for decoder: %s\n", | ||
772 | ✗ | av_err2str(ret)); | |
773 | ✗ | return ret; | |
774 | } | ||
775 | |||
776 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6283 times.
|
6283 | if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) { |
777 | ✗ | if (ret == AVERROR_EXPERIMENTAL) | |
778 | ✗ | exit_program(1); | |
779 | |||
780 | ✗ | av_log(ist, AV_LOG_ERROR, "Error while opening decoder: %s\n", | |
781 | ✗ | av_err2str(ret)); | |
782 | ✗ | return ret; | |
783 | } | ||
784 | 6283 | assert_avoptions(ist->decoder_opts); | |
785 | |||
786 | 6283 | return 0; | |
787 | } | ||
788 |