~ubuntu-branches/ubuntu/breezy/mplayerplug-in/breezy-backports

« back to all changes in this revision

Viewing changes to Source/plugin-threads.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ubuntu Archive Auto-Backport
  • Date: 2006-01-03 20:29:21 UTC
  • mfrom: (4.1.1 dapper)
  • Revision ID: james.westby@ubuntu.com-20060103202921-ea16kg4tqsao21fp
Tags: 3.17-1ubuntu1~breezy1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
#include <signal.h>
8
8
#include <sys/wait.h>
9
9
#include <sys/param.h>
 
10
#include <errno.h>
10
11
 
11
12
extern int DEBUG;
 
13
extern int errno;
12
14
 
13
15
static void sig_child(int signo)
14
16
{
63
65
    if (instance->mediaCompleteCallback != NULL)
64
66
        NPN_GetURL(instance->mInstance,
65
67
                   instance->mediaCompleteCallback, "_self");
 
68
    if (instance->mediaCompleteWithErrorCallback != NULL)
 
69
        NPN_GetURL(instance->mInstance,
 
70
                   instance->mediaCompleteWithErrorCallback, "_self");
66
71
    return FALSE;
67
72
}
68
73
#endif
103
108
    if (DEBUG)
104
109
        printf("In launchPlayerThread, state = %d\n", instance->state);
105
110
 
106
 
    if (instance->threadlaunched == 1)
 
111
    if (instance->threadlaunched == 1) {
 
112
        if (DEBUG)
 
113
            printf("launchPlayerThread - joining thread\n");
107
114
        pthread_join(instance->player_thread, &thread_return);
108
 
 
 
115
    }
109
116
    if (instance->js_state == JS_STATE_UNDEFINED) {
110
 
 
 
117
        if (DEBUG)
 
118
            printf("launchPlayerThread - creating new thread\n");
111
119
        pthread_create(&(instance->player_thread),
112
120
                       &(instance->thread_attr), playPlaylist,
113
121
                       (void *) (instance->td));
148
156
        pthread_cond_signal(&(instance->playlist_complete_cond));
149
157
        pthread_mutex_unlock(&(instance->playlist_cond_mutex));
150
158
        instance->threadsignaled = 1;
151
 
        pthread_mutex_unlock(&(instance->control_mutex));
152
159
    } else {
153
160
        if (DEBUG)
154
161
            printf("****Player thread did not start correctly****\n");
155
 
        pthread_mutex_unlock(&(instance->control_mutex));
156
162
    }
 
163
    pthread_mutex_unlock(&(instance->control_mutex));
157
164
}
158
165
 
159
 
FILE *mypopen(char **argv, pid_t * pid, int *control)
 
166
FILE *mypopen(char **argv, pid_t * pid, int *control,
 
167
              nsPluginInstance * instance)
160
168
{
161
 
    int filedesr[2], filedesw[2];
 
169
    int filedesr[2], filedesw[2], err;
162
170
    pid_t child;
163
171
    long flags;
164
172
    sigset_t newmask;
189
197
        sigaddset(&newmask, SIGKILL);
190
198
        pthread_sigmask(SIG_UNBLOCK, &newmask, 0L);
191
199
        usleep(500);
192
 
        if (execvp(argv[0], argv) < 0)
 
200
        if (execvp(argv[0], argv) < 0) {
 
201
            err = errno;
 
202
#ifdef GTK_ENABLED
 
203
            snprintf(instance->lastmessage, 1024, "Error: %i - %s", err,
 
204
                     strerror(err));
 
205
            g_idle_add(gtkgui_message, instance);
 
206
#endif
193
207
            perror("execv");
 
208
 
 
209
        }
194
210
        _exit(0);
195
211
 
196
212
    } else {
254
270
        instance->td->list = instance->list;
255
271
    }
256
272
 
 
273
/*
257
274
    if (instance->href) {
258
275
        if (DEBUG)
259
276
            printf("using href for url\n");
260
277
        snprintf(instance->td->list->url, 1024, "%s", instance->href);
261
 
    } else if (instance->fname) {
 
278
    } else 
 
279
*/
 
280
    if (instance->fname) {
262
281
        if (DEBUG)
263
282
            printf("using fname for url\n");
264
283
        snprintf(instance->td->list->url, 1024, "%s", instance->fname);
268
287
        snprintf(instance->td->list->url, 1024, "%s", instance->url);
269
288
    }
270
289
 
 
290
    if ((instance->fname == NULL) && (instance->url == NULL)) {
 
291
        if (DEBUG)
 
292
            printf("using href for url\n");
 
293
        snprintf(instance->td->list->url, 1024, "%s", instance->href);
 
294
    }
 
295
 
271
296
    if (instance->mode == NP_FULL) {
272
297
        snprintf(xval, 32, "%i", instance->window_width);
273
298
        snprintf(yval, 32, "%i", instance->window_height);
274
299
    } else {
275
300
        snprintf(xval, 32, "%i", instance->embed_width);
276
 
        snprintf(yval, 32, "%i", instance->embed_height);
 
301
        if (instance->maintain_aspect == 0 && instance->showcontrols == 1) {
 
302
            snprintf(yval, 32, "%i", instance->embed_height - 16);
 
303
        } else {
 
304
            snprintf(yval, 32, "%i", instance->embed_height);
 
305
        }
 
306
 
277
307
    }
278
308
 
279
309
    baseurl = NULL;
350
380
        }
351
381
    }
352
382
 
