2015-06-30 13 views
8

Próbuję użyć kilku źródeł GPUImagePicture jako źródła tekstur wraz z shaderem fragmentów do filtrowania odtwarzanego wideo.GPUImageMovie używać wielu obrazów jako tekstury i procesu

Jestem w stanie przetwarzać w ten sposób obrazy doskonałe, ale nie mogę zrozumieć, czego mi brakuje, aby to zadziałało na GPUImageMovie. Doceniam każdą oferowaną pomoc.

@property (nonatomic, strong) GPUImageView *gpuPlayerView; 
@property (nonatomic, strong) GPUImageMovie *gpuMovie; 

AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:self.video]; 

self.player = [AVPlayer playerWithPlayerItem:playerItem]; 

self.player.actionAtItemEnd = AVPlayerActionAtItemEndNone; 

[self.player play]; 

self.gpuMovie = [[GPUImageMovie alloc]initWithPlayerItem:playerItem]; 

self.gpuMovie.playAtActualSpeed = YES; 

GPUImagePicture *sourcePicture1 = [[GPUImagePicture alloc]initWithImage: 
[UIImage imageNamed:@"FilterBG"]]; 

GPUImagePicture *sourcePicture2 = [[GPUImagePicture alloc]initWithImage: 
[UIImage imageNamed:@"FilterOverlay"]]; 

GPUImagePicture *sourcePicture3 = [[GPUImagePicture alloc]initWithImage: 
[UIImage imageNamed:@"Filter1Map"]]; 

GPUImageFilter *filter = [[GPUImageFourInputFilter alloc]initWithFragmentShaderFromString: 
kFilter1ShaderString]; 

[self.gpuMovie addTarget:filter atTextureLocation:0]; 

if (sourcePicture1) 
{ 
    [sourcePicture1 addTarget:filter atTextureLocation:1]; 
} 

if (sourcePicture2) 
{ 
    [sourcePicture2 addTarget:filter atTextureLocation:2]; 
} 

if (sourcePicture3) 
{ 
    [sourcePicture3 addTarget:filter atTextureLocation:3]; 
} 

[filter addTarget:self.gpuPlayerView]; 

[self.gpuMovie startProcessing]; 
+0

Proszę spróbować tego może być pomocny .. [GPUImageMovie] (http://stackoverflow.com/questions/23799836/gpuimagemovie-pause -to-apply-filter) – 0yeoj

+0

Czy masz jakiś mały projekt do zaprezentowania swojego problemu? –

+0

Skąd wziąłeś swoją implementację GPUImageFourInputFilter? zakładając, że był oparty na klasach GPUImageTwoInputFilter lub GPUImageThreeInputFilter, które są dostarczane ze strukturą.Możesz sprawdzić tę klasę, aby upewnić się, że propaguje znaczniki czasu odpowiednio do aktualizacji treści. Przetestuj powyższe za pomocą GPUImageTwoInputFilter lub GPUImageThreeInputFilter i mniej obrazów mieszania, aby zobaczyć, czy jest to zlokalizowane w twojej implementacji GPUImageFourInFiltr. –

Odpowiedz

-1

Jest to metoda, która można użyć, aby osiągnąć ten sam

CVOpenGLESTextureCacheCreateTextureFromImage

który umożliwia wspólną bufor pomiędzy tekstur GL i filmu. W tym rdzeniu wideo pamięci podręczne OpenGLES służą do buforowania i zarządzania teksturami CVOpenGLESTextureRef. Te pamięci podręczne tekstur zapewniają sposób bezpośredniego odczytywania i zapisywania buforów w różnych formatach pikseli, takich jak 420v lub BGRA, z GLES.

//Mapping a BGRA buffer as a source texture: 
CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RGBA, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0, &outTexture); 
//Mapping a BGRA buffer as a renderbuffer: 
CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, pixelBuffer, NULL, GL_RENDERBUFFER, GL_RGBA8_OES, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0, &outTexture); 
//Mapping the luma plane of a 420v buffer as a source texture: 
CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_LUMINANCE, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, &outTexture); 
//Mapping the chroma plane of a 420v buffer as a source texture: 
CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, width/2, height/2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, &outTexture); 
//Mapping a yuvs buffer as a source texture (note: yuvs/f and 2vuy are unpacked and resampled -- not colorspace converted) 
CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RGB_422_APPLE, width, height, GL_RGB_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 1, &outTexture); 

    CVReturn CVOpenGLESTextureCacheCreateTextureFromImage (CFAllocatorRef 
    __nullable allocator, CVOpenGLESTextureCacheRef __nonnull textureCache, CVImageBufferRef __nonnull sourceImage, CFDictionaryRef 
    __nullable textureAttributes, GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, size_t planeIndex, CVOpenGLESTextureRef __nullable * __nonnull textureOut); 

