Example #1
0
def tivo_compatable(inFile, tsn = ''):
    supportedModes = [[720, 480], [704, 480], [544, 480], [480, 480], [352, 480]]
    type, width, height, fps, millisecs, kbps, akbps, acodec, afreq, vpar =  video_info(inFile)
    #print type, width, height, fps, millisecs, kbps, akbps, acodec

    if (inFile[-5:]).lower() == '.tivo':
        debug_write(__name__, fn_attr(), ['TRUE, ends with .tivo.', inFile])
        return True

    if not type == 'mpeg2video':
        #print 'Not Tivo Codec'
        debug_write(__name__, fn_attr(), ['FALSE, type', type, 'not mpeg2video.', inFile])
        return False

    if os.path.splitext(inFile)[-1].lower() in ('.ts', '.mpv'):
        debug_write(__name__, fn_attr(), ['FALSE, ext', os.path.splitext(inFile)[-1],\
                'not tivo compatible.', inFile])
        return False

    if acodec == 'dca':
        debug_write(__name__, fn_attr(), ['FALSE, acodec', acodec, ', not supported.', inFile])
        return False

    if acodec != None:
        if not akbps or int(akbps) > config.getMaxAudioBR(tsn):
            debug_write(__name__, fn_attr(), ['FALSE,', akbps, 'kbps exceeds max audio bitrate.', inFile])
            return False

    if kbps != None:
        abit = max('0', akbps)
        if int(kbps)-int(abit) > config.strtod(config.getMaxVideoBR())/1000:
            debug_write(__name__, fn_attr(), ['FALSE,', kbps, 'kbps exceeds max video bitrate.', inFile])
            return False
    else:
        debug_write(__name__, fn_attr(), ['FALSE,', kbps, 'kbps not supported.', inFile])
        return False

    if config.isHDtivo(tsn):
        if vpar != 1.0:
            if config.getPixelAR(0):
                if vpar != None or config.getPixelAR(1) != 1.0:
                    debug_write(__name__, fn_attr(), ['FALSE,', vpar, 'not correct PAR,', inFile])
                    return False
        debug_write(__name__, fn_attr(), ['TRUE, HD Tivo detected, skipping remaining tests', inFile])
        return True

    if not fps == '29.97':
        #print 'Not Tivo fps'
        debug_write(__name__, fn_attr(), ['FALSE,', fps, 'fps, should be 29.97.', inFile])
        return False

    for mode in supportedModes:
        if (mode[0], mode[1]) == (width, height):
            #print 'Is TiVo!'
            debug_write(__name__, fn_attr(), ['TRUE,', width, 'x', height, 'is valid.', inFile])
            return True
    #print 'Not Tivo dimensions'
    debug_write(__name__, fn_attr(), ['FALSE,', width, 'x', height, 'not in supported modes.', inFile])
    return False
Example #2
0
def tivo_compatible_video(vInfo, tsn, mime=''):
    message = (True, '')
    while True:
        codec = vInfo.get('vCodec', '')
        if mime == 'video/mp4':
            if codec != 'h264':
                message = (False, 'vCodec %s not compatible' % codec)

            break

        if mime == 'video/bif':
            if codec != 'vc1':
                message = (False, 'vCodec %s not compatible' % codec)

            break

        if codec not in ('mpeg2video', 'mpeg1video'):
            message = (False, 'vCodec %s not compatible' % codec)
            break

        if vInfo['kbps'] != None:
            abit = max('0', vInfo['aKbps'])
            if (int(vInfo['kbps']) - int(abit) >
                config.strtod(config.getMaxVideoBR(tsn)) / 1000):
                message = (False, '%s kbps exceeds max video bitrate' %
                                  vInfo['kbps'])
                break
        else:
            message = (False, '%s kbps not supported' % vInfo['kbps'])
            break

        if config.isHDtivo(tsn):
            if vInfo['par2'] != 1.0:
                if config.getPixelAR(0):
                    if vInfo['par2'] != None or config.getPixelAR(1) != 1.0:
                        message = (False, '%s not correct PAR' % vInfo['par2'])
                        break
            # HD Tivo detected, skipping remaining tests.
            break

        if not vInfo['vFps'] in ['29.97', '59.94']:
            message = (False, '%s vFps, should be 29.97' % vInfo['vFps'])
            break

        if ((config.get169Blacklist(tsn) and not config.get169Setting(tsn))
            or (config.get169Letterbox(tsn) and config.get169Setting(tsn))):
            if vInfo['dar1'] and vInfo['dar1'] not in ('4:3', '8:9', '880:657'):
                message = (False, ('DAR %s not supported ' +
                                   'by BLACKLIST_169 tivos') % vInfo['dar1'])
                break

        mode = (vInfo['vWidth'], vInfo['vHeight'])
        if mode not in [(720, 480), (704, 480), (544, 480),
                        (528, 480), (480, 480), (352, 480), (352, 240)]:
            message = (False, '%s x %s not in supported modes' % mode)
        break

    return message
