Comparing deinterlacers

From MythTV Official Wiki
Jump to: navigation, search

Here is a python script that can be used to quickly change the deinterlacer being used, making it easy to compare deinterlacers and decide which one works best for you.

Please be sure to read the instructions at the top of the file and to edit the file as necessary. It was quickly thrown together and isn't designed to handle every possible set-up.


#!/usr/bin/env python

Usage:  Set up a playback profile named "test" with only one rule:

  if rez >= 0 0

Put any renderers/deinterlacers you want, except leave the secondary
deinterlacer as "none" so you'll be able to tell if the primary one
isn't working.

Make this your default playback profile.  Then start this script
from a terminal window (e.g. a laptop remotely logged in).  (You
may need to edit the script to provide database credentials.)
If all is well, it will show your current settings for the test
profile, and offer you a list of deinterlacers to choose from.
When you choose a deinterlacer, it will stop playback, adjust the
database settings, pause a bit, restart playback and skip backwards.

When you select a deinterlacer, it changes the renderers to match and
within about a second you find yourself 15 seconds back in the same
recording.  So you can watch the same 15 seconds over and over again
with different deinterlacers.

Currently only compares opengl and vdpau deinterlacers.

Note that this script *changes the database*.  Use it at your own risk.

# Original version written by Dan Christensen <>, June 2010.

deinterlacers = 'none onefield linearblend bobdeint kerneldeint kerneldoubleprocessdeint greedyhdeint greedyhdoubleprocessdeint yadifdeint yadifdoubleprocessdeint fieldorderdoubleprocessdeint vdpauonefield vdpaubobdeint vdpaubasic vdpaubasicdoublerate vdpauadvanced vdpauadvanceddoublerate'.split()

filters = dict(opengl='openglbicubic', vdpau='vdpauhqscaling')
osdrenderers = dict(opengl='opengl2', vdpau='vdpau')

from MythTV import *
from time import sleep
import sys

# You may need to pass arguments here instead, e.g.
# db = MythDB(DBHostName='mybackend',  DBName='mythconverg',
#             DBUserName='mythtv',     DBPassword='mythtv')
db = MythDB()

cs = db.cursor()

# Assume the first frontend is the one we want:
frontend = db.getFrontends()[0]

def do(*args, **kwargs):
    cs.execute(*args, **kwargs)
    return cs.fetchall()

def do1(*args, **kwargs):
    cs.execute(*args, **kwargs)
    return cs.fetchone()

pgid = do1('select profilegroupid from displayprofilegroups where name = "test"')[0]
print 'Editing profile with profilegroupid', pgid

while True:
    print 'Current settings:'
    cursettings = {}
    for row in do('select * from displayprofiles where profilegroupid = %s', (pgid,)):
        cursettings[row[2]] = row[3]
        print '%-18s: %s' % (row[2], row[3])
    print 'Deinterlacers:'
    for i, d in enumerate(deinterlacers):
        print '%-2s %s' % (i, d)
    print 's  Toggle high-quality scaling filter'
    # v: Toggle openglvsync?
    print 'q  Quit'

    key = raw_input('Choose a deinterlacer: ')

    newsettings = dict(cursettings)

    if key == 'q':
    elif key == 's':
        if cursettings['pref_filters'] == '':
            renderer = cursettings['pref_videorenderer']
            newsettings['pref_filters'] = filters[renderer]
            newsettings['pref_filters'] = ''
            key = int(key)
            deint = deinterlacers[key]
            print 'Error, please try again...'

        newsettings['pref_deint0'] = deint

        decoder = 'ffmpeg'
        if 'vdpau' in deint:
            decoder = 'vdpau'
        newsettings['pref_decoder'] = decoder
        renderer = 'opengl'
        if 'vdpau' in deint:
            renderer = 'vdpau'
        newsettings['pref_videorenderer'] = renderer
        newsettings['pref_osdrenderer'] = osdrenderers[renderer]
        # If we have a hq scaling filter in place, make sure it
        # is compatible with the renderer:
        if cursettings['pref_filters'] != '':
            newsettings['pref_filters'] = filters[renderer]

    # Stop current playback:
    if frontend.sendQuery('location').startswith('Playback'):
        print frontend.sendQuery('location')

    # Make changes to database:
    print 'Making these changes:'
    for setting in newsettings:
        if newsettings[setting] != cursettings[setting]:
            do('update displayprofiles set data = %s where value = %s and profilegroupid = %s LIMIT 1',
               (newsettings[setting], setting, pgid,))
            print '%-18s: %-28s --> %-28s' % (setting, cursettings[setting], newsettings[setting])
    print 'Done.'

    # Restart playback; need to wait so frontend is ready.
    loc = frontend.sendQuery('location')
    if loc in ['playbackbox', 'itemdetailpopup']:
        print 'Starting playback.'
        # See output of frontend.getKey() and getPlay() for possible things to send.
        if loc == 'itemdetailpopup':
            # say to play starting at bookmark:
        frontend.sendPlay('seek backward')