Ejemplo n.º 1
0
   // Video thread
   void Scheduler::video_thread_fn()
   {
      auto vid = GL::shared(file->video().width, file->video().height, file->video().aspect_ratio, file->video().ctx->pix_fmt);
      video = vid;
      auto event = GLEvent::shared();

      if (file->sub().active)
         sub_renderer = ASSRenderer::shared(file->sub().fonts, file->sub().ass_data, file->video().width, file->video().height);

      AVFrame *frame = avcodec_alloc_frame();

      // Add event handler for GL.
      add_event_handler(event);

      while (video_thread_active && vid_pkt_queue.alive())
      {
         event->poll(); 
         avlock.lock();
         if (vid_pkt_queue.size() > 0 && !is_paused)
         {
            auto pkt = vid_pkt_queue.pull();
            avlock.unlock();
            process_video(pkt.get(), vid, frame);

            if (file->sub().active)
               process_subtitle(vid);

            // We have to calculate how long we should wait before swapping frame to screen.
            // We sync everything to audio clock.
            double delta = get_time();

            avlock.lock();
            delta -= audio_pts_ts;
            double sleep_time = video_pts - (audio_pts + delta);
            avlock.unlock();

            // Yes, it can happen! :(
            if (delta < 0.0)
               delta = 0.0;
            //std::cout << "Delta: " << delta << std::endl;

            if (video_pts > (audio_pts + delta) && audio_thread_active)
            {
               double last_frame_delta = get_time();
               last_frame_delta -= video_pts_ts;

               // :(
               if (last_frame_delta < 0.0)
                  last_frame_delta = 0.0;

               // We try to keep the sleep time to a somewhat small value to avoid choppy video in some cases.
               // Max sleep time should be a bit over 1 frame time to allow audio to catch up.
               double max_sleep = 1.2 * frame_time() - last_frame_delta;

               if (max_sleep < 0.0)
                  max_sleep = 0.0;

               if (sleep_time > max_sleep)
               {
                  sleep_time = max_sleep;
               }
               //std::cout << "Sleep for " << sleep_time << std::endl;
               sync_sleep(sleep_time);
            }

            video_pts_ts = get_time();
            vid->flip();
         }
         else
         {
            avlock.unlock();

            if (is_paused)
               sync_sleep(0.01);
            else
            {
               // Having some race conditions... quickfix it for now.
               vid_pkt_queue.wait();
               //sync_sleep(0.01);
               //vid_pkt_queue.signal();
            }
         }
      }
      video_thread_active = false;
      av_free(frame);
   }
Ejemplo n.º 2
0
//-------------------------------------------------------------------
// PURPOSE: Parse script (conf.script_file) for parameters and title
//-------------------------------------------------------------------
static void script_scan()
{
    // Reset everything
    sc_param *p = script_params;
    while (p)
    {
        if (p->name)       free(p->name);
        if (p->desc)       free(p->desc);
        if (p->options)    free(p->options);
        if (p->option_buf) free(p->option_buf);
        sc_param *l = p;
        p = p->next;
        free(l);
    }
    script_params = tail = 0;
    script_param_count = 0;

    parse_version(&script_version, "1.3.0.0", 0);
    script_has_version = 0;
    is_script_loaded = 0;

    // Load script file
    const char *buf=0;
    if (conf.script_file[0] != 0)
        buf = load_file_to_length(conf.script_file, 0, 1, 4096);    // Assumes parameters are in first 4K of script file

    // Check file loaded
    if (buf == 0)
    {
        strcpy(script_title, "NO SCRIPT");
        return;
    }

    // Build title from name (in case no title in script)
    const char *c = get_script_filename();
    strncpy(script_title, c, sizeof(script_title)-1);
    script_title[sizeof(script_title)-1]=0;

    // Fillup order, defaults
    const char *ptr = buf;
    while (ptr[0])
    {
        ptr = skip_whitespace(ptr);
        if (ptr[0] == '@')
        {
            if (strncmp("@title", ptr, 6)==0)
            {
                process_title(ptr+6);
            }
            else if (strncmp("@subtitle", ptr, 9)==0)
            {
                process_subtitle(ptr+9);
            }
            else if (strncmp("@param", ptr, 6)==0)
            {
                process_param(ptr+6);
            }
            else if (strncmp("@default", ptr, 8)==0)
            {
                process_default(ptr+8, 1);
            }
            else if (strncmp("@range", ptr, 6)==0)
            {
                process_range(ptr+6);
            }
            else if (strncmp("@values", ptr, 7)==0)
            {
                process_values(ptr+7);
            }
            else if (strncmp("@chdk_version", ptr, 13)==0)
            {
                ptr = skip_whitespace(ptr+13);
                parse_version(&script_version, ptr, 0);
                script_has_version = 1;
            }
        }
        else if (ptr[0] == '#')
        {
            process_single(ptr+1);
        }
        ptr = skip_eol(ptr);
    }

    free((void*)buf);
    is_script_loaded = 1;
}