Example #3
0
def tivo_compatible_video(vInfo, tsn, mime=""):
    message = (True, "")
    while True:
        codec = vInfo["vCodec"]
        if mime == "video/mp4":
            if codec != "h264":
                message = (False, "vCodec %s not compatible" % codec)

            break

        if mime == "video/bif":
            if codec != "vc1":
                message = (False, "vCodec %s not compatible" % codec)

            break

        if codec not in ("mpeg2video", "mpeg1video"):
            message = (False, "vCodec %s not compatible" % codec)
            break

        if vInfo["kbps"] != None:
            abit = max("0", vInfo["aKbps"])
            if int(vInfo["kbps"]) - int(abit) > config.strtod(config.getMaxVideoBR(tsn)) / 1000:
                message = (False, "%s kbps exceeds max video bitrate" % vInfo["kbps"])
                break
        else:
            message = (False, "%s kbps not supported" % vInfo["kbps"])
            break

        if config.isHDtivo(tsn):
            if vInfo["par2"] != 1.0:
                if config.getPixelAR(0):
                    if vInfo["par2"] != None or config.getPixelAR(1) != 1.0:
                        message = (False, "%s not correct PAR" % vInfo["par2"])
                        break
            # HD Tivo detected, skipping remaining tests.
            break

        if not vInfo["vFps"] in ["29.97", "59.94"]:
            message = (False, "%s vFps, should be 29.97" % vInfo["vFps"])
            break

        if (config.get169Blacklist(tsn) and not config.get169Setting(tsn)) or (
            config.get169Letterbox(tsn) and config.get169Setting(tsn)
        ):
            if vInfo["dar1"] and vInfo["dar1"] not in ("4:3", "8:9", "880:657"):
                message = (False, ("DAR %s not supported " + "by BLACKLIST_169 tivos") % vInfo["dar1"])
                break

        mode = (vInfo["vWidth"], vInfo["vHeight"])
        if mode not in [(720, 480), (704, 480), (544, 480), (528, 480), (480, 480), (352, 480), (352, 240)]:
            message = (False, "%s x %s not in supported modes" % mode)
        break

    return message