Ta funkcja jest nowy lub zwróci pamięci podręcznej obiektu CVOpenGLESTextureRef tekstury mapowane do CVImageBufferRef i powiązanych parametrów. Ta operacja powoduje utworzenie żywego powiązania między buforem obrazu a leżącym pod nim obiektem tekstury.

Mam nadzieję, że pomogą w tworzeniu tego, co jest wymagane :)

+0

to kod pobierający CVPixelBufferRef i nakładający na niego obraz przy jednoczesnym wykorzystaniu GPU. Przepraszamy, jestem początkującym użytkownikiem OpenGLES. A następnie ostatnia linia zwraca CVPixelBufferRef, który łączy oba obrazy? – Charlie

-2

Próbowałem przykładowy kod GPUImage „s (SimpleVideoFileFilter), aby osiągnąć swój wynik. Stworzyłem GPUImageFilterGroup i dodałem do niego filtry. Aby dodać obrazy jako teksturę, użyłem kodu filtra GPUImageMissEtikateFilter. Oto mój kod:

NSURL *sampleURL = [[NSBundle mainBundle] URLForResource:@"sample_iPod" withExtension:@"m4v"]; 

movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL]; 
movieFile.runBenchmark = YES; 
movieFile.playAtActualSpeed = YES; 
// filter = [[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"CustomFilter"]; 

filter = [[GPUImageFilterGroup alloc] init]; 

GPUImageSaturationFilter *saturationFilter = [[GPUImageSaturationFilter alloc] init]; 
[(GPUImageSaturationFilter *)saturationFilter setSaturation:0.0]; 
[(GPUImageFilterGroup *)filter addFilter:saturationFilter]; 

GPUImagePicture *lookupImageSource = [[GPUImagePicture alloc] initWithImage:[UIImage imageNamed:@"lookup_miss_etikate"]]; 
GPUImageLookupFilter *lookupFilter = [[GPUImageLookupFilter alloc] init]; 
[(GPUImageFilterGroup *)filter addFilter:lookupFilter]; 

[lookupImageSource addTarget:lookupFilter atTextureLocation:1]; 
[lookupImageSource processImage]; 

[saturationFilter addTarget:lookupFilter]; 

[(GPUImageFilterGroup *)filter setInitialFilters:@[saturationFilter]]; 
[(GPUImageFilterGroup *)filter setTerminalFilter:lookupFilter]; 

[movieFile addTarget:filter]; 

// Only rotate the video for display, leave orientation the same for recording 
GPUImageView *filterView = (GPUImageView *)self.view; 
[filter addTarget:filterView]; 

[movieFile startProcessing]; 

Mam nadzieję, że to ci pomoże.

+0

Potrzebuję użyć modułu cieniującego fragmentu, a także używam "GPUImagePicture's, a nie' GPUImageLookupFilter's. – klcjr89

-2

Po inicjalizacji swojej GPUImage:

GPUImagePicture *sourcePicture1 = [[GPUImagePicture alloc]initWithImage:[UIImage imageNamed:@"FilterBG"]]; 

trzeba zadzwonić:

[sourcePicture1 processImage]; 

skutecznie załadować obraz i udostępnić go do rurociągu GPUImage.

I zrób to samo dla sourcePicture2 i sourcePicture3.

Aktualizacja:

Co muszę zrobić kilka lat temu, gdy użyłem go z filmów i zdjęć, było dodać powiadomienie, kiedy film został załadowany i gotowy do gry (w GPUImageMovie.m, processAsset metoda , przed self.decodeIsAllowed = YES;. Tylko gdy film był gotowy, ustawiam docelowy potok GPUImage:

Powiązane problemy