Skip to content
Snippets Groups Projects
utils.c 64.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        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;
    
    
        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++;
                } 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  nice hexa dump of a buffer
     * @param f stream for output
    
    void av_hex_dump(FILE *f, uint8_t *buf, int size)
    
    {
        int len, i, j, c;
    
        for(i=0;i<size;i+=16) {
            len = size - i;
            if (len > 16)
                len = 16;
    
            fprintf(f, "%08x ", i);
    
                    fprintf(f, " %02x", buf[i+j]);
    
    /**
     * Print on 'f' a nice dump of a packet
     * @param f stream for output
     * @param pkt packet to dump
     * @param dump_payload true if the payload must be displayed too
     */
    void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
    {
        fprintf(f, "stream #%d:\n", pkt->stream_index);
        fprintf(f, "  keyframe=%d\n", ((pkt->flags & PKT_FLAG_KEY) != 0));
        fprintf(f, "  duration=%0.3f\n", (double)pkt->duration / AV_TIME_BASE);
    
        /* DTS is _always_ valid after av_read_frame() */
        fprintf(f, "  dts=");
        if (pkt->dts == AV_NOPTS_VALUE)
            fprintf(f, "N/A");
        else
            fprintf(f, "%0.3f", (double)pkt->dts / AV_TIME_BASE);
    
        /* PTS may be not known if B frames are present */
        fprintf(f, "  pts=");
        if (pkt->pts == AV_NOPTS_VALUE)
            fprintf(f, "N/A");
        else
            fprintf(f, "%0.3f", (double)pkt->pts / AV_TIME_BASE);
        fprintf(f, "\n");
        fprintf(f, "  size=%d\n", pkt->size);
        if (dump_payload)
            av_hex_dump(f, pkt->data, pkt->size);
    }
    
    
    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_t val, int64_t num, int64_t den)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        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_t val)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        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_t incr)
    
        int64_t num, den;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        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;
    }
    
    
    /**
     * register a new image format
     * @param img_fmt Image format descriptor
     */
    void av_register_image_format(AVImageFormat *img_fmt)
    {
        AVImageFormat **p;
    
        p = &first_image_format;
        while (*p != NULL) p = &(*p)->next;
        *p = img_fmt;
        img_fmt->next = NULL;
    }
    
    /* guess image format */
    AVImageFormat *av_probe_image_format(AVProbeData *pd)
    {
        AVImageFormat *fmt1, *fmt;
        int score, score_max;
    
        fmt = NULL;
        score_max = 0;
        for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
            if (fmt1->img_probe) {
                score = fmt1->img_probe(pd);
                if (score > score_max) {
                    score_max = score;
                    fmt = fmt1;
                }
            }
        }
        return fmt;
    }
    
    AVImageFormat *guess_image_format(const char *filename)
    {
        AVImageFormat *fmt1;
    
        for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
            if (fmt1->extensions && match_ext(filename, fmt1->extensions))
                return fmt1;
        }
        return NULL;
    }
    
    /**
     * Read an image from a stream. 
     * @param gb byte stream containing the image
     * @param fmt image format, NULL if probing is required
     */
    int av_read_image(ByteIOContext *pb, const char *filename,
                      AVImageFormat *fmt,
                      int (*alloc_cb)(void *, AVImageInfo *info), void *opaque)
    {
        char buf[PROBE_BUF_SIZE];
        AVProbeData probe_data, *pd = &probe_data;
        offset_t pos;
        int ret;
    
        if (!fmt) {
    
            pd->filename = filename;
    
            pd->buf = buf;
            pos = url_ftell(pb);
            pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE);
            url_fseek(pb, pos, SEEK_SET);
            fmt = av_probe_image_format(pd);
        }
        if (!fmt)
            return AVERROR_NOFMT;
        ret = fmt->img_read(pb, alloc_cb, opaque);
        return ret;
    }
    
    /**
     * Write an image to a stream.
     * @param pb byte stream for the image output
     * @param fmt image format
     * @param img image data and informations
     */
    int av_write_image(ByteIOContext *pb, AVImageFormat *fmt, AVImageInfo *img)
    {
        return fmt->img_write(pb, img);
    }