Example #4
0
def select_aspect(inFile, tsn = ''):
    TIVO_WIDTH = config.getTivoWidth(tsn)
    TIVO_HEIGHT = config.getTivoHeight(tsn)

    vInfo = video_info(inFile)

    debug('tsn: %s' % tsn)

    aspect169 = config.get169Setting(tsn)

    debug('aspect169: %s' % aspect169)

    optres = config.getOptres(tsn)

    debug('optres: %s' % optres)

    if optres:
        optHeight = config.nearestTivoHeight(vInfo['vHeight'])
        optWidth = config.nearestTivoWidth(vInfo['vWidth'])
        if optHeight < TIVO_HEIGHT:
            TIVO_HEIGHT = optHeight
        if optWidth < TIVO_WIDTH:
            TIVO_WIDTH = optWidth

    if vInfo.get('par2'):
        par2 = vInfo['par2']
    elif vInfo.get('par'):
        par2 = float(vInfo['par'])
    else:
        # Assume PAR = 1.0
        par2 = 1.0

    debug(('File=%s vCodec=%s vWidth=%s vHeight=%s vFps=%s millisecs=%s ' +
           'TIVO_HEIGHT=%s TIVO_WIDTH=%s') % (inFile, vInfo['vCodec'],
          vInfo['vWidth'], vInfo['vHeight'], vInfo['vFps'],
          vInfo['millisecs'], TIVO_HEIGHT, TIVO_WIDTH))

    if config.isHDtivo(tsn) and not optres:
        if config.getPixelAR(0) or vInfo['par']:
            if vInfo['par2'] == None:
                if vInfo['par']:
                    npar = par2
                else:
                    npar = config.getPixelAR(1)
            else:
                npar = par2

            # adjust for pixel aspect ratio, if set

            if npar < 1.0:
                return ['-s', '%dx%d' % (vInfo['vWidth'],
                                         math.ceil(vInfo['vHeight'] / npar))]
            elif npar > 1.0:
                # FFMPEG expects width to be a multiple of two
                return ['-s', '%dx%d' % (math.ceil(vInfo['vWidth']*npar/2.0)*2,
                                         vInfo['vHeight'])]

        if vInfo['vHeight'] <= TIVO_HEIGHT:
            # pass all resolutions to S3, except heights greater than
            # conf height
            return []
        # else, resize video.

    d = gcd(vInfo['vHeight'], vInfo['vWidth'])
    rheight, rwidth = vInfo['vHeight'] / d, vInfo['vWidth'] / d
    debug('rheight=%s rwidth=%s' % (rheight, rwidth))

    if (rwidth, rheight) in [(1, 1)] and vInfo['par1'] == '8:9':
        debug('File + PAR is within 4:3.')
        return ['-aspect', '4:3', '-s', '%sx%s' % (TIVO_WIDTH, TIVO_HEIGHT)]

    elif ((rwidth, rheight) in [(4, 3), (10, 11), (15, 11), (59, 54),
                                (59, 72), (59, 36), (59, 54)] or
          vInfo['dar1'] == '4:3'):
        debug('File is within 4:3 list.')
        return ['-aspect', '4:3', '-s', '%sx%s' % (TIVO_WIDTH, TIVO_HEIGHT)]

    elif (((rwidth, rheight) in [(16, 9), (20, 11), (40, 33), (118, 81),
                                (59, 27)] or vInfo['dar1'] == '16:9')
          and (aspect169 or config.get169Letterbox(tsn))):
        debug('File is within 16:9 list and 16:9 allowed.')

        if config.get169Blacklist(tsn) or (aspect169 and
                                           config.get169Letterbox(tsn)):
            aspect = '4:3'
        else:
            aspect = '16:9'
        return ['-aspect', aspect, '-s', '%sx%s' % (TIVO_WIDTH, TIVO_HEIGHT)]

    else:
        settings = ['-aspect']

        multiplier16by9 = (16.0 * TIVO_HEIGHT) / (9.0 * TIVO_WIDTH) / par2
        multiplier4by3  =  (4.0 * TIVO_HEIGHT) / (3.0 * TIVO_WIDTH) / par2
        ratio = vInfo['vWidth'] * 100 * par2 / vInfo['vHeight']
        debug('par2=%.3f ratio=%.3f mult4by3=%.3f' % (par2, ratio,
                                                      multiplier4by3))

        # If video is wider than 4:3 add top and bottom padding

        if ratio > 133: # Might be 16:9 file, or just need padding on
                        # top and bottom

            if aspect169 and ratio > 135: # If file would fall in 4:3
                                          # assume it is supposed to be 4:3

                if (config.get169Blacklist(tsn) or
                    config.get169Letterbox(tsn)):
                    settings.append('4:3')
                else:
                    settings.append('16:9')

                if ratio > 177: # too short needs padding top and bottom
                    settings += pad_TB(TIVO_WIDTH, TIVO_HEIGHT,
                                       multiplier16by9, vInfo)
                    debug(('16:9 aspect allowed, file is wider ' +
                           'than 16:9 padding top and bottom\n%s') %
                          ' '.join(settings))

                else: # too skinny needs padding on left and right.
                    settings += pad_LR(TIVO_WIDTH, TIVO_HEIGHT,
                                       multiplier16by9, vInfo)
                    debug(('16:9 aspect allowed, file is narrower ' +
                           'than 16:9 padding left and right\n%s') %
                          ' '.join(settings))

            else: # this is a 4:3 file or 16:9 output not allowed
                if ratio > 135 and config.get169Letterbox(tsn):
                    settings.append('16:9')
                    multiplier = multiplier16by9
                else:
                    settings.append('4:3')
                    multiplier = multiplier4by3
                settings += pad_TB(TIVO_WIDTH, TIVO_HEIGHT,
                                   multiplier, vInfo)
                debug(('File is wider than 4:3 padding ' +
                       'top and bottom\n%s') % ' '.join(settings))

        # If video is taller than 4:3 add left and right padding, this
        # is rare. All of these files will always be sent in an aspect
        # ratio of 4:3 since they are so narrow.

        else:
            settings.append('4:3')
            settings += pad_LR(TIVO_WIDTH, TIVO_HEIGHT, multiplier4by3, vInfo)
            debug('File is taller than 4:3 padding left and right\n%s'
                  % ' '.join(settings))

        return settings
