New upstream version 18.0.1+dfsg1
This commit is contained in:
parent
6efda2859e
commit
a03541a0f8
763 changed files with 69366 additions and 2632 deletions
194
deps/libcaption/src/srt.c
vendored
Normal file
194
deps/libcaption/src/srt.c
vendored
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/**********************************************************************************************/
|
||||
/* The MIT License */
|
||||
/* */
|
||||
/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining a copy */
|
||||
/* of this software and associated documentation files (the "Software"), to deal */
|
||||
/* in the Software without restriction, including without limitation the rights */
|
||||
/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
|
||||
/* copies of the Software, and to permit persons to whom the Software is */
|
||||
/* furnished to do so, subject to the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be included in */
|
||||
/* all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN */
|
||||
/* THE SOFTWARE. */
|
||||
/**********************************************************************************************/
|
||||
#include "srt.h"
|
||||
#include "utf8.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
srt_t* srt_new (const utf8_char_t* data, size_t size, double timestamp, srt_t* prev, srt_t** head)
|
||||
{
|
||||
srt_t* srt = malloc (sizeof (srt_t)+size+1);
|
||||
srt->next = 0;
|
||||
srt->duration = 0;
|
||||
srt->aloc = size;
|
||||
srt->timestamp = timestamp;
|
||||
utf8_char_t* dest = (utf8_char_t*) srt_data (srt);
|
||||
|
||||
if (prev) {
|
||||
prev->next = srt;
|
||||
prev->duration = timestamp - prev->timestamp;
|
||||
}
|
||||
|
||||
if (head && 0 == (*head)) {
|
||||
(*head) = srt;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
memcpy (dest, data, size);
|
||||
} else {
|
||||
memset (dest, 0, size);
|
||||
}
|
||||
|
||||
dest[size] = '\0';
|
||||
return srt;
|
||||
}
|
||||
|
||||
srt_t* srt_free_head (srt_t* head)
|
||||
{
|
||||
srt_t* next = head->next;
|
||||
free (head);
|
||||
return next;
|
||||
}
|
||||
|
||||
void srt_free (srt_t* srt)
|
||||
{
|
||||
while (srt) {
|
||||
srt = srt_free_head (srt);
|
||||
}
|
||||
}
|
||||
|
||||
#define SRTTIME2SECONDS(HH,MM,SS,MS) ((HH*3600.0) + (MM*60.0) + SS + (MS/1000.0))
|
||||
srt_t* srt_parse (const utf8_char_t* data, size_t size)
|
||||
{
|
||||
int counter;
|
||||
srt_t* head = 0, *prev = 0;
|
||||
double str_pts = 0, end_pts = 0;
|
||||
size_t line_length = 0, trimmed_length = 0;
|
||||
int hh1, hh2, mm1, mm2, ss1, ss2, ms1, ms2;
|
||||
|
||||
for (;;) {
|
||||
line_length = 0;
|
||||
|
||||
do {
|
||||
data += line_length;
|
||||
size -= line_length;
|
||||
line_length = utf8_line_length (data);
|
||||
trimmed_length = utf8_trimmed_length (data,line_length);
|
||||
// Skip empty lines
|
||||
} while (0 < line_length && 0 == trimmed_length);
|
||||
|
||||
// linelength cant be zero before EOF
|
||||
if (0 == line_length) {
|
||||
break;
|
||||
}
|
||||
|
||||
counter = atoi (data);
|
||||
// printf ("counter (%d): '%.*s'\n", line_length, (int) line_length, data);
|
||||
data += line_length;
|
||||
size -= line_length;
|
||||
|
||||
line_length = utf8_line_length (data);
|
||||
// printf ("time (%d): '%.*s'\n", line_length, (int) line_length, data);
|
||||
|
||||
{
|
||||
if (8 == sscanf (data, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d", &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2)) {
|
||||
str_pts = SRTTIME2SECONDS (hh1, mm1, ss1, ms1);
|
||||
end_pts = SRTTIME2SECONDS (hh2, mm2, ss2, ms2);
|
||||
}
|
||||
|
||||
data += line_length;
|
||||
size -= line_length;
|
||||
}
|
||||
|
||||
// Caption text starts here
|
||||
const utf8_char_t* text = data;
|
||||
size_t text_size = 0;
|
||||
// printf ("time: '(%f --> %f)\n",srt.srt_time, srt.end_time);
|
||||
|
||||
do {
|
||||
line_length = utf8_line_length (data);
|
||||
trimmed_length = utf8_trimmed_length (data,line_length);
|
||||
// printf ("cap (%d): '%.*s'\n", line_length, (int) trimmed_length, data);
|
||||
data += line_length;
|
||||
size -= line_length;
|
||||
text_size += line_length;
|
||||
} while (trimmed_length);
|
||||
|
||||
// should we trim here?
|
||||
srt_t* srt = srt_new (text,text_size,str_pts,prev,&head);
|
||||
srt->duration = end_pts - str_pts;
|
||||
prev = srt;
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
int srt_to_caption_frame (srt_t* srt, caption_frame_t* frame)
|
||||
{
|
||||
const char* data = srt_data (srt);
|
||||
return caption_frame_from_text (frame,data);
|
||||
}
|
||||
|
||||
srt_t* srt_from_caption_frame (caption_frame_t* frame, srt_t* prev, srt_t** head)
|
||||
{
|
||||
// CRLF per row, plus an extra at the end
|
||||
srt_t* srt = srt_new (0, 2+CAPTION_FRAME_TEXT_BYTES, frame->timestamp, prev, head);
|
||||
utf8_char_t* data = srt_data (srt);
|
||||
|
||||
caption_frame_to_text (frame,data);
|
||||
// srt requires an extra new line
|
||||
strcat ( (char*) data,"\r\n");
|
||||
|
||||
return srt;
|
||||
}
|
||||
|
||||
static inline void _crack_time (double tt, int* hh, int* mm, int* ss, int* ms)
|
||||
{
|
||||
(*ms) = (int) ((int64_t) (tt * 1000.0) % 1000);
|
||||
(*ss) = (int) ((int64_t) (tt) % 60);
|
||||
(*mm) = (int) ((int64_t) (tt / (60.0)) % 60);
|
||||
(*hh) = (int) ((int64_t) (tt / (60.0*60.0)));
|
||||
}
|
||||
|
||||
static void _dump (srt_t* head, char type)
|
||||
{
|
||||
int i;
|
||||
srt_t* srt;
|
||||
|
||||
if ('v' == type) {
|
||||
printf ("WEBVTT\r\n");
|
||||
}
|
||||
|
||||
for (srt = head, i = 1; srt; srt=srt_next (srt), ++i) {
|
||||
int hh1, hh2, mm1, mm2, ss1, ss2, ms1, ms2;
|
||||
_crack_time (srt->timestamp, &hh1, &mm1, &ss1, &ms1);
|
||||
_crack_time (srt->timestamp + srt->duration, &hh2, &mm2, &ss2, &ms2);
|
||||
|
||||
if ('s' == type) {
|
||||
printf ("%02d\r\n%d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n%s\r\n", i,
|
||||
hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2, srt_data (srt));
|
||||
}
|
||||
|
||||
else if ('v' == type) {
|
||||
printf ("%d:%02d:%02d.%03d --> %02d:%02d:%02d.%03d\r\n%s\r\n",
|
||||
hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2, srt_data (srt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void srt_dump (srt_t* head) { _dump (head,'s'); }
|
||||
void vtt_dump (srt_t* head) { _dump (head,'v'); }
|
||||
Loading…
Add table
Add a link
Reference in a new issue