Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2017-2021
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / ffmpeg decode filter
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include <gpac/setup.h>
27 :
28 : #ifdef GPAC_HAS_FFMPEG
29 :
30 : #include "ff_common.h"
31 :
32 : #include <libswscale/swscale.h>
33 :
34 : #define FF_CHECK_PROP(_name, _ffname, _type) if (ctx->_name != ctx->decoder->_ffname) { \
35 : gf_filter_pid_set_property(ctx->out_pid, _type, &PROP_UINT( (u32) ctx->decoder->_ffname ) ); \
36 : ctx->_name = (u32) ctx->decoder->_ffname; \
37 : } \
38 :
39 : #define FF_CHECK_PROPL(_name, _ffname, _type) if (ctx->_name != ctx->decoder->_ffname) { \
40 : gf_filter_pid_set_property(ctx->out_pid, _type, &PROP_LONGUINT( (u32) ctx->decoder->_ffname ) ); \
41 : ctx->_name = (u32) ctx->decoder->_ffname; \
42 : } \
43 :
44 : #define FF_CHECK_PROP_VAL(_name, _val, _type) if (ctx->_name != _val) { \
45 : gf_filter_pid_set_property(ctx->out_pid, _type, &PROP_UINT( _val ) ); \
46 : ctx->_name = _val; \
47 : } \
48 :
49 : static GF_Err ffdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove);
50 :
51 :
52 : typedef struct _gf_ffdec_ctx
53 : {
54 : //internal data
55 : Bool initialized;
56 :
57 : Bool owns_context;
58 : AVCodecContext *decoder;
59 : //decode options
60 : AVDictionary *options;
61 :
62 : Bool reconfig_pending;
63 :
64 : GF_FilterPid *in_pid, *out_pid;
65 : //media type
66 : u32 type;
67 : //CRC32 of extra_data
68 : u32 extra_data_crc;
69 :
70 : GF_Err (*process)(GF_Filter *filter, struct _gf_ffdec_ctx *ctx);
71 :
72 : u32 flush_done;
73 :
74 : //for now we don't share the data
75 : AVFrame *frame;
76 : //audio state
77 : u32 channels, sample_rate, sample_fmt, bytes_per_sample;
78 : u64 channel_layout;
79 : u32 frame_start;
80 : u32 nb_samples_already_in_frame;
81 :
82 : //video state
83 : u32 width, height, pixel_fmt, stride, stride_uv;
84 : GF_Fraction sar;
85 : struct SwsContext *sws_ctx;
86 :
87 : GF_List *src_packets;
88 :
89 : u32 o_ff_pfmt;
90 : Bool force_full_range;
91 : Bool drop_non_refs;
92 :
93 : s64 first_cts_plus_one;
94 : s64 delay;
95 : u32 ts_offset;
96 : } GF_FFDecodeCtx;
97 :
98 141 : static GF_Err ffdec_initialize(GF_Filter *filter)
99 : {
100 141 : GF_FFDecodeCtx *ctx = (GF_FFDecodeCtx *) gf_filter_get_udta(filter);
101 141 : ctx->initialized = GF_TRUE;
102 141 : ctx->src_packets = gf_list_new();
103 :
104 141 : ffmpeg_setup_logs(GF_LOG_CODEC);
105 141 : return GF_OK;
106 : }
107 :
108 140 : static void ffdec_finalize(GF_Filter *filter)
109 : {
110 140 : GF_FFDecodeCtx *ctx = (GF_FFDecodeCtx *) gf_filter_get_udta(filter);
111 :
112 140 : if (ctx->options) av_dict_free(&ctx->options);
113 140 : if (ctx->frame) av_frame_free(&ctx->frame);
114 140 : if (ctx->sws_ctx) sws_freeContext(ctx->sws_ctx);
115 :
116 159 : while (gf_list_count(ctx->src_packets)) {
117 19 : GF_FilterPacket *pck = gf_list_pop_back(ctx->src_packets);
118 19 : gf_filter_pck_unref(pck);
119 : }
120 140 : gf_list_del(ctx->src_packets);
121 :
122 140 : if (ctx->owns_context && ctx->decoder) {
123 140 : avcodec_free_context(&ctx->decoder);
124 : }
125 140 : return;
126 : }
127 :
128 128 : static void ffdec_check_pix_fmt_change(struct _gf_ffdec_ctx *ctx, u32 pix_fmt)
129 : {
130 128 : if (ctx->pixel_fmt != pix_fmt) {
131 124 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_PIXFMT, &PROP_UINT(pix_fmt));
132 124 : ctx->pixel_fmt = pix_fmt;
133 124 : ctx->force_full_range = GF_FALSE;
134 124 : if (ctx->decoder->color_range==AVCOL_RANGE_JPEG)
135 2 : ctx->force_full_range = GF_TRUE;
136 122 : else if (ffmpeg_pixfmt_is_fullrange(ctx->decoder->pix_fmt))
137 0 : ctx->force_full_range = GF_TRUE;
138 : else
139 122 : ctx->force_full_range = GF_FALSE;
140 :
141 124 : if (ctx->force_full_range)
142 2 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_RANGE, &PROP_BOOL(GF_TRUE) );
143 : else
144 122 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_RANGE, NULL );
145 :
146 124 : if (ctx->decoder->color_primaries!=AVCOL_PRI_UNSPECIFIED)
147 0 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_PRIMARIES, &PROP_UINT(ctx->decoder->color_primaries) );
148 : else
149 124 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_PRIMARIES, NULL );
150 :
151 124 : if (ctx->decoder->colorspace!=AVCOL_SPC_UNSPECIFIED)
152 1 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_MX, &PROP_UINT(ctx->decoder->colorspace) );
153 : else
154 123 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_MX, NULL );
155 :
156 124 : if (ctx->decoder->color_trc!=AVCOL_TRC_UNSPECIFIED)
157 0 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_TRANSFER, &PROP_UINT(ctx->decoder->color_trc) );
158 : else
159 124 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_TRANSFER, NULL );
160 : }
161 128 : }
162 :
163 157688 : static GF_Err ffdec_process_video(GF_Filter *filter, struct _gf_ffdec_ctx *ctx)
164 : {
165 : AVPacket pkt;
166 : AVFrame *frame;
167 : AVPicture pict;
168 : Bool is_eos=GF_FALSE;
169 : s32 res;
170 : s32 gotpic;
171 : u64 out_cts;
172 : const char *data = NULL;
173 : Bool seek_flag = GF_FALSE;
174 : u32 i, count, ff_pfmt;
175 157688 : u32 size=0, outsize, pix_out, stride, stride_uv, uv_height, nb_planes;
176 : u8 *out_buffer;
177 : GF_FilterPacket *pck_src;
178 : GF_FilterPacket *dst_pck;
179 157688 : GF_FilterPacket *pck = gf_filter_pid_get_packet(ctx->in_pid);
180 :
181 157688 : if (ctx->reconfig_pending) {
182 : pck = NULL;
183 157666 : } else if (!pck) {
184 76105 : is_eos = gf_filter_pid_is_eos(ctx->in_pid);
185 76105 : if (!is_eos) return GF_OK;
186 : }
187 :
188 156973 : if (pck && ctx->drop_non_refs && !gf_filter_pck_get_sap(pck)) {
189 1 : gf_filter_pid_drop_packet(ctx->in_pid);
190 1 : return GF_OK;
191 : }
192 : //we don't own the codec and we're in end of stream, don't try to decode (the context might have been closed)
193 156994 : if (!pck && !ctx->owns_context) {
194 0 : gf_filter_pid_set_eos(ctx->out_pid);
195 0 : return GF_EOS;
196 : }
197 :
198 156994 : frame = ctx->frame;
199 :
200 156994 : av_init_packet(&pkt);
201 :
202 156994 : if (pck) {
203 81560 : data = gf_filter_pck_get_data(pck, &size);
204 :
205 81560 : if (!size) {
206 0 : gf_filter_pid_drop_packet(ctx->in_pid);
207 0 : return GF_OK;
208 : }
209 :
210 81560 : pck_src = pck;
211 81560 : gf_filter_pck_ref_props(&pck_src);
212 81560 : if (pck_src) gf_list_add(ctx->src_packets, pck_src);
213 :
214 : //seems ffmpeg is not properly handling the decoding after a flush, we close and reopen the codec
215 81560 : if (ctx->flush_done) {
216 : #if 0
217 : AVDictionary *options = NULL;
218 : const AVCodec *codec = ctx->decoder->codec;
219 : avcodec_free_context(&ctx->decoder);
220 :
221 : av_dict_copy(&options, ctx->options, 0);
222 : avcodec_open2(ctx->decoder, codec, &options );
223 : if (options) av_dict_free(&options);
224 : #else
225 2 : avcodec_flush_buffers(ctx->decoder);
226 : #endif
227 2 : ctx->flush_done = GF_FALSE;
228 : }
229 :
230 81560 : pkt.dts = gf_filter_pck_get_dts(pck);
231 81560 : pkt.pts = gf_filter_pck_get_cts(pck);
232 81560 : pkt.duration = gf_filter_pck_get_duration(pck);
233 81560 : if (gf_filter_pck_get_sap(pck)>0)
234 3317 : pkt.flags = AV_PKT_FLAG_KEY;
235 : }
236 156994 : pkt.data = (uint8_t*)data;
237 156994 : pkt.size = size;
238 :
239 : /*TOCHECK: for AVC bitstreams after ISMA decryption, in case (as we do) the decryption DRM tool
240 : doesn't put back nalu size, we have to do it ourselves, but we can't modify input data...*/
241 :
242 156994 : gotpic=0;
243 156994 : res = avcodec_decode_video2(ctx->decoder, frame, &gotpic, &pkt);
244 156994 : if (pck) gf_filter_pid_drop_packet(ctx->in_pid);
245 :
246 156994 : if (!gotpic) {
247 75474 : if (is_eos) {
248 75336 : ctx->flush_done = GF_TRUE;
249 75336 : gf_filter_pid_set_eos(ctx->out_pid);
250 75336 : return GF_EOS;
251 : }
252 138 : if (ctx->reconfig_pending) {
253 7 : avcodec_free_context(&ctx->decoder);
254 7 : ctx->decoder = NULL;
255 7 : ctx->reconfig_pending = GF_FALSE;
256 : //these properties are checked after decode, when we reconfigure we copy props from input to output
257 : //so we need to make sure we retrigger pid config even if these did not change
258 7 : ctx->pixel_fmt = 0;
259 7 : ctx->width = 0;
260 7 : ctx->height = 0;
261 7 : ctx->stride = 0;
262 7 : ctx->stride_uv = 0;
263 7 : ctx->sar.num = ctx->sar.den = 0;
264 14 : while (gf_list_count(ctx->src_packets)) {
265 0 : GF_FilterPacket *ref_pck = gf_list_pop_back(ctx->src_packets);
266 0 : gf_filter_pck_unref(ref_pck);
267 : }
268 7 : GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[FFDec] PID %s reconfigure pending and all frames flushed, reconfguring\n", gf_filter_pid_get_name(ctx->in_pid) ));
269 7 : return ffdec_configure_pid(filter, ctx->in_pid, GF_FALSE);
270 : }
271 : }
272 :
273 81651 : if (res < 0) {
274 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] PID %s failed to decode frame PTS "LLU": %s\n", gf_filter_pid_get_name(ctx->in_pid), pkt.pts, av_err2str(res) ));
275 : return GF_NON_COMPLIANT_BITSTREAM;
276 : }
277 81651 : if (!gotpic) return GF_OK;
278 :
279 81520 : if (ctx->decoder->pix_fmt != ctx->o_ff_pfmt) {
280 8 : u32 pix_fmt = ffmpeg_pixfmt_to_gpac(ctx->decoder->pix_fmt);
281 8 : ctx->o_ff_pfmt = ctx->decoder->pix_fmt;
282 8 : if (!pix_fmt) {
283 : pix_fmt = GF_PIXEL_RGB;
284 0 : ctx->o_ff_pfmt = AV_PIX_FMT_RGB24;
285 : }
286 8 : ffdec_check_pix_fmt_change(ctx, pix_fmt);
287 : }
288 : //update all props
289 81520 : FF_CHECK_PROP(width, width, GF_PROP_PID_WIDTH)
290 81520 : FF_CHECK_PROP(height, height, GF_PROP_PID_HEIGHT)
291 :
292 81520 : stride = stride_uv = uv_height = nb_planes = 0;
293 81520 : if (! gf_pixel_get_size_info(ctx->pixel_fmt, ctx->width, ctx->height, &outsize, &stride, &stride_uv, &nb_planes, &uv_height) ) {
294 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] PID %s failed to query pixelformat size infon", gf_filter_pid_get_name(ctx->in_pid) ));
295 : return GF_NOT_SUPPORTED;
296 : }
297 :
298 81520 : FF_CHECK_PROP_VAL(stride, stride, GF_PROP_PID_STRIDE)
299 81520 : FF_CHECK_PROP_VAL(stride_uv, stride_uv, GF_PROP_PID_STRIDE_UV)
300 81520 : if (ctx->sar.num * ctx->decoder->sample_aspect_ratio.den != ctx->sar.den * ctx->decoder->sample_aspect_ratio.num) {
301 0 : ctx->sar.num = ctx->decoder->sample_aspect_ratio.num;
302 0 : ctx->sar.den = ctx->decoder->sample_aspect_ratio.den;
303 :
304 0 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_SAR, &PROP_FRAC( ctx->sar ) );
305 : }
306 :
307 : memset(&pict, 0, sizeof(pict));
308 :
309 81520 : pck_src = NULL;
310 81520 : count = gf_list_count(ctx->src_packets);
311 145631 : for (i=0; i<count; i++) {
312 : u64 cts;
313 145631 : pck_src = gf_list_get(ctx->src_packets, i);
314 145631 : cts = gf_filter_pck_get_cts(pck_src);
315 145631 : if (cts == frame->pts)
316 : break;
317 64111 : if (cts == frame->pkt_pts)
318 : break;
319 64111 : pck_src = NULL;
320 : }
321 :
322 : seek_flag = GF_FALSE;
323 81520 : if (pck_src) {
324 81520 : seek_flag = gf_filter_pck_get_seek_flag(pck_src);
325 81520 : out_cts = gf_filter_pck_get_cts(pck_src);
326 : } else {
327 0 : out_cts = frame->pts;
328 : }
329 : //this was a seek frame, do not dispatch
330 81520 : if (seek_flag) {
331 33 : if (pck_src) {
332 33 : gf_list_del_item(ctx->src_packets, pck_src);
333 33 : gf_filter_pck_unref(pck_src);
334 : }
335 : return GF_OK;
336 : }
337 :
338 81487 : dst_pck = gf_filter_pck_new_alloc(ctx->out_pid, outsize, &out_buffer);
339 81487 : if (!dst_pck) return GF_OUT_OF_MEM;
340 :
341 81487 : if (pck_src) {
342 81487 : gf_filter_pck_merge_properties(pck_src, dst_pck);
343 81487 : gf_list_del_item(ctx->src_packets, pck_src);
344 81487 : gf_filter_pck_unref(pck_src);
345 : } else {
346 0 : gf_filter_pck_set_sap(dst_pck, GF_FILTER_SAP_1);
347 : }
348 :
349 : //rewrite dts and pts to PTS value
350 81487 : gf_filter_pck_set_dts(dst_pck, out_cts);
351 81487 : gf_filter_pck_set_cts(dst_pck, out_cts);
352 :
353 81487 : ff_pfmt = ctx->decoder->pix_fmt;
354 81487 : if (ff_pfmt==AV_PIX_FMT_YUVJ420P) {
355 : ff_pfmt = AV_PIX_FMT_YUV420P;
356 1 : if (!ctx->force_full_range) {
357 1 : ctx->force_full_range = GF_TRUE;
358 1 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_RANGE, &PROP_BOOL(GF_TRUE));
359 : }
360 : }
361 :
362 : //TODO: cleanup, we should not convert pixel format in the decoder but through filters !
363 81487 : switch (ctx->pixel_fmt) {
364 1 : case GF_PIXEL_RGB:
365 1 : pict.data[0] = (uint8_t *)out_buffer;
366 1 : pict.linesize[0] = 3*ctx->width;
367 : pix_out = AV_PIX_FMT_RGB24;
368 1 : break;
369 1 : case GF_PIXEL_RGBA:
370 1 : pict.data[0] = (uint8_t *)out_buffer;
371 1 : pict.linesize[0] = 4*ctx->width;
372 : pix_out = AV_PIX_FMT_RGBA;
373 1 : break;
374 21441 : case GF_PIXEL_YUV:
375 : case GF_PIXEL_YUV_10:
376 21441 : pict.data[0] = (uint8_t *)out_buffer;
377 21441 : pict.data[1] = (uint8_t *)out_buffer + ctx->stride * ctx->height;
378 21441 : pict.data[2] = (uint8_t *)pict.data[1] + ctx->stride_uv * uv_height;
379 21441 : pict.linesize[0] = ctx->stride;
380 21441 : pict.linesize[1] = pict.linesize[2] = ctx->stride_uv;
381 21441 : if (ctx->pixel_fmt == GF_PIXEL_YUV_10)
382 : pix_out = AV_PIX_FMT_YUV420P10LE;
383 : else
384 : pix_out = AV_PIX_FMT_YUV420P;
385 : break;
386 :
387 30022 : case GF_PIXEL_YUV422:
388 : case GF_PIXEL_YUV422_10:
389 30022 : pict.data[0] = (uint8_t *)out_buffer;
390 30022 : pict.data[1] = (uint8_t *)out_buffer + ctx->stride * ctx->height;
391 30022 : pict.data[2] = (uint8_t *)pict.data[1] + ctx->stride_uv * ctx->height;
392 30022 : pict.linesize[0] = ctx->stride;
393 30022 : pict.linesize[1] = pict.linesize[2] = ctx->stride_uv;
394 30022 : if (ctx->pixel_fmt == GF_PIXEL_YUV422_10)
395 : pix_out = AV_PIX_FMT_YUV422P10LE;
396 : else
397 : pix_out = AV_PIX_FMT_YUV422P;
398 : break;
399 :
400 30022 : case GF_PIXEL_YUV444:
401 : case GF_PIXEL_YUV444_10:
402 30022 : pict.data[0] = (uint8_t *)out_buffer;
403 30022 : pict.data[1] = (uint8_t *)out_buffer + ctx->stride * ctx->height;
404 30022 : pict.data[2] = (uint8_t *)out_buffer + 2*ctx->stride * ctx->height;
405 30022 : pict.linesize[0] = pict.linesize[1] = pict.linesize[2] = ctx->stride;
406 30022 : if (ctx->pixel_fmt == GF_PIXEL_YUV444_10)
407 : pix_out = AV_PIX_FMT_YUV444P10LE;
408 : else
409 : pix_out = AV_PIX_FMT_YUV444P;
410 : break;
411 :
412 0 : default:
413 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] Unsupported pixel format %s, patch welcome\n", av_get_pix_fmt_name(ctx->decoder->pix_fmt) ));
414 :
415 0 : gf_filter_pck_discard(dst_pck);
416 :
417 0 : return GF_NOT_SUPPORTED;
418 : }
419 :
420 325948 : ctx->sws_ctx = sws_getCachedContext(ctx->sws_ctx,
421 81487 : ctx->decoder->width, ctx->decoder->height, ff_pfmt,
422 162974 : ctx->width, ctx->height, pix_out, SWS_BICUBIC, NULL, NULL, NULL);
423 81487 : if (ctx->sws_ctx) {
424 81487 : sws_scale(ctx->sws_ctx, (const uint8_t * const*)frame->data, frame->linesize, 0, ctx->height, pict.data, pict.linesize);
425 : }
426 :
427 81487 : gf_filter_pck_set_seek_flag(dst_pck, GF_FALSE);
428 :
429 81487 : if (frame->interlaced_frame)
430 0 : gf_filter_pck_set_interlaced(dst_pck, frame->top_field_first ? 2 : 1);
431 :
432 81487 : gf_filter_pck_send(dst_pck);
433 81487 : return GF_OK;
434 : }
435 :
436 :
437 3978 : static GF_Err ffdec_process_audio(GF_Filter *filter, struct _gf_ffdec_ctx *ctx)
438 : {
439 : AVPacket pkt;
440 : s32 gotpic;
441 : s32 len, in_size, i;
442 : u32 samples_to_trash;
443 : u32 output_size, prev_afmt;
444 : Bool is_eos=GF_FALSE;
445 : u8 *data;
446 : AVFrame *frame;
447 : GF_FilterPacket *dst_pck, *src_pck;
448 : GF_FilterPacket *pck;
449 :
450 : decode_next:
451 5900 : pck = gf_filter_pid_get_packet(ctx->in_pid);
452 5900 : in_size = 0;
453 :
454 5900 : if (ctx->reconfig_pending) {
455 : pck = NULL;
456 5900 : } else if (!pck) {
457 3024 : is_eos = gf_filter_pid_is_eos(ctx->in_pid);
458 3024 : if (!is_eos) return GF_OK;
459 : }
460 :
461 3018 : av_init_packet(&pkt);
462 3018 : if (pck) pkt.data = (uint8_t *) gf_filter_pck_get_data(pck, &in_size);
463 :
464 3018 : if (pck) {
465 2876 : src_pck = pck;
466 2876 : gf_filter_pck_ref_props(&src_pck);
467 2876 : if (src_pck) gf_list_add(ctx->src_packets, src_pck);
468 :
469 2876 : if (!pkt.data) {
470 0 : gf_filter_pid_drop_packet(ctx->in_pid);
471 0 : return GF_OK;
472 : }
473 :
474 2876 : pkt.pts = gf_filter_pck_get_cts(pck);
475 2876 : pkt.dts = gf_filter_pck_get_dts(pck);
476 :
477 2876 : pkt.size = in_size;
478 2876 : if ((s32) ctx->frame_start > pkt.size) ctx->frame_start = 0;
479 : //seek to last byte consumed by the previous decode4()
480 2876 : else if (ctx->frame_start) {
481 0 : pkt.data += ctx->frame_start;
482 0 : pkt.size -= ctx->frame_start;
483 : }
484 2876 : pkt.duration = gf_filter_pck_get_duration(pck);
485 2876 : if (gf_filter_pck_get_sap(pck)>0)
486 2876 : pkt.flags = AV_PKT_FLAG_KEY;
487 :
488 2876 : if (!ctx->first_cts_plus_one)
489 31 : ctx->first_cts_plus_one = pkt.pts + 1;
490 :
491 : } else {
492 142 : pkt.size = 0;
493 : }
494 :
495 3018 : prev_afmt = ctx->decoder->sample_fmt;
496 3018 : frame = ctx->frame;
497 3018 : len = avcodec_decode_audio4(ctx->decoder, frame, &gotpic, &pkt);
498 :
499 : samples_to_trash = 0;
500 3018 : if ( gotpic && (ctx->delay<0)) {
501 0 : if (pkt.pts + 1 - ctx->first_cts_plus_one + ctx->delay < 0) {
502 0 : if (pkt.duration + ctx->delay < 0) {
503 0 : frame->nb_samples = 0;
504 : samples_to_trash = 0;
505 0 : ctx->delay += pkt.duration;
506 : } else {
507 0 : samples_to_trash = (u32) -ctx->delay;
508 : }
509 :
510 0 : if (!samples_to_trash || (samples_to_trash > (u32) frame->nb_samples) ) {
511 0 : frame->nb_samples = 0;
512 : samples_to_trash = 0;
513 : }
514 0 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_DELAY, NULL);
515 : } else {
516 0 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_DELAY, NULL);
517 0 : ctx->delay = 0;
518 : }
519 : }
520 :
521 : //this will handle eos as well
522 3018 : if ((len<0) || !gotpic) {
523 169 : ctx->frame_start = 0;
524 169 : if (pck) gf_filter_pid_drop_packet(ctx->in_pid);
525 169 : if (pkt.size && (len<0)) {
526 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] PID %s failed to decode frame PTS "LLU": %s\n", gf_filter_pid_get_name(ctx->in_pid), pkt.pts, av_err2str(len) ));
527 : return GF_NON_COMPLIANT_BITSTREAM;
528 : }
529 169 : if (is_eos) {
530 142 : gf_filter_pid_set_eos(ctx->out_pid);
531 142 : return GF_EOS;
532 : }
533 27 : if (ctx->reconfig_pending) {
534 0 : avcodec_free_context(&ctx->decoder);
535 0 : ctx->decoder = NULL;
536 0 : ctx->reconfig_pending = GF_FALSE;
537 : //these properties are checked after decode, when we reconfigure we copy props from input to output
538 : //so we need to make sure we retrigger pid config even if these did not change
539 0 : ctx->sample_fmt = 0;
540 0 : ctx->sample_rate = 0;
541 0 : ctx->channels = 0;
542 0 : ctx->channel_layout = 0;
543 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[FFDec] PID %s reconfigure pending and all frames flushed, reconfguring\n", gf_filter_pid_get_name(ctx->in_pid) ));
544 0 : return ffdec_configure_pid(filter, ctx->in_pid, GF_FALSE);
545 : }
546 : return GF_OK;
547 : }
548 :
549 2849 : FF_CHECK_PROP(channels, channels, GF_PROP_PID_NUM_CHANNELS)
550 2849 : FF_CHECK_PROPL(channel_layout, channel_layout, GF_PROP_PID_CHANNEL_LAYOUT)
551 2849 : FF_CHECK_PROP(sample_rate, sample_rate, GF_PROP_PID_SAMPLE_RATE)
552 :
553 2849 : if (prev_afmt != ctx->decoder->sample_fmt) {
554 0 : ctx->sample_fmt = ffmpeg_audio_fmt_to_gpac(ctx->decoder->sample_fmt);
555 0 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_AUDIO_FORMAT, &PROP_UINT(ctx->sample_fmt) );
556 0 : ctx->bytes_per_sample = gf_audio_fmt_bit_depth(ctx->sample_fmt) / 8;
557 : }
558 :
559 2849 : if (pck && gf_filter_pid_eos_received(ctx->in_pid)) {
560 433 : u32 timescale = gf_filter_pck_get_timescale(pck);
561 433 : u64 odur = gf_filter_pck_get_duration(pck);
562 433 : if (timescale != ctx->sample_rate) {
563 0 : odur *= ctx->sample_rate;
564 0 : odur /= timescale;
565 : }
566 433 : if (odur < frame->nb_samples) {
567 0 : frame->nb_samples = (int) odur;
568 : }
569 : }
570 :
571 :
572 2849 : output_size = (frame->nb_samples - samples_to_trash) * ctx->channels * ctx->bytes_per_sample;
573 2849 : dst_pck = gf_filter_pck_new_alloc(ctx->out_pid, output_size, &data);
574 2849 : if (!dst_pck) return GF_OUT_OF_MEM;
575 :
576 2849 : switch (frame->format) {
577 : case AV_SAMPLE_FMT_U8P:
578 : case AV_SAMPLE_FMT_S16P:
579 : case AV_SAMPLE_FMT_S32P:
580 : case AV_SAMPLE_FMT_FLTP:
581 : case AV_SAMPLE_FMT_DBLP:
582 5550 : for (i=0; (u32) i< ctx->channels; i++) {
583 5550 : char *inputChannel = frame->extended_data[i] + samples_to_trash * ctx->bytes_per_sample;
584 5550 : memcpy(data, inputChannel, ctx->bytes_per_sample * (frame->nb_samples-samples_to_trash) );
585 5550 : data += ctx->bytes_per_sample * (frame->nb_samples-samples_to_trash);
586 : }
587 : break;
588 68 : default:
589 68 : memcpy(data, ctx->frame->data[0] + samples_to_trash * ctx->bytes_per_sample, ctx->bytes_per_sample * (frame->nb_samples - samples_to_trash) * ctx->channels);
590 : break;
591 : }
592 :
593 : //we don't follow the same approach as in video, we assume the codec works with one in one out
594 : //and use the first entry in src packets to match in order to copy the properties
595 : //a nicer approach would be to count delay frames (number of frames used to initialize)
596 : //and backmerge properties from the last packet in to the last-nb_init_frames
597 2849 : src_pck = gf_list_get(ctx->src_packets, 0);
598 :
599 2849 : if (src_pck) {
600 2849 : gf_filter_pck_merge_properties(src_pck, dst_pck);
601 2849 : gf_list_rem(ctx->src_packets, 0);
602 2849 : gf_filter_pck_unref(src_pck);
603 : }
604 :
605 2849 : if (output_size) {
606 2849 : if (frame->pkt_pts != AV_NOPTS_VALUE) {
607 2849 : u64 pts = frame->pkt_pts;
608 2849 : u32 timescale = gf_filter_pck_get_timescale(pck);
609 2849 : if (ctx->nb_samples_already_in_frame) {
610 0 : if (ctx->sample_rate == timescale) {
611 0 : pts += ctx->nb_samples_already_in_frame;
612 : }
613 : }
614 2849 : if (pts >= ctx->ts_offset) pts -= ctx->ts_offset;
615 : else pts = 0;
616 2849 : gf_filter_pck_set_cts(dst_pck, pts);
617 2849 : gf_filter_pck_set_dts(dst_pck, pts);
618 : }
619 2849 : gf_filter_pck_send(dst_pck);
620 : } else {
621 0 : gf_filter_pck_discard(dst_pck);
622 : }
623 :
624 2849 : ctx->frame_start += len;
625 : //done with this input packet
626 2849 : if (in_size <= (s32) ctx->frame_start) {
627 2849 : frame->nb_samples = 0;
628 2849 : ctx->frame_start = 0;
629 2849 : ctx->nb_samples_already_in_frame = 0;
630 2849 : gf_filter_pid_drop_packet(ctx->in_pid);
631 :
632 2849 : if (gf_filter_pid_would_block(ctx->out_pid))
633 : return GF_OK;
634 :
635 : //if space available in ouput, decode right away - needed for audio formats with very short frames
636 : //avoid recursion
637 : goto decode_next;
638 : }
639 : //still some data to decode in packet, don't drop it
640 : //todo: check if frame->pkt_pts or frame->pts is updated by ffmpeg, otherwise do it ourselves !
641 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] Code not yet tested - frame PTS was "LLU" - nb samples dec %d\n", frame->pkt_pts, frame->nb_samples));
642 0 : ctx->nb_samples_already_in_frame += frame->nb_samples;
643 0 : frame->nb_samples = 0;
644 :
645 : //avoid recursion
646 0 : goto decode_next;
647 :
648 : // return ffdec_process_audio(filter, ctx);
649 : }
650 :
651 : #ifdef FF_SUB_SUPPORT
652 : static GF_Err ffdec_process_subtitle(GF_Filter *filter, struct _gf_ffdec_ctx *ctx)
653 : {
654 : AVPacket pkt;
655 : AVSubtitle subs;
656 : s32 gotpic;
657 : s32 len, in_size;
658 : Bool is_eos=GF_FALSE;
659 :
660 : GF_FilterPacket *pck = gf_filter_pid_get_packet(ctx->in_pid);
661 :
662 : if (!pck) {
663 : is_eos = gf_filter_pid_is_eos(ctx->in_pid);
664 : if (!is_eos) return GF_OK;
665 : }
666 : av_init_packet(&pkt);
667 : if (pck) pkt.data = (uint8_t *) gf_filter_pck_get_data(pck, &in_size);
668 :
669 : if (!is_eos) {
670 : u64 dts;
671 : pkt.pts = gf_filter_pck_get_cts(pck);
672 :
673 : //copy over SAP and duration in dts
674 : dts = gf_filter_pck_get_sap(pck);
675 : dts <<= 32;
676 : dts |= gf_filter_pck_get_duration(pck);
677 : pkt.dts = dts;
678 :
679 : pkt.size = in_size;
680 : if (ctx->frame_start > pkt.size) ctx->frame_start = 0;
681 : //seek to last byte consumed by the previous decode4()
682 : else if (ctx->frame_start) {
683 : pkt.data += ctx->frame_start;
684 : pkt.size -= ctx->frame_start;
685 : }
686 : } else {
687 : pkt.size = 0;
688 : }
689 :
690 : memset(&subs, 0, sizeof(AVSubtitle));
691 : len = avcodec_decode_subtitle2(ctx->decoder, &subs, &gotpic, &pkt);
692 :
693 : //this will handle eos as well
694 : if ((len<0) || !gotpic) {
695 : ctx->frame_start = 0;
696 : if (pck) gf_filter_pid_drop_packet(ctx->in_pid);
697 : if (len<0) {
698 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] PID %s failed to decode frame PTS "LLU": %s\n", gf_filter_pid_get_name(ctx->in_pid), pkt.pts, av_err2str(len) ));
699 : return GF_NON_COMPLIANT_BITSTREAM;
700 : }
701 : if (is_eos) {
702 : gf_filter_pid_set_eos(ctx->out_pid);
703 : return GF_EOS;
704 : }
705 : return GF_OK;
706 : }
707 : //TODO - do we want to remap to TX3G/other and handle the rendering some place else, or do we do the rendering here ?
708 :
709 :
710 : avsubtitle_free(&subs);
711 : if (pck) gf_filter_pid_drop_packet(ctx->in_pid);
712 : return GF_OK;
713 : }
714 : #endif
715 :
716 161666 : static GF_Err ffdec_process(GF_Filter *filter)
717 : {
718 161666 : GF_FFDecodeCtx *ctx = (GF_FFDecodeCtx *) gf_filter_get_udta(filter);
719 161666 : if (gf_filter_pid_would_block(ctx->out_pid))
720 : return GF_OK;
721 :
722 161666 : return ctx->process(filter, ctx);
723 : }
724 :
725 : static const GF_FilterCapability FFDecodeAnnexBCaps[] =
726 : {
727 : CAP_UINT(GF_CAPS_INPUT_OUTPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_VISUAL),
728 : CAP_BOOL(GF_CAPS_INPUT, GF_PROP_PID_UNFRAMED, GF_TRUE),
729 : CAP_UINT(GF_CAPS_INPUT, GF_PROP_PID_CODECID, GF_CODECID_VVC),
730 : CAP_UINT(GF_CAPS_INPUT, GF_PROP_PID_CODECID, GF_CODECID_AVC),
731 : CAP_UINT(GF_CAPS_INPUT, GF_PROP_PID_CODECID, GF_CODECID_HEVC),
732 : CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_CODECID, GF_CODECID_RAW),
733 : };
734 :
735 :
736 161 : static GF_Err ffdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
737 : {
738 : s32 res;
739 : u32 type=0, gpac_codecid=0;
740 161 : AVDictionary *options = NULL;
741 : const GF_PropertyValue *prop;
742 : AVCodec *codec=NULL;
743 161 : GF_FFDecodeCtx *ctx = (GF_FFDecodeCtx *) gf_filter_get_udta(filter);
744 :
745 : //disconnect of src pid (not yet supported)
746 161 : if (is_remove) {
747 : //one in one out, this is simple
748 3 : if (ctx->out_pid) {
749 3 : gf_filter_pid_remove(ctx->out_pid);
750 3 : ctx->out_pid = NULL;
751 : }
752 : return GF_OK;
753 : }
754 :
755 : //check our PID: streamtype and codecid
756 158 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_STREAM_TYPE);
757 158 : if (!prop) return GF_NOT_SUPPORTED;
758 :
759 158 : type = prop->value.uint;
760 158 : switch (type) {
761 : case GF_STREAM_AUDIO:
762 : case GF_STREAM_VISUAL:
763 : #ifdef FF_SUB_SUPPORT
764 : case GF_STREAM_TEXT:
765 : #endif
766 : break;
767 : default:
768 : return GF_NOT_SUPPORTED;
769 : }
770 158 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_CODECID);
771 158 : if (!prop) return GF_NOT_SUPPORTED;
772 158 : gpac_codecid = prop->value.uint;
773 158 : if (gpac_codecid==GF_CODECID_RAW)
774 : return GF_NOT_SUPPORTED;
775 :
776 :
777 : //initial config or update
778 158 : if (!ctx->in_pid || (ctx->in_pid==pid)) {
779 158 : ctx->in_pid = pid;
780 158 : if (!ctx->type) ctx->type = type;
781 17 : else if (ctx->type != type) {
782 : return GF_NOT_SUPPORTED;
783 : }
784 : } else {
785 : //only one input pid in ctx
786 : if (ctx->in_pid) return GF_REQUIRES_NEW_INSTANCE;
787 : }
788 :
789 158 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_WIDTH);
790 158 : ctx->width = prop ? prop->value.uint : 0;
791 158 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_HEIGHT);
792 158 : ctx->height = prop ? prop->value.uint : 0;
793 158 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_SAMPLE_RATE);
794 158 : ctx->sample_rate = prop ? prop->value.uint : 0;
795 158 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_NUM_CHANNELS);
796 158 : ctx->channels = prop ? prop->value.uint : 0;
797 :
798 158 : if (gpac_codecid==GF_CODECID_VVC) {
799 0 : u32 codec_id = ffmpeg_codecid_from_gpac(gpac_codecid, NULL);
800 0 : codec = codec_id ? avcodec_find_decoder(codec_id) : NULL;
801 : //libvvdec only supports annexB, request ufnalu adaptation filter
802 0 : if (codec && codec->name && strstr(codec->name, "vvdec")) {
803 0 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_UNFRAMED);
804 0 : if (!prop || !prop->value.boolean) {
805 0 : gf_filter_override_caps(filter, FFDecodeAnnexBCaps, GF_ARRAY_LENGTH(FFDecodeAnnexBCaps));
806 0 : gf_filter_pid_negociate_property(ctx->in_pid, GF_PROP_PID_UNFRAMED, &PROP_BOOL(GF_TRUE) );
807 0 : return GF_OK;
808 : }
809 : }
810 : }
811 :
812 :
813 158 : if (gpac_codecid == GF_CODECID_FFMPEG) {
814 0 : prop = gf_filter_pid_get_property(pid, GF_FFMPEG_DECODER_CONFIG);
815 0 : if (!prop || !prop->value.ptr) {
816 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] PID %s codec context not exposed by demuxer !\n", gf_filter_pid_get_name(pid) ));
817 : return GF_SERVICE_ERROR;
818 : }
819 0 : ctx->decoder = prop->value.ptr;
820 0 : codec = avcodec_find_decoder(ctx->decoder->codec_id);
821 0 : if (!codec) return GF_NOT_SUPPORTED;
822 :
823 0 : ctx->owns_context = GF_FALSE;
824 : }
825 : //we reconfigure the stream
826 : else {
827 158 : u32 codec_id, ff_codectag=0;
828 :
829 158 : if (!ctx->owns_context) {
830 141 : ctx->decoder = NULL;
831 : }
832 158 : if (ctx->decoder) {
833 10 : codec_id = ffmpeg_codecid_from_gpac(gpac_codecid, NULL);
834 : //same codec, same config, don't reinit
835 10 : if (ctx->decoder->codec->id == codec_id) {
836 : u32 cfg_crc=0;
837 10 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_DECODER_CONFIG);
838 10 : if (prop && prop->value.data.ptr && prop->value.data.size) {
839 10 : cfg_crc = gf_crc_32(prop->value.data.ptr, prop->value.data.size);
840 : }
841 10 : if (cfg_crc == ctx->extra_data_crc) {
842 : goto reuse_codec_context;
843 : }
844 : }
845 :
846 :
847 : //we could further optimize by detecting we have the same codecid and injecting the extradata
848 : //but this is not 100% reliable, and will require parsing AVC/HEVC config
849 : //since this seems to work properly with decoder close/open, we keep it as is
850 7 : ctx->reconfig_pending = GF_TRUE;
851 7 : GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[FFDec] PID %s reconfigure detected, flushing frame\n", gf_filter_pid_get_name(pid) ));
852 7 : return GF_OK;
853 : }
854 :
855 148 : codec_id = ffmpeg_codecid_from_gpac(gpac_codecid, &ff_codectag);
856 : //specific remaps
857 148 : if (!codec_id) {
858 0 : switch (gpac_codecid) {
859 : case GF_CODECID_MVC: codec_id = AV_CODEC_ID_H264; break;
860 : }
861 :
862 : }
863 148 : if (codec_id) codec = avcodec_find_decoder(codec_id);
864 148 : if (!codec) {
865 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] No decoder found for codec %s\n", gf_codecid_name(gpac_codecid) ));
866 : return GF_NOT_SUPPORTED;
867 : }
868 :
869 148 : ctx->decoder = avcodec_alloc_context3(NULL);
870 148 : if (! ctx->decoder) return GF_OUT_OF_MEM;
871 148 : ctx->owns_context = GF_TRUE;
872 148 : if (ff_codectag)
873 0 : ctx->decoder->codec_tag = ff_codectag;
874 :
875 148 : ffmpeg_set_enc_dec_flags(ctx->options, ctx->decoder);
876 :
877 : //for some raw codecs
878 148 : if (ctx->width && ctx->height) {
879 117 : ctx->decoder->width = ctx->width;
880 117 : ctx->decoder->height = ctx->height;
881 : }
882 148 : if (ctx->sample_rate && ctx->channels) {
883 31 : ctx->decoder->sample_rate = ctx->sample_rate;
884 31 : ctx->decoder->channels = ctx->channels;
885 : }
886 :
887 : //we may have a dsi here!
888 148 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_DECODER_CONFIG);
889 148 : if (prop && prop->value.data.ptr && prop->value.data.size) {
890 : //looks like ffmpeg wants the fLaC keyword
891 140 : if (gpac_codecid==GF_CODECID_FLAC) {
892 1 : ctx->decoder->extradata_size = prop->value.data.size+4;
893 1 : ctx->decoder->extradata = av_malloc(sizeof(char) * prop->value.data.size+4);
894 1 : memcpy(ctx->decoder->extradata, "fLaC", 4);
895 1 : memcpy(ctx->decoder->extradata+4, prop->value.data.ptr, prop->value.data.size);
896 : } else {
897 139 : ctx->decoder->extradata_size = prop->value.data.size;
898 139 : ctx->decoder->extradata = av_malloc(sizeof(char) * prop->value.data.size);
899 139 : memcpy(ctx->decoder->extradata, prop->value.data.ptr, prop->value.data.size);
900 : }
901 140 : ctx->extra_data_crc = gf_crc_32(prop->value.data.ptr, prop->value.data.size);
902 : }
903 : }
904 :
905 : //by default let libavcodec decide - if single thread is required, let the user define -threads option
906 148 : if (codec->capabilities & AV_CODEC_CAP_AUTO_THREADS)
907 0 : ctx->decoder->thread_count = 0;
908 :
909 : //clone options (in case we need to destroy/recreate the codec) and open codec
910 148 : av_dict_copy(&options, ctx->options, 0);
911 148 : res = avcodec_open2(ctx->decoder, codec, &options);
912 148 : if (res < 0) {
913 0 : if (options) av_dict_free(&options);
914 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] PID %s failed to open codec context: %s\n", gf_filter_pid_get_name(pid), av_err2str(res) ));
915 : return GF_NON_COMPLIANT_BITSTREAM;
916 : }
917 :
918 148 : if (options) {
919 42 : ffmpeg_report_unused_options(filter, options);
920 42 : av_dict_free(&options);
921 : }
922 :
923 : //we're good to go, declare our output pid
924 148 : ctx->in_pid = pid;
925 148 : if (!ctx->out_pid) {
926 : char szCodecName[1000];
927 141 : ctx->out_pid = gf_filter_pid_new(filter);
928 :
929 : //to change once we implement on-the-fly codec change
930 141 : sprintf(szCodecName, "ffdec:%s", ctx->decoder->codec->name ? ctx->decoder->codec->name : "unknown");
931 141 : gf_filter_set_name(filter, szCodecName);
932 141 : gf_filter_pid_set_framing_mode(ctx->in_pid, GF_TRUE);
933 : }
934 :
935 158 : reuse_codec_context:
936 : //copy props it at init config or at reconfig
937 151 : if (ctx->out_pid) {
938 151 : gf_filter_pid_copy_properties(ctx->out_pid, ctx->in_pid);
939 151 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_CODECID, &PROP_UINT(GF_CODECID_RAW) );
940 151 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_DECODER_CONFIG, NULL );
941 : }
942 :
943 151 : if (type==GF_STREAM_VISUAL) {
944 : u32 pix_fmt;
945 120 : ctx->force_full_range = GF_FALSE;
946 120 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_RANGE, NULL );
947 120 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_MX, NULL );
948 120 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_TRANSFER, NULL );
949 120 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_COLR_PRIMARIES, NULL );
950 :
951 120 : ctx->process = ffdec_process_video;
952 : //for some streams, we don't have w/h/pixfmt after opening the decoder
953 : //to make sure we are not confusing potential filters expecting them, init to default values
954 120 : if (ctx->decoder->pix_fmt>=0) {
955 19 : ctx->o_ff_pfmt = ctx->decoder->pix_fmt;
956 19 : pix_fmt = ffmpeg_pixfmt_to_gpac(ctx->decoder->pix_fmt);
957 19 : if (!pix_fmt) {
958 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[FFDec] Unsupported pixel format %d, defaulting to RGB\n", ctx->decoder->pix_fmt));
959 : pix_fmt = GF_PIXEL_RGB;
960 0 : ctx->o_ff_pfmt = AV_PIX_FMT_RGB24;
961 : }
962 : } else {
963 : pix_fmt = GF_PIXEL_YUV;
964 101 : ctx->o_ff_pfmt = AV_PIX_FMT_YUV420P;
965 : }
966 120 : ffdec_check_pix_fmt_change(ctx, pix_fmt);
967 :
968 120 : if (ctx->decoder->width) {
969 120 : FF_CHECK_PROP(width, width, GF_PROP_PID_WIDTH)
970 : } else {
971 0 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_WIDTH, &PROP_UINT( ctx->width) );
972 : }
973 120 : if (ctx->decoder->height) {
974 120 : FF_CHECK_PROP(height, height, GF_PROP_PID_HEIGHT)
975 : } else {
976 0 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_HEIGHT, &PROP_UINT( ctx->height) );
977 : }
978 120 : if (ctx->decoder->sample_aspect_ratio.num && ctx->decoder->sample_aspect_ratio.den) {
979 4 : ctx->sar.num = ctx->decoder->sample_aspect_ratio.num;
980 4 : ctx->sar.den = ctx->decoder->sample_aspect_ratio.den;
981 4 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_SAR, &PROP_FRAC( ctx->sar) );
982 : }
983 120 : if (!ctx->frame)
984 110 : ctx->frame = av_frame_alloc();
985 :
986 120 : if (ctx->pixel_fmt) {
987 120 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_PIXFMT, &PROP_UINT( ctx->pixel_fmt) );
988 : }
989 :
990 31 : } else if (type==GF_STREAM_AUDIO) {
991 31 : ctx->process = ffdec_process_audio;
992 31 : if (ctx->decoder->sample_fmt != AV_SAMPLE_FMT_NONE) {
993 31 : ctx->sample_fmt = ffmpeg_audio_fmt_to_gpac(ctx->decoder->sample_fmt);
994 31 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_AUDIO_FORMAT, &PROP_UINT(ctx->sample_fmt) );
995 31 : ctx->bytes_per_sample = gf_audio_fmt_bit_depth(ctx->sample_fmt) / 8;
996 : }
997 :
998 : //override PID props with what decoder gives us
999 31 : if (ctx->decoder->channels) {
1000 31 : ctx->channels = 0;
1001 31 : FF_CHECK_PROP(channels, channels, GF_PROP_PID_NUM_CHANNELS)
1002 : }
1003 31 : if (ctx->decoder->channel_layout) {
1004 28 : u64 ch_lay = ffmpeg_channel_layout_to_gpac(ctx->decoder->channel_layout);
1005 28 : if (ctx->channel_layout != ch_lay) {
1006 28 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_CHANNEL_LAYOUT, &PROP_LONGUINT(ch_lay ) );
1007 28 : ctx->channel_layout = ch_lay;
1008 : }
1009 : }
1010 31 : if (ctx->decoder->sample_rate) {
1011 31 : ctx->sample_rate = 0;
1012 31 : FF_CHECK_PROP(sample_rate, sample_rate, GF_PROP_PID_SAMPLE_RATE)
1013 : }
1014 31 : if (!ctx->frame)
1015 31 : ctx->frame = av_frame_alloc();
1016 :
1017 31 : if (ctx->sample_fmt) {
1018 31 : gf_filter_pid_set_property(ctx->out_pid, GF_PROP_PID_AUDIO_FORMAT, &PROP_UINT( ctx->sample_fmt) );
1019 : }
1020 :
1021 31 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_NO_PRIMING);
1022 31 : if (prop && prop->value.boolean) {
1023 0 : ctx->delay = 0;
1024 : } else {
1025 31 : prop = gf_filter_pid_get_property(pid, GF_PROP_PID_DELAY);
1026 31 : ctx->delay = prop ? prop->value.longsint : 0;
1027 31 : ctx->first_cts_plus_one = 0;
1028 :
1029 31 : if (ctx->delay<0)
1030 0 : ctx->ts_offset = (u32) -ctx->delay;
1031 : else
1032 31 : ctx->ts_offset = 0;
1033 : }
1034 :
1035 : } else {
1036 : #ifdef FF_SUB_SUPPORT
1037 : ctx->process = ffdec_process_subtitle;
1038 : #endif
1039 : }
1040 : return GF_OK;
1041 : }
1042 :
1043 :
1044 60 : static GF_Err ffdec_update_arg(GF_Filter *filter, const char *arg_name, const GF_PropertyValue *arg_val)
1045 : {
1046 : s32 res;
1047 60 : GF_FFDecodeCtx *ctx = gf_filter_get_udta(filter);
1048 :
1049 : //initial parsing of arguments
1050 60 : if (!ctx->initialized) {
1051 60 : switch (arg_val->type) {
1052 60 : case GF_PROP_STRING:
1053 60 : res = av_dict_set(&ctx->options, arg_name, arg_val->value.string, 0);
1054 60 : if (res<0) {
1055 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] Failed to set option %s:%s\n", arg_name, arg_val ));
1056 : }
1057 : break;
1058 0 : default:
1059 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FFDec] Failed to set option %s:%s, unrecognized type %d\n", arg_name, arg_val, arg_val->type ));
1060 : return GF_NOT_SUPPORTED;
1061 : }
1062 : return GF_OK;
1063 : }
1064 : //updates of arguments, not supported for ffmpeg decoders
1065 : return GF_NOT_SUPPORTED;
1066 : }
1067 :
1068 3552 : static Bool ffdec_process_event(GF_Filter *filter, const GF_FilterEvent *evt)
1069 : {
1070 3552 : GF_FFDecodeCtx *ctx = (GF_FFDecodeCtx *) gf_filter_get_udta(filter);
1071 :
1072 3552 : if ((evt->base.type==GF_FEVT_PLAY) || (evt->base.type==GF_FEVT_SET_SPEED) || (evt->base.type==GF_FEVT_RESUME)) {
1073 162 : ctx->drop_non_refs = evt->play.drop_non_ref;
1074 : }
1075 : //play request, detach all pending source packets and trigger a reconfig to start from a clean state
1076 3390 : else if (evt->base.type==GF_FEVT_STOP) {
1077 100 : while (gf_list_count(ctx->src_packets)) {
1078 48 : GF_FilterPacket *pck = gf_list_pop_back(ctx->src_packets);
1079 48 : gf_filter_pck_unref(pck);
1080 : //for video, this will reset the decoder
1081 48 : ctx->flush_done = GF_TRUE;
1082 : }
1083 : }
1084 :
1085 3552 : return GF_FALSE;
1086 : }
1087 :
1088 : static const GF_FilterCapability FFDecodeCaps[] =
1089 : {
1090 : CAP_UINT(GF_CAPS_INPUT_OUTPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_VISUAL),
1091 : CAP_BOOL(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
1092 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_RAW),
1093 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_NONE),
1094 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_SVC),
1095 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_LHVC),
1096 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_HEVC_TILES),
1097 : CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_CODECID, GF_CODECID_RAW),
1098 : CAP_BOOL(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_TILE_BASE, GF_TRUE),
1099 : { .code=GF_PROP_PID_SCALABLE, .val={.type=GF_PROP_BOOL, .value.boolean = GF_TRUE}, .flags=(GF_CAPS_INPUT_OPT), .priority=255 },
1100 : {0},
1101 : CAP_UINT(GF_CAPS_INPUT_OUTPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_AUDIO),
1102 : CAP_BOOL(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
1103 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_NONE),
1104 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_RAW),
1105 : CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_CODECID, GF_CODECID_RAW),
1106 :
1107 : #ifdef FF_SUB_SUPPORT
1108 : {0},
1109 : CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_STREAM_TYPE, GF_STREAM_TEXT),
1110 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_TEXT_MPEG4),
1111 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_TX3G),
1112 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_WEBVTT),
1113 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_SUBS_XML),
1114 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_SIMPLE_TEXT),
1115 : CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_TEXT),
1116 : CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_CODECID, GF_CODECID_RAW),
1117 : #endif
1118 :
1119 : };
1120 :
1121 : GF_FilterRegister FFDecodeRegister = {
1122 : .name = "ffdec",
1123 : .version = LIBAVCODEC_IDENT,
1124 : GF_FS_SET_DESCRIPTION("FFMPEG decoder")
1125 : GF_FS_SET_HELP("Decodes audio and video streams.\n"
1126 : "See FFMPEG documentation (https://ffmpeg.org/documentation.html) for more details.\n"
1127 : "To list all supported decoders for your GPAC build, use `gpac -h ffdec:*`.\n"
1128 : "\n"
1129 : "Options can be passed from prompt using `-+OPT=VAL`\n"
1130 : "The default threading mode is to let libavcodec decide how many threads to use. To enforce single thread, use `-+threads=1`\n"
1131 : )
1132 : .private_size = sizeof(GF_FFDecodeCtx),
1133 : SETCAPS(FFDecodeCaps),
1134 : .initialize = ffdec_initialize,
1135 : .finalize = ffdec_finalize,
1136 : .configure_pid = ffdec_configure_pid,
1137 : .process = ffdec_process,
1138 : .update_arg = ffdec_update_arg,
1139 : .process_event = ffdec_process_event,
1140 : .flags = GF_FS_REG_META,
1141 : //use middle priorty, so that hardware decs/other native impl in gpac can take over if needed
1142 : //don't use lowest one since we use this for scalable codecs
1143 : .priority = 128
1144 :
1145 : };
1146 :
1147 :
1148 : static const GF_FilterArgs FFDecodeArgs[] =
1149 : {
1150 : { "*", -1, "any possible options defined for AVCodecContext and sub-classes. See `gpac -hx ffdec` and `gpac -hx ffdec:*`", GF_PROP_STRING, NULL, NULL, GF_FS_ARG_META},
1151 : {0}
1152 : };
1153 :
1154 2877 : const GF_FilterRegister *ffdec_register(GF_FilterSession *session)
1155 : {
1156 2877 : ffmpeg_build_register(session, &FFDecodeRegister, FFDecodeArgs, 1, FF_REG_TYPE_DECODE);
1157 2877 : return &FFDecodeRegister;
1158 : }
1159 :
1160 : #else
1161 : #include <gpac/filters.h>
1162 : const GF_FilterRegister *ffdec_register(GF_FilterSession *session)
1163 : {
1164 : return NULL;
1165 : }
1166 : #endif
1167 :
|