Example #5
0
def select_aspect(inFile, tsn=""):
    TIVO_WIDTH = config.getTivoWidth(tsn)
    TIVO_HEIGHT = config.getTivoHeight(tsn)

    vInfo = video_info(inFile)

    debug("tsn: %s" % tsn)

    aspect169 = config.get169Setting(tsn)

    debug("aspect169: %s" % aspect169)

    optres = config.getOptres(tsn)

    debug("optres: %s" % optres)

    if optres:
        optHeight = config.nearestTivoHeight(vInfo["vHeight"])
        optWidth = config.nearestTivoWidth(vInfo["vWidth"])
        if optHeight < TIVO_HEIGHT:
            TIVO_HEIGHT = optHeight
        if optWidth < TIVO_WIDTH:
            TIVO_WIDTH = optWidth

    if vInfo.get("par2"):
        par2 = vInfo["par2"]
    elif vInfo.get("par"):
        par2 = float(vInfo["par"])
    else:
        # Assume PAR = 1.0
        par2 = 1.0

    debug(
        ("File=%s vCodec=%s vWidth=%s vHeight=%s vFps=%s millisecs=%s " + "TIVO_HEIGHT=%s TIVO_WIDTH=%s")
        % (
            inFile,
            vInfo["vCodec"],
            vInfo["vWidth"],
            vInfo["vHeight"],
            vInfo["vFps"],
            vInfo["millisecs"],
            TIVO_HEIGHT,
            TIVO_WIDTH,
        )
    )

    if config.isHDtivo(tsn) and not optres:
        if config.getPixelAR(0) or vInfo["par"]:
            if vInfo["par2"] == None:
                if vInfo["par"]:
                    npar = par2
                else:
                    npar = config.getPixelAR(1)
            else:
                npar = par2

            # adjust for pixel aspect ratio, if set

            if npar < 1.0:
                return ["-s", "%dx%d" % (vInfo["vWidth"], math.ceil(vInfo["vHeight"] / npar))]
            elif npar > 1.0:
                # FFMPEG expects width to be a multiple of two
                return ["-s", "%dx%d" % (math.ceil(vInfo["vWidth"] * npar / 2.0) * 2, vInfo["vHeight"])]

        if vInfo["vHeight"] <= TIVO_HEIGHT:
            # pass all resolutions to S3, except heights greater than
            # conf height
            return []
        # else, resize video.

    d = gcd(vInfo["vHeight"], vInfo["vWidth"])
    rheight, rwidth = vInfo["vHeight"] / d, vInfo["vWidth"] / d
    debug("rheight=%s rwidth=%s" % (rheight, rwidth))

    if (rwidth, rheight) in [(1, 1)] and vInfo["par1"] == "8:9":
        debug("File + PAR is within 4:3.")
        return ["-aspect", "4:3", "-s", "%sx%s" % (TIVO_WIDTH, TIVO_HEIGHT)]

    elif (rwidth, rheight) in [(4, 3), (10, 11), (15, 11), (59, 54), (59, 72), (59, 36), (59, 54)] or vInfo[
        "dar1"
    ] == "4:3":
        debug("File is within 4:3 list.")
        return ["-aspect", "4:3", "-s", "%sx%s" % (TIVO_WIDTH, TIVO_HEIGHT)]

    elif ((rwidth, rheight) in [(16, 9), (20, 11), (40, 33), (118, 81), (59, 27)] or vInfo["dar1"] == "16:9") and (
        aspect169 or config.get169Letterbox(tsn)
    ):
        debug("File is within 16:9 list and 16:9 allowed.")

        if config.get169Blacklist(tsn) or (aspect169 and config.get169Letterbox(tsn)):
            aspect = "4:3"
        else:
            aspect = "16:9"
        return ["-aspect", aspect, "-s", "%sx%s" % (TIVO_WIDTH, TIVO_HEIGHT)]

    else:
        settings = ["-aspect"]

        multiplier16by9 = (16.0 * TIVO_HEIGHT) / (9.0 * TIVO_WIDTH) / par2
        multiplier4by3 = (4.0 * TIVO_HEIGHT) / (3.0 * TIVO_WIDTH) / par2
        ratio = vInfo["vWidth"] * 100 * par2 / vInfo["vHeight"]
        debug("par2=%.3f ratio=%.3f mult4by3=%.3f" % (par2, ratio, multiplier4by3))

        # If video is wider than 4:3 add top and bottom padding

        if ratio > 133:  # Might be 16:9 file, or just need padding on
            # top and bottom

            if aspect169 and ratio > 135:  # If file would fall in 4:3
                # assume it is supposed to be 4:3

                if config.get169Blacklist(tsn) or config.get169Letterbox(tsn):
                    settings.append("4:3")
                else:
                    settings.append("16:9")

                if ratio > 177:  # too short needs padding top and bottom
                    settings += pad_TB(TIVO_WIDTH, TIVO_HEIGHT, multiplier16by9, vInfo)
                    debug(
                        ("16:9 aspect allowed, file is wider " + "than 16:9 padding top and bottom\n%s")
                        % " ".join(settings)
                    )

                else:  # too skinny needs padding on left and right.
                    settings += pad_LR(TIVO_WIDTH, TIVO_HEIGHT, multiplier16by9, vInfo)
                    debug(
                        ("16:9 aspect allowed, file is narrower " + "than 16:9 padding left and right\n%s")
                        % " ".join(settings)
                    )

            else:  # this is a 4:3 file or 16:9 output not allowed
                if ratio > 135 and config.get169Letterbox(tsn):
                    settings.append("16:9")
                    multiplier = multiplier16by9
                else:
                    settings.append("4:3")
                    multiplier = multiplier4by3
                settings += pad_TB(TIVO_WIDTH, TIVO_HEIGHT, multiplier, vInfo)
                debug(("File is wider than 4:3 padding " + "top and bottom\n%s") % " ".join(settings))

        # If video is taller than 4:3 add left and right padding, this
        # is rare. All of these files will always be sent in an aspect
        # ratio of 4:3 since they are so narrow.

        else:
            settings.append("4:3")
            settings += pad_LR(TIVO_WIDTH, TIVO_HEIGHT, multiplier4by3, vInfo)
            debug("File is taller than 4:3 padding left and right\n%s" % " ".join(settings))

        return settings
