Beispiel #1
0
static int write_frame(struct AVFormatContext *s, int stream_index,
                       AVFrame **frame, unsigned flags)
{
    AVBPrint bp;
    int ret = 0;
    enum AVMediaType type;
    const char *type_name;

    if ((flags & AV_WRITE_UNCODED_FRAME_QUERY))
        return 0;

    av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
    av_bprintf(&bp, "%d, %10"PRId64"",
               stream_index, (*frame)->pts);
    type = s->streams[stream_index]->codec->codec_type;
    type_name = av_get_media_type_string(type);
    av_bprintf(&bp, ", %s", type_name ? type_name : "unknown");
    switch (type) {
        case AVMEDIA_TYPE_VIDEO:
            video_frame_cksum(&bp, *frame);
            break;
        case AVMEDIA_TYPE_AUDIO:
            audio_frame_cksum(&bp, *frame);
            break;
    }

    av_bprint_chars(&bp, '\n', 1);
    if (av_bprint_is_complete(&bp))
        avio_write(s->pb, bp.str, bp.len);
    else
        ret = AVERROR(ENOMEM);
    av_bprint_finalize(&bp, NULL);
    return ret;
}
Beispiel #2
0
static void video_frame_cksum(AVBPrint *bp, AVFrame *frame)
{
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
    int i, y;
    uint8_t *data;
    int linesize[5] = { 0 };

    av_bprintf(bp, ", %d x %d", frame->width, frame->height);
    if (!desc) {
        av_bprintf(bp, ", unknown");
        return;
    }
    if (av_image_fill_linesizes(linesize, frame->format, frame->width) < 0)
        return;
    av_bprintf(bp, ", %s", desc->name);
    for (i = 0; linesize[i]; i++) {
        unsigned cksum = 0;
        int h = frame->height;
        if ((i == 1 || i == 2) && desc->nb_components >= 3)
            h = AV_CEIL_RSHIFT(h, desc->log2_chroma_h);
        data = frame->data[i];
        for (y = 0; y < h; y++) {
            cksum = av_adler32_update(cksum, data, linesize[i]);
            data += frame->linesize[i];
        }
        av_bprintf(bp, ", 0x%08x", cksum);
    }
}
Beispiel #3
0
static int rt_event_to_ass(AVBPrint *buf, const char *p)
{
    int prev_chr_is_space = 1;

    while (*p) {
        if (*p != '<') {
            if (!isspace(*p))
                av_bprint_chars(buf, *p, 1);
            else if (!prev_chr_is_space)
                av_bprint_chars(buf, ' ', 1);
            prev_chr_is_space = isspace(*p);
        } else {
            const char *end = strchr(p, '>');
            if (!end)
                break;
            if (!av_strncasecmp(p, "<br/>", 5) ||
                !av_strncasecmp(p, "<br>",  4)) {
                av_bprintf(buf, "\\N");
            }
            p = end;
        }
        p++;
    }
    av_bprintf(buf, "\r\n");
    return 0;
}
Beispiel #4
0
static int webvtt_event_to_ass(AVBPrint *buf, const char *p)
{
    int i, skip = 0;

    while (*p) {

        for (i = 0; i < FF_ARRAY_ELEMS(webvtt_tag_replace); i++) {
            const char *from = webvtt_tag_replace[i].from;
            const size_t len = strlen(from);
            if (!strncmp(p, from, len)) {
                av_bprintf(buf, "%s", webvtt_tag_replace[i].to);
                p += len;
                break;
            }
        }
        if (!*p)
            break;

        if (*p == '<')
            skip = 1;
        else if (*p == '>')
            skip = 0;
        else if (p[0] == '\n' && p[1])
            av_bprintf(buf, "\\N");
        else if (!skip && *p != '\r')
            av_bprint_chars(buf, *p, 1);
        p++;
    }
    av_bprintf(buf, "\r\n");
    return 0;
}
Beispiel #5
0
static void format_line(void *ptr, int level, const char *fmt, va_list vl,
                        AVBPrint part[3], int *print_prefix, int type[2])
{
    AVClass* avc = ptr ? *(AVClass **) ptr : NULL;
    av_bprint_init(part+0, 0, 1);
    av_bprint_init(part+1, 0, 1);
    av_bprint_init(part+2, 0, 65536);

    if(type) type[0] = type[1] = AV_CLASS_CATEGORY_NA + 16;
    if (*print_prefix && avc) {
        if (avc->parent_log_context_offset) {
            AVClass** parent = *(AVClass ***) (((uint8_t *) ptr) +
                                   avc->parent_log_context_offset);
            if (parent && *parent) {
                av_bprintf(part+0, "[%s @ %p] ",
                         (*parent)->item_name(parent), parent);
                if(type) type[0] = get_category(parent);
            }
        }
        av_bprintf(part+1, "[%s @ %p] ",
                 avc->item_name(ptr), ptr);
        if(type) type[1] = get_category(ptr);
    }

    av_vbprintf(part+2, fmt, vl);

    if(*part[0].str || *part[1].str || *part[2].str) {
        char lastc = part[2].len ? part[2].str[part[2].len - 1] : 0;
        *print_prefix = lastc == '\n' || lastc == '\r';
    }
}
Beispiel #6
0
static int print_link_prop(AVBPrint *buf, AVFilterLink *link)
{
    char *format;
    char layout[64];

    if (!buf)
        buf = &(AVBPrint){ 0 }; /* dummy buffer */
    switch (link->type) {
        case AVMEDIA_TYPE_VIDEO:
            format = av_x_if_null(av_get_pix_fmt_name(link->format), "?");
            av_bprintf(buf, "[%dx%d %d:%d %s]", link->w, link->h,
                    link->sample_aspect_ratio.num,
                    link->sample_aspect_ratio.den,
                    format);
            break;

        case AVMEDIA_TYPE_AUDIO:
            av_get_channel_layout_string(layout, sizeof(layout),
                                         -1, link->channel_layout);
            format = av_x_if_null(av_get_sample_fmt_name(link->format), "?");
            av_bprintf(buf, "[%dHz %s:%s:%s]",
                    (int)link->sample_rate, format, layout,
                    link->planar ? "planar" : "packed");
            break;

        default:
            av_bprintf(buf, "?");
            break;
    }
    return buf->len;
}
Beispiel #7
0
int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
                    int ts_start, int duration, int raw)
{
    AVBPrint buf;
    int ret, dlen;
    AVSubtitleRect **rects;

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
    if (!raw) {
        av_bprintf(&buf, "Dialogue: 0,");
        insert_ts(&buf, ts_start);
        insert_ts(&buf, duration == -1 ? -1 : ts_start + duration);
        av_bprintf(&buf, "Default,");
    }

    dlen = strcspn(dialog, "\n");
    dlen += dialog[dlen] == '\n';

    av_bprintf(&buf, "%.*s", dlen, dialog);
    if (!av_bprint_is_complete(&buf))
        return AVERROR(ENOMEM);

    rects = av_realloc(sub->rects, (sub->num_rects+1) * sizeof(*sub->rects));
    if (!rects)
        return AVERROR(ENOMEM);
    sub->rects = rects;
    sub->end_display_time = FFMAX(sub->end_display_time, 10 * duration);
    rects[sub->num_rects]       = av_mallocz(sizeof(*rects[0]));
    rects[sub->num_rects]->type = SUBTITLE_ASS;
    ret = av_bprint_finalize(&buf, &rects[sub->num_rects]->ass);
    if (ret < 0)
        return ret;
    sub->num_rects++;
    return dlen;
}
Beispiel #8
0
static void microdvd_close_no_persistent_tags(AVBPrint *new_line,
                                              struct microdvd_tag *tags)
{
    int i, sidx;

