plugin-threads.cpp
上传用户:hongyu5696
上传日期:2018-01-22
资源大小:391k
文件大小:61k
源码类别:
PlugIns编程
开发平台:
Unix_Linux
- #include "plugin.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include "plugin-setup.h"
- #include <fcntl.h>
- #include <signal.h>
- #include <sys/wait.h>
- #include <sys/param.h>
- #include <errno.h>
- extern int DEBUG;
- extern int errno;
- static void sig_child(int signo)
- {
- wait(NULL);
- }
- /*
- * Copyright (c) 2002 - 2003
- * NetGroup, Politecnico di Torino (Italy)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- /*
- * the above copyright applies to pthread_suspend only
- */
- #ifdef GTK_ENABLED
- gboolean mediacallback(void *data)
- {
- nsPluginInstance *instance;
- if (DEBUG > 1)
- printf("in mediacallbackn");
- instance = (nsPluginInstance *) data;
- if (instance->mediaCompleteCallback != NULL)
- NPN_GetURL(instance->mInstance,
- instance->mediaCompleteCallback, "_self");
- if (instance->mediaCompleteWithErrorCallback != NULL)
- NPN_GetURL(instance->mInstance,
- instance->mediaCompleteWithErrorCallback, "_self");
- return FALSE;
- }
- #endif
- void pthread_suspend(int msec)
- {
- struct timespec abstime;
- struct timeval now;
- pthread_cond_t cond;
- pthread_mutex_t mutex;
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutex_init(&mutex, &attr);
- pthread_mutex_lock(&mutex);
- pthread_cond_init(&cond, NULL);
- gettimeofday(&now, NULL);
- abstime.tv_sec = now.tv_sec + msec / 1000;
- abstime.tv_nsec = now.tv_usec * 1000 + (msec % 1000) * 1000 * 1000;
- pthread_cond_timedwait(&cond, &mutex, &abstime);
- pthread_mutex_destroy(&mutex);
- pthread_cond_destroy(&cond);
- }
- //this function must be called with control_mutex locked
- void launchPlayerThread(nsPluginInstance * instance)
- {
- void *thread_return;
- if (DEBUG)
- printf("In launchPlayerThread, state = %dn", instance->state);
- if (instance->threadlaunched == 1) {
- if (DEBUG)
- printf("launchPlayerThread - joining threadn");
- pthread_join(instance->player_thread, &thread_return);
- }
- if (instance->js_state == JS_STATE_UNDEFINED) {
- if (DEBUG)
- printf("launchPlayerThread - creating new threadn");
- pthread_create(&(instance->player_thread),
- &(instance->thread_attr), playPlaylist,
- (void *) (instance->td));
- instance->js_state = JS_STATE_INITIALIZING;
- instance->threadlaunched = 1;
- instance->threadsignaled = 0;
- } else {
- printf
- ("****WARNING: launching duplicate player thread, js_state = %dn",
- instance->js_state);
- instance->threadlaunched = 0;
- }
- }
- void signalPlayerThread(nsPluginInstance * instance)
- {
- //signal the player thread
- if (DEBUG) {
- printf("Signalling Player thread, state = %d, js_state = %dn",
- instance->state, instance->js_state);
- }
- if (instance->threadlaunched != 1)
- if (DEBUG)
- printf("****Player thread did not launch correctly****n");
- pthread_mutex_lock(&(instance->control_mutex));
- while (instance->js_state == JS_STATE_INITIALIZING) {
- if (DEBUG)
- printf("Waiting for player thread to start....%in",
- instance->js_state);
- pthread_mutex_unlock(&(instance->control_mutex));
- pthread_suspend(10);
- pthread_mutex_lock(&(instance->control_mutex));
- }
- if (instance->js_state == JS_STATE_BUFFERING
- || instance->js_state == JS_STATE_READY) {
- pthread_mutex_lock(&(instance->playlist_cond_mutex));
- pthread_cond_signal(&(instance->playlist_complete_cond));
- pthread_mutex_unlock(&(instance->playlist_cond_mutex));
- instance->threadsignaled = 1;
- } else {
- if (DEBUG)
- printf("****Player thread did not start correctly****n");
- }
- pthread_mutex_unlock(&(instance->control_mutex));
- }
- FILE *mypopen(char **argv, pid_t * pid, int *control,
- nsPluginInstance * instance)
- {
- int filedesr[2], filedesw[2], err;
- pid_t child;
- long flags;
- sigset_t newmask;
- FILE *retfd;
- pipe(filedesr);
- pipe(filedesw);
- child = fork();
- if (!child) {
- if (DEBUG) {
- char **tmp;
- tmp = argv;
- printf("Starting: ");
- while (*tmp)
- printf("%s ", *(tmp++));
- printf("n");
- }
- dup2(filedesw[0], 0);
- dup2(filedesr[1], 1);
- dup2(filedesr[1], 2);
- close(filedesw[1]);
- close(filedesr[0]);
- setsid();
- setpgid(0, 0);
- sigemptyset(&newmask);
- sigaddset(&newmask, SIGTERM);
- sigaddset(&newmask, SIGKILL);
- pthread_sigmask(SIG_UNBLOCK, &newmask, 0L);
- usleep(500);
- if (execvp(argv[0], argv) < 0) {
- err = errno;
- #ifdef GTK_ENABLED
- snprintf(instance->lastmessage, 1024, "Error: %i - %s", err,
- strerror(err));
- g_idle_add(gtkgui_message, instance);
- #endif
- perror("execv");
- }
- _exit(0);
- } else {
- // setup signal handler for child
- signal(SIGCHLD, sig_child);
- sigemptyset(&newmask);
- sigaddset(&newmask, SIGCHLD);
- sigaddset(&newmask, SIGTERM);
- sigaddset(&newmask, SIGKILL);
- pthread_sigmask(SIG_UNBLOCK, &newmask, 0L);
- *pid = child;
- *control = filedesw[1];
- close(filedesw[0]);
- close(filedesr[1]);
- // make the operations on the control pipe non-blocking
- flags = fcntl(*control, F_GETFL, 0);
- flags |= O_NONBLOCK;
- #ifndef BSD
- flags |= O_NDELAY;
- #endif
- fcntl(*control, F_SETFL, flags);
- retfd = fdopen(filedesr[0], "r");
- return retfd;
- }
- }
- void SetupPlayer(nsPluginInstance * instance, XEvent * event)
- {
- int i;
- char xval[32], yval[32];
- char *filename;
- char *baseurl;
- char buffer[1024];
- #ifndef X_DISPLAY_MISSING
- char *dispName = XDisplayName(NULL);
- #endif
- bool isRemoteDisplay = false;
- if (instance->threadsetup == 1)
- return;
- if (instance->toolkitok != 0)
- return;
- instance->td->w = instance->widget;
- instance->td->instance = instance;
- if (DEBUG > 1)
- printf("Entering SetupPlayern");
- #ifdef X_ENABLED
- DrawUI(instance->widget, instance, _("Loading Media..."), 0, -1);
- #endif
- #ifdef GTK_ENABLED
- if (instance->status != NULL)
- gtk_label_set_text(instance->status, _("Loading Media..."));
- #endif
- if (instance->td->list == NULL) {
- instance->td->list = instance->list;
- }
- /*
- if (instance->href) {
- if (DEBUG)
- printf("using href for urln");
- snprintf(instance->td->list->url, 1024, "%s", instance->href);
- } else
- */
- if (instance->fname) {
- if (DEBUG)
- printf("using fname for urln");
- snprintf(instance->td->list->url, 1024, "%s", instance->fname);
- } else {
- if (DEBUG)
- printf("using url for urln");
- snprintf(instance->td->list->url, 1024, "%s", instance->url);
- }
- if ((instance->fname == NULL) && (instance->url == NULL)) {
- if (DEBUG)
- printf("using href for urln");
- snprintf(instance->td->list->url, 1024, "%s", instance->href);
- }
- if (instance->mode == NP_FULL) {
- snprintf(xval, 32, "%i", instance->window_width);
- snprintf(yval, 32, "%i", instance->window_height);
- } else {
- snprintf(xval, 32, "%i", instance->embed_width);
- if (instance->maintain_aspect == 0 && instance->showcontrols == 1) {
- snprintf(yval, 32, "%i", instance->embed_height - 16);
- } else {
- snprintf(yval, 32, "%i", instance->embed_height);
- }
- }
- baseurl = NULL;
- if (instance->baseurl == NULL) {
- baseurl = getURLBase(instance->td->list->url);
- if (baseurl != NULL) {
- if (instance->baseurl == NULL) {
- instance->baseurl = baseurl;
- } else {
- if (strcmp(instance->baseurl, baseurl) != 0) {
- NPN_MemFree(instance->baseurl);
- instance->baseurl = baseurl;
- } else {
- NPN_MemFree(baseurl);
- }
- }
- }
- }
- if (instance->hostname == NULL)
- instance->hostname = getURLHostname(instance->td->list->url);
- if (instance->keep_download == 1) {
- instance->td->list->remove = 0;
- filename = getURLFilename(instance->td->list->url);
- snprintf(instance->td->list->fname, 1024, "%s/%s",
- instance->download_dir, filename);
- if (filename)
- NPN_MemFree(filename);
- } else {
- if ((instance->nomediacache == 0)
- && (instance->td->list->bytes > 0)) {
- if (strlen(instance->td->list->fname) == 0) {
- snprintf(instance->td->list->fname, 1024, "%s",
- tempnam("/tmp", "downloadplug-inXXXXXX"));
- }
- } else {
- // fix up the URL
- pthread_mutex_lock(&(instance->playlist_mutex));
- fullyQualifyURL(instance, instance->td->list->url, buffer);
- if (DEBUG)
- printf("url %snbuffer %sn", instance->td->list->url,
- buffer);
- snprintf(instance->td->list->url, 1024, "%s", buffer);
- pthread_mutex_unlock(&(instance->playlist_mutex));
- }
- }
- // set up the vars
- i = 0;
- while (i < 50) {
- instance->td->argv[i++] = NULL;
- }
- i = 0;
- snprintf(buffer, 1024, "download");
- instance->td->argv[i++] = strdup(buffer);
- if (instance->novop == 1) {
- snprintf(buffer, 1024, "-vop");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "null");
- instance->td->argv[i++] = strdup(buffer);
- } else {
- if (instance->vop != NULL) {
- snprintf(buffer, 1024, "-vop");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "%s", instance->vop);
- instance->td->argv[i++] = strdup(buffer);
- if (strncmp(instance->vop, "scale=", 6) == 0) {
- snprintf(buffer, 1024, "-fs");
- instance->td->argv[i++] = strdup(buffer);
- }
- }
- }
- if ((instance->mode == NP_EMBED) && (instance->noembed == 0)) {
- if (instance->window != 0) {
- snprintf(buffer, 1024, "-wid");
- instance->td->argv[i++] = strdup(buffer);
- #ifdef X_ENABLED
- // instance->player_window =
- // XCreateSimpleWindow(instance->display, instance->window, 0,
- // 0, instance->embed_width,
- // instance->embed_height, 0, 0, 0);
- snprintf(buffer, 1024, "0x%x", (int) instance->window);
- instance->td->argv[i++] = strdup(buffer);
- #endif
- #ifdef GTK_ENABLED
- if (instance->targetplayer == 1) {
- gtk_widget_show(instance->gtkwidget);
- gtk_widget_show(instance->drawing_area);
- }
- #ifdef GTK2_ENABLED
- instance->player_window =
- gtk_socket_get_id(GTK_SOCKET(instance->drawing_area));
- #endif
- #ifdef GTK1_ENABLED
- instance->player_window =
- GDK_WINDOW_XWINDOW(instance->drawing_area->window);
- #endif /* if (instance->targetplayer == 1) */
- snprintf(buffer, 1024, "0x%x", (int) instance->player_window);
- instance->td->argv[i++] = strdup(buffer);
- #ifdef GTK2_ENABLED
- instance->visible_signal_id =
- g_signal_connect_after(G_OBJECT(instance->gtkwidget),
- "visibility-notify-event",
- G_CALLBACK(window_visible),
- instance);
- #endif
- if (instance->targetplayer == 1)
- gtk_widget_hide(instance->gtkwidget);
- #endif
- } else {
- instance->player_window = 0;
- }
- }
- if ((instance->mode == NP_FULL) && (instance->noembed == 0)) {
- if (instance->window != 0) {
- snprintf(buffer, 1024, "-wid");
- instance->td->argv[i++] = strdup(buffer);
- #ifdef X_ENABLED
- snprintf(buffer, 1024, "0x%x", (int) instance->window);
- instance->td->argv[i++] = strdup(buffer);
- #endif
- #ifdef GTK_ENABLED
- gtk_widget_set_usize(GTK_WIDGET(instance->status),
- instance->window_width - 20, 19);
- #ifdef GTK2_ENABLED
- instance->player_window =
- gtk_socket_get_id(GTK_SOCKET(instance->drawing_area));
- #endif
- #ifdef GTK1_ENABLED
- instance->player_window =
- GDK_WINDOW_XWINDOW(instance->drawing_area->window);
- #endif
- snprintf(buffer, 1024, "0x%x", (int) instance->player_window);
- instance->td->argv[i++] = strdup(buffer);
- #endif
- } else {
- instance->player_window = 0;
- }
- }
- if ((instance->embed_width == 0)
- || (instance->noembed == 1)) {
- // do nothing
- } else {
- if (instance->mode == NP_EMBED) {
- #ifndef X_DISPLAY_MISSING
- // on remote display, XShm will be disabled.
- // it should not specified aspect.
- if (dispName) {
- if (strncmp(dispName, "unix:", 5) == 0)
- dispName += 4;
- else if (strncmp(dispName, "localhost:", 10) == 0)
- dispName += 9;
- if (*dispName != ':' || atoi(dispName + 1) >= 10) {
- isRemoteDisplay = true;
- instance->maintain_aspect = 0;
- if (DEBUG)
- printf("x11 is running on remote display.n");
- }
- }
- #endif
- if ((isRemoteDisplay == false)
- && (instance->targetplayer == 0)) {
- if (instance->maintain_aspect == 1) {
- snprintf(buffer, 1024, "-vf");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "scale=%s:-3", xval);
- instance->td->argv[i++] = strdup(buffer);
- } else {
- snprintf(buffer, 1024, "-x");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "%s", xval);
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "-y");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "%s", yval);
- instance->td->argv[i++] = strdup(buffer);
- }
- }
- }
- }
- // if (instance->rtsp_use_tcp == 1) {
- // snprintf(buffer, 1024, "-rtsp-stream-over-tcp");
- // instance->td->argv[i++] = strdup(buffer);
- // }
- // if (instance->cachesize > 0) {
- // snprintf(buffer, 1024, "-cache");
- // instance->td->argv[i++] = strdup(buffer);
- // snprintf(buffer, 1024, "%i", instance->cachesize);
- // instance->td->argv[i++] = strdup(buffer);
- // } else {
- // snprintf(buffer, 1024, "-nocache");
- // instance->td->argv[i++] = strdup(buffer);
- // }
- // if (instance->loop == 1) {
- // snprintf(instance->td->argv[i++], 1024, "-loop");
- // snprintf(instance->td->argv[i++], 1024, "0");
- // }
- if (instance->vo) {
- snprintf(buffer, 1024, "-vo");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "%s", instance->vo);
- instance->td->argv[i++] = strdup(buffer);
- if ((strncmp(buffer, "x11", 3) == 0)
- || (strstr(buffer, ",x11") != NULL)) {
- snprintf(buffer, 1024, "-zoom"); /* -vo x11 needs -zoom for rescaling */
- instance->td->argv[i++] = strdup(buffer);
- }
- }
- if (instance->ao) {
- snprintf(buffer, 1024, "-ao");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "%s", instance->ao);
- instance->td->argv[i++] = strdup(buffer);
- }
- if (instance->af) {
- snprintf(buffer, 1024, "-af");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "%s", instance->af);
- instance->td->argv[i++] = strdup(buffer);
- }
- if (instance->output_display) {
- snprintf(buffer, 1024, "-display");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "%s", instance->output_display);
- instance->td->argv[i++] = strdup(buffer);
- }
- if (instance->framedrop == 1) {
- snprintf(buffer, 1024, "-framedrop");
- instance->td->argv[i++] = strdup(buffer);
- }
- if (instance->autosync > 0) {
- snprintf(buffer, 1024, "-autosync");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "%i", instance->autosync);
- instance->td->argv[i++] = strdup(buffer);
- }
- if (instance->mc > 0) {
- snprintf(buffer, 1024, "-mc");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "%i", instance->mc);
- instance->td->argv[i++] = strdup(buffer);
- }
- snprintf(buffer, 1024, "-osdlevel");
- instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "%i", instance->osdlevel);
- instance->td->argv[i++] = strdup(buffer);
- /* some extra flags for download */
- snprintf(buffer, 1024, "-nojoystick"); /* annoying... */
- instance->td->argv[i++] = strdup(buffer);
- if (instance->noconsolecontrols) {
- snprintf(buffer, 1024, "-noconsolecontrols");
- instance->td->argv[i++] = strdup(buffer);
- }
- if (instance->cookies) {
- snprintf(buffer, 1024, "-cookies");
- instance->td->argv[i++] = strdup(buffer);
- }
- // snprintf(buffer, 1024, "-nofs"); /* no full screen */
- // instance->td->argv[i++] = strdup(buffer);
- snprintf(buffer, 1024, "-slave"); /* slave mode */
- instance->td->argv[i++] = strdup(buffer);
- instance->td->argv[i++] = NULL;
- // ok we have the command line setup
- if (DEBUG)
- printf("ready to setup threadsn");
- pthread_attr_setdetachstate(&(instance->thread_attr),
- PTHREAD_CREATE_JOINABLE);
- if (DEBUG)
- printf("creating thread - NP_EMBEDn");
- #ifdef X_ENABLED
- DrawUI(instance->widget, instance, _("Getting playlist..."), 0, -1);
- #endif
- #ifdef GTK_ENABLED
- if (instance->status != NULL)
- gtk_label_set_text(instance->status, _("Getting playlist..."));
- #endif
- if (instance->state < STATE_GETTING_PLAYLIST)
- instance->state = STATE_GETTING_PLAYLIST;
- if (0) {
- printf("SetupPlayer: printing instance->listn");
- printList(instance->list);
- printf("SetupPlayer: printing instance->td->listn");
- printList(instance->td->list);
- }
- if (DEBUG)
- printf("creating player threadn");
- pthread_mutex_lock(&(instance->control_mutex));
- instance->js_state = JS_STATE_UNDEFINED;
- launchPlayerThread(instance);
- instance->threadsetup = 1;
- pthread_mutex_unlock(&(instance->control_mutex));
- // recommended slight pause
- usleep(1);
- if (DEBUG)
- printf("MAIN THREAD DONEn");
- }
- void refresh_frame(char *buffer, _ThreadData * td, Node * node)
- {
- int seconds;
- static int oldseconds = -1;
- char *start;
- char *endptr;
- area *runner;
- area *this_area;
- #ifdef SMILDEBUG
- static FILE *error = NULL;
- char errortmp[64];
- if (!error)
- error = fopen("/tmp/downloadplugin-smil.log", "a");
- #endif
- /* just to be sure */
- if (node == NULL || node->area == NULL)
- return;
- start = buffer;
- while ((start = strstr(start, "A:")) != NULL && strlen(start) > 7) {
- start += 2;
- seconds = (int) strtol(start, &endptr, 0);
- if (seconds == oldseconds || start == endptr)
- continue;
- #ifdef SMILDEBUG
- strlcpy(errortmp, start, 63);
- errortmp[64] = 0;
- fprintf(error, "->seconds: %d, oldseconds: %d, buffer: '%s'n",
- seconds, oldseconds, errortmp);
- fflush(error);
- #endif
- runner = node->area;
- this_area = node->area;
- while (runner) {
- if (runner->begin < seconds
- && runner->begin > this_area->begin)
- this_area = runner;
- if (runner->begin == seconds) {
- NPN_GetURL(td->instance->mInstance,
- runner->url, runner->target);
- break;
- }
- runner = runner->next;
- }
- /*
- * If it was a seek we have to follow.
- */
- if ((oldseconds - seconds > 1 || seconds - oldseconds > 1)
- && !runner)
- NPN_GetURL(td->instance->mInstance, this_area->url,
- this_area->target);
- oldseconds = seconds;
- }
- }
- //return true if we should try to play this again immediately, false if not
- PlayResult *playNode(ThreadData * local_td, Node * local_list,
- char *local_url, int local_mmsstream, int *usefps,
- int *nomouseinput, int *maybeplaylist)
- {
- PlayResult *result = (PlayResult *) NPN_MemAlloc(sizeof(PlayResult));
- char buffer[1024];
- char message[1024];
- int notfound;
- char *vo;
- char vm[10];
- char *cf;
- double cfpercent;
- char *eos;
- char *msg;
- long cfbytes, flags = 0;
- int i,amt;
- int zerocfbytes_count = 0;
- char url_copy[1024];
- int c;
- int length_request_count = 0;
- float lastmedialength = -1.0;
- int lastmediapercent = -1;
- int lastpercent = -1;
- #ifdef GTK_ENABLED
- int fsupdated = 0;
- #endif
- result->errorcode = ERROR_NO_ERROR;
- result->tryagain = TRYAGAIN_FALLBACK;
- result->retval = FALSE;
- /*
- the meaning of the above is as follows:
- TRYAGAIN_TRUE: we should definitely try playing this url again immediately
- TRYAGAIN_FALSE: we should definitely NOT do that.
- TRYAGAIN_FALLBACK if we should try playing this url again immediately
- only if we have a fallback url.
- these are for internal use in this function only. The function
- should still return either 0 or 1 (and never 2).
- */
- pthread_cleanup_push((void (*)(void *))
- pthread_mutex_unlock,
- (void *) &(local_td->instance->control_mutex));
- pthread_mutex_lock(&(local_td->instance->control_mutex));
- sendCommand(local_td->instance, "get_time_length");
- local_td->instance->mediaLength = 0.0;
- pthread_mutex_unlock(&(local_td->instance->control_mutex));
- pthread_cleanup_pop(0);
- #ifdef GTK_ENABLED
- g_idle_add(gtkgui_save_enable, local_td->instance);
- // g_idle_add(gtkgui_refreshbuttonstate, local_td->instance);
- #endif
- // set this to 0 for every new media file;
- local_td->instance->movie_height = 0;
- local_td->instance->movie_width = 0;
- if (local_td->instance->player != NULL) {
- if (DEBUG) {
- printf("Getting file mode flagsn");
- }
- flags = fcntl(fileno(local_td->instance->player), F_GETFL, 0);
- }
- while (1) {
- pthread_testcancel();
- if (local_td->instance->player == NULL)
- break;
- if (feof(local_td->instance->player)) {
- pthread_testcancel();
- break;
- }
- pthread_testcancel();
- assert(local_td != NULL);
- assert(local_td->instance != NULL);
- assert(local_td->instance->control > 0);
- assert(local_td->instance->player != NULL);
- pthread_testcancel();
- #ifdef GTK_ENABLED
- // g_idle_add(gtkgui_save_enable, local_td->instance);
- // g_idle_add(gtkgui_refreshbuttonstate, local_td->instance);
- #endif
- pthread_testcancel();
- if (local_td->instance->player != NULL) {
- // if (fgets(buffer, 1024, local_td->instance->player) == NULL) {
- // continue;
- // }
- // fgets is not a pthread cancel point, so we basically have to rewrite fgets
- // to make this work better. If we cancel the thread while fgets is waiting for
- // for an EOS then we crash.
- buffer[0] = ' ';
- i = 0;
- do {
- pthread_testcancel();
- // need to lock around the read
- pthread_mutex_lock(&(local_td->instance->read_mutex));
- if ((local_td->instance->cancelled == 0)
- && (local_td->instance->player != NULL)) {
- // c = fgetc(local_td->instance->player);
- amt = fread(&c, 1, 1, local_td->instance->player);
- } else {
- c = EOF;
- amt = 0;
- }
- pthread_mutex_unlock(&(local_td->instance->read_mutex));
- if (c == EOF) {
- buffer[i] = ' ';
- break;
- }
- if (c == 0)
- continue;
- buffer[i] = (char) c;
- i += amt;
- if (i >= 1024) {
- buffer[1023] = ' ';
- break;
- }
- } while (((unsigned char) c != 'n'));
- if (buffer[0] == ' ')
- continue;
- else if (i < 1024) // make sure we don't access out of bounds
- buffer[i] = ' '; // make sure we NULL terminate the string
- }
- pthread_testcancel();
- if (DEBUG) {
- if (strlen(buffer) > 0)
- printf("READ: %s n", buffer);
- }
- refresh_frame(buffer, local_td, local_list);
- pthread_testcancel();
- if (strstr(buffer, "STREAM") != NULL) {
- if (local_td->instance->player != NULL) {
- if (DEBUG) {
- printf("Setting file mode to non-blockingn");
- }
- fcntl(fileno(local_td->instance->player), F_SETFL, flags | O_NONBLOCK);
- }
- }
- pthread_testcancel();
- if (strstr(buffer, "Cache size") != NULL || strstr(buffer, "Starting playback") != NULL ) {
- if (local_td->instance->player != NULL) {
- if (DEBUG) {
- printf("Setting file mode back to blockingn");
- }
- fcntl(fileno(local_td->instance->player), F_SETFL, flags);
- }
- }
- pthread_testcancel();
- if (strstr(buffer, "Cache fill:") != NULL) {
- strlcpy(message, strstr(buffer, "Cache fill"), 1024);
- notfound = 1;
- while (notfound) {
- eos = strrchr(message, 'r');
- if (eos == NULL)
- eos = message;
- if (strstr(eos, "Cache fill:") == NULL) {
- // if we don't find "Cache fill:" then replace the r with