Esempio n. 1
0
int subtitle_ParseSSA (char **Line) {

    if ((Line == NULL) || (*Line == NULL))
    {
        subtitle_err("null pointer passed\n");
        return cERR_SUBTITLE_ERROR;
    }

    subtitle_printf(20, "-> Text=%s\n", *Line);

    replace_all(Line, "\x0d", "");
    replace_all(Line, "\n\n", "\\N");
    replace_all(Line, "\n", "");
    replace_all(Line, "\\N", "\n");
    replace_all(Line, "ö", "oe");
    replace_all(Line, "ä", "ae");
    replace_all(Line, "ü", "ue");
    replace_all(Line, "Ö", "Oe");
    replace_all(Line, "Ä", "Ae");
    replace_all(Line, "Ü", "Ue");
    replace_all(Line, "ß", "ss");

    subtitle_printf(10, "<- Text=%s\n", *Line);

    return cERR_SUBTITLE_NO_ERROR;
}
Esempio n. 2
0
static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
	int ret = cERR_SUBTITLE_NO_ERROR;

	subtitle_printf(50, "%d\n", command);

	switch(command)
	{
		case OUTPUT_GET_SUBTITLE_DATA:
			*((Subtitle_Out_t **)argument) = (Subtitle_Out_t *) &subtitleData[readPointer];
			subtitle_printf(50, "Get data %d Text:%s [%lld] -> [%lld]\n",
				readPointer, (const char *)subtitleData[readPointer].data, subtitleData[readPointer].pts,
				subtitleData[readPointer].pts + subtitleData[readPointer].duration);
			break;
		case OUTPUT_DEL_SUBTITLE_DATA:
			ret = subtitle_DelData();
			break;
		case OUTPUT_OPEN:
			ret = subtitle_Open();
			break;
		case OUTPUT_CLOSE:
			ret = subtitle_Close();
			break;
		default:
			subtitle_err("OutputCmd %d not supported!\n", command);
			ret = cERR_SUBTITLE_ERROR;
			break;
	}

	subtitle_printf(50, "exiting with value %d\n", ret);

	return ret;
}
Esempio n. 3
0
static int subtitle_DelData()
{
	subtitle_printf(10, " %d\n", readPointer);

	if (subtitleData[readPointer].data == NULL)
	{
		subtitle_err("null pointer in data\n");
	}
	else
	{
		free(subtitleData[readPointer].data);
		subtitleData[readPointer].data = NULL;
	}
	subtitleData[readPointer].pts	   = 0;
	subtitleData[readPointer].duration = 0;

	readPointer++;

	if (readPointer == PUFFERSIZE)
	{
		readPointer = 0;
	}

	return cERR_SUBTITLE_NO_ERROR;
}
Esempio n. 4
0
int getNextSub(char ** text, unsigned long long int * pts, long int * milliDuration) {

    subtitle_printf(50, "index %d\n", readPointer);

    if (text == NULL)
    {
        subtitle_err("null pointer passed\n");
        return cERR_SUBTITLE_ERROR;
    }

    getMutex(__LINE__);

    if (subPuffer[readPointer].text == NULL)
    {
        /* this is acutally not an error, because it may happen
         * that there is no subtitle for a while
         */
        subtitle_printf(200, "null in subPuffer\n");
        releaseMutex(__LINE__);
        return cERR_SUBTITLE_ERROR;
    }
    
    *text = strdup(subPuffer[readPointer].text);
    free(subPuffer[readPointer].text);
    subPuffer[readPointer].text = NULL;

    *pts = subPuffer[readPointer].pts;
    subPuffer[readPointer].pts = 0;

    *milliDuration = subPuffer[readPointer].milliDuration;
    subPuffer[readPointer].milliDuration = 0;

    readPointer++;

    if (readPointer == PUFFERSIZE)
        readPointer = 0;

    if (writePointer == readPointer)
    {
        /* this may happen, in normal case the reader is ones ahead the 
         * writer. So this is the normal case that we eat the data
         * and have the reader reached.
         */
        subtitle_printf(20, "ups something went wrong. no more writers? \n");
    }

    releaseMutex(__LINE__);

    subtitle_printf(20, "readPointer %d\n",readPointer);
    subtitle_printf(10, "<\n");

    return cERR_SUBTITLE_NO_ERROR;
}
Esempio n. 5
0
int subtitle_ParseASS (char **Line) {
    char* Text;
    int   i;
    char* ptr1;

    if ((Line == NULL) || (*Line == NULL))
    {
        subtitle_err("null pointer passed\n");
        return cERR_SUBTITLE_ERROR;
    }
    
    Text = strdup(*Line);

    subtitle_printf(10, "-> Text = %s\n", *Line);

    ptr1 = Text;
    
    for (i=0; i < 9 && *ptr1 != '\0'; ptr1++) {

        subtitle_printf(20, "%s",ptr1);

        if (*ptr1 == ',')
            i++;
    }

    free(*Line);

    *Line = strdup(ptr1);
    free(Text);

    replace_all(Line, "\\N", "\n");

    replace_all(Line, "{\\i1}", "<i>");
    replace_all(Line, "{\\i0}", "</i>");

    subtitle_printf(10, "<- Text=%s\n", *Line);

    return cERR_SUBTITLE_NO_ERROR;
}
Esempio n. 6
0
void replace_all(char ** string, char * search, char * replace) {
    int len = 0;
    char * ptr = NULL;
    char tempString[512];
    char newString[512];

    newString[0] = '\0';

    if ((string == NULL) || (*string == NULL) || (search == NULL) || (replace == NULL))
    {
        subtitle_err("null pointer passed\n");
        return;
    }
    
    strncpy(tempString, *string, 511);
    tempString[511] = '\0';

    free(*string);

    while ((ptr = strstr(tempString, search)) != NULL) {
        len  = ptr - tempString;
        strncpy(newString, tempString, len);
        newString[len] = '\0';
        strcat(newString, replace);

        len += strlen(search);
        strcat(newString, tempString+len);

        strcpy(tempString, newString);
    }

    subtitle_printf(20, "strdup in line %d\n", __LINE__);

    if(newString[0] != '\0')
        *string = strdup(newString);
    else
        *string = strdup(tempString);

}
Esempio n. 7
0
static int Write(void* _context, void *data) {
    Context_t  * context = (Context_t  *) _context;
    char * Encoding = NULL;
    char * Text;
    SubtitleOut_t * out;
    int DataLength;
    unsigned long long int Pts;
    float Duration;
 
    subtitle_printf(10, "\n");

    if (data == NULL)
    {
        subtitle_err("null pointer passed\n");
        return cERR_SUBTITLE_ERROR;
    }

    out = (SubtitleOut_t*) data;
    
    if (out->type == eSub_Txt)
    {
        Text = strdup((const char*) out->u.text.data);
    } else
    {
/* fixme handle gfx subs from container_ass and send it to
 * the callback. this must be implemented also in e2/neutrino
 * then.
 */    
        subtitle_err("subtitle gfx currently not handled\n");
        return cERR_SUBTITLE_ERROR;
    } 

    DataLength = out->u.text.len;
    Pts = out->pts;
    Duration = out->duration;
    
    context->manager->subtitle->Command(context, MANAGER_GETENCODING, &Encoding);

    if (Encoding == NULL)
    {
       subtitle_err("encoding unknown\n");
       free(Text);
       return cERR_SUBTITLE_ERROR;
    }
    
    subtitle_printf(20, "Encoding:%s Text:%s Len:%d\n", Encoding,Text, DataLength);

    if (    !strncmp("S_TEXT/SSA",  Encoding, 10) ||
            !strncmp("S_SSA",       Encoding, 5))
        subtitle_ParseSSA(&Text);
    
    else if(!strncmp("S_TEXT/ASS",  Encoding, 10) ||
            !strncmp("S_AAS",       Encoding, 5))
        subtitle_ParseASS(&Text);
    
    else if(!strncmp("S_TEXT/SRT",  Encoding, 10) ||
            !strncmp("S_SRT",       Encoding, 5))
        subtitle_ParseSRT(&Text);
    else
    {
        subtitle_err("unknown encoding %s\n", Encoding);
        return  cERR_SUBTITLE_ERROR;
    }
    
    subtitle_printf(10, "Text:%s Duration:%f\n", Text,Duration);

    addSub(context, Text, Pts, Duration * 1000);
    
    free(Text);
    free(Encoding);

    subtitle_printf(10, "<\n");

    return cERR_SUBTITLE_NO_ERROR;
}
Esempio n. 8
0
static void* SubtitleThread(void* data) {
    Context_t *context = (Context_t*) data;
    char *                  subText             = NULL;
    long int                subMilliDuration    = 0;
    unsigned long long int  subPts              = 0;
    unsigned long long int  Pts                 = 0;

    subtitle_printf(10, "\n");
    hasThreadStarted = 1;

    while ( context->playback->isCreationPhase ) {
        subtitle_err("Thread waiting for end of init phase...\n");
        usleep(1000);
    }

    subtitle_printf(10, "done\n");

    while ( context &&
            context->playback &&
            context->playback->isPlaying && hasThreadStarted == 1) {

        int curtrackid = -1;
        
        if (context && context->manager && context->manager->subtitle)
            context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid);

        subtitle_printf(50, "curtrackid %d\n", curtrackid);

        if (curtrackid >= 0) {
            if (getNextSub(&subText, &subPts, &subMilliDuration) != 0) {
                usleep(500000);
                continue;
            }

            if (context && context->playback)
                context->playback->Command(context, PLAYBACK_PTS, &Pts);
            else break;

            if(Pts > subPts) {
                subtitle_printf(10,"subtitle is to late, ignoring\n");
                if(subText != NULL)
                    free(subText);
                continue;
            }

            subtitle_printf(20, "Pts:%llu < subPts%llu duration %ld\n", Pts, subPts,subMilliDuration);

            while ( context &&
                    context->playback &&
                    context->playback->isPlaying &&
                    Pts < subPts && hasThreadStarted == 1) {

                unsigned long int diff = subPts - Pts;
                diff = (diff*1000)/90.0;

                subtitle_printf(50, "DIFF: %lud\n", diff);

                if(diff > 100)
                    usleep(diff);

                if (context && context->playback)
                    context->playback->Command(context, PLAYBACK_PTS, &Pts);
                else
                { 
                   subtitle_err("no playback ? terminated?\n");
                   break;
                }
                subtitle_printf(20, "cur: %llu wanted: %llu\n", Pts, subPts);
            }

            if (    context &&
                    context->playback &&
                    context->playback->isPlaying &&
                    subText != NULL && hasThreadStarted == 1) {

                if(clientFunction != NULL)
                    clientFunction(subMilliDuration, strlen(subText), subText, clientData);
                else
                    subtitle_printf(10, "writing Sub failed (%ld) (%d) \"%s\"\n", subMilliDuration, strlen(subText), subText);

                free(subText);
            }

        } /* trackID >= 0 */
        else //Wait
            usleep(500000);

    } /* outer while */
    
    subtitle_printf(0, "has ended\n");
 
    hasThreadStarted = 0;
   
    return NULL;
}
Esempio n. 9
0
void addSub(Context_t  *context, char * text, unsigned long long int pts, unsigned long int milliDuration) {
    int count = 20;
    
    subtitle_printf(50, "index %d\n", writePointer);

    if(context && context->playback && !context->playback->isPlaying)
    {
        subtitle_err("1. aborting ->no playback\n");
        return;
    }
    
    if (text == NULL)
    {
        subtitle_err("null pointer passed\n");
        return;
    }

    if (pts == 0)
    {
        subtitle_err("pts 0\n");
        return;
    }

    if (milliDuration == 0)
    {
        subtitle_err("duration 0\n");
        return;
    }
    
    while (subPuffer[writePointer].text != NULL) {
        //List is full, wait till we got some free space

        if(context && context->playback && !context->playback->isPlaying)
        {
            subtitle_err("2. aborting ->no playback\n");
            return;
        }

/* konfetti: we dont want to block forever here. if no buffer
 * is available we start ring from the beginning and loose some stuff
 * which is acceptable!
 */
        subtitle_printf(10, "waiting on free buffer %d - %d (%d) ...\n", writePointer, readPointer, count);
        usleep(10000);
        count--;
        
        if (count == 0)
        {
            subtitle_err("abort waiting on buffer...\n");
            break;
        }
    }
    
    subtitle_printf(20, "from mkv: %s pts:%lld milliDuration:%lud\n",text,pts,milliDuration);

    getMutex(__LINE__);

    if (count == 0)
    {
        int i;
        subtitle_err("freeing not delivered data\n");
        
        //Reset all
        readPointer = 0;
        writePointer = 0;

        for (i = 0; i < PUFFERSIZE; i++) {
            if (subPuffer[i].text != NULL)
               free(subPuffer[i].text);
            subPuffer[i].text          = NULL;
            subPuffer[i].pts           = 0;
            subPuffer[i].milliDuration = 0;
        }
    }

    subPuffer[writePointer].text = strdup(text);
    subPuffer[writePointer].pts = pts;
    subPuffer[writePointer].milliDuration = milliDuration;

    writePointer++;
    
    if (writePointer == PUFFERSIZE)
        writePointer = 0;

    if (writePointer == readPointer)
    {
        /* this should not happen, and means that there is nor reader or
         * the reader has performance probs ;)
         * the recovery is done at startup of this function - but next time
         */
        subtitle_err("ups something went wrong. no more readers? \n");
    }

    releaseMutex(__LINE__);

    subtitle_printf(10, "<\n");
}
Esempio n. 10
0
static int Write(Context_t *context, void *data)
{
	subtitle_printf(10, "\n");
	char *Encoding = NULL;
	int msg = 0;

	if (data == NULL)
	{
		subtitle_err("null pointer passed\n");
		return cERR_SUBTITLE_ERROR;
	}

	context->manager->subtitle->Command(context, MANAGER_GETENCODING, &Encoding);

	if (Encoding == NULL)
	{
		subtitle_err("encoding unknown\n");
		return cERR_SUBTITLE_ERROR;
	}

	Subtitle_Out_t* out = (Subtitle_Out_t*) data;

	if (subtitleData[writePointer].data != NULL)
	{
		subtitle_err("subtitle list is full, dlete %d\n", writePointer);
		free(subtitleData[writePointer].data);
		subtitleData[writePointer].data     = NULL;
		subtitleData[writePointer].pts	    = 0;
		subtitleData[writePointer].duration = 0;
	}

	if (!strncmp("S_TEXT/ASS", Encoding, 10))
	{
		subtitleData[writePointer].data = (uint8_t *)strdup(ass_get_text((char *)out->data));
	}
	else if (!strncmp("S_TEXT/SUBRIP", Encoding, 13) || !strncmp("S_TEXT/SRT", Encoding, 10) || !strncmp("S_TEXT/SSA", Encoding, 10))
	{
		subtitleData[writePointer].data = (uint8_t *)strdup((const char *)out->data);
	}
	else
	{
		subtitle_err("unknown encoding %s\n", Encoding);
		return cERR_SUBTITLE_ERROR;
	}

	subtitleData[writePointer].pts	    = out->pts;
	subtitleData[writePointer].duration = out->duration;

	subtitle_printf(10, "Encoding:%s Text:%s [%lld] -> [%lld]\n",
		Encoding, (const char *)subtitleData[writePointer].data, subtitleData[writePointer].pts,
		subtitleData[writePointer].pts + subtitleData[writePointer].duration);

	writePointer++;

	if (writePointer == PUFFERSIZE)
	{
		writePointer = 0;
	}

	/* Tell enigma2 that we have subtitles */
	context->playback->Command(context, PLAYBACK_SEND_MESSAGE, (void *) &msg);

	subtitle_printf(10, "<\n");
	return cERR_SUBTITLE_NO_ERROR;
}