Esempio n. 1
0
static int subviewer_decode_frame(AVCodecContext *avctx,
                                  void *data, int *got_sub_ptr, AVPacket *avpkt)
{
    char c;
    AVSubtitle *sub = data;
    const char *ptr = avpkt->data;
    AVBPrint buf;

    /* To be removed later */
    if (ptr && sscanf(ptr, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1) {
        av_log(avctx, AV_LOG_ERROR, "AVPacket is not clean (contains timing "
               "information). You need to upgrade your libavformat or "
               "sanitize your packet.\n");
        return AVERROR_INVALIDDATA;
    }

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
    // note: no need to rescale pts & duration since they are in the same
    // timebase as ASS (1/100)
    if (ptr && avpkt->size > 0 && !subviewer_event_to_ass(&buf, ptr))
        ff_ass_add_rect(sub, buf.str, avpkt->pts, avpkt->duration, 0);
    *got_sub_ptr = sub->num_rects > 0;
    av_bprint_finalize(&buf, NULL);
    return avpkt->size;
}
Esempio n. 2
0
static int jacosub_decode_frame(AVCodecContext *avctx,
                                void *data, int *got_sub_ptr, AVPacket *avpkt)
{
    AVSubtitle *sub = data;
    const char *ptr = avpkt->data;

    if (avpkt->size <= 0)
        goto end;

    if (*ptr) {
        AVBPrint buffer;
        char *dec_sub;

        // skip timers
        ptr = jss_skip_whitespace(ptr);
        ptr = strchr(ptr, ' '); if (!ptr) goto end; ptr++;
        ptr = strchr(ptr, ' '); if (!ptr) goto end; ptr++;

        av_bprint_init(&buffer, JSS_MAX_LINESIZE, JSS_MAX_LINESIZE);
        jacosub_to_ass(avctx, &buffer, ptr);
        av_bprint_finalize(&buffer, &dec_sub);
        ff_ass_add_rect(sub, dec_sub, avpkt->pts, avpkt->duration, 0);
        av_free(dec_sub);
    }

end:
    *got_sub_ptr = sub->num_rects > 0;
    return avpkt->size;
}
Esempio n. 3
0
File: ass.c Progetto: Tefnet/FFmpeg
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;
}
Esempio n. 4
0
static int mpl2_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_sub_ptr, AVPacket *avpkt)
{
    AVBPrint buf;
    AVSubtitle *sub = data;
    const char *ptr = avpkt->data;
#ifdef IDE_COMPILE
    AVRational tmp;
	int ts_start;
    int ts_duration;

    tmp.num = 1;
	tmp.den = 100;
	ts_start = av_rescale_q(avpkt->pts, avctx->time_base, tmp);
    ts_duration = avpkt->duration != -1 ? av_rescale_q(avpkt->duration, avctx->time_base, tmp) : -1;
#else
	const int ts_start     = av_rescale_q(avpkt->pts,      avctx->time_base, (AVRational){1,100});
    const int ts_duration  = avpkt->duration != -1 ?
                             av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1;
#endif

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
    if (ptr && avpkt->size > 0 && *ptr && !mpl2_event_to_ass(&buf, ptr)) {
        if (!av_bprint_is_complete(&buf)) {
            av_bprint_finalize(&buf, NULL);
            return AVERROR(ENOMEM);
        }
        ff_ass_add_rect(sub, buf.str, ts_start, ts_duration, 0);
    }
    *got_sub_ptr = sub->num_rects > 0;
    av_bprint_finalize(&buf, NULL);
    return avpkt->size;
}
Esempio n. 5
0
static int srt_decode_frame(AVCodecContext *avctx,
                            void *data, int *got_sub_ptr, AVPacket *avpkt)
{
    AVSubtitle *sub = data;
    AVBPrint buffer;
    int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
    int size, ret;
    const uint8_t *p = av_packet_get_side_data(avpkt, AV_PKT_DATA_SUBTITLE_POSITION, &size);
    FFASSDecoderContext *s = avctx->priv_data;

    if (p && size == 16) {
        x1 = AV_RL32(p     );
        y1 = AV_RL32(p +  4);
        x2 = AV_RL32(p +  8);
        y2 = AV_RL32(p + 12);
    }

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

    av_bprint_init(&buffer, 0, AV_BPRINT_SIZE_UNLIMITED);

    srt_to_ass(avctx, &buffer, avpkt->data, x1, y1, x2, y2);
    ret = ff_ass_add_rect(sub, buffer.str, s->readorder++, 0, NULL, NULL);
    av_bprint_finalize(&buffer, NULL);
    if (ret < 0)
        return ret;

    *got_sub_ptr = sub->num_rects > 0;
    return avpkt->size;
}
Esempio n. 6
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 ((ret = ff_ass_bprint_dialog(&buf, dialog, ts_start, duration, raw)) < 0)
        goto err;
    dlen = ret;
    if (!av_bprint_is_complete(&buf))
        goto errnomem;

    rects = av_realloc_array(sub->rects, (sub->num_rects+1), sizeof(*sub->rects));
    if (!rects)
        goto errnomem;
    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)
        goto err;
    sub->num_rects++;
    return dlen;