Example #6
0
def select_aspect(inFile, tsn = ''):
    TIVO_WIDTH = config.getTivoWidth(tsn)
    TIVO_HEIGHT = config.getTivoHeight(tsn)

    type, width, height, fps, millisecs, kbps, akbps, acodec, afreq, vpar =  video_info(inFile)

    debug_write(__name__, fn_attr(), ['tsn:', tsn])

    aspect169 = config.get169Setting(tsn)

    debug_write(__name__, fn_attr(), ['aspect169:', aspect169])

    optres = config.getOptres(tsn)

    debug_write(__name__, fn_attr(), ['optres:', optres])

    if optres:
        optHeight = config.nearestTivoHeight(height)
        optWidth = config.nearestTivoWidth(width)
        if optHeight < TIVO_HEIGHT:
            TIVO_HEIGHT = optHeight
        if optWidth < TIVO_WIDTH:
            TIVO_WIDTH = optWidth

    d = gcd(height,width)
    ratio = (width*100)/height
    rheight, rwidth = height/d, width/d

    debug_write(__name__, fn_attr(), ['File=', inFile, ' Type=', type, ' width=', width, ' height=', height, ' fps=', fps, ' millisecs=', millisecs, ' ratio=', ratio, ' rheight=', rheight, ' rwidth=', rwidth, ' TIVO_HEIGHT=', TIVO_HEIGHT, 'TIVO_WIDTH=', TIVO_WIDTH])

    multiplier16by9 = (16.0 * TIVO_HEIGHT) / (9.0 * TIVO_WIDTH)
    multiplier4by3  =  (4.0 * TIVO_HEIGHT) / (3.0 * TIVO_WIDTH)

    if config.isHDtivo(tsn) and optres:
        if config.getPixelAR(0):
            if vpar == None:
                npar = config.getPixelAR(1)
            else:
                npar = vpar
            # adjust for pixel aspect ratio, if set, because TiVo expects square pixels
            if npar<1.0:
                return ['-s', str(width) + 'x' + str(int(math.ceil(height/npar)))]
            elif npar>1.0:
                # FFMPEG expects width to be a multiple of two
                return ['-s', str(int(math.ceil(width*npar/2.0)*2)) + 'x' + str(height)]
        if height <= TIVO_HEIGHT:
            # pass all resolutions to S3, except heights greater than conf height
            return []
        # else, resize video.
    if (rwidth, rheight) in [(4, 3), (10, 11), (15, 11), (59, 54), (59, 72), (59, 36), (59, 54)]:
        debug_write(__name__, fn_attr(), ['File is within 4:3 list.'])
        return ['-aspect', '4:3', '-s', str(TIVO_WIDTH) + 'x' + str(TIVO_HEIGHT)]
    elif ((rwidth, rheight) in [(16, 9), (20, 11), (40, 33), (118, 81), (59, 27)]) and aspect169:
        debug_write(__name__, fn_attr(), ['File is within 16:9 list and 16:9 allowed.'])
        return ['-aspect', '16:9', '-s', str(TIVO_WIDTH) + 'x' + str(TIVO_HEIGHT)]
    else:
        settings = []
        #If video is wider than 4:3 add top and bottom padding
        if (ratio > 133): #Might be 16:9 file, or just need padding on top and bottom
            if aspect169 and (ratio > 135): #If file would fall in 4:3 assume it is supposed to be 4:3 
                if (ratio > 177):#too short needs padding top and bottom
                    endHeight = int(((TIVO_WIDTH*height)/width) * multiplier16by9)
                    settings.append('-aspect')
                    settings.append('16:9')
                    if endHeight % 2:
                        endHeight -= 1
                    if endHeight < TIVO_HEIGHT * 0.99:
                        settings.append('-s')
                        settings.append(str(TIVO_WIDTH) + 'x' + str(endHeight))

                        topPadding = ((TIVO_HEIGHT - endHeight)/2)
                        if topPadding % 2:
                            topPadding -= 1
                        
                        settings.append('-padtop')
                        settings.append(str(topPadding))
                        bottomPadding = (TIVO_HEIGHT - endHeight) - topPadding
                        settings.append('-padbottom')
                        settings.append(str(bottomPadding))
                    else:   #if only very small amount of padding needed, then just stretch it
                        settings.append('-s')
                        settings.append(str(TIVO_WIDTH) + 'x' + str(TIVO_HEIGHT))
                    debug_write(__name__, fn_attr(), ['16:9 aspect allowed, file is wider than 16:9 padding top and bottom', ' '.join(settings)])
                else: #too skinny needs padding on left and right.
                    endWidth = int((TIVO_HEIGHT*width)/(height*multiplier16by9))
                    settings.append('-aspect')
                    settings.append('16:9')
                    if endWidth % 2:
                        endWidth -= 1
                    if endWidth < (TIVO_WIDTH-10):
                        settings.append('-s')
                        settings.append(str(endWidth) + 'x' + str(TIVO_HEIGHT))

                        leftPadding = ((TIVO_WIDTH - endWidth)/2)
                        if leftPadding % 2:
                            leftPadding -= 1

                        settings.append('-padleft')
                        settings.append(str(leftPadding))
                        rightPadding = (TIVO_WIDTH - endWidth) - leftPadding
                        settings.append('-padright')
                        settings.append(str(rightPadding))
                    else: #if only very small amount of padding needed, then just stretch it
                        settings.append('-s')
                        settings.append(str(TIVO_WIDTH) + 'x' + str(TIVO_HEIGHT))
                    debug_write(__name__, fn_attr(), ['16:9 aspect allowed, file is narrower than 16:9 padding left and right\n', ' '.join(settings)])
            else: #this is a 4:3 file or 16:9 output not allowed
                settings.append('-aspect')
                settings.append('4:3')
                endHeight = int(((TIVO_WIDTH*height)/width) * multiplier4by3)
                if endHeight % 2:
                    endHeight -= 1
                if endHeight < TIVO_HEIGHT * 0.99:
                    settings.append('-s')
                    settings.append(str(TIVO_WIDTH) + 'x' + str(endHeight))

                    topPadding = ((TIVO_HEIGHT - endHeight)/2)
                    if topPadding % 2:
                        topPadding -= 1
                    
                    settings.append('-padtop')
                    settings.append(str(topPadding))
                    bottomPadding = (TIVO_HEIGHT - endHeight) - topPadding
                    settings.append('-padbottom')
                    settings.append(str(bottomPadding))
                else:   #if only very small amount of padding needed, then just stretch it
                    settings.append('-s')
                    settings.append(str(TIVO_WIDTH) + 'x' + str(TIVO_HEIGHT))
                debug_write(__name__, fn_attr(), ['File is wider than 4:3 padding top and bottom\n', ' '.join(settings)])

            return settings
        #If video is taller than 4:3 add left and right padding, this is rare. All of these files will always be sent in
        #an aspect ratio of 4:3 since they are so narrow.
        else:
            endWidth = int((TIVO_HEIGHT*width)/(height*multiplier4by3))
            settings.append('-aspect')
            settings.append('4:3')
            if endWidth % 2:
                endWidth -= 1
            if endWidth < (TIVO_WIDTH * 0.99):
                settings.append('-s')
                settings.append(str(endWidth) + 'x' + str(TIVO_HEIGHT))

                leftPadding = ((TIVO_WIDTH - endWidth)/2)
                if leftPadding % 2:
                    leftPadding -= 1

                settings.append('-padleft')
                settings.append(str(leftPadding))
                rightPadding = (TIVO_WIDTH - endWidth) - leftPadding
                settings.append('-padright')
                settings.append(str(rightPadding))
            else: #if only very small amount of padding needed, then just stretch it
                settings.append('-s')
                settings.append(str(TIVO_WIDTH) + 'x' + str(TIVO_HEIGHT))

            debug_write(__name__, fn_attr(), ['File is taller than 4:3 padding left and right\n', ' '.join(settings)])
            
            return settings
