Hi everybody,
i am new to kdenlive and i will furthermore use it in future in my workflow.
After i completed my first test project i noticed after a while that there is something wrong with my final clip.
If there is heavy motion, the video begins "pumping/pulsing". If i set the deinterlace filter to a simpler method like "Linear" e.g. in VLC so i can see the "pulsing" very extreme. It seems that bottom- and topfields are interchanged? Better filters are coating the problem (e.g. Yadif).
My source is a h264 1080i50 m2ts file from Panasonic SD707 (Europe).
part of mediainfo -f output:
Frame rate : 25.000
Frame rate : 25.000 fps
Frame count : 993
Scan type : Interlaced
Scan order : TFF
Scan order : Top Field First
Interlacement : TFF
Interlacement : Top Field First
If i watch this file direct in VLC, there is no problem.
For a better performance, i do a transcode to DNxHD 1080i50 185MBit (from the presets).
If i watch the resulting .mov file in VLC, i can see the same problem still prior to the kdenlive workflow. I guess something goes wrong by the transcode step.
Part of mediainfo -f output from the DNxHD .mov file:
Frame rate mode : CFR
Frame rate mode : Constant
Frame rate : 25.000
Frame rate : 25.000 fps
Frame count : 994
The output shows nothing about scan type or order.
I'm sure it makes no sense to go ahead with this material.
Any idea?
Greetings from Munich,
Christian
System-Info: OpenSuse 11.3 64Bit. kdenlive 0.7.7.1 (all from packman repo...)
Can't find much info on the 707 only the 700. But did you shoot in interlaced mode or progressive? And at 25 or 50 fps. Putting aside what mediainfo says.
For example I have a Canon HV30 and 550D. The HV30 shoots progressive but in two interlaced streams, called psf25. Progressive Segmented Frames, yet mediainfo and such suggest it's interlaced because of the 'i' container those two duplicate streams are in. Maybe your video is progressive?
Trying to deinterlace progressive video will cause problems, so would putting a progressive shot in a interlaced kdenlive project I'd imagine.
Ok, so maybe it's a problem with the h264 encoding profile in kdenlive for an interlaced project?
re encoding profiles, I'm new to kdenlive and don't have it in front of me, so I can't really help you. :-(
This is rather confusing to follow and be able to comment on. It seems as though you want interlaced output for whatever reason. OK. MLT does automatic field order detection and normalization (when not progressive profile/output) into bottom-field-first due to some DV and SDI lineage for the original sponsor of the project and, as a result, because some filters do field-based rendering with that assumption.
I can not explain why the MP4 and MPEG-2 outputs have opposite field orders. That is surprising. Is that because only MPEG-2 format has a flag for field order? (I need to look that up.)
MLT automatically adds the ilme and idct libavcodec flags when your profile/output is not progressive.
So, it seems that Kdenlive's DNxHD transcode profiles need revision to add '-top -1'.
Contrary to the docs, I checked the code to see if DNxHD supports interlaced prior to adding those transcode profiles, and it does.
Already I have somewhat high on the MLT ToDo list a top-field-first output (but this inconsistent result with MP4 and MPEG-2 makes me concerned that it will help much).
Finally, Scanning = Auto means to use what the Project setting indicates. The stuff in the Render dialog for scanning and resolution overrides what you have in the Project settings in case you need that for certain outputs.
I had the same problems, interlaced input can be uses very well and all seems fine.
encoding to mpeg4/mpeg2 works also fine.
but encoding to x264 will always fail if you have top field first.
i made a patch for ffmpeg, to set this to TFF. i did not find a place, to take this automatic but it solves first the problems for TFF video.
in libavcodec/libx264.c put after
x4->params.b_interlaced = avctx->flags & CODEC_FLAG_INTERLACED_DCT;
this line (tff is true, but must be set to 0, maybe field order changed in mlt ??? )
x4->params.b_tff =0;
then encoded x264 video play correct (interlaced and field order ) and with 50 fps (very clean picture)
Reached download limit. :-(
Re: How works kdenlive, MLT, ffmpeg together in detail? Especially MLT and ffmpeg?
You have to read the sources; it's very complicated.
Re: How does (field order) normalization work?
Simple: if input field order and requested field order are different, move the image up or down by one line since the fields are stored together in one image. The only loss is one line of resolution. I know this works not only in theory but also because I have used MLT with SDI output and analog converter connected to an analog monitor - both NTSC and PAL. I have directly seen the ill result of incorrect field order as well as the positive result of a simple line shift. Meanwhile, MLT does use the top_field_first flag from libavcodec (there is an override not yet exposed in kdenlive). It uses it both on input and sets it when encoding (should always be to zero now due to BFF-only). But of course, it is possible that a regression was introduced.
Also, if you do anything that must scale the image in the vertical direction, MLT will automatically deinterlace because it does not have a field-aware scaler. So, a 1080i source output to DVD will cause a deinterlace before any attempt at field-order normalization. Then, the deinterlace sets the frame scanning attribute to progressive thereby preventing field-order normalization. However, I am seeing that the YADIF deinterlacer takes as inputs both a parity and a top-field-first parameter. I do not recall what parity is for, but it is related to field order, and it always set 0 currently. Hmmm, that could be a problem. Reviewing the Avisynth plugin source, that should be (tff ^ 1).
Are you causing any scaling? Are you building MLT yourself such that you can test a change?
@lxvidcut
I search also long for this option, to put this from outside to libx264.
since this option is relative new in libx264, it must be set with the code from ffmpeg (libx264.c). But as you see no line of code will set this value.
The default setting is b_tff=1. when mlt converts tff to bff (which is not a problem, if known) libx264 will render this as b_tff=1 (with the stucking video)
if ffmpeg has a option for this, is could be set from kdenlive direct. But until then there is no way for x624 files to set this (unless you patch this from hand).
mlt/ffmpeg have no problems setting this in other formats (where it works correct).
I wrote:
> However, I am seeing that the YADIF deinterlacer takes as inputs both
> a parity and a top-field-first parameter. I do not recall what parity
> is for, but it is related to field order, and it always set 0 currently.
> Hmmm, that could be a problem. Reviewing the Avisynth plugin source,
> that should be (tff ^ 1).
I just realized that for lxvidcut's clip, which is tff, that the parity parameter would evaluate to 0. So, this would not be a source of the problem.
I did some testing with a BFF DV file that stresses interlace by bouncing a basketball in front of a checkerboard-like background. When I use (parity = tff ^ 1) the results are much worse! So, I am not confident to make that change. Maybe there is some additional special context required when it should be used.
Then, I located a TFF file to do some testing. I quickly discovered a bug in the ffmpeg plugin's image caching (caching is important for yadif, which needs to process previous and next frames for each frame). It was not properly propagating the TFF flag. There could be circumstances outside of yadif-deinterlace where it hits the cache. But this TFF clip is not good for testing the yadif deinterlacer.
Next, I wanted to see if the parity logic was somehow inverted. So, I manually converted the bouncing ball video into a TFF video to test yadif with parity=0 vs 1. (I did this by overriding the detected field order thereby kicking on the field order corrector, and verifying these activities occurring by adding some log messages.) The results with tff=1 & parity=0 are way better than parity=1.
I committed a change to MLT git to fix the field order signaling when returning cached images. However, I have no real way of knowing at this time if that is the problem you are seeing.
lxvidcut, I went into a lot of detail making notes while I was analyzing and testing. It does look x264 or its integration could be the problem. I found that playing in VLC with the Bob deinterlace mode is a good way to perceive field order problems. However, in a straight transcode scenario (TFF source -> no scaling/deinterlace -> MP4), I could not reproduce a problem with H.264 output here using ffmpeg 0.6 and x264 build 85.
Re: "could you explain the used method a little bit preciser on an example?"
// Get the input image, width and height
int size = owidth * oheight * bpp;
int8_t *ptr = image + owidth * bpp;
memmove( ptr, image, size - owidth * bpp );
Re: "is this method the cause of the 1 pix high green line at the bottom of my final clips?"
No
I just some testing and analysis of your files. Both t0.mkv and t1.mkv both indicate TFF, and that should not be the case since MLT is BFF only. When I render your original_t1.m2ts.mov to mpeg4 instead of x264, then the result correctly shows BFF. I am determining the _indicated_ field order by adding a printf in MLT based on the info in the libavcodec api after decoding (when it is reliable to get it). Indicating TFF when it is not is obviously going to look wrong, and it looks like g.marco's info was spot on.
The problem with patching ffmpeg is that it looks like this flag must be passed to x264 on initialization, but ffmpeg does not know until encoding a frame because it has top_field_first as an attribute on the frame.
like in other encodings in ffmpeg/libavocdec the top_field_first must be set during frame encoding.
static int X264_frame would be the right place (since per definiton, every frame could have a own field order)
patch (since top_field_first ist negated in ffmpeg i set the ! ):
--- ffmpeg-0.6/libavcodec/libx264.c 2010-04-19 23:20:20.000000000 +0200
+++ ffmpeg-0.6-new/libavcodec/libx264.c 2010-09-04 17:28:38.000000000 +0200
@@ -100,6 +100,8 @@
x4->pic.i_pts = frame->pts;
x4->pic.i_type = X264_TYPE_AUTO;
+
+ x4->params.b_tff = !frame->top_field_first;
}
if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
i think this would be an solution, that work then for every type of field order.
g.marco, did you test that? The reason I did not think that will work is because no other x264 params are set in X264_frame(); params is only used in X264_init().
after many search and test i found:
the param b_tff can not be set with a function later.
but the instance x4 hat the param values for the frames.
set
x4->params.b_tff = !frame->top_field_first;
should work. but with some debug i found, that frame_top_field_first ist every time "1" no matter what is changed in mlt (i changed top_field_first for the producer and for the avformat consumer). The effect was: ffmpeg will get alway top_field_first as "1".
so i could not the further if this change in ffmpeg will work.
@dan
is changing the top_field_first value ov consumer the right way to set this ?
--edit:
setting the param during encode can be don with setting x4->pic.param for a frame.
but change b_tff to !top_field_first or top_field_first will no set the field flag.
it will only make a difference during encoding teh interlaced frame. must this be set to the header only, or both ?
if (frame) {
for (i = 0; i < 3; i++) {
x4->pic.img.plane[i] = frame->data[i];
x4->pic.img.i_stride[i] = frame->linesize[i];
}
x4->pic.i_pts = frame->pts;
x4->pic.i_type = X264_TYPE_AUTO;
if (x4->params.b_tff == frame->top_field_first) {
x4->params.b_tff = !frame->top_field_first;
}
}
x4->pic.param=&x4->params;
consumer_avformat.c: sets frame->top_field_first:
1354: output->top_field_first = mlt_properties_get_int( frame_properties, "top_field_first" );
I have no idea how you get that frame property to be 1. It is not supposed to be possible at this time, and some quick testing shows it always 0 here. Furthermore, we have seen that value respected in mpeg4 and mpeg2 output. So, I do not know how that gets set 1 by the time libavcodec/libx264 gets it.
after search during the code i found:
1. x264 does not allow to change the field order after init.
2. ffmpeg cannot ( because of 1.) change the field order
patching these two libs will let it work.
tested with tff video (that will be bff after melt usage) and it play perfect.
| Attachment | Size |
|---|---|
| x264_copy_b_tff.patch | 496 bytes |
| ffmpeg_x264_b_tff.patch | 569 bytes |
yes the way for ffmpeg seems ok, if you want to have a patched ffmpeg on your system.
for x264 you need to do the same, but with latest x264 the .so version may be change, so all your program/libs that are linked against the "old" x264 are broken.
i wrote to the x264 list with that patch, if this is commited i'll write to ffmpeg to get the change there too.
if you don't want to change x264 too, simple but the x4->params.b_tff=0 to the init method in ffmpeg (but you can't encode tff video then anymore)
Hi once again,
I found a solution. If I add "-top 1" to the ffmpeg options, the video in the .mov file is now smooth.
Also "-top -1" works fine! It enables field order auto detection. "-top 0" produces the same bad output.
Without a parameter set it seems ffmpeg uses fix the bottom field first?
Furthermore I'm irritated by the mediainfo output. It says Constant Frames by 25 fps.
If I count each independent frame in VLC with activated linear deinterlacer, there are 50 frames present.
Now i think the .mov file is ok to go ahead with kdenlive.
Does anyone know about the mediainfo output from mov files?
Won't it be a good thing to add the "-top -1" parameter to all interlaced transcode profiles in the next kdenlive version?
Christian