errnomem:
    ret = AVERROR(ENOMEM);
err:
    av_bprint_finalize(&buf, NULL);
    return ret;
}
Esempio n. 7
0
int av_dict_get_string(const AVDictionary *m, char **buffer,
                       const char key_val_sep, const char pairs_sep)
{
    AVDictionaryEntry *t = NULL;
    AVBPrint bprint;
    int cnt = 0;
    char special_chars[] = {pairs_sep, key_val_sep, '\0'};

    if (!buffer || pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
        pairs_sep == '\\' || key_val_sep == '\\')
        return AVERROR(EINVAL);

    if (!av_dict_count(m)) {
        *buffer = av_strdup("");
        return *buffer ? 0 : AVERROR(ENOMEM);
    }

    av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
    while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) {
        if (cnt++)
            av_bprint_append_data(&bprint, &pairs_sep, 1);
        av_bprint_escape(&bprint, t->key, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
        av_bprint_append_data(&bprint, &key_val_sep, 1);
        av_bprint_escape(&bprint, t->value, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
    }
    return av_bprint_finalize(&bprint, buffer);
}
static int srt_read_header(AVFormatContext *s)
{
    SRTContext *srt = s->priv_data;
    AVBPrint buf;
    AVStream *st = avformat_new_stream(s, NULL);
    int res = 0;
    FFTextReader tr;
    ff_text_init_avio(s, &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_SUBRIP;

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);

    while (!ff_text_eof(&tr)) {
        ff_subtitles_read_text_chunk(&tr, &buf);

        if (buf.len) {
            int64_t pos = ff_text_pos(&tr);
            int64_t pts;
            int duration;
            const char *ptr = buf.str;
            int32_t x1 = -1, y1 = -1, x2 = -1, y2 = -1;
            AVPacket *sub;

            pts = get_pts(&ptr, &duration, &x1, &y1, &x2, &y2);
            if (pts != AV_NOPTS_VALUE) {
                int len = buf.len - (ptr - buf.str);
                if (len <= 0)
                    continue;
                sub = ff_subtitles_queue_insert(&srt->q, ptr, len, 0);
                if (!sub) {
                    res = AVERROR(ENOMEM);
                    goto end;
                }
                sub->pos = pos;
                sub->pts = pts;
                sub->duration = duration;
                if (x1 != -1) {
                    uint8_t *p = av_packet_new_side_data(sub, AV_PKT_DATA_SUBTITLE_POSITION, 16);
                    if (p) {
                        AV_WL32(p,      x1);
                        AV_WL32(p +  4, y1);
                        AV_WL32(p +  8, x2);
                        AV_WL32(p + 12, y2);
                    }
                }
            }
        }
    }

    ff_subtitles_queue_finalize(&srt->q);

end:
    av_bprint_finalize(&buf, NULL);
    return res;
}
Esempio n. 9
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;
}
Esempio n. 10
0
static int mpsub_read_header(AVFormatContext *s)
{
    MPSubContext *mpsub = s->priv_data;
    AVStream *st;
    AVBPrint buf;
    AVRational pts_info = (AVRational){ 100, 1 }; // ts based by default
    int res = 0;
    float multiplier = 100.0;
    float current_pts = 0;

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);

    while (!url_feof(s->pb)) {
        char line[1024];
        float start, duration;
        int fps, len = ff_get_line(s->pb, line, sizeof(line));

        if (!len)
            break;

        line[strcspn(line, "\r\n")] = 0;

        if (sscanf(line, "FORMAT=%d", &fps) == 1 && fps > 3 && fps < 100) {
            /* frame based timing */
            pts_info = (AVRational){ fps, 1 };
            multiplier = 1.0;
        } else if (sscanf(line, "%f %f", &start, &duration) == 2) {
            AVPacket *sub;
            const int64_t pos = avio_tell(s->pb);

            ff_subtitles_read_chunk(s->pb, &buf);
            if (buf.len) {
                sub = ff_subtitles_queue_insert(&mpsub->q, buf.str, buf.len, 0);
                if (!sub) {
                    res = AVERROR(ENOMEM);
                    goto end;
                }
                sub->pts = (int64_t)(current_pts + start*multiplier);
                sub->duration = (int)(duration * multiplier);
                current_pts += (start + duration) * multiplier;
                sub->pos = pos;
            }
        }
    }

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 64, pts_info.den, pts_info.num);
    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codec->codec_id   = AV_CODEC_ID_TEXT;

    ff_subtitles_queue_finalize(&mpsub->q);

