Ticket #6391: mythtv-0.21-field-order.2.patch

File mythtv-0.21-field-order.2.patch, 9.9 KB (added by mythtv@…, 15 years ago)

Patch against vanilla 2.1 fixes (previous patch was against 2.1 fixes plus vdpau patch

  • filters/fieldorder/fieldorder.pro

    diff -Naur mythtv-0.21-20283-old/filters/fieldorder/fieldorder.pro mythtv-0.21-20283-new/filters/fieldorder/fieldorder.pro
    old new  
     1include ( ../filter-common.pro )
     2include ( ../filter-avcodec.pro )
     3
     4INCLUDEPATH += ../../libs/libmythtv ../../libs/libavcodec ../..
     5
     6# Input
     7SOURCES += filter_fieldorder.c
     8
  • filters/fieldorder/filter_fieldorder.c

    diff -Naur mythtv-0.21-20283-old/filters/fieldorder/filter_fieldorder.c mythtv-0.21-20283-new/filters/fieldorder/filter_fieldorder.c
    old new  
     1/*
     2 * Field-order deinterlacer
     3 *
     4 * Written by Paul Gardiner (mythtv@glidos.net), based on overal
     5 * structure of yadif deinterlacer.
     6 */
     7#include <stdlib.h>
     8#include <stdio.h>
     9
     10#include "config.h"
     11#ifdef HAVE_STDINT_H
     12#include <stdint.h>
     13#endif
     14#include <inttypes.h>
     15
     16#include <string.h>
     17#include <math.h>
     18
     19#include "filter.h"
     20#include "frame.h"
     21
     22#define NREFS 2
     23#define NCHANS 3
     24
     25typedef struct ThisFilter
     26{
     27    VideoFilter vf;
     28
     29    long long last_framenr;
     30
     31    uint8_t *ref[NREFS+1][NCHANS];
     32    int stride[NCHANS];
     33    int8_t got_frames[NREFS+1];
     34
     35    int width;
     36    int height;
     37
     38    TF_STRUCT;
     39} ThisFilter;
     40
     41
     42static void AllocFilter(ThisFilter* filter, int width, int height)
     43{
     44    int i,j;
     45    if ((width != filter->width) || height != filter->height)
     46    {
     47        for (i=0; i<NCHANS*NREFS; i++)
     48        {
     49            uint8_t **p= &filter->ref[i/NCHANS][i%NCHANS];
     50            if (*p) free(*p);
     51            *p= NULL;
     52        }
     53        for (i=0; i<NCHANS; i++)
     54        {
     55            int is_chroma= !!i;
     56            int w= ((width   + 31) & (~31))>>is_chroma;
     57            int h= ((height  + 31) & (~31))>>is_chroma;
     58
     59            filter->stride[i]= w;
     60            for (j=0; j<NREFS; j++)
     61            {
     62                filter->ref[j][i]= (uint8_t*)calloc(w*h*sizeof(uint8_t),1);
     63            }
     64        }
     65        filter->width = width;
     66        filter->height = height;
     67        memset(filter->got_frames, 0, sizeof(filter->got_frames));
     68    }
     69}
     70
     71static inline void * memcpy_pic(void * dst, const void * src,
     72                                int bytesPerLine, int height,
     73                                int dstStride, int srcStride)
     74{
     75    int i;
     76    void *retval=dst;
     77
     78    if (dstStride == srcStride)
     79    {
     80        if (srcStride < 0)
     81        {
     82            src = (uint8_t*)src + (height-1)*srcStride;
     83            dst = (uint8_t*)dst + (height-1)*dstStride;
     84            srcStride = -srcStride;
     85        }
     86        memcpy(dst, src, srcStride*height);
     87    }
     88    else
     89    {
     90        for (i=0; i<height; i++)
     91        {
     92            memcpy(dst, src, bytesPerLine);
     93            src = (uint8_t*)src + srcStride;
     94            dst = (uint8_t*)dst + dstStride;
     95        }
     96    }
     97
     98    return retval;
     99}
     100
     101static void store_ref(struct ThisFilter *p, uint8_t *src, int src_offsets[3], int src_stride[3], int width, int height)
     102{
     103    int i;
     104
     105    memcpy (p->ref[NREFS], p->ref[0], sizeof(uint8_t *)*NCHANS);
     106    memmove(p->ref[0], p->ref[1], sizeof(uint8_t *)*NREFS*NCHANS);
     107
     108    memcpy (&p->got_frames[NREFS], &p->got_frames[0], sizeof(uint8_t));
     109    memmove(&p->got_frames[0], &p->got_frames[1], sizeof(uint8_t) * NREFS);
     110
     111    for (i=0; i<NCHANS; i++)
     112    {
     113        int is_chroma= !!i;
     114        memcpy_pic(p->ref[NREFS-1][i], src + src_offsets[i], width>>is_chroma, height>>is_chroma, p->stride[i], src_stride[i]);
     115    }
     116    p->got_frames[NREFS-1] = 1;
     117}
     118
     119
     120
     121static void filter_func(struct ThisFilter *p, uint8_t *dst, int dst_offsets[3], int dst_stride[3], int width, int height, int parity, int tff)
     122{
     123    int y, i;
     124
     125    uint8_t nr_p, nr_c;
     126
     127    //check if we already got this frames
     128    nr_c = NREFS-1;//always there after store_ref
     129    nr_p = p->got_frames[NREFS-2]?(NREFS-2):nr_c;
     130
     131    for (i=0; i<NCHANS; i++)
     132    {
     133        int is_chroma= !!i;
     134        int w= width >>is_chroma;
     135        int h= height>>is_chroma;
     136        int refs= p->stride[i];
     137
     138        for (y=0; y<h; y++)
     139        {
     140            /* Alter only lines of the second field */
     141            if (y & tff)
     142            {
     143                if(parity)
     144                {
     145                    /* Second call: put back the second field to its previous state */
     146                    memcpy(dst + dst_offsets[i] + y*dst_stride[i], &p->ref[nr_c][i][y*refs], w);
     147                }
     148                else
     149                {
     150                    /* First call: replace second field by that of the previous frame */
     151                    memcpy(dst + dst_offsets[i] + y*dst_stride[i], &p->ref[nr_p][i][y*refs], w);
     152                }
     153            }
     154        }
     155    }
     156}
     157
     158
     159static int FieldorderDeint (VideoFilter * f, VideoFrame * frame)
     160{
     161    ThisFilter *filter = (ThisFilter *) f;
     162    TF_VARS;
     163
     164    int second_field = 0;
     165    AllocFilter(filter, frame->width, frame->height);
     166
     167    if (filter->last_framenr != frame->frameNumber)
     168    {
     169        if (filter->last_framenr != (frame->frameNumber - 1))
     170        {
     171            memset(filter->got_frames, 0, sizeof(filter->got_frames));
     172        }
     173        store_ref(filter, frame->buf,  frame->offsets, frame->pitches, frame->width, frame->height);
     174        second_field = 0;
     175    }
     176    else
     177    {
     178        second_field = 1;
     179    }
     180
     181    /* filter all frames, even if frame->interlaced_frame is not set */
     182    filter_func(
     183        filter, frame->buf, frame->offsets, frame->pitches,
     184        frame->width, frame->height, second_field, frame->top_field_first);
     185
     186    filter->last_framenr = frame->frameNumber;
     187
     188    return 0;
     189}
     190
     191
     192void CleanupFieldorderDeintFilter (VideoFilter * filter)
     193{
     194    int i;
     195    ThisFilter* f = (ThisFilter*)filter;
     196    for (i=0; i<NCHANS*NREFS; i++)
     197    {
     198        uint8_t **p= &f->ref[i/NCHANS][i%NCHANS];
     199        if (*p) free(*p);
     200        *p= NULL;
     201    }
     202}
     203
     204VideoFilter * FieldorderDeintFilter (VideoFrameType inpixfmt, VideoFrameType outpixfmt,
     205    int *width, int *height, char *options)
     206{
     207    ThisFilter *filter;
     208    (void) height;
     209    (void) options;
     210
     211    fprintf(stderr, "Initialize Fieldorder Deinterlacer. In-Pixformat = %d Out-Pixformat=%d\n", inpixfmt, outpixfmt);
     212    filter = (ThisFilter *) malloc (sizeof(ThisFilter));
     213    if (filter == NULL)
     214    {
     215        fprintf (stderr, "FieldorderDeint: failed to allocate memory for filter.\n");
     216        return NULL;
     217    }
     218
     219    filter->width = 0;
     220    filter->height = 0;
     221    memset(filter->ref, 0, sizeof(filter->ref));
     222
     223    AllocFilter(filter, *width, *height);
     224
     225    filter->vf.filter = &FieldorderDeint;
     226    filter->vf.cleanup = &CleanupFieldorderDeintFilter;
     227    return (VideoFilter *) filter;
     228}
     229
     230
     231static FmtConv FmtList[] =
     232{
     233    { FMT_YV12, FMT_YV12 } ,
     234    FMT_NULL
     235};
     236
     237FilterInfo filter_table[] =
     238{
     239    {
     240symbol:     "FieldorderDeintFilter",
     241            name:       "fieldorderdoubleprocessdeint",
     242            descript:   "avoids synchronisation problems when matching an interlaced video mode to an interlaced source",
     243            formats:    FmtList,
     244            libname:    NULL
     245    },FILT_NULL
     246};
     247
     248/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • filters/filters.pro

    diff -Naur mythtv-0.21-20283-old/filters/filters.pro mythtv-0.21-20283-new/filters/filters.pro
    old new  
    22
    33# Directories
    44SUBDIRS += invert linearblend denoise3d quickdnr kerneldeint crop force convert
    5 SUBDIRS += adjust onefield bobdeint ivtc greedyhdeint yadif
     5SUBDIRS += adjust onefield bobdeint ivtc greedyhdeint yadif fieldorder
    66
    77# This filter is currently broken, because the FFmpeg code that
    88# it depends on was moved into a seperate library (libpostproc).
  • libs/libmythtv/videodisplayprofile.cpp

    diff -Naur mythtv-0.21-20283-old/libs/libmythtv/videodisplayprofile.cpp mythtv-0.21-20283-new/libs/libmythtv/videodisplayprofile.cpp
    old new  
    673673        return QObject::tr("Bob (2x)");
    674674    else if ("onefield" == short_name)
    675675        return QObject::tr("One field");
     676    else if ("fieldorderdoubleprocessdeint" == short_name)
     677        return QObject::tr("Interlaced (2x)");
    676678    else if ("opengllinearblend" == short_name)
    677679        return QObject::tr("Linear blend (HW)");
    678680    else if ("openglkerneldeint" == short_name)
     
    12271229        "This deinterlacer uses several fields to reduce motion blur. "
    12281230        "It has increased CPU requirements.");
    12291231
     1232    QString kFieldorderMsg = QObject::tr(
     1233        "This deinterlacer avoids synchronisation problems when using an "
     1234        "interlaced display mode that exactly matches the source. "
     1235        "It has low CPU requirements.");
     1236
    12301237    if (deint == "none")
    12311238        msg = kNoneMsg;
    12321239    else if (deint == "onefield")
     
    12611268        msg = kYadifMsg;
    12621269    else if (deint == "yadifdoubleprocessdeint")
    12631270        msg = kYadifMsg + " " +  kDoubleRateMsg;
     1271    else if (deint == "fieldorderdoubleprocessdeint")
     1272        msg = kFieldorderMsg + " " +  kDoubleRateMsg;
    12641273    else
    12651274        msg = QObject::tr("'%1' has not been documented yet.").arg(deint);
    12661275
     
    14311440"greedyhdoubleprocessdeint"
    14321441"yadifdeint"
    14331442"yadifdoubleprocessdeint"
     1443"fieldorderdoubleprocessdeint"
    14341444"opengllinearblend"
    14351445"openglkerneldeint"
    14361446"openglonefield"
     
    14671477        safe_deint[*it] += "greedyhdoubleprocessdeint";
    14681478        safe_deint[*it] += "yadifdeint";
    14691479        safe_deint[*it] += "yadifdoubleprocessdeint";
     1480        safe_deint[*it] += "fieldorderdoubleprocessdeint";
    14701481        safe_deint[*it] += "none";
    14711482        safe_osd[*it]   += "softblend";
    14721483    }