Skip to content
Snippets Groups Projects
utils.c 32.9 KiB
Newer Older
  • Learn to ignore specific revisions
  •     /* Now we have all the fields that we can get */
        if (!q) {
            if (duration)
                return 0;
            else
                return now * INT64_C(1000000);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
            t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
    
            dt.tm_isdst = -1;       /* unknown */
            if (is_utc) {
                t = mktimegm(&dt);
            } else {
                t = mktime(&dt);
            }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            int val, n;
    
            q++;
            for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
                if (!isdigit(*q)) 
                    break;
                val += n * (*q - '0');
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
            t += val;
        }
        return t;
    }
    
    
    /* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
       1 if found */
    int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
    {
        const char *p;
        char tag[128], *q;
    
        p = info;
        if (*p == '?')
            p++;
        for(;;) {
            q = tag;
            while (*p != '\0' && *p != '=' && *p != '&') {
                if ((q - tag) < sizeof(tag) - 1)
                    *q++ = *p;
                p++;
            }
            *q = '\0';
            q = arg;
            if (*p == '=') {
                p++;
                while (*p != '&' && *p != '\0') {
    
                    if ((q - arg) < arg_size - 1) {
                        if (*p == '+')
                            *q++ = ' ';
                        else
                            *q++ = *p;
                    }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
                    p++;
                }
                *q = '\0';
            }
            if (!strcmp(tag, tag1)) 
                return 1;
            if (*p != '&')
                break;
    
    /* Return in 'buf' the path with '%d' replaced by number. Also handles
       the '%0nd' format where 'n' is the total number of digits and
       '%%'. Return 0 if OK, and -1 if format error */
    int get_frame_filename(char *buf, int buf_size,
                           const char *path, int number)
    {
        const char *p;
        char *q, buf1[20];
        int nd, len, c, percentd_found;
    
        q = buf;
        p = path;
        percentd_found = 0;
        for(;;) {
            c = *p++;
            if (c == '\0')
                break;
            if (c == '%') {
    
                do {
                    nd = 0;
                    while (isdigit(*p)) {
                        nd = nd * 10 + *p++ - '0';
                    }
                    c = *p++;
                    if (c == '*' && nd > 0) {
                        // The nd field is actually the modulus
                        number = number % nd;
                        c = *p++;
                        nd = 0;
                    }
                } while (isdigit(c));
    
    
                switch(c) {
                case '%':
                    goto addchar;
                case 'd':
                    if (percentd_found)
                        goto fail;
                    percentd_found = 1;
                    snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
                    len = strlen(buf1);
                    if ((q - buf + len) > buf_size - 1)
                        goto fail;
                    memcpy(q, buf1, len);
                    q += len;
                    break;
                default:
                    goto fail;
                }
            } else {
            addchar:
                if ((q - buf) < buf_size - 1)
                    *q++ = c;
            }
        }
        if (!percentd_found)
            goto fail;
        *q = '\0';
        return 0;
     fail:
        *q = '\0';
        return -1;
    }
    
    
    /**
     *
     * Print on stdout a nice hexa dump of a buffer
     * @param buf buffer
     * @param size buffer size
     */
    void av_hex_dump(UINT8 *buf, int size)
    {
        int len, i, j, c;
    
        for(i=0;i<size;i+=16) {
            len = size - i;
            if (len > 16)
                len = 16;
            printf("%08x ", i);
            for(j=0;j<16;j++) {
                if (j < len)
                    printf(" %02x", buf[i+j]);
                else
                    printf("   ");
            }
            printf(" ");
            for(j=0;j<len;j++) {
                c = buf[i+j];
                if (c < ' ' || c > '~')
                    c = '.';
                printf("%c", c);
            }
            printf("\n");
        }
    }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    void url_split(char *proto, int proto_size,
                   char *hostname, int hostname_size,
                   int *port_ptr,
                   char *path, int path_size,
                   const char *url)
    {
        const char *p;
        char *q;
        int port;
    
        port = -1;
    
        p = url;
        q = proto;
        while (*p != ':' && *p != '\0') {
            if ((q - proto) < proto_size - 1)
                *q++ = *p;
            p++;
        }
        if (proto_size > 0)
            *q = '\0';
        if (*p == '\0') {
            if (proto_size > 0)
                proto[0] = '\0';
            if (hostname_size > 0)
                hostname[0] = '\0';
            p = url;
        } else {
            p++;
            if (*p == '/')
                p++;
            if (*p == '/')
                p++;
            q = hostname;
            while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
                if ((q - hostname) < hostname_size - 1)
                    *q++ = *p;
                p++;
            }
            if (hostname_size > 0)
                *q = '\0';
            if (*p == ':') {
                p++;
                port = strtoul(p, (char **)&p, 10);
            }
        }
        if (port_ptr)
            *port_ptr = port;
        pstrcpy(path, path_size, p);
    }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    /**
     * Set the pts for a given stream
     * @param s stream 
     * @param pts_wrap_bits number of bits effectively used by the pts
     *        (used for wrap control, 33 is the value for MPEG) 
     * @param pts_num numerator to convert to seconds (MPEG: 1) 
     * @param pts_den denominator to convert to seconds (MPEG: 90000)
     */
    void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
                         int pts_num, int pts_den)
    {
        s->pts_wrap_bits = pts_wrap_bits;
        s->pts_num = pts_num;
        s->pts_den = pts_den;
    }
    
    /* fraction handling */
    
    /**
     * f = val + (num / den) + 0.5. 'num' is normalized so that it is such
     * as 0 <= num < den.
     *
     * @param f fractional number
     * @param val integer value
     * @param num must be >= 0
     * @param den must be >= 1 
     */
    void av_frac_init(AVFrac *f, INT64 val, INT64 num, INT64 den)
    {
        num += (den >> 1);
        if (num >= den) {
            val += num / den;
            num = num % den;
        }
        f->val = val;
        f->num = num;
        f->den = den;
    }
    
    /* set f to (val + 0.5) */
    void av_frac_set(AVFrac *f, INT64 val)
    {
        f->val = val;
        f->num = f->den >> 1;
    }
    
    /**
     * Fractionnal addition to f: f = f + (incr / f->den)
     *
     * @param f fractional number
     * @param incr increment, can be positive or negative
     */
    void av_frac_add(AVFrac *f, INT64 incr)
    {
        INT64 num, den;
    
        num = f->num + incr;
        den = f->den;
        if (num < 0) {
            f->val += num / den;
            num = num % den;
            if (num < 0) {
                num += den;
                f->val--;
            }
        } else if (num >= den) {
            f->val += num / den;
            num = num % den;
        }
        f->num = num;
    }