Statistics
| Branch: | Revision:

ffmpeg / libavfilter / libmpcodecs / vf_dint.c @ e4852fb3

History | View | Annotate | Download (7 KB)

1
/*
2
 * This file is part of MPlayer.
3
 *
4
 * MPlayer is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 2 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * MPlayer is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License along
15
 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
 */
18

    
19
#include <stdio.h>
20
#include <stdlib.h>
21
#include <string.h>
22
#include <inttypes.h>
23

    
24
#include "config.h"
25
#include "mp_msg.h"
26

    
27
#include "mp_image.h"
28
#include "img_format.h"
29
#include "vf.h"
30

    
31
struct vf_priv_s {
32
  float sense; // first parameter
33
  float level; // second parameter
34
  unsigned int imgfmt;
35
  char diff;
36
  uint32_t max;
37
//  int dfr;
38
//  int rdfr;
39
  int was_dint;
40
  mp_image_t *pmpi; // previous mpi
41
};
42

    
43
#define MAXROWSIZE 1200
44

    
45
static int config (struct vf_instance *vf,
46
        int width, int height, int d_width, int d_height,
47
        unsigned int flags, unsigned int outfmt)
48
{
49
    int rowsize;
50

    
51
    vf->priv->pmpi = vf_get_image (vf->next, outfmt, MP_IMGTYPE_TEMP,
52
                                   0, width, height);
53
    if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
54
        outfmt != IMGFMT_RGB32 && outfmt != IMGFMT_BGR32 &&
55
        outfmt != IMGFMT_RGB24 && outfmt != IMGFMT_BGR24 &&
56
        outfmt != IMGFMT_RGB16 && outfmt != IMGFMT_BGR16)
57
    {
58
      mp_msg (MSGT_VFILTER, MSGL_WARN, "Drop-interlaced filter doesn't support this outfmt :(\n");
59
      return 0;
60
    }
61
    vf->priv->imgfmt = outfmt;
62
    // recalculate internal values
63
    rowsize = vf->priv->pmpi->width;
64
    if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE;
65
    vf->priv->max = vf->priv->level * vf->priv->pmpi->height * rowsize / 2;
66
    if (vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) // planar YUV
67
      vf->priv->diff = vf->priv->sense * 256;
68
    else
69
      vf->priv->diff = vf->priv->sense * (1 << (vf->priv->pmpi->bpp/3));
70
    if (vf->priv->diff < 0) vf->priv->diff = 0;
71
    if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
72
        vf->priv->pmpi->bpp < 24 && vf->priv->diff > 31)
73
      vf->priv->diff = 31;
74
    mp_msg (MSGT_VFILTER, MSGL_INFO, "Drop-interlaced: %dx%d diff %d / level %u\n",
75
           vf->priv->pmpi->width, vf->priv->pmpi->height,
76
           (int)vf->priv->diff, (unsigned int)vf->priv->max);
77
//    vf->priv->rdfr = vf->priv->dfr = 0;
78
    vf->priv->was_dint = 0;
79
    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
