예제 #1
0
static int subviewer1_read_header(AVFormatContext *s)
{
    int delay = 0;
    AVPacket *sub = NULL;
    SubViewer1Context *subviewer1 = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);

    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 64, 1, 1);
    st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codecpar->codec_id   = AV_CODEC_ID_SUBVIEWER1;

    while (!avio_feof(s->pb)) {
        char line[4096];
        int len = ff_get_line(s->pb, line, sizeof(line));
        int hh, mm, ss;

        if (!len)
            break;

        if (!strncmp(line, "[DELAY]", 7)) {
            ff_get_line(s->pb, line, sizeof(line));
            sscanf(line, "%d", &delay);
        }

        if (sscanf(line, "[%d:%d:%d]", &hh, &mm, &ss) == 3) {
            const int64_t pos = avio_tell(s->pb);
            int64_t pts_start = hh*3600LL + mm*60LL + ss + delay;

            len = ff_get_line(s->pb, line, sizeof(line));
            line[strcspn(line, "\r\n")] = 0;
            if (!*line) {
                if (sub)
                    sub->duration = pts_start - sub->pts;
            } else {
                sub = ff_subtitles_queue_insert(&subviewer1->q, line, len, 0);
                if (!sub)
                    return AVERROR(ENOMEM);
                sub->pos = pos;
                sub->pts = pts_start;
                sub->duration = -1;
            }
        }
    }

    ff_subtitles_queue_finalize(s, &subviewer1->q);
    return 0;
}
예제 #2
0
static int pvf_read_header(AVFormatContext *s)
{
    char buffer[32];
    AVStream *st;
    int bps, channels, sample_rate;

    avio_skip(s->pb, 5);
    ff_get_line(s->pb, buffer, sizeof(buffer));
    if (sscanf(buffer, "%d %d %d",
               &channels,
               &sample_rate,
               &bps) != 3)
        return AVERROR_INVALIDDATA;

    if (channels <= 0 || bps <= 0 || sample_rate <= 0)
        return AVERROR_INVALIDDATA;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
    st->codec->channels    = channels;
    st->codec->sample_rate = sample_rate;
    st->codec->codec_id    = ff_get_pcm_codec_id(bps, 0, 1, 0xFFFF);
    st->codec->bits_per_coded_sample = bps;
    st->codec->block_align = bps * st->codec->channels / 8;

    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

    return 0;
}
예제 #3
0
static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
{
    int len = ff_get_line(s, buf, maxlen);
    while (len > 0 && isspace(buf[len - 1]))
        buf[--len] = '\0';
    return len;
}
static int microdvd_read_header(AVFormatContext *s)
{
    AVRational pts_info = (AVRational){ 2997, 125 };  /* default: 23.976 fps */
    MicroDVDContext *microdvd = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);
    int i, frame;
    double fps;
    char c;

    if (!st)
        return -1;
    for (i=0; i<FF_ARRAY_ELEMS(microdvd->lines); i++) {
        microdvd->pos[i] = avio_tell(s->pb);
        ff_get_line(s->pb, microdvd->lines[i], sizeof(microdvd->lines[i]));
        if ((sscanf(microdvd->lines[i], "{%d}{}%6lf",    &frame, &fps) == 2 ||
             sscanf(microdvd->lines[i], "{%d}{%*d}%6lf", &frame, &fps) == 2)
            && frame <= 1 && fps > 3 && fps < 100)
            pts_info = av_d2q(fps, 100000);
        if (sscanf(microdvd->lines[i], "{DEFAULT}{}%c", &c) == 1) {
            st->codec->extradata = av_strdup(microdvd->lines[i] + 11);
            st->codec->extradata_size = strlen(st->codec->extradata);
            i--;
        }
    }
    avpriv_set_pts_info(st, 64, pts_info.den, pts_info.num);
    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codec->codec_id   = CODEC_ID_MICRODVD;
    return 0;
}
예제 #5
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;
}
예제 #6
0
static int text_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    char buffer[2048], *ptr = buffer, *ptr2, *prt3;
    char data[1024] = {0};
    int64_t pos = avio_tell(s->pb);
    int res = AVERROR_EOF;

    do {
        ptr2 = ptr;
        ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
    } while(is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);

    do {
        prt3 = ptr;
        ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
    } while(is_eol(*prt3) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);

    


    if (buffer[0]) {
        int64_t pts;
        int duration;
        const char *end = ptr;


        ptr = buffer;

        pts = get_pts(&ptr, &duration, data);
        
        if (pts != AV_NOPTS_VALUE &&
            !(res = av_new_packet(pkt, strlen(data)))) {
            memcpy(pkt->data, data, strlen(data));
            memset(data, 0, 1024);
            pkt->flags |= AV_PKT_FLAG_KEY;
            pkt->pos = pos;
            pkt->pts = pkt->dts = pts;
            pkt->duration = duration;
        }

    }
    
    return res;
}
예제 #7
0
파일: mpjpegdec.c 프로젝트: JacyG/FFmpeg
static int get_line(AVIOContext *pb, char *line, int line_size)
{
    ff_get_line(pb, line, line_size);

    if (pb->error)
        return pb->error;

    if (pb->eof_reached)
        return AVERROR_EOF;

    trim_right(line);
    return 0;
}
예제 #8
0
static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
{
    int len = ff_get_line(s, buf, maxlen);
    while (len > 0 && isspace(buf[len - 1]))
        buf[--len] = '\0';
     if(len==0){
	 	if(url_feof(s))
			return AVERROR_EOF;
		if(url_ferror(s))
			return url_ferror(s);
    }	
    return len;
}
예제 #9
0
static int microdvd_read_header(AVFormatContext *s)
{
    AVRational pts_info = (AVRational){ 2997, 125 };  /* default: 23.976 fps */
    MicroDVDContext *microdvd = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);
    int i = 0;
    char line[MAX_LINESIZE];

    if (!st)
        return AVERROR(ENOMEM);

    while (!url_feof(s->pb)) {
        AVPacket *sub;
        int64_t pos = avio_tell(s->pb);
        int len = ff_get_line(s->pb, line, sizeof(line));

        if (!len)
            break;
        if (i < 3) {
            int frame;
            double fps;
            char c;

            i++;
            if ((sscanf(line, "{%d}{}%6lf",    &frame, &fps) == 2 ||
                 sscanf(line, "{%d}{%*d}%6lf", &frame, &fps) == 2)
                && frame <= 1 && fps > 3 && fps < 100)
                pts_info = av_d2q(fps, 100000);
            if (!st->codec->extradata && sscanf(line, "{DEFAULT}{}%c", &c) == 1) {
                st->codec->extradata = av_strdup(line + 11);
                if (!st->codec->extradata)
                    return AVERROR(ENOMEM);
                st->codec->extradata_size = strlen(st->codec->extradata) + 1;
                continue;
            }
        }
        sub = ff_subtitles_queue_insert(&microdvd->q, line, len, 0);
        if (!sub)
            return AVERROR(ENOMEM);
        sub->pos = pos;
        sub->pts = get_pts(sub->data);
        sub->duration = get_duration(sub->data);
    }
    ff_subtitles_queue_finalize(&microdvd->q);
    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_MICRODVD;
    return 0;
}
예제 #10
0
static int get_line(AVIOContext *pb, char *line, int line_size)
{
    int i = ff_get_line(pb, line, line_size);

    if (i > 1 && line[i - 2] == '\r')
        line[i - 2] = '\0';

    if (pb->error)
        return pb->error;

    if (pb->eof_reached)
        return AVERROR_EOF;

    return 0;
}
예제 #11
0
파일: srtdec.c 프로젝트: 0x0B501E7E/ffmpeg
static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    char buffer[2048], *ptr = buffer, *ptr2;
    int64_t pos = avio_tell(s->pb);
    int res = AVERROR_EOF;

    do {
        ptr2 = ptr;
        ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
    } while (!is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);

    if (buffer[0] && !(res = av_new_packet(pkt, ptr-buffer))) {
        memcpy(pkt->data, buffer, pkt->size);
        pkt->flags |= AV_PKT_FLAG_KEY;
        pkt->pos = pos;
        pkt->pts = pkt->dts = get_pts(pkt->data);
    }
    return res;
}
예제 #12
0
static int pjs_read_header(AVFormatContext *s)
{
    PJSContext *pjs = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);
    int res = 0;

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

    while (!avio_feof(s->pb)) {
        char line[4096];
        char *p = line;
        const int64_t pos = avio_tell(s->pb);
        int len = ff_get_line(s->pb, line, sizeof(line));
        int64_t pts_start;
        int duration;

        if (!len)
            break;

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

        pts_start = read_ts(&p, &duration);
        if (pts_start != AV_NOPTS_VALUE) {
            AVPacket *sub;

            p[strcspn(p, "\"")] = 0;
            sub = ff_subtitles_queue_insert(&pjs->q, p, strlen(p), 0);
            if (!sub)
                return AVERROR(ENOMEM);
            sub->pos = pos;
            sub->pts = pts_start;
            sub->duration = duration;
        }
    }

    ff_subtitles_queue_finalize(&pjs->q);
    return res;
}
예제 #13
0
파일: srtdec.c 프로젝트: ikoaoo/FFmpeg
static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    char buffer[2048], *ptr = buffer, *ptr2;
    int64_t pos = avio_tell(s->pb);
    int res = AVERROR_EOF;

    do {
        ptr2 = ptr;
        ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
    } while (!is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);

    if (buffer[0]) {
        int64_t pts;
        int duration;
        const char *end = ptr;
        int32_t x1 = -1, y1 = -1, x2 = -1, y2 = -1;

        ptr = buffer;
        pts = get_pts(&ptr, &duration, &x1, &y1, &x2, &y2);
        if (pts != AV_NOPTS_VALUE &&
            !(res = av_new_packet(pkt, end - ptr))) {
            memcpy(pkt->data, ptr, pkt->size);
            pkt->flags |= AV_PKT_FLAG_KEY;
            pkt->pos = pos;
            pkt->pts = pkt->dts = pts;
            pkt->duration = duration;
            if (x1 != -1) {
                uint8_t *p = av_packet_new_side_data(pkt, 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);
                }
            }
        }
    }
    return res;
}
예제 #14
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;
}
예제 #15
0
파일: microdvddec.c 프로젝트: 1c0n/xbmc
static int microdvd_read_header(AVFormatContext *s)
{
    AVRational pts_info = (AVRational){ 2997, 125 };  /* default: 23.976 fps */
    MicroDVDContext *microdvd = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);
    int i = 0;
    char line[MAX_LINESIZE];

    if (!st)
        return AVERROR(ENOMEM);

    while (!url_feof(s->pb)) {
        char *p = line;
        AVPacket *sub;
        int64_t pos = avio_tell(s->pb);
        int len = ff_get_line(s->pb, line, sizeof(line));

        if (!len)
            break;
        line[strcspn(line, "\r\n")] = 0;
        if (i++ < 3) {
            int frame;
            double fps;
            char c;

            if ((sscanf(line, "{%d}{}%6lf",    &frame, &fps) == 2 ||
                 sscanf(line, "{%d}{%*d}%6lf", &frame, &fps) == 2)
                && frame <= 1 && fps > 3 && fps < 100)
                pts_info = av_d2q(fps, 100000);
            if (!st->codec->extradata && sscanf(line, "{DEFAULT}{}%c", &c) == 1) {
                st->codec->extradata = av_strdup(line + 11);
                if (!st->codec->extradata)
                    return AVERROR(ENOMEM);
                st->codec->extradata_size = strlen(st->codec->extradata) + 1;
                continue;
            }
        }
#define SKIP_FRAME_ID                                       \
    p = strchr(p, '}');                                     \
    if (!p) {                                               \
        av_log(s, AV_LOG_WARNING, "Invalid event \"%s\""    \
               " at line %d\n", line, i);                   \
        continue;                                           \
    }                                                       \
    p++
        SKIP_FRAME_ID;
        SKIP_FRAME_ID;
        if (!*p)
            continue;
        sub = ff_subtitles_queue_insert(&microdvd->q, p, strlen(p), 0);
        if (!sub)
            return AVERROR(ENOMEM);
        sub->pos = pos;
        sub->pts = get_pts(line);
        sub->duration = get_duration(line);
    }
    ff_subtitles_queue_finalize(&microdvd->q);
    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_MICRODVD;
    return 0;
}
예제 #16
0
static int nist_read_header(AVFormatContext *s)
{
    char buffer[32], coding[32] = "pcm", format[32] = "01";
    int bps = 0, be = 0;
    int32_t header_size = -1;
    AVStream *st;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

    ff_get_line(s->pb, buffer, sizeof(buffer));
    ff_get_line(s->pb, buffer, sizeof(buffer));
    sscanf(buffer, "%"SCNd32, &header_size);
    if (header_size <= 0)
        return AVERROR_INVALIDDATA;

    while (!avio_feof(s->pb)) {
        ff_get_line(s->pb, buffer, sizeof(buffer));

        if (avio_tell(s->pb) >= header_size)
            return AVERROR_INVALIDDATA;

        if (!memcmp(buffer, "end_head", 8)) {
            if (!st->codec->bits_per_coded_sample)
                st->codec->bits_per_coded_sample = bps << 3;

            if (!av_strcasecmp(coding, "pcm")) {
                st->codec->codec_id = ff_get_pcm_codec_id(st->codec->bits_per_coded_sample,
                                                          0, be, 0xFFFF);
            } else if (!av_strcasecmp(coding, "alaw")) {
                st->codec->codec_id = AV_CODEC_ID_PCM_ALAW;
            } else if (!av_strcasecmp(coding, "ulaw") ||
                       !av_strcasecmp(coding, "mu-law")) {
                st->codec->codec_id = AV_CODEC_ID_PCM_MULAW;
            } else {
                avpriv_request_sample(s, "coding %s", coding);
            }

            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

            st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8;

            if (avio_tell(s->pb) > header_size)
                return AVERROR_INVALIDDATA;

            avio_skip(s->pb, header_size - avio_tell(s->pb));

            return 0;
        } else if (!memcmp(buffer, "channel_count", 13)) {
            sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->channels);
        } else if (!memcmp(buffer, "sample_byte_format", 18)) {
            sscanf(buffer, "%*s %*s %31s", format);

            if (!av_strcasecmp(format, "01")) {
                be = 0;
            } else if (!av_strcasecmp(format, "10")) {
                be = 1;
            } else if (av_strcasecmp(format, "1")) {
                avpriv_request_sample(s, "sample byte format %s", format);
                return AVERROR_PATCHWELCOME;
            }
        } else if (!memcmp(buffer, "sample_coding", 13)) {
            sscanf(buffer, "%*s %*s %31s", coding);
        } else if (!memcmp(buffer, "sample_count", 12)) {
            sscanf(buffer, "%*s %*s %"SCNd64, &st->duration);
        } else if (!memcmp(buffer, "sample_n_bytes", 14)) {
            sscanf(buffer, "%*s %*s %"SCNd32, &bps);
        } else if (!memcmp(buffer, "sample_rate", 11)) {
            sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->sample_rate);
        } else if (!memcmp(buffer, "sample_sig_bits", 15)) {
            sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->bits_per_coded_sample);
        } else {
            char key[32], value[32];
            if (sscanf(buffer, "%31s %*s %31s", key, value) == 3) {
                av_dict_set(&s->metadata, key, value, AV_DICT_APPEND);
            } else {
                av_log(s, AV_LOG_ERROR, "Failed to parse '%s' as metadata\n", buffer);
            }
        }
    }

    return AVERROR_EOF;
}
예제 #17
0
파일: jacosubdec.c 프로젝트: 26mansi/FFmpeg
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;
}
예제 #18
0
static int read_header(AVFormatContext *s)
{
    int i, len, header_remaining;
    ASSContext *ass = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *st;
    int allocated[2]= {0};
    uint8_t *p, **dst[2]= {0};
    int pos[2]= {0};

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

    header_remaining= INT_MAX;
    dst[0] = &st->codec->extradata;
    dst[1] = &ass->event_buffer;
    while(!pb->eof_reached) {
        uint8_t line[MAX_LINESIZE];

        len = ff_get_line(pb, line, sizeof(line));

        if(!memcmp(line, "[Events]", 8))
            header_remaining= 2;
        else if(line[0]=='[')
            header_remaining= INT_MAX;

        i= header_remaining==0;

        if(i && get_pts(line) == AV_NOPTS_VALUE)
            continue;

        p = av_fast_realloc(*(dst[i]), &allocated[i], pos[i]+MAX_LINESIZE);
        if(!p)
            goto fail;
        *(dst[i])= p;
        memcpy(p + pos[i], line, len+1);
        pos[i] += len;
        if(i) ass->event_count++;
        else  header_remaining--;
    }
    st->codec->extradata_size= pos[0];

    if(ass->event_count >= UINT_MAX / sizeof(*ass->event))
        goto fail;

    ass->event= av_malloc(ass->event_count * sizeof(*ass->event));
    p= ass->event_buffer;
    for(i=0; i<ass->event_count; i++) {
        ass->event[i]= p;
        while(*p && *p != '\n')
            p++;
        p++;
    }

    qsort(ass->event, ass->event_count, sizeof(*ass->event), (void*)event_cmp);

    return 0;

fail:
    read_close(s);

    return -1;
}
예제 #19
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;

    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   = CODEC_ID_JACOSUB;

    jacosub->timeres = 30;

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

    while (!url_feof(pb)) {
        int cmd_len;
        const char *p = line;
        int64_t pos = avio_tell(pb);

        ff_get_line(pb, line, sizeof(line));

        p = jss_skip_whitespace(p);

        /* queue timed line */
        if (merge_line || timed_line(p)) {
            SubEntry *subs, *sub;
            const int len = strlen(line);

            if (merge_line) {
                char *tmp;
                const int old_len = strlen(sub->line);

                sub = &subs[jacosub->nsub];
                tmp = av_realloc(sub->line, old_len + len + 1);
                if (!tmp)
                    return AVERROR(ENOMEM);
                sub->line = tmp;
                strcpy(sub->line + old_len, line);
            } else {
                subs = av_realloc(jacosub->subs,
                                  sizeof(*jacosub->subs) * (jacosub->nsub+1));
                if (!subs)
                    return AVERROR(ENOMEM);
                jacosub->subs = subs;
                sub = &subs[jacosub->nsub];
                sub->pos  = pos;
                sub->line = av_strdup(line);
                if (!sub->line)
                    return AVERROR(ENOMEM);
            }
            merge_line = len > 1 && !strcmp(&line[len - 2], "\\\n");
            if (!merge_line)
                jacosub->nsub++;
            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);
            av_bprintf(&header, "#T %s", p);
            break;
        }
    }

    /* general/essential directives in the extradata */
    av_bprint_finalize(&header, (char **)&st->codec->extradata);
    st->codec->extradata_size = header.len + 1;

    /* SHIFT and TIMERES affect the whole script so packet timing can only be
     * done in a second pass */
    for (i = 0; i < jacosub->nsub; i++) {
        SubEntry *sub = &jacosub->subs[i];
        read_ts(jacosub, sub->line, &sub->start, &sub->end);
    }
    qsort(jacosub->subs, jacosub->nsub, sizeof(*jacosub->subs), cmp_timed_sub);

    return 0;
}
static int microdvd_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    MicroDVDContext *microdvd = s->priv_data;
    char buffer[MAX_LINESIZE];
    int64_t pos = avio_tell(s->pb);
    int i, len = 0, res = AVERROR_EOF;

    // last packet has its duration set but couldn't be raised earlier
    if (microdvd->last_pkt_ready) {
        *pkt = microdvd->last_pkt;
        microdvd->last_pkt_ready = 0;
        return 0;
    }

    for (i=0; i<FF_ARRAY_ELEMS(microdvd->lines); i++) {
        if (microdvd->lines[i][0]) {
            strcpy(buffer, microdvd->lines[i]);
            pos = microdvd->pos[i];
            len = strlen(buffer);
            microdvd->lines[i][0] = 0;
            break;
        }
    }
    if (!len)
        len = ff_get_line(s->pb, buffer, sizeof(buffer));

    if (microdvd->last_pkt.duration == -1 && !buffer[0]) {
        // if the previous subtitle line had no duration, last until the end of
        // the presentation
        microdvd->last_pkt.duration = 0;
        *pkt = microdvd->last_pkt;
        pkt->duration = -1;
        res = 0;
    } else if (buffer[0] && !(res = av_new_packet(pkt, len))) {
        memcpy(pkt->data, buffer, len);
        pkt->flags |= AV_PKT_FLAG_KEY;
        pkt->pos = pos;
        pkt->pts = pkt->dts = get_pts(buffer);

        if (pkt->pts != AV_NOPTS_VALUE) {
            pkt->duration = get_duration(buffer);
            if (microdvd->last_pkt.duration == -1) {
                // previous packet wasn't raised because it was lacking the
                // duration info, so set its duration with the new packet pts
                // and raise it
                AVPacket tmp_pkt;

                tmp_pkt = microdvd->last_pkt;
                tmp_pkt.duration = pkt->pts - tmp_pkt.pts;
                microdvd->last_pkt = *pkt;
                microdvd->last_pkt_ready = pkt->duration != -1;
                *pkt = tmp_pkt;
            } else if (pkt->duration == -1) {
                // no packet without duration queued, and current one is
                // lacking the duration info, we need to parse another subtitle
                // event.
                microdvd->last_pkt = *pkt;
                res = AVERROR(EAGAIN);
            }
        }
    }
    return res;
}