hmmlib: multiple annotators/co-hosts/guests support

This commit is contained in:
Alex Baines 2017-06-20 20:54:26 +01:00
parent 74f667c5c6
commit f23eceace0
3 changed files with 53 additions and 93 deletions

View File

@ -15,9 +15,15 @@ typedef struct {
char* title; char* title;
char* vod_platform; char* vod_platform;
char* id; char* id;
char* co_host;
char* guest; char** co_hosts;
char* annotator; size_t co_host_count;
char** guests;
size_t guest_count;
char** annotators;
size_t annotator_count;
} HMML_VideoMetaData; } HMML_VideoMetaData;
typedef struct { typedef struct {

View File

@ -15,7 +15,7 @@
HMML_Error error; HMML_Error error;
char** attr; void* attr;
int mnext; int mnext;
bool first; bool first;
} HMML_ParseState; } HMML_ParseState;
@ -88,6 +88,7 @@ RB \]
%s VIDEO %s VIDEO
%s V_ATTR %s V_ATTR
%s V2_ATTR
%s ANNOTATION %s ANNOTATION
%s TEXT_START %s TEXT_START
%s TEXT %s TEXT
@ -116,17 +117,22 @@ RB \]
<VIDEO>title{S}= { yyextra->attr = V_(title); BEGIN(V_ATTR); } <VIDEO>title{S}= { yyextra->attr = V_(title); BEGIN(V_ATTR); }
<VIDEO>vod_platform{S}= { yyextra->attr = V_(vod_platform); BEGIN(V_ATTR); } <VIDEO>vod_platform{S}= { yyextra->attr = V_(vod_platform); BEGIN(V_ATTR); }
<VIDEO>id{S}= { yyextra->attr = V_(id); BEGIN(V_ATTR); } <VIDEO>id{S}= { yyextra->attr = V_(id); BEGIN(V_ATTR); }
<VIDEO>co_host{S}= { yyextra->attr = V_(co_host); BEGIN(V_ATTR); } <VIDEO>co\-host{S}= { yyextra->attr = V_(co_hosts); BEGIN(V2_ATTR); }
<VIDEO>guest{S}= { yyextra->attr = V_(guest); BEGIN(V_ATTR); } <VIDEO>guest{S}= { yyextra->attr = V_(guests); BEGIN(V2_ATTR); }
<VIDEO>annotator{S}= { yyextra->attr = V_(annotator); BEGIN(V_ATTR); } <VIDEO>annotator{S}= { yyextra->attr = V_(annotators); BEGIN(V2_ATTR); }
<VIDEO>\] { BEGIN(ANNOTATION); }; <VIDEO>\] { BEGIN(ANNOTATION); };
<VIDEO>. { HMML_ERR("Invalid char '%s' in video tag.", yytext); } <VIDEO>. { HMML_ERR("Invalid char '%s' in video tag.", yytext); }
<V_ATTR>{S} { BEGIN(VIDEO); } <V_ATTR>{S} { BEGIN(VIDEO); }
<V_ATTR>{ATTR_SIMPLE} { *yyextra->attr = strndup(yytext , yyleng ); BEGIN(VIDEO); } <V_ATTR>{ATTR_SIMPLE} { *(char**)yyextra->attr = strndup(yytext , yyleng ); BEGIN(VIDEO); }
<V_ATTR>{ATTR_QUOTED} { *yyextra->attr = UNQUOTE(strndup(yytext+1, yyleng-2)); BEGIN(VIDEO); } <V_ATTR>{ATTR_QUOTED} { *(char**)yyextra->attr = UNQUOTE(strndup(yytext+1, yyleng-2)); BEGIN(VIDEO); }
<V_ATTR>\] { yyless(0); BEGIN(VIDEO); } <V_ATTR>\] { yyless(0); BEGIN(VIDEO); }
<V2_ATTR>{S} { BEGIN(VIDEO); }
<V2_ATTR>{ATTR_SIMPLE} { sb_push(*(char***)yyextra->attr, strndup(yytext , yyleng )); BEGIN(VIDEO); }
<V2_ATTR>{ATTR_QUOTED} { sb_push(*(char***)yyextra->attr, UNQUOTE(strndup(yytext+1, yyleng-2))); BEGIN(VIDEO); }
<V2_ATTR>\] { yyless(0); BEGIN(VIDEO); }
<ANNOTATION>{TIMECODE}{LB}@ { NEWANNO(); yyextra->an.time = strndup(yytext+1, yyleng-4); BEGIN(AUTHOR); } <ANNOTATION>{TIMECODE}{LB}@ { NEWANNO(); yyextra->an.time = strndup(yytext+1, yyleng-4); BEGIN(AUTHOR); }
<ANNOTATION>{TIMECODE} { NEWANNO(); yyextra->an.time = strndup(yytext+1, yyleng-2); BEGIN(TEXT_START); } <ANNOTATION>{TIMECODE} { NEWANNO(); yyextra->an.time = strndup(yytext+1, yyleng-2); BEGIN(TEXT_START); }
<ANNOTATION>{BAD_TIMECODE} { HMML_ERR("Timecode %s out of range.", yytext); } <ANNOTATION>{BAD_TIMECODE} { HMML_ERR("Timecode %s out of range.", yytext); }
@ -186,8 +192,8 @@ RB \]
<REF>. { HMML_ERR("Unexpected item in ref: %s", yytext); } <REF>. { HMML_ERR("Unexpected item in ref: %s", yytext); }
<R_ATTR>{S} <R_ATTR>{S}
<R_ATTR>{ATTR_SIMPLE} { *yyextra->attr = strndup(yytext , yyleng ); BEGIN(REF); } <R_ATTR>{ATTR_SIMPLE} { *(char**)yyextra->attr = strndup(yytext, yyleng); BEGIN(REF); }
<R_ATTR>{ATTR_QUOTED} { *yyextra->attr = UNQUOTE(strndup(yytext+1, yyleng-2)); BEGIN(REF); } <R_ATTR>{ATTR_QUOTED} { *(char**)yyextra->attr = UNQUOTE(strndup(yytext+1, yyleng-2)); BEGIN(REF); }
<AFTERTEXT,ANNOTATION>\[\/video\] { NEWANNO(); return 0; } <AFTERTEXT,ANNOTATION>\[\/video\] { NEWANNO(); return 0; }
@ -235,6 +241,10 @@ HMML_Output hmml_parse_file(FILE* f){
memcpy(&output.metadata, &state.meta, sizeof(HMML_VideoMetaData)); memcpy(&output.metadata, &state.meta, sizeof(HMML_VideoMetaData));
output.metadata.co_host_count = sb_count(output.metadata.co_hosts);
output.metadata.guest_count = sb_count(output.metadata.guests);
output.metadata.annotator_count = sb_count(output.metadata.annotators);
output.annotations = state.annos; output.annotations = state.annos;
output.annotation_count = sb_count(state.annos); output.annotation_count = sb_count(state.annos);
@ -277,15 +287,15 @@ static void _hmml_free_anno(HMML_Annotation* a){
free(a->author); free(a->author);
sb_free(a->text); sb_free(a->text);
for(size_t j = 0; j < sb_count(a->references); ++j){ sb_each(r, a->references){
_hmml_free_ref(a->references + j); _hmml_free_ref(r);
} }
sb_free(a->references); sb_free(a->references);
for(size_t j = 0; j < sb_count(a->markers); ++j){ sb_each(m, a->markers){
free(a->markers[j].marker); free(m->marker);
free(a->markers[j].episode); free(m->episode);
sb_free(a->markers[j].parameter); sb_free(m->parameter);
} }
sb_free(a->markers); sb_free(a->markers);
@ -295,15 +305,28 @@ static void _hmml_free_anno(HMML_Annotation* a){
void hmml_free(HMML_Output* hmml){ void hmml_free(HMML_Output* hmml){
if(!hmml) return; if(!hmml) return;
for(size_t i = 0; i < sizeof(HMML_VideoMetaData)/sizeof(char*); ++i){
free(((char**)&hmml->metadata)[i]);
}
for(size_t i = 0; i < hmml->annotation_count; ++i){ for(size_t i = 0; i < hmml->annotation_count; ++i){
_hmml_free_anno(hmml->annotations + i); _hmml_free_anno(hmml->annotations + i);
} }
sb_free(hmml->annotations); sb_free(hmml->annotations);
free(hmml->metadata.member);
free(hmml->metadata.stream_platform);
free(hmml->metadata.stream_username);
free(hmml->metadata.project);
free(hmml->metadata.title);
free(hmml->metadata.vod_platform);
free(hmml->metadata.id);
sb_each(i, hmml->metadata.co_hosts) free(*i);
sb_each(i, hmml->metadata.guests) free(*i);
sb_each(i, hmml->metadata.annotators) free(*i);
sb_free(hmml->metadata.co_hosts);
sb_free(hmml->metadata.guests);
sb_free(hmml->metadata.annotators);
free(hmml->error.message); free(hmml->error.message);
memset(hmml, 0, sizeof(*hmml)); memset(hmml, 0, sizeof(*hmml));
} }

View File

@ -13,6 +13,7 @@
#define sb_end stb_sb_end #define sb_end stb_sb_end
#define sb_pop stb_sb_pop #define sb_pop stb_sb_pop
#define sb_erase stb_sb_erase #define sb_erase stb_sb_erase
#define sb_each stb_sb_each
#endif #endif
#define stb_sb_free(a) ((a) ? free(stb__sbraw(a)),(a)=0,0 : 0) #define stb_sb_free(a) ((a) ? free(stb__sbraw(a)),(a)=0,0 : 0)
@ -32,6 +33,8 @@
#define stb__sbmaybegrow(a,n) (stb__sbneedgrow(a,(n)) ? stb__sbgrow(a,n) : 0) #define stb__sbmaybegrow(a,n) (stb__sbneedgrow(a,(n)) ? stb__sbgrow(a,n) : 0)
#define stb__sbgrow(a,n) ((a) = stb__sbgrowf((a), (n), sizeof(*(a)))) #define stb__sbgrow(a,n) ((a) = stb__sbgrowf((a), (n), sizeof(*(a))))
#define stb_sb_each(n,h) for(typeof(h) n = h; n < sb_end(h); ++n)
#include <stdlib.h> #include <stdlib.h>
static inline void * stb__sbgrowf(void *arr, int increment, int itemsize) static inline void * stb__sbgrowf(void *arr, int increment, int itemsize)
@ -53,76 +56,4 @@ static inline void * stb__sbgrowf(void *arr, int increment, int itemsize)
} }
} }
#ifdef STB_SB_MMAP
#include <sys/mman.h>
#include <stdio.h>
#define sbmm_free(a) ((a) ? munmap(stb__sbraw(a), stb__sbm(a)),(a)=0,0 : 0)
#define sbmm_push(a,v) (stb__sbmaybegrow_mm(a,1), (a)[stb__sbn(a)++] = (v))
#define sbmm_add(a,n) (stb__sbmaybegrow_mm(a,n), stb__sbn(a)+=(n), &(a)[stb__sbn(a)-(n)])
#define sbmm_count stb_sb_count
#define sbmm_last stb_sb_last
#define sbmm_end stb_sb_end
#define sbmm_pop stb_sb_pop
#define sbmm_erase stb_sb_erase
#define stb__sbmaybegrow_mm(a,n) (stb__sbneedgrow(a,(n)) ? stb__sbgrow_mm(a,n) : 0)
#define stb__sbgrow_mm(a,n) ((a) = stb__sbgrowf_mm((a), (n), sizeof(*(a))))
#define SB_PAGE_SIZE 4096
static inline void * stb__sbgrowf_mm(void *arr, int increment, int itemsize)
{
size_t inc_cur = arr ? stb__sbm(arr) + SB_PAGE_SIZE : 0;
size_t min_needed = stb_sb_count(arr) + increment;
size_t m = inc_cur > min_needed ? inc_cur : min_needed;
size_t mem_needed = m * itemsize + sizeof(size_t) * 2;
mem_needed = (mem_needed + (SB_PAGE_SIZE-1)) & ~(SB_PAGE_SIZE-1);
size_t mem_have = !arr ? 0 : stb__sbm(arr) * itemsize + sizeof(size_t) * 2;
mem_have = (mem_have + (SB_PAGE_SIZE-1)) & ~(SB_PAGE_SIZE-1);
size_t* p = 0;
if(arr){
p = mremap(
stb__sbraw(arr),
mem_have,
mem_needed,
MREMAP_MAYMOVE
);
if(p == MAP_FAILED){
perror("mremap");
}
} else {
p = mmap(
0,
mem_needed,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
-1,
0
);
if(p == MAP_FAILED){
perror("mmap");
}
}
if (p != MAP_FAILED) {
if (!arr)
p[1] = 0;
p[0] = m;
return p+2;
} else {
#ifdef STRETCHY_BUFFER_OUT_OF_MEMORY
STRETCHY_BUFFER_OUT_OF_MEMORY ;
#endif
return (void *) (2*sizeof(size_t)); // try to force a NULL pointer exception later
}
}
#endif // STB_SB_MMAP
#endif // STB_STRETCHY_BUFFER_H_INCLUDED #endif // STB_STRETCHY_BUFFER_H_INCLUDED