end:
    av_bprint_finalize(&buf, NULL);
    return res;
}
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;
}
Esempio n. 12
0
int main(void)
{
    AVBPrint b;
    char buf[256];
    struct tm testtime = { .tm_year = 100, .tm_mon = 11, .tm_mday = 20 };

    av_bprint_init(&b, 0, -1);
    bprint_pascal(&b, 5);
    printf("Short text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
    printf("%s\n", b.str);
    av_bprint_finalize(&b, NULL);

    av_bprint_init(&b, 0, -1);
    bprint_pascal(&b, 25);
    printf("Long text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
    av_bprint_finalize(&b, NULL);

    av_bprint_init(&b, 0, 2048);
    bprint_pascal(&b, 25);
    printf("Long text in limited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
    av_bprint_finalize(&b, NULL);

    av_bprint_init(&b, 0, 1);
    bprint_pascal(&b, 5);
    printf("Short text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);

    av_bprint_init(&b, 0, 1);
    bprint_pascal(&b, 25);
    printf("Long text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str)/8*8, b.len);
    /* Note that the size of the automatic buffer is arch-dependent. */

    av_bprint_init(&b, 0, 0);
    bprint_pascal(&b, 25);
    printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);

    av_bprint_init_for_buffer(&b, buf, sizeof(buf));
    bprint_pascal(&b, 25);
    printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(buf), b.len);

    av_bprint_init(&b, 0, -1);
    av_bprint_strftime(&b, "%Y-%m-%d", &testtime);
    printf("strftime full: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str);
    av_bprint_finalize(&b, NULL);

    av_bprint_init(&b, 0, 8);
    av_bprint_strftime(&b, "%Y-%m-%d", &testtime);
    printf("strftime truncated: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str);

    return 0;
}
Esempio n. 13
0
static av_cold int mov_text_encode_init(AVCodecContext *avctx)
{
    /*
     * For now, we'll use a fixed default style. When we add styling
     * support, this will be generated from the ASS style.
     */
    static const uint8_t text_sample_entry[] = {
        0x00, 0x00, 0x00, 0x00, // uint32_t displayFlags
        0x01,                   // int8_t horizontal-justification
        0xFF,                   // int8_t vertical-justification
        0x00, 0x00, 0x00, 0x00, // uint8_t background-color-rgba[4]
        // BoxRecord {
        0x00, 0x00,             // int16_t top
        0x00, 0x00,             // int16_t left
        0x00, 0x00,             // int16_t bottom
        0x00, 0x00,             // int16_t right
        // };
        // StyleRecord {
        0x00, 0x00,             // uint16_t startChar
        0x00, 0x00,             // uint16_t endChar
        0x00, 0x01,             // uint16_t font-ID
        0x00,                   // uint8_t face-style-flags
        0x12,                   // uint8_t font-size
        0xFF, 0xFF, 0xFF, 0xFF, // uint8_t text-color-rgba[4]
        // };
        // FontTableBox {
        0x00, 0x00, 0x00, 0x12, // uint32_t size
        'f', 't', 'a', 'b',     // uint8_t name[4]
        0x00, 0x01,             // uint16_t entry-count
        // FontRecord {
        0x00, 0x01,             // uint16_t font-ID
        0x05,                   // uint8_t font-name-length
        'S', 'e', 'r', 'i', 'f',// uint8_t font[font-name-length]
        // };
        // };
    };

    MovTextContext *s = avctx->priv_data;

    avctx->extradata_size = sizeof text_sample_entry;
    avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!avctx->extradata)
        return AVERROR(ENOMEM);

    av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED);

    memcpy(avctx->extradata, text_sample_entry, avctx->extradata_size);

    s->ass_ctx = ff_ass_split(avctx->subtitle_header);
    return s->ass_ctx ? 0 : AVERROR_INVALIDDATA;
}
Esempio n. 14
0
static int mov_text_decode_frame(AVCodecContext *avctx,
                                 void *data, int *got_sub_ptr, AVPacket *avpkt)
{
  AVSubtitle *sub = data;
  int ts_start, ts_end;
  AVBPrint buf;
  const char *ptr = avpkt->data;
  const char *end;

  if (!ptr || avpkt->size < 2)
    return AVERROR_INVALIDDATA;

  /*
   * A packet of size two with value zero is an empty subtitle
   * used to mark the end of the previous non-empty subtitle.
   * We can just drop them here as we have duration information
   * already. If the value is non-zero, then it's technically a
   * bad packet.
   */
  if (avpkt->size == 2)
    return AV_RB16(ptr) == 0 ? 0 : AVERROR_INVALIDDATA;

  /*
   * The first two bytes of the packet are the length of the text string
   * In complex cases, there are style descriptors appended to the string
   * so we can't just assume the packet size is the string size.
   */
  end = ptr + FFMIN(2 + AV_RB16(ptr), avpkt->size);
  ptr += 2;

  ts_start = av_rescale_q(avpkt->pts,
                          avctx->time_base,
                          (AVRational){1,100});
  ts_end   = av_rescale_q(avpkt->pts + avpkt->duration,
                          avctx->time_base,
                          (AVRational){1,100});

  // Note that the spec recommends lines be no longer than 2048 characters.
  av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
  text_to_ass(&buf, ptr, end);

  if (!av_bprint_is_complete(&buf))
    return AVERROR(ENOMEM);

  ff_ass_add_rect(sub, buf.str, ts_start, ts_end-ts_start, 0);
  *got_sub_ptr = sub->num_rects > 0;
  av_bprint_finalize(&buf, NULL);
  return avpkt->size;
}
Esempio n. 15
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);
}
Esempio n. 16
0
int av_escape(char **dst, const char *src, const char *special_chars,
              enum AVEscapeMode mode, int flags)
{
    AVBPrint dstbuf;

    av_bprint_init(&dstbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
    av_bprint_escape(&dstbuf, src, special_chars, mode, flags);

    if (!av_bprint_is_complete(&dstbuf)) {
        av_bprint_finalize(&dstbuf, NULL);
        return AVERROR(ENOMEM);
    } else {
        av_bprint_finalize(&dstbuf, dst);
        return dstbuf.len;
    }
}
Esempio n. 17
0
static int realtext_decode_frame(AVCodecContext *avctx,
                                 void *data, int *got_sub_ptr, AVPacket *avpkt)
{
    AVSubtitle *sub = data;
    const char *ptr = avpkt->data;
    AVBPrint buf;

    av_bprint_init(&buf, 0, 4096);
    // note: no need to rescale pts & duration since they are in the same
    // timebase as ASS (1/100)
    if (ptr && avpkt->size > 0 && !rt_event_to_ass(&buf, ptr))
        ff_ass_add_rect(sub, buf.str, avpkt->pts, avpkt->duration, 0);
    *got_sub_ptr = sub->num_rects > 0;
    av_bprint_finalize(&buf, NULL);
    return avpkt->size;
}
Esempio n. 18
0
static inline char *make_command_flags_str(AVBPrint *pbuf, int flags)
{
    static const char * const flag_strings[] = { "enter", "leave" };
    int i, is_first = 1;

    av_bprint_init(pbuf, 0, AV_BPRINT_SIZE_AUTOMATIC);
    for (i = 0; i < FF_ARRAY_ELEMS(flag_strings); i++) {
        if (flags & 1<<i) {
            if (!is_first)
                av_bprint_chars(pbuf, '+', 1);
            av_bprintf(pbuf, "%s", flag_strings[i]);
            is_first = 0;
        }
    }

    return pbuf->str;
}
Esempio n. 19
0
static int microdvd_decode_frame(AVCodecContext *avctx,
                                 void *data, int *got_sub_ptr, AVPacket *avpkt)
{
    AVSubtitle *sub = data;
    AVBPrint new_line;
    char *line = avpkt->data;
    char *end = avpkt->data + avpkt->size;
    FFASSDecoderContext *s = avctx->priv_data;
    struct microdvd_tag tags[sizeof(MICRODVD_TAGS) - 1] = {{0}};

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

    av_bprint_init(&new_line, 0, 2048);

    // 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++;
        }
    }
    if (new_line.len) {
        int ret = ff_ass_add_rect(sub, new_line.str, s->readorder++, 0, NULL, NULL);
        av_bprint_finalize(&new_line, NULL);
        if (ret < 0)
            return ret;
    }

    *got_sub_ptr = sub->num_rects > 0;
    return avpkt->size;
}
Esempio n. 20
0
static int subviewer_decode_frame(AVCodecContext *avctx,
                                  void *data, int *got_sub_ptr, AVPacket *avpkt)
{
    int ret = 0;
    AVSubtitle *sub = data;
    const char *ptr = avpkt->data;
    AVBPrint buf;

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
    // note: no need to rescale pts & duration since they are in the same
    // timebase as ASS (1/100)
    if (ptr && avpkt->size > 0 && !subviewer_event_to_ass(&buf, ptr))
        ret = ff_ass_add_rect_bprint(sub, &buf, avpkt->pts, avpkt->duration);
    av_bprint_finalize(&buf, NULL);
    if (ret < 0)
        return ret;
    *got_sub_ptr = sub->num_rects > 0;
    return avpkt->size;
}
Esempio n. 21
0
int init_filters(struct liveStream *ctx)
{
	int ret = 0;

	if (sem_init(&ctx->filter_lock, 0, 1) == -1)
	{
		av_log(NULL,AV_LOG_ERROR,"Unable to init filter locks\n");
	}

	av_bprint_init(&ctx->graph_desc, 0, 1);
	av_bprintf(&ctx->graph_desc, "[0]format=yuv420p,scale=%d:%d[bg]",STREAM_WIDTH,STREAM_HEIGHT);

	ret = configure_filter(ctx);
	if(ret <  0)
	{
		printf("unable to configure filter\n");
	}

	return 0;
}
Esempio n. 22
0
static int webvtt_decode_frame(AVCodecContext *avctx,
                               void *data, int *got_sub_ptr, AVPacket *avpkt)
{
    int ret = 0;
    AVSubtitle *sub = data;
    const char *ptr = avpkt->data;
    AVBPrint buf;

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
    if (ptr && avpkt->size > 0 && !webvtt_event_to_ass(&buf, ptr)) {
        int ts_start     = av_rescale_q(avpkt->pts, avctx->time_base, (AVRational){1,100});
        int ts_duration  = avpkt->duration != -1 ?
                           av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1;
        ret = ff_ass_add_rect_bprint(sub, &buf, ts_start, ts_duration, 0);
    }
    av_bprint_finalize(&buf, NULL);
    if (ret < 0)
        return ret;
    *got_sub_ptr = sub->num_rects > 0;
    return avpkt->size;
}
Esempio n. 23
0
EXPORT int duplicate_overlayed_stream(void *actx,int xpos, int ypos, int height, int width)
{
	int ret = 0;
	struct liveStream *ctx = (struct liveStream *)actx;
	if(!ctx)
		return -1;

	av_bprint_init(&ctx->graph_desc, 0, 1);
	av_bprintf(&ctx->graph_desc, "[0]format=yuv420p,scale=iw:ih,split[dup1][dup2];"
		"[dup2]scale=%d:%d[scaled_dup2];"
		"[dup1][scaled_dup2]overlay=%d:%d[bg]",
		width, height,
		xpos, ypos);
	ret = configure_filter(ctx);
	if(ret < 0)
	{
		av_log(NULL,AV_LOG_ERROR,"Unable to configure Filter\n");
		return ret;
	}
	return ret;
}
Esempio n. 24
0
static int srt_decode_frame(AVCodecContext *avctx,
                            void *data, int *got_sub_ptr, AVPacket *avpkt)
{
    AVSubtitle *sub = data;
    AVBPrint buffer;
    int ts_start, ts_end, x1 = -1, y1 = -1, x2 = -1, y2 = -1;
    int size, ret;
    const uint8_t *p = av_packet_get_side_data(avpkt, AV_PKT_DATA_SUBTITLE_POSITION, &size);

    if (p && size == 16) {
        x1 = AV_RL32(p     );
        y1 = AV_RL32(p +  4);
        x2 = AV_RL32(p +  8);
        y2 = AV_RL32(p + 12);
    }

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

    av_bprint_init(&buffer, 0, AV_BPRINT_SIZE_UNLIMITED);

        // TODO: reindent
            // Do final divide-by-10 outside rescale to force rounding down.
            ts_start = av_rescale_q(avpkt->pts,
                                    avctx->time_base,
                                    (AVRational){1,100});
            ts_end   = av_rescale_q(avpkt->pts + avpkt->duration,
                                    avctx->time_base,
                                    (AVRational){1,100});

    srt_to_ass(avctx, &buffer, avpkt->data, x1, y1, x2, y2);
    ret = ff_ass_add_rect_bprint(sub, &buffer, ts_start, ts_end-ts_start);
    av_bprint_finalize(&buffer, NULL);
    if (ret < 0)
        return ret;

    *got_sub_ptr = sub->num_rects > 0;
    return avpkt->size;
}
Esempio n. 25
0
int configure_input_filter(struct liveStream *ctx, long in_id, AVFilterInOut *in)
{
	AVFilter *buffer = avfilter_get_by_name("buffer");
	struct lsInput *input = NULL;
	AVStream *st;
	AVCodecContext *dec_ctx;
	AVRational tb;
	AVBPrint args;
	int ret = 0;
	char name[128];

	input = get_input_by_id(ctx->inputs,in_id);
	if(!input)
	{
		av_log(NULL,AV_LOG_ERROR,"Invalid input id for inputs list\n");
		return -1;
	}
	st = input->st;
	dec_ctx = input->dec_ctx;
	tb = st->time_base;

	av_bprint_init(&args, 0, 1);
	/* buffer video source: the decoded frames from the decoder will be inserted here. */
	av_bprintf(&args,"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
			dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
			tb.num, tb.den,
			dec_ctx->sample_aspect_ratio.num,
			dec_ctx->sample_aspect_ratio.den);
	snprintf(name, sizeof(name), "Input %ld", in_id);
	ret = avfilter_graph_create_filter(&input->in_filter, buffer, name, args.str, NULL, ctx->filter_graph);
	if(ret < 0)
		return ret;

	if ((ret = avfilter_link(input->in_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
		return ret;


	return ret;
}
Esempio n. 26
0
static const char *bsf_list_item_name(void *ctx)
{
    static const char *null_filter_name = "null";
    AVBSFContext *bsf_ctx = ctx;
    BSFListContext *lst = bsf_ctx->priv_data;

    if (!lst->nb_bsfs)
        return null_filter_name;

    if (!lst->item_name) {
        int i;
        AVBPrint bp;
        av_bprint_init(&bp, 16, 128);

        av_bprintf(&bp, "bsf_list(");
        for (i = 0; i < lst->nb_bsfs; i++)
            av_bprintf(&bp, i ? ",%s" : "%s", lst->bsfs[i]->filter->name);
        av_bprintf(&bp, ")");

        av_bprint_finalize(&bp, &lst->item_name);
    }

    return lst->item_name;
}
Esempio n. 27
0
static int subviewer_read_header(AVFormatContext *s)
{
    SubViewerContext *subviewer = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);
    AVBPrint header;
    int res = 0, new_event = 1;
    int64_t pts_start = AV_NOPTS_VALUE;
    int duration = -1;
    AVPacket *sub = 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_SUBVIEWER;

    av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);

    while (!avio_feof(s->pb)) {
        char line[2048];
        int64_t pos = 0;
        int len = ff_get_line(s->pb, line, sizeof(line));

        if (!len)
            break;

        line[strcspn(line, "\r\n")] = 0;

        if (line[0] == '[' && strncmp(line, "[br]", 4)) {

            /* ignore event style, XXX: add to side_data? */
            if (strstr(line, "[COLF]") || strstr(line, "[SIZE]") ||
                strstr(line, "[FONT]") || strstr(line, "[STYLE]"))
                continue;

            if (!st->codec->extradata) { // header not finalized yet
                av_bprintf(&header, "%s\n", line);
                if (!strncmp(line, "[END INFORMATION]", 17) || !strncmp(line, "[SUBTITLE]", 10)) {
                    /* end of header */
                    res = avpriv_bprint_to_extradata(st->codec, &header);
                    if (res < 0)
                        goto end;
                } else if (strncmp(line, "[INFORMATION]", 13)) {
                    /* assume file metadata at this point */
                    int i, j = 0;
                    char key[32], value[128];

                    for (i = 1; i < sizeof(key) - 1 && line[i] && line[i] != ']'; i++)
                        key[i - 1] = av_tolower(line[i]);
                    key[i - 1] = 0;

                    if (line[i] == ']')
                        i++;
                    while (line[i] == ' ')
                        i++;
                    while (j < sizeof(value) - 1 && line[i] && line[i] != ']')
                        value[j++] = line[i++];
                    value[j] = 0;

                    av_dict_set(&s->metadata, key, value, 0);
                }
            }
        } else if (read_ts(line, &pts_start, &duration) >= 0) {
            new_event = 1;
            pos = avio_tell(s->pb);
        } else if (*line) {
            if (!new_event) {
                sub = ff_subtitles_queue_insert(&subviewer->q, "\n", 1, 1);
                if (!sub) {
                    res = AVERROR(ENOMEM);
                    goto end;
                }
            }
            sub = ff_subtitles_queue_insert(&subviewer->q, line, strlen(line), !new_event);
            if (!sub) {
                res = AVERROR(ENOMEM);
                goto end;
            }
            if (new_event) {
                sub->pos = pos;
                sub->pts = pts_start;
                sub->duration = duration;
            }
            new_event = 0;
        }
    }

    ff_subtitles_queue_finalize(&subviewer->q);

end:
    av_bprint_finalize(&header, NULL);
    return res;
}
Esempio n. 28
0
static int mov_text_decode_frame(AVCodecContext *avctx,
                            void *data, int *got_sub_ptr, AVPacket *avpkt)
{
    AVSubtitle *sub = data;
    MovTextContext *m = avctx->priv_data;
    int ret, ts_start, ts_end;
    AVBPrint buf;
    char *ptr = avpkt->data;
    char *end;
    int text_length, tsmb_type, ret_tsmb;
    uint64_t tsmb_size;
    const uint8_t *tsmb;

    if (!ptr || avpkt->size < 2)
        return AVERROR_INVALIDDATA;

    /*
     * A packet of size two with value zero is an empty subtitle
     * used to mark the end of the previous non-empty subtitle.
     * We can just drop them here as we have duration information
     * already. If the value is non-zero, then it's technically a
     * bad packet.
     */
    if (avpkt->size == 2)
        return AV_RB16(ptr) == 0 ? 0 : AVERROR_INVALIDDATA;

    /*
     * The first two bytes of the packet are the length of the text string
     * In complex cases, there are style descriptors appended to the string
     * so we can't just assume the packet size is the string size.
     */
    text_length = AV_RB16(ptr);
    end = ptr + FFMIN(2 + text_length, avpkt->size);
    ptr += 2;

    ts_start = av_rescale_q(avpkt->pts,
                            avctx->time_base,
                            (AVRational){1,100});
    ts_end   = av_rescale_q(avpkt->pts + avpkt->duration,
                            avctx->time_base,
                            (AVRational){1,100});

    tsmb_size = 0;
    m->tracksize = 2 + text_length;
    m->style_entries = 0;
    m->box_flags = 0;
    m->count_s = 0;
    // Note that the spec recommends lines be no longer than 2048 characters.
    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
    if (text_length + 2 != avpkt->size) {
        while (m->tracksize + 8 <= avpkt->size) {
            // A box is a minimum of 8 bytes.
            tsmb = ptr + m->tracksize - 2;
            tsmb_size = AV_RB32(tsmb);
            tsmb += 4;
            tsmb_type = AV_RB32(tsmb);
            tsmb += 4;

            if (tsmb_size == 1) {
                if (m->tracksize + 16 > avpkt->size)
                    break;
                tsmb_size = AV_RB64(tsmb);
                tsmb += 8;
                m->size_var = 16;
            } else
                m->size_var = 8;
            //size_var is equal to 8 or 16 depending on the size of box

            if (m->tracksize + tsmb_size > avpkt->size)
                break;

            for (size_t i = 0; i < box_count; i++) {
                if (tsmb_type == box_types[i].type) {
                    if (m->tracksize + m->size_var + box_types[i].base_size > avpkt->size)
                        break;
                    ret_tsmb = box_types[i].decode(tsmb, m, avpkt);
                    if (ret_tsmb == -1)
                        break;
                }
            }
            m->tracksize = m->tracksize + tsmb_size;
        }
        text_to_ass(&buf, ptr, end, m);
        mov_text_cleanup(m);
    } else
        text_to_ass(&buf, ptr, end, m);

    ret = ff_ass_add_rect_bprint(sub, &buf, ts_start, ts_end - ts_start);
    av_bprint_finalize(&buf, NULL);
    if (ret < 0)
        return ret;
    *got_sub_ptr = sub->num_rects > 0;
    return avpkt->size;
}
Esempio n. 29
0
static av_cold int init(AVFilterContext *ctx)
{
    int err;
    DrawTextContext *s = ctx->priv;
    Glyph *glyph;

    if (!s->fontfile && !CONFIG_LIBFONTCONFIG) {
        av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
        return AVERROR(EINVAL);
    }

    if (s->textfile) {
        if (s->text) {
            av_log(ctx, AV_LOG_ERROR,
                   "Both text and text file provided. Please provide only one\n");
            return AVERROR(EINVAL);
        }
        if ((err = load_textfile(ctx)) < 0)
            return err;
    }

    if (s->reload && !s->textfile)
        av_log(ctx, AV_LOG_WARNING, "No file to reload\n");

    if (s->tc_opt_string) {
        int ret = av_timecode_init_from_string(&s->tc, s->tc_rate,
                                               s->tc_opt_string, ctx);
        if (ret < 0)
            return ret;
        if (s->tc24hmax)
            s->tc.flags |= AV_TIMECODE_FLAG_24HOURSMAX;
        if (!s->text)
            s->text = av_strdup("");
    }

    if (!s->text) {
        av_log(ctx, AV_LOG_ERROR,
               "Either text, a valid file or a timecode must be provided\n");
        return AVERROR(EINVAL);
    }

#if CONFIG_LIBFRIBIDI
    if (s->text_shaping)
        if ((err = shape_text(ctx)) < 0)
            return err;
#endif

    if ((err = FT_Init_FreeType(&(s->library)))) {
        av_log(ctx, AV_LOG_ERROR,
               "Could not load FreeType: %s\n", FT_ERRMSG(err));
        return AVERROR(EINVAL);
    }

    err = load_font(ctx);
    if (err)
        return err;
    if (!s->fontsize)
        s->fontsize = 16;
    if ((err = FT_Set_Pixel_Sizes(s->face, 0, s->fontsize))) {
        av_log(ctx, AV_LOG_ERROR, "Could not set font size to %d pixels: %s\n",
               s->fontsize, FT_ERRMSG(err));
        return AVERROR(EINVAL);
    }

    if (s->borderw) {
        if (FT_Stroker_New(s->library, &s->stroker)) {
            av_log(ctx, AV_LOG_ERROR, "Coult not init FT stroker\n");
            return AVERROR_EXTERNAL;
        }
        FT_Stroker_Set(s->stroker, s->borderw << 6, FT_STROKER_LINECAP_ROUND,
                       FT_STROKER_LINEJOIN_ROUND, 0);
    }

    s->use_kerning = FT_HAS_KERNING(s->face);

    /* load the fallback glyph with code 0 */
    load_glyph(ctx, NULL, 0);

    /* set the tabsize in pixels */
    if ((err = load_glyph(ctx, &glyph, ' ')) < 0) {
        av_log(ctx, AV_LOG_ERROR, "Could not set tabsize.\n");
        return err;
    }
    s->tabsize *= glyph->advance;

    if (s->exp_mode == EXP_STRFTIME &&
        (strchr(s->text, '%') || strchr(s->text, '\\')))
        av_log(ctx, AV_LOG_WARNING, "expansion=strftime is deprecated.\n");

    av_bprint_init(&s->expanded_text, 0, AV_BPRINT_SIZE_UNLIMITED);
    av_bprint_init(&s->expanded_fontcolor, 0, AV_BPRINT_SIZE_UNLIMITED);

    return 0;
}
Esempio n. 30
0
static int jacosub_read_header(AVFormatContext *s)
{
    AVBPrint header;
    AVIOContext *pb = s->pb;
    char line[JSS_MAX_LINESIZE];
    JACOsubContext *jacosub = s->priv_data;
    int shift_set = 0; // only the first shift matters
    int merge_line = 0;
    int i, ret;

    AVStream *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_JACOSUB;

    jacosub->timeres = 30;

    av_bprint_init(&header, 1024+FF_INPUT_BUFFER_PADDING_SIZE, 4096);

    while (!avio_feof(pb)) {
        int cmd_len;
        const char *p = line;
        int64_t pos = avio_tell(pb);
        int len = ff_get_line(pb, line, sizeof(line));

        p = jss_skip_whitespace(p);

        /* queue timed line */
        if (merge_line || timed_line(p)) {
            AVPacket *sub;

            sub = ff_subtitles_queue_insert(&jacosub->q, line, len, merge_line);
            if (!sub)
                return AVERROR(ENOMEM);
            sub->pos = pos;
            merge_line = len > 1 && !strcmp(&line[len - 2], "\\\n");
            continue;
        }

        /* skip all non-compiler commands and focus on the command */
        if (*p != '#')
            continue;
        p++;
        i = get_jss_cmd(p[0]);
        if (i == -1)
            continue;

        /* trim command + spaces */
        cmd_len = strlen(cmds[i]);
        if (av_strncasecmp(p, cmds[i], cmd_len) == 0)
            p += cmd_len;
        else
            p++;
        p = jss_skip_whitespace(p);

        /* handle commands which affect the whole script */
        switch (cmds[i][0]) {
        case 'S': // SHIFT command affect the whole script...
            if (!shift_set) {
                jacosub->shift = get_shift(jacosub->timeres, p);
                shift_set = 1;
            }
            av_bprintf(&header, "#S %s", p);
            break;
        case 'T': // ...but must be placed after TIMERES
            jacosub->timeres = strtol(p, NULL, 10);
            if (!jacosub->timeres)
                jacosub->timeres = 30;
            else
                av_bprintf(&header, "#T %s", p);
            break;
        }
    }

    /* general/essential directives in the extradata */
    ret = avpriv_bprint_to_extradata(st->codec, &header);
    if (ret < 0)
        return ret;

    /* SHIFT and TIMERES affect the whole script so packet timing can only be
     * done in a second pass */
    for (i = 0; i < jacosub->q.nb_subs; i++) {
        AVPacket *sub = &jacosub->q.subs[i];
        read_ts(jacosub, sub->data, &sub->pts, &sub->duration);
    }
    ff_subtitles_queue_finalize(&jacosub->q);

    return 0;
}