    for (i = sizeof(MICRODVD_TAGS) - 2; i >= 0; i--) {
        if (tags[i].persistent != MICRODVD_PERSISTENT_OFF)
            continue;
        switch (tags[i].key) {

        case 'y':
            for (sidx = sizeof(MICRODVD_STYLES) - 2; sidx >= 0; sidx--)
                if (tags[i].data1 & (1 << sidx))
                    av_bprintf(new_line, "{\\%c0}", MICRODVD_STYLES[sidx]);
            break;

        case 'c':
            av_bprintf(new_line, "{\\c}");
            break;

        case 'f':
            av_bprintf(new_line, "{\\fn}");
            break;

        case 's':
            av_bprintf(new_line, "{\\fs}");
            break;
        }
        tags[i].key = 0;
    }
}
EXPORT int duplicate_stream(void *actx,enum DuplicateFormat format)
{
	int ret = 0;
	struct liveStream *ctx = (struct liveStream *)actx;
	if(!ctx)
		return -1;

	av_bprint_init(&ctx->graph_desc, 0, 1);
	if(format == SIDE_BY_SIDE)
		av_bprintf(&ctx->graph_desc, "[0]format=yuv420p,scale=iw/2:ih,pad=iw*2:ih[main];[main]split[dup1][dup2];[dup1][dup2]overlay=W/2:0[bg]");
	else if ( format == TOP_N_BOTTOM)
		av_bprintf(&ctx->graph_desc, "[0]format=yuv420p,scale=iw:ih/2,pad=iw:ih*2[main];[main]split[dup1][dup2];[dup1][dup2]overlay=0:H/2[bg]");
	else
	{
		av_log(NULL,AV_LOG_ERROR,"Invalid format Speified only side_by_side and top_n_bottom supported\n");
		return -1;
	}
	ret = configure_filter(ctx);
	if(ret < 0)
	{
		av_log(NULL,AV_LOG_ERROR,"Unable to configure Filter\n");
		return ret;
	}
	return ret;
}
Beispiel #10
0
static int func_metadata(AVFilterContext *ctx, AVBPrint *bp,
                         char *fct, unsigned argc, char **argv, int tag)
{
    DrawTextContext *s = ctx->priv;
    AVDictionaryEntry *e = av_dict_get(s->metadata, argv[0], NULL, 0);

    if (e && e->value)
        av_bprintf(bp, "%s", e->value);
    else if (argc >= 2)
        av_bprintf(bp, "%s", argv[1]);
    return 0;
}
Beispiel #11
0
static void insert_ts(AVBPrint *buf, int ts)
{
    if (ts == -1) {
        av_bprintf(buf, "9:59:59.99,");
    } else {
        int h, m, s;

        h = ts/360000;  ts -= 360000*h;
        m = ts/  6000;  ts -=   6000*m;
        s = ts/   100;  ts -=    100*s;
        av_bprintf(buf, "%d:%02d:%02d.%02d,", h, m, s, ts);
    }
}
Beispiel #12
0
static int func_pts(AVFilterContext *ctx, AVBPrint *bp,
                    char *fct, unsigned argc, char **argv, int tag)
{
    DrawTextContext *s = ctx->priv;
    const char *fmt;
    double pts = s->var_values[VAR_T];
    int ret;

    fmt = argc >= 1 ? argv[0] : "flt";
    if (argc >= 2) {
        int64_t delta;
        if ((ret = av_parse_time(&delta, argv[1], 1)) < 0) {
            av_log(ctx, AV_LOG_ERROR, "Invalid delta '%s'\n", argv[1]);
            return ret;
        }
        pts += (double)delta / AV_TIME_BASE;
    }
    if (!strcmp(fmt, "flt")) {
        av_bprintf(bp, "%.6f", pts);
    } else if (!strcmp(fmt, "hms")) {
        if (isnan(pts)) {
            av_bprintf(bp, " ??:??:??.???");
        } else {
            int64_t ms = llrint(pts * 1000);
            char sign = ' ';
            if (ms < 0) {
                sign = '-';
                ms = -ms;
            }
            av_bprintf(bp, "%c%02d:%02d:%02d.%03d", sign,
                       (int)(ms / (60 * 60 * 1000)),
                       (int)(ms / (60 * 1000)) % 60,
                       (int)(ms / 1000) % 60,
                       (int)(ms % 1000));
        }
    } else if (!strcmp(fmt, "localtime") ||
               !strcmp(fmt, "gmtime")) {
        struct tm tm;
        time_t ms = (time_t)pts;
        const char *timefmt = argc >= 3 ? argv[2] : "%Y-%m-%d %H:%M:%S";
        if (!strcmp(fmt, "localtime"))
            localtime_r(&ms, &tm);
        else
            gmtime_r(&ms, &tm);
        av_bprint_strftime(bp, timefmt, &tm);
    } else {
        av_log(ctx, AV_LOG_ERROR, "Invalid format '%s'\n", fmt);
        return AVERROR(EINVAL);
    }
    return 0;
}
Beispiel #13
0
static int microdvd_init(AVCodecContext *avctx)
{
    int i, sidx;
    AVBPrint font_buf;
    int font_size    = ASS_DEFAULT_FONT_SIZE;
    int color        = ASS_DEFAULT_COLOR;
    int bold         = ASS_DEFAULT_BOLD;
    int italic       = ASS_DEFAULT_ITALIC;
    int underline    = ASS_DEFAULT_UNDERLINE;
    int alignment    = ASS_DEFAULT_ALIGNMENT;
    struct microdvd_tag tags[sizeof(MICRODVD_TAGS) - 1] = {{0}};

    av_bprint_init(&font_buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
    av_bprintf(&font_buf, "%s", ASS_DEFAULT_FONT);

    if (avctx->extradata) {
        microdvd_load_tags(tags, avctx->extradata);
        for (i = 0; i < sizeof(MICRODVD_TAGS) - 1; i++) {
            switch (av_tolower(tags[i].key)) {
            case 'y':
                for (sidx = 0; sidx < sizeof(MICRODVD_STYLES) - 1; sidx++) {
                    if (tags[i].data1 & (1 << sidx)) {
                        switch (MICRODVD_STYLES[sidx]) {
                        case 'i': italic    = 1; break;
                        case 'b': bold      = 1; break;
                        case 'u': underline = 1; break;
                        }
                    }
                }
                break;

            case 'c': color     = tags[i].data1; break;
            case 's': font_size = tags[i].data1; break;
            case 'p': alignment =             8; break;

            case 'f':
                av_bprint_clear(&font_buf);
                av_bprintf(&font_buf, "%.*s",
                           tags[i].data_string_len, tags[i].data_string);
                break;
            }
        }
    }
    return ff_ass_subtitle_header(avctx, font_buf.str, font_size, color,
                                  ASS_DEFAULT_BACK_COLOR, bold, italic,
                                  underline, ASS_DEFAULT_BORDERSTYLE,
                                  alignment);
}
Beispiel #14
0
static int read_dialogue(ASSContext *ass, AVBPrint *dst, const uint8_t *p,
                         int64_t *start, int *duration)
{
    int pos = 0;
    int64_t end;
    int hh1, mm1, ss1, ms1;
    int hh2, mm2, ss2, ms2;

    if (sscanf(p, "Dialogue: %*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d,%n",
               &hh1, &mm1, &ss1, &ms1,
               &hh2, &mm2, &ss2, &ms2, &pos) >= 8 && pos > 0) {

        /* This is not part of the sscanf itself in order to handle an actual
         * number (which would be the Layer) or the form "Marked=N" (which is
         * the old SSA field, now replaced by Layer, and will lead to Layer
         * being 0 here). */
        const int layer = atoi(p + 10);

        end    = (hh2*3600LL + mm2*60LL + ss2) * 100LL + ms2;
        *start = (hh1*3600LL + mm1*60LL + ss1) * 100LL + ms1;
        *duration = end - *start;

        av_bprint_clear(dst);
        av_bprintf(dst, "%u,%d,%s", ass->readorder++, layer, p + pos);

        /* right strip the buffer */
        while (dst->len > 0 &&
               dst->str[dst->len - 1] == '\r' ||
               dst->str[dst->len - 1] == '\n')
            dst->str[--dst->len] = 0;
        return 0;
    }
    return -1;
}
Beispiel #15
0
static int sami_read_header(AVFormatContext *s)
{
    SAMIContext *sami = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);
    AVBPrint buf, hdr_buf;
    char c = 0;
    int res = 0, got_first_sync_point = 0;
    FFTextReader tr;
    ff_text_init_avio(&tr, s->pb);

    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 64, 1, 1000);
    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codec->codec_id   = AV_CODEC_ID_SAMI;

    av_bprint_init(&buf,     0, AV_BPRINT_SIZE_UNLIMITED);
    av_bprint_init(&hdr_buf, 0, AV_BPRINT_SIZE_UNLIMITED);

    while (!ff_text_eof(&tr)) {
        AVPacket *sub;
        const int64_t pos = ff_text_pos(&tr) - (c != 0);
        int is_sync, n = ff_smil_extract_next_text_chunk(&tr, &buf, &c);

        if (n == 0)
            break;

        is_sync = !av_strncasecmp(buf.str, "<SYNC", 5);
        if (is_sync)
            got_first_sync_point = 1;

        if (!got_first_sync_point) {
            av_bprintf(&hdr_buf, "%s", buf.str);
        } else {
            sub = ff_subtitles_queue_insert(&sami->q, buf.str, buf.len, !is_sync);
            if (!sub) {
                res = AVERROR(ENOMEM);
                goto end;
            }
            if (is_sync) {
                const char *p = ff_smil_get_attr_ptr(buf.str, "Start");
                sub->pos      = pos;
                sub->pts      = p ? strtol(p, NULL, 10) : 0;
                sub->duration = -1;
            }
        }
        av_bprint_clear(&buf);
    }

    res = avpriv_bprint_to_extradata(st->codec, &hdr_buf);
    if (res < 0)
        goto end;

    ff_subtitles_queue_finalize(&sami->q);

