EXPORT(sqInt) primitiveMPEG3VideoFrames(void) { mpeg3_t * file; sqInt result; sqInt fileHandle; sqInt aNumber; sqInt _return_value; fileHandle = interpreterProxy->stackValue(1); aNumber = interpreterProxy->stackIntegerValue(0); if (interpreterProxy->failed()) { return null; } file = mpeg3tValueOf(fileHandle); if (file == null) { if (interpreterProxy->failed()) { return null; } interpreterProxy->popthenPush(3, 0); return null; } if (aNumber < 0) { interpreterProxy->success(0); return null; } if (aNumber >= (result = mpeg3_total_vstreams(file))) { interpreterProxy->success(0); if (interpreterProxy->failed()) { return null; } interpreterProxy->popthenPush(3, 0); return null; } result = mpeg3_video_frames(file,aNumber); _return_value = interpreterProxy->floatObjectOf(result); if (interpreterProxy->failed()) { return null; } interpreterProxy->popthenPush(3, _return_value); return null; }
void Gear_VideoTexture::onUpdateSettings() { // Timer timer; // timer.reset(); char tempstr[1024]; // XXX todo : parameters double power = 1.0; int nEpochs = 3; double alpha = 0.999; pthread_mutex_lock(_mutex); // Initialize (open) the movie. strcpy(tempstr,_settings.get(SETTING_FILENAME)->valueStr().c_str()); std::cout << "opening movie : " << tempstr << std::endl; if (_file!=NULL) mpeg3_close(_file); _file = mpeg3_open(tempstr); if (_file==NULL) { std::cout << "error opening movie : " << tempstr << std::endl; pthread_mutex_unlock(_mutex); return; } _sizeX = mpeg3_video_width(_file, 0); _sizeY = mpeg3_video_height(_file, 0); //_nFrames = (int)CLAMP((long int)_settings.get(SETTING_NFRAMES)->valueInt(), 1l, mpeg3_video_frames(_file, 0)); _nFrames = (int)_settings.get(SETTING_NFRAMES)->valueInt(); ASSERT_ERROR(_nFrames >= 1); std::cout << "movie size X : " << _sizeX << std::endl; std::cout << "movie size Y : " << _sizeY << std::endl; std::cout << "numframes : " << _nFrames << " / " << mpeg3_video_frames(_file, 0) << std::endl; std::cout << "movie samplerate : " << mpeg3_sample_rate(_file,0) << std::endl; for (int i=0;i<_sizeY-1;i++) _frame[i] = (RGBA*) realloc(_frame[i], _sizeX * sizeof(RGBA)); //from the doc : //You must allocate 4 extra bytes in the last output_row. This is scratch area for the MMX routines. _frame[_sizeY-1] = (RGBA*) realloc(_frame[_sizeY-1], (_sizeX * sizeof(RGBA)) + 4); // std::cout << "Time to initialize things: " << timer.getTime() << std::endl; // timer.reset(); // Fill sequences and distance matrix. _distances.resize(_nFrames, _nFrames); _sequences.resize(_nFrames); _size = _sizeX * _sizeY; NOTICE("Filling distance and sequence matrix."); for (int i=0; i<_nFrames; ++i) { Array2D<RGBA>& currImage = _sequences[i]; currImage.resize(_sizeX, _sizeY); // Read current image. mpeg3_read_frame(_file, (unsigned char**)_frame, 0, 0, _sizeX, _sizeY, _sizeX, _sizeY, MPEG3_RGBA8888, 0); // Add image to sequences. for(int y=0;y<_sizeY;y++) memcpy(currImage.row(y), _frame[y], sizeof(RGBA) * _sizeX); // Update distance matrix (this is the bottleneck of the whole algorithm). _distances(i,i) = 0.0; for (int j=0; j<i; ++j) _distances(i,j) = _distances(j,i) = L2((unsigned char*)currImage.data(), (unsigned char*)_sequences[j].data(), (size_t)_size*SIZE_RGBA); } // std::cout << "Time to fill sequence and distance: " << timer.getTime() << std::endl; // timer.reset(); #if DEBUG_NOTICE std::cout << "Distances: " << std::endl; for (int i=0; i<_nFrames; ++i) { for (int j=0; j<_nFrames; ++j) std::cout << _distances(j,i) << " "; std::cout << std::endl; } std::cout << std::endl; #endif // Add temporal coherence to distance matrix by smoothing the distance with linear interpolation. NOTICE("Computing smoothed distances."); int timeWindowLength = CLAMP(_settings.get(SETTING_TIMEWINDOWLENGTH)->valueInt(), 0, 2); _smoothedDistances.resize(_nFrames, _nFrames); switch (timeWindowLength) { case 0: memcpy(_smoothedDistances.data(), _distances.data(), _distances.size()); break; case 1: for (int i=0; i<_nFrames; ++i) { for (int j=0; j<_nFrames; ++j) { int iPrev = MAX(i-1,0); int jPrev = MAX(j-1,0); _smoothedDistances(j,i) = 0.5 * _distances(jPrev,iPrev) + 0.5 * _distances(j,i); } } break; case 2: for (int i=0; i<_nFrames; ++i) { for (int j=0; j<_nFrames; ++j) { int iPrev = MAX(i-1,0); int jPrev = MAX(j-1,0); int iNext = MIN(i+1,_nFrames-1); int jNext = MIN(j+1,_nFrames-1); int iPrev2 = MAX(i-2,0); int jPrev2 = MAX(j-2,0); _smoothedDistances(j,i) = 0.125 * _distances(jPrev2,iPrev2) + 0.375 * _distances(jPrev,iPrev) + 0.375 * _distances(j,i) + 0.125 * _distances(jNext,iNext); } } break; default:; error("Wrong time window length specified, please check"); } // std::cout << "Time to compute smoothed distances: " << timer.getTime() << std::endl; // timer.reset(); #if DEBUG_NOTICE std::cout << "Smoothed distances: " << std::endl; for (int i=0; i<_nFrames; ++i) { for (int j=0; j<_nFrames; ++j) std::cout << _smoothedDistances(i,j) << " "; std::cout << std::endl; } std::cout << std::endl; #endif // Using Q-learning, recompute the matrix of distances. NOTICE("Computing final set of distances using Q-learning."); _minDistances.resize(_nFrames); // Initialize distances. for (int i=0; i<_nFrames; ++i) for (int j=0; j<=i; ++j) _distances(i,j) = _distances(j,i) = _smoothedDistances(i,j) = _smoothedDistances(j,i) = pow(_smoothedDistances(i,j), power); // Q-learning. for (int t=0; t<nEpochs; ++t) { #if DEBUG_NOTICE std::cout << "Q-learn distances step " << t << " : " << std::endl; for (int i=0; i<_nFrames; ++i) { for (int j=0; j<_nFrames; ++j) std::cout << _distances(j,i) << " "; std::cout << std::endl; } std::cout << std::endl; #endif // Init min distances. for (int j=0; j<_nFrames; ++j) _minDistances[j] = min(_distances.row(j), (size_t)_nFrames); for (int i=_nFrames-1; i>=0; --i) for (int j=0; j<_nFrames; ++j) { // Update distances. _distances(j,i) = _smoothedDistances(j,i) + alpha * _minDistances[j]; // Update min distances. _minDistances[j] = min(_distances.row(j), (size_t)_nFrames); } } // std::cout << "Time to compute Q-learned distances: " << timer.getTime() << std::endl; // timer.reset(); // Calculate the mean (smoothed) distance. double meanDistance = sum(_distances.data(), _distances.size()) / (double)_distances.size(); // Compute cumulative probabilities. _logCumProbs.resize(_nFrames, _nFrames); for (int i=0; i<_nFrames; ++i) { // Compute logCumProbs. _logCumProbs(0,i) = LOG_ZERO; for (int j=1; j<_nFrames; ++j) _logCumProbs(j,i) = logAdd(_logCumProbs(j-1,i), -_distances(j,i) / meanDistance); // Normalize to make a true probability. double norm = _logCumProbs(_nFrames-1,i); for (int j=0; j<_nFrames; ++j) _logCumProbs(j,i) -= norm; } // std::cout << "Time to compute probabilities: "<< timer.getTime() << std::endl; #if DEBUG_NOTICE std::cout << "Distances: " << std::endl; for (int i=0; i<_nFrames; ++i) { for (int j=0; j<_nFrames; ++j) std::cout << _distances(j,i) << " "; std::cout << std::endl; } std::cout << std::endl; std::cout << "Probabilities: " << std::endl; for (int i=0; i<_nFrames; ++i) { for (int j=0; j<_nFrames; ++j) std::cout << exp(_logCumProbs(j,i)) << " "; std::cout << std::endl; } std::cout << std::endl; #endif _currentFrame = 0; pthread_mutex_unlock(_mutex); }
int main2() { mpeg3_t *file; int i, result = 0; unsigned char *output, **output_rows; float *audio_output_f; short *audio_output_i; long total_samples = 0; Rect sourceRect; OSErr error; PixMapHandle hPixmap; Ptr gBaseLocation; long targetRowBytes; file = mpeg3_open("randomAlien.mpg"); if(file) { mpeg3_set_cpus(file, 1); //audio_output_f = (float *) memoryAllocate(1,BUFSIZE * sizeof(float)); //audio_output_i = (short *) memoryAllocate(1,BUFSIZE * sizeof(short)); //mpeg3_set_sample(file, 11229518, 0); //result = mpeg3_read_audio(file, audio_output_f, 0, 0, BUFSIZE, 0); // result = mpeg3_read_audio(file, 0, audio_output_i, 1, BUFSIZE, 0); // fwrite(audio_output_i, BUFSIZE, 1, stdout); //mpeg3_set_frame(file, 1000, 0); sourceRect.top = 0; sourceRect.left = 0; sourceRect.bottom = mpeg3_video_height(file, 0); sourceRect.right = mpeg3_video_width(file, 0); error = NewGWorld (&gpGWOffScreen, 32, &sourceRect, NULL, NULL, keepLocal); if (error != noErr) { DebugStr ("\pUnable to allocate off screen image"); } hPixmap = GetGWorldPixMap (gpGWOffScreen); error = LockPixels (hPixmap); gBaseLocation = GetPixBaseAddr(hPixmap); targetRowBytes = ((**hPixmap).rowBytes & 0x3FFF)/4; output_rows = (unsigned char **) memoryAllocate(1,sizeof(unsigned char*) * mpeg3_video_height(file, 0)); for(i = 0; i < mpeg3_video_height(file, 0); i++) output_rows[i] = (unsigned char*) gBaseLocation + i * targetRowBytes*4; for (i=0;i < mpeg3_video_frames(file, 0);i++) { result = mpeg3_read_frame(file, output_rows, 0, 0, mpeg3_video_width(file, 0), mpeg3_video_height(file, 0), mpeg3_video_width(file, 0), mpeg3_video_height(file, 0), MPEG3_RGBAF8888, 0); CopyBits (GetPortBitMapForCopyBits(gpGWOffScreen), GetPortBitMapForCopyBits(GetWindowPort(pWindow)), &sourceRect, &sourceRect, srcCopy, NULL); } UnlockPixels (hPixmap); DisposeGWorld(gpGWOffScreen); memoryFree(output_rows); fprintf(stderr, "Audio streams: %d\n", mpeg3_total_astreams(file)); for(i = 0; i < mpeg3_total_astreams(file); i++) { fprintf(stderr, " Stream %d: channels %d sample rate %d total samples %ld\n", i, mpeg3_audio_channels(file, i), mpeg3_sample_rate(file, i), mpeg3_audio_samples(file, i)); } fprintf(stderr, "Video streams: %d\n", mpeg3_total_vstreams(file)); for(i = 0; i < mpeg3_total_vstreams(file); i++) { fprintf(stderr, " Stream %d: width %d height %d frame rate %0.3f total frames %ld\n", i, mpeg3_video_width(file, i), mpeg3_video_height(file, i), mpeg3_frame_rate(file, i), mpeg3_video_frames(file, i)); } mpeg3_close(file); }