vector<int> retrieve(string s, string e, string gra) { int64_t stop = mm[gra]; int64_t sts = read_ts(s, stop); int64_t ets = read_ts(e, stop) + stop; vector<int> ans; for (auto it=idm.lower_bound(sts); it!=idm.end() && it->first<ets; ++it) { ans.push_back(it->second); } return ans; }
static int srt_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { AVSubtitle *sub = data; int ts_start, ts_end, x1 = -1, y1 = -1, x2 = -1, y2 = -1; char buffer[2048]; const char *ptr = avpkt->data; const char *end = avpkt->data + avpkt->size; if (avpkt->size <= 0) return avpkt->size; while (ptr < end && *ptr) { if (avctx->codec->id == CODEC_ID_SRT) { ptr = read_ts(ptr, &ts_start, &ts_end, &x1, &y1, &x2, &y2); if (!ptr) break; } else { // 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}); } ptr = srt_to_ass(avctx, buffer, buffer+sizeof(buffer), ptr, x1, y1, x2, y2); ff_ass_add_rect(sub, buffer, ts_start, ts_end-ts_start, 0); } *got_sub_ptr = sub->num_rects > 0; return avpkt->size; }
static int srt_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { AVSubtitle *sub = data; int ts_start, ts_end, x1 = -1, y1 = -1, x2 = -1, y2 = -1; char buffer[2048]; const char *ptr = avpkt->data; const char *end = avpkt->data + avpkt->size; if (avpkt->size <= 0) return avpkt->size; ff_ass_init(sub); while (ptr < end && *ptr) { ptr = read_ts(ptr, &ts_start, &ts_end, &x1, &y1, &x2, &y2); if (!ptr) break; ptr = srt_to_ass(avctx, buffer, buffer+sizeof(buffer), ptr, x1, y1, x2, y2); ff_ass_add_rect(sub, buffer, ts_start, ts_end, 0); } *got_sub_ptr = sub->num_rects > 0; return avpkt->size; }
static int srt_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { AVSubtitle *sub = data; int ts_start, ts_end, x1 = -1, y1 = -1, x2 = -1, y2 = -1; char buffer[2048]; const char *ptr = avpkt->data; const char *end = avpkt->data + avpkt->size; int size; 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; while (ptr < end && *ptr) { if (avctx->codec->id == AV_CODEC_ID_SRT) { ptr = read_ts(ptr, &ts_start, &ts_end, &x1, &y1, &x2, &y2); if (!ptr) break; } else { #ifdef IDE_COMPILE AVRational tmp; tmp.num = 1; tmp.den = 100; // Do final divide-by-10 outside rescale to force rounding down. ts_start = av_rescale_q(avpkt->pts, avctx->time_base, tmp); ts_end = av_rescale_q(avpkt->pts + avpkt->duration, avctx->time_base, tmp); #else // 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}); #endif } ptr = srt_to_ass(avctx, buffer, buffer+sizeof(buffer), ptr, x1, y1, x2, y2); ff_ass_add_rect(sub, buffer, ts_start, ts_end-ts_start, 0); } *got_sub_ptr = sub->num_rects > 0; return avpkt->size; }
CSubtitle* CSubtitleWebvttReader::ReadSubTitle(CSubtitleText *reader) { int64_t start, stop; CSubtitle *subtitle = new CSubtitle(); CSubtitleItem *item = NULL; for(;;) { wchar_t *text = reader->ReadLine(); if (text == NULL) break; start = read_ts(text); if (start == -1) continue; text = wcsstr(text, L"-->"); if (text == NULL) continue; stop = read_ts(text); if (stop == -1) continue; int32_t i = 0; if (item == NULL) item = subtitle->NewItem(); item->m_StartTime = start; item->m_Duration = stop - start; for(;;) { text = reader->ReadLine(); if (text == NULL) break; if (*text == NULL) break; item->AddLine(text); } if (item->m_Count) { item = NULL; } } if (item) subtitle->DeleteItem(item->m_index); if (subtitle->m_Count) return subtitle; delete subtitle; return NULL; }
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; }
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; }
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; }
static int realtext_read_header(AVFormatContext *s) { RealTextContext *rt = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); AVBPrint buf; char c = 0; int res = 0, duration = read_ts("60"); // default duration is 60 seconds 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_REALTEXT; av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); while (!url_feof(s->pb)) { AVPacket *sub; const int64_t pos = avio_tell(s->pb) - (c != 0); int n = ff_smil_extract_next_chunk(s->pb, &buf, &c); if (n == 0) break; if (!av_strncasecmp(buf.str, "<window", 7)) { /* save header to extradata */ const char *p = ff_smil_get_attr_ptr(buf.str, "duration"); if (p) duration = read_ts(p); st->codec->extradata = av_strdup(buf.str); if (!st->codec->extradata) { res = AVERROR(ENOMEM); goto end; } st->codec->extradata_size = buf.len + 1; } else { /* if we just read a <time> tag, introduce a new event, otherwise merge * with the previous one */ int merge = !av_strncasecmp(buf.str, "<time", 5) ? 0 : 1; sub = ff_subtitles_queue_insert(&rt->q, buf.str, buf.len, merge); if (!sub) { res = AVERROR(ENOMEM); goto end; } if (!merge) { const char *begin = ff_smil_get_attr_ptr(buf.str, "begin"); const char *end = ff_smil_get_attr_ptr(buf.str, "end"); sub->pos = pos; sub->pts = begin ? read_ts(begin) : 0; sub->duration = end ? (read_ts(end) - sub->pts) : duration; } } av_bprint_clear(&buf); } ff_subtitles_queue_finalize(&rt->q); end: av_bprint_finalize(&buf, NULL); return res; }
static int lrc_read_header(AVFormatContext *s) { LRCContext *lrc = s->priv_data; AVBPrint line; AVStream *st; st = avformat_new_stream(s, NULL); if(!st) { return AVERROR(ENOMEM); } avpriv_set_pts_info(st, 64, 1, 1000); lrc->ts_offset = 0; st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codec->codec_id = AV_CODEC_ID_TEXT; av_bprint_init(&line, 0, AV_BPRINT_SIZE_UNLIMITED); while(!url_feof(s->pb)) { int64_t pos = read_line(&line, s->pb); int64_t header_offset = find_header(line.str); if(header_offset >= 0) { char *comma_offset = strchr(line.str, ':'); if(comma_offset) { char *right_bracket_offset = strchr(line.str, ']'); if(!right_bracket_offset) { continue; } *right_bracket_offset = *comma_offset = '\0'; if(strcmp(line.str + 1, "offset") || sscanf(comma_offset + 1, "%"SCNd64, &lrc->ts_offset) != 1) { av_dict_set(&s->metadata, line.str + 1, comma_offset + 1, 0); } *comma_offset = ':'; *right_bracket_offset = ']'; } } else { AVPacket *sub; int64_t ts_start = AV_NOPTS_VALUE; int64_t ts_stroffset = 0; int64_t ts_stroffset_incr = 0; int64_t ts_strlength = count_ts(line.str); while((ts_stroffset_incr = read_ts(line.str + ts_stroffset, &ts_start)) != 0) { ts_stroffset += ts_stroffset_incr; sub = ff_subtitles_queue_insert(&lrc->q, line.str + ts_strlength, line.len - ts_strlength, 0); if(!sub) { return AVERROR(ENOMEM); } sub->pos = pos; sub->pts = ts_start - lrc->ts_offset; sub->duration = -1; } } } ff_subtitles_queue_finalize(&lrc->q); ff_metadata_conv_ctx(s, NULL, ff_lrc_metadata_conv); return 0; }
CSubtitle* CSubtitleRealTextReader::ReadSubTitle(CSubtitleText *reader) { wchar_t Buffer[MAX_SUBTITLE_LINE_SIZE]; CSubtitle *subtitle = new CSubtitle(); for(;;) { wchar_t *line = reader->ReadLine(); if (line == NULL) break; line = StrIStr(line, L"<time "); if (line == NULL) continue; line += 6; wchar_t *begin = StrIStr(line, L"Begin=\""); if (begin == NULL) continue; int64_t start = read_ts(begin); wchar_t *end = StrIStr(line, L"end=\""); int64_t stop = end ? read_ts(end) : 0; line = StrIStr(line, L">"); int32_t skip = 0; int32_t i = 0; for(wchar_t *p = line; *p; p++) { if(*p == '>') { skip = 0; continue; } if(*p == '<') { skip = 1; continue; } if(skip) { continue; } if (i < MAX_SUBTITLE_LINE_SIZE - 1) { Buffer[i] = *p; i++; } } if (i) { Buffer[i] = 0; CSubtitleItem *item = subtitle->NewItem(); item->AddLine(Buffer); item->m_StartTime = start; item->m_Duration = stop; } } if (subtitle->m_Count) return subtitle; delete subtitle; return NULL; }
static int ass_read_header(AVFormatContext *s) { ASSContext *ass = s->priv_data; AVBPrint header, line; int header_remaining, res = 0; AVStream *st; 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_SSA; header_remaining = INT_MAX; av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED); av_bprint_init(&line, 0, AV_BPRINT_SIZE_UNLIMITED); for (;;) { int64_t pos = get_line(&line, s->pb); if (!line.str[0]) // EOF break; if (!memcmp(line.str, "[Events]", 8)) header_remaining = 2; else if (line.str[0] == '[') header_remaining = INT_MAX; if (header_remaining) { av_bprintf(&header, "%s", line.str); header_remaining--; } else { int64_t ts_start = AV_NOPTS_VALUE; int duration = -1; AVPacket *sub; if (read_ts(line.str, &ts_start, &duration) < 0) continue; sub = ff_subtitles_queue_insert(&ass->q, line.str, line.len, 0); if (!sub) { res = AVERROR(ENOMEM); goto end; } sub->pos = pos; sub->pts = ts_start; sub->duration = duration; } } av_bprint_finalize(&line, NULL); res = avpriv_bprint_to_extradata(st->codec, &header); if (res < 0) goto end; ff_subtitles_queue_finalize(&ass->q); end: return res; }
static void ts_scan(cyg_addrword_t param) { short lastX, lastY; short x, y; struct _event *ev; bool pen_down; diag_printf("Touch Screen thread started\n"); // Discard the first sample - it's always 0 x = read_ts(ADS_MEASURE_X); y = read_ts(ADS_MEASURE_Y); lastX = lastY = -1; pen_down = false; while (true) { cyg_thread_delay(SCAN_DELAY); if ((*(volatile cyg_uint32 *)AAEC_PFDR & TS_INT) == 0) { // Pen is down x = read_ts(ADS_MEASURE_X); y = read_ts(ADS_MEASURE_Y); // diag_printf("X = %x, Y = %x\n", x, y); if ((x < X_THRESHOLD) || (y < Y_THRESHOLD)) { // Ignore 'bad' samples continue; } lastX = x; lastY = y; pen_down = true; } else { if (pen_down) { // Capture first 'up' event pen_down = false; x = lastX; y = lastY; } else { continue; // Nothing new to report } } if (num_events < MAX_EVENTS) { num_events++; ev = &_events[_event_put++]; if (_event_put == MAX_EVENTS) { _event_put = 0; } ev->button_state = pen_down ? 0x04 : 0x00; ev->xPos = x; ev->yPos = y; if (ts_select_active) { ts_select_active = false; cyg_selwakeup(&ts_select_info); } } #ifdef DEBUG_RAW_EVENTS memcpy(&_ts_buf[_ts_buf_ptr], pkt->data, 8); _ts_buf_ptr += 8; if (_ts_buf_ptr == 512) { diag_printf("TS handler\n"); diag_dump_buf(_ts_buf, 512); _ts_buf_ptr = 0; } #endif } }
static int webvtt_read_header(AVFormatContext *s) { WebVTTContext *webvtt = s->priv_data; AVBPrint header, cue; int res = 0; AVStream *st = avformat_new_stream(s, NULL); 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_WEBVTT; av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED); av_bprint_init(&cue, 0, AV_BPRINT_SIZE_UNLIMITED); for (;;) { int i; int64_t pos; AVPacket *sub; const char *p, *identifier; //const char *settings = NULL; int64_t ts_start, ts_end; ff_subtitles_read_chunk(s->pb, &cue); if (!cue.len) break; p = identifier = cue.str; pos = avio_tell(s->pb); /* ignore header chunk */ if (!strncmp(p, "\xEF\xBB\xBFWEBVTT", 9) || !strncmp(p, "WEBVTT", 6)) continue; /* optional cue identifier (can be a number like in SRT or some kind of * chaptering id), silently skip it */ for (i = 0; p[i] && p[i] != '\n'; i++) { if (!strncmp(p + i, "-->", 3)) { identifier = NULL; break; } } if (identifier) p += strcspn(p, "\n"); /* cue timestamps */ if ((ts_start = read_ts(p)) == AV_NOPTS_VALUE) break; if (!(p = strstr(p, "-->"))) break; p += 3; do p++; while (*p == ' ' || *p == '\t'); if ((ts_end = read_ts(p)) == AV_NOPTS_VALUE) break; /* optional cue settings, TODO: store in side_data */ p += strcspn(p, "\n\t "); while (*p == '\t' || *p == ' ') p++; if (*p != '\n') { //settings = p; p += strcspn(p, "\n"); } if (*p == '\n') p++; /* create packet */ sub = ff_subtitles_queue_insert(&webvtt->q, p, strlen(p), 0); if (!sub) { res = AVERROR(ENOMEM); goto end; } sub->pos = pos; sub->pts = ts_start; sub->duration = ts_end - ts_start; } ff_subtitles_queue_finalize(&webvtt->q); end: av_bprint_finalize(&cue, NULL); av_bprint_finalize(&header, NULL); return res; }
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; }
void put(int id, string timestamp) { int64_t ts = read_ts(timestamp, 1LL); idm[ts] = id; }