'Generate the output filename.'

def prepare_filename(self, info_dict):

    try:
        template_dict = dict(info_dict)
        template_dict[u'epoch'] = int(time.time())
        autonumber_size = self.params.get(u'autonumber_size')
        if (autonumber_size is None):
            autonumber_size = 5
        template_dict[u'autonumber'] = ((self.params.get(u'autonumber_start', 1) - 1) + self._num_downloads)
        if (template_dict.get(u'resolution') is None):
            if (template_dict.get(u'width') and template_dict.get(u'height')):
                template_dict[u'resolution'] = (u'%dx%d' % (template_dict[u'width'], template_dict[u'height']))
            elif template_dict.get(u'height'):
                template_dict[u'resolution'] = (u'%sp' % template_dict[u'height'])
            elif template_dict.get(u'width'):
                template_dict[u'resolution'] = (u'%dx?' % template_dict[u'width'])
        sanitize = (lambda k, v: sanitize_filename(compat_str(v), restricted=self.params.get(u'restrictfilenames'), is_id=((k == u'id') or k.endswith(u'_id'))))
        template_dict = dict(((k, (v if isinstance(v, compat_numeric_types) else sanitize(k, v))) for (k, v) in template_dict.items() if ((v is not None) and (not isinstance(v, (list, tuple, dict))))))
        template_dict = collections.defaultdict((lambda : u'NA'), template_dict)
        outtmpl = self.params.get(u'outtmpl', DEFAULT_OUTTMPL)
        field_size_compat_map = {u'playlist_index': len(str(template_dict[u'n_entries'])), u'autonumber': autonumber_size}
        FIELD_SIZE_COMPAT_RE = u'(?<!%)%\\((?P<field>autonumber|playlist_index)\\)s'
        mobj = re.search(FIELD_SIZE_COMPAT_RE, outtmpl)
        if mobj:
            outtmpl = re.sub(FIELD_SIZE_COMPAT_RE, (u'%%(\\1)0%dd' % field_size_compat_map[mobj.group(u'field')]), outtmpl)
        for numeric_field in self._NUMERIC_FIELDS:
            if (numeric_field not in template_dict):
                FORMAT_RE = u'(?x)\n                                                                                                (?<!%)\n                                                                                                %\n                                                                                                \\({0}\\)        #    mapping    key\n                                                                                                (?:[#0\\-+    ]+)?        #    conversion    flags    (optional)\n                                                                                                (?:\\d+)?        #    minimum    field    width    (optional)\n                                                                                                (?:\\.\\d+)?        #    precision    (optional)\n                                                                                                [hlL]?        #    length    modifier    (optional)\n                                                                                                [diouxXeEfFgGcrs%]        #    conversion    type\n                                                                                '
                outtmpl = re.sub(FORMAT_RE.format(numeric_field), u'%({0})s'.format(numeric_field), outtmpl)
        sep = u''.join([random.choice(ascii_letters) for _ in range(32)])
        outtmpl = outtmpl.replace(u'%%', u'%{0}%'.format(sep)).replace(u'$$', u'${0}$'.format(sep))
        filename = (expand_path(outtmpl).replace(sep, u'') % template_dict)
        if ((sys.version_info < (3, 0)) and (sys.platform == u'win32')):
            filename = encodeFilename(filename, True).decode(preferredencoding())
        return sanitize_path(filename)
    except ValueError as err:
        self.report_error(((((u'Error    in    output    template:    ' + str(err)) + u'    (encoding:    ') + repr(preferredencoding())) + u')'))
        return None
