[FFmpeg-devel] [PATCH] add top video filter
Mark Himsley
mark at mdsh.com
Tue Mar 29 19:51:38 CEST 2011
On 29/03/11 17:50, Stefano Sabatini wrote:
> On date Monday 2011-03-28 14:47:20 +0100, Mark Himsley encoded:
>> Dear developers,
>>
>> Converting to and from interlaced PAL DV files, with their
>> bottom-field-first interlace field order, can be a pain. Converting
>> tff files to DV results in tff DV files, which are hard to work with
>> in editing software.
>>
>> The attached filter can:
>>
>> Convert field order by either moving all of the lines in the picture
>> up by 1 line (bff to tff conversion) or down by 1 line (tff to bff
>> conversion). The remaining line, the bottom line in bff to tff
>> transforms or the top line in tff to bff transforms, is filled by
>> copying the closest line in that field.
>>
>> Previous to this filter I have used a filter chain like this to do
>> bff to tff conversion.
>>
>> format=yuv422p,crop=720:575:0:1,pad=720:576:0:0:black
>>
>> but that chain does not fill the remaining line.
Thanks for the feedback Stefano. I shall make some changes and resend soon.
[...]
>> + for (plane = 0; plane< 4&& outpic->data[plane]; plane++) {
>> + cpy_dst = outpic->data[plane] + y * outpic->linesize[plane];
>> + if (top->dst_tff) {
>> + for (i = 0; i< h; i++) {
>> + if (1 + y + i< outpic->video->h) {
>> + memcpy(cpy_dst, cpy_dst + outpic->linesize[plane], outpic->linesize[plane]);
>
> You're copying more than it is required, outpic->linesize[plane] -> line_step[plane] * w;
>
>> + } else {
>> + memcpy(cpy_dst, cpy_dst - 2 * outpic->linesize[plane], outpic->linesize[plane]);
>> + }
>
> If I'm correct this is copy the line which is tow lines up the current
> one, that is:
> ...
> line N-2
> line N-1
> line N-2
>
> Can you confirm this is the standard behavior? (also it should be
> possibly documented).
In this instance (the move up to convert bff to tff) every line is moved
up one. That means the top line is lost and the bottom line is unchanged.
For an interlaced picture that would mean the bottom line of both fields
is the same - which is wrong in the time domain.
So, in this instance, I copy the the penultimate line in the bottom
field into the last line in the bottom field (which is also the last
line of the frame) so that at least the data is from the right point in
time.
I think I document that behavior in the docs, but I'll add a note to the
source too.
>> + cpy_dst += outpic->linesize[plane];
>> + }
>> + } else {
>> + cpy_dst += (h -1) * outpic->linesize[plane];
>> + for (i = h -1; i>= 0 ; i--) {
>> + if ( y + i> 0) {
>> + memcpy( cpy_dst, cpy_dst - outpic->linesize[plane], outpic->linesize[plane] );
>> + } else {
>> + memcpy( cpy_dst, cpy_dst + 2 * outpic->linesize[plane], outpic->linesize[plane] );
>> + }
>> + cpy_dst -= outpic->linesize[plane];
>> + }
>> + }
>> + }
>
>> + } else {
>
>> + av_log(ctx, AV_LOG_DEBUG,
>> + "field order already correct\n");
>
> av_dlog()
>
>> + }
>> + }
>> +
>> + avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir);
>> +}
>
> Is top->line_step() used?
Apparently not. I obviously forgot it completely when code was refactored.
--
Mark
More information about the ffmpeg-devel
mailing list