170 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * This program is free software; you can redistribute it and/or
 | 
						|
 * modify it under the terms of the GNU General Public License
 | 
						|
 * as published by the Free Software Foundation; either version 2
 | 
						|
 * of the License, or (at your option) any later version.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program; if not, write to the Free Software Foundation,
 | 
						|
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
						|
 *
 | 
						|
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 | 
						|
 * All rights reserved.
 | 
						|
 */
 | 
						|
 | 
						|
/** \file
 | 
						|
 * \ingroup spseq
 | 
						|
 */
 | 
						|
 | 
						|
#include "DNA_sequence_types.h"
 | 
						|
#include "DNA_sound_types.h"
 | 
						|
 | 
						|
#include "BLI_listbase.h"
 | 
						|
#include "BLI_threads.h"
 | 
						|
 | 
						|
#include "BKE_context.h"
 | 
						|
#include "BKE_global.h"
 | 
						|
#include "BKE_sound.h"
 | 
						|
 | 
						|
#include "WM_api.h"
 | 
						|
#include "WM_types.h"
 | 
						|
 | 
						|
#include "ED_screen.h"
 | 
						|
 | 
						|
#include "MEM_guardedalloc.h"
 | 
						|
 | 
						|
#include "sequencer_intern.h"
 | 
						|
 | 
						|
typedef struct PreviewJob {
 | 
						|
  ListBase previews;
 | 
						|
  ThreadMutex *mutex;
 | 
						|
  Scene *scene;
 | 
						|
  int total;
 | 
						|
  int processed;
 | 
						|
} PreviewJob;
 | 
						|
 | 
						|
typedef struct PreviewJobAudio {
 | 
						|
  struct PreviewJobAudio *next, *prev;
 | 
						|
  struct Main *bmain;
 | 
						|
  bSound *sound;
 | 
						|
  int lr; /* Sample left or right. */
 | 
						|
  int startframe;
 | 
						|
  bool waveform; /* Reload sound or waveform. */
 | 
						|
} PreviewJobAudio;
 | 
						|
 | 
						|
static void free_preview_job(void *data)
 | 
						|
{
 | 
						|
  PreviewJob *pj = (PreviewJob *)data;
 | 
						|
 | 
						|
  BLI_mutex_free(pj->mutex);
 | 
						|
  BLI_freelistN(&pj->previews);
 | 
						|
  MEM_freeN(pj);
 | 
						|
}
 | 
						|
 | 
						|
/* Only this runs inside thread. */
 | 
						|
static void preview_startjob(void *data, short *stop, short *do_update, float *progress)
 | 
						|
{
 | 
						|
  PreviewJob *pj = data;
 | 
						|
  PreviewJobAudio *previewjb;
 | 
						|
 | 
						|
  BLI_mutex_lock(pj->mutex);
 | 
						|
  previewjb = pj->previews.first;
 | 
						|
  BLI_mutex_unlock(pj->mutex);
 | 
						|
 | 
						|
  while (previewjb) {
 | 
						|
    PreviewJobAudio *preview_next;
 | 
						|
    bSound *sound = previewjb->sound;
 | 
						|
 | 
						|
    BKE_sound_read_waveform(previewjb->bmain, sound, stop);
 | 
						|
 | 
						|
    if (*stop || G.is_break) {
 | 
						|
      BLI_mutex_lock(pj->mutex);
 | 
						|
      previewjb = previewjb->next;
 | 
						|
      BLI_mutex_unlock(pj->mutex);
 | 
						|
      while (previewjb) {
 | 
						|
        sound = previewjb->sound;
 | 
						|
 | 
						|
        /* Make sure we cleanup the loading flag! */
 | 
						|
        BLI_spin_lock(sound->spinlock);
 | 
						|
        sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
 | 
						|
        BLI_spin_unlock(sound->spinlock);
 | 
						|
 | 
						|
        BLI_mutex_lock(pj->mutex);
 | 
						|
        previewjb = previewjb->next;
 | 
						|
        BLI_mutex_unlock(pj->mutex);
 | 
						|
      }
 | 
						|
 | 
						|
      BLI_mutex_lock(pj->mutex);
 | 
						|
      BLI_freelistN(&pj->previews);
 | 
						|
      pj->total = 0;
 | 
						|
      pj->processed = 0;
 | 
						|
      BLI_mutex_unlock(pj->mutex);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    BLI_mutex_lock(pj->mutex);
 | 
						|
    preview_next = previewjb->next;
 | 
						|
    BLI_freelinkN(&pj->previews, previewjb);
 | 
						|
    previewjb = preview_next;
 | 
						|
    pj->processed++;
 | 
						|
    *progress = (pj->total > 0) ? (float)pj->processed / (float)pj->total : 1.0f;
 | 
						|
    *do_update = true;
 | 
						|
    BLI_mutex_unlock(pj->mutex);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
static void preview_endjob(void *data)
 | 
						|
{
 | 
						|
  PreviewJob *pj = data;
 | 
						|
 | 
						|
  WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, pj->scene);
 | 
						|
}
 | 
						|
 | 
						|
void sequencer_preview_add_sound(const bContext *C, Sequence *seq)
 | 
						|
{
 | 
						|
  wmJob *wm_job;
 | 
						|
  PreviewJob *pj;
 | 
						|
  ScrArea *area = CTX_wm_area(C);
 | 
						|
  PreviewJobAudio *audiojob = MEM_callocN(sizeof(PreviewJobAudio), "preview_audio");
 | 
						|
  wm_job = WM_jobs_get(CTX_wm_manager(C),
 | 
						|
                       CTX_wm_window(C),
 | 
						|
                       CTX_data_scene(C),
 | 
						|
                       "Strip Previews",
 | 
						|
                       WM_JOB_PROGRESS,
 | 
						|
                       WM_JOB_TYPE_SEQ_BUILD_PREVIEW);
 | 
						|
 | 
						|
  /* Get the preview job if it exists. */
 | 
						|
  pj = WM_jobs_customdata_get(wm_job);
 | 
						|
 | 
						|
  if (!pj) {
 | 
						|
    pj = MEM_callocN(sizeof(PreviewJob), "preview rebuild job");
 | 
						|
 | 
						|
    pj->mutex = BLI_mutex_alloc();
 | 
						|
    pj->scene = CTX_data_scene(C);
 | 
						|
 | 
						|
    WM_jobs_customdata_set(wm_job, pj, free_preview_job);
 | 
						|
    WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_SEQUENCER, NC_SCENE | ND_SEQUENCER);
 | 
						|
    WM_jobs_callbacks(wm_job, preview_startjob, NULL, NULL, preview_endjob);
 | 
						|
  }
 | 
						|
 | 
						|
  audiojob->bmain = CTX_data_main(C);
 | 
						|
  audiojob->sound = seq->sound;
 | 
						|
 | 
						|
  BLI_mutex_lock(pj->mutex);
 | 
						|
  BLI_addtail(&pj->previews, audiojob);
 | 
						|
  pj->total++;
 | 
						|
  BLI_mutex_unlock(pj->mutex);
 | 
						|
 | 
						|
  if (!WM_jobs_is_running(wm_job)) {
 | 
						|
    G.is_break = false;
 | 
						|
    WM_jobs_start(CTX_wm_manager(C), wm_job);
 | 
						|
  }
 | 
						|
 | 
						|
  ED_area_tag_redraw(area);
 | 
						|
}
 |