yesterday found to play TS stream when there is a cross-grain, check data to find the reason is decoded out of the screen is used for interlaced scanning display, you need to reverse-interlace processing into a progressive scan display screen.
In FFmpeg, the reverse interleaving needs to use the avfilter, that is, the image filter, FFmpeg has a lot of filters, very powerful, anti-interleaving filter is yadif.
The basic filter usage flow is:
Decoded Screen--->buffer filter----> Other filters---->buffersink Filter---> Finished screen
All filters form a filter chain, the two filters must be the buffer filter and the Buffersink filter, the former function is to load the decoded screen into the filter chain, the role of the latter is to treat the picture from the filter chain read out.
Then the anti-interleaving filter chain should look like this:
Buffer Filter--->yadif Filter--->buffersink filter
Filter-related structures:
Avfiltergraph: Managing all filter Images
Avfiltercontext: Filter Context
Avfilter: Filter
Here's how to create a filter chain:
The first step is to create the Avfiltergraph
avfiltergraph *filter_graph=avfilter_graph_alloc ();
The second step is to get the filter you want to use:
Avfilter *filter_buffer=avfilter_get_by_name ("buffer");
Avfilter *filter_yadif=avfilter_get_by_name ("Yadif");
Avfilter *filter_buffersink=avfilter_get_by_name ("Buffersink");
The third step is to create the filter context, which is avfiltercontext:
int Avfilter_graph_create_filter (Avfiltercontext **filt_ctx, const avfilter *filt,
const char *name, const char *args, void *opaque,
Avfiltergraph *graph_ctx);
Parameter description: Filt_ctx is used to save the created filter context, filt is the filter, name is the filter name (should be unique in the filter chain), args is passed to the filter parameters (each filter is different, can be found in the corresponding filter code), Opaque is not used in the code, GRAPH_CTX is a filter image management pointer. Example:
Avfiltercontext *filter_buffer_ctx,*filter_yadif_ctx,*filter_buffersink_ctx;
Create buffer Filter
snprintf (args, sizeof (args),
"Video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
Dec_ctx->width, Dec_ctx->height, DEC_CTX->PIX_FMT,
Dec_ctx->time_base.num, Dec_ctx->time_base.den,
Dec_ctx->sample_aspect_ratio.num, Dec_ctx->sample_aspect_ratio.den);
Avfilter_graph_create_filter (&filter_buffer_ctx, Avfilter_get_by_name ("buffer"), "in",
Args, NULL, filter_graph);
Create a YADIF filter
Avfilter_graph_create_filter (&filter_yadif_ctx, Avfilter_get_by_name ("Yadif"), "Yadif",
"Mode=send_frame:parity=auto:deint=interlaced", NULL, Filter_graph);
Create a Buffersink filter
Enum Avpixelformat pix_fmts[] = {av_pix_fmt_yuv420p, av_pix_fmt_none};
Avfilter_graph_create_filter (&filter_buffersink_ctx, Avfilter_get_by_name ("Buffersink"), "out",
NULL, null,filter_graph);
Av_opt_set_int_list (Filter_buffersink_ctx, "Pix_fmts", Pix_fmts,
Av_pix_fmt_none, Av_opt_search_children);
Fourth step, connect the filter
Avfilter_link (filter_buffer_ctx, 0, filter_yadif_ctx, 0);
Avfilter_link (filter_yadif_ctx, 0, filter_buffersink_ctx, 0);
Fifth step, check that all configurations are correct:
if (ret = Avfilter_graph_config (player->filter_graph, NULL)) < 0) {
LOGE (0, "avfilter_graph_config:%d\n", ret);
Goto end;
}
Note that all of the above functions should check the return value, which is a bit of a write-down, and the filter chain is created if there is no error.
How to filter using a filter chain, mainly using two functions:
Pushes the decoded frame to the filter chain
int Av_buffersrc_add_frame_flags (Avfiltercontext *buffer_src,
Avframe *frame, int flags);
Pull out the processed frame:
int Av_buffersink_get_frame (Avfiltercontext *ctx, Avframe *frame);
For example:
Av_buffersrc_add_frame_flags (Filter_buffer_ctx, Orgin_frame, av_buffersrc_flag_keep_ref);
while (1) {
ret = Av_buffersink_get_frame (filter_buffersink_ctx, frame);
if (ret = = Averror (eagain) | | ret = = averror_eof) {
Break
}
Display (frame);
};
Image contrast before and after anti-interlacing:
Although it is rather vague, the transverse lines are indeed removed.
Ffmeg using YADIF to do the reverse interleaving