353
 
 
354
383
    if ((instance->mode == NP_EMBED) && (instance->noembed == 0)) {
355
384
        if (instance->window != 0) {
356
385
            snprintf(buffer, 1024, "-wid");
370
399
            gtk_fixed_put(GTK_FIXED(instance->fixed_container),
371
400
                          instance->drawing_area, 0, 0);
372
401
            gtk_widget_show(instance->drawing_area);
 
402
            if (instance->targetplayer == 1)
 
403
                gtk_widget_show(instance->gtkwidget);
373
404
            instance->player_window =
374
405
                GDK_WINDOW_XWINDOW(instance->drawing_area->window);
 
406
            if (instance->targetplayer == 1)
 
407
                gtk_widget_hide(instance->gtkwidget);
375
408
            snprintf(buffer, 1024, "0x%x", (int) instance->player_window);
376
409
            instance->td->argv[i++] = strdup(buffer);
 
410
#ifdef GTK2_ENABLED
 
411
            g_signal_connect_after(G_OBJECT(instance->gtkwidget),
 
412
                                   "visibility-notify-event",
 
413
                                   G_CALLBACK(window_visible), instance);
 
414
#endif
377
415
#endif
378
416
        } else {
379
417
            instance->player_window = 0;
428
466
                }
429
467
            }
