Замена QTMovieView на NSWindow вызывает мерцание

Я бы хотел сделать вот что:

  • воспроизвести мастер-фильм Quicktime (prores или pjpg) на одном экране (со звуком)
  • воспроизвести другой ведомый фильм Quicktime (prores или pjpg) на другом экране синхронно с ведущим
  • когда я нажимаю влево или вправо, переключаться между разными ведомыми фильмами

Вот что я сделал:

  • создать NSWindow для каждого экрана
  • создать массив QTMovies (фактически массив массивов на экран)
  • создать массив QTMovieViews (фактически массив массивов на экран)
  • играть в основной QTMovie как обычно
  • настроить NSTimer для обновления текущего времени ведомого фильма от времени основного фильма
  • если нажата клавиша, поменяйте вид содержимого окна на новый QTMovieView

мой полный код находится на http://codepad.org/gDsJLPAy

Все это работает, однако, когда я переключаю видео, я получаю однокадровую вспышку старого кадра видео, на которое переключается. Т.е. если я запускаю приложение для 50 кадров и переключаюсь на SlaveVideo2, я мельком вижу кадр 0 SlaveVideo2, а затем он немедленно переходит к кадру 50 SlaveVideo2 и продолжает работать как обычно. Если после 20 кадров я снова переключаюсь на SlaveVideo1, я мельком вижу кадр 50 SlaveVideo1, а затем он переходит к кадру 70 SlaveVideo1 и продолжает работать как обычно.

Я схожу с ума, пытаясь понять это. Я пробовал всевозможные методы обновления и отображения, но безрезультатно. Есть идеи, как я могу это исправить?

P.S. Вы можете видеть в timerFireMethod, если я все время обновляю все ведомые фильмы (а не только активный), мерцания у меня не возникает. Очевидно, это не решение, так как я постоянно ищу тонны видео, которые слишком тяжелые и ненужные!

P.P.S. Я попытался воссоздать настройку в Quartz Composer, и у меня возникла точно такая же проблема.

I'm on 10.7.3


person memo    schedule 06.03.2012    source источник


Ответы (1)


Ради архивов свои выводы выложу сюда.

Я не мог найти прямого решения этой проблемы. Если подчиненный фильм приостановлен, когда я делаю его просмотр активным - даже если я начинаю воспроизводить фильм немного раньше - после того, как он становится видимым, он сначала показывает старый кадр. Обходное решение, которое я нашел, заключалось в том, чтобы фильм постоянно проигрывался (что отстой).

Однако я нашел этот https://developer.apple.com/library/mac/#documentation/QuickTime/RM/MovieInternals/MTTimeSpace/B-Chapter/2MovieTimeandSpace.html

и, вызывая GetMovieTimeBase в главном фильме и применяя SetTimeBaseMasterTimeBase к подчиненному фильму, он позволяет двум фильмам воспроизводиться синхронно в задней части, без необходимости вручную поддерживать их синхронизацию. Таким образом, весь код синхронизации можно свести к:

-(void)setLayerIndex:(int)i {
    // make sure target index is within bounds
    if(i<0) i=[[movies objectAtIndex:1] count]-1;
    else if(i>[[movies objectAtIndex:1] count]-1) i=0;

    // pause all slave views
    [[viewers objectAtIndex:1] makeObjectsPerformSelector:@selector(pause:) withObject:self];

    // save current index
    currentLayerIndex = i;

    // sync frame of new slave movie
    [[self currentSlaveMovie] setCurrentTime:[masterMovie currentTime]];

    // set windows view to QTView
    [[windows objectAtIndex:1] setContentView:[self currentSlaveView]];

    // set timebase of slave to timebase of master
    TimeBase masterTimeBase = GetMovieTimeBase([masterMovie quickTimeMovie]);
    TimeValue masterTimeScale = GetMovieTimeScale([masterMovie quickTimeMovie]);
    TimeRecord slaveZero;
    TimeValue slaveZeroTV = GetTimeBaseStartTime(masterTimeBase, masterTimeScale, &slaveZero); 
    SetMovieMasterTimeBase([[self currentSlaveMovie] quickTimeMovie], masterTimeBase, &slaveZero);    

    // play master movie
    [masterViewer play:self];

    // play slave movie
    [[self currentSlaveView] play:self];

}

person memo    schedule 14.03.2012