end:
    av_bprint_finalize(&buf, NULL);
    return res;
}
Beispiel #16
0
static int func_eval_expr_int_format(AVFilterContext *ctx, AVBPrint *bp,
                          char *fct, unsigned argc, char **argv, int tag)
{
    DrawTextContext *s = ctx->priv;
    double res;
    int intval;
    int ret;
    unsigned int positions = 0;
    char fmt_str[30] = "%";

    /*
     * argv[0] expression to be converted to `int`
     * argv[1] format: 'x', 'X', 'd' or 'u'
     * argv[2] positions printed (optional)
     */

    ret = av_expr_parse_and_eval(&res, argv[0], var_names, s->var_values,
                                 NULL, NULL, fun2_names, fun2,
                                 &s->prng, 0, ctx);
    if (ret < 0) {
        av_log(ctx, AV_LOG_ERROR,
               "Expression '%s' for the expr text expansion function is not valid\n",
               argv[0]);
        return ret;
    }

    if (!strchr("xXdu", argv[1][0])) {
        av_log(ctx, AV_LOG_ERROR, "Invalid format '%c' specified,"
                " allowed values: 'x', 'X', 'd', 'u'\n", argv[1][0]);
        return AVERROR(EINVAL);
    }

    if (argc == 3) {
        ret = sscanf(argv[2], "%u", &positions);
        if (ret != 1) {
            av_log(ctx, AV_LOG_ERROR, "expr_int_format(): Invalid number of positions"
                    " to print: '%s'\n", argv[2]);
            return AVERROR(EINVAL);
        }
    }

    feclearexcept(FE_ALL_EXCEPT);
    intval = res;
    if ((ret = fetestexcept(FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW))) {
        av_log(ctx, AV_LOG_ERROR, "Conversion of floating-point result to int failed. Control register: 0x%08x. Conversion result: %d\n", ret, intval);
        return AVERROR(EINVAL);
    }

    if (argc == 3)
        av_strlcatf(fmt_str, sizeof(fmt_str), "0%u", positions);
    av_strlcatf(fmt_str, sizeof(fmt_str), "%c", argv[1][0]);

    av_log(ctx, AV_LOG_DEBUG, "Formatting value %f (expr '%s') with spec '%s'\n",
            res, argv[0], fmt_str);

    av_bprintf(bp, fmt_str, intval);

    return 0;
}
Beispiel #17
0
static int subviewer_event_to_ass(AVBPrint *buf, const char *p)
{
    while (*p) {
        if (!strncmp(p, "[br]", 4)) {
            av_bprintf(buf, "\\N");
            p += 4;
        } else {
            if (p[0] == '\n' && p[1])
                av_bprintf(buf, "\\N");
            else if (*p != '\n' && *p != '\r')
                av_bprint_chars(buf, *p, 1);
            p++;
        }
    }

    return 0;
}
Beispiel #18
0
static void read_chunk(AVIOContext *pb, AVBPrint *buf)
{
    char eol_buf[5];
    int n = 0, i = 0, nb_eol = 0;

    av_bprint_clear(buf);

    for (;;) {
        char c = avio_r8(pb);

        if (!c)
            break;

        /* ignore all initial line breaks */
        if (n == 0 && is_eol(c))
            continue;

        /* line break buffering: we don't want to add the trailing \r\n */
        if (is_eol(c)) {
            nb_eol += c == '\n';
            if (nb_eol == 2)
                break;
            eol_buf[i++] = c;
            if (i == sizeof(eol_buf) - 1)
                break;
            continue;
        }

        /* only one line break followed by data: we flush the line breaks
         * buffer */
        if (i) {
            eol_buf[i] = 0;
            av_bprintf(buf, "%s", eol_buf);
            i = nb_eol = 0;
        }

        av_bprint_chars(buf, c, 1);
        n++;
    }

    /* FIXME: remove the following when the lavc SubRip decoder is fixed
     * (trailing tags are not correctly flushed, see what happens to FATE when
     * you disable this code) */
    if (buf->len)
        av_bprintf(buf, "\n");
}
Beispiel #19
0
static int func_frame_num(AVFilterContext *ctx, AVBPrint *bp,
                          char *fct, unsigned argc, char **argv, int tag)
{
    DrawTextContext *s = ctx->priv;

    av_bprintf(bp, "%d", (int)s->var_values[VAR_N]);
    return 0;
}
Beispiel #20
0
static int func_pict_type(AVFilterContext *ctx, AVBPrint *bp,
                          char *fct, unsigned argc, char **argv, int tag)
{
    DrawTextContext *s = ctx->priv;

    av_bprintf(bp, "%c", av_get_picture_type_char(s->var_values[VAR_PICT_TYPE]));
    return 0;
}
int ff_ass_add_rect_bprint(AVSubtitle *sub, AVBPrint *buf,
                           int ts_start, int duration)
{
    av_bprintf(buf, "\r\n");
    if (!av_bprint_is_complete(buf))
        return AVERROR(ENOMEM);
    return ff_ass_add_rect(sub, buf->str, ts_start, duration, 0);
}
Beispiel #22
0
static void bprint_pascal(AVBPrint *b, unsigned size)
{
    unsigned i, j;
    unsigned p[42];

    av_assert0(size < FF_ARRAY_ELEMS(p));

    p[0] = 1;
    av_bprintf(b, "%8d\n", 1);
    for (i = 1; i <= size; i++) {
        p[i] = 1;
        for (j = i - 1; j > 0; j--)
            p[j] = p[j] + p[j - 1];
        for (j = 0; j <= i; j++)
            av_bprintf(b, "%8d", p[j]);
        av_bprintf(b, "\n");
    }
}
Beispiel #23
0
static void audio_frame_cksum(AVBPrint *bp, AVFrame *frame)
{
    int nb_planes, nb_samples, p;
    const char *name;

    nb_planes  = av_frame_get_channels(frame);
    nb_samples = frame->nb_samples;
    if (!av_sample_fmt_is_planar(frame->format)) {
        nb_samples *= nb_planes;
        nb_planes = 1;
    }
    name = av_get_sample_fmt_name(frame->format);
    av_bprintf(bp, ", %d samples", frame->nb_samples);
    av_bprintf(bp, ", %s", name ? name : "unknown");
    for (p = 0; p < nb_planes; p++) {
        uint32_t cksum = 0;
        void *d = frame->extended_data[p];
        switch (frame->format) {
        case AV_SAMPLE_FMT_U8:
        case AV_SAMPLE_FMT_U8P:
            cksum_line_u8(&cksum, d, nb_samples);
            break;
        case AV_SAMPLE_FMT_S16:
        case AV_SAMPLE_FMT_S16P:
            cksum_line_s16(&cksum, d, nb_samples);
            break;
        case AV_SAMPLE_FMT_S32:
        case AV_SAMPLE_FMT_S32P:
            cksum_line_s32(&cksum, d, nb_samples);
            break;
        case AV_SAMPLE_FMT_FLT:
        case AV_SAMPLE_FMT_FLTP:
            cksum_line_flt(&cksum, d, nb_samples);
            break;
        case AV_SAMPLE_FMT_DBL:
        case AV_SAMPLE_FMT_DBLP:
            cksum_line_dbl(&cksum, d, nb_samples);
            break;
        default:
            av_assert0(!"reached");
        }
        av_bprintf(bp, ", 0x%08x", cksum);
    }
}
Beispiel #24
0
static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end)
{
  while (text < text_end) {
    switch (*text) {
    case '\r':
      break;
    case '\n':
      av_bprintf(buf, "\\N");
      break;
    default:
      av_bprint_chars(buf, *text, 1);
      break;
    }
    text++;
  }

  av_bprintf(buf, "\r\n");
  return 0;
}
static int microdvd_decode_frame(AVCodecContext *avctx,
                                 void *data, int *got_sub_ptr, AVPacket *avpkt)
{
    AVSubtitle *sub = data;
    AVBPrint new_line;
    char *decoded_sub;
    char *line = avpkt->data;
    char *end = avpkt->data + avpkt->size;
    struct microdvd_tag tags[sizeof(MICRODVD_TAGS) - 1] = {{0}};

    if (avpkt->size <= 0)
        return avpkt->size;

    av_bprint_init(&new_line, 0, 2048);

    // skip {frame_start}{frame_end}
    line = strchr(line, '}'); if (!line) goto end; line++;
    line = strchr(line, '}'); if (!line) goto end; line++;

    // subtitle content
    while (line < end && *line) {

        // parse MicroDVD tags, and open them in ASS
        line = microdvd_load_tags(tags, line);
        microdvd_open_tags(&new_line, tags);

        // simple copy until EOL or forced carriage return
        while (line < end && *line && *line != '|') {
            av_bprint_chars(&new_line, *line, 1);
            line++;
        }

        // line split
        if (line < end && *line == '|') {
            microdvd_close_no_persistent_tags(&new_line, tags);
            av_bprintf(&new_line, "\\N");
            line++;
        }
    }

end:
    av_bprint_finalize(&new_line, &decoded_sub);
    if (*decoded_sub) {
        int64_t start    = avpkt->pts;
        int64_t duration = avpkt->duration;
        int ts_start     = av_rescale_q(start,    avctx->time_base, (AVRational){1,100});
        int ts_duration  = duration != -1 ?
                           av_rescale_q(duration, avctx->time_base, (AVRational){1,100}) : -1;
        ff_ass_add_rect(sub, decoded_sub, ts_start, ts_duration, 0);
    }
    av_free(decoded_sub);

    *got_sub_ptr = sub->num_rects > 0;
    return avpkt->size;
}
Beispiel #26
0
static int ass_read_header(AVFormatContext *s)
{
    ASSContext *ass = s->priv_data;
    AVBPrint header, line, rline;
    int res = 0;
    AVStream *st;
    FFTextReader tr;
    ff_text_init_avio(s, &tr, s->pb);

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 64, 1, 100);
    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codec->codec_id   = AV_CODEC_ID_ASS;

    av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
    av_bprint_init(&line,   0, AV_BPRINT_SIZE_UNLIMITED);
    av_bprint_init(&rline,  0, AV_BPRINT_SIZE_UNLIMITED);

    for (;;) {
        int64_t pos = get_line(&line, &tr);
        int64_t ts_start = AV_NOPTS_VALUE;
        int duration = -1;
        AVPacket *sub;

        if (!line.str[0]) // EOF
            break;

        if (read_dialogue(ass, &rline, line.str, &ts_start, &duration) < 0) {
            av_bprintf(&header, "%s", line.str);
            continue;
        }
        sub = ff_subtitles_queue_insert(&ass->q, rline.str, rline.len, 0);
        if (!sub) {
            res = AVERROR(ENOMEM);
            goto end;
        }
        sub->pos = pos;
        sub->pts = ts_start;
        sub->duration = duration;
    }

    res = avpriv_bprint_to_extradata(st->codec, &header);
    if (res < 0)
        goto end;

    ff_subtitles_queue_finalize(&ass->q);

