gchar *language_code;
gchar *language_key;
};
+#define MAX_LANGUAGE 10
#endif
struct _GstSamiContext
{
#ifdef SUBPARSE_MODIFICATION
guint64 time3; /* To store the last current time when language is changed */
GList *lang_list; /* Language list for an external subtitle file */
- gboolean time_set; /* If language is set already by user */
gchar *current_language; /* Current language parsed */
gchar *desired_language; /* Language set by user */
gboolean language_changed; /* language changed signal */
+ gboolean end_body; /* </BODY> reached */
#endif
};
for (i = 0; i < count; i += 2) {
gchar *attr_name = NULL, *attr_value = NULL;
gsize length;
+
+#ifdef SUBPARSE_MODIFICATION
+ /* sometimes count can unnecessarily be high value, because of unrequired "=" in subtitle file.
+ * In that case it should not crash */
+ if (!next)
+ break;
+#endif
+
next = string_token (next + 1, "=", &attr_name);
+
+#ifdef SUBPARSE_MODIFICATION
+ /* sometimes count can unnecessarily be high value, because of unrequired "=" in subtitle file.
+ * In that case it should not crash */
+ if (!next)
+ break;
+#endif
+
next = string_token (next + 1, " ", &attr_value);
/* strip " or ' from attribute value */
key = atts[i];
value = atts[i + 1];
- if (sctx->current_language && value && strcmp(sctx->current_language, value))
+ if (sctx->current_language && value && strcmp(sctx->current_language, value)
+ && (sctx->time1 == sctx->time2))
sctx->language_changed = TRUE;
else if (!sctx->current_language)
if (key && !g_ascii_strcasecmp ("class", key) && value) {
strcpy (sctx->current_language, value);
+ if (sctx->desired_language == NULL && key) {
+ sctx->desired_language = (gchar*) malloc (strlen(value) + 1);
+ strcpy(sctx->desired_language, value);
+ GST_LOG("no language list was found and desired lang was set to %s",sctx->desired_language);
+ }
}
if (sctx->language_changed)
{
- sctx->time1 = sctx->time3;
- sctx->time2 = sctx->time1;
- sctx->time_set = FALSE;
+ sctx->time1 = 0;
+ sctx->time2 = sctx->time3;
sctx->language_changed = FALSE;
}
if (!value)
GstLangStruct *temp = NULL;
if (atts != NULL) {
+ if (g_list_length (sctx->lang_list)) {
+ GST_LOG ("We already got the language list");
+ return;
+ }
for (i = 0; (atts[attrIndex] != NULL); i++) {
const gchar *key, *value;
(!g_ascii_strcasecmp ("sami", name))) {
/* We will usually have one buffer left when the body is closed
* as we need the next sync to actually send it */
+
+#ifdef SUBPARSE_MODIFICATION
+ sctx->end_body = TRUE;
+#endif
+
if (sctx->buf->len != 0) {
/* Only set a new start time if we don't have text pending */
if (sctx->resultbuf->len == 0)
#ifdef SUBPARSE_MODIFICATION
context->current_language = NULL;
context->desired_language = NULL;
- context->time_set = FALSE;
context->lang_list = NULL;
context->language_changed = FALSE;
+ context->end_body = FALSE;
#endif
state->user_data = context;
}
GstSamiContext *context = (GstSamiContext *) state->user_data;
GST_LOG ("**********desired language was %s**************", context->desired_language);
free (context->desired_language);
- context->desired_language = state->current_language;
- context->time_set = TRUE;
+ if(state->current_language) {
+ context->desired_language = state->current_language;
+ } else {
+ context->desired_language = state->msl_language;
+ }
GST_LOG ("desired language changed to %s", context->desired_language);
}
+
+gchar *
+sami_convert_to_utf8 (const gchar * str, gsize len, const gchar * encoding,
+ gsize * consumed, GError ** err, GstSubParse * self)
+{
+ gchar *ret = NULL;
+
+ /* The char cast is necessary in glib < 2.24 */
+ ret =
+ g_convert_with_fallback (str, len, "UTF-8", encoding, (char *) "*",
+ consumed, NULL, err);
+
+ if (ret == NULL)
+ {
+ GST_DEBUG_OBJECT (self, "g_convert_with_fallback returns NULL");
+ return ret;
+ }
+
+ /* + 3 to skip UTF-8 BOM if it was added */
+ len = strlen (ret);
+ if (len >= 3 && (guint8) ret[0] == 0xEF && (guint8) ret[1] == 0xBB
+ && (guint8) ret[2] == 0xBF)
+ g_memmove (ret, ret + 3, len + 1 - 3);
+
+ return ret;
+}
+
+gboolean
+sami_validate_langlist_body(GList * lang_list, GstSubParse * self){
+ gchar * file_path_type = NULL;
+ gchar * file_path = NULL;
+ gchar line[1024];
+ FILE * fp = NULL;
+ guint i = 0, found_count = 0;
+ const guint list_len = g_list_length(lang_list);
+ gboolean counter[MAX_LANGUAGE];
+ struct LangStruct
+ {
+ gchar *language_code;
+ gchar *language_key;
+ } * lang;
+
+ GstQuery *cquery;
+ GstStructure *structure;
+ const GValue *value;
+ structure = gst_structure_new ("FileSrcURI",
+ "file-uri", G_TYPE_STRING, NULL, NULL);
+
+ cquery = gst_query_new_application (GST_QUERY_CUSTOM, structure);
+
+ if (!gst_pad_peer_query (self->sinkpad, cquery))
+ {
+ GST_DEBUG_OBJECT (self, "failed to query SMI file path");
+ gst_query_unref (cquery);
+ return FALSE;
+ }
+ structure = gst_query_get_structure (cquery);
+ value = gst_structure_get_value (structure, "file-uri");
+ file_path = g_strdup (g_value_get_string (value));
+
+ if (file_path == NULL){
+ GST_DEBUG_OBJECT (self, "could not parse the SMI file path");
+ gst_query_unref (cquery);
+ return FALSE;
+ }
+ gst_query_unref (cquery);
+
+ GST_INFO_OBJECT (self, "file path comes as %s", file_path);
+
+ file_path_type = g_strndup ((gchar *) file_path, 4);
+ GST_INFO_OBJECT (self, "received file path by query = %s,%s", file_path,file_path_type);
+ if (!g_strcmp0(file_path_type, "file")){
+ file_path += 7;
+ GST_INFO_OBJECT (self, "file path comes as %s", file_path);
+
+ fp = fopen (file_path, "r");
+ if (!fp){
+ GST_DEBUG_OBJECT (self, "failed to open file");
+ return FALSE;
+ }
+
+ for(i=0;i<list_len;i++){
+ counter[i] = FALSE;
+ }
+
+ while(!feof(fp) && found_count < list_len){
+ GError *err = NULL;
+ gsize * consumed = NULL;
+ gint gap = 0;
+ guint charCount = 0;
+ gchar* result = NULL;
+ gchar* temp = NULL;
+ gchar* temp_lang = NULL;
+ gchar * temp1 = NULL;
+ gchar *con_temp_lang = NULL;
+ gchar *con_temp = NULL;
+ gboolean conversion = TRUE;
+ charCount = fread (line, sizeof(char), 1024, fp);
+ if (!charCount) {
+ GST_WARNING_OBJECT (self, "fread returned zero bytes");
+ continue;
+ }
+ GST_DEBUG("value of detected encoding is %s and self encoding is %s",self->detected_encoding,self->encoding);
+ if (self->detected_encoding && strcmp (self->detected_encoding, "UTF-8") && conversion){
+ result = sami_convert_to_utf8 (line, charCount, self->detected_encoding, consumed, &err, self);
+ }
+ if(result == NULL) {
+ result = line;
+ conversion = FALSE;
+ }
+ con_temp = g_utf8_strdown (result,strlen(result));
+ temp = con_temp;
+ while(con_temp) {
+ con_temp = g_strstr_len(con_temp, strlen(con_temp),"class=");
+ if(con_temp) {
+ temp1 = g_strstr_len(con_temp+1, strlen(con_temp),"class=");
+ }
+ if(temp1 && con_temp){
+ gap = strlen(con_temp)-strlen(temp1);
+ }else if(con_temp) {
+ gap = strlen(con_temp);
+ } else {
+ continue;
+ }
+ if(con_temp){
+ for(i=0;i<list_len;i++){
+ if(counter[i]==TRUE){
+ con_temp=con_temp+1;
+ continue;
+ }
+ lang = (struct LangStruct *) g_list_nth_data(lang_list,i);
+ if(lang) {
+ temp_lang = (gchar*)g_malloc(strlen(lang->language_key)+1);
+ strcpy(temp_lang,lang->language_key);
+ con_temp_lang = g_utf8_strdown (temp_lang,strlen(temp_lang));
+ if(g_strstr_len(con_temp,gap,con_temp_lang)){
+ found_count++;
+ counter[i]=TRUE;
+ GST_INFO_OBJECT (self, " valid Language in list : [%s]", lang->language_key);
+ con_temp=con_temp+1;
+ }
+ g_free(temp_lang);
+ g_free(con_temp_lang);
+ }
+ }
+ }
+ }
+ if(conversion)
+ g_free (result);
+ if(temp)
+ g_free(temp);
+
+ }
+
+ if(found_count < list_len){
+ for(i=0;i<list_len;i++){
+ if(counter[i]==FALSE)
+ lang_list = g_list_delete_link(lang_list,g_list_nth(lang_list,i));
+ }
+ }
+ }
+ return TRUE;
+}
#endif
gchar *
parse_sami (ParserState * state, const gchar * line)
{
gchar *ret = NULL;
+#ifdef SUBPARSE_MODIFICATION
+ gint64 clip_start = 0, clip_stop = 0;
+ gboolean in_seg = FALSE;
+#endif
GstSamiContext *context = (GstSamiContext *) state->user_data;
gchar *unescaped = unescape_string (line);
g_free (unescaped);
#ifdef SUBPARSE_MODIFICATION
if (context->desired_language && context->current_language) {
- if (!strcmp(context->current_language, context->desired_language)) {
+ if ((!strcmp(context->current_language, context->desired_language)) || context->end_body) {
#endif
if (context->has_result) {
if (context->rubybuf->len) {
context->has_result = FALSE;
}
#ifdef SUBPARSE_MODIFICATION
+ context->end_body = FALSE;
}
}
+ /* Check our segment start/stop */
+ in_seg = gst_segment_clip (state->segment, GST_FORMAT_TIME,
+ state->start_time, state->start_time + state->duration, &clip_start,
+ &clip_stop);
+
+ /* No need to send that text if it's out of segment */
+ if (in_seg) {
+ state->start_time = clip_start;
+ state->duration = clip_stop - clip_start;
+ } else {
+ return NULL;
+ }
#endif
return ret;
}