Example #7
0
def tivo_compatible_video(vInfo, tsn, mime=''):
    message = (True, '')
    while True:
        codec = vInfo.get('vCodec', '')
        if mime == 'video/mp4':
            if codec != 'h264':
                message = (False, 'vCodec %s not compatible' % codec)

            break

        if mime == 'video/bif':
            if codec != 'vc1':
                message = (False, 'vCodec %s not compatible' % codec)

            break

        if codec not in ('mpeg2video', 'mpeg1video'):
            message = (False, 'vCodec %s not compatible' % codec)
            break

        if vInfo['kbps'] != None:
            abit = max('0', vInfo['aKbps'])
            if (int(vInfo['kbps']) - int(abit) >
                    config.strtod(config.getMaxVideoBR(tsn)) / 1000):
                message = (False,
                           '%s kbps exceeds max video bitrate' % vInfo['kbps'])
                break
        else:
            message = (False, '%s kbps not supported' % vInfo['kbps'])
            break

        if config.isHDtivo(tsn):
            if vInfo['par2'] != 1.0:
                if config.getPixelAR(0):
                    if vInfo['par2'] != None or config.getPixelAR(1) != 1.0:
                        message = (False, '%s not correct PAR' % vInfo['par2'])
                        break
            # HD Tivo detected, skipping remaining tests.
            break

        if not vInfo['vFps'] in ['29.97', '59.94']:
            message = (False, '%s vFps, should be 29.97' % vInfo['vFps'])
            break

        if ((config.get169Blacklist(tsn) and not config.get169Setting(tsn)) or
            (config.get169Letterbox(tsn) and config.get169Setting(tsn))):
            if vInfo['dar1'] and vInfo['dar1'] not in ('4:3', '8:9',
                                                       '880:657'):
                message = (
                    False,
                    ('DAR %s not supported ' + 'by BLACKLIST_169 tivos') %
                    vInfo['dar1'])
                break

        mode = (vInfo['vWidth'], vInfo['vHeight'])
        if mode not in [(720, 480), (704, 480), (544, 480), (528, 480),
                        (480, 480), (352, 480), (352, 240)]:
            message = (False, '%s x %s not in supported modes' % mode)
        break

    return message