80
}
81

    
82
static int put_image (struct vf_instance *vf, mp_image_t *mpi, double pts)
83
{
84
    char rrow0[MAXROWSIZE];
85
    char rrow1[MAXROWSIZE];
86
    char rrow2[MAXROWSIZE];
87
    char *row0 = rrow0, *row1 = rrow1, *row2 = rrow2/*, *row3 = rrow3*/;
88
    int rowsize = mpi->width;
89
    uint32_t nok = 0, max = vf->priv->max;
90
    int diff = vf->priv->diff;
91
    int i, j;
92
    register int n1, n2;
93
    unsigned char *cur0, *prv0;
94
    register unsigned char *cur, *prv;
95

    
96
    if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE;
97
    // check if nothing to do
98
    if (mpi->imgfmt == vf->priv->imgfmt)
99
    {
100
      cur0 = mpi->planes[0] + mpi->stride[0];
101
      prv0 = mpi->planes[0];
102
      for (j = 1; j < mpi->height && nok <= max; j++)
103
      {
104
        cur = cur0;
105
        prv = prv0;
106
        // analyse row (row0)
107
        if (mpi->flags & MP_IMGFLAG_PLANAR) // planar YUV - check luminance
108
          for (i = 0; i < rowsize; i++)
109
          {
110
            if (cur[0] - prv[0] > diff)
111
              row0[i] = 1;
112
            else if (cur[0] - prv[0] < -diff)
113
              row0[i] = -1;
114
            else
115
              row0[i] = 0;
116
            cur++;
117
            prv++;
118
            // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
119
            // but row3 is 1 so it's interlaced ptr (nok++)
120
            if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
121
                (++nok) > max)
122
              break;
123
          }
124
        else if (mpi->bpp < 24) // RGB/BGR 16 - check all colors
125
          for (i = 0; i < rowsize; i++)
126
          {
127
            n1 = cur[0] + (cur[1]<<8);
128
            n2 = prv[0] + (prv[1]<<8);
129
            if ((n1&0x1f) - (n2&0x1f) > diff ||
130
                ((n1>>5)&0x3f) - ((n2>>5)&0x3f) > diff ||
131
                ((n1>>11)&0x1f) - ((n2>>11)&0x1f) > diff)
132
              row0[i] = 1;
133
            else if ((n1&0x1f) - (n2&0x1f) < -diff ||
134
                     ((n1>>5)&0x3f) - ((n2>>5)&0x3f) < -diff ||
135
                     ((n1>>11)&0x1f) - ((n2>>11)&0x1f) < -diff)
136
              row0[i] = -1;
137
            else
138
              row0[i] = 0;
139
            cur += 2;
140
            prv += 2;
141
            // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
142
            // but row3 is 1 so it's interlaced ptr (nok++)
143
            if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
144
                (++nok) > max)
145
              break;
146
          }
147
        else // RGB/BGR 24/32
148
          for (i = 0; i < rowsize; i++)
149
          {
150
            if (cur[0] - prv[0] > diff ||
151
                cur[1] - prv[1] > diff ||
152
                cur[2] - prv[2] > diff)
153
              row0[i] = 1;
154
            else if (prv[0] - cur[0] > diff ||
155
                     prv[1] - cur[1] > diff ||
156
                     prv[2] - cur[2] > diff)
157
              row0[i] = -1;
158
            else
159
              row0[i] = 0;
160
            cur += mpi->bpp/8;
161
            prv += mpi->bpp/8;
162
            // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
163
            // but row3 is 1 so it's interlaced ptr (nok++)
164
            if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
165
                (++nok) > max)
166
              break;
167
          }
168
        cur0 += mpi->stride[0];
169
        prv0 += mpi->stride[0];
170
        // rotate rows
171
        cur = row2;
172
        row2 = row1;
173
        row1 = row0;
174
        row0 = cur;
175
      }
176
    }
177
    // check if number of interlaced is above of max
178
    if (nok > max)
179
    {
180
//    vf->priv->dfr++;
181
      if (vf->priv->was_dint < 1) // can skip at most one frame!
182
      {
183
        vf->priv->was_dint++;
184
//      vf->priv->rdfr++;
185
//      mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
186
        return 0;
187
      }
188
    }
189
    vf->priv->was_dint = 0;
190
//    mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
191
    return vf_next_put_image (vf, mpi, pts);
192
}
193

    
194
static int vf_open(vf_instance_t *vf, char *args){
195
    vf->config = config;
196
    vf->put_image = put_image;
197
//  vf->default_reqs=VFCAP_ACCEPT_STRIDE;
198
    vf->priv = malloc (sizeof(struct vf_priv_s));
199
    vf->priv->sense = 0.1;
200
    vf->priv->level = 0.15;
201
    vf->priv->pmpi = NULL;
202
    if (args)
203
      sscanf (args, "%f:%f", &vf->priv->sense, &vf->priv->level);
204
    return 1;
205
}
206

    
207
const vf_info_t vf_info_dint = {
208
    "drop interlaced frames",
209
    "dint",
210
    "A.G.",
211
    "",
212
    vf_open,
213
    NULL
214
};