430
468
#endif
431
 
            if (isRemoteDisplay == false) {
 
469
            if ((isRemoteDisplay == false)
 
470
                && (instance->targetplayer == 0)) {
432
471
                if (instance->maintain_aspect == 1) {
433
472
                    snprintf(buffer, 1024, "-xy");
434
473
                    instance->td->argv[i++] = strdup(buffer);
448
487
        }
449
488
    }
450
489
 
451
 
    if (instance->rtsp_use_tcp == 1) {
452
 
        snprintf(buffer, 1024, "-rtsp-stream-over-tcp");
453
 
        instance->td->argv[i++] = strdup(buffer);
454
 
    }
 
490
//    if (instance->rtsp_use_tcp == 1) {
 
491
//      snprintf(buffer, 1024, "-rtsp-stream-over-tcp");
 
492
//      instance->td->argv[i++] = strdup(buffer);
 
493
//    }
455
494
//    if (instance->cachesize > 0) {
456
495
//      snprintf(buffer, 1024, "-cache");
457
496
//      instance->td->argv[i++] = strdup(buffer);
472
511
        instance->td->argv[i++] = strdup(buffer);
473
512
        snprintf(buffer, 1024, "%s", instance->vo);
474
513
        instance->td->argv[i++] = strdup(buffer);
475
 
        if ((strcmp(buffer, "x11") == 0)
 
514
        if ((strncmp(buffer, "x11", 3) == 0)
476
515
            || (strstr(buffer, ",x11") != NULL)) {
477
516
            snprintf(buffer, 1024, "-zoom");    /* -vo x11 needs -zoom for rescaling */
478
517
            instance->td->argv[i++] = strdup(buffer);
486
525
        instance->td->argv[i++] = strdup(buffer);
487
526
    }
488
527
 
 
528
    if (instance->af) {
 
529
        snprintf(buffer, 1024, "-af");
 
530
        instance->td->argv[i++] = strdup(buffer);
 
531
        snprintf(buffer, 1024, "%s", instance->af);
 
532
        instance->td->argv[i++] = strdup(buffer);
 
533
    }
 
534
 
489
535
    if (instance->output_display) {
490
536
        snprintf(buffer, 1024, "-display");
491
537
        instance->td->argv[i++] = strdup(buffer);
574
620
 
575
621
 
576
622
    pthread_mutex_lock(&(instance->control_mutex));
 
623
    instance->js_state = JS_STATE_UNDEFINED;
577
624
    launchPlayerThread(instance);
578
625
    instance->threadsetup = 1;
579
626
    pthread_mutex_unlock(&(instance->control_mutex));
644
691
 
645
692
//return true if we should try to play this again immediately, false if not 
646
693
 
647
 
int playNode(ThreadData * local_td, Node * local_list, char *local_url,
648
 
             int local_mmsstream, int *usefps, int *nomouseinput,
649
 
             int *maybeplaylist)
 
694
PlayResult *playNode(ThreadData * local_td, Node * local_list,
 
695
                     char *local_url, int local_mmsstream, int *usefps,
 
696
                     int *nomouseinput, int *maybeplaylist)
650
697
{
651
698
 
 
699
    PlayResult *result = (PlayResult *) NPN_MemAlloc(sizeof(PlayResult));
652
700
    char buffer[1024];
653
701
    char message[1024];
654
702
    int notfound;
656
704
    char vm[10];
657
705
    char *cf;
658
706
    double cfpercent;
659
 
    int retval = FALSE;
660
707
    char *eos;
661
708
    char *msg;
662
709
 
665
712
    int zerocfbytes_count = 0;
666
713
    char url_copy[1024];
667
714
    int c;
 
715
    int length_request_count = 0;
 
716
    float lastmedialength = -1.0;
 
717
    int lastmediapercent = -1;
 
718
    int lastpercent = -1;
668
719
#ifdef GTK_ENABLED
669
720
    int fsupdated = 0;
670
721
#endif
671
 
#define TRYAGAIN_FALSE 0
672
 
#define TRYAGAIN_TRUE 1
673
 
#define TRYAGAIN_FALLBACK 2
674
 
 
675
 
    int tryagain = TRYAGAIN_FALLBACK;
676
 
 
 
722
 
 
723
    result->errorcode = ERROR_NO_ERROR;
 
724
    result->tryagain = TRYAGAIN_FALLBACK;
 
725
    result->retval = FALSE;
677
726
 
678
727
/*
679
728
  the meaning of the above is as follows:
692
741
                         (void *) &(local_td->instance->control_mutex));
693
742
    pthread_mutex_lock(&(local_td->instance->control_mutex));
694
743
    sendCommand(local_td->instance, "get_time_length");
 
744
    local_td->instance->mediaLength = 0.0;
695
745
    pthread_mutex_unlock(&(local_td->instance->control_mutex));
696
746
    pthread_cleanup_pop(0);
 
747
#ifdef GTK_ENABLED
 
748
        g_idle_add(gtkgui_save_enable, local_td->instance);
 
749
//      g_idle_add(gtkgui_refreshbuttonstate, local_td->instance);
 
750
#endif
697
751
 
 
752
    // set this to 0 for every new media file;
 
753
    local_td->instance->movie_height = 0;
 
754
    local_td->instance->movie_width = 0;
 
755
    
698
756
    while (1) {
699
757
        pthread_testcancel();
700
758
        if (local_td->instance->player == NULL)
713
771
 
714
772
        pthread_testcancel();
715
773
#ifdef GTK_ENABLED
716
 
        g_idle_add(gtkgui_save_enable, local_td->instance);
 
774
//      g_idle_add(gtkgui_save_enable, local_td->instance);
 
775
//      g_idle_add(gtkgui_refreshbuttonstate, local_td->instance);
717
776
#endif
718
777
 
719
778
        pthread_testcancel();
730
789
            i = 0;
731
790
            do {
732
791
                pthread_testcancel();
733
 
                c = fgetc(local_td->instance->player);
734
 
                if (c == EOF) {
 
792
                // need to lock around the read
 
793
                pthread_mutex_lock(&(local_td->instance->read_mutex));
 
794
 
 
795
                if ((local_td->instance->cancelled == 0) && (local_td->instance->player != NULL)) {
 
796
                        // c = fgetc(local_td->instance->player);
 
797
                        fread(&c,1,1,local_td->instance->player);
 
798
                } else {
 
799
                        c = EOF;
 
800
                }
 
801
                pthread_mutex_unlock(&(local_td->instance->read_mutex));
 
802
 
 
803
                if (c == EOF) {
735
804
                    buffer[i] = '\0';
736
805
                    break;
737
806
                }
780
849
            // Only update the display if there is something worth displaying
781
850
            if (strstr(eos, "Cache fill:") != NULL) {
782
851
                cf = strstr(eos, "Cache fill:");
 
852
                lastpercent = (int)cfpercent;
783
853
                i = sscanf(cf, "Cache fill: %lf %% (%ld bytes)",
784
854
                           &cfpercent, &cfbytes);
785
855
                //the following is a workaround for an mplayer bug
794
864
                }
795
865
                if (zerocfbytes_count >= 1 &&
796
866
                    ((strncmp(local_url, "mms://", 6) == 0) ||
797
 
                     local_mmsstream
798
 
                     && strncmp(local_url, "http://", 7) == 0)) {
 
867
                     (local_mmsstream
 
868
                      && strncmp(local_url, "http://", 7) == 0))) {
799
869
 
800
870
                    if (DEBUG) {
801
871
                        printf("Exiting. Will try again with mmst://\n");
802
872
                    }
803
 
                    tryagain = TRYAGAIN_FALLBACK;
 
873
                    result->tryagain = TRYAGAIN_FALLBACK;
804
874
                    break;
805
875
                }
806
876
 
814
884
#ifdef GTK_ENABLED
815
885
                snprintf(local_td->instance->lastmessage, 1024, "%s",
816
886
                         message);
817
 
                g_idle_add(gtkgui_message, local_td->instance);
818
 
                local_td->instance->percent = (cfpercent / 100.0);
819
 
                g_idle_add(gtkgui_progress, local_td->instance);
 
887
 
 
888
                local_td->instance->percent = (cfpercent / 100.0);
 
889
                if (lastpercent != cfpercent) {
 
890
                        g_idle_add(gtkgui_message, local_td->instance);
 
891
                        g_idle_add(gtkgui_progress, local_td->instance);
 
892
                }
820
893
#endif
 
894
            pthread_mutex_lock(&(local_td->instance->control_mutex));
 
895
            local_td->instance->js_state = JS_STATE_BUFFERING;
 
896
            pthread_mutex_unlock(&(local_td->instance->control_mutex));
 
897
            
821
898
            }
822
899
        }
823
900
 
833
910
            snprintf(local_td->instance->lastmessage, 1024, "%s", message);
834
911
            g_idle_add(gtkgui_message, local_td->instance);
835
912
#endif
 
913
            pthread_mutex_lock(&(local_td->instance->control_mutex));
 
914
            local_td->instance->js_state = JS_STATE_PLAYING;
 
915
            pthread_mutex_unlock(&(local_td->instance->control_mutex));
836
916
        }
837
917
 
838
918
        pthread_testcancel();
852
932
                        local_td->instance->embed_height -
853
933
                        local_list->play_y;
854
934
 
855
 
                if (local_td->instance->player_window != 0) {
 
935
                if (local_td->instance->player_window != 0 && local_td->instance->movie_height != local_list->play_y) { 
856
936
 
857
937
                    local_td->instance->movie_height = local_list->play_y;
858
938
                    local_td->instance->movie_width = local_list->play_x;
869
949
 
870
950
            } else {
871
951
                local_td->instance->panel_height = 16;
872
 
                local_td->instance->movie_height = local_list->play_y;
873
 
                local_td->instance->movie_width = local_list->play_x;
874
 
                if (local_td->instance->player_window != 0) {
 
952
                if (local_td->instance->player_window != 0 && local_td->instance->movie_height != local_list->play_y) {
 
953
                    local_td->instance->movie_height = local_list->play_y;
 
954
                    local_td->instance->movie_width = local_list->play_x;
875
955
 
876
956
#ifdef GTK_ENABLED
877
957
                    g_idle_add(gtkgui_resize, local_td->instance);
906
986
        pthread_testcancel();
907
987
        // mplayer answer back messages
908
988
        if (strstr(buffer, "ANS_LENGTH") != 0) {
 
989
            if ((int) local_td->instance->mediaLength != 0)
 
990
                lastmedialength = local_td->instance->mediaLength;
909
991
            msg = strstr(buffer, "ANS_LENGTH");
910
992
            sscanf(msg, "ANS_LENGTH=%f",
911
993
                   &(local_td->instance->mediaLength));
915
997
        }
916
998
 
917
999
        pthread_testcancel();
 
1000
        // mplayer answer back messages
 
1001
        if (strstr(buffer, "ANS_TIME_POSITION") != 0) {
 
1002
            msg = strstr(buffer, "ANS_TIME_POSITION");
 
1003
            sscanf(msg, "ANS_TIME_POSITION=%f",
 
1004
                   &(local_td->instance->mediaPos));
 
1005
            if (DEBUG > 1)
 
1006
                printf("Media Position = %f\n",
 
1007
                       local_td->instance->mediaPos);
 
1008
            if ((int) local_td->instance->mediaLength > 1) {
 
1009
                lastmediapercent = local_td->instance->mediaPercent;
 
1010
                local_td->instance->mediaPercent =
 
1011
                    (int) ((local_td->instance->mediaPos * 100) /
 
1012
                           local_td->instance->mediaLength);
 
1013
#ifdef GTK_ENABLED
 
1014
                if (lastmediapercent != local_td->instance->mediaPercent) {
 
1015
                    g_idle_add(gtkgui_drawMediaProgress, local_td->instance);
 
1016
                    g_idle_add(gtkgui_refreshbuttonstate, local_td->instance);
 
1017
                }
 
1018
#endif
 
1019
            }
 
1020
        }
 
1021
 
 
1022
        pthread_testcancel();
918
1023
        if (strstr(buffer, "ANS_PERCENT_POSITION") != 0) {
919
1024
            msg = strstr(buffer, "ANS_PERCENT_POSITION");
920
1025
            sscanf(msg, "ANS_PERCENT_POSITION=%i",
921
1026
                   &(local_td->instance->mediaPercent));
922
1027
            if (local_td->instance->mediaPercent == 0) {
923
 
                if (local_td->instance->mediaLength != 0)
 
1028
                if ((int) local_td->instance->mediaLength > 1)
 
1029
                    lastmediapercent = local_td->instance->mediaPercent;
924
1030
                    local_td->instance->mediaPercent =
925
 
                        (int) ((local_td->instance->mediaTime * 100) /
 
1031
                        (int) ((local_td->instance->mediaPos * 100) /
926
1032
                               local_td->instance->mediaLength);
 
1033
#ifdef GTK_ENABLED
 
1034
                if (lastmediapercent != local_td->instance->mediaPercent) {
 
1035
                    g_idle_add(gtkgui_drawMediaProgress, local_td->instance);
 
1036
                    g_idle_add(gtkgui_refreshbuttonstate, local_td->instance);
 
1037
                }
 
1038
#endif
927
1039
            }
928
1040
            if (DEBUG > 1)
929
1041
                printf("Percent Played = %i\n",
930
1042
                       local_td->instance->mediaPercent);
931
 
#ifdef GTK_ENABLED
932
 
            g_idle_add(gtkgui_drawMediaProgress, local_td->instance);
933
 
#endif
934
1043
        }
935
1044
 
936
1045
        pthread_testcancel();
944
1053
                    printf("mediaTime = %f\n",
945
1054
                           local_td->instance->mediaTime);
946
1055
#ifdef GTK_ENABLED
947
 
                g_idle_add(gtkgui_draw, local_td->instance);
 
1056
//              g_idle_add(gtkgui_draw, local_td->instance);
948
1057
#endif
949
1058
            } else {
950
1059
                msg = strstr(buffer, "\rV:");
968
1077
 
969
1078
            pthread_mutex_unlock(&(local_td->instance->control_mutex));
970
1079
            pthread_cleanup_pop(0);
 
1080
            pthread_testcancel();
971
1081
            if (local_td->instance->paused == 0) {
972
1082
                pthread_cleanup_push((void (*)(void *))
973
1083
                                     pthread_mutex_unlock,
974
1084
                                     (void *) &(local_td->instance->
975
1085
                                                control_mutex));
976
1086
                pthread_mutex_lock(&(local_td->instance->control_mutex));
977
 
                sendCommand(local_td->instance, "get_percent_pos");
 
1087
                if ((int) local_td->instance->mediaLength > 1)
 
1088
                    sendCommand(local_td->instance, "get_time_pos");
 
1089
                if (local_td->instance->mediaLength > lastmedialength) {
 
1090
                    sendCommand(local_td->instance, "get_time_length");
 
1091
                } else {
 
1092
                    if (length_request_count < 10) {
 
1093
                        sendCommand(local_td->instance, "get_time_length");
 
1094
                        length_request_count++;
 
1095
                    }
 
1096
                }
978
1097
                pthread_mutex_unlock(&(local_td->instance->control_mutex));
979
1098
                pthread_cleanup_pop(0);
980
1099
#ifdef GTK_ENABLED
985
1104
                }
986
1105
#endif
987
1106
            }
988
 
            tryagain = TRYAGAIN_FALSE;
 
1107
            result->tryagain = TRYAGAIN_FALSE;
989
1108
        }
990
1109
 
991
1110
        pthread_testcancel();
999
1118
            snprintf(local_td->instance->lastmessage, 1024, "%s", message);
1000
1119
            g_idle_add(gtkgui_message, local_td->instance);
1001
1120
#endif
 
1121
            pthread_mutex_lock(&(local_td->instance->control_mutex));
 
1122
            local_td->instance->js_state = JS_STATE_WAITING;
 
1123
            pthread_mutex_unlock(&(local_td->instance->control_mutex));
 
1124
        
 
1125
        }
 
1126
 
 
1127
        pthread_testcancel();
 
1128
        if (strstr(buffer, "Initiated") != NULL) {
 
1129
            snprintf(message, 1024, "%s", buffer);
 
1130
#ifdef X_ENABLED
 
1131
            DrawUI(local_td->instance->widget,
 
1132
                   local_td->instance, message, 0, -1);
 
1133
#endif
 
1134
#ifdef GTK_ENABLED
 
1135
            snprintf(local_td->instance->lastmessage, 1024, "%s", message);
 
1136
            g_idle_add(gtkgui_message, local_td->instance);
 
1137
#endif
1002
1138
        }
1003
1139
 
1004
1140
        pthread_testcancel();
1012
1148
            snprintf(local_td->instance->lastmessage, 1024, "%s", message);
1013
1149
            g_idle_add(gtkgui_message, local_td->instance);
1014
1150
#endif
 
1151
            result->tryagain = TRYAGAIN_FALSE;
 
1152
            result->errorcode = ERROR_NO_STREAM;
 
1153
            break;
1015
1154
        }
1016
1155
 
1017
1156
 
1018
1157
        pthread_testcancel();
1019
1158
        if (strstr(buffer, "Example: mplayer -playlist ") != NULL) {
1020
1159
            if (*maybeplaylist == 0) {
1021
 
                tryagain = TRYAGAIN_TRUE;
 
1160
                result->tryagain = TRYAGAIN_TRUE;
1022
1161
                *maybeplaylist = 1;
1023
 
            } else
1024
 
                tryagain = TRYAGAIN_FALSE;
 
1162
            } else {
 
1163
                result->tryagain = TRYAGAIN_FALSE;
 
1164
                result->errorcode = ERROR_NOT_PLAYLIST;
 
1165
            }
1025
1166
            break;
1026
1167
        }
1027
1168
 
1028
1169
        pthread_testcancel();
1029
 
        if (strstr(buffer, "Stream not seekable") != NULL) {
1030
 
            if (*maybeplaylist == 0) {
1031
 
                tryagain = TRYAGAIN_TRUE;
1032
 
                *maybeplaylist = 1;
1033
 
            } else
1034
 
                tryagain = TRYAGAIN_FALSE;
 
1170
        if (strstr(buffer, "File not found") != NULL) {
 
1171
            result->tryagain = TRYAGAIN_FALSE;
 
1172
            result->errorcode = ERROR_FILE_NOT_FOUND;
1035
1173
            break;
1036
1174
        }
1037
1175
 
1038
1176
        pthread_testcancel();
1039
1177
        if (strstr(buffer, "Error while decoding") != NULL) {
1040
 
            if (!isMms(local_url)) {
 
1178
            if (!isMms(local_url, local_td->instance->nomediacache)) {
1041
1179
                if (DEBUG)
1042
1180
                    printf("Resetting stream, 1 sec rewind\n");
1043
1181
                pthread_suspend(1000);
1058
1196
            if (DEBUG)
1059
1197
                printf("----player thread: breaking read loop - Quit\n");
1060
1198
            local_td->instance->js_state = JS_STATE_UNDEFINED;
1061
 
            tryagain = TRYAGAIN_FALSE;
1062
 
            break;
1063
 
        }
 
1199
            result->tryagain = TRYAGAIN_FALSE;
 
1200
            break;
 
1201
        }
 
1202
 
 
1203
        pthread_testcancel();
 
1204
        if (strstr
 
1205
            (buffer,
 
1206
             "MPlayer interrupted by signal 13 in module: demux_open") !=
 
1207
            NULL) {
 
1208
            if (DEBUG)
 
1209
                printf
 
1210
                    ("----player thread: breaking read loop - demux_open\n");
 
1211
            local_td->instance->js_state = JS_STATE_UNDEFINED;
 
1212
            if (local_td->instance->rtsp_use_tcp == 1) {
 
1213
                local_td->instance->rtsp_use_tcp = 0;
 
1214
                result->tryagain = TRYAGAIN_TRUE;
 
1215
            } else {
 
1216
                result->tryagain = TRYAGAIN_FALSE;
 
1217
                result->errorcode = ERROR_PLAYER_INTERRUPTED;
 
1218
            }
 
1219
            break;
 
1220
        }
 
1221
 
1064
1222
 
1065
1223
        pthread_testcancel();
1066
1224
        // detect Quicktime file with old codec
1070
1228
                printf
1071
1229
                    ("----player thread: waiting to download entire movie\n");
1072
1230
            }
1073
 
            tryagain = TRYAGAIN_TRUE;
 
1231
            result->tryagain = TRYAGAIN_TRUE;
1074
1232
            while (1) {
1075
1233
                pthread_testcancel();
1076
1234
                usleep(100);
1077
1235
                pthread_testcancel();
 
1236
                pthread_mutex_lock(&(local_td->instance->control_mutex));
 
1237
                local_td->instance->js_state = JS_STATE_BUFFERING;
 
1238
                pthread_mutex_unlock(&(local_td->instance->control_mutex));
1078
1239
                pthread_mutex_lock(&(local_td->instance->playlist_mutex));
1079
1240
                local_td->instance->state = STATE_DOWNLOADING;
1080
1241
                if (local_list->retrieved == 1) {
1081
1242
                    local_td->instance->state = STATE_PLAYING;
 
1243
                    pthread_mutex_lock(&(local_td->instance->control_mutex));
 
1244
                    local_td->instance->js_state = JS_STATE_PLAYING;
 
1245
                    pthread_mutex_unlock(&(local_td->instance->control_mutex));
1082
1246
                    pthread_mutex_unlock(&
1083
1247
                                         (local_td->instance->
1084
1248
                                          playlist_mutex));
1093
1257
 
1094
1258
        pthread_testcancel();
1095
1259
        if (strstr(buffer, "FPS not specified") != NULL) {
1096
 
            tryagain = TRYAGAIN_TRUE;
 
1260
            result->tryagain = TRYAGAIN_TRUE;
1097
1261
            *usefps = 1;
1098
1262
            break;
1099
1263
        }
1101
1265
        pthread_testcancel();
1102
1266
        if (strstr(buffer, "nomouseinput") != NULL) {
1103
1267
            *nomouseinput = 0;
1104
 
            tryagain = TRYAGAIN_TRUE;
 
1268
            result->tryagain = TRYAGAIN_TRUE;
1105
1269
            break;
1106
1270
        }
1107
 
// Possible work around for cinema now site     
1108
 
//      if (strstr(buffer, "ASF file format detected") != NULL) {
1109
 
//          tryagain = TRYAGAIN_TRUE;
1110
 
//          local_list->playlist = 1;
1111
 
//          break;
1112
 
//      }
1113
 
 
1114
1271
 
1115
1272
        pthread_testcancel();
1116
1273
        if (strstr(buffer, "Exiting") != NULL) {
1123
1280
                g_idle_add(gtkgui_drawMediaProgress, local_td->instance);
1124
1281
#endif
1125
1282
            }
1126
 
            tryagain = TRYAGAIN_FALSE;
 
1283
            result->tryagain = TRYAGAIN_FALSE;
 
1284
            result->errorcode = ERROR_NO_ERROR;
1127
1285
            break;
1128
1286
        }
1129
1287
 
1133
1291
            if (DEBUG)
1134
1292
                printf
1135
1293
                    ("----player thread: breaking read loop - interrupted\n");
 
1294
            if (strstr(buffer, "video_read_frame") != NULL) {
 
1295
                local_td->instance->js_state = JS_STATE_UNDEFINED;
 
1296
                if (local_td->instance->rtsp_use_tcp == 1) {
 
1297
                    local_td->instance->rtsp_use_tcp = 0;
 
1298
                    result->tryagain = TRYAGAIN_TRUE;
 
1299
                } else {
 
1300
#ifdef GTK_ENABLED
 
1301
                    snprintf(local_td->instance->lastmessage, 1024,
 
1302
                             "Error: %s", buffer);
 
1303
                    g_idle_add(gtkgui_message, local_td->instance);
 
1304
#endif
 
1305
                    result->tryagain = TRYAGAIN_FALSE;
 
1306
                    result->errorcode = ERROR_PLAYER_INTERRUPTED;
 
1307
                }
 
1308
            }
 
1309
            break;
 
1310
        }
 
1311
 
 
1312
        pthread_testcancel();
 
1313
        if (strstr(buffer, "execv") != NULL) {
 
1314
            if (DEBUG)
 
1315
                printf
 
1316
                    ("----player thread: breaking read loop - execv failed\n");
 
1317
            local_td->instance->js_state = JS_STATE_UNDEFINED;
 
1318
#ifdef GTK_ENABLED
 
1319
            snprintf(local_td->instance->lastmessage, 1024, "Error: %s %s",
 
1320
                     local_td->argv[0], buffer);
 
1321
            g_idle_add(gtkgui_message, local_td->instance);
 
1322
#endif
 
1323
            result->tryagain = TRYAGAIN_FALSE;
 
1324
            result->errorcode = ERROR_EXECV;
1136
1325
            break;
1137
1326
        }
1138
1327
 
1140
1329
        if (strstr(buffer, "explicit kill") != NULL) {
1141
1330
            if (DEBUG)
1142
1331
                printf("----player thread: breaking read loop - killed\n");
 
1332
            result->tryagain = TRYAGAIN_FALSE;
 
1333
            result->errorcode = ERROR_EXPLICIT_KILL;
1143
1334
            break;
1144
1335
        }
1145
1336
 
1146
1337
        pthread_testcancel();
 
1338
/*      commmented out to make BBC site work    
1147
1339
        if (strstr(buffer, "everything done") != NULL) {
1148
1340
            if (DEBUG)
1149
1341
                printf
1150
1342
                    ("----player thread: breaking read loop - codec issue\n");
 
1343
            result->tryagain = TRYAGAIN_FALSE;
 
1344
            result->errorcode = ERROR_CODEC_FAILURE;
1151
1345
            break;
1152
1346
        }
1153
 
 
 
1347
*/
1154
1348
 
1155
1349
        assert(local_td->instance->player != NULL);
1156
1350
 
1157
1351
    }                           // end of READ LOOP
1158
1352
 
1159
1353
    if (DEBUG) {
1160
 
        printf("----player thread: tryagain = %d\n", tryagain);
 
1354
        printf("----player thread: tryagain = %d\n", result->tryagain);
1161
1355
    }
1162
1356
    //we always return either true or false
1163
 
    if (tryagain == TRYAGAIN_TRUE) {
1164
 
        retval = TRUE;
1165
 
    }
1166
 
 
1167
 
    if (tryagain == TRYAGAIN_FALSE) {
1168
 
        retval = FALSE;
1169
 
    }
1170
 
 
1171
 
    if (tryagain == TRYAGAIN_FALLBACK) {
 
1357
    if (result->tryagain == TRYAGAIN_TRUE) {
 
1358
        result->retval = TRUE;
 
1359
    }
 
1360
 
 
1361
    if (result->tryagain == TRYAGAIN_FALSE) {
 
1362
        result->retval = FALSE;
 
1363
    }
 
1364
 
 
1365
    if (result->tryagain == TRYAGAIN_FALLBACK) {
1172
1366
        //fallback to msst if we can
1173
1367
        strlcpy(url_copy, local_url, 1023);
1174
1368
        url_copy[1023] = '\0';
1175
1369
 
1176
1370
        if (strncmp(local_url, "mms://", 6) == 0) {
1177
1371
            snprintf(local_url, 1023, "mmst://%s", url_copy + 6);
1178
 
            retval = TRUE;
 
1372
            result->retval = TRUE;
1179
1373
        } else if (local_mmsstream &&
1180
1374
                   strncmp(local_url, "http://", 7) == 0) {
1181
1375
 
1182
1376
            snprintf(local_url, 1023, "mmst://%s", url_copy + 7);
1183
 
            retval = TRUE;
 
1377
            result->retval = TRUE;
1184
1378
        } else {
1185
 
            retval = FALSE;
 
1379
            result->retval = FALSE;
1186
1380
        }
1187
1381
    }
1188
 
 
1189
 
    return retval;
 
1382
#ifdef GTK_ENABLED
 
1383
    if (strstr(local_td->instance->lastmessage, "Error") == NULL) {
 
1384
        snprintf(local_td->instance->lastmessage, 1024, _("Stopped"));
 
1385
        g_idle_add(gtkgui_message, local_td->instance);
 
1386
    }
 
1387
#endif
 
1388
    return result;
1190
1389
}
1191
1390
 
1192
1391
void *playPlaylist(void *td)
1193
1392
{
1194
1393
 
 
1394
    PlayResult *result = NULL;
1195
1395
    FILE *playlist;
1196
1396
    char cmd[2048];
1197
1397
    char message[1024];
1198
1398
    char mmsplaylist[1024];
1199
1399
    char buffer[1024];          // scratch pad
 
1400
    char *p;                    // pointer to find the ( in the callback
1200
1401
 
1201
1402
    int argc = 0, base_argc = 0;
1202
1403
    ThreadData *local_td;
1213
1414
    int nomouseinput;
1214
1415
    int maybeplaylist;
1215
1416
    int listempty;
 
1417
    int lasterror = -1;
1216
1418
 
1217
1419
    local_td = (ThreadData *) td;
1218
1420
    local_list = local_td->list;
1221
1423
        pthread_exit(0);
1222
1424
 
1223
1425
    if (DEBUG)
1224
 
        printf("----player thread: in playPlayList\n");
 
1426
        printf("----player thread: in playPlaylist\n");
1225
1427
 
1226
1428
    pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock,
1227
1429
                         (void *) &(local_td->instance->
1241
1443
    if (local_td->instance->state < STATE_STARTED_PLAYER) {
1242
1444
        // wait for playlist_complete_cond to be signalled
1243
1445
        // this should happen when we have completed getting all the playlist elements
 
1446
        local_td->instance->state = STATE_WAITING_FOR_SIGNAL;
1244
1447
        pthread_cond_wait(&(local_td->instance->playlist_complete_cond),
1245
1448
                          &(local_td->instance->playlist_cond_mutex));
1246
1449
        pthread_mutex_unlock(&(local_td->instance->playlist_cond_mutex));
1247
1450
 
1248
1451
        pthread_testcancel();
1249
1452
        sleep(1);
1250
 
        // playlist_cond_mutex should be locked now
 
1453
        // playlist_cond_mutex should be unlocked now
1251
1454
        if (local_td != NULL) {
1252
1455
            if (DEBUG > 1)
1253
1456
                printf("local_td = %p\n", local_td);
1275
1478
                    ("We were signalled to start but local_td is NULL, should not happen\n");
1276
1479
            pthread_exit(0);
1277
1480
        }
 
1481
    } else {
 
1482
        local_td->instance->threadsignaled = 1;
1278
1483
    }
1279
1484
 
1280
1485
    pthread_cleanup_pop(0);
1418
1623
                printf("----player thread: nothing on the list to play\n");
1419
1624
            listempty = 1;
1420
1625
            local_mmsstream = 0;
 
1626
            // update MediaCompleteWithError Callback with PLAYLIST EMPTY but only if we have not played anything
 
1627
            if ((local_td->instance->mediaCompleteWithErrorCallback !=
 
1628
                 NULL) && (lasterror == -1)) {
 
1629
                if (DEBUG)
 
1630
                    printf("mediaCompleteWithError(before) = %s\n",
 
1631
                           local_td->instance->
 
1632
                           mediaCompleteWithErrorCallback);
 
1633
                strlcpy(message,
 
1634
                        local_td->instance->mediaCompleteWithErrorCallback,
 
1635
                        1024);
 
1636
                p = index(message, '(');
 
1637
                if (p == NULL) {
 
1638
                    p = message + strlen(message);
 
1639
                }
 
1640
                *p = '\0';
 
1641
                snprintf(buffer, 1024, "%s(%i);", message,
 
1642
                         ERROR_PLAYLIST_EMPTY);
 
1643
                NPN_MemFree(local_td->instance->
 
1644
                            mediaCompleteWithErrorCallback);
 
1645
                local_td->instance->mediaCompleteWithErrorCallback =
 
1646
                    (char *) NPN_MemAlloc(strlen(buffer));
 
1647
                strlcpy(local_td->instance->mediaCompleteWithErrorCallback,
 
1648
                        buffer, strlen(buffer));
 
1649
                if (DEBUG)
 
1650
                    printf("mediaCompleteWithError(after) = %s\n",
 
1651
                           local_td->instance->
 
1652
                           mediaCompleteWithErrorCallback);
 
1653
            }
1421
1654
        } else {
1422
1655
            //we have a node to play
1423
1656
            if (DEBUG)
1442
1675
        maybeplaylist = 0;
1443
1676
 
1444
1677
        do {
 
1678
            if (result != NULL) {
 
1679
                lasterror = result->errorcode;
 
1680
                NPN_MemFree(result);
 
1681
                result = NULL;
 
1682
            }
1445
1683
 
1446
1684
            pthread_testcancel();
1447
1685
 
1482
1720
                usefps = 0;
1483
1721
            }
1484
1722
 
 
1723
            if (local_td->instance->rtsp_use_tcp == 1) {
 
1724
                snprintf(buffer, 1024, "-rtsp-stream-over-tcp");
 
1725
                local_td->argv[argc++] = strdup(buffer);
 
1726
            }
 
1727
 
1485
1728
            if (nomouseinput) {
1486
1729
                local_td->argv[argc++] = strdup("-nomouseinput");
1487
1730
//          } else {
1521
1764
                }
1522
1765
            } else {
1523
1766
                if (strlen(local_list->fname) == 0) {
 
1767
                    if (local_list->playlist == 1 || maybeplaylist != 0)
 
1768
                        local_td->argv[argc++] = strdup("-playlist");
1524
1769
                    local_td->argv[argc++] = strdup(local_url);
1525
1770
                } else {
1526
1771
                    local_td->argv[argc++] = strdup("-nocache");
 
1772
                    if (local_list->playlist == 1 || maybeplaylist != 0)
 
1773
                        local_td->argv[argc++] = strdup("-playlist");
1527
1774
                    local_td->argv[argc++] = strdup(local_list->fname);
1528
1775
                }
1529
1776
            }
1530
1777
 
1531
 
            if (local_list->playlist == 1 || maybeplaylist != 0)
1532
 
                local_td->argv[argc++] = strdup("-playlist");
1533
1778
 
1534
1779
            if (DEBUG) {
1535
1780
                printf("----player thread: URL: %s\n", local_url);
1549
1794
 
1550
1795
            local_td->instance->player =
1551
1796
                mypopen(local_td->argv, &(local_td->instance->pid),
1552
 
                        &(local_td->instance->control));
 
1797
                        &(local_td->instance->control),
 
1798
                        local_td->instance);
1553
1799
            if (local_td->instance->player != NULL) {
1554
1800
                local_td->instance->js_state = JS_STATE_PLAYING;
1555
1801
            }
1566
1812
                local_td->instance->mediaLength = 0.0;
1567
1813
                local_td->instance->mediaPercent = 0;
1568
1814
 
1569
 
                tryagain =
 
1815
                result =
1570
1816
                    playNode(local_td, local_list, local_url,
1571
1817
                             local_mmsstream, &usefps, &nomouseinput,
1572
1818
                             &maybeplaylist);
1573
1819
 
1574
 
                if (DEBUG)
 
1820
                pthread_mutex_lock(&(local_td->instance->control_mutex));
 
1821
                local_td->instance->js_state = JS_STATE_TRANSITIONING;
 
1822
                pthread_mutex_unlock(&(local_td->instance->control_mutex));
 
1823
 
 
1824
                if (DEBUG)
1575
1825
                    printf
1576
1826
                        ("----player thread: playNode returned = %d\n",
1577
 
                         tryagain);
 
1827
                         result->retval);
1578
1828
 
1579
1829
                pthread_testcancel();
1580
1830
                assert(local_list != NULL);
1586
1836
 
1587
1837
                // this cancels the download of this media
1588
1838
                // if there are more than 1, saves bandwidth
1589
 
                //also revents us from playing it again
 
1839
                // also revents us from playing it again
1590
1840
                pthread_mutex_lock(&(local_td->instance->playlist_mutex));
1591
 
                if (!tryagain) {
 
1841
                if (!(result->retval)) {
1592
1842
                    local_list->played = 1;
1593
1843
                }
1594
1844
                pthread_mutex_unlock(&
1597
1847
                assert(local_td->instance != NULL);
1598
1848
 
1599
1849
                //close the pipes to mplayer
1600
 
                pthread_mutex_lock(&(local_td->instance->control_mutex));
1601
 
                local_td->instance->js_state = JS_STATE_TRANSITIONING;
1602
 
                pthread_mutex_unlock(&(local_td->instance->control_mutex));
1603
1850
 
1604
1851
 
1605
1852
                assert(local_td->instance->control > 0);
1616
1863
                local_td->instance->state = STATE_PLAYLIST_NEXT;
1617
1864
 
1618
1865
            }
1619
 
        } while (tryagain);
 
1866
            // update MediaCompleteWithError Callback
 
1867
            if (local_td->instance->mediaCompleteWithErrorCallback != NULL) {
 
1868
                if (DEBUG)
 
1869
                    printf("mediaCompleteWithError(before) = %s\n",
 
1870
                           local_td->instance->
 
1871
                           mediaCompleteWithErrorCallback);
 
1872
                strlcpy(message,
 
1873
                        local_td->instance->mediaCompleteWithErrorCallback,
 
1874
                        1024);
 
1875
                p = index(message, '(');
 
1876
                if (p == NULL) {
 
1877
                    p = message + strlen(message);
 
1878
                }
 
1879
                *p = '\0';
 
1880
                snprintf(buffer, 1024, "%s(%i);", message,
 
1881
                         result->errorcode);
 
1882
                NPN_MemFree(local_td->instance->
 
1883
                            mediaCompleteWithErrorCallback);
 
1884
                local_td->instance->mediaCompleteWithErrorCallback =
 
1885
                    (char *) NPN_MemAlloc(strlen(buffer));
 
1886
                strlcpy(local_td->instance->mediaCompleteWithErrorCallback,
 
1887
                        buffer, strlen(buffer));
 
1888
                if (DEBUG)
 
1889
                    printf("mediaCompleteWithError(after) = %s\n",
 
1890
                           local_td->instance->
 
1891
                           mediaCompleteWithErrorCallback);
 
1892
            }
 
1893
 
 
1894
        } while (result->retval);
1620
1895
 
1621
1896
        local_td->instance->currentnode = NULL;
1622
1897
 
1656
1931
        g_idle_add(mediacallback, local_td->instance);
1657
1932
    }
1658
1933
#endif
1659
 
 
 
1934
#ifdef X_ENABLED
 
1935
    if (local_td->instance->mediaCompleteCallback != NULL)
 
1936
        NPN_GetURL(local_td->instance->mInstance,
 
1937
                   local_td->instance->mediaCompleteCallback, "_self");
 
1938
    if (local_td->instance->mediaCompleteWithErrorCallback != NULL)
 
1939
        NPN_GetURL(local_td->instance->mInstance,
 
1940
                   local_td->instance->mediaCompleteWithErrorCallback,
 
1941
                   "_self");
 
1942
#endif
 
1943
#ifdef GTK2_ENABLED
 
1944
    if (GTK_IS_WIDGET(local_td->instance->src_event_box)) {
 
1945
        gtk_widget_show(local_td->instance->src_event_box);
 
1946
    }
 
1947
#endif
1660
1948
    if (DEBUG) {
1661
1949
        printf("----player thread: callbacks complete\n");
1662
1950
    }
1683
1971
    if (DEBUG) {
1684
1972
        printf("----player thread: normal exit\n");
1685
1973
    }
1686
 
 
1687
 
    pthread_exit(0);
 
1974
    //pthread_exit(0);
1688
1975
 
1689
1976
    return NULL;
1690
1977
}