Began integration of several components into video looper to make isntallation easier and repeatablepull/34/head
| @@ -1,3 +1,7 @@ | |||
| #hello_video | |||
| *.a | |||
| *.bin | |||
| omxplayer-dist.tgz* | |||
| # Byte-compiled / optimized / DLL files | |||
| __pycache__/ | |||
| @@ -1,2 +1,11 @@ | |||
| # pi_video_looper | |||
| Application to turn your Raspberry Pi into a dedicated looping video playback device, good for art installations, information displays, or just playing cat videos all day. | |||
| # Raspberry Pi hello video | |||
| Fork of hello_video example from Raspberry Pi sample code that provides seamless looping of a raw H264 video stream. Original code is available at: https://github.com/raspberrypi/userland/tree/master/host_applications/linux/apps/hello_pi | |||
| Build by executing `hv_rebuild.sh`. | |||
| Install by executing `sudo make install` inside hello_video directory. | |||
| Run by executing `hello_video.bin`. With no parameters the usage will be printed. | |||
| @@ -12,13 +12,18 @@ fi | |||
| echo "Installing dependencies..." | |||
| echo "==========================" | |||
| apt-get update | |||
| apt-get -y install build-essential python-dev python-pip python-pygame supervisor git omxplayer | |||
| apt-get -y install build-essential python-dev python-pip python-pygame supervisor git omxplayer samba samba-common-bin | |||
| echo "Installing hello_video..." | |||
| echo "=========================" | |||
| git clone https://github.com/adafruit/pi_hello_video.git | |||
| cd pi_hello_video | |||
| ./rebuild.sh | |||
| make -C libs/ilclient clean | |||
| make -C hello_video clean | |||
| make -C libs/ilclient | |||
| make -C hello_video | |||
| cd hello_video | |||
| make install | |||
| cd ../.. | |||
| @@ -0,0 +1,29 @@ | |||
| CFLAGS+=-DSTANDALONE -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -DTARGET_POSIX -D_LINUX -fPIC -DPIC -D_REENTRANT -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -U_FORTIFY_SOURCE -Wall -g -DHAVE_LIBOPENMAX=2 -DOMX -DOMX_SKIP64BIT -ftree-vectorize -pipe -DUSE_EXTERNAL_OMX -DHAVE_LIBBCM_HOST -DUSE_EXTERNAL_LIBBCM_HOST -DUSE_VCHIQ_ARM -Wno-psabi | |||
| LDFLAGS+=-L$(SDKSTAGE)/opt/vc/lib/ -lGLESv2 -lEGL -lopenmaxil -lbcm_host -lvcos -lvchiq_arm -lpthread -lrt -lm -L../libs/ilclient -L../libs/vgfont | |||
| INCLUDES+=-I$(SDKSTAGE)/opt/vc/include/ -I$(SDKSTAGE)/opt/vc/include/interface/vcos/pthreads -I$(SDKSTAGE)/opt/vc/include/interface/vmcs_host/linux -I./ -I../libs/ilclient -I../libs/vgfont | |||
| all: $(BIN) $(LIB) | |||
| %.o: %.c | |||
| @rm -f $@ | |||
| $(CC) $(CFLAGS) $(INCLUDES) -g -c $< -o $@ -Wno-deprecated-declarations | |||
| %.o: %.cpp | |||
| @rm -f $@ | |||
| $(CXX) $(CFLAGS) $(INCLUDES) -g -c $< -o $@ -Wno-deprecated-declarations | |||
| %.bin: $(OBJS) | |||
| $(CC) -o $@ -Wl,--whole-archive $(OBJS) $(LDFLAGS) -Wl,--no-whole-archive -rdynamic | |||
| %.a: $(OBJS) | |||
| $(AR) r $@ $^ | |||
| clean: | |||
| for i in $(OBJS); do (if test -e "$$i"; then ( rm $$i ); fi ); done | |||
| @rm -f $(BIN) $(LIB) | |||
| install: | |||
| cp $(BIN) /usr/local/bin/ | |||
| @@ -0,0 +1,6 @@ | |||
| OBJS=video.o | |||
| BIN=hello_video.bin | |||
| LDFLAGS+=-lilclient | |||
| include ../Makefile.include | |||
| @@ -0,0 +1 @@ | |||
| The video clip test.h264 is (c) copyright 2008, Blender Foundation / www.bigbuckbunny.org | |||
| @@ -0,0 +1,246 @@ | |||
| /* | |||
| Copyright (c) 2012, Broadcom Europe Ltd | |||
| All rights reserved. | |||
| Redistribution and use in source and binary forms, with or without | |||
| modification, are permitted provided that the following conditions are met: | |||
| * Redistributions of source code must retain the above copyright | |||
| notice, this list of conditions and the following disclaimer. | |||
| * Redistributions in binary form must reproduce the above copyright | |||
| notice, this list of conditions and the following disclaimer in the | |||
| documentation and/or other materials provided with the distribution. | |||
| * Neither the name of the copyright holder nor the | |||
| names of its contributors may be used to endorse or promote products | |||
| derived from this software without specific prior written permission. | |||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY | |||
| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| // Video deocode demo using OpenMAX IL though the ilcient helper library | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include "bcm_host.h" | |||
| #include "ilclient.h" | |||
| static int video_decode_test(char *filename, int loop) | |||
| { | |||
| OMX_VIDEO_PARAM_PORTFORMATTYPE format; | |||
| OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; | |||
| COMPONENT_T *video_decode = NULL, *video_scheduler = NULL, *video_render = NULL, *clock = NULL; | |||
| COMPONENT_T *list[5]; | |||
| TUNNEL_T tunnel[4]; | |||
| ILCLIENT_T *client; | |||
| FILE *in; | |||
| int status = 0; | |||
| unsigned int data_len = 0; | |||
| memset(list, 0, sizeof(list)); | |||
| memset(tunnel, 0, sizeof(tunnel)); | |||
| if((in = fopen(filename, "rb")) == NULL) | |||
| return -2; | |||
| if((client = ilclient_init()) == NULL) | |||
| { | |||
| fclose(in); | |||
| return -3; | |||
| } | |||
| if(OMX_Init() != OMX_ErrorNone) | |||
| { | |||
| ilclient_destroy(client); | |||
| fclose(in); | |||
| return -4; | |||
| } | |||
| // create video_decode | |||
| if(ilclient_create_component(client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0) | |||
| status = -14; | |||
| list[0] = video_decode; | |||
| // create video_render | |||
| if(status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0) | |||
| status = -14; | |||
| list[1] = video_render; | |||
| // create clock | |||
| if(status == 0 && ilclient_create_component(client, &clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0) | |||
| status = -14; | |||
| list[2] = clock; | |||
| memset(&cstate, 0, sizeof(cstate)); | |||
| cstate.nSize = sizeof(cstate); | |||
| cstate.nVersion.nVersion = OMX_VERSION; | |||
| cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; | |||
| cstate.nWaitMask = 1; | |||
| if(clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(clock), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone) | |||
| status = -13; | |||
| // create video_scheduler | |||
| if(status == 0 && ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0) | |||
| status = -14; | |||
| list[3] = video_scheduler; | |||
| set_tunnel(tunnel, video_decode, 131, video_scheduler, 10); | |||
| set_tunnel(tunnel+1, video_scheduler, 11, video_render, 90); | |||
| set_tunnel(tunnel+2, clock, 80, video_scheduler, 12); | |||
| // setup clock tunnel first | |||
| if(status == 0 && ilclient_setup_tunnel(tunnel+2, 0, 0) != 0) | |||
| status = -15; | |||
| else | |||
| ilclient_change_component_state(clock, OMX_StateExecuting); | |||
| if(status == 0) | |||
| ilclient_change_component_state(video_decode, OMX_StateIdle); | |||
| memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); | |||
| format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); | |||
| format.nVersion.nVersion = OMX_VERSION; | |||
| format.nPortIndex = 130; | |||
| format.eCompressionFormat = OMX_VIDEO_CodingAVC; | |||
| if(status == 0 && | |||
| OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone && | |||
| ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0) | |||
| { | |||
| OMX_BUFFERHEADERTYPE *buf; | |||
| int port_settings_changed = 0; | |||
| int first_packet = 1; | |||
| ilclient_change_component_state(video_decode, OMX_StateExecuting); | |||
| while((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL) | |||
| { | |||
| // feed data and wait until we get port settings changed | |||
| unsigned char *dest = buf->pBuffer; | |||
| data_len += fread(dest, 1, buf->nAllocLen-data_len, in); | |||
| if(port_settings_changed == 0 && | |||
| ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) || | |||
| (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1, | |||
| ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10000) == 0))) | |||
| { | |||
| port_settings_changed = 1; | |||
| if(ilclient_setup_tunnel(tunnel, 0, 0) != 0) | |||
| { | |||
| status = -7; | |||
| break; | |||
| } | |||
| ilclient_change_component_state(video_scheduler, OMX_StateExecuting); | |||
| // now setup tunnel to video_render | |||
| if(ilclient_setup_tunnel(tunnel+1, 0, 1000) != 0) | |||
| { | |||
| status = -12; | |||
| break; | |||
| } | |||
| ilclient_change_component_state(video_render, OMX_StateExecuting); | |||
| } | |||
| if(!data_len) { | |||
| // Finished reading the file, either loop or exit. | |||
| if (loop) { | |||
| fseek(in, 0, SEEK_SET); | |||
| } | |||
| else { | |||
| break; | |||
| } | |||
| } | |||
| buf->nFilledLen = data_len; | |||
| data_len = 0; | |||
| buf->nOffset = 0; | |||
| if(first_packet) | |||
| { | |||
| buf->nFlags = OMX_BUFFERFLAG_STARTTIME; | |||
| first_packet = 0; | |||
| } | |||
| else | |||
| buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; | |||
| if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) | |||
| { | |||
| status = -6; | |||
| break; | |||
| } | |||
| } | |||
| buf->nFilledLen = 0; | |||
| buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS; | |||
| if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) | |||
| status = -20; | |||
| // wait for EOS from render | |||
| ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0, | |||
| ILCLIENT_BUFFER_FLAG_EOS, 10000); | |||
| // need to flush the renderer to allow video_decode to disable its input port | |||
| ilclient_flush_tunnels(tunnel, 0); | |||
| ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL); | |||
| } | |||
| fclose(in); | |||
| ilclient_disable_tunnel(tunnel); | |||
| ilclient_disable_tunnel(tunnel+1); | |||
| ilclient_disable_tunnel(tunnel+2); | |||
| ilclient_teardown_tunnels(tunnel); | |||
| ilclient_state_transition(list, OMX_StateIdle); | |||
| ilclient_state_transition(list, OMX_StateLoaded); | |||
| ilclient_cleanup_components(list); | |||
| OMX_Deinit(); | |||
| ilclient_destroy(client); | |||
| return status; | |||
| } | |||
| void error_usage(char* name) { | |||
| printf("Usage: %s [--loop] <filename>\n", name); | |||
| exit(1); | |||
| } | |||
| int main (int argc, char **argv) | |||
| { | |||
| int loop = 0; | |||
| if (argc < 2 || argc > 3) { | |||
| error_usage(argv[0]); | |||
| } | |||
| // Check optional parameter. | |||
| if (argc == 3) { | |||
| // Check for loop parameter. | |||
| if (strcmp(argv[1], "--loop") == 0) { | |||
| loop = 1; | |||
| } | |||
| // Error unknown parameter. | |||
| else { | |||
| error_usage(argv[0]); | |||
| } | |||
| } | |||
| bcm_host_init(); | |||
| return video_decode_test(argv[argc-1], loop); | |||
| } | |||
| @@ -0,0 +1,5 @@ | |||
| OBJS=ilclient.o ilcore.o | |||
| LIB=libilclient.a | |||
| include ../../Makefile.include | |||
| @@ -0,0 +1,308 @@ | |||
| /* | |||
| Copyright (c) 2012, Broadcom Europe Ltd | |||
| All rights reserved. | |||
| Redistribution and use in source and binary forms, with or without | |||
| modification, are permitted provided that the following conditions are met: | |||
| * Redistributions of source code must retain the above copyright | |||
| notice, this list of conditions and the following disclaimer. | |||
| * Redistributions in binary form must reproduce the above copyright | |||
| notice, this list of conditions and the following disclaimer in the | |||
| documentation and/or other materials provided with the distribution. | |||
| * Neither the name of the copyright holder nor the | |||
| names of its contributors may be used to endorse or promote products | |||
| derived from this software without specific prior written permission. | |||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY | |||
| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| /* | |||
| * \file | |||
| * | |||
| * \brief Host core implementation. | |||
| */ | |||
| #include <stdio.h> | |||
| #include <stdarg.h> | |||
| //includes | |||
| #include <memory.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include "IL/OMX_Component.h" | |||
| #include "interface/vcos/vcos.h" | |||
| #include "interface/vmcs_host/vcilcs.h" | |||
| #include "interface/vmcs_host/vchost.h" | |||
| #include "interface/vmcs_host/vcilcs_common.h" | |||
| static int coreInit = 0; | |||
| static int nActiveHandles = 0; | |||
| static ILCS_SERVICE_T *ilcs_service = NULL; | |||
| static VCOS_MUTEX_T lock; | |||
| static VCOS_ONCE_T once = VCOS_ONCE_INIT; | |||
| /* Atomic creation of lock protecting shared state */ | |||
| static void initOnce(void) | |||
| { | |||
| VCOS_STATUS_T status; | |||
| status = vcos_mutex_create(&lock, VCOS_FUNCTION); | |||
| vcos_demand(status == VCOS_SUCCESS); | |||
| } | |||
| /* OMX_Init */ | |||
| OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void) | |||
| { | |||
| VCOS_STATUS_T status; | |||
| OMX_ERRORTYPE err = OMX_ErrorNone; | |||
| status = vcos_once(&once, initOnce); | |||
| vcos_demand(status == VCOS_SUCCESS); | |||
| vcos_mutex_lock(&lock); | |||
| if(coreInit == 0) | |||
| { | |||
| // we need to connect via an ILCS connection to VideoCore | |||
| VCHI_INSTANCE_T initialise_instance; | |||
| VCHI_CONNECTION_T *connection; | |||
| ILCS_CONFIG_T config; | |||
| vc_host_get_vchi_state(&initialise_instance, &connection); | |||
| vcilcs_config(&config); | |||
| ilcs_service = ilcs_init((VCHIQ_INSTANCE_T) initialise_instance, (void **) &connection, &config, 0); | |||
| if(ilcs_service == NULL) | |||
| { | |||
| err = OMX_ErrorHardware; | |||
| goto end; | |||
| } | |||
| coreInit = 1; | |||
| } | |||
| else | |||
| coreInit++; | |||
| end: | |||
| vcos_mutex_unlock(&lock); | |||
| return err; | |||
| } | |||
| /* OMX_Deinit */ | |||
| OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void) | |||
| { | |||
| if(coreInit == 0) // || (coreInit == 1 && nActiveHandles > 0)) | |||
| return OMX_ErrorNotReady; | |||
| vcos_mutex_lock(&lock); | |||
| coreInit--; | |||
| if(coreInit == 0) | |||
| { | |||
| // we need to teardown the ILCS connection to VideoCore | |||
| ilcs_deinit(ilcs_service); | |||
| ilcs_service = NULL; | |||
| } | |||
| vcos_mutex_unlock(&lock); | |||
| return OMX_ErrorNone; | |||
| } | |||
| /* OMX_ComponentNameEnum */ | |||
| OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( | |||
| OMX_OUT OMX_STRING cComponentName, | |||
| OMX_IN OMX_U32 nNameLength, | |||
| OMX_IN OMX_U32 nIndex) | |||
| { | |||
| if(ilcs_service == NULL) | |||
| return OMX_ErrorBadParameter; | |||
| return vcil_out_component_name_enum(ilcs_get_common(ilcs_service), cComponentName, nNameLength, nIndex); | |||
| } | |||
| /* OMX_GetHandle */ | |||
| OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle( | |||
| OMX_OUT OMX_HANDLETYPE* pHandle, | |||
| OMX_IN OMX_STRING cComponentName, | |||
| OMX_IN OMX_PTR pAppData, | |||
| OMX_IN OMX_CALLBACKTYPE* pCallBacks) | |||
| { | |||
| OMX_ERRORTYPE eError; | |||
| OMX_COMPONENTTYPE *pComp; | |||
| OMX_HANDLETYPE hHandle = 0; | |||
| if (pHandle == NULL || cComponentName == NULL || pCallBacks == NULL || ilcs_service == NULL) | |||
| { | |||
| if(pHandle) | |||
| *pHandle = NULL; | |||
| return OMX_ErrorBadParameter; | |||
| } | |||
| { | |||
| pComp = (OMX_COMPONENTTYPE *)malloc(sizeof(OMX_COMPONENTTYPE)); | |||
| if (!pComp) | |||
| { | |||
| vcos_assert(0); | |||
| return OMX_ErrorInsufficientResources; | |||
| } | |||
| memset(pComp, 0, sizeof(OMX_COMPONENTTYPE)); | |||
| hHandle = (OMX_HANDLETYPE)pComp; | |||
| pComp->nSize = sizeof(OMX_COMPONENTTYPE); | |||
| pComp->nVersion.nVersion = OMX_VERSION; | |||
| eError = vcil_out_create_component(ilcs_get_common(ilcs_service), hHandle, cComponentName); | |||
| if (eError == OMX_ErrorNone) { | |||
| // Check that all function pointers have been filled in. | |||
| // All fields should be non-zero. | |||
| int i; | |||
| uint32_t *p = (uint32_t *) pComp; | |||
| for(i=0; i<sizeof(OMX_COMPONENTTYPE)>>2; i++) | |||
| if(*p++ == 0) | |||
| eError = OMX_ErrorInvalidComponent; | |||
| if(eError != OMX_ErrorNone && pComp->ComponentDeInit) | |||
| pComp->ComponentDeInit(hHandle); | |||
| } | |||
| if (eError == OMX_ErrorNone) { | |||
| eError = pComp->SetCallbacks(hHandle,pCallBacks,pAppData); | |||
| if (eError != OMX_ErrorNone) | |||
| pComp->ComponentDeInit(hHandle); | |||
| } | |||
| if (eError == OMX_ErrorNone) { | |||
| *pHandle = hHandle; | |||
| } | |||
| else { | |||
| *pHandle = NULL; | |||
| free(pComp); | |||
| } | |||
| } | |||
| if (eError == OMX_ErrorNone) { | |||
| vcos_mutex_lock(&lock); | |||
| nActiveHandles++; | |||
| vcos_mutex_unlock(&lock); | |||
| } | |||
| return eError; | |||
| } | |||
| /* OMX_FreeHandle */ | |||
| OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle( | |||
| OMX_IN OMX_HANDLETYPE hComponent) | |||
| { | |||
| OMX_ERRORTYPE eError = OMX_ErrorNone; | |||
| OMX_COMPONENTTYPE *pComp; | |||
| if (hComponent == NULL || ilcs_service == NULL) | |||
| return OMX_ErrorBadParameter; | |||
| pComp = (OMX_COMPONENTTYPE*)hComponent; | |||
| if (ilcs_service == NULL) | |||
| return OMX_ErrorBadParameter; | |||
| eError = (pComp->ComponentDeInit)(hComponent); | |||
| if (eError == OMX_ErrorNone) { | |||
| vcos_mutex_lock(&lock); | |||
| --nActiveHandles; | |||
| vcos_mutex_unlock(&lock); | |||
| free(pComp); | |||
| } | |||
| vcos_assert(nActiveHandles >= 0); | |||
| return eError; | |||
| } | |||
| /* OMX_SetupTunnel */ | |||
| OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel( | |||
| OMX_IN OMX_HANDLETYPE hOutput, | |||
| OMX_IN OMX_U32 nPortOutput, | |||
| OMX_IN OMX_HANDLETYPE hInput, | |||
| OMX_IN OMX_U32 nPortInput) | |||
| { | |||
| OMX_ERRORTYPE eError = OMX_ErrorNone; | |||
| OMX_COMPONENTTYPE *pCompIn, *pCompOut; | |||
| OMX_TUNNELSETUPTYPE oTunnelSetup; | |||
| if ((hOutput == NULL && hInput == NULL) || ilcs_service == NULL) | |||
| return OMX_ErrorBadParameter; | |||
| oTunnelSetup.nTunnelFlags = 0; | |||
| oTunnelSetup.eSupplier = OMX_BufferSupplyUnspecified; | |||
| pCompOut = (OMX_COMPONENTTYPE*)hOutput; | |||
| if (hOutput){ | |||
| eError = pCompOut->ComponentTunnelRequest(hOutput, nPortOutput, hInput, nPortInput, &oTunnelSetup); | |||
| } | |||
| if (eError == OMX_ErrorNone && hInput) { | |||
| pCompIn = (OMX_COMPONENTTYPE*)hInput; | |||
| eError = pCompIn->ComponentTunnelRequest(hInput, nPortInput, hOutput, nPortOutput, &oTunnelSetup); | |||
| if (eError != OMX_ErrorNone && hOutput) { | |||
| /* cancel tunnel request on output port since input port failed */ | |||
| pCompOut->ComponentTunnelRequest(hOutput, nPortOutput, NULL, 0, NULL); | |||
| } | |||
| } | |||
| return eError; | |||
| } | |||
| /* OMX_GetComponentsOfRole */ | |||
| OMX_ERRORTYPE OMX_GetComponentsOfRole ( | |||
| OMX_IN OMX_STRING role, | |||
| OMX_INOUT OMX_U32 *pNumComps, | |||
| OMX_INOUT OMX_U8 **compNames) | |||
| { | |||
| OMX_ERRORTYPE eError = OMX_ErrorNone; | |||
| *pNumComps = 0; | |||
| return eError; | |||
| } | |||
| /* OMX_GetRolesOfComponent */ | |||
| OMX_ERRORTYPE OMX_GetRolesOfComponent ( | |||
| OMX_IN OMX_STRING compName, | |||
| OMX_INOUT OMX_U32 *pNumRoles, | |||
| OMX_OUT OMX_U8 **roles) | |||
| { | |||
| OMX_ERRORTYPE eError = OMX_ErrorNone; | |||
| *pNumRoles = 0; | |||
| return eError; | |||
| } | |||
| /* OMX_GetDebugInformation */ | |||
| OMX_ERRORTYPE OMX_GetDebugInformation ( | |||
| OMX_OUT OMX_STRING debugInfo, | |||
| OMX_INOUT OMX_S32 *pLen) | |||
| { | |||
| if(ilcs_service == NULL) | |||
| return OMX_ErrorBadParameter; | |||
| return vcil_out_get_debug_information(ilcs_get_common(ilcs_service), debugInfo, pLen); | |||
| } | |||
| /* File EOF */ | |||
| @@ -2,12 +2,12 @@ from ez_setup import use_setuptools | |||
| use_setuptools() | |||
| from setuptools import setup, find_packages | |||
| setup(name = 'Adafruit_Video_Looper', | |||
| setup(name = 'NURD_Video_Looper', | |||
| version = '1.0.0', | |||
| author = 'Tony DiCola', | |||
| author_email = 'tdicola@adafruit.com', | |||
| description = 'Application to turn your Raspberry Pi into a dedicated looping video playback device, good for art installations, information displays, or just playing cat videos all day.', | |||
| author = 'Nurds', | |||
| author_email = 'ben@nurd.me', | |||
| description = 'Application to turn your Raspberry Pi Zero into a dedicated looping video playback device', | |||
| license = 'GNU GPLv2', | |||
| url = 'https://github.com/adafruit/pi_video_looper', | |||
| url = 'https://github.com/FRCTeam3255/pi_video_looper', | |||
| install_requires = ['pyudev'], | |||
| packages = find_packages()) | |||
| @@ -20,8 +20,8 @@ video_player = omxplayer | |||
| # directory option will search only a specified directory on the SD card for | |||
| # movie files. Note that you change the directory by modifying the setting in | |||
| # the [directory] section below. The default is usb_drive. | |||
| file_reader = usb_drive | |||
| #file_reader = directory | |||
| #file_reader = usb_drive | |||
| file_reader = directory | |||
| # The rest of the configuration for video looper below is optional and can be | |||
| # ignored. | |||
| @@ -54,7 +54,7 @@ console_output = true | |||
| [directory] | |||
| # The path to search for movies when using the directory file reader. | |||
| path = /home/pi | |||
| path = /home/pi/video | |||
| # USB drive file reader configuration follows. | |||
| [usb_drive] | |||