Example #8
0
def select_aspect(inFile, tsn=''):
    TIVO_WIDTH = config.getTivoWidth(tsn)
    TIVO_HEIGHT = config.getTivoHeight(tsn)

    vInfo = video_info(inFile)

    debug('tsn: %s' % tsn)

    aspect169 = config.get169Setting(tsn)

    debug('aspect169: %s' % aspect169)

    optres = config.getOptres(tsn)

    debug('optres: %s' % optres)

    if optres:
        optHeight = config.nearestTivoHeight(vInfo['vHeight'])
        optWidth = config.nearestTivoWidth(vInfo['vWidth'])
        if optHeight < TIVO_HEIGHT:
            TIVO_HEIGHT = optHeight
        if optWidth < TIVO_WIDTH:
            TIVO_WIDTH = optWidth

    if vInfo.get('par2'):
        par2 = vInfo['par2']
    elif vInfo.get('par'):
        par2 = float(vInfo['par'])
    else:
        # Assume PAR = 1.0
        par2 = 1.0

    debug(('File=%s vCodec=%s vWidth=%s vHeight=%s vFps=%s millisecs=%s ' +
           'TIVO_HEIGHT=%s TIVO_WIDTH=%s') %
          (inFile, vInfo['vCodec'], vInfo['vWidth'], vInfo['vHeight'],
           vInfo['vFps'], vInfo['millisecs'], TIVO_HEIGHT, TIVO_WIDTH))

    if config.isHDtivo(tsn) and not optres:
        if config.getPixelAR(0) or vInfo['par']:
            if vInfo['par2'] == None:
                if vInfo['par']:
                    npar = par2
                else:
                    npar = config.getPixelAR(1)
            else:
                npar = par2

            # adjust for pixel aspect ratio, if set

            if npar < 1.0:
                return [
                    '-s',
                    '%dx%d' %
                    (vInfo['vWidth'], math.ceil(vInfo['vHeight'] / npar))
                ]
            elif npar > 1.0:
                # FFMPEG expects width to be a multiple of two
                return [
                    '-s',
                    '%dx%d' % (math.ceil(vInfo['vWidth'] * npar / 2.0) * 2,
                               vInfo['vHeight'])
                ]

        if vInfo['vHeight'] <= TIVO_HEIGHT:
            # pass all resolutions to S3, except heights greater than
            # conf height
            return []
        # else, resize video.

    d = gcd(vInfo['vHeight'], vInfo['vWidth'])
    rheight, rwidth = vInfo['vHeight'] / d, vInfo['vWidth'] / d
    debug('rheight=%s rwidth=%s' % (rheight, rwidth))

    if (rwidth, rheight) in [(1, 1)] and vInfo['par1'] == '8:9':
        debug('File + PAR is within 4:3.')
        return ['-aspect', '4:3', '-s', '%sx%s' % (TIVO_WIDTH, TIVO_HEIGHT)]

    elif ((rwidth, rheight) in [(4, 3), (10, 11), (15, 11), (59, 54), (59, 72),
                                (59, 36), (59, 54)] or vInfo['dar1'] == '4:3'):
        debug('File is within 4:3 list.')
        return ['-aspect', '4:3', '-s', '%sx%s' % (TIVO_WIDTH, TIVO_HEIGHT)]

    elif (((rwidth, rheight) in [(16, 9), (20, 11), (40, 33), (118, 81),
                                 (59, 27)] or vInfo['dar1'] == '16:9')
          and (aspect169 or config.get169Letterbox(tsn))):
        debug('File is within 16:9 list and 16:9 allowed.')

        if config.get169Blacklist(tsn) or (aspect169
                                           and config.get169Letterbox(tsn)):
            aspect = '4:3'
        else:
            aspect = '16:9'
        return ['-aspect', aspect, '-s', '%sx%s' % (TIVO_WIDTH, TIVO_HEIGHT)]

    else:
        settings = ['-aspect']

        multiplier16by9 = (16.0 * TIVO_HEIGHT) / (9.0 * TIVO_WIDTH) / par2
        multiplier4by3 = (4.0 * TIVO_HEIGHT) / (3.0 * TIVO_WIDTH) / par2
        ratio = vInfo['vWidth'] * 100 * par2 / vInfo['vHeight']
        debug('par2=%.3f ratio=%.3f mult4by3=%.3f' %
              (par2, ratio, multiplier4by3))

        # If video is wider than 4:3 add top and bottom padding

        if ratio > 133:  # Might be 16:9 file, or just need padding on
            # top and bottom

            if aspect169 and ratio > 135:  # If file would fall in 4:3
                # assume it is supposed to be 4:3

                if (config.get169Blacklist(tsn)
                        or config.get169Letterbox(tsn)):
                    settings.append('4:3')
                else:
                    settings.append('16:9')

                if ratio > 177:  # too short needs padding top and bottom
                    settings += pad_TB(TIVO_WIDTH, TIVO_HEIGHT,
                                       multiplier16by9, vInfo)
                    debug(('16:9 aspect allowed, file is wider ' +
                           'than 16:9 padding top and bottom\n%s') %
                          ' '.join(settings))

                else:  # too skinny needs padding on left and right.
                    settings += pad_LR(TIVO_WIDTH, TIVO_HEIGHT,
                                       multiplier16by9, vInfo)
                    debug(('16:9 aspect allowed, file is narrower ' +
                           'than 16:9 padding left and right\n%s') %
                          ' '.join(settings))

            else:  # this is a 4:3 file or 16:9 output not allowed
                if ratio > 135 and config.get169Letterbox(tsn):
                    settings.append('16:9')
                    multiplier = multiplier16by9
                else:
                    settings.append('4:3')
                    multiplier = multiplier4by3
                settings += pad_TB(TIVO_WIDTH, TIVO_HEIGHT, multiplier, vInfo)
                debug(
                    ('File is wider than 4:3 padding ' + 'top and bottom\n%s')
                    % ' '.join(settings))

        # If video is taller than 4:3 add left and right padding, this
        # is rare. All of these files will always be sent in an aspect
        # ratio of 4:3 since they are so narrow.

        else:
            settings.append('4:3')
            settings += pad_LR(TIVO_WIDTH, TIVO_HEIGHT, multiplier4by3, vInfo)
            debug('File is taller than 4:3 padding left and right\n%s' %
                  ' '.join(settings))

        return settings