end:
    av_bprint_finalize(&header, NULL);
    av_bprint_finalize(&line,   NULL);
    av_bprint_finalize(&rline,  NULL);
    return res;
}
Beispiel #27
0
void av_bprint_channel_layout(struct AVBPrint *bp,
                              int nb_channels, uint64_t channel_layout)
{
    int i;

    if (nb_channels <= 0)
        nb_channels = av_get_channel_layout_nb_channels(channel_layout);

    for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
        if (nb_channels    == channel_layout_map[i].nb_channels &&
            channel_layout == channel_layout_map[i].layout) {
            av_bprintf(bp, "%s", channel_layout_map[i].name);
            return;
        }

    av_bprintf(bp, "%d channels", nb_channels);
    if (channel_layout) {
        int i, ch;
        av_bprintf(bp, " (");
        for (i = 0, ch = 0; i < 64; i++) {
            if ((channel_layout & (UINT64_C(1) << i))) {
                const char *name = get_channel_name(i);
                if (name) {
                    if (ch > 0)
                        av_bprintf(bp, "+");
                    av_bprintf(bp, "%s", name);
                }
                ch++;
            }
        }
        av_bprintf(bp, ")");
    }
}
Beispiel #28
0
static int mpl2_event_to_ass(AVBPrint *buf, const char *p)
{
    if (*p == ' ')
        p++;

    while (*p) {
        int got_style = 0;

        while (*p && strchr("/\\_", *p)) {
            if      (*p == '/')  av_bprintf(buf, "{\\i1}");
            else if (*p == '\\') av_bprintf(buf, "{\\b1}");
            else if (*p == '_')  av_bprintf(buf, "{\\u1}");
            got_style = 1;
            p++;
        }

        while (*p && *p != '|') {
            if (*p != '\r' && *p != '\n')
                av_bprint_chars(buf, *p, 1);
            p++;
        }

        if (*p == '|') {
            if (got_style)
                av_bprintf(buf, "{\\r}");
            av_bprintf(buf, "\\N");
            p++;
        }
    }

    av_bprintf(buf, "\r\n");
    return 0;
}
Beispiel #29
0
void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size,
                             const char *linebreaks, int keep_ass_markup)
{
    const char *p_end = p + size;

    for (; p < p_end && *p; p++) {

        /* forced custom line breaks, not accounted as "normal" EOL */
        if (linebreaks && strchr(linebreaks, *p)) {
            av_bprintf(buf, "\\N");

        /* standard ASS escaping so random characters don't get mis-interpreted
         * as ASS */
        } else if (!keep_ass_markup && strchr("{}\\", *p)) {
            av_bprintf(buf, "\\%c", *p);

        /* some packets might end abruptly (no \0 at the end, like for example
         * in some cases of demuxing from a classic video container), some
         * might be terminated with \n or \r\n which we have to remove (for
         * consistency with those who haven't), and we also have to deal with
         * evil cases such as \r at the end of the buffer (and no \0 terminated
         * character) */
        } else if (p[0] == '\n') {
            /* some stuff left so we can insert a line break */
            if (p < p_end - 1)
                av_bprintf(buf, "\\N");
        } else if (p[0] == '\r' && p < p_end - 1 && p[1] == '\n') {
            /* \r followed by a \n, we can skip it. We don't insert the \N yet
             * because we don't know if it is followed by more text */
            continue;

        /* finally, a sane character */
        } else {
            av_bprint_chars(buf, *p, 1);
        }
    }
    av_bprintf(buf, "\r\n");
}
int ff_ass_bprint_dialog(AVBPrint *buf, const char *dialog,
                         int ts_start, int duration, int raw)
{
    int dlen;

    if (!raw || raw == 2) {
        long int layer = 0;

        if (raw == 2) {
            /* skip ReadOrder */
            dialog = strchr(dialog, ',');
            if (!dialog)
                return AVERROR_INVALIDDATA;
            dialog++;

            /* extract Layer or Marked */
            layer = strtol(dialog, (char**)&dialog, 10);
            if (*dialog != ',')
                return AVERROR_INVALIDDATA;
            dialog++;
        }
        av_bprintf(buf, "Dialogue: %ld,", layer);
        insert_ts(buf, ts_start);
        insert_ts(buf, duration == -1 ? -1 : ts_start + duration);
        if (raw != 2)
            av_bprintf(buf, "Default,,0,0,0,,");
    }

    dlen = strcspn(dialog, "\n");
    dlen += dialog[dlen] == '\n';

    av_bprintf(buf, "%.*s", dlen, dialog);
    if (raw == 2)
        av_bprintf(buf, "\r\n");

    return dlen;
}