175 enum AVPixelFormat pixFmts[] = { pixFmt, AV_PIX_FMT_NONE };
177#if LIBAVFILTER_BUILD >= AV_VERSION_INT(10, 6, 100)
179 AV_OPT_SEARCH_CHILDREN, 0,
sizeof(pixFmts) /
sizeof(pixFmts[0]) - 1, AV_OPT_TYPE_PIXEL_FMT, pixFmts);
182 pixFmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
186 LOGFATAL(
"filter thread: %s: Cannot set output pixel format (%d)", __FUNCTION__, ret);
200 const char *filterDescr = NULL;
203 LOGFATAL(
"filter thread: %s: Cannot alloc filter graph", __FUNCTION__);
208 const AVFilter *buffersrc = avfilter_get_by_name(
"buffer");
209 const AVFilter *buffersink = avfilter_get_by_name(
"buffersink");
211#if LIBAVFILTER_VERSION_INT < AV_VERSION_INT(7,16,100)
212 avfilter_register_all();
219 if (enableDeinterlacer) {
220 if (frame->format == AV_PIX_FMT_DRM_PRIME) {
221 filterDescr =
"deinterlace_v4l2m2m";
222 }
else if (frame->format == AV_PIX_FMT_YUV420P) {
223 filterDescr =
"bwdif=1:-1:0";
226 }
else if (frame->format == AV_PIX_FMT_YUV420P) {
227 filterDescr =
"scale";
229 LOGFATAL(
"filter thread: %s: Unexpected pixel format: %d", __FUNCTION__, frame->format);
233 LOGFATAL(
"filter thread: %s: Cannot create buffer sink", __FUNCTION__);
238 AVRational sar = videoCtx->sample_aspect_ratio;
239 if (videoCtx->sample_aspect_ratio.num == 0 && videoCtx->height == 576) {
240 sar = (AVRational){64, 45};
241 LOGDEBUG2(
L_CODEC,
"filter thread: %s: Observed 576i material with a sar 0/1, stretch it with sar %d/%d", __FUNCTION__, sar.num, sar.den);
244 if (frame->format == AV_PIX_FMT_DRM_PRIME) {
249 LOGFATAL(
"filter thread: %s: Cannot create buffer src", __FUNCTION__);
251 AVBufferSrcParameters *par = av_buffersrc_parameters_alloc();
252 memset(par, 0,
sizeof(*par));
254 par->format = AV_PIX_FMT_DRM_PRIME;
255 par->hw_frames_ctx = frame->hw_frames_ctx;
256 par->time_base = videoCtx->pkt_timebase;
257 par->width = videoCtx->width;
258 par->height = videoCtx->height;
259 par->sample_aspect_ratio = sar;
261 LOGDEBUG2(
L_CODEC,
"filter thread: %s: filter=\"%s\" fmt %d, hw ctx %p, tb %d/%d, wxh %dx%d, sar %d/%d",
262 __FUNCTION__, filterDescr,
263 par->format, par->hw_frames_ctx, par->time_base.num, par->time_base.den,
264 par->width, par->height, par->sample_aspect_ratio.num, par->sample_aspect_ratio.den);
268 LOGFATAL(
"filter thread: %s: Cannot av_buffersrc_parameters_set (%d)", __FUNCTION__, ret);
274 LOGFATAL(
"filter thread: %s: Cannot initialize buffer src (%d)", __FUNCTION__, ret);
278 snprintf(args,
sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
279 videoCtx->width, videoCtx->height, frame->format,
280 videoCtx->pkt_timebase.num ? videoCtx->pkt_timebase.num : 1,
281 videoCtx->pkt_timebase.num ? videoCtx->pkt_timebase.den : 1,
284 LOGDEBUG2(
L_CODEC,
"filter thread: %s: filter=\"%s\" args=\"%s\"", __FUNCTION__, filterDescr, args);
288 LOGFATAL(
"filter thread: %s: Cannot create buffer src", __FUNCTION__);
293 LOGFATAL(
"filter thread: %s: Cannot initialize buffer sink (%d)", __FUNCTION__, ret);
295 AVFilterInOut *outputs = avfilter_inout_alloc();
296 AVFilterInOut *inputs = avfilter_inout_alloc();
298 outputs->name = av_strdup(
"in");
300 outputs->pad_idx = 0;
301 outputs->next = NULL;
303 inputs->name = av_strdup(
"out");
308 ret = avfilter_graph_parse_ptr(
m_pFilterGraph, filterDescr, &inputs, &outputs, NULL);
310 LOGFATAL(
"filter thread: %s: avfilter_graph_parse_ptr failed (%d)", __FUNCTION__, ret);
313 avfilter_inout_free(&inputs);
314 avfilter_inout_free(&outputs);
318 LOGFATAL(
"filter thread: %s: avfilter_graph_config failed (%d)", __FUNCTION__, ret);
325 LOGDEBUG(
"threads: video filter thread started");
341 if ((ret = av_buffersrc_add_frame_flags(
m_pBuffersrcCtx, frame, AV_BUFFERSRC_FLAG_KEEP_REF)) < 0)
342 LOGWARNING(
"filter thread: %s: can't add_frame: %s", __FUNCTION__, av_err2str(ret));
344 av_frame_free(&frame);
348 AVFrame *filtFrame = av_frame_alloc();
350 LOGFATAL(
"filter thread: %s: can't allocate frame", __FUNCTION__);
354 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
355 av_frame_free(&filtFrame);
357 }
else if (ret < 0) {
358 LOGERROR(
"filter thread: %s: can't get filtered frame: %s", __FUNCTION__, av_err2str(ret));
359 av_frame_free(&filtFrame);
367 if (filtFrame->format == AV_PIX_FMT_NV12 &&
m_filterBug)
372 av_frame_free(&filtFrame);
375 LOGDEBUG(
"threads: filter thread stopped");