mirror of
https://github.com/raspberrypi/userland.git
synced 2025-12-06 04:49:12 +00:00
Add hello_pi apps and bcm_host.h to userland. Merge with latest code.
This commit is contained in:
5
buildme
5
buildme
@@ -3,5 +3,10 @@ mkdir -p build/arm-linux/release/
|
|||||||
pushd build/arm-linux/release/
|
pushd build/arm-linux/release/
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=Release ../../..
|
cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=Release ../../..
|
||||||
make -j 6
|
make -j 6
|
||||||
|
|
||||||
|
if [ "$1" != "" ]; then
|
||||||
|
sudo make install DESTDIR=$1
|
||||||
|
fi
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
|||||||
@@ -86,9 +86,16 @@ typedef enum {
|
|||||||
METADATA_FLAT_AREA_A = ( 'F'<<24)+('L'<<16)+('T'<<8)+('A'), // 'FLTA' : FLAT_AREA_METADATA_T defined in /middleware/camplus/sw/perceptual/flatarea.h
|
METADATA_FLAT_AREA_A = ( 'F'<<24)+('L'<<16)+('T'<<8)+('A'), // 'FLTA' : FLAT_AREA_METADATA_T defined in /middleware/camplus/sw/perceptual/flatarea.h
|
||||||
METADATA_STILL_AREA_A = ( 'S'<<24)+('T'<<16)+('L'<<8)+('A'), // 'STLA' : FLAT_AREA_METADATA_T defined in /middleware/camplus/sw/perceptual/stillarea.h
|
METADATA_STILL_AREA_A = ( 'S'<<24)+('T'<<16)+('L'<<8)+('A'), // 'STLA' : FLAT_AREA_METADATA_T defined in /middleware/camplus/sw/perceptual/stillarea.h
|
||||||
METADATA_DDITHER_A = ( 'D'<<24)+('D'<<16)+('T'<<8)+('A'), // 'DDTA' : DDITHER_METADATA_T defined in /middleware/camplus/sw/perceptual/...
|
METADATA_DDITHER_A = ( 'D'<<24)+('D'<<16)+('T'<<8)+('A'), // 'DDTA' : DDITHER_METADATA_T defined in /middleware/camplus/sw/perceptual/...
|
||||||
|
|
||||||
|
#ifdef CONFIG_VC_IMAGE_LINKED_MULTICHANN
|
||||||
|
METADATA_LINKED_MULTICHANN = ( 'I'<<24)+('L'<<16)+('M'<<8)+('C'), // 'ILMC' : VC_IMAGE_LINKED_MULTICHANN_T defined in /helpers/vc_image/vc_image.h
|
||||||
|
#endif
|
||||||
|
|
||||||
METADATA_HDR = ( 0 <<24)+( 'H'<<16)+('D'<<8)+('R'), // 'HDR' : HDR_METADATA_T defined in /middleware/camplus/sw/hdr/hdr_metadata.h
|
METADATA_HDR = ( 0 <<24)+( 'H'<<16)+('D'<<8)+('R'), // 'HDR' : HDR_METADATA_T defined in /middleware/camplus/sw/hdr/hdr_metadata.h
|
||||||
|
METADATA_FOCUS_STATS_PREPROC = ('F'<<24)+('S'<<16)+('P'<<8)+('M'), // 'FSPM' : FOCUS_STATS_PREPROC_METADATA defined in /middleware/camplus/sw/hdr/focus_stats_preproc/focus_stats_preproc.h
|
||||||
|
METADATA_ACUTE_AWB_LOG = ('A'<<24)+('E'<<16)+('L'<<8)+('C'), // 'AELC' : ISP_ACUTE_AWB_LOG
|
||||||
|
METADATA_DF = ( 0 <<24)+( 0<<16)+('D'<<8)+('F'), // '\x00\x00DF' : DF_METADATA_T defined in /middleware/camplus/sw/df/df_metadata.h
|
||||||
|
METADATA_MAGIC_MEASURE = ('S'<<24)+('S'<<16)+('M'<<8) + ('M'), // 'SSMM' : A statistic from the ISP used to determine the JPEG quality setting for a certain customer.
|
||||||
METADATA_UNKNOWN = ('U'<<24)+('N'<<16)+('K'<<8)+('N') // 'UNKN'
|
METADATA_UNKNOWN = ('U'<<24)+('N'<<16)+('K'<<8)+('N') // 'UNKN'
|
||||||
|
|
||||||
} METADATA_CODE_T;
|
} METADATA_CODE_T;
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ typedef struct vc_metadata_item_s {
|
|||||||
typedef struct vc_metadata_header_s {
|
typedef struct vc_metadata_header_s {
|
||||||
int size;
|
int size;
|
||||||
#ifdef VCMODS_LCC
|
#ifdef VCMODS_LCC
|
||||||
char readonly;
|
unsigned char readonly;
|
||||||
#else
|
#else
|
||||||
char readonly:1;
|
unsigned char readonly:1;
|
||||||
#endif
|
#endif
|
||||||
int offset_next;
|
int offset_next;
|
||||||
RTOS_LATCH_T latch;
|
RTOS_LATCH_T latch;
|
||||||
|
|||||||
29
host_applications/linux/apps/hello_pi/CMakeLists.txt
Normal file
29
host_applications/linux/apps/hello_pi/CMakeLists.txt
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
set(BUILD_FONT FALSE)
|
||||||
|
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR})
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/host_applications/linux/libs/bcm_host/include)
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libs/ilclient)
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libs/vgfont)
|
||||||
|
|
||||||
|
set(ILCLIENT_SRCS libs/ilclient/ilclient.c libs/ilclient/ilcore.c)
|
||||||
|
add_library(ilclient ${ILCLIENT_SRCS})
|
||||||
|
|
||||||
|
set(HELLO_PI_LIBS ilclient openmaxil bcm_host vcos vchiq_arm)
|
||||||
|
|
||||||
|
add_subdirectory(hello_world)
|
||||||
|
add_subdirectory(hello_video)
|
||||||
|
add_subdirectory(hello_audio)
|
||||||
|
add_subdirectory(hello_triangle)
|
||||||
|
add_subdirectory(hello_triangle2)
|
||||||
|
add_subdirectory(hello_dispmanx)
|
||||||
|
add_subdirectory(hello_tiger)
|
||||||
|
add_subdirectory(hello_encode)
|
||||||
|
add_subdirectory(hello_jpeg)
|
||||||
|
|
||||||
|
if(BUILD_FONT)
|
||||||
|
set(VGFONT_SRCS libs/vgfont/font.c libs/vgfont/vgft.c libs/vgfont/graphics.c)
|
||||||
|
set_source_files_properties(${VGFONT_SRCS} PROPERTIES COMPILE_DEFINITIONS "_HAVE_TIMER_T")
|
||||||
|
add_library(vgfont ${VGFONT_SRCS})
|
||||||
|
|
||||||
|
add_subdirectory(hello_font)
|
||||||
|
endif(BUILD_FONT)
|
||||||
28
host_applications/linux/apps/hello_pi/Makefile.include
Executable file
28
host_applications/linux/apps/hello_pi/Makefile.include
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
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 -L../libs/ilclient -L../libs/vgfont
|
||||||
|
|
||||||
|
INCLUDES+=-I$(SDKSTAGE)/opt/vc/include/ -I$(SDKSTAGE)/opt/vc/include/interface/vcos/pthreads -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)
|
||||||
|
|
||||||
|
|
||||||
12
host_applications/linux/apps/hello_pi/README
Executable file
12
host_applications/linux/apps/hello_pi/README
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
To build the test apps, first build the libs:
|
||||||
|
make -C libs/ilclient
|
||||||
|
make -C libs/vgfont
|
||||||
|
|
||||||
|
then by entering each test app directory and run make. E.g.
|
||||||
|
cd hello_world
|
||||||
|
make
|
||||||
|
./hello_world.bin
|
||||||
|
|
||||||
|
Running ./rebuild.sh will rebuild the all libs and and apps.
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
set(EXEC hello_audio.bin)
|
||||||
|
set(SRCS audio.c sinewave.c)
|
||||||
|
|
||||||
|
add_executable(${EXEC} ${SRCS})
|
||||||
|
target_link_libraries(${EXEC} ${HELLO_PI_LIBS})
|
||||||
|
|
||||||
|
install(TARGETS ${EXEC}
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
6
host_applications/linux/apps/hello_pi/hello_audio/Makefile
Executable file
6
host_applications/linux/apps/hello_pi/hello_audio/Makefile
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
OBJS=audio.o sinewave.o
|
||||||
|
BIN=hello_audio.bin
|
||||||
|
LDFLAGS+=-lilclient
|
||||||
|
|
||||||
|
include ../Makefile.include
|
||||||
|
|
||||||
425
host_applications/linux/apps/hello_pi/hello_audio/audio.c
Executable file
425
host_applications/linux/apps/hello_pi/hello_audio/audio.c
Executable file
@@ -0,0 +1,425 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Audio output demo using OpenMAX IL though the ilcient helper library
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
#include "bcm_host.h"
|
||||||
|
#include "ilclient.h"
|
||||||
|
|
||||||
|
#define N_WAVE 1024 /* dimension of Sinewave[] */
|
||||||
|
#define PI (1<<16>>1)
|
||||||
|
#define SIN(x) Sinewave[((x)>>6) & (N_WAVE-1)]
|
||||||
|
#define COS(x) SIN((x)+(PI>>1))
|
||||||
|
extern short Sinewave[];
|
||||||
|
|
||||||
|
#ifndef countof
|
||||||
|
#define countof(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BUFFER_SIZE_SAMPLES 1024
|
||||||
|
|
||||||
|
typedef int int32_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
sem_t sema;
|
||||||
|
ILCLIENT_T *client;
|
||||||
|
COMPONENT_T *audio_render;
|
||||||
|
COMPONENT_T *list[2];
|
||||||
|
OMX_BUFFERHEADERTYPE *user_buffer_list; // buffers owned by the client
|
||||||
|
uint32_t num_buffers;
|
||||||
|
uint32_t bytes_per_sample;
|
||||||
|
} AUDIOPLAY_STATE_T;
|
||||||
|
|
||||||
|
static void input_buffer_callback(void *data, COMPONENT_T *comp)
|
||||||
|
{
|
||||||
|
// do nothing - could add a callback to the user
|
||||||
|
// to indicate more buffers may be available.
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t audioplay_create(AUDIOPLAY_STATE_T **handle,
|
||||||
|
uint32_t sample_rate,
|
||||||
|
uint32_t num_channels,
|
||||||
|
uint32_t bit_depth,
|
||||||
|
uint32_t num_buffers,
|
||||||
|
uint32_t buffer_size)
|
||||||
|
{
|
||||||
|
uint32_t bytes_per_sample = (bit_depth * num_channels) >> 3;
|
||||||
|
int32_t ret = -1;
|
||||||
|
|
||||||
|
*handle = NULL;
|
||||||
|
|
||||||
|
// basic sanity check on arguments
|
||||||
|
if(sample_rate >= 8000 && sample_rate <= 96000 &&
|
||||||
|
(num_channels == 1 || num_channels == 2 || num_channels == 4 || num_channels == 8) &&
|
||||||
|
(bit_depth == 16 || bit_depth == 32) &&
|
||||||
|
num_buffers > 0 &&
|
||||||
|
buffer_size >= bytes_per_sample)
|
||||||
|
{
|
||||||
|
// buffer lengths must be 16 byte aligned for VCHI
|
||||||
|
int size = (buffer_size + 15) & ~15;
|
||||||
|
AUDIOPLAY_STATE_T *st;
|
||||||
|
|
||||||
|
// buffer offsets must also be 16 byte aligned for VCHI
|
||||||
|
st = calloc(1, sizeof(AUDIOPLAY_STATE_T));
|
||||||
|
|
||||||
|
if(st)
|
||||||
|
{
|
||||||
|
OMX_ERRORTYPE error;
|
||||||
|
OMX_PARAM_PORTDEFINITIONTYPE param;
|
||||||
|
OMX_AUDIO_PARAM_PCMMODETYPE pcm;
|
||||||
|
int32_t s;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
*handle = st;
|
||||||
|
|
||||||
|
// create and start up everything
|
||||||
|
s = sem_init(&st->sema, 0, 1);
|
||||||
|
assert(s == 0);
|
||||||
|
|
||||||
|
st->bytes_per_sample = bytes_per_sample;
|
||||||
|
st->num_buffers = num_buffers;
|
||||||
|
|
||||||
|
st->client = ilclient_init();
|
||||||
|
assert(st->client != NULL);
|
||||||
|
|
||||||
|
ilclient_set_empty_buffer_done_callback(st->client, input_buffer_callback, st);
|
||||||
|
|
||||||
|
error = OMX_Init();
|
||||||
|
assert(error == OMX_ErrorNone);
|
||||||
|
|
||||||
|
ilclient_create_component(st->client, &st->audio_render, "audio_render", ILCLIENT_ENABLE_INPUT_BUFFERS | ILCLIENT_DISABLE_ALL_PORTS);
|
||||||
|
assert(st->audio_render != NULL);
|
||||||
|
|
||||||
|
st->list[0] = st->audio_render;
|
||||||
|
|
||||||
|
// set up the number/size of buffers
|
||||||
|
memset(¶m, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
|
||||||
|
param.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
|
||||||
|
param.nVersion.nVersion = OMX_VERSION;
|
||||||
|
param.nPortIndex = 100;
|
||||||
|
|
||||||
|
error = OMX_GetParameter(ILC_GET_HANDLE(st->audio_render), OMX_IndexParamPortDefinition, ¶m);
|
||||||
|
assert(error == OMX_ErrorNone);
|
||||||
|
|
||||||
|
param.nBufferSize = size;
|
||||||
|
param.nBufferCountActual = num_buffers;
|
||||||
|
|
||||||
|
error = OMX_SetParameter(ILC_GET_HANDLE(st->audio_render), OMX_IndexParamPortDefinition, ¶m);
|
||||||
|
assert(error == OMX_ErrorNone);
|
||||||
|
|
||||||
|
// set the pcm parameters
|
||||||
|
memset(&pcm, 0, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
|
||||||
|
pcm.nSize = sizeof(OMX_AUDIO_PARAM_PCMMODETYPE);
|
||||||
|
pcm.nVersion.nVersion = OMX_VERSION;
|
||||||
|
pcm.nPortIndex = 100;
|
||||||
|
pcm.nChannels = num_channels;
|
||||||
|
pcm.eNumData = OMX_NumericalDataSigned;
|
||||||
|
pcm.eEndian = OMX_EndianLittle;
|
||||||
|
pcm.nSamplingRate = sample_rate;
|
||||||
|
pcm.bInterleaved = OMX_TRUE;
|
||||||
|
pcm.nBitPerSample = bit_depth;
|
||||||
|
pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
|
||||||
|
|
||||||
|
switch(num_channels) {
|
||||||
|
case 1:
|
||||||
|
pcm.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
|
||||||
|
pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
|
||||||
|
pcm.eChannelMapping[2] = OMX_AUDIO_ChannelCF;
|
||||||
|
pcm.eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
|
||||||
|
pcm.eChannelMapping[4] = OMX_AUDIO_ChannelLR;
|
||||||
|
pcm.eChannelMapping[5] = OMX_AUDIO_ChannelRR;
|
||||||
|
pcm.eChannelMapping[6] = OMX_AUDIO_ChannelLS;
|
||||||
|
pcm.eChannelMapping[7] = OMX_AUDIO_ChannelRS;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
|
||||||
|
pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
|
||||||
|
pcm.eChannelMapping[2] = OMX_AUDIO_ChannelLR;
|
||||||
|
pcm.eChannelMapping[3] = OMX_AUDIO_ChannelRR;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
|
||||||
|
pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = OMX_SetParameter(ILC_GET_HANDLE(st->audio_render), OMX_IndexParamAudioPcm, &pcm);
|
||||||
|
assert(error == OMX_ErrorNone);
|
||||||
|
|
||||||
|
ilclient_change_component_state(st->audio_render, OMX_StateIdle);
|
||||||
|
if(ilclient_enable_port_buffers(st->audio_render, 100, NULL, NULL, NULL) < 0)
|
||||||
|
{
|
||||||
|
// error
|
||||||
|
ilclient_change_component_state(st->audio_render, OMX_StateLoaded);
|
||||||
|
ilclient_cleanup_components(st->list);
|
||||||
|
|
||||||
|
error = OMX_Deinit();
|
||||||
|
assert(error == OMX_ErrorNone);
|
||||||
|
|
||||||
|
ilclient_destroy(st->client);
|
||||||
|
|
||||||
|
sem_destroy(&st->sema);
|
||||||
|
free(st);
|
||||||
|
*handle = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ilclient_change_component_state(st->audio_render, OMX_StateExecuting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t audioplay_delete(AUDIOPLAY_STATE_T *st)
|
||||||
|
{
|
||||||
|
OMX_ERRORTYPE error;
|
||||||
|
|
||||||
|
ilclient_change_component_state(st->audio_render, OMX_StateIdle);
|
||||||
|
|
||||||
|
error = OMX_SendCommand(ILC_GET_HANDLE(st->audio_render), OMX_CommandStateSet, OMX_StateLoaded, NULL);
|
||||||
|
assert(error == OMX_ErrorNone);
|
||||||
|
|
||||||
|
ilclient_disable_port_buffers(st->audio_render, 100, st->user_buffer_list, NULL, NULL);
|
||||||
|
ilclient_change_component_state(st->audio_render, OMX_StateLoaded);
|
||||||
|
ilclient_cleanup_components(st->list);
|
||||||
|
|
||||||
|
error = OMX_Deinit();
|
||||||
|
assert(error == OMX_ErrorNone);
|
||||||
|
|
||||||
|
ilclient_destroy(st->client);
|
||||||
|
|
||||||
|
sem_destroy(&st->sema);
|
||||||
|
free(st);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *audioplay_get_buffer(AUDIOPLAY_STATE_T *st)
|
||||||
|
{
|
||||||
|
OMX_BUFFERHEADERTYPE *hdr = NULL;
|
||||||
|
|
||||||
|
hdr = ilclient_get_input_buffer(st->audio_render, 100, 0);
|
||||||
|
|
||||||
|
if(hdr)
|
||||||
|
{
|
||||||
|
// put on the user list
|
||||||
|
sem_wait(&st->sema);
|
||||||
|
|
||||||
|
hdr->pAppPrivate = st->user_buffer_list;
|
||||||
|
st->user_buffer_list = hdr;
|
||||||
|
|
||||||
|
sem_post(&st->sema);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdr ? hdr->pBuffer : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t audioplay_play_buffer(AUDIOPLAY_STATE_T *st,
|
||||||
|
uint8_t *buffer,
|
||||||
|
uint32_t length)
|
||||||
|
{
|
||||||
|
OMX_BUFFERHEADERTYPE *hdr = NULL, *prev = NULL;
|
||||||
|
int32_t ret = -1;
|
||||||
|
|
||||||
|
if(length % st->bytes_per_sample)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
sem_wait(&st->sema);
|
||||||
|
|
||||||
|
// search through user list for the right buffer header
|
||||||
|
hdr = st->user_buffer_list;
|
||||||
|
while(hdr != NULL && hdr->pBuffer != buffer && hdr->nAllocLen < length)
|
||||||
|
{
|
||||||
|
prev = hdr;
|
||||||
|
hdr = hdr->pAppPrivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hdr) // we found it, remove from list
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
if(prev)
|
||||||
|
prev->pAppPrivate = hdr->pAppPrivate;
|
||||||
|
else
|
||||||
|
st->user_buffer_list = hdr->pAppPrivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
sem_post(&st->sema);
|
||||||
|
|
||||||
|
if(hdr)
|
||||||
|
{
|
||||||
|
OMX_ERRORTYPE error;
|
||||||
|
|
||||||
|
hdr->pAppPrivate = NULL;
|
||||||
|
hdr->nOffset = 0;
|
||||||
|
hdr->nFilledLen = length;
|
||||||
|
|
||||||
|
error = OMX_EmptyThisBuffer(ILC_GET_HANDLE(st->audio_render), hdr);
|
||||||
|
assert(error == OMX_ErrorNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t audioplay_set_dest(AUDIOPLAY_STATE_T *st, const char *name)
|
||||||
|
{
|
||||||
|
int32_t success = -1;
|
||||||
|
OMX_CONFIG_BRCMAUDIODESTINATIONTYPE ar_dest;
|
||||||
|
|
||||||
|
if (name && strlen(name) < sizeof(ar_dest.sName))
|
||||||
|
{
|
||||||
|
OMX_ERRORTYPE error;
|
||||||
|
memset(&ar_dest, 0, sizeof(ar_dest));
|
||||||
|
ar_dest.nSize = sizeof(OMX_CONFIG_BRCMAUDIODESTINATIONTYPE);
|
||||||
|
ar_dest.nVersion.nVersion = OMX_VERSION;
|
||||||
|
strcpy((char *)ar_dest.sName, name);
|
||||||
|
|
||||||
|
error = OMX_SetConfig(ILC_GET_HANDLE(st->audio_render), OMX_IndexConfigBrcmAudioDestination, &ar_dest);
|
||||||
|
assert(error == OMX_ErrorNone);
|
||||||
|
success = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t audioplay_get_latency(AUDIOPLAY_STATE_T *st)
|
||||||
|
{
|
||||||
|
OMX_PARAM_U32TYPE param;
|
||||||
|
OMX_ERRORTYPE error;
|
||||||
|
|
||||||
|
memset(¶m, 0, sizeof(OMX_PARAM_U32TYPE));
|
||||||
|
param.nSize = sizeof(OMX_PARAM_U32TYPE);
|
||||||
|
param.nVersion.nVersion = OMX_VERSION;
|
||||||
|
param.nPortIndex = 100;
|
||||||
|
|
||||||
|
error = OMX_GetConfig(ILC_GET_HANDLE(st->audio_render), OMX_IndexConfigAudioRenderingLatency, ¶m);
|
||||||
|
assert(error == OMX_ErrorNone);
|
||||||
|
|
||||||
|
return param.nU32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CTTW_SLEEP_TIME 10
|
||||||
|
#define MIN_LATENCY_TIME 20
|
||||||
|
|
||||||
|
const int SAMPLERATE[] = {8000, 11025, 44100, 96000};
|
||||||
|
const int BITDEPTH[] = {16, 32};
|
||||||
|
const int CHANNELS[] = {1, 2, 4, 8};
|
||||||
|
|
||||||
|
static const char *audio_dest[] = {"local", "hdmi"};
|
||||||
|
void play_api_test(int samplerate, int bitdepth, int nchannels, int dest)
|
||||||
|
{
|
||||||
|
AUDIOPLAY_STATE_T *st;
|
||||||
|
int32_t ret;
|
||||||
|
unsigned int i, j, n;
|
||||||
|
int phase = 0;
|
||||||
|
int inc = 256<<16;
|
||||||
|
int dinc = 0;
|
||||||
|
int buffer_size = (BUFFER_SIZE_SAMPLES * bitdepth * nchannels)>>3;
|
||||||
|
|
||||||
|
assert(dest == 0 || dest == 1);
|
||||||
|
|
||||||
|
ret = audioplay_create(&st, samplerate, nchannels, bitdepth, 10, buffer_size);
|
||||||
|
assert(ret == 0);
|
||||||
|
|
||||||
|
ret = audioplay_set_dest(st, audio_dest[dest]);
|
||||||
|
assert(ret == 0);
|
||||||
|
|
||||||
|
// iterate for 5 seconds worth of packets
|
||||||
|
for (n=0; n<((samplerate * 5)/ BUFFER_SIZE_SAMPLES); n++)
|
||||||
|
{
|
||||||
|
uint8_t *buf;
|
||||||
|
int16_t *p;
|
||||||
|
uint32_t latency;
|
||||||
|
|
||||||
|
while((buf = audioplay_get_buffer(st)) == NULL)
|
||||||
|
usleep(10*1000);
|
||||||
|
|
||||||
|
p = (int16_t *) buf;
|
||||||
|
|
||||||
|
// fill the buffer
|
||||||
|
for (i=0; i<BUFFER_SIZE_SAMPLES; i++)
|
||||||
|
{
|
||||||
|
int16_t val = SIN(phase);
|
||||||
|
phase += inc>>16;
|
||||||
|
inc += dinc;
|
||||||
|
if (inc>>16 < 512)
|
||||||
|
dinc++;
|
||||||
|
else
|
||||||
|
dinc--;
|
||||||
|
|
||||||
|
for(j=0; j<nchannels; j++)
|
||||||
|
{
|
||||||
|
if (bitdepth == 32)
|
||||||
|
*p++ = 0;
|
||||||
|
*p++ = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// try and wait for a minimum latency time (in ms) before
|
||||||
|
// sending the next packet
|
||||||
|
while((latency = audioplay_get_latency(st)) > (samplerate * (MIN_LATENCY_TIME + CTTW_SLEEP_TIME) / 1000))
|
||||||
|
usleep(CTTW_SLEEP_TIME*1000);
|
||||||
|
|
||||||
|
ret = audioplay_play_buffer(st, buf, buffer_size);
|
||||||
|
assert(ret == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
audioplay_delete(st);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
// 0=headphones, 1=hdmi
|
||||||
|
int audio_dest = 0;
|
||||||
|
// audio sample rate in Hz
|
||||||
|
int samplerate = 48000;
|
||||||
|
// numnber of audio channels
|
||||||
|
int channels = 2;
|
||||||
|
// number of bits per sample
|
||||||
|
int bitdepth = 16;
|
||||||
|
bcm_host_init();
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
audio_dest = atoi(argv[1]);
|
||||||
|
|
||||||
|
printf("Outputting audio to %s\n", audio_dest==0 ? "analogue":"hdmi");
|
||||||
|
|
||||||
|
play_api_test(samplerate, bitdepth, channels, audio_dest);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
159
host_applications/linux/apps/hello_pi/hello_audio/audioplay.h
Executable file
159
host_applications/linux/apps/hello_pi/hello_audio/audioplay.h
Executable file
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// API for host applications to deliver raw PCM samples to rendered on VideoCore
|
||||||
|
|
||||||
|
#ifndef AUDIOPLAY_H
|
||||||
|
#define AUDIOPLAY_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief This API allows the host to provide PCM samples to be
|
||||||
|
* rendered via <DFN>audio_render</DFN>.
|
||||||
|
*
|
||||||
|
* This file describes a simple API for host applications to play sound
|
||||||
|
* using VideoCore. It includes the functionality to:
|
||||||
|
*
|
||||||
|
* \li open/close
|
||||||
|
* \li set pcm parameters
|
||||||
|
* \li set buffer size parameters
|
||||||
|
* \li retrieve empty buffer available to use
|
||||||
|
* \li send full buffer to be played
|
||||||
|
* \li retrieve current buffering level
|
||||||
|
*
|
||||||
|
* This API has no thread context of it's own, so the caller must be
|
||||||
|
* aware that the IL API will be used in context. This has
|
||||||
|
* implications on executing calls inside callback contexts, and on
|
||||||
|
* the minimum size of stack that the caller requires. See the
|
||||||
|
* <DFN>ilclient_stack_size()</DFN> function for assistance.
|
||||||
|
*
|
||||||
|
* This API will use a single <DFN>audio_render</DFN> IL component, and
|
||||||
|
* supply buffers to the input port using the OpenMAX IL base profile mode.
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
struct AUDIOPLAY_STATE_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <DFN>AUDIOPLAY_STATE_T</DFN> is an opaque type that represents the
|
||||||
|
* audioplus engine handle.
|
||||||
|
*******************************************************************************/
|
||||||
|
typedef struct AUDIOPLAY_STATE_T AUDIOPLAY_STATE_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <DFN>audioplay_create()</DFN> function creates the audioplay object.
|
||||||
|
*
|
||||||
|
* @param handle On success, this is filled in with a handle to use in other
|
||||||
|
* API functions.
|
||||||
|
*
|
||||||
|
* @param sample_rate The sample rate, in samples per second, for the PCM data.
|
||||||
|
* This shall be between 8000 and 96000.
|
||||||
|
*
|
||||||
|
* @param num_channels The number of channels for the PCM data. Must be 1, 2, 4, or 8.
|
||||||
|
* Channels must be sent interleaved.
|
||||||
|
*
|
||||||
|
* @param bit_depth The bitdepth per channel per sample. Must be 16 or 32.
|
||||||
|
*
|
||||||
|
* @param num_buffers The number of buffers that will be created to write PCM
|
||||||
|
* samples into.
|
||||||
|
*
|
||||||
|
* @param buffer_size The size in bytes of each buffer that will be used to write
|
||||||
|
* PCM samples into. Note that small buffers of less than a few
|
||||||
|
* Kb in size may be faster than larger buffers, although this is
|
||||||
|
* platform dependant.
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 on failure.
|
||||||
|
*********************************************************************************/
|
||||||
|
VCHPRE_ int32_t VCHPOST_ audioplay_create(AUDIOPLAY_STATE_T **handle,
|
||||||
|
uint32_t sample_rate,
|
||||||
|
uint32_t num_channels,
|
||||||
|
uint32_t bit_depth,
|
||||||
|
uint32_t num_buffers,
|
||||||
|
uint32_t buffer_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <DFN>audioplay_delete()</DFN> function deletes the audioplay object.
|
||||||
|
*
|
||||||
|
* @param handle Must be a handle previously created by
|
||||||
|
* <DFN>audioplay_create()</DFN>. After calling this
|
||||||
|
* function that handle is no longer valid. Any
|
||||||
|
* buffers provided by <DFN>audioplay_get_buffer()</DFN>
|
||||||
|
* are also no longer valid and must not be referenced.
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 on failure.
|
||||||
|
********************************************************************************/
|
||||||
|
VCHPRE_ int32_t VCHPOST_ audioplay_delete(AUDIOPLAY_STATE_T *handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <DFN>audioplay_get_buffer()</DFN> function requests an empty
|
||||||
|
* buffer. Any buffer returned will have the valid size indicated in
|
||||||
|
* the call to <DFN>audioplay_create()</DFN>.
|
||||||
|
*
|
||||||
|
* @param handle Must be a handle previously created by
|
||||||
|
* <DFN>audioplay_create()</DFN>.
|
||||||
|
*
|
||||||
|
* @return A pointer to an available buffer. If no buffers are
|
||||||
|
* available, then <DFN>NULL</DFN> will be returned.
|
||||||
|
*********************************************************************************/
|
||||||
|
VCHPRE_ uint8_t * VCHPOST_ audioplay_get_buffer(AUDIOPLAY_STATE_T *handle);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <DFN>audioplay_play_buffer()</DFN> sends a buffer containing
|
||||||
|
* raw samples to be rendered.
|
||||||
|
*
|
||||||
|
* @param handle Must be a handle previously created by
|
||||||
|
* <DFN>audioplay_create()</DFN>.
|
||||||
|
*
|
||||||
|
* @param buffer Must be a pointer previously returned by
|
||||||
|
* <DFN>audioplay_get_buffer()</DFN>. After calling this function
|
||||||
|
* the buffer pointer must not be referenced until returned
|
||||||
|
* again by another call to <DFN>audioplay_get_buffer()</DFN>.
|
||||||
|
*
|
||||||
|
* @param length Length in bytes of valid data. Must be a whole number of
|
||||||
|
* samples, ie a multiple of (num_channels*bit_depth/8).
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 on failure
|
||||||
|
********************************************************************************/
|
||||||
|
VCHPRE_ int32_t VCHPOST_ audioplay_play_buffer(AUDIOPLAY_STATE_T *handle,
|
||||||
|
uint8_t *buffer,
|
||||||
|
uint32_t length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <DFN>audioplay_get_latency()</DFN> requests the current audio
|
||||||
|
* playout buffer size in samples, which is the latency until the next
|
||||||
|
* sample supplied is to be rendered.
|
||||||
|
*
|
||||||
|
* @param handle Must be a handle previously created by
|
||||||
|
* <DFN>audioplay_create()</DFN>.
|
||||||
|
*
|
||||||
|
* @return Number of samples currently buffered.
|
||||||
|
*********************************************************************************/
|
||||||
|
VCHPRE_ uint32_t VCHPOST_ audioplay_get_latency(AUDIOPLAY_STATE_T *handle);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* AUDIOPLAY_H */
|
||||||
160
host_applications/linux/apps/hello_pi/hello_audio/sinewave.c
Normal file
160
host_applications/linux/apps/hello_pi/hello_audio/sinewave.c
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Lookup table for audio output demo
|
||||||
|
|
||||||
|
short Sinewave[] = {
|
||||||
|
0, 201, 402, 603, 804, 1005, 1206, 1406,
|
||||||
|
1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011,
|
||||||
|
3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608,
|
||||||
|
4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195,
|
||||||
|
6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766,
|
||||||
|
7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319,
|
||||||
|
9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849,
|
||||||
|
11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353,
|
||||||
|
12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827,
|
||||||
|
14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268,
|
||||||
|
15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672,
|
||||||
|
16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036,
|
||||||
|
18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357,
|
||||||
|
19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631,
|
||||||
|
20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855,
|
||||||
|
22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027,
|
||||||
|
23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143,
|
||||||
|
24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201,
|
||||||
|
25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198,
|
||||||
|
26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132,
|
||||||
|
27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001,
|
||||||
|
28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802,
|
||||||
|
28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534,
|
||||||
|
29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195,
|
||||||
|
30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783,
|
||||||
|
30851, 30918, 30984, 31049,
|
||||||
|
31113, 31175, 31236, 31297,
|
||||||
|
31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735,
|
||||||
|
31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097,
|
||||||
|
32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382,
|
||||||
|
32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588,
|
||||||
|
32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717,
|
||||||
|
32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766,
|
||||||
|
32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736,
|
||||||
|
32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628,
|
||||||
|
32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441,
|
||||||
|
32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176,
|
||||||
|
32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833,
|
||||||
|
31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413,
|
||||||
|
31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918,
|
||||||
|
30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349,
|
||||||
|
30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706,
|
||||||
|
29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992,
|
||||||
|
28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208,
|
||||||
|
28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355,
|
||||||
|
27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437,
|
||||||
|
26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456,
|
||||||
|
25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413,
|
||||||
|
24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311,
|
||||||
|
23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153,
|
||||||
|
22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942,
|
||||||
|
20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680,
|
||||||
|
19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371,
|
||||||
|
18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017,
|
||||||
|
16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623,
|
||||||
|
15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191,
|
||||||
|
14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724,
|
||||||
|
12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227,
|
||||||
|
11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703,
|
||||||
|
9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156,
|
||||||
|
7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589,
|
||||||
|
6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006,
|
||||||
|
4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411,
|
||||||
|
3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808,
|
||||||
|
1607, 1406, 1206, 1005, 804, 603, 402, 201,
|
||||||
|
0, -201, -402, -603, -804, -1005, -1206, -1406,
|
||||||
|
-1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011,
|
||||||
|
-3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608,
|
||||||
|
-4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195,
|
||||||
|
-6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766,
|
||||||
|
-7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319,
|
||||||
|
-9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849,
|
||||||
|
-11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353,
|
||||||
|
-12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827,
|
||||||
|
-14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268,
|
||||||
|
-15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672,
|
||||||
|
-16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036,
|
||||||
|
-18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357,
|
||||||
|
-19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631,
|
||||||
|
-20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855,
|
||||||
|
-22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027,
|
||||||
|
-23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143,
|
||||||
|
-24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201,
|
||||||
|
-25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198,
|
||||||
|
-26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132,
|
||||||
|
-27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001,
|
||||||
|
-28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802,
|
||||||
|
-28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534,
|
||||||
|
-29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195,
|
||||||
|
-30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783,
|
||||||
|
-30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297,
|
||||||
|
-31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735,
|
||||||
|
-31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097,
|
||||||
|
-32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382,
|
||||||
|
-32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588,
|
||||||
|
-32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717,
|
||||||
|
-32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766,
|
||||||
|
-32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736,
|
||||||
|
-32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628,
|
||||||
|
-32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441,
|
||||||
|
-32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176,
|
||||||
|
-32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833,
|
||||||
|
-31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413,
|
||||||
|
-31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918,
|
||||||
|
-30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349,
|
||||||
|
-30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706,
|
||||||
|
-29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992,
|
||||||
|
-28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208,
|
||||||
|
-28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355,
|
||||||
|
-27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437,
|
||||||
|
-26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456,
|
||||||
|
-25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413,
|
||||||
|
-24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311,
|
||||||
|
-23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153,
|
||||||
|
-22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942,
|
||||||
|
-20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680,
|
||||||
|
-19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371,
|
||||||
|
-18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017,
|
||||||
|
-16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623,
|
||||||
|
-15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191,
|
||||||
|
-14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724,
|
||||||
|
-12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227,
|
||||||
|
-11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703,
|
||||||
|
-9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156,
|
||||||
|
-7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589,
|
||||||
|
-6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006,
|
||||||
|
-4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411,
|
||||||
|
-3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808,
|
||||||
|
-1607, -1406, -1206, -1005, -804, -603, -402, -201,
|
||||||
|
};
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
set(EXEC hello_dispmanx.bin)
|
||||||
|
set(SRCS dispmanx.c)
|
||||||
|
|
||||||
|
add_executable(${EXEC} ${SRCS})
|
||||||
|
target_link_libraries(${EXEC} ${HELLO_PI_LIBS})
|
||||||
|
|
||||||
|
install(TARGETS ${EXEC}
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
5
host_applications/linux/apps/hello_pi/hello_dispmanx/Makefile
Executable file
5
host_applications/linux/apps/hello_pi/hello_dispmanx/Makefile
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
OBJS=dispmanx.o
|
||||||
|
BIN=hello_dispmanx.bin
|
||||||
|
|
||||||
|
include ../Makefile.include
|
||||||
|
|
||||||
161
host_applications/linux/apps/hello_pi/hello_dispmanx/dispmanx.c
Executable file
161
host_applications/linux/apps/hello_pi/hello_dispmanx/dispmanx.c
Executable file
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// A simple demo using dispmanx to display an overlay
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "bcm_host.h"
|
||||||
|
|
||||||
|
#define WIDTH 200
|
||||||
|
#define HEIGHT 200
|
||||||
|
|
||||||
|
#define ALIGN_UP(x,y) ((x + (y)-1) & ~((y)-1))
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DISPMANX_DISPLAY_HANDLE_T display;
|
||||||
|
DISPMANX_MODEINFO_T info;
|
||||||
|
void *image;
|
||||||
|
DISPMANX_UPDATE_HANDLE_T update;
|
||||||
|
DISPMANX_RESOURCE_HANDLE_T resource;
|
||||||
|
DISPMANX_ELEMENT_HANDLE_T element;
|
||||||
|
uint32_t vc_image_ptr;
|
||||||
|
|
||||||
|
} RECT_VARS_T;
|
||||||
|
|
||||||
|
static RECT_VARS_T gRectVars;
|
||||||
|
|
||||||
|
static void FillRect( VC_IMAGE_TYPE_T type, void *image, int pitch, int aligned_height, int x, int y, int w, int h, int val )
|
||||||
|
{
|
||||||
|
int row;
|
||||||
|
int col;
|
||||||
|
|
||||||
|
uint16_t *line = (uint16_t *)image + y * (pitch>>1) + x;
|
||||||
|
|
||||||
|
for ( row = 0; row < h; row++ )
|
||||||
|
{
|
||||||
|
for ( col = 0; col < w; col++ )
|
||||||
|
{
|
||||||
|
line[col] = val;
|
||||||
|
}
|
||||||
|
line += (pitch>>1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
RECT_VARS_T *vars;
|
||||||
|
uint32_t screen = 0;
|
||||||
|
int ret;
|
||||||
|
VC_RECT_T src_rect;
|
||||||
|
VC_RECT_T dst_rect;
|
||||||
|
VC_IMAGE_TYPE_T type = VC_IMAGE_RGB565;
|
||||||
|
int width = WIDTH, height = HEIGHT;
|
||||||
|
int pitch = ALIGN_UP(width*2, 32);
|
||||||
|
int aligned_height = ALIGN_UP(height, 16);
|
||||||
|
VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,
|
||||||
|
120, /*alpha 0->255*/
|
||||||
|
0 };
|
||||||
|
|
||||||
|
vars = &gRectVars;
|
||||||
|
|
||||||
|
bcm_host_init();
|
||||||
|
|
||||||
|
printf("Open display[%i]...\n", screen );
|
||||||
|
vars->display = vc_dispmanx_display_open( screen );
|
||||||
|
|
||||||
|
ret = vc_dispmanx_display_get_info( vars->display, &vars->info);
|
||||||
|
assert(ret == 0);
|
||||||
|
printf( "Display is %d x %d\n", vars->info.width, vars->info.height );
|
||||||
|
|
||||||
|
vars->image = calloc( 1, pitch * height );
|
||||||
|
assert(vars->image);
|
||||||
|
|
||||||
|
FillRect( type, vars->image, pitch, aligned_height, 0, 0, width, height, 0xFFFF );
|
||||||
|
FillRect( type, vars->image, pitch, aligned_height, 0, 0, width, height, 0xF800 );
|
||||||
|
FillRect( type, vars->image, pitch, aligned_height, 20, 20, width - 40, height - 40, 0x07E0 );
|
||||||
|
FillRect( type, vars->image, pitch, aligned_height, 40, 40, width - 80, height - 80, 0x001F );
|
||||||
|
|
||||||
|
vars->resource = vc_dispmanx_resource_create( type,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
&vars->vc_image_ptr );
|
||||||
|
assert( vars->resource );
|
||||||
|
vc_dispmanx_rect_set( &dst_rect, 0, 0, width, height);
|
||||||
|
ret = vc_dispmanx_resource_write_data( vars->resource,
|
||||||
|
type,
|
||||||
|
pitch,
|
||||||
|
vars->image,
|
||||||
|
&dst_rect );
|
||||||
|
assert( ret == 0 );
|
||||||
|
vars->update = vc_dispmanx_update_start( 10 );
|
||||||
|
assert( vars->update );
|
||||||
|
|
||||||
|
vc_dispmanx_rect_set( &src_rect, 0, 0, width << 16, height << 16 );
|
||||||
|
|
||||||
|
vc_dispmanx_rect_set( &dst_rect, ( vars->info.width - width ) / 2,
|
||||||
|
( vars->info.height - height ) / 2,
|
||||||
|
width,
|
||||||
|
height );
|
||||||
|
|
||||||
|
vars->element = vc_dispmanx_element_add( vars->update,
|
||||||
|
vars->display,
|
||||||
|
2000, // layer
|
||||||
|
&dst_rect,
|
||||||
|
vars->resource,
|
||||||
|
&src_rect,
|
||||||
|
DISPMANX_PROTECTION_NONE,
|
||||||
|
&alpha,
|
||||||
|
NULL, // clamp
|
||||||
|
VC_IMAGE_ROT0 );
|
||||||
|
|
||||||
|
ret = vc_dispmanx_update_submit_sync( vars->update );
|
||||||
|
assert( ret == 0 );
|
||||||
|
|
||||||
|
printf( "Sleeping for 10 seconds...\n" );
|
||||||
|
sleep( 10 );
|
||||||
|
|
||||||
|
vars->update = vc_dispmanx_update_start( 10 );
|
||||||
|
assert( vars->update );
|
||||||
|
ret = vc_dispmanx_element_remove( vars->update, vars->element );
|
||||||
|
assert( ret == 0 );
|
||||||
|
ret = vc_dispmanx_update_submit_sync( vars->update );
|
||||||
|
assert( ret == 0 );
|
||||||
|
ret = vc_dispmanx_resource_delete( vars->resource );
|
||||||
|
assert( ret == 0 );
|
||||||
|
ret = vc_dispmanx_display_close( vars->display );
|
||||||
|
assert( ret == 0 );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
set(EXEC hello_encode.bin)
|
||||||
|
set(SRCS encode.c)
|
||||||
|
|
||||||
|
add_executable(${EXEC} ${SRCS})
|
||||||
|
target_link_libraries(${EXEC} ${HELLO_PI_LIBS})
|
||||||
|
|
||||||
|
install(TARGETS ${EXEC}
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
6
host_applications/linux/apps/hello_pi/hello_encode/Makefile
Executable file
6
host_applications/linux/apps/hello_pi/hello_encode/Makefile
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
OBJS=encode.o
|
||||||
|
BIN=hello_encode.bin
|
||||||
|
LDFLAGS+=-lilclient
|
||||||
|
|
||||||
|
include ../Makefile.include
|
||||||
|
|
||||||
284
host_applications/linux/apps/hello_pi/hello_encode/encode.c
Normal file
284
host_applications/linux/apps/hello_pi/hello_encode/encode.c
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2012, Broadcom Europe Ltd
|
||||||
|
Copyright (c) 2012, Kalle Vahlman <zuh@iki>
|
||||||
|
Tuomas Kulve <tuomas@kulve.fi>
|
||||||
|
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 encode 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"
|
||||||
|
|
||||||
|
#define NUMFRAMES 300
|
||||||
|
#define WIDTH 640
|
||||||
|
#define PITCH ((WIDTH+31)&~31)
|
||||||
|
#define HEIGHT ((WIDTH)*9/16)
|
||||||
|
#define HEIGHT16 ((HEIGHT+15)&~15)
|
||||||
|
#define SIZE ((WIDTH * HEIGHT16 * 3)/2)
|
||||||
|
|
||||||
|
// generate an animated test card in YUV format
|
||||||
|
static int
|
||||||
|
generate_test_card(void *buf, OMX_U32 * filledLen, int frame)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
char *y = buf, *u = y + PITCH * HEIGHT16, *v =
|
||||||
|
u + (PITCH >> 1) * (HEIGHT16 >> 1);
|
||||||
|
|
||||||
|
for (j = 0; j < HEIGHT / 2; j++) {
|
||||||
|
char *py = y + 2 * j * PITCH;
|
||||||
|
char *pu = u + j * (PITCH >> 1);
|
||||||
|
char *pv = v + j * (PITCH >> 1);
|
||||||
|
for (i = 0; i < WIDTH / 2; i++) {
|
||||||
|
int z = (((i + frame) >> 4) ^ ((j + frame) >> 4)) & 15;
|
||||||
|
py[0] = py[1] = py[PITCH] = py[PITCH + 1] = 0x80 + z * 0x8;
|
||||||
|
pu[0] = 0x00 + z * 0x10;
|
||||||
|
pv[0] = 0x80 + z * 0x30;
|
||||||
|
py += 2;
|
||||||
|
pu++;
|
||||||
|
pv++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*filledLen = SIZE;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_def(OMX_PARAM_PORTDEFINITIONTYPE def)
|
||||||
|
{
|
||||||
|
printf("Port %lu: %s %lu/%lu %lu %lu %s,%s,%s %lux%lu %lux%lu @%lu %u\n",
|
||||||
|
def.nPortIndex,
|
||||||
|
def.eDir == OMX_DirInput ? "in" : "out",
|
||||||
|
def.nBufferCountActual,
|
||||||
|
def.nBufferCountMin,
|
||||||
|
def.nBufferSize,
|
||||||
|
def.nBufferAlignment,
|
||||||
|
def.bEnabled ? "enabled" : "disabled",
|
||||||
|
def.bPopulated ? "populated" : "not pop.",
|
||||||
|
def.bBuffersContiguous ? "contig." : "not cont.",
|
||||||
|
def.format.video.nFrameWidth,
|
||||||
|
def.format.video.nFrameHeight,
|
||||||
|
def.format.video.nStride,
|
||||||
|
def.format.video.nSliceHeight,
|
||||||
|
def.format.video.xFramerate, def.format.video.eColorFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_encode_test(char *outputfilename)
|
||||||
|
{
|
||||||
|
OMX_VIDEO_PARAM_PORTFORMATTYPE format;
|
||||||
|
OMX_PARAM_PORTDEFINITIONTYPE def;
|
||||||
|
COMPONENT_T *video_encode = NULL;
|
||||||
|
COMPONENT_T *list[5];
|
||||||
|
OMX_BUFFERHEADERTYPE *buf;
|
||||||
|
OMX_BUFFERHEADERTYPE *out;
|
||||||
|
OMX_ERRORTYPE r;
|
||||||
|
ILCLIENT_T *client;
|
||||||
|
int status = 0;
|
||||||
|
int framenumber = 0;
|
||||||
|
FILE *outf;
|
||||||
|
|
||||||
|
memset(list, 0, sizeof(list));
|
||||||
|
|
||||||
|
if ((client = ilclient_init()) == NULL) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OMX_Init() != OMX_ErrorNone) {
|
||||||
|
ilclient_destroy(client);
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create video_encode
|
||||||
|
r = ilclient_create_component(client, &video_encode, "video_encode",
|
||||||
|
ILCLIENT_DISABLE_ALL_PORTS |
|
||||||
|
ILCLIENT_ENABLE_INPUT_BUFFERS |
|
||||||
|
ILCLIENT_ENABLE_OUTPUT_BUFFERS);
|
||||||
|
if (r != 0) {
|
||||||
|
printf
|
||||||
|
("ilclient_create_component() for video_encode failed with %x!\n",
|
||||||
|
r);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
list[0] = video_encode;
|
||||||
|
|
||||||
|
memset(&def, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
|
||||||
|
def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
|
||||||
|
def.nVersion.nVersion = OMX_VERSION;
|
||||||
|
def.nPortIndex = 200;
|
||||||
|
|
||||||
|
if (OMX_GetParameter
|
||||||
|
(ILC_GET_HANDLE(video_encode), OMX_IndexParamPortDefinition,
|
||||||
|
&def) != OMX_ErrorNone) {
|
||||||
|
printf("%s:%d: OMX_GetParameter() for video_encode port 200 failed!\n",
|
||||||
|
__FUNCTION__, __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_def(def);
|
||||||
|
|
||||||
|
// Port 200: in 1/1 115200 16 enabled,not pop.,not cont. 320x240 320x240 @1966080 20
|
||||||
|
def.format.video.nFrameWidth = WIDTH;
|
||||||
|
def.format.video.nFrameHeight = HEIGHT;
|
||||||
|
def.format.video.xFramerate = 30 << 16;
|
||||||
|
def.format.video.nSliceHeight = def.format.video.nFrameHeight;
|
||||||
|
def.format.video.nStride = def.format.video.nFrameWidth;
|
||||||
|
def.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
|
||||||
|
|
||||||
|
print_def(def);
|
||||||
|
|
||||||
|
r = OMX_SetParameter(ILC_GET_HANDLE(video_encode),
|
||||||
|
OMX_IndexParamPortDefinition, &def);
|
||||||
|
if (r != OMX_ErrorNone) {
|
||||||
|
printf
|
||||||
|
("%s:%d: OMX_SetParameter() for video_encode port 200 failed with %x!\n",
|
||||||
|
__FUNCTION__, __LINE__, r);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
|
||||||
|
format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
|
||||||
|
format.nVersion.nVersion = OMX_VERSION;
|
||||||
|
format.nPortIndex = 201;
|
||||||
|
format.eCompressionFormat = OMX_VIDEO_CodingAVC;
|
||||||
|
|
||||||
|
printf("OMX_SetParameter for video_encode:201...\n");
|
||||||
|
r = OMX_SetParameter(ILC_GET_HANDLE(video_encode),
|
||||||
|
OMX_IndexParamVideoPortFormat, &format);
|
||||||
|
if (r != OMX_ErrorNone) {
|
||||||
|
printf
|
||||||
|
("%s:%d: OMX_SetParameter() for video_encode port 201 failed with %x!\n",
|
||||||
|
__FUNCTION__, __LINE__, r);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("encode to idle...\n");
|
||||||
|
if (ilclient_change_component_state(video_encode, OMX_StateIdle) == -1) {
|
||||||
|
printf
|
||||||
|
("%s:%d: ilclient_change_component_state(video_encode, OMX_StateIdle) failed",
|
||||||
|
__FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("enabling port buffers for 200...\n");
|
||||||
|
if (ilclient_enable_port_buffers(video_encode, 200, NULL, NULL, NULL) != 0) {
|
||||||
|
printf("enabling port buffers for 200 failed!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("enabling port buffers for 201...\n");
|
||||||
|
if (ilclient_enable_port_buffers(video_encode, 201, NULL, NULL, NULL) != 0) {
|
||||||
|
printf("enabling port buffers for 201 failed!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("encode to executing...\n");
|
||||||
|
ilclient_change_component_state(video_encode, OMX_StateExecuting);
|
||||||
|
|
||||||
|
outf = fopen(outputfilename, "w");
|
||||||
|
if (outf == NULL) {
|
||||||
|
printf("Failed to open '%s' for writing video\n", outputfilename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("looping for buffers...\n");
|
||||||
|
do {
|
||||||
|
buf = ilclient_get_input_buffer(video_encode, 200, 1);
|
||||||
|
if (buf == NULL) {
|
||||||
|
printf("Doh, no buffers for me!\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* fill it */
|
||||||
|
generate_test_card(buf->pBuffer, &buf->nFilledLen, framenumber++);
|
||||||
|
|
||||||
|
if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_encode), buf) !=
|
||||||
|
OMX_ErrorNone) {
|
||||||
|
printf("Error emptying buffer!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
out = ilclient_get_output_buffer(video_encode, 201, 1);
|
||||||
|
|
||||||
|
r = OMX_FillThisBuffer(ILC_GET_HANDLE(video_encode), out);
|
||||||
|
if (r != OMX_ErrorNone) {
|
||||||
|
printf("Error filling buffer: %x\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out != NULL) {
|
||||||
|
if (out->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < out->nFilledLen; i++)
|
||||||
|
printf("%x ", out->pBuffer[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
r = fwrite(out->pBuffer, 1, out->nFilledLen, outf);
|
||||||
|
if (r != out->nFilledLen) {
|
||||||
|
printf("fwrite: Error emptying buffer: %d!\n", r);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Writing frame %d/%d\n", framenumber, NUMFRAMES);
|
||||||
|
}
|
||||||
|
out->nFilledLen = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Not getting it :(\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (framenumber < NUMFRAMES);
|
||||||
|
|
||||||
|
fclose(outf);
|
||||||
|
|
||||||
|
printf("Teardown.\n");
|
||||||
|
|
||||||
|
printf("disabling port buffers for 200 and 201...\n");
|
||||||
|
ilclient_disable_port_buffers(video_encode, 200, NULL, NULL, NULL);
|
||||||
|
ilclient_disable_port_buffers(video_encode, 201, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
ilclient_state_transition(list, OMX_StateIdle);
|
||||||
|
ilclient_state_transition(list, OMX_StateLoaded);
|
||||||
|
|
||||||
|
ilclient_cleanup_components(list);
|
||||||
|
|
||||||
|
OMX_Deinit();
|
||||||
|
|
||||||
|
ilclient_destroy(client);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Usage: %s <filename>\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
bcm_host_init();
|
||||||
|
return video_encode_test(argv[1]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
set(EXEC hello_font.bin)
|
||||||
|
set(SRCS main.c)
|
||||||
|
|
||||||
|
add_executable(${EXEC} ${SRCS})
|
||||||
|
target_link_libraries(${EXEC} ${HELLO_PI_LIBS})
|
||||||
|
target_link_libraries(${EXEC} vgfont freetype z)
|
||||||
|
|
||||||
|
install(TARGETS ${EXEC}
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
7
host_applications/linux/apps/hello_pi/hello_font/Makefile
Executable file
7
host_applications/linux/apps/hello_pi/hello_font/Makefile
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
OBJS=main.o
|
||||||
|
BIN=hello_font.bin
|
||||||
|
|
||||||
|
LDFLAGS+=-lvgfont -lfreetype -lz
|
||||||
|
|
||||||
|
include ../Makefile.include
|
||||||
|
|
||||||
BIN
host_applications/linux/apps/hello_pi/hello_font/Vera.ttf
Normal file
BIN
host_applications/linux/apps/hello_pi/hello_font/Vera.ttf
Normal file
Binary file not shown.
138
host_applications/linux/apps/hello_pi/hello_font/main.c
Normal file
138
host_applications/linux/apps/hello_pi/hello_font/main.c
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Test app for VG font library.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "bcm_host.h"
|
||||||
|
#include "vgfont.h"
|
||||||
|
|
||||||
|
static const char *strnchr(const char *str, size_t len, char c)
|
||||||
|
{
|
||||||
|
const char *e = str + len;
|
||||||
|
do {
|
||||||
|
if (*str == c) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
} while (++str < e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t render_subtitle(GRAPHICS_RESOURCE_HANDLE img, const char *text, const int skip, const uint32_t text_size, const uint32_t y_offset)
|
||||||
|
{
|
||||||
|
uint32_t text_length = strlen(text)-skip;
|
||||||
|
uint32_t width=0, height=0;
|
||||||
|
const char *split = text;
|
||||||
|
int32_t s=0;
|
||||||
|
int len = 0; // length of pre-subtitle
|
||||||
|
uint32_t img_w, img_h;
|
||||||
|
|
||||||
|
graphics_get_resource_size(img, &img_w, &img_h);
|
||||||
|
|
||||||
|
if (text_length==0)
|
||||||
|
return 0;
|
||||||
|
while (split[0]) {
|
||||||
|
s = graphics_resource_text_dimensions_ext(img, split, text_length-(split-text), &width, &height, text_size);
|
||||||
|
if (s != 0) return s;
|
||||||
|
if (width > img_w) {
|
||||||
|
const char *space = strnchr(split, text_length-(split-text), ' ');
|
||||||
|
if (!space) {
|
||||||
|
len = split+1-text;
|
||||||
|
split = split+1;
|
||||||
|
} else {
|
||||||
|
len = space-text;
|
||||||
|
split = space+1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// split now points to last line of text. split-text = length of initial text. text_length-(split-text) is length of last line
|
||||||
|
if (width) {
|
||||||
|
s = graphics_resource_render_text_ext(img, (img_w - width)>>1, y_offset-height,
|
||||||
|
GRAPHICS_RESOURCE_WIDTH,
|
||||||
|
GRAPHICS_RESOURCE_HEIGHT,
|
||||||
|
GRAPHICS_RGBA32(0xff,0xff,0xff,0xff), /* fg */
|
||||||
|
GRAPHICS_RGBA32(0,0,0,0x80), /* bg */
|
||||||
|
split, text_length-(split-text), text_size);
|
||||||
|
if (s!=0) return s;
|
||||||
|
}
|
||||||
|
return render_subtitle(img, text, skip+text_length-len, text_size, y_offset - height);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
GRAPHICS_RESOURCE_HANDLE img;
|
||||||
|
uint32_t width, height;
|
||||||
|
int LAYER=1;
|
||||||
|
bcm_host_init();
|
||||||
|
int s;
|
||||||
|
|
||||||
|
s = gx_graphics_init(".");
|
||||||
|
assert(s == 0);
|
||||||
|
|
||||||
|
s = graphics_get_display_size(0, &width, &height);
|
||||||
|
assert(s == 0);
|
||||||
|
|
||||||
|
s = gx_create_window(0, width, height, GRAPHICS_RESOURCE_RGBA32, &img);
|
||||||
|
assert(s == 0);
|
||||||
|
|
||||||
|
// transparent before display to avoid screen flash
|
||||||
|
graphics_resource_fill(img, 0, 0, width, height, GRAPHICS_RGBA32(0,0,0,0x00));
|
||||||
|
|
||||||
|
graphics_display_resource(img, 0, LAYER, 0, 0, GRAPHICS_RESOURCE_WIDTH, GRAPHICS_RESOURCE_HEIGHT, VC_DISPMAN_ROT0, 1);
|
||||||
|
|
||||||
|
uint32_t text_size = 10;
|
||||||
|
while (1) {
|
||||||
|
const char *text = "The quick brown fox jumps over the lazy dog";
|
||||||
|
uint32_t y_offset = height-60+text_size/2;
|
||||||
|
graphics_resource_fill(img, 0, 0, width, height, GRAPHICS_RGBA32(0,0,0,0x00));
|
||||||
|
// blue, at the top (y=40)
|
||||||
|
graphics_resource_fill(img, 0, 40, width, 1, GRAPHICS_RGBA32(0,0,0xff,0xff));
|
||||||
|
|
||||||
|
// green, at the bottom (y=height-40)
|
||||||
|
graphics_resource_fill(img, 0, height-40, width, 1, GRAPHICS_RGBA32(0,0xff,0,0xff));
|
||||||
|
|
||||||
|
// draw the subtitle text
|
||||||
|
render_subtitle(img, text, 0, text_size, y_offset);
|
||||||
|
graphics_update_displayed_resource(img, 0, 0, 0, 0);
|
||||||
|
text_size += 1;
|
||||||
|
if (text_size > 50)
|
||||||
|
text_size = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics_display_resource(img, 0, LAYER, 0, 0, GRAPHICS_RESOURCE_WIDTH, GRAPHICS_RESOURCE_HEIGHT, VC_DISPMAN_ROT0, 0);
|
||||||
|
graphics_delete_resource(img);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
set(EXEC hello_jpeg.bin)
|
||||||
|
set(SRCS jpeg.c)
|
||||||
|
|
||||||
|
add_executable(${EXEC} ${SRCS})
|
||||||
|
target_link_libraries(${EXEC} ${HELLO_PI_LIBS})
|
||||||
|
|
||||||
|
install(TARGETS ${EXEC}
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
6
host_applications/linux/apps/hello_pi/hello_jpeg/Makefile
Executable file
6
host_applications/linux/apps/hello_pi/hello_jpeg/Makefile
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
OBJS=jpeg.o
|
||||||
|
BIN=hello_jpeg.bin
|
||||||
|
LDFLAGS+=-lilclient
|
||||||
|
|
||||||
|
include ../Makefile.include
|
||||||
|
|
||||||
696
host_applications/linux/apps/hello_pi/hello_jpeg/jpeg.c
Normal file
696
host_applications/linux/apps/hello_pi/hello_jpeg/jpeg.c
Normal file
@@ -0,0 +1,696 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2012, Matt Ownby
|
||||||
|
Anthong Sale
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "jpeg.h"
|
||||||
|
|
||||||
|
#define TIMEOUT_MS 2000
|
||||||
|
|
||||||
|
typedef struct _COMPONENT_DETAILS {
|
||||||
|
COMPONENT_T *component;
|
||||||
|
OMX_HANDLETYPE handle;
|
||||||
|
int inPort;
|
||||||
|
int outPort;
|
||||||
|
} COMPONENT_DETAILS;
|
||||||
|
|
||||||
|
struct _OPENMAX_JPEG_DECODER {
|
||||||
|
ILCLIENT_T *client;
|
||||||
|
COMPONENT_DETAILS *imageDecoder;
|
||||||
|
COMPONENT_DETAILS *imageResizer;
|
||||||
|
OMX_BUFFERHEADERTYPE **ppInputBufferHeader;
|
||||||
|
int inputBufferHeaderCount;
|
||||||
|
OMX_BUFFERHEADERTYPE *pOutputBufferHeader;
|
||||||
|
};
|
||||||
|
|
||||||
|
int bufferIndex = 0; // index to buffer array
|
||||||
|
|
||||||
|
int
|
||||||
|
portSettingsChanged(OPENMAX_JPEG_DECODER * decoder)
|
||||||
|
{
|
||||||
|
OMX_PARAM_PORTDEFINITIONTYPE portdef;
|
||||||
|
|
||||||
|
// need to setup the input for the resizer with the output of the
|
||||||
|
// decoder
|
||||||
|
portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
|
||||||
|
portdef.nVersion.nVersion = OMX_VERSION;
|
||||||
|
portdef.nPortIndex = decoder->imageDecoder->outPort;
|
||||||
|
OMX_GetParameter(decoder->imageDecoder->handle,
|
||||||
|
OMX_IndexParamPortDefinition, &portdef);
|
||||||
|
|
||||||
|
unsigned int uWidth =
|
||||||
|
(unsigned int) portdef.format.image.nFrameWidth;
|
||||||
|
unsigned int uHeight =
|
||||||
|
(unsigned int) portdef.format.image.nFrameHeight;
|
||||||
|
|
||||||
|
// tell resizer input what the decoder output will be providing
|
||||||
|
portdef.nPortIndex = decoder->imageResizer->inPort;
|
||||||
|
OMX_SetParameter(decoder->imageResizer->handle,
|
||||||
|
OMX_IndexParamPortDefinition, &portdef);
|
||||||
|
|
||||||
|
// establish tunnel between decoder output and resizer input
|
||||||
|
OMX_SetupTunnel(decoder->imageDecoder->handle,
|
||||||
|
decoder->imageDecoder->outPort,
|
||||||
|
decoder->imageResizer->handle,
|
||||||
|
decoder->imageResizer->inPort);
|
||||||
|
|
||||||
|
// enable ports
|
||||||
|
OMX_SendCommand(decoder->imageDecoder->handle,
|
||||||
|
OMX_CommandPortEnable,
|
||||||
|
decoder->imageDecoder->outPort, NULL);
|
||||||
|
OMX_SendCommand(decoder->imageResizer->handle,
|
||||||
|
OMX_CommandPortEnable,
|
||||||
|
decoder->imageResizer->inPort, NULL);
|
||||||
|
|
||||||
|
// put resizer in idle state (this allows the outport of the decoder
|
||||||
|
// to become enabled)
|
||||||
|
OMX_SendCommand(decoder->imageResizer->handle,
|
||||||
|
OMX_CommandStateSet, OMX_StateIdle, NULL);
|
||||||
|
|
||||||
|
// wait for state change complete
|
||||||
|
ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventCmdComplete,
|
||||||
|
OMX_CommandStateSet, 1,
|
||||||
|
OMX_StateIdle, 1, 0, TIMEOUT_MS);
|
||||||
|
|
||||||
|
// once the state changes, both ports should become enabled and the
|
||||||
|
// resizer
|
||||||
|
// output should generate a settings changed event
|
||||||
|
ilclient_wait_for_event(decoder->imageDecoder->component,
|
||||||
|
OMX_EventCmdComplete,
|
||||||
|
OMX_CommandPortEnable, 1,
|
||||||
|
decoder->imageDecoder->outPort, 1, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandPortEnable, 1,
|
||||||
|
decoder->imageResizer->inPort, 1, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventPortSettingsChanged,
|
||||||
|
decoder->imageResizer->outPort, 1, 0, 1, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
|
||||||
|
ilclient_disable_port(decoder->imageResizer->component,
|
||||||
|
decoder->imageResizer->outPort);
|
||||||
|
|
||||||
|
// query output buffer requirements for resizer
|
||||||
|
portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
|
||||||
|
portdef.nVersion.nVersion = OMX_VERSION;
|
||||||
|
portdef.nPortIndex = decoder->imageResizer->outPort;
|
||||||
|
OMX_GetParameter(decoder->imageResizer->handle,
|
||||||
|
OMX_IndexParamPortDefinition, &portdef);
|
||||||
|
|
||||||
|
// change output color format and dimensions to match input
|
||||||
|
portdef.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
|
||||||
|
portdef.format.image.eColorFormat = OMX_COLOR_Format32bitABGR8888;
|
||||||
|
portdef.format.image.nFrameWidth = uWidth;
|
||||||
|
portdef.format.image.nFrameHeight = uHeight;
|
||||||
|
portdef.format.image.nStride = 0;
|
||||||
|
portdef.format.image.nSliceHeight = 0;
|
||||||
|
portdef.format.image.bFlagErrorConcealment = OMX_FALSE;
|
||||||
|
|
||||||
|
OMX_SetParameter(decoder->imageResizer->handle,
|
||||||
|
OMX_IndexParamPortDefinition, &portdef);
|
||||||
|
|
||||||
|
// grab output requirements again to get actual buffer size
|
||||||
|
// requirement (and buffer count requirement!)
|
||||||
|
OMX_GetParameter(decoder->imageResizer->handle,
|
||||||
|
OMX_IndexParamPortDefinition, &portdef);
|
||||||
|
|
||||||
|
// move resizer into executing state
|
||||||
|
ilclient_change_component_state(decoder->imageResizer->component,
|
||||||
|
OMX_StateExecuting);
|
||||||
|
|
||||||
|
// show some logging so user knows it's working
|
||||||
|
printf
|
||||||
|
("Width: %u Height: %u Output Color Format: 0x%x Buffer Size: %u\n",
|
||||||
|
(unsigned int) portdef.format.image.nFrameWidth,
|
||||||
|
(unsigned int) portdef.format.image.nFrameHeight,
|
||||||
|
(unsigned int) portdef.format.image.eColorFormat,
|
||||||
|
(unsigned int) portdef.nBufferSize);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
// enable output port of resizer
|
||||||
|
OMX_SendCommand(decoder->imageResizer->handle,
|
||||||
|
OMX_CommandPortEnable,
|
||||||
|
decoder->imageResizer->outPort, NULL);
|
||||||
|
|
||||||
|
// allocate the buffer
|
||||||
|
// void* outputBuffer = 0;
|
||||||
|
// if (posix_memalign(&outputBuffer, portdef.nBufferAlignment,
|
||||||
|
// portdef.nBufferSize) != 0)
|
||||||
|
// {
|
||||||
|
// perror("Allocating output buffer");
|
||||||
|
// return OMXJPEG_ERROR_MEMORY;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// set the buffer
|
||||||
|
// int ret = OMX_UseBuffer(decoder->imageResizer->handle,
|
||||||
|
// &decoder->pOutputBufferHeader,
|
||||||
|
// decoder->imageResizer->outPort, NULL,
|
||||||
|
// portdef.nBufferSize,
|
||||||
|
// (OMX_U8 *) outputBuffer);
|
||||||
|
int ret = OMX_AllocateBuffer(decoder->imageResizer->handle,
|
||||||
|
&decoder->pOutputBufferHeader,
|
||||||
|
decoder->imageResizer->
|
||||||
|
outPort,
|
||||||
|
NULL,
|
||||||
|
portdef.nBufferSize);
|
||||||
|
if (ret != OMX_ErrorNone) {
|
||||||
|
perror("Eror allocating buffer");
|
||||||
|
return OMXJPEG_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventCmdComplete,
|
||||||
|
OMX_CommandPortEnable, 1,
|
||||||
|
decoder->imageResizer->outPort, 1, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
|
||||||
|
return OMXJPEG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
portSettingsChangedAgain(OPENMAX_JPEG_DECODER * decoder)
|
||||||
|
{
|
||||||
|
ilclient_disable_port(decoder->imageDecoder->component,
|
||||||
|
decoder->imageDecoder->outPort);
|
||||||
|
ilclient_disable_port(decoder->imageResizer->component,
|
||||||
|
decoder->imageResizer->inPort);
|
||||||
|
|
||||||
|
OMX_PARAM_PORTDEFINITIONTYPE portdef;
|
||||||
|
|
||||||
|
// need to setup the input for the resizer with the output of the
|
||||||
|
// decoder
|
||||||
|
portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
|
||||||
|
portdef.nVersion.nVersion = OMX_VERSION;
|
||||||
|
portdef.nPortIndex = decoder->imageDecoder->outPort;
|
||||||
|
OMX_GetParameter(decoder->imageDecoder->handle,
|
||||||
|
OMX_IndexParamPortDefinition, &portdef);
|
||||||
|
|
||||||
|
// tell resizer input what the decoder output will be providing
|
||||||
|
portdef.nPortIndex = decoder->imageResizer->inPort;
|
||||||
|
OMX_SetParameter(decoder->imageResizer->handle,
|
||||||
|
OMX_IndexParamPortDefinition, &portdef);
|
||||||
|
|
||||||
|
// enable output of decoder and input of resizer (ie enable tunnel)
|
||||||
|
ilclient_enable_port(decoder->imageDecoder->component,
|
||||||
|
decoder->imageDecoder->outPort);
|
||||||
|
ilclient_enable_port(decoder->imageResizer->component,
|
||||||
|
decoder->imageResizer->inPort);
|
||||||
|
|
||||||
|
// need to wait for this event
|
||||||
|
ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventPortSettingsChanged,
|
||||||
|
decoder->imageResizer->outPort, 1,
|
||||||
|
0, 0, 0, TIMEOUT_MS);
|
||||||
|
|
||||||
|
return OMXJPEG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
prepareResizer(OPENMAX_JPEG_DECODER * decoder)
|
||||||
|
{
|
||||||
|
decoder->imageResizer = malloc(sizeof(COMPONENT_DETAILS));
|
||||||
|
if (decoder->imageResizer == NULL) {
|
||||||
|
perror("malloc image resizer");
|
||||||
|
return OMXJPEG_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = ilclient_create_component(decoder->client,
|
||||||
|
&decoder->
|
||||||
|
imageResizer->
|
||||||
|
component,
|
||||||
|
"resize",
|
||||||
|
ILCLIENT_DISABLE_ALL_PORTS
|
||||||
|
|
|
||||||
|
ILCLIENT_ENABLE_INPUT_BUFFERS
|
||||||
|
|
|
||||||
|
ILCLIENT_ENABLE_OUTPUT_BUFFERS);
|
||||||
|
if (ret != 0) {
|
||||||
|
perror("image resizer");
|
||||||
|
return OMXJPEG_ERROR_CREATING_COMP;
|
||||||
|
}
|
||||||
|
// grab the handle for later use
|
||||||
|
decoder->imageResizer->handle =
|
||||||
|
ILC_GET_HANDLE(decoder->imageResizer->component);
|
||||||
|
|
||||||
|
// get and store the ports
|
||||||
|
OMX_PORT_PARAM_TYPE port;
|
||||||
|
port.nSize = sizeof(OMX_PORT_PARAM_TYPE);
|
||||||
|
port.nVersion.nVersion = OMX_VERSION;
|
||||||
|
|
||||||
|
OMX_GetParameter(ILC_GET_HANDLE(decoder->imageResizer->component),
|
||||||
|
OMX_IndexParamImageInit, &port);
|
||||||
|
if (port.nPorts != 2) {
|
||||||
|
return OMXJPEG_ERROR_WRONG_NO_PORTS;
|
||||||
|
}
|
||||||
|
decoder->imageResizer->inPort = port.nStartPortNumber;
|
||||||
|
decoder->imageResizer->outPort = port.nStartPortNumber + 1;
|
||||||
|
|
||||||
|
decoder->pOutputBufferHeader = NULL;
|
||||||
|
|
||||||
|
return OMXJPEG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
prepareImageDecoder(OPENMAX_JPEG_DECODER * decoder)
|
||||||
|
{
|
||||||
|
decoder->imageDecoder = malloc(sizeof(COMPONENT_DETAILS));
|
||||||
|
if (decoder->imageDecoder == NULL) {
|
||||||
|
perror("malloc image decoder");
|
||||||
|
return OMXJPEG_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = ilclient_create_component(decoder->client,
|
||||||
|
&decoder->
|
||||||
|
imageDecoder->
|
||||||
|
component,
|
||||||
|
"image_decode",
|
||||||
|
ILCLIENT_DISABLE_ALL_PORTS
|
||||||
|
|
|
||||||
|
ILCLIENT_ENABLE_INPUT_BUFFERS);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
perror("image decode");
|
||||||
|
return OMXJPEG_ERROR_CREATING_COMP;
|
||||||
|
}
|
||||||
|
// grab the handle for later use in OMX calls directly
|
||||||
|
decoder->imageDecoder->handle =
|
||||||
|
ILC_GET_HANDLE(decoder->imageDecoder->component);
|
||||||
|
|
||||||
|
// get and store the ports
|
||||||
|
OMX_PORT_PARAM_TYPE port;
|
||||||
|
port.nSize = sizeof(OMX_PORT_PARAM_TYPE);
|
||||||
|
port.nVersion.nVersion = OMX_VERSION;
|
||||||
|
|
||||||
|
OMX_GetParameter(decoder->imageDecoder->handle,
|
||||||
|
OMX_IndexParamImageInit, &port);
|
||||||
|
if (port.nPorts != 2) {
|
||||||
|
return OMXJPEG_ERROR_WRONG_NO_PORTS;
|
||||||
|
}
|
||||||
|
decoder->imageDecoder->inPort = port.nStartPortNumber;
|
||||||
|
decoder->imageDecoder->outPort = port.nStartPortNumber + 1;
|
||||||
|
|
||||||
|
return OMXJPEG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
startupImageDecoder(OPENMAX_JPEG_DECODER * decoder)
|
||||||
|
{
|
||||||
|
// move to idle
|
||||||
|
ilclient_change_component_state(decoder->imageDecoder->component,
|
||||||
|
OMX_StateIdle);
|
||||||
|
|
||||||
|
// set input image format
|
||||||
|
OMX_IMAGE_PARAM_PORTFORMATTYPE imagePortFormat;
|
||||||
|
memset(&imagePortFormat, 0, sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE));
|
||||||
|
imagePortFormat.nSize = sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE);
|
||||||
|
imagePortFormat.nVersion.nVersion = OMX_VERSION;
|
||||||
|
imagePortFormat.nPortIndex = decoder->imageDecoder->inPort;
|
||||||
|
imagePortFormat.eCompressionFormat = OMX_IMAGE_CodingJPEG;
|
||||||
|
OMX_SetParameter(decoder->imageDecoder->handle,
|
||||||
|
OMX_IndexParamImagePortFormat, &imagePortFormat);
|
||||||
|
|
||||||
|
// get buffer requirements
|
||||||
|
OMX_PARAM_PORTDEFINITIONTYPE portdef;
|
||||||
|
portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
|
||||||
|
portdef.nVersion.nVersion = OMX_VERSION;
|
||||||
|
portdef.nPortIndex = decoder->imageDecoder->inPort;
|
||||||
|
OMX_GetParameter(decoder->imageDecoder->handle,
|
||||||
|
OMX_IndexParamPortDefinition, &portdef);
|
||||||
|
|
||||||
|
// enable the port and setup the buffers
|
||||||
|
OMX_SendCommand(decoder->imageDecoder->handle,
|
||||||
|
OMX_CommandPortEnable,
|
||||||
|
decoder->imageDecoder->inPort, NULL);
|
||||||
|
decoder->inputBufferHeaderCount = portdef.nBufferCountActual;
|
||||||
|
// allocate pointer array
|
||||||
|
decoder->ppInputBufferHeader =
|
||||||
|
(OMX_BUFFERHEADERTYPE **) malloc(sizeof(void) *
|
||||||
|
decoder->inputBufferHeaderCount);
|
||||||
|
// allocate each buffer
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < decoder->inputBufferHeaderCount; i++) {
|
||||||
|
if (OMX_AllocateBuffer(decoder->imageDecoder->handle,
|
||||||
|
&decoder->ppInputBufferHeader[i],
|
||||||
|
decoder->imageDecoder->inPort,
|
||||||
|
(void *) i,
|
||||||
|
portdef.nBufferSize) != OMX_ErrorNone) {
|
||||||
|
perror("Allocate decode buffer");
|
||||||
|
return OMXJPEG_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// wait for port enable to complete - which it should once buffers are
|
||||||
|
// assigned
|
||||||
|
int ret =
|
||||||
|
ilclient_wait_for_event(decoder->imageDecoder->component,
|
||||||
|
OMX_EventCmdComplete,
|
||||||
|
OMX_CommandPortEnable, 0,
|
||||||
|
decoder->imageDecoder->inPort, 0,
|
||||||
|
0, TIMEOUT_MS);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "Did not get port enable %d\n", ret);
|
||||||
|
return OMXJPEG_ERROR_EXECUTING;
|
||||||
|
}
|
||||||
|
// start executing the decoder
|
||||||
|
ret = OMX_SendCommand(decoder->imageDecoder->handle,
|
||||||
|
OMX_CommandStateSet, OMX_StateExecuting, NULL);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "Error starting image decoder %x\n", ret);
|
||||||
|
return OMXJPEG_ERROR_EXECUTING;
|
||||||
|
}
|
||||||
|
ret = ilclient_wait_for_event(decoder->imageDecoder->component,
|
||||||
|
OMX_EventCmdComplete,
|
||||||
|
OMX_StateExecuting, 0, 0, 1, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "Did not receive executing stat %d\n", ret);
|
||||||
|
// return OMXJPEG_ERROR_EXECUTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OMXJPEG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this function run the boilerplate to setup the openmax components;
|
||||||
|
int
|
||||||
|
setupOpenMaxJpegDecoder(OPENMAX_JPEG_DECODER ** pDecoder)
|
||||||
|
{
|
||||||
|
*pDecoder = malloc(sizeof(OPENMAX_JPEG_DECODER));
|
||||||
|
if (pDecoder[0] == NULL) {
|
||||||
|
perror("malloc decoder");
|
||||||
|
return OMXJPEG_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
memset(*pDecoder, 0, sizeof(OPENMAX_JPEG_DECODER));
|
||||||
|
|
||||||
|
if ((pDecoder[0]->client = ilclient_init()) == NULL) {
|
||||||
|
perror("ilclient_init");
|
||||||
|
return OMXJPEG_ERROR_ILCLIENT_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OMX_Init() != OMX_ErrorNone) {
|
||||||
|
ilclient_destroy(pDecoder[0]->client);
|
||||||
|
perror("OMX_Init");
|
||||||
|
return OMXJPEG_ERROR_OMX_INIT;
|
||||||
|
}
|
||||||
|
// prepare the image decoder
|
||||||
|
int ret = prepareImageDecoder(pDecoder[0]);
|
||||||
|
if (ret != OMXJPEG_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = prepareResizer(pDecoder[0]);
|
||||||
|
if (ret != OMXJPEG_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = startupImageDecoder(pDecoder[0]);
|
||||||
|
if (ret != OMXJPEG_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return OMXJPEG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this function passed the jpeg image buffer in, and returns the decoded
|
||||||
|
// image
|
||||||
|
int
|
||||||
|
decodeImage(OPENMAX_JPEG_DECODER * decoder, char *sourceImage,
|
||||||
|
size_t imageSize)
|
||||||
|
{
|
||||||
|
char *sourceOffset = sourceImage; // we store a seperate
|
||||||
|
// buffer ot image so we
|
||||||
|
// can offset it
|
||||||
|
size_t toread = 0; // bytes left to read from buffer
|
||||||
|
toread += imageSize;
|
||||||
|
int bFilled = 0; // have we filled our output
|
||||||
|
// buffer
|
||||||
|
bufferIndex = 0;
|
||||||
|
|
||||||
|
while (toread > 0) {
|
||||||
|
// get next buffer from array
|
||||||
|
OMX_BUFFERHEADERTYPE *pBufHeader =
|
||||||
|
decoder->ppInputBufferHeader[bufferIndex];
|
||||||
|
|
||||||
|
// step index and reset to 0 if required
|
||||||
|
bufferIndex++;
|
||||||
|
if (bufferIndex >= decoder->inputBufferHeaderCount)
|
||||||
|
bufferIndex = 0;
|
||||||
|
|
||||||
|
// work out the next chunk to load into the decoder
|
||||||
|
if (toread > pBufHeader->nAllocLen)
|
||||||
|
pBufHeader->nFilledLen = pBufHeader->nAllocLen;
|
||||||
|
else
|
||||||
|
pBufHeader->nFilledLen = toread;
|
||||||
|
|
||||||
|
toread = toread - pBufHeader->nFilledLen;
|
||||||
|
|
||||||
|
// pass the bytes to the buffer
|
||||||
|
memcpy(pBufHeader->pBuffer, sourceOffset, pBufHeader->nFilledLen);
|
||||||
|
|
||||||
|
// update the buffer pointer and set the input flags
|
||||||
|
|
||||||
|
sourceOffset = sourceOffset + pBufHeader->nFilledLen;
|
||||||
|
pBufHeader->nOffset = 0;
|
||||||
|
pBufHeader->nFlags = 0;
|
||||||
|
if (toread <= 0) {
|
||||||
|
pBufHeader->nFlags = OMX_BUFFERFLAG_EOS;
|
||||||
|
}
|
||||||
|
// empty the current buffer
|
||||||
|
int ret =
|
||||||
|
OMX_EmptyThisBuffer(decoder->imageDecoder->handle,
|
||||||
|
pBufHeader);
|
||||||
|
|
||||||
|
if (ret != OMX_ErrorNone) {
|
||||||
|
perror("Empty input buffer");
|
||||||
|
fprintf(stderr, "return code %x\n", ret);
|
||||||
|
return OMXJPEG_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
// wait for buffer to empty or port changed event
|
||||||
|
int done = 0;
|
||||||
|
while ((done == 0) || (decoder->pOutputBufferHeader == NULL)) {
|
||||||
|
if (decoder->pOutputBufferHeader == NULL) {
|
||||||
|
ret =
|
||||||
|
ilclient_wait_for_event
|
||||||
|
(decoder->imageDecoder->component,
|
||||||
|
OMX_EventPortSettingsChanged,
|
||||||
|
decoder->imageDecoder->outPort, 0, 0, 1, 0, 5);
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
portSettingsChanged(decoder);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret =
|
||||||
|
ilclient_remove_event(decoder->imageDecoder->component,
|
||||||
|
OMX_EventPortSettingsChanged,
|
||||||
|
decoder->imageDecoder->outPort,
|
||||||
|
0, 0, 1);
|
||||||
|
if (ret == 0)
|
||||||
|
portSettingsChangedAgain(decoder);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// check to see if buffer is now empty
|
||||||
|
if (pBufHeader->nFilledLen == 0)
|
||||||
|
done = 1;
|
||||||
|
|
||||||
|
if ((done == 0)
|
||||||
|
|| (decoder->pOutputBufferHeader == NULL))
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill the buffer if we have created the buffer
|
||||||
|
if (bFilled == 0) {
|
||||||
|
if ((decoder->pOutputBufferHeader == NULL)) {
|
||||||
|
portSettingsChanged(decoder);
|
||||||
|
}
|
||||||
|
ret = OMX_FillThisBuffer(decoder->imageResizer->handle,
|
||||||
|
decoder->pOutputBufferHeader);
|
||||||
|
if (ret != OMX_ErrorNone) {
|
||||||
|
perror("Filling output buffer");
|
||||||
|
fprintf(stderr, "Error code %x\n", ret);
|
||||||
|
return OMXJPEG_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
bFilled = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for buffer to fill
|
||||||
|
/*
|
||||||
|
* while(pBufHeader->nFilledLen == 0) { sleep(5); }
|
||||||
|
*/
|
||||||
|
|
||||||
|
// wait for end of stream events
|
||||||
|
int ret =
|
||||||
|
ilclient_wait_for_event(decoder->imageDecoder->component,
|
||||||
|
OMX_EventBufferFlag,
|
||||||
|
decoder->imageDecoder->outPort, 1,
|
||||||
|
OMX_BUFFERFLAG_EOS, 1,
|
||||||
|
0, 2);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "No EOS event on image decoder %d\n", ret);
|
||||||
|
}
|
||||||
|
ret = ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventBufferFlag,
|
||||||
|
decoder->imageResizer->outPort, 1,
|
||||||
|
OMX_BUFFERFLAG_EOS, 1, 0, 2);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "No EOS event on image resizer %d\n", ret);
|
||||||
|
}
|
||||||
|
return OMXJPEG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this function cleans up the decoder.
|
||||||
|
void
|
||||||
|
cleanup(OPENMAX_JPEG_DECODER * decoder)
|
||||||
|
{
|
||||||
|
// flush everything through
|
||||||
|
OMX_SendCommand(decoder->imageDecoder->handle,
|
||||||
|
OMX_CommandFlush, decoder->imageDecoder->outPort,
|
||||||
|
NULL);
|
||||||
|
ilclient_wait_for_event(decoder->imageDecoder->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandFlush, 0,
|
||||||
|
decoder->imageDecoder->outPort, 0, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
OMX_SendCommand(decoder->imageResizer->handle, OMX_CommandFlush,
|
||||||
|
decoder->imageResizer->inPort, NULL);
|
||||||
|
ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandFlush, 0,
|
||||||
|
decoder->imageResizer->inPort, 1, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
|
||||||
|
OMX_SendCommand(decoder->imageDecoder->handle, OMX_CommandPortDisable,
|
||||||
|
decoder->imageDecoder->inPort, NULL);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (i = 0; i < decoder->inputBufferHeaderCount; i++) {
|
||||||
|
OMX_BUFFERHEADERTYPE *vpBufHeader =
|
||||||
|
decoder->ppInputBufferHeader[i];
|
||||||
|
|
||||||
|
OMX_FreeBuffer(decoder->imageDecoder->handle,
|
||||||
|
decoder->imageDecoder->inPort, vpBufHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
ilclient_wait_for_event(decoder->imageDecoder->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
||||||
|
0, decoder->imageDecoder->inPort, 0, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
|
||||||
|
OMX_SendCommand(decoder->imageResizer->handle, OMX_CommandPortDisable,
|
||||||
|
decoder->imageResizer->outPort, NULL);
|
||||||
|
|
||||||
|
OMX_FreeBuffer(decoder->imageResizer->handle,
|
||||||
|
decoder->imageResizer->outPort,
|
||||||
|
decoder->pOutputBufferHeader);
|
||||||
|
|
||||||
|
ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
||||||
|
0, decoder->imageResizer->outPort, 0, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
|
||||||
|
OMX_SendCommand(decoder->imageDecoder->handle, OMX_CommandPortDisable,
|
||||||
|
decoder->imageDecoder->outPort, NULL);
|
||||||
|
ilclient_wait_for_event(decoder->imageDecoder->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
||||||
|
0, decoder->imageDecoder->outPort, 0, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
|
||||||
|
OMX_SendCommand(decoder->imageResizer->handle, OMX_CommandPortDisable,
|
||||||
|
decoder->imageResizer->inPort, NULL);
|
||||||
|
ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
||||||
|
0, decoder->imageResizer->inPort, 0, 0,
|
||||||
|
TIMEOUT_MS);
|
||||||
|
|
||||||
|
OMX_SetupTunnel(decoder->imageDecoder->handle,
|
||||||
|
decoder->imageDecoder->outPort, NULL, 0);
|
||||||
|
OMX_SetupTunnel(decoder->imageResizer->handle,
|
||||||
|
decoder->imageResizer->inPort, NULL, 0);
|
||||||
|
|
||||||
|
ilclient_change_component_state(decoder->imageDecoder->component,
|
||||||
|
OMX_StateIdle);
|
||||||
|
ilclient_change_component_state(decoder->imageResizer->component,
|
||||||
|
OMX_StateIdle);
|
||||||
|
|
||||||
|
ilclient_wait_for_event(decoder->imageDecoder->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandStateSet, 0,
|
||||||
|
OMX_StateIdle, 0, 0, TIMEOUT_MS);
|
||||||
|
ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandStateSet, 0,
|
||||||
|
OMX_StateIdle, 0, 0, TIMEOUT_MS);
|
||||||
|
|
||||||
|
ilclient_change_component_state(decoder->imageDecoder->component,
|
||||||
|
OMX_StateLoaded);
|
||||||
|
ilclient_change_component_state(decoder->imageResizer->component,
|
||||||
|
OMX_StateLoaded);
|
||||||
|
|
||||||
|
ilclient_wait_for_event(decoder->imageDecoder->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandStateSet, 0,
|
||||||
|
OMX_StateLoaded, 0, 0, TIMEOUT_MS);
|
||||||
|
ilclient_wait_for_event(decoder->imageResizer->component,
|
||||||
|
OMX_EventCmdComplete, OMX_CommandStateSet, 0,
|
||||||
|
OMX_StateLoaded, 0, 0, TIMEOUT_MS);
|
||||||
|
|
||||||
|
OMX_Deinit();
|
||||||
|
|
||||||
|
if (decoder->client != NULL) {
|
||||||
|
ilclient_destroy(decoder->client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
OPENMAX_JPEG_DECODER *pDecoder;
|
||||||
|
char *sourceImage;
|
||||||
|
size_t imageSize;
|
||||||
|
int s;
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Usage: %s <filename>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
FILE *fp = fopen(argv[1], "rb");
|
||||||
|
if (!fp) {
|
||||||
|
printf("File %s not found.\n", argv[1]);
|
||||||
|
}
|
||||||
|
fseek(fp, 0L, SEEK_END);
|
||||||
|
imageSize = ftell(fp);
|
||||||
|
fseek(fp, 0L, SEEK_SET);
|
||||||
|
sourceImage = malloc(imageSize);
|
||||||
|
assert(sourceImage != NULL);
|
||||||
|
s = fread(sourceImage, 1, imageSize, fp);
|
||||||
|
assert(s == imageSize);
|
||||||
|
fclose(fp);
|
||||||
|
bcm_host_init();
|
||||||
|
s = setupOpenMaxJpegDecoder(&pDecoder);
|
||||||
|
assert(s == 0);
|
||||||
|
s = decodeImage(pDecoder, sourceImage, imageSize);
|
||||||
|
assert(s == 0);
|
||||||
|
cleanup(pDecoder);
|
||||||
|
free(sourceImage);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
68
host_applications/linux/apps/hello_pi/hello_jpeg/jpeg.h
Normal file
68
host_applications/linux/apps/hello_pi/hello_jpeg/jpeg.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2012, Matt Ownby
|
||||||
|
Anthong Sale
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _OPTION_H_
|
||||||
|
#define _OPTION_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
Defines the methods for interacting with openmax il and ilclient to decode
|
||||||
|
jpeg images from the camera
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "bcm_host.h"
|
||||||
|
#include "ilclient.h"
|
||||||
|
|
||||||
|
#define OMXJPEG_OK 0
|
||||||
|
#define OMXJPEG_ERROR_ILCLIENT_INIT -1024
|
||||||
|
#define OMXJPEG_ERROR_OMX_INIT -1025
|
||||||
|
#define OMXJPEG_ERROR_MEMORY -1026
|
||||||
|
#define OMXJPEG_ERROR_CREATING_COMP -1027
|
||||||
|
#define OMXJPEG_ERROR_WRONG_NO_PORTS -1028
|
||||||
|
#define OMXJPEG_ERROR_EXECUTING -1029
|
||||||
|
#define OMXJPEG_ERROR_NOSETTINGS -1030
|
||||||
|
|
||||||
|
typedef struct _OPENMAX_JPEG_DECODER OPENMAX_JPEG_DECODER;
|
||||||
|
|
||||||
|
//this function run the boilerplate to setup the openmax components;
|
||||||
|
int setupOpenMaxJpegDecoder(OPENMAX_JPEG_DECODER** decoder);
|
||||||
|
|
||||||
|
//this function passed the jpeg image buffer in, and returns the decoded image
|
||||||
|
int decodeImage(OPENMAX_JPEG_DECODER* decoder,
|
||||||
|
char* sourceImage, size_t imageSize);
|
||||||
|
|
||||||
|
//this function cleans up the decoder.
|
||||||
|
void cleanup(OPENMAX_JPEG_DECODER* decoder);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
set(EXEC hello_tiger.bin)
|
||||||
|
set(SRCS tiger.c main.c)
|
||||||
|
|
||||||
|
add_executable(${EXEC} ${SRCS})
|
||||||
|
target_link_libraries(${EXEC} ${HELLO_PI_LIBS})
|
||||||
|
|
||||||
|
add_definitions(-D__RASPBERRYPI__)
|
||||||
|
|
||||||
|
install(TARGETS ${EXEC}
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
8
host_applications/linux/apps/hello_pi/hello_tiger/Makefile
Executable file
8
host_applications/linux/apps/hello_pi/hello_tiger/Makefile
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
OBJS=main.o tiger.o
|
||||||
|
BIN=hello_tiger.bin
|
||||||
|
|
||||||
|
#LDFLAGS+=
|
||||||
|
CFLAGS+=-D__RASPBERRYPI__
|
||||||
|
|
||||||
|
include ../Makefile.include
|
||||||
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
OpenVG 1.1 Reference Implementation
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2007 The Khronos Group Inc.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and /or associated documentation files
|
||||||
|
(the "Materials "), to deal in the Materials without restriction,
|
||||||
|
including without limitation the rights to use, copy, modify, merge,
|
||||||
|
publish, distribute, sublicense, and/or sell copies of the Materials,
|
||||||
|
and to permit persons to whom the Materials are furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Materials.
|
||||||
|
|
||||||
|
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
|
||||||
|
THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
|
||||||
|
|
||||||
|
Path data for the Tiger sample program has been extracted from Ghostscript's
|
||||||
|
tiger.eps example file distributed under GNU General Public License.
|
||||||
|
|
||||||
|
Ghostscript's License document:
|
||||||
|
" The files in the src, lib, toolbin, examples, doc and man
|
||||||
|
directories (folders) and any subdirectories (sub-folders)
|
||||||
|
thereof are part of GPL Ghostscript.
|
||||||
|
|
||||||
|
The files in the Resource directory and any subdirectories thereof
|
||||||
|
are also part of GPL Ghostscript, with the explicit exception of
|
||||||
|
the files in the CMap subdirectory. The CMap files are copyright
|
||||||
|
Adobe Systems Incorporated and covered by a separate license
|
||||||
|
which permits only verbatim distribution.
|
||||||
|
|
||||||
|
GPL Ghostscript is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of version 2 of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
GPL Ghostscript 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 so you can know your rights and responsibilities.
|
||||||
|
It should be in a file named doc/COPYING. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 59 Temple Place Suite 330, Boston, MA
|
||||||
|
02111-1307, USA."
|
||||||
533
host_applications/linux/apps/hello_pi/hello_tiger/main.c
Normal file
533
host_applications/linux/apps/hello_pi/hello_tiger/main.c
Normal file
@@ -0,0 +1,533 @@
|
|||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* OpenVG 1.0.1 Reference Implementation sample code
|
||||||
|
* -------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007 The Khronos Group Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and /or associated documentation files
|
||||||
|
* (the "Materials "), to deal in the Materials without restriction,
|
||||||
|
* including without limitation the rights to use, copy, modify, merge,
|
||||||
|
* publish, distribute, sublicense, and/or sell copies of the Materials,
|
||||||
|
* and to permit persons to whom the Materials are furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Materials.
|
||||||
|
*
|
||||||
|
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
|
||||||
|
* THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*
|
||||||
|
*//**
|
||||||
|
* \file
|
||||||
|
* \brief Tiger sample application. Resizing the application window
|
||||||
|
* rerenders the tiger in the new resolution. Pressing 1,2,3
|
||||||
|
* or 4 sets pixel zoom factor, mouse moves inside the zoomed
|
||||||
|
* image (mouse move works on OpenGL >= 1.2).
|
||||||
|
* \note
|
||||||
|
*//*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#define UNREF(X) ((void)(X))
|
||||||
|
|
||||||
|
#ifdef HG_FLAT_INCLUDES
|
||||||
|
# include "openvg.h"
|
||||||
|
# include "vgu.h"
|
||||||
|
# include "egl.h"
|
||||||
|
#else
|
||||||
|
# include "VG/openvg.h"
|
||||||
|
# include "VG/vgu.h"
|
||||||
|
# include "EGL/egl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tiger.h"
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef __RASPBERRYPI__
|
||||||
|
static float rotateN = 0.0f;
|
||||||
|
#endif
|
||||||
|
const float aspectRatio = 612.0f / 792.0f;
|
||||||
|
int renderWidth = 0;
|
||||||
|
int renderHeight = 0;
|
||||||
|
EGLDisplay egldisplay;
|
||||||
|
EGLConfig eglconfig;
|
||||||
|
EGLSurface eglsurface;
|
||||||
|
EGLContext eglcontext;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
VGFillRule m_fillRule;
|
||||||
|
VGPaintMode m_paintMode;
|
||||||
|
VGCapStyle m_capStyle;
|
||||||
|
VGJoinStyle m_joinStyle;
|
||||||
|
float m_miterLimit;
|
||||||
|
float m_strokeWidth;
|
||||||
|
VGPaint m_fillPaint;
|
||||||
|
VGPaint m_strokePaint;
|
||||||
|
VGPath m_path;
|
||||||
|
} PathData;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PathData* m_paths;
|
||||||
|
int m_numPaths;
|
||||||
|
} PS;
|
||||||
|
|
||||||
|
PS* PS_construct(const char* commands, int commandCount, const float* points, int pointCount)
|
||||||
|
{
|
||||||
|
PS* ps = (PS*)malloc(sizeof(PS));
|
||||||
|
int p = 0;
|
||||||
|
int c = 0;
|
||||||
|
int i = 0;
|
||||||
|
int paths = 0;
|
||||||
|
int maxElements = 0;
|
||||||
|
unsigned char* cmd;
|
||||||
|
UNREF(pointCount);
|
||||||
|
|
||||||
|
while(c < commandCount)
|
||||||
|
{
|
||||||
|
int elements, e;
|
||||||
|
c += 4;
|
||||||
|
p += 8;
|
||||||
|
elements = (int)points[p++];
|
||||||
|
assert(elements > 0);
|
||||||
|
if(elements > maxElements)
|
||||||
|
maxElements = elements;
|
||||||
|
for(e=0;e<elements;e++)
|
||||||
|
{
|
||||||
|
switch(commands[c])
|
||||||
|
{
|
||||||
|
case 'M': p += 2; break;
|
||||||
|
case 'L': p += 2; break;
|
||||||
|
case 'C': p += 6; break;
|
||||||
|
case 'E': break;
|
||||||
|
default:
|
||||||
|
assert(0); //unknown command
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
paths++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ps->m_numPaths = paths;
|
||||||
|
ps->m_paths = (PathData*)malloc(paths * sizeof(PathData));
|
||||||
|
cmd = (unsigned char*)malloc(maxElements);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
p = 0;
|
||||||
|
c = 0;
|
||||||
|
while(c < commandCount)
|
||||||
|
{
|
||||||
|
int elements, startp, e;
|
||||||
|
float color[4];
|
||||||
|
|
||||||
|
//fill type
|
||||||
|
int paintMode = 0;
|
||||||
|
ps->m_paths[i].m_fillRule = VG_NON_ZERO;
|
||||||
|
switch( commands[c] )
|
||||||
|
{
|
||||||
|
case 'N':
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
ps->m_paths[i].m_fillRule = VG_NON_ZERO;
|
||||||
|
paintMode |= VG_FILL_PATH;
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
ps->m_paths[i].m_fillRule = VG_EVEN_ODD;
|
||||||
|
paintMode |= VG_FILL_PATH;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0); //unknown command
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
|
||||||
|
//stroke
|
||||||
|
switch( commands[c] )
|
||||||
|
{
|
||||||
|
case 'N':
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
paintMode |= VG_STROKE_PATH;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0); //unknown command
|
||||||
|
}
|
||||||
|
ps->m_paths[i].m_paintMode = (VGPaintMode)paintMode;
|
||||||
|
c++;
|
||||||
|
|
||||||
|
//line cap
|
||||||
|
switch( commands[c] )
|
||||||
|
{
|
||||||
|
case 'B':
|
||||||
|
ps->m_paths[i].m_capStyle = VG_CAP_BUTT;
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
ps->m_paths[i].m_capStyle = VG_CAP_ROUND;
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
ps->m_paths[i].m_capStyle = VG_CAP_SQUARE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0); //unknown command
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
|
||||||
|
//line join
|
||||||
|
switch( commands[c] )
|
||||||
|
{
|
||||||
|
case 'M':
|
||||||
|
ps->m_paths[i].m_joinStyle = VG_JOIN_MITER;
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
ps->m_paths[i].m_joinStyle = VG_JOIN_ROUND;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
ps->m_paths[i].m_joinStyle = VG_JOIN_BEVEL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0); //unknown command
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
|
||||||
|
//the rest of stroke attributes
|
||||||
|
ps->m_paths[i].m_miterLimit = points[p++];
|
||||||
|
ps->m_paths[i].m_strokeWidth = points[p++];
|
||||||
|
|
||||||
|
//paints
|
||||||
|
color[0] = points[p++];
|
||||||
|
color[1] = points[p++];
|
||||||
|
color[2] = points[p++];
|
||||||
|
color[3] = 1.0f;
|
||||||
|
ps->m_paths[i].m_strokePaint = vgCreatePaint();
|
||||||
|
vgSetParameteri(ps->m_paths[i].m_strokePaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
|
||||||
|
vgSetParameterfv(ps->m_paths[i].m_strokePaint, VG_PAINT_COLOR, 4, color);
|
||||||
|
|
||||||
|
color[0] = points[p++];
|
||||||
|
color[1] = points[p++];
|
||||||
|
color[2] = points[p++];
|
||||||
|
color[3] = 1.0f;
|
||||||
|
ps->m_paths[i].m_fillPaint = vgCreatePaint();
|
||||||
|
vgSetParameteri(ps->m_paths[i].m_fillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
|
||||||
|
vgSetParameterfv(ps->m_paths[i].m_fillPaint, VG_PAINT_COLOR, 4, color);
|
||||||
|
|
||||||
|
//read number of elements
|
||||||
|
|
||||||
|
elements = (int)points[p++];
|
||||||
|
assert(elements > 0);
|
||||||
|
startp = p;
|
||||||
|
for(e=0;e<elements;e++)
|
||||||
|
{
|
||||||
|
switch( commands[c] )
|
||||||
|
{
|
||||||
|
case 'M':
|
||||||
|
cmd[e] = VG_MOVE_TO | VG_ABSOLUTE;
|
||||||
|
p += 2;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
cmd[e] = VG_LINE_TO | VG_ABSOLUTE;
|
||||||
|
p += 2;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
cmd[e] = VG_CUBIC_TO | VG_ABSOLUTE;
|
||||||
|
p += 6;
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
cmd[e] = VG_CLOSE_PATH;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0); //unknown command
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ps->m_paths[i].m_path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, (unsigned int)VG_PATH_CAPABILITY_ALL);
|
||||||
|
vgAppendPathData(ps->m_paths[i].m_path, elements, cmd, points + startp);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
free(cmd);
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PS_destruct(PS* ps)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
assert(ps);
|
||||||
|
for(i=0;i<ps->m_numPaths;i++)
|
||||||
|
{
|
||||||
|
vgDestroyPaint(ps->m_paths[i].m_fillPaint);
|
||||||
|
vgDestroyPaint(ps->m_paths[i].m_strokePaint);
|
||||||
|
vgDestroyPath(ps->m_paths[i].m_path);
|
||||||
|
}
|
||||||
|
free(ps->m_paths);
|
||||||
|
free(ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PS_render(PS* ps)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
assert(ps);
|
||||||
|
vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
|
||||||
|
|
||||||
|
for(i=0;i<ps->m_numPaths;i++)
|
||||||
|
{
|
||||||
|
vgSeti(VG_FILL_RULE, ps->m_paths[i].m_fillRule);
|
||||||
|
vgSetPaint(ps->m_paths[i].m_fillPaint, VG_FILL_PATH);
|
||||||
|
|
||||||
|
if(ps->m_paths[i].m_paintMode & VG_STROKE_PATH)
|
||||||
|
{
|
||||||
|
vgSetf(VG_STROKE_LINE_WIDTH, ps->m_paths[i].m_strokeWidth);
|
||||||
|
vgSeti(VG_STROKE_CAP_STYLE, ps->m_paths[i].m_capStyle);
|
||||||
|
vgSeti(VG_STROKE_JOIN_STYLE, ps->m_paths[i].m_joinStyle);
|
||||||
|
vgSetf(VG_STROKE_MITER_LIMIT, ps->m_paths[i].m_miterLimit);
|
||||||
|
vgSetPaint(ps->m_paths[i].m_strokePaint, VG_STROKE_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
vgDrawPath(ps->m_paths[i].m_path, ps->m_paths[i].m_paintMode);
|
||||||
|
}
|
||||||
|
assert(vgGetError() == VG_NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
PS* tiger = NULL;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void render(int w, int h)
|
||||||
|
{
|
||||||
|
#ifndef __RASPBERRYPI__
|
||||||
|
if(renderWidth != w || renderHeight != h)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
float clearColor[4] = {1,1,1,1};
|
||||||
|
float scale = w / (tigerMaxX - tigerMinX);
|
||||||
|
|
||||||
|
eglSwapBuffers(egldisplay, eglsurface); //force EGL to recognize resize
|
||||||
|
|
||||||
|
vgSetfv(VG_CLEAR_COLOR, 4, clearColor);
|
||||||
|
vgClear(0, 0, w, h);
|
||||||
|
|
||||||
|
vgLoadIdentity();
|
||||||
|
#ifdef __RASPBERRYPI__
|
||||||
|
vgTranslate(w * 0.5f, h * 0.5f);
|
||||||
|
vgRotate(rotateN);
|
||||||
|
vgTranslate(-w * 0.5f, -h * 0.5f);
|
||||||
|
#endif
|
||||||
|
vgScale(scale, scale);
|
||||||
|
vgTranslate(-tigerMinX, -tigerMinY + 0.5f * (h / scale - (tigerMaxY - tigerMinY)));
|
||||||
|
|
||||||
|
PS_render(tiger);
|
||||||
|
assert(vgGetError() == VG_NO_ERROR);
|
||||||
|
|
||||||
|
renderWidth = w;
|
||||||
|
renderHeight = h;
|
||||||
|
}
|
||||||
|
#ifndef __RASPBERRYPI__
|
||||||
|
eglSwapBuffers(egldisplay, eglsurface);
|
||||||
|
assert(eglGetError() == EGL_SUCCESS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void init(NativeWindowType window)
|
||||||
|
{
|
||||||
|
static const EGLint s_configAttribs[] =
|
||||||
|
{
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_ALPHA_SIZE, 8,
|
||||||
|
EGL_LUMINANCE_SIZE, EGL_DONT_CARE, //EGL_DONT_CARE
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
EGL_SAMPLES, 1,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
EGLint numconfigs;
|
||||||
|
|
||||||
|
egldisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
|
eglInitialize(egldisplay, NULL, NULL);
|
||||||
|
assert(eglGetError() == EGL_SUCCESS);
|
||||||
|
eglBindAPI(EGL_OPENVG_API);
|
||||||
|
|
||||||
|
eglChooseConfig(egldisplay, s_configAttribs, &eglconfig, 1, &numconfigs);
|
||||||
|
assert(eglGetError() == EGL_SUCCESS);
|
||||||
|
assert(numconfigs == 1);
|
||||||
|
|
||||||
|
eglsurface = eglCreateWindowSurface(egldisplay, eglconfig, window, NULL);
|
||||||
|
assert(eglGetError() == EGL_SUCCESS);
|
||||||
|
eglcontext = eglCreateContext(egldisplay, eglconfig, NULL, NULL);
|
||||||
|
assert(eglGetError() == EGL_SUCCESS);
|
||||||
|
eglMakeCurrent(egldisplay, eglsurface, eglsurface, eglcontext);
|
||||||
|
assert(eglGetError() == EGL_SUCCESS);
|
||||||
|
|
||||||
|
tiger = PS_construct(tigerCommands, tigerCommandCount, tigerPoints, tigerPointCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void deinit(void)
|
||||||
|
{
|
||||||
|
PS_destruct(tiger);
|
||||||
|
eglMakeCurrent(egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
assert(eglGetError() == EGL_SUCCESS);
|
||||||
|
eglTerminate(egldisplay);
|
||||||
|
assert(eglGetError() == EGL_SUCCESS);
|
||||||
|
eglReleaseThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#pragma warning(disable:4115) /* named type definition in parentheses (this comes from a visual studio include file) */
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
static LONG WINAPI windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_CLOSE:
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
case WM_PAINT:
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
InvalidateRect(hWnd, NULL, 0);
|
||||||
|
GetClientRect(hWnd, &rect);
|
||||||
|
render(rect.right - rect.left, rect.bottom - rect.top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
HWND window;
|
||||||
|
{
|
||||||
|
WNDCLASS wndclass;
|
||||||
|
wndclass.style = 0;
|
||||||
|
wndclass.lpfnWndProc = windowProc;
|
||||||
|
wndclass.cbClsExtra = 0;
|
||||||
|
wndclass.cbWndExtra = 0;
|
||||||
|
wndclass.hInstance = (HINSTANCE)GetModuleHandle(NULL);
|
||||||
|
wndclass.hIcon = LoadIcon(wndclass.hInstance, MAKEINTRESOURCE(101));
|
||||||
|
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wndclass.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
|
||||||
|
wndclass.lpszMenuName = NULL;
|
||||||
|
wndclass.lpszClassName = "MainWndClass";
|
||||||
|
if (!wndclass.hIcon)
|
||||||
|
wndclass.hIcon = LoadIcon(NULL, IDI_EXCLAMATION);
|
||||||
|
RegisterClass(&wndclass);
|
||||||
|
}
|
||||||
|
|
||||||
|
window = CreateWindow(
|
||||||
|
"MainWndClass",
|
||||||
|
"OpenVG Tiger sample (rendering, please wait)",
|
||||||
|
WS_OVERLAPPEDWINDOW,
|
||||||
|
200, 200, 400, (int)(400.0f / aspectRatio),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(HINSTANCE)GetModuleHandle(NULL),
|
||||||
|
NULL);
|
||||||
|
if (!window)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
init((NativeWindowType)window);
|
||||||
|
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
ShowWindow(window, SW_SHOW);
|
||||||
|
while (GetMessage(&msg, NULL, 0, 0))
|
||||||
|
{
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
if (msg.message == WM_QUIT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit();
|
||||||
|
|
||||||
|
DestroyWindow(window);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#elif defined __APPLE__
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <OpenGL/gl.h>
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
#elif defined __RASPBERRYPI__
|
||||||
|
#include "bcm_host.h"
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
uint32_t width, height;
|
||||||
|
bcm_host_init();
|
||||||
|
int s;
|
||||||
|
|
||||||
|
static EGL_DISPMANX_WINDOW_T nativewindow;
|
||||||
|
|
||||||
|
DISPMANX_ELEMENT_HANDLE_T dispman_element;
|
||||||
|
DISPMANX_DISPLAY_HANDLE_T dispman_display;
|
||||||
|
DISPMANX_UPDATE_HANDLE_T dispman_update;
|
||||||
|
VC_RECT_T dst_rect;
|
||||||
|
VC_RECT_T src_rect;
|
||||||
|
|
||||||
|
s = graphics_get_display_size(0 /* LCD */, &width, &height);
|
||||||
|
assert( s >= 0 );
|
||||||
|
|
||||||
|
dst_rect.x = 0;
|
||||||
|
dst_rect.y = 0;
|
||||||
|
dst_rect.width = width;
|
||||||
|
dst_rect.height = height;
|
||||||
|
|
||||||
|
src_rect.x = 0;
|
||||||
|
src_rect.y = 0;
|
||||||
|
src_rect.width = width << 16;
|
||||||
|
src_rect.height = height << 16;
|
||||||
|
|
||||||
|
dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
|
||||||
|
dispman_update = vc_dispmanx_update_start( 0 );
|
||||||
|
|
||||||
|
dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
|
||||||
|
1/*layer*/, &dst_rect, 0/*src*/,
|
||||||
|
&src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);
|
||||||
|
|
||||||
|
nativewindow.element = dispman_element;
|
||||||
|
nativewindow.width = width;
|
||||||
|
nativewindow.height = height;
|
||||||
|
vc_dispmanx_update_submit_sync( dispman_update );
|
||||||
|
|
||||||
|
init(&nativewindow);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
render(width, height);
|
||||||
|
rotateN += 1.0f;
|
||||||
|
}
|
||||||
|
deinit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
263
host_applications/linux/apps/hello_pi/hello_tiger/readme.txt
Normal file
263
host_applications/linux/apps/hello_pi/hello_tiger/readme.txt
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
OpenVG 1.1 Reference Implementation
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2007 The Khronos Group Inc.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and /or associated documentation files
|
||||||
|
(the "Materials "), to deal in the Materials without restriction,
|
||||||
|
including without limitation the rights to use, copy, modify, merge,
|
||||||
|
publish, distribute, sublicense, and/or sell copies of the Materials,
|
||||||
|
and to permit persons to whom the Materials are furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Materials.
|
||||||
|
|
||||||
|
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
|
||||||
|
THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
|
||||||
|
|
||||||
|
Version
|
||||||
|
-------
|
||||||
|
Official RI for OpenVG 1.1
|
||||||
|
Released: May 13, 2008
|
||||||
|
|
||||||
|
|
||||||
|
Release Notes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
This release is based on OpenVG 1.1 and EGL 1.3 specifications.
|
||||||
|
This release is Windows-only, although the source code
|
||||||
|
compiles at least on Mac OS X 10.5 and Cygwin. Project files are
|
||||||
|
provided for MSVC 6.
|
||||||
|
|
||||||
|
This archive contains sources for OpenVG RI, VGU and EGL. There's
|
||||||
|
also a precompiled libOpenVG.dll that contains OpenVG and EGL implementations.
|
||||||
|
|
||||||
|
|
||||||
|
Package Structure
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
bin
|
||||||
|
win32
|
||||||
|
libOpenVG.dll OpenVG Windows .dll
|
||||||
|
tiger.exe Windows executable of the Tiger sample
|
||||||
|
lib
|
||||||
|
libOpenVG.lib MSVC 6 dll import library
|
||||||
|
ri
|
||||||
|
openvg_ri.dsp MSVC 6 project file for libOpenVG.dll
|
||||||
|
src .cpp and .h -files of the reference implementation
|
||||||
|
win32 Windows backend for EGL
|
||||||
|
macosx Mac OS X backend for EGL
|
||||||
|
null null backend for EGL
|
||||||
|
include Public OpenVG and EGL headers
|
||||||
|
EGL
|
||||||
|
egl.h
|
||||||
|
VG
|
||||||
|
openvg.h
|
||||||
|
vgu.h
|
||||||
|
samples
|
||||||
|
samples.dsw MSVC 6 workspace file for tiger sample and libOpenVG.dll
|
||||||
|
samples.dsp MSVC 6 project file for tiger.exe
|
||||||
|
tiger
|
||||||
|
main.c
|
||||||
|
tiger.c
|
||||||
|
tiger.h
|
||||||
|
readme.txt
|
||||||
|
license.txt
|
||||||
|
|
||||||
|
|
||||||
|
Samples
|
||||||
|
-------
|
||||||
|
|
||||||
|
Tiger
|
||||||
|
|
||||||
|
The release contains a sample application that renders an image of a
|
||||||
|
tiger. Note that the sample doesn't start immediately, since it takes
|
||||||
|
a few seconds to render the image. Resizing the window rerenders the
|
||||||
|
image in the new resolution.
|
||||||
|
|
||||||
|
|
||||||
|
Known Issues
|
||||||
|
------------
|
||||||
|
|
||||||
|
-EGL functionality is incomplete (some functions lack proper error checking, some
|
||||||
|
attribs may not be processed, etc.)
|
||||||
|
-When opening samples.dsw, MSVC may complain about missing Perforce connection. Just
|
||||||
|
ignore that.
|
||||||
|
|
||||||
|
|
||||||
|
Changes
|
||||||
|
-------
|
||||||
|
|
||||||
|
Nov 25, 2008
|
||||||
|
-Clamp color transform scale to [-127, 127] and bias to [-1, 1]
|
||||||
|
|
||||||
|
May 13, 2008
|
||||||
|
- Changed 8 sample MSAA configs into 32 sample configs
|
||||||
|
- Changed max gaussian std deviation to 16 (was 128)
|
||||||
|
- VG_DRAW_IMAGE_MULTIPLY converts luminance to RGB if either paint or image color is RGB
|
||||||
|
- Fixes A40102 by storing input floats as is
|
||||||
|
|
||||||
|
February 12, 2008
|
||||||
|
- fixed arc transformation.
|
||||||
|
- fixed point along path corner cases.
|
||||||
|
- partially fixed A40102 by not filtering invalid float input.
|
||||||
|
|
||||||
|
December 12, 2007
|
||||||
|
- fixed an overflow bug in vgFillMaskLayer error handling.
|
||||||
|
- increased accuracy for Gaussian blur. The new code avoids an infinite loop with a very small std dev.
|
||||||
|
- fixed a bug in Font::find that caused deleted fonts to be returned.
|
||||||
|
|
||||||
|
November 20, 2007
|
||||||
|
- reimplemented 1,2 & 4 bits per pixel images
|
||||||
|
- fixed vgGetParameter for paint
|
||||||
|
- fixed https://cvs.khronos.org/bugzilla/show_bug.cgi?id=1095 RI handling of child images with shared storage
|
||||||
|
-vgGetParent: return closest valid ancestor, or image itself if no ancestor was found.
|
||||||
|
- EGL refactoring & clean up
|
||||||
|
- divided OS native parts of EGL into separate files that should be included in that platform's build
|
||||||
|
- added a generic OS backend for EGL (not thread safe, no window rendering)
|
||||||
|
- fixed https://cvs.khronos.org/bugzilla/show_bug.cgi?id=1943 RI does not handle channel mask correctly for lL/sL/BW1
|
||||||
|
- removed EGL_IMAGE_IN_USE_ERROR from vgDrawGlyph(s)
|
||||||
|
- added configs without an alpha mask to facilitate CTS reference image creation
|
||||||
|
- implemented more accurate stroking by rendering each stroke part into a coverage buffer and compositing from there
|
||||||
|
-fixes https://cvs.khronos.org/bugzilla/show_bug.cgi?id=2221 RI errors at end of curved strokes.
|
||||||
|
- bugfix: joins used path midpoints, interpolateStroke and caps didn't => seams (visible in some G60101 cases)
|
||||||
|
- vgCreateMaskLayer returns VG_INVALID_HANDLE if the current surface doesn't have a mask layer
|
||||||
|
- vgRenderToMask bugfix: temp buffer is now cleared between fill and stroke
|
||||||
|
- bugfix: vgCreateImage returns an error if allowedQuality is zero
|
||||||
|
- bugfix: vgSetPaint returns an error if paintModes is zero
|
||||||
|
- bugfix: vgCreateFont doesn't return an error if capacityHint is zero
|
||||||
|
- bugfix: writeFilteredPixel writes also into luminance formats
|
||||||
|
|
||||||
|
October 12, 2007
|
||||||
|
-Upgrade to OpenVG 1.1, including
|
||||||
|
-Implemented MSAA, added 4 and 8 sample EGLConfigs
|
||||||
|
-Implemented VG_A_4 and VG_A_1 image formats and EGLConfigs
|
||||||
|
-Implemented Glyph API
|
||||||
|
-Implemented new masking functions
|
||||||
|
-Implemented color transform
|
||||||
|
-Implemented native EGL backends for Windows & Mac OS X => Fix for bugzilla 1376 RI uses non-standard EGL implementation
|
||||||
|
*RI now works with CTS generation's native_w32.c (native_ri.c can be removed).
|
||||||
|
*dependency on GLUT has been removed. GLUT code is still included and can be compiled in instead of native by defining RI_USE_GLUT.
|
||||||
|
-16 bit EGLConfigs now expose 4 mask bits, 8 bit configs 8, 4 bit configs 4, and 1 bit configs 1. MSAA configs expose one bit per sample.
|
||||||
|
-EGL now works with any display, not just EGL_DEFAULT_DISPLAY
|
||||||
|
-Simplification: removed code to handle less than 8 bits per pixel. Smaller bit depths always allocate 8 bits per pixel.
|
||||||
|
-Changed rasterizer data types to RScalar and RVector2 so that it's possible to alter RIfloat precision without affecting rasterization.
|
||||||
|
-Accuracy: increased circularLerp precision
|
||||||
|
-Bugfix: matrix inversion now checks if the input matrix is affine and forces the inverted matrix to be affine as well
|
||||||
|
-Bugfix: fixed eglCopyBuffers (copied from dst to dst)
|
||||||
|
-Bugfix: fixed eglCreatePixmapSurface (allowed only VG_sRGBA_8888, didn't give an error if config had more than one sample per pixel)
|
||||||
|
-Bugfix: bugzilla 2465: RI asserts when setting maximum amount of gradient stops
|
||||||
|
|
||||||
|
February 27, 2007
|
||||||
|
-changed to MIT open source license.
|
||||||
|
-bugfix, bugzilla 820: RGB and luminance are now treated as different color spaces.
|
||||||
|
-bugfix, bugzilla 1094/1095: vgGetParent now returns the input image in case its parent is already destroyed.
|
||||||
|
|
||||||
|
December 1, 2006
|
||||||
|
-bugfix, bugzilla 649: allowed image quality is now taken into account when deciding resampling filter.
|
||||||
|
-bugfix, bugzilla 650, bad stroking accuracy reported by TK Chan and Mika Tuomi: curve tessellation is now increased from 64 to 256. RI_MAX_EDGES has been increased from 100000 to 262144 to facilitate the increased number of edges.
|
||||||
|
-bugfix, reported by Chris Wynn, affects I30206: degenerate gradients in repeat mode now render the first stop color instead of the last one.
|
||||||
|
-changed float to RIfloat, added an option to compile RIfloat into a class to test reduced precision float ops
|
||||||
|
|
||||||
|
September 6, 2006
|
||||||
|
-bugfix, bugzilla 591: CLOSE_PATH followed by a MOVE_TO doesn't produce an extra end cap anymore
|
||||||
|
-abs values of arc axis lengths are taken only just before rendering
|
||||||
|
-undefined bits of bitfields are now ignored in the API
|
||||||
|
|
||||||
|
September 1, 2006
|
||||||
|
-changed colorToInt to use mathematical round-to-nearest as recommended by new language in section 3.4.4.
|
||||||
|
-implemented VG_PAINT_COLOR_RAMP_PREMULTIPLIED
|
||||||
|
-implemented VG_STROKE_DASH_PHASE_RESET
|
||||||
|
-implemented new language for filter channelMasks (section 11.2)
|
||||||
|
-tangents returned by vgPointAlongPath are now normalized
|
||||||
|
-implemented VG_MAX_GAUSSIAN_STD_DEVIATION, rewrote Gaussian blur code
|
||||||
|
-vgGetString: if no context, return NULL. VG_VERSION returns the spec version (1.0).
|
||||||
|
-bugfix, bugzilla 542: vgSeparableConvolve now convolves the edge color with the horizontal kernel and uses that as the edge color for the vertical pass
|
||||||
|
-ellipse rh and rv are replaced by their absolute values whenever read for processing, the absolute values are not written into the path data
|
||||||
|
|
||||||
|
August 18, 2006
|
||||||
|
-bugfix, M30301: the arguments for vguComputeWarpQuadToQuad were the wrong way around, destination should come before source.
|
||||||
|
-bugfix, M10102: check for degeneracy in vguComputeWarpSquareToQuad is done before the affinity check so that degenerate affine matrices also produce the bad warp error
|
||||||
|
-bugfix, bugzilla 491: Chris Wynn's vgComputeWarpSquareToQuad -case. There was a wrong mapping between vertices, (1,1) was mapped to (dx2,dy2)
|
||||||
|
-bugfix, bugzilla 519: vguPolygon wrong error check. vguPolygon didn't have an error check for the count argument
|
||||||
|
-bugfix, bugzilla 518: vgGetParameterfv/iv wrong errors. vgGetParametrtfv/iv error checking was for count < 0 instead of count <= 0.
|
||||||
|
-bugfix, bugzilla 517: wrong cap flag checked in vgPathTransformedBounds
|
||||||
|
-bugfix, bugzilla 494: egl.h has wrong values for OPENVG_BIT and OPENGL_ES_BIT. Copied the enumerations from the 1.3 egl.h on the Khronos site (OpenKode/egl/egl.h)
|
||||||
|
-bugfix, bugzilla 492: gradient filter window was biased
|
||||||
|
-bugfix: when appending paths, there was a loop over coordinates to replace arc axis lengths by their absolute values. However, if the path wasn't empty, the loop accessed wrong coordinates. Fixes: Qingping Zhang's cases 2&3.
|
||||||
|
-bugfix: image filter write mask was ignored when writing to VG_A_8 images. Fixes: Qingping Zhang's case 13.
|
||||||
|
-bugfix: if image filter processing format is premultiplied, color channels are clamped to alpha before conversion to destination format
|
||||||
|
-bugfix: in eglReleaseThread the EGL instance was freed when its reference count reached zero, but the pointer wasn't made NULL, causing the use of uninitialized instance.
|
||||||
|
-bugfix: vgClearImage didn't clamp the clear color to [0,1] range
|
||||||
|
-bugfix: a zero-length dash at a path vertex produces a join
|
||||||
|
-bugfix: vgSetParameter now checks paramType for all object types
|
||||||
|
-bugfix: convolution filters incorrectly restricted the area read from the source image to the intersection of source and destination image sizes
|
||||||
|
-bugfix: EGL surface creation now defaults correctly to EGL_COLOR_SPACE_sRGB
|
||||||
|
-antialiasing is done in the linear color space as the spec recommends.
|
||||||
|
-image filters clamp the result to [0,1] range.
|
||||||
|
-Color::pack and Color::convert assert that their input is in [0,1] range
|
||||||
|
-in case a projective transform is used, VGImageMode is always VG_DRAW_IMAGE_NORMAL
|
||||||
|
-the default value for VG_FILTER_FORMAT_LINEAR is now VG_FALSE
|
||||||
|
-added Matrix::isAffine for easy affinity check
|
||||||
|
-Color::clamp clamps color channels to alpha for premultiplied colors
|
||||||
|
-VG_BLEND_LIGHTEN: color channels cannot exceed alpha anymore
|
||||||
|
-RI now supports flexible pixel formats. Any bit depth for RGBA is now supported.
|
||||||
|
-eglGetProcAddress is now properly implemented, it returns a function pointer for eglSetConfigPreferenceHG extension
|
||||||
|
-eglQueryString now returns "eglSetConfigPreferenceHG" for EGL_EXTENSIONS
|
||||||
|
-location of egl.h in RI. use EGL/egl.h, VG/openvg.h, VG/vgu.h
|
||||||
|
-OpenVG 1.0.1 spec changes
|
||||||
|
+use the latest openvg.h
|
||||||
|
+2.8: AA happens in linear space
|
||||||
|
+3.4: alpha channel depth of zero results in alpha=1 when read
|
||||||
|
+4.1: return VG_NO_CONTEXT_ERROR from vgGetError in case no context is current
|
||||||
|
+5.1: VG_SCREEN_LAYOUT (default = screen layout of the display)
|
||||||
|
+5.2, 5.3: vgSet, vgGet, vgSetParameter, vgGetParameter: handling of invalid values of count
|
||||||
|
+5.2.1: new default for VG_FILTER_FORMAT_LINEAR is VG_FALSE
|
||||||
|
+8.5.3: get rid of VG_PATH_DATATYPE_INVALID and VG_IMAGE_FORMAT_INVALID enums
|
||||||
|
+10.2: get rid of old extension image formats, add the official ones
|
||||||
|
+10.5: when reading/writing pixels, clamp color channels to [0, alpha]
|
||||||
|
+10.8: when a projective transform is used, always use VG_DRAW_IMAGE_NORMAL mode
|
||||||
|
+10.8: VG_DRAW_IMAGE_MULTIPLY: if color spaces of paint and image don't match, no conversion takes place, result is in image color space
|
||||||
|
+12.4: clamp the result of additive blend to [0,1]
|
||||||
|
|
||||||
|
October 20, 2005
|
||||||
|
-Gradients are filtered to avoid aliasing
|
||||||
|
-Subpaths that ended with a close path segment were capped and joined incorrectly. Fixed.
|
||||||
|
-Alpha mask was allocated per context, not per EGL surface. Fixed.
|
||||||
|
|
||||||
|
August 22, 2005
|
||||||
|
-Updated to spec amendment
|
||||||
|
-Fixed bugs
|
||||||
|
-Implemented eglChooseConfig and eglReleaseThread
|
||||||
|
|
||||||
|
July 22, 2005
|
||||||
|
-Updated to 18th July 2005 version of the OpenVG 1.0 spec.
|
||||||
|
-Updated to 20th July 2005 version of the EGL 1.2 spec.
|
||||||
|
-Fixed bugs.
|
||||||
|
-openvg.h, vgu.h and egl.h are now contained in include/vg directory.
|
||||||
|
|
||||||
|
May 4, 2005
|
||||||
|
-Updated to April 26th 2005 version of the OpenVG 1.0 spec.
|
||||||
|
-Can share images, paths, and paint between contexts.
|
||||||
|
-Fixed path tangent computation.
|
||||||
|
-Implemented image filters.
|
||||||
|
-Fixed bugs.
|
||||||
|
-Changed directory structure a bit.
|
||||||
|
|
||||||
|
March 29, 2005
|
||||||
|
-Updated to March 28th 2005 version of the OpenVG 1.0 spec.
|
||||||
|
-Changed rasterizer to use 32 samples per pixel in the high quality
|
||||||
|
mode (renders faster at the expense of some aliasing).
|
||||||
|
-EGL allocates sRGB rendering surfaces.
|
||||||
|
-Includes GLUT dll against which tiger.exe was linked.
|
||||||
|
|
||||||
|
March 24, 2005
|
||||||
|
-Initial release.
|
||||||
1952
host_applications/linux/apps/hello_pi/hello_tiger/tiger.c
Normal file
1952
host_applications/linux/apps/hello_pi/hello_tiger/tiger.c
Normal file
File diff suppressed because it is too large
Load Diff
45
host_applications/linux/apps/hello_pi/hello_tiger/tiger.h
Normal file
45
host_applications/linux/apps/hello_pi/hello_tiger/tiger.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef __TIGER_H
|
||||||
|
#define __TIGER_H
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* OpenVG 1.0.1 Reference Implementation sample code
|
||||||
|
* -------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007 The Khronos Group Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and /or associated documentation files
|
||||||
|
* (the "Materials "), to deal in the Materials without restriction,
|
||||||
|
* including without limitation the rights to use, copy, modify, merge,
|
||||||
|
* publish, distribute, sublicense, and/or sell copies of the Materials,
|
||||||
|
* and to permit persons to whom the Materials are furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Materials.
|
||||||
|
*
|
||||||
|
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
|
||||||
|
* THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*
|
||||||
|
*//**
|
||||||
|
* \file
|
||||||
|
* \brief Header for including the Tiger image data.
|
||||||
|
* \note
|
||||||
|
*//*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern const int tigerCommandCount;
|
||||||
|
extern const char tigerCommands[];
|
||||||
|
extern const float tigerMinX;
|
||||||
|
extern const float tigerMaxX;
|
||||||
|
extern const float tigerMinY;
|
||||||
|
extern const float tigerMaxY;
|
||||||
|
extern const int tigerPointCount;
|
||||||
|
extern const float tigerPoints[];
|
||||||
|
|
||||||
|
#endif /* __TIGER_H */
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
set(EXEC hello_triangle.bin)
|
||||||
|
set(SRCS triangle.c)
|
||||||
|
|
||||||
|
add_executable(${EXEC} ${SRCS})
|
||||||
|
target_link_libraries(${EXEC} ${HELLO_PI_LIBS})
|
||||||
|
|
||||||
|
install(TARGETS ${EXEC}
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
3
host_applications/linux/apps/hello_pi/hello_triangle/Djenne_128_128.raw
Executable file
3
host_applications/linux/apps/hello_pi/hello_triangle/Djenne_128_128.raw
Executable file
File diff suppressed because one or more lines are too long
BIN
host_applications/linux/apps/hello_pi/hello_triangle/Gaudi_128_128.raw
Executable file
BIN
host_applications/linux/apps/hello_pi/hello_triangle/Gaudi_128_128.raw
Executable file
Binary file not shown.
BIN
host_applications/linux/apps/hello_pi/hello_triangle/Lucca_128_128.raw
Executable file
BIN
host_applications/linux/apps/hello_pi/hello_triangle/Lucca_128_128.raw
Executable file
Binary file not shown.
5
host_applications/linux/apps/hello_pi/hello_triangle/Makefile
Executable file
5
host_applications/linux/apps/hello_pi/hello_triangle/Makefile
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
OBJS=triangle.o
|
||||||
|
BIN=hello_triangle.bin
|
||||||
|
|
||||||
|
include ../Makefile.include
|
||||||
|
|
||||||
135
host_applications/linux/apps/hello_pi/hello_triangle/cube_texture_and_coords.h
Executable file
135
host_applications/linux/apps/hello_pi/hello_triangle/cube_texture_and_coords.h
Executable file
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Spatial coordinates for the cube
|
||||||
|
|
||||||
|
static const GLbyte quadx[6*4*3] = {
|
||||||
|
/* FRONT */
|
||||||
|
-10, -10, 10,
|
||||||
|
10, -10, 10,
|
||||||
|
-10, 10, 10,
|
||||||
|
10, 10, 10,
|
||||||
|
|
||||||
|
/* BACK */
|
||||||
|
-10, -10, -10,
|
||||||
|
-10, 10, -10,
|
||||||
|
10, -10, -10,
|
||||||
|
10, 10, -10,
|
||||||
|
|
||||||
|
/* LEFT */
|
||||||
|
-10, -10, 10,
|
||||||
|
-10, 10, 10,
|
||||||
|
-10, -10, -10,
|
||||||
|
-10, 10, -10,
|
||||||
|
|
||||||
|
/* RIGHT */
|
||||||
|
10, -10, -10,
|
||||||
|
10, 10, -10,
|
||||||
|
10, -10, 10,
|
||||||
|
10, 10, 10,
|
||||||
|
|
||||||
|
/* TOP */
|
||||||
|
-10, 10, 10,
|
||||||
|
10, 10, 10,
|
||||||
|
-10, 10, -10,
|
||||||
|
10, 10, -10,
|
||||||
|
|
||||||
|
/* BOTTOM */
|
||||||
|
-10, -10, 10,
|
||||||
|
-10, -10, -10,
|
||||||
|
10, -10, 10,
|
||||||
|
10, -10, -10,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Texture coordinates for the quad. */
|
||||||
|
static const GLfloat texCoords[6 * 4 * 2] = {
|
||||||
|
0.f, 0.f,
|
||||||
|
0.f, 1.f,
|
||||||
|
1.f, 0.f,
|
||||||
|
1.f, 1.f,
|
||||||
|
|
||||||
|
0.f, 0.f,
|
||||||
|
0.f, 1.f,
|
||||||
|
1.f, 0.f,
|
||||||
|
1.f, 1.f,
|
||||||
|
|
||||||
|
0.f, 0.f,
|
||||||
|
0.f, 1.f,
|
||||||
|
1.f, 0.f,
|
||||||
|
1.f, 1.f,
|
||||||
|
|
||||||
|
0.f, 0.f,
|
||||||
|
0.f, 1.f,
|
||||||
|
1.f, 0.f,
|
||||||
|
1.f, 1.f,
|
||||||
|
|
||||||
|
0.f, 0.f,
|
||||||
|
0.f, 1.f,
|
||||||
|
1.f, 0.f,
|
||||||
|
1.f, 1.f,
|
||||||
|
|
||||||
|
0.f, 0.f,
|
||||||
|
0.f, 1.f,
|
||||||
|
1.f, 0.f,
|
||||||
|
1.f, 1.f
|
||||||
|
};
|
||||||
|
|
||||||
|
// Colors are invisible when textures appear on all 6 faces.
|
||||||
|
// If textures are disabled, e.g. by commenting out glEnable(GL_TEXTURE_2D),
|
||||||
|
// the colours will appear.
|
||||||
|
|
||||||
|
static const GLfloat colorsf[6*4*4] = {
|
||||||
|
1.f, 0.f, 0.f, 1.f, //red
|
||||||
|
1.f, 0.f, 0.f, 1.f,
|
||||||
|
1.f, 0.f, 0.f, 1.f,
|
||||||
|
1.f, 0.f, 0.f, 1.f,
|
||||||
|
|
||||||
|
0.f, 1.f, 0.f, 1.f, // blue
|
||||||
|
0.f, 1.f, 0.f, 1.f,
|
||||||
|
0.f, 1.f, 0.f, 1.f,
|
||||||
|
0.f, 1.f, 0.f, 1.f,
|
||||||
|
|
||||||
|
0.f, 0.f, 1.f, 1.f, // green
|
||||||
|
0.f, 0.f, 1.f, 1.f,
|
||||||
|
0.f, 0.f, 1.f, 1.f,
|
||||||
|
0.f, 0.f, 1.f, 1.f,
|
||||||
|
|
||||||
|
0.f, 0.5f, 0.5f, 1.f, // teal
|
||||||
|
0.f, 0.5f, 0.5f, 1.f,
|
||||||
|
0.f, 0.5f, 0.5f, 1.f,
|
||||||
|
0.f, 0.5f, 0.5f, 1.f,
|
||||||
|
|
||||||
|
0.5f, 0.5f, 0.f, 1.f, // yellow
|
||||||
|
0.5f, 0.5f, 0.f, 1.f,
|
||||||
|
0.5f, 0.5f, 0.f, 1.f,
|
||||||
|
0.5f, 0.5f, 0.f, 1.f,
|
||||||
|
|
||||||
|
0.5f, 0.f, 0.5f, 1.f, // purple
|
||||||
|
0.5f, 0.f, 0.5f, 1.f,
|
||||||
|
0.5f, 0.f, 0.5f, 1.f,
|
||||||
|
0.5f, 0.f, 0.5f, 1.f
|
||||||
|
};
|
||||||
551
host_applications/linux/apps/hello_pi/hello_triangle/triangle.c
Executable file
551
host_applications/linux/apps/hello_pi/hello_triangle/triangle.c
Executable file
@@ -0,0 +1,551 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// A rotating cube rendered with OpenGL|ES. Three images used as textures on the cube faces.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "bcm_host.h"
|
||||||
|
|
||||||
|
#include "GLES/gl.h"
|
||||||
|
#include "EGL/egl.h"
|
||||||
|
#include "EGL/eglext.h"
|
||||||
|
|
||||||
|
#include "cube_texture_and_coords.h"
|
||||||
|
|
||||||
|
#define PATH "./"
|
||||||
|
|
||||||
|
#define IMAGE_SIZE 128
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.141592654
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t screen_width;
|
||||||
|
uint32_t screen_height;
|
||||||
|
// OpenGL|ES objects
|
||||||
|
EGLDisplay display;
|
||||||
|
EGLSurface surface;
|
||||||
|
EGLContext context;
|
||||||
|
GLuint tex[6];
|
||||||
|
// model rotation vector and direction
|
||||||
|
GLfloat rot_angle_x_inc;
|
||||||
|
GLfloat rot_angle_y_inc;
|
||||||
|
GLfloat rot_angle_z_inc;
|
||||||
|
// current model rotation angles
|
||||||
|
GLfloat rot_angle_x;
|
||||||
|
GLfloat rot_angle_y;
|
||||||
|
GLfloat rot_angle_z;
|
||||||
|
// current distance from camera
|
||||||
|
GLfloat distance;
|
||||||
|
GLfloat distance_inc;
|
||||||
|
// pointers to texture buffers
|
||||||
|
char *tex_buf1;
|
||||||
|
char *tex_buf2;
|
||||||
|
char *tex_buf3;
|
||||||
|
} CUBE_STATE_T;
|
||||||
|
|
||||||
|
static void init_ogl(CUBE_STATE_T *state);
|
||||||
|
static void init_model_proj(CUBE_STATE_T *state);
|
||||||
|
static void reset_model(CUBE_STATE_T *state);
|
||||||
|
static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc);
|
||||||
|
static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc);
|
||||||
|
static void redraw_scene(CUBE_STATE_T *state);
|
||||||
|
static void update_model(CUBE_STATE_T *state);
|
||||||
|
static void init_textures(CUBE_STATE_T *state);
|
||||||
|
static void load_tex_images(CUBE_STATE_T *state);
|
||||||
|
static void exit_func(void);
|
||||||
|
static volatile int terminate;
|
||||||
|
static CUBE_STATE_T _state, *state=&_state;
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Name: init_ogl
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* CUBE_STATE_T *state - holds OGLES model info
|
||||||
|
*
|
||||||
|
* Description: Sets the display, OpenGL|ES context and screen stuff
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
static void init_ogl(CUBE_STATE_T *state)
|
||||||
|
{
|
||||||
|
int32_t success = 0;
|
||||||
|
EGLBoolean result;
|
||||||
|
EGLint num_config;
|
||||||
|
|
||||||
|
static EGL_DISPMANX_WINDOW_T nativewindow;
|
||||||
|
|
||||||
|
DISPMANX_ELEMENT_HANDLE_T dispman_element;
|
||||||
|
DISPMANX_DISPLAY_HANDLE_T dispman_display;
|
||||||
|
DISPMANX_UPDATE_HANDLE_T dispman_update;
|
||||||
|
VC_RECT_T dst_rect;
|
||||||
|
VC_RECT_T src_rect;
|
||||||
|
|
||||||
|
static const EGLint attribute_list[] =
|
||||||
|
{
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_ALPHA_SIZE, 8,
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
EGLConfig config;
|
||||||
|
|
||||||
|
// get an EGL display connection
|
||||||
|
state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
|
assert(state->display!=EGL_NO_DISPLAY);
|
||||||
|
|
||||||
|
// initialize the EGL display connection
|
||||||
|
result = eglInitialize(state->display, NULL, NULL);
|
||||||
|
assert(EGL_FALSE != result);
|
||||||
|
|
||||||
|
// get an appropriate EGL frame buffer configuration
|
||||||
|
result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
|
||||||
|
assert(EGL_FALSE != result);
|
||||||
|
|
||||||
|
// create an EGL rendering context
|
||||||
|
state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL);
|
||||||
|
assert(state->context!=EGL_NO_CONTEXT);
|
||||||
|
|
||||||
|
// create an EGL window surface
|
||||||
|
success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
|
||||||
|
assert( success >= 0 );
|
||||||
|
|
||||||
|
dst_rect.x = 0;
|
||||||
|
dst_rect.y = 0;
|
||||||
|
dst_rect.width = state->screen_width;
|
||||||
|
dst_rect.height = state->screen_height;
|
||||||
|
|
||||||
|
src_rect.x = 0;
|
||||||
|
src_rect.y = 0;
|
||||||
|
src_rect.width = state->screen_width << 16;
|
||||||
|
src_rect.height = state->screen_height << 16;
|
||||||
|
|
||||||
|
dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
|
||||||
|
dispman_update = vc_dispmanx_update_start( 0 );
|
||||||
|
|
||||||
|
dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
|
||||||
|
0/*layer*/, &dst_rect, 0/*src*/,
|
||||||
|
&src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);
|
||||||
|
|
||||||
|
nativewindow.element = dispman_element;
|
||||||
|
nativewindow.width = state->screen_width;
|
||||||
|
nativewindow.height = state->screen_height;
|
||||||
|
vc_dispmanx_update_submit_sync( dispman_update );
|
||||||
|
|
||||||
|
state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
|
||||||
|
assert(state->surface != EGL_NO_SURFACE);
|
||||||
|
|
||||||
|
// connect the context to the surface
|
||||||
|
result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
|
||||||
|
assert(EGL_FALSE != result);
|
||||||
|
|
||||||
|
// Set background color and clear buffers
|
||||||
|
glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
|
||||||
|
glClear( GL_COLOR_BUFFER_BIT );
|
||||||
|
glClear( GL_DEPTH_BUFFER_BIT );
|
||||||
|
glShadeModel(GL_FLAT);
|
||||||
|
|
||||||
|
// Enable back face culling.
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Name: init_model_proj
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* CUBE_STATE_T *state - holds OGLES model info
|
||||||
|
*
|
||||||
|
* Description: Sets the OpenGL|ES model to default values
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
static void init_model_proj(CUBE_STATE_T *state)
|
||||||
|
{
|
||||||
|
float nearp = 1.0f;
|
||||||
|
float farp = 500.0f;
|
||||||
|
float hht;
|
||||||
|
float hwd;
|
||||||
|
|
||||||
|
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
|
||||||
|
|
||||||
|
glViewport(0, 0, (GLsizei)state->screen_width, (GLsizei)state->screen_height);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
hht = nearp * (float)tan(45.0 / 2.0 / 180.0 * M_PI);
|
||||||
|
hwd = hht * (float)state->screen_width / (float)state->screen_height;
|
||||||
|
|
||||||
|
glFrustumf(-hwd, hwd, -hht, hht, nearp, farp);
|
||||||
|
|
||||||
|
glEnableClientState( GL_VERTEX_ARRAY );
|
||||||
|
glVertexPointer( 3, GL_BYTE, 0, quadx );
|
||||||
|
|
||||||
|
glEnableClientState( GL_COLOR_ARRAY );
|
||||||
|
glColorPointer(4, GL_FLOAT, 0, colorsf);
|
||||||
|
|
||||||
|
reset_model(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Name: reset_model
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* CUBE_STATE_T *state - holds OGLES model info
|
||||||
|
*
|
||||||
|
* Description: Resets the Model projection and rotation direction
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
static void reset_model(CUBE_STATE_T *state)
|
||||||
|
{
|
||||||
|
// reset model position
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
glTranslatef(0.f, 0.f, -50.f);
|
||||||
|
|
||||||
|
// reset model rotation
|
||||||
|
state->rot_angle_x = 45.f; state->rot_angle_y = 30.f; state->rot_angle_z = 0.f;
|
||||||
|
state->rot_angle_x_inc = 0.5f; state->rot_angle_y_inc = 0.5f; state->rot_angle_z_inc = 0.f;
|
||||||
|
state->distance = 40.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Name: update_model
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* CUBE_STATE_T *state - holds OGLES model info
|
||||||
|
*
|
||||||
|
* Description: Updates model projection to current position/rotation
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
static void update_model(CUBE_STATE_T *state)
|
||||||
|
{
|
||||||
|
// update position
|
||||||
|
state->rot_angle_x = inc_and_wrap_angle(state->rot_angle_x, state->rot_angle_x_inc);
|
||||||
|
state->rot_angle_y = inc_and_wrap_angle(state->rot_angle_y, state->rot_angle_y_inc);
|
||||||
|
state->rot_angle_z = inc_and_wrap_angle(state->rot_angle_z, state->rot_angle_z_inc);
|
||||||
|
state->distance = inc_and_clip_distance(state->distance, state->distance_inc);
|
||||||
|
|
||||||
|
glLoadIdentity();
|
||||||
|
// move camera back to see the cube
|
||||||
|
glTranslatef(0.f, 0.f, -state->distance);
|
||||||
|
|
||||||
|
// Rotate model to new position
|
||||||
|
glRotatef(state->rot_angle_x, 1.f, 0.f, 0.f);
|
||||||
|
glRotatef(state->rot_angle_y, 0.f, 1.f, 0.f);
|
||||||
|
glRotatef(state->rot_angle_z, 0.f, 0.f, 1.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Name: inc_and_wrap_angle
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* GLfloat angle current angle
|
||||||
|
* GLfloat angle_inc angle increment
|
||||||
|
*
|
||||||
|
* Description: Increments or decrements angle by angle_inc degrees
|
||||||
|
* Wraps to 0 at 360 deg.
|
||||||
|
*
|
||||||
|
* Returns: new value of angle
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc)
|
||||||
|
{
|
||||||
|
angle += angle_inc;
|
||||||
|
|
||||||
|
if (angle >= 360.0)
|
||||||
|
angle -= 360.f;
|
||||||
|
else if (angle <=0)
|
||||||
|
angle += 360.f;
|
||||||
|
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Name: inc_and_clip_distance
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* GLfloat distance current distance
|
||||||
|
* GLfloat distance_inc distance increment
|
||||||
|
*
|
||||||
|
* Description: Increments or decrements distance by distance_inc units
|
||||||
|
* Clips to range
|
||||||
|
*
|
||||||
|
* Returns: new value of angle
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc)
|
||||||
|
{
|
||||||
|
distance += distance_inc;
|
||||||
|
|
||||||
|
if (distance >= 120.0f)
|
||||||
|
distance = 120.f;
|
||||||
|
else if (distance <= 40.0f)
|
||||||
|
distance = 40.0f;
|
||||||
|
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Name: redraw_scene
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* CUBE_STATE_T *state - holds OGLES model info
|
||||||
|
*
|
||||||
|
* Description: Draws the model and calls eglSwapBuffers
|
||||||
|
* to render to screen
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
static void redraw_scene(CUBE_STATE_T *state)
|
||||||
|
{
|
||||||
|
// Start with a clear screen
|
||||||
|
glClear( GL_COLOR_BUFFER_BIT );
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
|
||||||
|
// Draw first (front) face:
|
||||||
|
// Bind texture surface to current vertices
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[0]);
|
||||||
|
|
||||||
|
// Need to rotate textures - do this by rotating each cube face
|
||||||
|
glRotatef(270.f, 0.f, 0.f, 1.f ); // front face normal along z axis
|
||||||
|
|
||||||
|
// draw first 4 vertices
|
||||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
// same pattern for other 5 faces - rotation chosen to make image orientation 'nice'
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[1]);
|
||||||
|
glRotatef(90.f, 0.f, 0.f, 1.f ); // back face normal along z axis
|
||||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 4, 4);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[2]);
|
||||||
|
glRotatef(90.f, 1.f, 0.f, 0.f ); // left face normal along x axis
|
||||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 8, 4);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[3]);
|
||||||
|
glRotatef(90.f, 1.f, 0.f, 0.f ); // right face normal along x axis
|
||||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 12, 4);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[4]);
|
||||||
|
glRotatef(270.f, 0.f, 1.f, 0.f ); // top face normal along y axis
|
||||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 16, 4);
|
||||||
|
|
||||||
|
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[5]);
|
||||||
|
glRotatef(90.f, 0.f, 1.f, 0.f ); // bottom face normal along y axis
|
||||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 20, 4);
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
eglSwapBuffers(state->display, state->surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Name: init_textures
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* CUBE_STATE_T *state - holds OGLES model info
|
||||||
|
*
|
||||||
|
* Description: Initialise OGL|ES texture surfaces to use image
|
||||||
|
* buffers
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
static void init_textures(CUBE_STATE_T *state)
|
||||||
|
{
|
||||||
|
// load three texture buffers but use them on six OGL|ES texture surfaces
|
||||||
|
load_tex_images(state);
|
||||||
|
glGenTextures(6, &state->tex[0]);
|
||||||
|
|
||||||
|
// setup first texture
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[0]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
|
||||||
|
// setup second texture - reuse first image
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[1]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
|
||||||
|
// third texture
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[2]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
|
||||||
|
// fourth texture - reuse second image
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[3]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
|
||||||
|
//fifth texture
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[4]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
|
||||||
|
// sixth texture - reuse third image
|
||||||
|
glBindTexture(GL_TEXTURE_2D, state->tex[5]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
|
||||||
|
|
||||||
|
// setup overall texture environment
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Name: load_tex_images
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* void
|
||||||
|
*
|
||||||
|
* Description: Loads three raw images to use as textures on faces
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
static void load_tex_images(CUBE_STATE_T *state)
|
||||||
|
{
|
||||||
|
FILE *tex_file1 = NULL, *tex_file2=NULL, *tex_file3 = NULL;
|
||||||
|
int bytes_read, image_sz = IMAGE_SIZE*IMAGE_SIZE*3;
|
||||||
|
|
||||||
|
state->tex_buf1 = malloc(image_sz);
|
||||||
|
state->tex_buf2 = malloc(image_sz);
|
||||||
|
state->tex_buf3 = malloc(image_sz);
|
||||||
|
|
||||||
|
tex_file1 = fopen(PATH "Lucca_128_128.raw", "rb");
|
||||||
|
if (tex_file1 && state->tex_buf1)
|
||||||
|
{
|
||||||
|
bytes_read=fread(state->tex_buf1, 1, image_sz, tex_file1);
|
||||||
|
assert(bytes_read == image_sz); // some problem with file?
|
||||||
|
fclose(tex_file1);
|
||||||
|
}
|
||||||
|
|
||||||
|
tex_file2 = fopen(PATH "Djenne_128_128.raw", "rb");
|
||||||
|
if (tex_file2 && state->tex_buf2)
|
||||||
|
{
|
||||||
|
bytes_read=fread(state->tex_buf2, 1, image_sz, tex_file2);
|
||||||
|
assert(bytes_read == image_sz); // some problem with file?
|
||||||
|
fclose(tex_file2);
|
||||||
|
}
|
||||||
|
|
||||||
|
tex_file3 = fopen(PATH "Gaudi_128_128.raw", "rb");
|
||||||
|
if (tex_file3 && state->tex_buf3)
|
||||||
|
{
|
||||||
|
bytes_read=fread(state->tex_buf3, 1, image_sz, tex_file3);
|
||||||
|
assert(bytes_read == image_sz); // some problem with file?
|
||||||
|
fclose(tex_file3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void exit_func(void)
|
||||||
|
// Function to be passed to atexit().
|
||||||
|
{
|
||||||
|
// clear screen
|
||||||
|
glClear( GL_COLOR_BUFFER_BIT );
|
||||||
|
eglSwapBuffers(state->display, state->surface);
|
||||||
|
|
||||||
|
// Release OpenGL resources
|
||||||
|
eglMakeCurrent( state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
|
||||||
|
eglDestroySurface( state->display, state->surface );
|
||||||
|
eglDestroyContext( state->display, state->context );
|
||||||
|
eglTerminate( state->display );
|
||||||
|
|
||||||
|
// release texture buffers
|
||||||
|
free(state->tex_buf1);
|
||||||
|
free(state->tex_buf2);
|
||||||
|
free(state->tex_buf3);
|
||||||
|
|
||||||
|
printf("\ncube closed\n");
|
||||||
|
} // exit_func()
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
bcm_host_init();
|
||||||
|
|
||||||
|
// Clear application state
|
||||||
|
memset( state, 0, sizeof( *state ) );
|
||||||
|
|
||||||
|
// Start OGLES
|
||||||
|
init_ogl(state);
|
||||||
|
|
||||||
|
// Setup the model world
|
||||||
|
init_model_proj(state);
|
||||||
|
|
||||||
|
// initialise the OGLES texture(s)
|
||||||
|
init_textures(state);
|
||||||
|
|
||||||
|
while (!terminate)
|
||||||
|
{
|
||||||
|
//usleep(5*1000);
|
||||||
|
update_model(state);
|
||||||
|
redraw_scene(state);
|
||||||
|
}
|
||||||
|
exit_func();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
set(EXEC hello_triangle2.bin)
|
||||||
|
set(SRCS triangle2.c)
|
||||||
|
|
||||||
|
add_executable(${EXEC} ${SRCS})
|
||||||
|
target_link_libraries(${EXEC} ${HELLO_PI_LIBS})
|
||||||
|
|
||||||
|
install(TARGETS ${EXEC}
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
5
host_applications/linux/apps/hello_pi/hello_triangle2/Makefile
Executable file
5
host_applications/linux/apps/hello_pi/hello_triangle2/Makefile
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
OBJS=triangle2.o
|
||||||
|
BIN=hello_triangle2.bin
|
||||||
|
|
||||||
|
include ../Makefile.include
|
||||||
|
|
||||||
509
host_applications/linux/apps/hello_pi/hello_triangle2/triangle2.c
Executable file
509
host_applications/linux/apps/hello_pi/hello_triangle2/triangle2.c
Executable file
@@ -0,0 +1,509 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// OpenGL|ES 2 demo using shader to compute mandelbrot/julia sets
|
||||||
|
// Thanks to Peter de Rivas for original Python code
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "bcm_host.h"
|
||||||
|
|
||||||
|
#include "GLES2/gl2.h"
|
||||||
|
#include "EGL/egl.h"
|
||||||
|
#include "EGL/eglext.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t screen_width;
|
||||||
|
uint32_t screen_height;
|
||||||
|
// OpenGL|ES objects
|
||||||
|
EGLDisplay display;
|
||||||
|
EGLSurface surface;
|
||||||
|
EGLContext context;
|
||||||
|
|
||||||
|
GLuint verbose;
|
||||||
|
GLuint vshader;
|
||||||
|
GLuint fshader;
|
||||||
|
GLuint mshader;
|
||||||
|
GLuint program;
|
||||||
|
GLuint program2;
|
||||||
|
GLuint tex_fb;
|
||||||
|
GLuint tex;
|
||||||
|
GLuint buf;
|
||||||
|
// julia attribs
|
||||||
|
GLuint unif_color, attr_vertex, unif_scale, unif_offset, unif_tex, unif_centre;
|
||||||
|
// mandelbrot attribs
|
||||||
|
GLuint attr_vertex2, unif_scale2, unif_offset2, unif_centre2;
|
||||||
|
} CUBE_STATE_T;
|
||||||
|
|
||||||
|
static CUBE_STATE_T _state, *state=&_state;
|
||||||
|
|
||||||
|
#define check() assert(glGetError() == 0)
|
||||||
|
|
||||||
|
static void showlog(GLint shader)
|
||||||
|
{
|
||||||
|
// Prints the compile log for a shader
|
||||||
|
char log[1024];
|
||||||
|
glGetShaderInfoLog(shader,sizeof log,NULL,log);
|
||||||
|
printf("%d:shader:\n%s\n", shader, log);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void showprogramlog(GLint shader)
|
||||||
|
{
|
||||||
|
// Prints the information log for a program object
|
||||||
|
char log[1024];
|
||||||
|
glGetProgramInfoLog(shader,sizeof log,NULL,log);
|
||||||
|
printf("%d:program:\n%s\n", shader, log);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Name: init_ogl
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* CUBE_STATE_T *state - holds OGLES model info
|
||||||
|
*
|
||||||
|
* Description: Sets the display, OpenGL|ES context and screen stuff
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
static void init_ogl(CUBE_STATE_T *state)
|
||||||
|
{
|
||||||
|
int32_t success = 0;
|
||||||
|
EGLBoolean result;
|
||||||
|
EGLint num_config;
|
||||||
|
|
||||||
|
static EGL_DISPMANX_WINDOW_T nativewindow;
|
||||||
|
|
||||||
|
DISPMANX_ELEMENT_HANDLE_T dispman_element;
|
||||||
|
DISPMANX_DISPLAY_HANDLE_T dispman_display;
|
||||||
|
DISPMANX_UPDATE_HANDLE_T dispman_update;
|
||||||
|
VC_RECT_T dst_rect;
|
||||||
|
VC_RECT_T src_rect;
|
||||||
|
|
||||||
|
static const EGLint attribute_list[] =
|
||||||
|
{
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_ALPHA_SIZE, 8,
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
static const EGLint context_attributes[] =
|
||||||
|
{
|
||||||
|
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
EGLConfig config;
|
||||||
|
|
||||||
|
// get an EGL display connection
|
||||||
|
state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
|
assert(state->display!=EGL_NO_DISPLAY);
|
||||||
|
check();
|
||||||
|
|
||||||
|
// initialize the EGL display connection
|
||||||
|
result = eglInitialize(state->display, NULL, NULL);
|
||||||
|
assert(EGL_FALSE != result);
|
||||||
|
check();
|
||||||
|
|
||||||
|
// get an appropriate EGL frame buffer configuration
|
||||||
|
result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
|
||||||
|
assert(EGL_FALSE != result);
|
||||||
|
check();
|
||||||
|
|
||||||
|
// get an appropriate EGL frame buffer configuration
|
||||||
|
result = eglBindAPI(EGL_OPENGL_ES_API);
|
||||||
|
assert(EGL_FALSE != result);
|
||||||
|
check();
|
||||||
|
|
||||||
|
// create an EGL rendering context
|
||||||
|
state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
|
||||||
|
assert(state->context!=EGL_NO_CONTEXT);
|
||||||
|
check();
|
||||||
|
|
||||||
|
// create an EGL window surface
|
||||||
|
success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
|
||||||
|
assert( success >= 0 );
|
||||||
|
|
||||||
|
dst_rect.x = 0;
|
||||||
|
dst_rect.y = 0;
|
||||||
|
dst_rect.width = state->screen_width;
|
||||||
|
dst_rect.height = state->screen_height;
|
||||||
|
|
||||||
|
src_rect.x = 0;
|
||||||
|
src_rect.y = 0;
|
||||||
|
src_rect.width = state->screen_width << 16;
|
||||||
|
src_rect.height = state->screen_height << 16;
|
||||||
|
|
||||||
|
dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
|
||||||
|
dispman_update = vc_dispmanx_update_start( 0 );
|
||||||
|
|
||||||
|
dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
|
||||||
|
0/*layer*/, &dst_rect, 0/*src*/,
|
||||||
|
&src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);
|
||||||
|
|
||||||
|
nativewindow.element = dispman_element;
|
||||||
|
nativewindow.width = state->screen_width;
|
||||||
|
nativewindow.height = state->screen_height;
|
||||||
|
vc_dispmanx_update_submit_sync( dispman_update );
|
||||||
|
|
||||||
|
check();
|
||||||
|
|
||||||
|
state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
|
||||||
|
assert(state->surface != EGL_NO_SURFACE);
|
||||||
|
check();
|
||||||
|
|
||||||
|
// connect the context to the surface
|
||||||
|
result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
|
||||||
|
assert(EGL_FALSE != result);
|
||||||
|
check();
|
||||||
|
|
||||||
|
// Set background color and clear buffers
|
||||||
|
glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
|
||||||
|
glClear( GL_COLOR_BUFFER_BIT );
|
||||||
|
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void init_shaders(CUBE_STATE_T *state)
|
||||||
|
{
|
||||||
|
static const GLfloat vertex_data[] = {
|
||||||
|
-1.0,-1.0,1.0,1.0,
|
||||||
|
1.0,-1.0,1.0,1.0,
|
||||||
|
1.0,1.0,1.0,1.0,
|
||||||
|
-1.0,1.0,1.0,1.0
|
||||||
|
};
|
||||||
|
const GLchar *vshader_source =
|
||||||
|
"attribute vec4 vertex;"
|
||||||
|
"varying vec2 tcoord;"
|
||||||
|
"void main(void) {"
|
||||||
|
" vec4 pos = vertex;"
|
||||||
|
" gl_Position = pos;"
|
||||||
|
" tcoord = vertex.xy*0.5+0.5;"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
//Mandelbrot
|
||||||
|
const GLchar *mandelbrot_fshader_source =
|
||||||
|
"uniform vec4 color;"
|
||||||
|
"uniform vec2 scale;"
|
||||||
|
"uniform vec2 centre;"
|
||||||
|
"varying vec2 tcoord;"
|
||||||
|
"void main(void) {"
|
||||||
|
" float intensity;"
|
||||||
|
" vec4 color2;"
|
||||||
|
" float cr=(gl_FragCoord.x-centre.x)*scale.x;"
|
||||||
|
" float ci=(gl_FragCoord.y-centre.y)*scale.y;"
|
||||||
|
" float ar=cr;"
|
||||||
|
" float ai=ci;"
|
||||||
|
" float tr,ti;"
|
||||||
|
" float col=0.0;"
|
||||||
|
" float p=0.0;"
|
||||||
|
" int i=0;"
|
||||||
|
" for(int i2=1;i2<16;i2++)"
|
||||||
|
" {"
|
||||||
|
" tr=ar*ar-ai*ai+cr;"
|
||||||
|
" ti=2.0*ar*ai+ci;"
|
||||||
|
" p=tr*tr+ti*ti;"
|
||||||
|
" ar=tr;"
|
||||||
|
" ai=ti;"
|
||||||
|
" if (p>16.0)"
|
||||||
|
" {"
|
||||||
|
" i=i2;"
|
||||||
|
" break;"
|
||||||
|
" }"
|
||||||
|
" }"
|
||||||
|
" color2 = vec4(float(i)*0.0625,0,0,1);"
|
||||||
|
" gl_FragColor = color2;"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
// Julia
|
||||||
|
const GLchar *julia_fshader_source =
|
||||||
|
"uniform vec4 color;"
|
||||||
|
"uniform vec2 scale;"
|
||||||
|
"uniform vec2 centre;"
|
||||||
|
"uniform vec2 offset;"
|
||||||
|
"varying vec2 tcoord;"
|
||||||
|
"uniform sampler2D tex;"
|
||||||
|
"void main(void) {"
|
||||||
|
" float intensity;"
|
||||||
|
" vec4 color2;"
|
||||||
|
" float ar=(gl_FragCoord.x-centre.x)*scale.x;"
|
||||||
|
" float ai=(gl_FragCoord.y-centre.y)*scale.y;"
|
||||||
|
" float cr=(offset.x-centre.x)*scale.x;"
|
||||||
|
" float ci=(offset.y-centre.y)*scale.y;"
|
||||||
|
" float tr,ti;"
|
||||||
|
" float col=0.0;"
|
||||||
|
" float p=0.0;"
|
||||||
|
" int i=0;"
|
||||||
|
" vec2 t2;"
|
||||||
|
" t2.x=tcoord.x+(offset.x-centre.x)*(0.5/centre.y);"
|
||||||
|
" t2.y=tcoord.y+(offset.y-centre.y)*(0.5/centre.x);"
|
||||||
|
" for(int i2=1;i2<16;i2++)"
|
||||||
|
" {"
|
||||||
|
" tr=ar*ar-ai*ai+cr;"
|
||||||
|
" ti=2.0*ar*ai+ci;"
|
||||||
|
" p=tr*tr+ti*ti;"
|
||||||
|
" ar=tr;"
|
||||||
|
" ai=ti;"
|
||||||
|
" if (p>16.0)"
|
||||||
|
" {"
|
||||||
|
" i=i2;"
|
||||||
|
" break;"
|
||||||
|
" }"
|
||||||
|
" }"
|
||||||
|
" color2 = vec4(0,float(i)*0.0625,0,1);"
|
||||||
|
" color2 = color2+texture2D(tex,t2);"
|
||||||
|
" gl_FragColor = color2;"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
state->vshader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(state->vshader, 1, &vshader_source, 0);
|
||||||
|
glCompileShader(state->vshader);
|
||||||
|
check();
|
||||||
|
|
||||||
|
if (state->verbose)
|
||||||
|
showlog(state->vshader);
|
||||||
|
|
||||||
|
state->fshader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(state->fshader, 1, &julia_fshader_source, 0);
|
||||||
|
glCompileShader(state->fshader);
|
||||||
|
check();
|
||||||
|
|
||||||
|
if (state->verbose)
|
||||||
|
showlog(state->fshader);
|
||||||
|
|
||||||
|
state->mshader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(state->mshader, 1, &mandelbrot_fshader_source, 0);
|
||||||
|
glCompileShader(state->mshader);
|
||||||
|
check();
|
||||||
|
|
||||||
|
if (state->verbose)
|
||||||
|
showlog(state->mshader);
|
||||||
|
|
||||||
|
// julia
|
||||||
|
state->program = glCreateProgram();
|
||||||
|
glAttachShader(state->program, state->vshader);
|
||||||
|
glAttachShader(state->program, state->fshader);
|
||||||
|
glLinkProgram(state->program);
|
||||||
|
check();
|
||||||
|
|
||||||
|
if (state->verbose)
|
||||||
|
showprogramlog(state->program);
|
||||||
|
|
||||||
|
state->attr_vertex = glGetAttribLocation(state->program, "vertex");
|
||||||
|
state->unif_color = glGetUniformLocation(state->program, "color");
|
||||||
|
state->unif_scale = glGetUniformLocation(state->program, "scale");
|
||||||
|
state->unif_offset = glGetUniformLocation(state->program, "offset");
|
||||||
|
state->unif_tex = glGetUniformLocation(state->program, "tex");
|
||||||
|
state->unif_centre = glGetUniformLocation(state->program, "centre");
|
||||||
|
|
||||||
|
// mandelbrot
|
||||||
|
state->program2 = glCreateProgram();
|
||||||
|
glAttachShader(state->program2, state->vshader);
|
||||||
|
glAttachShader(state->program2, state->mshader);
|
||||||
|
glLinkProgram(state->program2);
|
||||||
|
check();
|
||||||
|
|
||||||
|
if (state->verbose)
|
||||||
|
showprogramlog(state->program2);
|
||||||
|
|
||||||
|
state->attr_vertex2 = glGetAttribLocation(state->program2, "vertex");
|
||||||
|
state->unif_scale2 = glGetUniformLocation(state->program2, "scale");
|
||||||
|
state->unif_offset2 = glGetUniformLocation(state->program2, "offset");
|
||||||
|
state->unif_centre2 = glGetUniformLocation(state->program2, "centre");
|
||||||
|
check();
|
||||||
|
|
||||||
|
glClearColor ( 0.0, 1.0, 1.0, 1.0 );
|
||||||
|
|
||||||
|
glGenBuffers(1, &state->buf);
|
||||||
|
|
||||||
|
check();
|
||||||
|
|
||||||
|
// Prepare a texture image
|
||||||
|
glGenTextures(1, &state->tex);
|
||||||
|
check();
|
||||||
|
glBindTexture(GL_TEXTURE_2D,state->tex);
|
||||||
|
check();
|
||||||
|
// glActiveTexture(0)
|
||||||
|
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,state->screen_width,state->screen_height,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,0);
|
||||||
|
check();
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
check();
|
||||||
|
// Prepare a framebuffer for rendering
|
||||||
|
glGenFramebuffers(1,&state->tex_fb);
|
||||||
|
check();
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER,state->tex_fb);
|
||||||
|
check();
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,state->tex,0);
|
||||||
|
check();
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||||||
|
check();
|
||||||
|
// Prepare viewport
|
||||||
|
glViewport ( 0, 0, state->screen_width, state->screen_height );
|
||||||
|
check();
|
||||||
|
|
||||||
|
// Upload vertex data to a buffer
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, state->buf);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
|
||||||
|
vertex_data, GL_STATIC_DRAW);
|
||||||
|
glVertexAttribPointer(state->attr_vertex, 4, GL_FLOAT, 0, 16, 0);
|
||||||
|
glEnableVertexAttribArray(state->attr_vertex);
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void draw_mandelbrot_to_texture(CUBE_STATE_T *state, GLfloat cx, GLfloat cy, GLfloat scale)
|
||||||
|
{
|
||||||
|
// Draw the mandelbrot to a texture
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER,state->tex_fb);
|
||||||
|
check();
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, state->buf);
|
||||||
|
|
||||||
|
glUseProgram ( state->program2 );
|
||||||
|
check();
|
||||||
|
|
||||||
|
glUniform2f(state->unif_scale2, scale, scale);
|
||||||
|
glUniform2f(state->unif_centre2, cx, cy);
|
||||||
|
check();
|
||||||
|
glDrawArrays ( GL_TRIANGLE_FAN, 0, 4 );
|
||||||
|
check();
|
||||||
|
|
||||||
|
glFlush();
|
||||||
|
glFinish();
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_triangles(CUBE_STATE_T *state, GLfloat cx, GLfloat cy, GLfloat scale, GLfloat x, GLfloat y)
|
||||||
|
{
|
||||||
|
// Now render to the main frame buffer
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||||||
|
// Clear the background (not really necessary I suppose)
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||||
|
check();
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, state->buf);
|
||||||
|
check();
|
||||||
|
glUseProgram ( state->program );
|
||||||
|
check();
|
||||||
|
glBindTexture(GL_TEXTURE_2D,state->tex);
|
||||||
|
check();
|
||||||
|
glUniform4f(state->unif_color, 0.5, 0.5, 0.8, 1.0);
|
||||||
|
glUniform2f(state->unif_scale, scale, scale);
|
||||||
|
glUniform2f(state->unif_offset, x, y);
|
||||||
|
glUniform2f(state->unif_centre, cx, cy);
|
||||||
|
glUniform1i(state->unif_tex, 0); // I don't really understand this part, perhaps it relates to active texture?
|
||||||
|
check();
|
||||||
|
|
||||||
|
glDrawArrays ( GL_TRIANGLE_FAN, 0, 4 );
|
||||||
|
check();
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
glFlush();
|
||||||
|
glFinish();
|
||||||
|
check();
|
||||||
|
|
||||||
|
eglSwapBuffers(state->display, state->surface);
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_mouse(CUBE_STATE_T *state, int *outx, int *outy)
|
||||||
|
{
|
||||||
|
static int fd = -1;
|
||||||
|
const int width=state->screen_width, height=state->screen_height;
|
||||||
|
static int x=800, y=400;
|
||||||
|
const int XSIGN = 1<<4, YSIGN = 1<<5;
|
||||||
|
if (fd<0) {
|
||||||
|
fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
|
||||||
|
}
|
||||||
|
if (fd>=0) {
|
||||||
|
struct {char buttons, dx, dy; } m;
|
||||||
|
while (1) {
|
||||||
|
int bytes = read(fd, &m, sizeof m);
|
||||||
|
if (bytes < (int)sizeof m) goto _exit;
|
||||||
|
if (m.buttons&8) {
|
||||||
|
break; // This bit should always be set
|
||||||
|
}
|
||||||
|
read(fd, &m, 1); // Try to sync up again
|
||||||
|
}
|
||||||
|
if (m.buttons&3)
|
||||||
|
return m.buttons&3;
|
||||||
|
x+=m.dx;
|
||||||
|
y+=m.dy;
|
||||||
|
if (m.buttons&XSIGN)
|
||||||
|
x-=256;
|
||||||
|
if (m.buttons&YSIGN)
|
||||||
|
y-=256;
|
||||||
|
if (x<0) x=0;
|
||||||
|
if (y<0) y=0;
|
||||||
|
if (x>width) x=width;
|
||||||
|
if (y>height) y=height;
|
||||||
|
}
|
||||||
|
_exit:
|
||||||
|
if (outx) *outx = x;
|
||||||
|
if (outy) *outy = y;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
int terminate = 0;
|
||||||
|
GLfloat cx, cy;
|
||||||
|
bcm_host_init();
|
||||||
|
|
||||||
|
// Clear application state
|
||||||
|
memset( state, 0, sizeof( *state ) );
|
||||||
|
|
||||||
|
// Start OGLES
|
||||||
|
init_ogl(state);
|
||||||
|
init_shaders(state);
|
||||||
|
cx = state->screen_width/2;
|
||||||
|
cy = state->screen_height/2;
|
||||||
|
|
||||||
|
draw_mandelbrot_to_texture(state, cx, cy, 0.003);
|
||||||
|
while (!terminate)
|
||||||
|
{
|
||||||
|
int x, y, b;
|
||||||
|
b = get_mouse(state, &x, &y);
|
||||||
|
if (b) break;
|
||||||
|
draw_triangles(state, cx, cy, 0.003, x, y);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
set(EXEC hello_video.bin)
|
||||||
|
set(SRCS video.c)
|
||||||
|
|
||||||
|
add_executable(${EXEC} ${SRCS})
|
||||||
|
target_link_libraries(${EXEC} ${HELLO_PI_LIBS})
|
||||||
|
|
||||||
|
install(TARGETS ${EXEC}
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
6
host_applications/linux/apps/hello_pi/hello_video/Makefile
Executable file
6
host_applications/linux/apps/hello_pi/hello_video/Makefile
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
OBJS=video.o
|
||||||
|
BIN=hello_video.bin
|
||||||
|
LDFLAGS+=-lilclient
|
||||||
|
|
||||||
|
include ../Makefile.include
|
||||||
|
|
||||||
1
host_applications/linux/apps/hello_pi/hello_video/README
Executable file
1
host_applications/linux/apps/hello_pi/hello_video/README
Executable file
@@ -0,0 +1 @@
|
|||||||
|
The video clip test.h264 is (c) copyright 2008, Blender Foundation / www.bigbuckbunny.org
|
||||||
BIN
host_applications/linux/apps/hello_pi/hello_video/test.h264
Executable file
BIN
host_applications/linux/apps/hello_pi/hello_video/test.h264
Executable file
Binary file not shown.
280
host_applications/linux/apps/hello_pi/hello_video/video.c
Executable file
280
host_applications/linux/apps/hello_pi/hello_video/video.c
Executable file
@@ -0,0 +1,280 @@
|
|||||||
|
/*
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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 char *data = NULL;
|
||||||
|
unsigned int data_len = 0;
|
||||||
|
int find_start_codes = 0;
|
||||||
|
int packet_size = 16<<10;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(find_start_codes && (data = malloc(packet_size+4)) == NULL)
|
||||||
|
{
|
||||||
|
status = -16;
|
||||||
|
if(OMX_Deinit() != OMX_ErrorNone)
|
||||||
|
status = -17;
|
||||||
|
ilclient_destroy(client);
|
||||||
|
fclose(in);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
// 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 = find_start_codes ? data + data_len : buf->pBuffer;
|
||||||
|
|
||||||
|
data_len += fread(dest, 1, packet_size+(find_start_codes*4)-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)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(find_start_codes)
|
||||||
|
{
|
||||||
|
int i, start = -1, len = 0;
|
||||||
|
int max_len = data_len > packet_size ? packet_size : data_len;
|
||||||
|
for(i=2; i<max_len; i++)
|
||||||
|
{
|
||||||
|
if(data[i-2] == 0 && data[i-1] == 0 && data[i] == 1)
|
||||||
|
{
|
||||||
|
len = 3;
|
||||||
|
start = i-2;
|
||||||
|
|
||||||
|
// check for 4 byte start code
|
||||||
|
if(i > 2 && data[i-3] == 0)
|
||||||
|
{
|
||||||
|
len++;
|
||||||
|
start--;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(start == 0)
|
||||||
|
{
|
||||||
|
// start code is next, so just send that
|
||||||
|
buf->nFilledLen = len;
|
||||||
|
}
|
||||||
|
else if(start == -1)
|
||||||
|
{
|
||||||
|
// no start codes seen, send the first block
|
||||||
|
buf->nFilledLen = max_len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// start code in the middle of the buffer, send up to the code
|
||||||
|
buf->nFilledLen = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf->pBuffer, data, buf->nFilledLen);
|
||||||
|
memmove(data, data + buf->nFilledLen, data_len - buf->nFilledLen);
|
||||||
|
data_len -= buf->nFilledLen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Usage: %s <filename>\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
bcm_host_init();
|
||||||
|
return video_decode_test(argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
set(EXEC hello_world.bin)
|
||||||
|
set(SRCS world.c)
|
||||||
|
|
||||||
|
add_executable(${EXEC} ${SRCS})
|
||||||
|
target_link_libraries(${EXEC} ${HELLO_PI_LIBS})
|
||||||
|
|
||||||
|
install(TARGETS ${EXEC}
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
5
host_applications/linux/apps/hello_pi/hello_world/Makefile
Executable file
5
host_applications/linux/apps/hello_pi/hello_world/Makefile
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
OBJS=world.o
|
||||||
|
BIN=hello_world.bin
|
||||||
|
|
||||||
|
include ../Makefile.include
|
||||||
|
|
||||||
39
interface/vmcs_host/linux/vchost_config.h → host_applications/linux/apps/hello_pi/hello_world/world.c
Normal file → Executable file
39
interface/vmcs_host/linux/vchost_config.h → host_applications/linux/apps/hello_pi/hello_world/world.c
Normal file → Executable file
@@ -25,37 +25,12 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef VCHOST_CONFIG_H
|
// Classic Hello World
|
||||||
#define VCHOST_CONFIG_H
|
|
||||||
|
|
||||||
#include "interface/vcos/vcos.h"
|
#include <stdio.h>
|
||||||
|
|
||||||
#if 0
|
int main(void)
|
||||||
/* Types that map onto VideoCore's types of the same name. */
|
{
|
||||||
typedef unsigned char uint8_t;
|
printf("Hello world!\n");
|
||||||
typedef unsigned short uint16_t;
|
return 0;
|
||||||
typedef short int16_t;
|
}
|
||||||
typedef long int32_t;
|
|
||||||
typedef unsigned long uint32_t;
|
|
||||||
typedef long long int64_t;
|
|
||||||
typedef unsigned long long uint64_t;
|
|
||||||
|
|
||||||
#ifndef vc_assert
|
|
||||||
#define vc_assert(cond) vcos_assert(cond)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* On this platform we need to be able to release the host-side software resources. */
|
|
||||||
extern void vc_os_close(void);
|
|
||||||
|
|
||||||
#ifndef VCHPRE_
|
|
||||||
#define VCHPRE_ extern
|
|
||||||
#endif
|
|
||||||
#ifndef VCHPOST_
|
|
||||||
#define VCHPOST_
|
|
||||||
#endif
|
|
||||||
#ifndef VCCPRE_
|
|
||||||
#define VCCPRE_
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
5
host_applications/linux/apps/hello_pi/libs/ilclient/Makefile
Executable file
5
host_applications/linux/apps/hello_pi/libs/ilclient/Makefile
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
OBJS=ilclient.o ilcore.o
|
||||||
|
LIB=libilclient.a
|
||||||
|
|
||||||
|
include ../../Makefile.include
|
||||||
|
|
||||||
1836
host_applications/linux/apps/hello_pi/libs/ilclient/ilclient.c
Normal file
1836
host_applications/linux/apps/hello_pi/libs/ilclient/ilclient.c
Normal file
File diff suppressed because it is too large
Load Diff
1039
host_applications/linux/apps/hello_pi/libs/ilclient/ilclient.h
Normal file
1039
host_applications/linux/apps/hello_pi/libs/ilclient/ilclient.h
Normal file
File diff suppressed because it is too large
Load Diff
308
host_applications/linux/apps/hello_pi/libs/ilclient/ilcore.c
Normal file
308
host_applications/linux/apps/hello_pi/libs/ilclient/ilcore.c
Normal file
@@ -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 */
|
||||||
|
|
||||||
8
host_applications/linux/apps/hello_pi/libs/vgfont/Makefile
Executable file
8
host_applications/linux/apps/hello_pi/libs/vgfont/Makefile
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
OBJS=font.o vgft.o graphics.o
|
||||||
|
LIB=libvgfont.a
|
||||||
|
|
||||||
|
INCLUDES+=-I$(SDKSTAGE)/usr/include/freetype2 -I$(SDKSTAGE)/usr/include -I$(SDKSTAGE)/usr/include/arm-linux-gnueabi
|
||||||
|
CFLAGS+=-D_HAVE_TIMER_T
|
||||||
|
|
||||||
|
include ../../Makefile.include
|
||||||
|
|
||||||
351
host_applications/linux/apps/hello_pi/libs/vgfont/font.c
Normal file
351
host_applications/linux/apps/hello_pi/libs/vgfont/font.c
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Font handling for graphicsx
|
||||||
|
|
||||||
|
/** @file font.c
|
||||||
|
*
|
||||||
|
* Fairly primitive font handling, just enough to emulate the old API.
|
||||||
|
*
|
||||||
|
* Hinting and Font Size
|
||||||
|
*
|
||||||
|
* The old API does not create fonts explicitly, it just renders them
|
||||||
|
* as needed. That works fine for unhinted fonts, but for hinted fonts we
|
||||||
|
* care about font size.
|
||||||
|
*
|
||||||
|
* Since we now *can* do hinted fonts, we should do. Regenerating the
|
||||||
|
* fonts each time becomes quite slow, so we maintain a cache of fonts.
|
||||||
|
*
|
||||||
|
* For the typical applications which use graphics_x this is fine, but
|
||||||
|
* won't work well if lots of fonts sizes are used.
|
||||||
|
*
|
||||||
|
* Unicode
|
||||||
|
*
|
||||||
|
* This API doesn't support unicode at all at present, nor UTF-8.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "graphics_x_private.h"
|
||||||
|
#include "vgft.h"
|
||||||
|
|
||||||
|
#define VMCS_INSTALL_PREFIX ""
|
||||||
|
|
||||||
|
/** The one and only (default) font we support for now.
|
||||||
|
*/
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
const char *file;
|
||||||
|
void *mem;
|
||||||
|
size_t len;
|
||||||
|
} default_font = { "Vera.ttf" };
|
||||||
|
|
||||||
|
/** An entry in our list of fonts
|
||||||
|
*/
|
||||||
|
typedef struct gx_font_cache_entry_t
|
||||||
|
{
|
||||||
|
struct gx_font_cache_entry_t *next;
|
||||||
|
VGFT_FONT_T font;
|
||||||
|
uint32_t ptsize; /** size in points, 26.6 */
|
||||||
|
} gx_font_cache_entry_t;
|
||||||
|
|
||||||
|
static char fname[128];
|
||||||
|
static int inited;
|
||||||
|
static gx_font_cache_entry_t *fonts;
|
||||||
|
|
||||||
|
static VGFT_FONT_T *find_font(const char *text, uint32_t text_size);
|
||||||
|
|
||||||
|
VCOS_STATUS_T gx_priv_font_init(const char *font_dir)
|
||||||
|
{
|
||||||
|
VCOS_STATUS_T ret;
|
||||||
|
size_t len;
|
||||||
|
int rc;
|
||||||
|
if (vgft_init())
|
||||||
|
{
|
||||||
|
ret = VCOS_ENOMEM;
|
||||||
|
goto fail_init;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = -1;
|
||||||
|
// search for the font
|
||||||
|
sprintf(fname, "%s/%s", font_dir, default_font.file);
|
||||||
|
fd = open(fname, O_RDONLY);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
GX_ERROR("Could not open font file '%s'", default_font.file);
|
||||||
|
ret = VCOS_ENOENT;
|
||||||
|
goto fail_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = lseek(fd, 0, SEEK_END);
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
default_font.mem = vcos_malloc(len, default_font.file);
|
||||||
|
if (!default_font.mem)
|
||||||
|
{
|
||||||
|
GX_ERROR("No memory for font %s", fname);
|
||||||
|
ret = VCOS_ENOMEM;
|
||||||
|
goto fail_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = read(fd, default_font.mem, len);
|
||||||
|
if (rc != len)
|
||||||
|
{
|
||||||
|
GX_ERROR("Could not read font %s", fname);
|
||||||
|
ret = VCOS_EINVAL;
|
||||||
|
goto fail_rd;
|
||||||
|
}
|
||||||
|
default_font.len = len;
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
GX_TRACE("Opened font file '%s'", fname);
|
||||||
|
|
||||||
|
inited = 1;
|
||||||
|
return VCOS_SUCCESS;
|
||||||
|
|
||||||
|
fail_rd:
|
||||||
|
vcos_free(default_font.mem);
|
||||||
|
fail_mem:
|
||||||
|
if (fd >= 0) close(fd);
|
||||||
|
fail_open:
|
||||||
|
vgft_term();
|
||||||
|
fail_init:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gx_priv_font_term(void)
|
||||||
|
{
|
||||||
|
gx_font_cache_flush();
|
||||||
|
vgft_term();
|
||||||
|
vcos_free(default_font.mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Render text.
|
||||||
|
*
|
||||||
|
* FIXME: Not at all optimal - re-renders each time.
|
||||||
|
* FIXME: Not UTF-8 aware
|
||||||
|
* FIXME: better caching
|
||||||
|
*/
|
||||||
|
VCOS_STATUS_T gx_priv_render_text( GX_DISPLAY_T *disp,
|
||||||
|
GRAPHICS_RESOURCE_HANDLE res,
|
||||||
|
int32_t x,
|
||||||
|
int32_t y,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t fg_colour,
|
||||||
|
uint32_t bg_colour,
|
||||||
|
const char *text,
|
||||||
|
uint32_t text_length,
|
||||||
|
uint32_t text_size )
|
||||||
|
{
|
||||||
|
VGfloat vg_colour[4];
|
||||||
|
VGFT_FONT_T *font;
|
||||||
|
VGPaint fg;
|
||||||
|
GX_CLIENT_STATE_T save;
|
||||||
|
VCOS_STATUS_T status = VCOS_SUCCESS;
|
||||||
|
int clip = 1;
|
||||||
|
|
||||||
|
vcos_demand(inited); // has gx_font_init() been called?
|
||||||
|
|
||||||
|
gx_priv_save(&save, res);
|
||||||
|
|
||||||
|
if (width == GRAPHICS_RESOURCE_WIDTH &&
|
||||||
|
height == GRAPHICS_RESOURCE_HEIGHT)
|
||||||
|
{
|
||||||
|
clip = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = (width == GRAPHICS_RESOURCE_WIDTH) ? res->width : width;
|
||||||
|
height = (height == GRAPHICS_RESOURCE_HEIGHT) ? res->height : height;
|
||||||
|
font = find_font(text, text_size);
|
||||||
|
if (!font)
|
||||||
|
{
|
||||||
|
status = VCOS_ENOMEM;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup the clipping rectangle
|
||||||
|
if (clip)
|
||||||
|
{
|
||||||
|
VGint coords[] = {x,y,width,height};
|
||||||
|
vgSeti(VG_SCISSORING, VG_TRUE);
|
||||||
|
vgSetiv(VG_SCISSOR_RECTS, 4, coords);
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup the background colour if needed
|
||||||
|
if (bg_colour != GRAPHICS_TRANSPARENT_COLOUR)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
VGfloat rendered_w, rendered_h;
|
||||||
|
VGfloat vg_bg_colour[4];
|
||||||
|
|
||||||
|
// setup the background colour...
|
||||||
|
gx_priv_colour_to_paint(bg_colour, vg_bg_colour);
|
||||||
|
vgSetfv(VG_CLEAR_COLOR, 4, vg_bg_colour);
|
||||||
|
|
||||||
|
// fill in a rectangle...
|
||||||
|
vgft_get_text_extents(font, text, text_length, (VGfloat)x, (VGfloat)y, &rendered_w, &rendered_h);
|
||||||
|
|
||||||
|
if ( ( 0 < (VGint)rendered_w ) && ( 0 < (VGint)rendered_h ) )
|
||||||
|
{
|
||||||
|
vgClear(x, y, (VGint)rendered_w, (VGint)rendered_h);
|
||||||
|
err = vgGetError();
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
GX_LOG("Error %d clearing bg text %d %d %g %g",
|
||||||
|
err, x, y, rendered_w, rendered_h);
|
||||||
|
vcos_assert(0);
|
||||||
|
} // if
|
||||||
|
} // if
|
||||||
|
} // if
|
||||||
|
// setup the foreground colour
|
||||||
|
fg = vgCreatePaint();
|
||||||
|
if (!fg)
|
||||||
|
{
|
||||||
|
status = VCOS_ENOMEM;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the foreground text
|
||||||
|
vgSetParameteri(fg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
|
||||||
|
gx_priv_colour_to_paint(fg_colour, vg_colour);
|
||||||
|
vgSetParameterfv(fg, VG_PAINT_COLOR, 4, vg_colour);
|
||||||
|
vgSetPaint(fg, VG_FILL_PATH);
|
||||||
|
|
||||||
|
vgft_font_draw(font, (VGfloat)x, (VGfloat)y, text, text_length, VG_FILL_PATH);
|
||||||
|
|
||||||
|
vgDestroyPaint(fg);
|
||||||
|
|
||||||
|
vcos_assert(vgGetError() == 0);
|
||||||
|
vgSeti(VG_SCISSORING, VG_FALSE);
|
||||||
|
|
||||||
|
finish:
|
||||||
|
gx_priv_restore(&save);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Find a font in our cache, or create a new entry in the cache.
|
||||||
|
*
|
||||||
|
* Very primitive at present.
|
||||||
|
*/
|
||||||
|
static VGFT_FONT_T *find_font(const char *text, uint32_t text_size)
|
||||||
|
{
|
||||||
|
int ptsize, dpi_x = 0, dpi_y = 0;
|
||||||
|
VCOS_STATUS_T status;
|
||||||
|
gx_font_cache_entry_t *font;
|
||||||
|
|
||||||
|
ptsize = text_size << 6; // freetype takes size in points, in 26.6 format.
|
||||||
|
|
||||||
|
for (font = fonts; font; font = font->next)
|
||||||
|
{
|
||||||
|
if (font->ptsize == ptsize)
|
||||||
|
return &font->font;
|
||||||
|
}
|
||||||
|
|
||||||
|
font = vcos_malloc(sizeof(*font), "font");
|
||||||
|
if (!font)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
font->ptsize = ptsize;
|
||||||
|
|
||||||
|
status = vgft_font_init(&font->font);
|
||||||
|
if (status != VCOS_SUCCESS)
|
||||||
|
{
|
||||||
|
vcos_free(font);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the font
|
||||||
|
status = vgft_font_load_mem(&font->font, default_font.mem, default_font.len);
|
||||||
|
if (status != VCOS_SUCCESS)
|
||||||
|
{
|
||||||
|
GX_LOG("Could not load font from memory: %d", status);
|
||||||
|
vgft_font_term(&font->font);
|
||||||
|
vcos_free(font);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = vgft_font_convert_glyphs(&font->font, ptsize, dpi_x, dpi_y);
|
||||||
|
if (status != VCOS_SUCCESS)
|
||||||
|
{
|
||||||
|
GX_LOG("Could not convert font '%s' at size %d", fname, ptsize);
|
||||||
|
vgft_font_term(&font->font);
|
||||||
|
vcos_free(font);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
font->next = fonts;
|
||||||
|
fonts = font;
|
||||||
|
|
||||||
|
return &font->font;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gx_font_cache_flush(void)
|
||||||
|
{
|
||||||
|
while (fonts != NULL)
|
||||||
|
{
|
||||||
|
struct gx_font_cache_entry_t *next = fonts->next;
|
||||||
|
vgft_font_term(&fonts->font);
|
||||||
|
vcos_free(fonts);
|
||||||
|
fonts = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t graphics_resource_text_dimensions_ext(GRAPHICS_RESOURCE_HANDLE res,
|
||||||
|
const char *text,
|
||||||
|
const uint32_t text_length,
|
||||||
|
uint32_t *width,
|
||||||
|
uint32_t *height,
|
||||||
|
const uint32_t text_size )
|
||||||
|
{
|
||||||
|
GX_CLIENT_STATE_T save;
|
||||||
|
VGfloat w, h;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
gx_priv_save(&save, res);
|
||||||
|
|
||||||
|
VGFT_FONT_T *font = find_font(text, text_size);
|
||||||
|
if (!font)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
|
||||||
|
vgft_get_text_extents(font, text, text_length, 0.0, 0.0, &w, &h);
|
||||||
|
*width = w;
|
||||||
|
*height = h;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
finish:
|
||||||
|
gx_priv_restore(&save);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
1609
host_applications/linux/apps/hello_pi/libs/vgfont/graphics.c
Normal file
1609
host_applications/linux/apps/hello_pi/libs/vgfont/graphics.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,366 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Graphics library for VG
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_X_PRIVATE_H
|
||||||
|
#define GRAPHICS_X_PRIVATE_H
|
||||||
|
|
||||||
|
#define VCOS_LOG_CATEGORY (&gx_log_cat)
|
||||||
|
|
||||||
|
#include "EGL/egl.h"
|
||||||
|
#include "EGL/eglext.h"
|
||||||
|
#include "VG/openvg.h"
|
||||||
|
#include "VG/vgu.h"
|
||||||
|
|
||||||
|
#include "vgfont.h"
|
||||||
|
#include "bcm_host.h"
|
||||||
|
|
||||||
|
extern VCOS_LOG_CAT_T gx_log_cat;
|
||||||
|
|
||||||
|
#define LOG_ERR( fmt, arg... ) vcos_log_error( "%s:%d " fmt, __func__, __LINE__, ##arg)
|
||||||
|
|
||||||
|
#define GX_ERROR(format, arg...) if (1) {} else printf( format "\n", ##arg)
|
||||||
|
#define GX_LOG(format, arg...) if (1) {} else printf( format "\n", ##arg)
|
||||||
|
#define GX_TRACE(format, arg...) if (1) {} else printf( format "\n", ##arg)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
EGL_DISPMANX_WINDOW_T egl_win;
|
||||||
|
} GX_NATIVE_WINDOW_T;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GX_TOP_BOTTOM,
|
||||||
|
GX_BOTTOM_TOP,
|
||||||
|
} GX_RASTER_ORDER_T;
|
||||||
|
|
||||||
|
typedef struct {} GX_PAINT_T;
|
||||||
|
|
||||||
|
typedef struct GX_CLIENT_STATE_T GX_CLIENT_STATE_T;
|
||||||
|
typedef struct {
|
||||||
|
EGLDisplay disp;
|
||||||
|
} GX_DISPLAY_T;
|
||||||
|
|
||||||
|
struct GX_DISPLAY_T
|
||||||
|
{
|
||||||
|
EGLDisplay disp;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GX_WINDOW, GX_PIXMAP, GX_PBUFFER
|
||||||
|
} GX_RES_TYPE;
|
||||||
|
|
||||||
|
#define RES_MAGIC ('G'<<24|'X'<<16|'R'<<8|'S'<<0)
|
||||||
|
#define GX_PRIV_FLAG_FLIP (1<<0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure encapsulating the per-surface state.
|
||||||
|
***********************************************************/
|
||||||
|
typedef struct GRAPHICS_RESOURCE_HANDLE_TABLE_T
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
GX_NATIVE_WINDOW_T native_window;
|
||||||
|
VGImage pixmap;
|
||||||
|
} u;
|
||||||
|
GX_RES_TYPE type;
|
||||||
|
|
||||||
|
uint32_t magic; /** To work around broken create interface */
|
||||||
|
int context_bound;
|
||||||
|
const char *last_caller;
|
||||||
|
EGLSurface surface;
|
||||||
|
EGLContext context;
|
||||||
|
EGLConfig config;
|
||||||
|
uint32_t screen_id; /** 0-LCD, etc */
|
||||||
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
GRAPHICS_RESOURCE_TYPE_T restype;
|
||||||
|
VC_DISPMAN_TRANSFORM_T transform;
|
||||||
|
|
||||||
|
VC_RECT_T dest; /** destination rectangle in use, for book-keeping */
|
||||||
|
|
||||||
|
VGfloat alpha;
|
||||||
|
} GRAPHICS_RESOURCE_HANDLE_TABLE_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure used to store an EGL client state.
|
||||||
|
***********************************************************/
|
||||||
|
struct GX_CLIENT_STATE_T
|
||||||
|
{
|
||||||
|
EGLSurface read_surface;
|
||||||
|
EGLSurface draw_surface;
|
||||||
|
EGLContext context;
|
||||||
|
EGLenum api;
|
||||||
|
GRAPHICS_RESOURCE_HANDLE res;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fixme add documentation
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
void gx_priv_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fixme add documentation
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
void gx_priv_destroy(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fixme add documentation
|
||||||
|
*
|
||||||
|
* @param col colour
|
||||||
|
*
|
||||||
|
* @param rgba OpenVG paint colour
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
void gx_priv_colour_to_paint(uint32_t col, VGfloat *rgba);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save current EGL client state.
|
||||||
|
*
|
||||||
|
* @param state upon return, holds the saved EGL client state.
|
||||||
|
*
|
||||||
|
* @param res handle to the surface the EGL client state belongs to (may be <code>NULL</code>).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void gx_priv_save(GX_CLIENT_STATE_T *state, GRAPHICS_RESOURCE_HANDLE res);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore current EGL client state.
|
||||||
|
*
|
||||||
|
* @param state the EGL client state to restore.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void gx_priv_restore(GX_CLIENT_STATE_T *state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a native window for a surface.
|
||||||
|
*
|
||||||
|
* @param screen_id \fixme
|
||||||
|
*
|
||||||
|
* @param w width of the window
|
||||||
|
*
|
||||||
|
* @param h height of the window
|
||||||
|
*
|
||||||
|
* @param type color/raster format of the resource
|
||||||
|
*
|
||||||
|
* @param win upon successful return, holds a handle to the native window
|
||||||
|
*
|
||||||
|
* @param cookie \fixme
|
||||||
|
*
|
||||||
|
* @return VCOS_SUCCESS on success, or error code.
|
||||||
|
*/
|
||||||
|
int gx_priv_create_native_window(uint32_t screen_id,
|
||||||
|
uint32_t w, uint32_t h,
|
||||||
|
GRAPHICS_RESOURCE_TYPE_T type,
|
||||||
|
GX_NATIVE_WINDOW_T *win,
|
||||||
|
void **cookie);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy native window bound to surface.
|
||||||
|
*
|
||||||
|
* @param res Handle to surface.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void gx_priv_destroy_native_window(GRAPHICS_RESOURCE_HANDLE_TABLE_T *res);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise font from the given directory.
|
||||||
|
*
|
||||||
|
* @param font_dir path to font
|
||||||
|
*
|
||||||
|
* \fixme only supports Vera.tff at the moment?
|
||||||
|
*
|
||||||
|
* @return VCOS_SUCCESS on success, or error code.
|
||||||
|
*/
|
||||||
|
VCOS_STATUS_T gx_priv_font_init(const char *font_dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fixme add documentation
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
void gx_priv_font_term(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill an area of a surface with a single colour.
|
||||||
|
*
|
||||||
|
* @param res Handle to surface.
|
||||||
|
*
|
||||||
|
* @param x x-offset of area to fill
|
||||||
|
*
|
||||||
|
* @param y y-offset of area to fill
|
||||||
|
*
|
||||||
|
* @param width width of area to fill
|
||||||
|
*
|
||||||
|
* @param height height of area to fill
|
||||||
|
*
|
||||||
|
* @param fill_colour fill colour
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
VCOS_STATUS_T gx_priv_resource_fill(GRAPHICS_RESOURCE_HANDLE res,
|
||||||
|
uint32_t x,
|
||||||
|
uint32_t y,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t fill_colour );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render text into a surface
|
||||||
|
*
|
||||||
|
* @param disp Handle to display.
|
||||||
|
*
|
||||||
|
* @param res Handle to surface.
|
||||||
|
*
|
||||||
|
* @param x x-offset
|
||||||
|
*
|
||||||
|
* @param y y-offset
|
||||||
|
*
|
||||||
|
* @param width bounding rectangle width
|
||||||
|
*
|
||||||
|
* @param height bounding rectangle height
|
||||||
|
*
|
||||||
|
* @param fg_colour foreground color
|
||||||
|
*
|
||||||
|
* @param bg_colour background color
|
||||||
|
*
|
||||||
|
* @param text text to render
|
||||||
|
*
|
||||||
|
* @param text_length length of text
|
||||||
|
*
|
||||||
|
* @param text_size size of text
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
VCOS_STATUS_T gx_priv_render_text( GX_DISPLAY_T *disp,
|
||||||
|
GRAPHICS_RESOURCE_HANDLE res,
|
||||||
|
int32_t x,
|
||||||
|
int32_t y,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t fg_colour,
|
||||||
|
uint32_t bg_colour,
|
||||||
|
const char *text,
|
||||||
|
uint32_t text_length,
|
||||||
|
uint32_t text_size );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush a surface.
|
||||||
|
*
|
||||||
|
* @param res Handle to surface.
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
void gx_priv_flush(GRAPHICS_RESOURCE_HANDLE res);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the EGL/VG initialisation of a window has completed
|
||||||
|
* following its creation.
|
||||||
|
*
|
||||||
|
* @param res ???
|
||||||
|
*
|
||||||
|
* @param cookie ???
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
void gx_priv_finish_native_window(GRAPHICS_RESOURCE_HANDLE_TABLE_T *res,
|
||||||
|
void *cookie);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush font cache.
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
void gx_font_cache_flush(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a bitmap (.BMP) image from the given file.
|
||||||
|
*
|
||||||
|
* @param filename filename (must not be <code>NULL</code>).
|
||||||
|
*
|
||||||
|
* @param width holds the width of the image upon return.
|
||||||
|
*
|
||||||
|
* @param height holds the height of the image upon return.
|
||||||
|
*
|
||||||
|
* @param pitch_bytes holds the pitch of the image data (in bytes) upon return.
|
||||||
|
*
|
||||||
|
* @param restype holds the type of the image upon return.
|
||||||
|
*
|
||||||
|
* @param vg_format holds the OpenVG image format upon return.
|
||||||
|
*
|
||||||
|
* @param flags holds flags describing image properties upon return.
|
||||||
|
*
|
||||||
|
* @param image_data_size holds size of the image data upon return.
|
||||||
|
*
|
||||||
|
* @param pimage_data holds the image data buffer upon return (must not be <code>NULL</code>),
|
||||||
|
* the caller is responsible for releasing the buffer afterwards.
|
||||||
|
*
|
||||||
|
* @return 0 if success, non-zero otherwise (in which case the output parameters
|
||||||
|
* may be invalid).
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
int gx_priv_read_bmp(const char *file_name,
|
||||||
|
uint32_t *width, uint32_t *height, uint32_t *pitch_bytes,
|
||||||
|
GRAPHICS_RESOURCE_TYPE_T *restype,
|
||||||
|
VGImageFormat *vg_format,
|
||||||
|
uint32_t *flags,
|
||||||
|
uint32_t *image_data_size,
|
||||||
|
void **pimage_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a Targa (.TGA) image from the given file.
|
||||||
|
*
|
||||||
|
* @param filename filename (must not be <code>NULL</code>).
|
||||||
|
*
|
||||||
|
* @param width holds the width of the image upon return.
|
||||||
|
*
|
||||||
|
* @param height holds the height of the image upon return.
|
||||||
|
*
|
||||||
|
* @param pitch_bytes holds the pitch of the image data (in bytes) upon return.
|
||||||
|
*
|
||||||
|
* @param restype holds the type of the image upon return.
|
||||||
|
*
|
||||||
|
* @param vg_format holds the OpenVG image format upon return.
|
||||||
|
*
|
||||||
|
* @param flags holds flags describing image properties upon return.
|
||||||
|
*
|
||||||
|
* @param image_data_size holds size of the image data upon return.
|
||||||
|
*
|
||||||
|
* @param pimage_data holds the image data buffer upon return (must not be <code>NULL</code>),
|
||||||
|
* the caller is responsible for releasing the memory afterwards.
|
||||||
|
*
|
||||||
|
* @return 0 if success, non-zero otherwise (in which case the output parameters.
|
||||||
|
* may be invalid).
|
||||||
|
*
|
||||||
|
***********************************************************/
|
||||||
|
int gx_priv_read_tga(const char *file_name,
|
||||||
|
uint32_t *width, uint32_t *height, uint32_t *pitch_bytes,
|
||||||
|
GRAPHICS_RESOURCE_TYPE_T *restype,
|
||||||
|
VGImageFormat *vg_format,
|
||||||
|
uint32_t *flags,
|
||||||
|
uint32_t *image_data_size,
|
||||||
|
void **pimage_data);
|
||||||
|
|
||||||
|
#endif
|
||||||
136
host_applications/linux/apps/hello_pi/libs/vgfont/vgfont.h
Normal file
136
host_applications/linux/apps/hello_pi/libs/vgfont/vgfont.h
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Font handling for graphicsx
|
||||||
|
|
||||||
|
#ifndef VCFTLIB_H
|
||||||
|
#define VCFTLIB_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "interface/vmcs_host/vc_dispservice_x_defs.h"
|
||||||
|
#include "interface/vctypes/vc_image_types.h"
|
||||||
|
#include "interface/vcos/vcos.h"
|
||||||
|
|
||||||
|
//Definitions which in certain functions can be used to mean the actual width and height of a resource, without
|
||||||
|
//having to know the data implicitly.
|
||||||
|
#define GRAPHICS_RESOURCE_WIDTH 0xFFFF
|
||||||
|
#define GRAPHICS_RESOURCE_HEIGHT 0xFFFF
|
||||||
|
|
||||||
|
#define R_888_MASK (0x00FF0000)
|
||||||
|
#define G_888_MASK (0x0000FF00)
|
||||||
|
#define B_888_MASK (0x000000FF)
|
||||||
|
#define ALPHA_888_MASK (0xFF000000)
|
||||||
|
#define GRAPHICS_RGBA32( r, g, b, a ) GRAPHICS_RGBA888( r, g, b, a )
|
||||||
|
#define GRAPHICS_RGBA888( r, g, b, a ) ( (((a) << (8+8+8)) & ALPHA_888_MASK) | (((b) << (8+8)) & R_888_MASK) | (((g) << 8) & G_888_MASK) | ((r) & B_888_MASK) )
|
||||||
|
#define GRAPHICS_TRANSPARENT_COLOUR 0x00000001UL
|
||||||
|
|
||||||
|
//resource defs
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GRAPHICS_RESOURCE_HANDLE_TYPE_MIN,
|
||||||
|
|
||||||
|
GRAPHICS_RESOURCE_RGB565,
|
||||||
|
GRAPHICS_RESOURCE_RGB888, /* 888 format is ONLY used when loading bitmaps
|
||||||
|
- you can't create or delete bitmaps with this format */
|
||||||
|
GRAPHICS_RESOURCE_RGBA32,
|
||||||
|
GRAPHICS_RESOURCE_TF_RGB32A,
|
||||||
|
GRAPHICS_RESOURCE_TF_RGB565,
|
||||||
|
GRAPHICS_RESOURCE_YUV420,
|
||||||
|
|
||||||
|
GRAPHICS_RESOURCE_HANDLE_TYPE_MAX
|
||||||
|
|
||||||
|
} GRAPHICS_RESOURCE_TYPE_T;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct GRAPHICS_RESOURCE_HANDLE_TABLE_T *GRAPHICS_RESOURCE_HANDLE;
|
||||||
|
|
||||||
|
VCOS_STATUS_T gx_graphics_init(const char *font_dir);
|
||||||
|
int32_t graphics_delete_resource( GRAPHICS_RESOURCE_HANDLE res );
|
||||||
|
VCOS_STATUS_T gx_create_window( uint32_t screen_id,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
GRAPHICS_RESOURCE_TYPE_T image_type,
|
||||||
|
GRAPHICS_RESOURCE_HANDLE *resource_handle );
|
||||||
|
|
||||||
|
int32_t graphics_display_resource( GRAPHICS_RESOURCE_HANDLE res,
|
||||||
|
const uint16_t screen_number,
|
||||||
|
const int16_t z_order,
|
||||||
|
const uint16_t offset_x,
|
||||||
|
const uint16_t offset_y,
|
||||||
|
const uint16_t dest_width,
|
||||||
|
const uint16_t dest_height,
|
||||||
|
const VC_DISPMAN_TRANSFORM_T transform,
|
||||||
|
const uint8_t display );
|
||||||
|
|
||||||
|
int32_t graphics_resource_fill(GRAPHICS_RESOURCE_HANDLE res,
|
||||||
|
uint32_t x,
|
||||||
|
uint32_t y,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t fill_colour );
|
||||||
|
|
||||||
|
int32_t graphics_update_displayed_resource(GRAPHICS_RESOURCE_HANDLE res,
|
||||||
|
const uint32_t x_offset,
|
||||||
|
const uint32_t y_offset,
|
||||||
|
const uint32_t width,
|
||||||
|
const uint32_t height );
|
||||||
|
|
||||||
|
int32_t graphics_resource_render_text_ext( GRAPHICS_RESOURCE_HANDLE res,
|
||||||
|
const int32_t x,
|
||||||
|
const int32_t y,
|
||||||
|
const uint32_t width,
|
||||||
|
const uint32_t height,
|
||||||
|
const uint32_t fg_colour,
|
||||||
|
const uint32_t bg_colour,
|
||||||
|
const char *text,
|
||||||
|
const uint32_t text_length,
|
||||||
|
const uint32_t text_size );
|
||||||
|
|
||||||
|
int32_t graphics_resource_text_dimensions_ext(GRAPHICS_RESOURCE_HANDLE res,
|
||||||
|
const char *text,
|
||||||
|
const uint32_t text_length,
|
||||||
|
uint32_t *width,
|
||||||
|
uint32_t *height,
|
||||||
|
const uint32_t text_size );
|
||||||
|
|
||||||
|
int32_t graphics_get_resource_size(
|
||||||
|
const GRAPHICS_RESOURCE_HANDLE res,
|
||||||
|
uint32_t *w,
|
||||||
|
uint32_t *h);
|
||||||
|
|
||||||
|
int32_t graphics_update_start(void);
|
||||||
|
|
||||||
|
int32_t graphics_update_end( void );
|
||||||
|
|
||||||
|
int32_t graphics_resource_text_dimensions( GRAPHICS_RESOURCE_HANDLE resource_handle,
|
||||||
|
const char *text,
|
||||||
|
const uint32_t text_length,
|
||||||
|
uint32_t *width,
|
||||||
|
uint32_t *height );
|
||||||
|
|
||||||
|
#endif
|
||||||
406
host_applications/linux/apps/hello_pi/libs/vgfont/vgft.c
Normal file
406
host_applications/linux/apps/hello_pi/libs/vgfont/vgft.c
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Font handling for graphicsx
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "graphics_x_private.h"
|
||||||
|
#include "vgft.h"
|
||||||
|
|
||||||
|
static FT_Library lib;
|
||||||
|
|
||||||
|
int vgft_init(void)
|
||||||
|
{
|
||||||
|
if (FT_Init_FreeType(&lib) == 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vgft_term(void)
|
||||||
|
{
|
||||||
|
FT_Done_FreeType(lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SEGMENTS_COUNT_MAX 256
|
||||||
|
#define COORDS_COUNT_MAX 1024
|
||||||
|
|
||||||
|
static VGuint segments_count;
|
||||||
|
static VGubyte segments[SEGMENTS_COUNT_MAX];
|
||||||
|
static VGuint coords_count;
|
||||||
|
static VGfloat coords[COORDS_COUNT_MAX];
|
||||||
|
|
||||||
|
static VGfloat float_from_26_6(FT_Pos x)
|
||||||
|
{
|
||||||
|
return (VGfloat)x / 64.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void convert_contour(const FT_Vector *points, const char *tags, short points_count)
|
||||||
|
{
|
||||||
|
int first_coords = coords_count;
|
||||||
|
|
||||||
|
int first = 1;
|
||||||
|
char last_tag = 0;
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
for (; points_count != 0; ++points, ++tags, --points_count) {
|
||||||
|
++c;
|
||||||
|
|
||||||
|
char tag = *tags;
|
||||||
|
if (first) {
|
||||||
|
assert(tag & 0x1);
|
||||||
|
assert(c==1); c=0;
|
||||||
|
segments[segments_count++] = VG_MOVE_TO;
|
||||||
|
first = 0;
|
||||||
|
} else if (tag & 0x1) {
|
||||||
|
/* on curve */
|
||||||
|
|
||||||
|
if (last_tag & 0x1) {
|
||||||
|
/* last point was also on -- line */
|
||||||
|
assert(c==1); c=0;
|
||||||
|
segments[segments_count++] = VG_LINE_TO;
|
||||||
|
} else {
|
||||||
|
/* last point was off -- quad or cubic */
|
||||||
|
if (last_tag & 0x2) {
|
||||||
|
/* cubic */
|
||||||
|
assert(c==3); c=0;
|
||||||
|
segments[segments_count++] = VG_CUBIC_TO;
|
||||||
|
} else {
|
||||||
|
/* quad */
|
||||||
|
assert(c==2); c=0;
|
||||||
|
segments[segments_count++] = VG_QUAD_TO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* off curve */
|
||||||
|
|
||||||
|
if (tag & 0x2) {
|
||||||
|
/* cubic */
|
||||||
|
|
||||||
|
assert((last_tag & 0x1) || (last_tag & 0x2)); /* last either on or off and cubic */
|
||||||
|
} else {
|
||||||
|
/* quad */
|
||||||
|
|
||||||
|
if (!(last_tag & 0x1)) {
|
||||||
|
/* last was also off curve */
|
||||||
|
|
||||||
|
assert(!(last_tag & 0x2)); /* must be quad */
|
||||||
|
|
||||||
|
/* add on point half-way between */
|
||||||
|
assert(c==2); c=1;
|
||||||
|
segments[segments_count++] = VG_QUAD_TO;
|
||||||
|
VGfloat x = (coords[coords_count - 2] + float_from_26_6(points->x)) * 0.5f;
|
||||||
|
VGfloat y = (coords[coords_count - 1] + float_from_26_6(points->y)) * 0.5f;
|
||||||
|
coords[coords_count++] = x;
|
||||||
|
coords[coords_count++] = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_tag = tag;
|
||||||
|
|
||||||
|
coords[coords_count++] = float_from_26_6(points->x);
|
||||||
|
coords[coords_count++] = float_from_26_6(points->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_tag & 0x1) {
|
||||||
|
/* last point was also on -- line (implicit with close path) */
|
||||||
|
assert(c==0);
|
||||||
|
} else {
|
||||||
|
++c;
|
||||||
|
|
||||||
|
/* last point was off -- quad or cubic */
|
||||||
|
if (last_tag & 0x2) {
|
||||||
|
/* cubic */
|
||||||
|
assert(c==3); c=0;
|
||||||
|
segments[segments_count++] = VG_CUBIC_TO;
|
||||||
|
} else {
|
||||||
|
/* quad */
|
||||||
|
assert(c==2); c=0;
|
||||||
|
segments[segments_count++] = VG_QUAD_TO;
|
||||||
|
}
|
||||||
|
|
||||||
|
coords[coords_count++] = coords[first_coords + 0];
|
||||||
|
coords[coords_count++] = coords[first_coords + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
segments[segments_count++] = VG_CLOSE_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void convert_outline(const FT_Vector *points, const char *tags, const short *contours, short contours_count, short points_count)
|
||||||
|
{
|
||||||
|
segments_count = 0;
|
||||||
|
coords_count = 0;
|
||||||
|
|
||||||
|
short last_contour = 0;
|
||||||
|
for (; contours_count != 0; ++contours, --contours_count) {
|
||||||
|
short contour = *contours + 1;
|
||||||
|
convert_contour(points + last_contour, tags + last_contour, contour - last_contour);
|
||||||
|
last_contour = contour;
|
||||||
|
}
|
||||||
|
assert(last_contour == points_count);
|
||||||
|
|
||||||
|
assert(segments_count <= SEGMENTS_COUNT_MAX); /* oops... we overwrote some memory */
|
||||||
|
assert(coords_count <= COORDS_COUNT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
VCOS_STATUS_T vgft_font_init(VGFT_FONT_T *font)
|
||||||
|
{
|
||||||
|
font->ft_face = NULL;
|
||||||
|
font->vg_font = vgCreateFont(0);
|
||||||
|
if (font->vg_font == VG_INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
return VCOS_ENOMEM;
|
||||||
|
}
|
||||||
|
return VCOS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VCOS_STATUS_T vgft_font_load_mem(VGFT_FONT_T *font, void *mem, size_t len)
|
||||||
|
{
|
||||||
|
if (FT_New_Memory_Face(lib, mem, len, 0, &font->ft_face))
|
||||||
|
{
|
||||||
|
return VCOS_EINVAL;
|
||||||
|
}
|
||||||
|
return VCOS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VCOS_STATUS_T vgft_font_load_file(VGFT_FONT_T *font, const char *file)
|
||||||
|
{
|
||||||
|
if (FT_New_Face(lib, file, 0, &font->ft_face)) {
|
||||||
|
return VCOS_EINVAL;
|
||||||
|
}
|
||||||
|
return VCOS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VCOS_STATUS_T vgft_font_convert_glyphs(VGFT_FONT_T *font, unsigned int char_height, unsigned int dpi_x, unsigned int dpi_y)
|
||||||
|
{
|
||||||
|
FT_UInt glyph_index;
|
||||||
|
FT_ULong ch;
|
||||||
|
|
||||||
|
if (FT_Set_Char_Size(font->ft_face, 0, char_height, dpi_x, dpi_y))
|
||||||
|
{
|
||||||
|
FT_Done_Face(font->ft_face);
|
||||||
|
vgDestroyFont(font->vg_font);
|
||||||
|
return VCOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = FT_Get_First_Char(font->ft_face, &glyph_index);
|
||||||
|
|
||||||
|
while (ch != 0)
|
||||||
|
{
|
||||||
|
if (FT_Load_Glyph(font->ft_face, glyph_index, FT_LOAD_DEFAULT)) {
|
||||||
|
FT_Done_Face(font->ft_face);
|
||||||
|
vgDestroyFont(font->vg_font);
|
||||||
|
return VCOS_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
VGPath vg_path;
|
||||||
|
FT_Outline *outline = &font->ft_face->glyph->outline;
|
||||||
|
if (outline->n_contours != 0) {
|
||||||
|
vg_path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_ALL);
|
||||||
|
assert(vg_path != VG_INVALID_HANDLE);
|
||||||
|
|
||||||
|
convert_outline(outline->points, outline->tags, outline->contours, outline->n_contours, outline->n_points);
|
||||||
|
vgAppendPathData(vg_path, segments_count, segments, coords);
|
||||||
|
} else {
|
||||||
|
vg_path = VG_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VGfloat origin[] = { 0.0f, 0.0f };
|
||||||
|
VGfloat escapement[] = { float_from_26_6(font->ft_face->glyph->advance.x), float_from_26_6(font->ft_face->glyph->advance.y) };
|
||||||
|
vgSetGlyphToPath(font->vg_font, glyph_index, vg_path, VG_FALSE, origin, escapement);
|
||||||
|
|
||||||
|
if (vg_path != VG_INVALID_HANDLE) {
|
||||||
|
vgDestroyPath(vg_path);
|
||||||
|
}
|
||||||
|
ch = FT_Get_Next_Char(font->ft_face, ch, &glyph_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return VCOS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vgft_font_term(VGFT_FONT_T *font)
|
||||||
|
{
|
||||||
|
if (font->ft_face)
|
||||||
|
FT_Done_Face(font->ft_face);
|
||||||
|
if (font->vg_font)
|
||||||
|
vgDestroyFont(font->vg_font);
|
||||||
|
memset(font, 0, sizeof(*font));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define CHAR_COUNT_MAX 200
|
||||||
|
static VGuint glyph_indices[CHAR_COUNT_MAX];
|
||||||
|
static VGfloat adjustments_x[CHAR_COUNT_MAX];
|
||||||
|
static VGfloat adjustments_y[CHAR_COUNT_MAX];
|
||||||
|
|
||||||
|
// Draws the first char_count characters from text, with adjustments, starting
|
||||||
|
// from the current origin. The peek argument indicates whether to peek ahead
|
||||||
|
// and get a final adjustment based on the next character past char_count, or
|
||||||
|
// else just assume that this is the end of the text and add no final
|
||||||
|
// adjustment.
|
||||||
|
|
||||||
|
static void draw_chars(VGFT_FONT_T *font, const char *text, int char_count, VGbitfield paint_modes, int peek) {
|
||||||
|
// Put in first character
|
||||||
|
glyph_indices[0] = FT_Get_Char_Index(font->ft_face, text[0]);
|
||||||
|
int prev_glyph_index = glyph_indices[0];
|
||||||
|
|
||||||
|
// Calculate glyph_indices and adjustments
|
||||||
|
int i;
|
||||||
|
FT_Vector kern;
|
||||||
|
for (i = 1; i != char_count; ++i) {
|
||||||
|
int glyph_index = FT_Get_Char_Index(font->ft_face, text[i]);
|
||||||
|
if (!glyph_index) { return; }
|
||||||
|
glyph_indices[i] = glyph_index;
|
||||||
|
|
||||||
|
if (FT_Get_Kerning(font->ft_face, prev_glyph_index, glyph_index, FT_KERNING_DEFAULT, &kern)) assert(0);
|
||||||
|
adjustments_x[i - 1] = float_from_26_6(kern.x);
|
||||||
|
adjustments_y[i - 1] = float_from_26_6(kern.y);
|
||||||
|
|
||||||
|
prev_glyph_index = glyph_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the last adjustment?
|
||||||
|
if (peek) {
|
||||||
|
int peek_glyph_index = FT_Get_Char_Index(font->ft_face, text[i]);
|
||||||
|
if (!peek_glyph_index) { return; }
|
||||||
|
if (FT_Get_Kerning(font->ft_face, prev_glyph_index, peek_glyph_index, FT_KERNING_DEFAULT, &kern)) assert(0);
|
||||||
|
adjustments_x[char_count - 1] = float_from_26_6(kern.x);
|
||||||
|
adjustments_y[char_count - 1] = float_from_26_6(kern.y);
|
||||||
|
} else {
|
||||||
|
adjustments_x[char_count - 1] = 0.0f;
|
||||||
|
adjustments_y[char_count - 1] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
vgDrawGlyphs(font->vg_font, char_count, glyph_indices, adjustments_x, adjustments_y, paint_modes, VG_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Goes to the x,y position and draws arbitrary number of characters, draws
|
||||||
|
// iteratively if the char_count exceeds the max buffer size given above.
|
||||||
|
|
||||||
|
static void draw_line(VGFT_FONT_T *font, VGfloat x, VGfloat y, const char *text, int char_count, VGbitfield paint_modes) {
|
||||||
|
if (char_count == 0) return;
|
||||||
|
|
||||||
|
// Set origin to requested x,y
|
||||||
|
VGfloat glor[] = { x, y };
|
||||||
|
vgSetfv(VG_GLYPH_ORIGIN, 2, glor);
|
||||||
|
|
||||||
|
// Draw the characters in blocks to reuse buffer memory
|
||||||
|
const char *curr_text = text;
|
||||||
|
int chars_left = char_count;
|
||||||
|
while (chars_left > CHAR_COUNT_MAX) {
|
||||||
|
draw_chars(font, curr_text, CHAR_COUNT_MAX, paint_modes, 1);
|
||||||
|
chars_left -= CHAR_COUNT_MAX;
|
||||||
|
curr_text += CHAR_COUNT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the last block
|
||||||
|
draw_chars(font, curr_text, chars_left, paint_modes, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vgft_font_draw(VGFT_FONT_T *font, VGfloat x, VGfloat y, const char *text, unsigned text_length, VGbitfield paint_modes)
|
||||||
|
{
|
||||||
|
VGfloat descent = float_from_26_6(font->ft_face->size->metrics.descender);
|
||||||
|
int last_draw = 0;
|
||||||
|
int i = 0;
|
||||||
|
y -= descent;
|
||||||
|
for (;;) {
|
||||||
|
int last = !text[i] || (text_length && i==text_length);
|
||||||
|
|
||||||
|
if ((text[i] == '\n') || last)
|
||||||
|
{
|
||||||
|
draw_line(font, x, y, text + last_draw, i - last_draw, paint_modes);
|
||||||
|
last_draw = i+1;
|
||||||
|
y -= float_from_26_6(font->ft_face->size->metrics.height);
|
||||||
|
}
|
||||||
|
if (last)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get text extents for a single line
|
||||||
|
|
||||||
|
static void line_extents(VGFT_FONT_T *font, VGfloat *x, VGfloat *y, const char *text, int chars_count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int prev_glyph_index = 0;
|
||||||
|
if (chars_count == 0) return;
|
||||||
|
|
||||||
|
for (i=0; i < chars_count; i++)
|
||||||
|
{
|
||||||
|
int glyph_index = FT_Get_Char_Index(font->ft_face, text[i]);
|
||||||
|
if (!glyph_index) return;
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
FT_Vector kern;
|
||||||
|
if (FT_Get_Kerning(font->ft_face, prev_glyph_index, glyph_index,
|
||||||
|
FT_KERNING_DEFAULT, &kern))
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
*x += float_from_26_6(kern.x);
|
||||||
|
*y += float_from_26_6(kern.y);
|
||||||
|
}
|
||||||
|
FT_Load_Glyph(font->ft_face, glyph_index, FT_LOAD_DEFAULT);
|
||||||
|
*x += float_from_26_6(font->ft_face->glyph->advance.x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text extents for some ASCII text.
|
||||||
|
//
|
||||||
|
// Use text_length if non-zero, otherwise look for trailing '\0'.
|
||||||
|
|
||||||
|
void vgft_get_text_extents(VGFT_FONT_T *font,
|
||||||
|
const char *text,
|
||||||
|
unsigned text_length,
|
||||||
|
VGfloat start_x, VGfloat start_y,
|
||||||
|
VGfloat *w, VGfloat *h) {
|
||||||
|
int last_draw = 0;
|
||||||
|
VGfloat max_x = start_x;
|
||||||
|
VGfloat y = start_y;
|
||||||
|
|
||||||
|
int i, last;
|
||||||
|
for (i = 0, last = 0; !last; ++i) {
|
||||||
|
last = !text[i] || (text_length && i==text_length);
|
||||||
|
if ((text[i] == '\n') || last) {
|
||||||
|
VGfloat x = 0;
|
||||||
|
line_extents(font, &x, &y, text + last_draw, i - last_draw);
|
||||||
|
last_draw = i+1;
|
||||||
|
y -= float_from_26_6(font->ft_face->size->metrics.height);
|
||||||
|
if (x > max_x) max_x = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*w = max_x - start_x;
|
||||||
|
*h = start_y - y;
|
||||||
|
}
|
||||||
68
host_applications/linux/apps/hello_pi/libs/vgfont/vgft.h
Normal file
68
host_applications/linux/apps/hello_pi/libs/vgfont/vgft.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Font handling for graphicsx
|
||||||
|
|
||||||
|
#ifndef VGFT_H
|
||||||
|
#define VGFT_H
|
||||||
|
|
||||||
|
#include "interface/vcos/vcos.h"
|
||||||
|
#include <VG/openvg.h>
|
||||||
|
#include <ft2build.h>
|
||||||
|
|
||||||
|
typedef int VGFT_BOOL;
|
||||||
|
#define VGFT_FALSE 0
|
||||||
|
#define VGFT_TRUE (!VGFT_FALSE)
|
||||||
|
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
/* Returns 0 on success */
|
||||||
|
extern int vgft_init(void);
|
||||||
|
extern void vgft_term(void);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
VGFont vg_font;
|
||||||
|
FT_Face ft_face;
|
||||||
|
} VGFT_FONT_T;
|
||||||
|
|
||||||
|
/** Initialise a FT->VG font */
|
||||||
|
VCOS_STATUS_T vgft_font_init(VGFT_FONT_T *font);
|
||||||
|
|
||||||
|
/** Load a font file from memory */
|
||||||
|
VCOS_STATUS_T vgft_font_load_mem(VGFT_FONT_T *font, void *mem, size_t len);
|
||||||
|
|
||||||
|
/** Convert a font into VG glyphs */
|
||||||
|
VCOS_STATUS_T vgft_font_convert_glyphs(VGFT_FONT_T *font, unsigned int char_height, unsigned int dpi_x, unsigned int dpi_y);
|
||||||
|
|
||||||
|
/** Release a font. */
|
||||||
|
void vgft_font_term(VGFT_FONT_T *font);
|
||||||
|
|
||||||
|
void vgft_font_draw(VGFT_FONT_T *font, VGfloat x, VGfloat y, const char *text, unsigned text_length, VGbitfield paint_modes);
|
||||||
|
|
||||||
|
void vgft_get_text_extents(VGFT_FONT_T *font, const char *text, unsigned text_length, VGfloat start_x, VGfloat start_y, VGfloat *w, VGfloat *h);
|
||||||
|
|
||||||
|
#endif
|
||||||
26
host_applications/linux/apps/hello_pi/rebuild.sh
Executable file
26
host_applications/linux/apps/hello_pi/rebuild.sh
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
make -C libs/ilclient clean
|
||||||
|
make -C libs/vgfont clean
|
||||||
|
make -C hello_world clean
|
||||||
|
make -C hello_triangle clean
|
||||||
|
make -C hello_triangle2 clean
|
||||||
|
make -C hello_video clean
|
||||||
|
make -C hello_audio clean
|
||||||
|
make -C hello_font clean
|
||||||
|
make -C hello_dispmanx clean
|
||||||
|
make -C hello_tiger clean
|
||||||
|
make -C hello_encode clean
|
||||||
|
make -C hello_jpeg clean
|
||||||
|
|
||||||
|
make -C libs/ilclient
|
||||||
|
make -C libs/vgfont
|
||||||
|
make -C hello_world
|
||||||
|
make -C hello_triangle
|
||||||
|
make -C hello_triangle2
|
||||||
|
make -C hello_video
|
||||||
|
make -C hello_audio
|
||||||
|
make -C hello_font
|
||||||
|
make -C hello_dispmanx
|
||||||
|
make -C hello_tiger
|
||||||
|
make -C hello_encode
|
||||||
|
make -C hello_jpeg
|
||||||
|
|
||||||
26
host_applications/linux/libs/bcm_host/bcm_host.h
Normal file
26
host_applications/linux/libs/bcm_host/bcm_host.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
@@ -6,7 +6,7 @@ add_library(vchiq_arm SHARED
|
|||||||
target_link_libraries(vchiq_arm)
|
target_link_libraries(vchiq_arm)
|
||||||
|
|
||||||
install(TARGETS vchiq_arm DESTINATION lib)
|
install(TARGETS vchiq_arm DESTINATION lib)
|
||||||
install(FILES etc/10-vchiq.rules DESTINATION /etc/udev/rules.d)
|
#install(FILES etc/10-vchiq.rules DESTINATION /etc/udev/rules.d)
|
||||||
|
|
||||||
include_directories(../..)
|
include_directories(../..)
|
||||||
|
|
||||||
|
|||||||
@@ -65,4 +65,4 @@ if (WIN32)
|
|||||||
configure_file (build_all.bat.in build_all.bat @ONLY)
|
configure_file (build_all.bat.in build_all.bat @ONLY)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
install (FILES ${HEADERS} DESTINATION include/interface/vcos)
|
#install (FILES ${HEADERS} DESTINATION include/interface/vcos)
|
||||||
|
|||||||
@@ -42,5 +42,5 @@ else ()
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
install(FILES ${HEADERS} DESTINATION include)
|
#install(FILES ${HEADERS} DESTINATION include)
|
||||||
install(TARGETS vcos DESTINATION lib)
|
install(TARGETS vcos DESTINATION lib)
|
||||||
|
|||||||
26
interface/vcos/pthreads/vchost_config.h
Normal file
26
interface/vcos/pthreads/vchost_config.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
@@ -50,6 +50,7 @@ typedef enum
|
|||||||
DISPLAY_3D_INTERLEAVED, // For autosteroscopic displays
|
DISPLAY_3D_INTERLEAVED, // For autosteroscopic displays
|
||||||
DISPLAY_3D_SBS_FULL_AUTO, // Side-By-Side, Full Width (also used by some autostereoscopic displays)
|
DISPLAY_3D_SBS_FULL_AUTO, // Side-By-Side, Full Width (also used by some autostereoscopic displays)
|
||||||
DISPLAY_3D_SBS_HALF_HORIZ, // Side-By-Side, Half Width, Horizontal Subsampling (see HDMI spec)
|
DISPLAY_3D_SBS_HALF_HORIZ, // Side-By-Side, Half Width, Horizontal Subsampling (see HDMI spec)
|
||||||
|
DISPLAY_3D_TB_HALF, // Top-bottom 3D
|
||||||
DISPLAY_3D_FORMAT_MAX
|
DISPLAY_3D_FORMAT_MAX
|
||||||
} DISPLAY_3D_FORMAT_T;
|
} DISPLAY_3D_FORMAT_T;
|
||||||
|
|
||||||
@@ -94,6 +95,12 @@ typedef struct
|
|||||||
uint32_t line_rate;
|
uint32_t line_rate;
|
||||||
// Format required for image data for 3D displays
|
// Format required for image data for 3D displays
|
||||||
DISPLAY_3D_FORMAT_T format_3d;
|
DISPLAY_3D_FORMAT_T format_3d;
|
||||||
|
// If display requires PV1 (e.g. DSI1), special config is required in HVS
|
||||||
|
uint32_t use_pixelvalve_1;
|
||||||
|
// Set for DSI displays which use video mode.
|
||||||
|
uint32_t dsi_video_mode;
|
||||||
|
// Select HVS channel (usually 0).
|
||||||
|
uint32_t hvs_channel;
|
||||||
} DISPLAY_INFO_T;
|
} DISPLAY_INFO_T;
|
||||||
|
|
||||||
#endif /* __VC_INCLUDE_IMAGE_TYPES_H__ */
|
#endif /* __VC_INCLUDE_IMAGE_TYPES_H__ */
|
||||||
|
|||||||
250
interface/vmcs_host/vc_dispservice_defs.h
Normal file
250
interface/vmcs_host/vc_dispservice_defs.h
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VC_DISPSERVICE_DEFS_H
|
||||||
|
#define VC_DISPSERVICE_DEFS_H
|
||||||
|
|
||||||
|
#define HOST_PITCH_ALIGNMENT 4
|
||||||
|
|
||||||
|
//Round up to the nearest multiple of 16
|
||||||
|
#define PAD16(x) (((x) + (VC_INTERFACE_BLOCK_SIZE-1)) & ~(VC_INTERFACE_BLOCK_SIZE-1))
|
||||||
|
|
||||||
|
//The max length for an effect name
|
||||||
|
#define DISPMAN_MAX_EFFECT_NAME (28)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// Values initially chosen to match VC_IMAGE_TYPE_T to aid debugging
|
||||||
|
// This is now a mandatory constraint
|
||||||
|
VC_FORMAT_RGB565 = 1,
|
||||||
|
VC_FORMAT_YUV420 = 3,
|
||||||
|
VC_FORMAT_RGB888 = 5,
|
||||||
|
VC_FORMAT_RGBA32 = 15,
|
||||||
|
VC_FORMAT_RGBA565 = 17,
|
||||||
|
VC_FORMAT_RGBA16 = 18,
|
||||||
|
VC_FORMAT_TF_RGBA32 = 20,
|
||||||
|
VC_FORMAT_TF_RGBA16 = 23,
|
||||||
|
VC_FORMAT_TF_RGB565 = 25,
|
||||||
|
VC_FORMAT_BGR888 = 31,
|
||||||
|
VC_FORMAT_BGR888_NP = 32,
|
||||||
|
|
||||||
|
VC_FORMAT_ARGB8888 = 43,
|
||||||
|
VC_FORMAT_XRGB8888 = 44,
|
||||||
|
|
||||||
|
/* To force 32-bit storage, enabling use in structures over-the-wire */
|
||||||
|
VC_FORMAT_RANGE_MAX = 0x7FFFFFFF
|
||||||
|
} VC_IMAGE_FORMAT_T;
|
||||||
|
|
||||||
|
// Transforms.
|
||||||
|
/* Image transformations. These must match the DISPMAN and Media Player versions */
|
||||||
|
#define TRANSFORM_HFLIP (1<<0)
|
||||||
|
#define TRANSFORM_VFLIP (1<<1)
|
||||||
|
#define TRANSFORM_TRANSPOSE (1<<2)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VC_DISPMAN_ROT0 = 0,
|
||||||
|
VC_DISPMAN_MIRROR_ROT0 = TRANSFORM_HFLIP,
|
||||||
|
VC_DISPMAN_MIRROR_ROT180 = TRANSFORM_VFLIP,
|
||||||
|
VC_DISPMAN_ROT180 = TRANSFORM_HFLIP|TRANSFORM_VFLIP,
|
||||||
|
VC_DISPMAN_MIRROR_ROT90 = TRANSFORM_TRANSPOSE,
|
||||||
|
VC_DISPMAN_ROT270 = TRANSFORM_TRANSPOSE|TRANSFORM_HFLIP,
|
||||||
|
VC_DISPMAN_ROT90 = TRANSFORM_TRANSPOSE|TRANSFORM_VFLIP,
|
||||||
|
VC_DISPMAN_MIRROR_ROT270 = TRANSFORM_TRANSPOSE|TRANSFORM_HFLIP|TRANSFORM_VFLIP,
|
||||||
|
} VC_DISPMAN_TRANSFORM_T;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VC_RESOURCE_TYPE_HOST,
|
||||||
|
VC_RESOURCE_TYPE_VIDEOCORE,
|
||||||
|
VC_RESOURCE_TYPE_VIDEOCORE_UNCACHED,
|
||||||
|
} VC_RESOURCE_TYPE_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t type; // VC_IMAGE_FORMAT_T
|
||||||
|
uint32_t width; // width in pixels
|
||||||
|
uint32_t height; // height in pixels
|
||||||
|
uint32_t pitch; // pitch of image_data array in *bytes*
|
||||||
|
uint32_t size; // number of *bytes* available in the image_data arry
|
||||||
|
uint32_t pointer; // pointer for image_data - this allows the object to be cast to a VC_IMAGE_T on the VIDEOCORE side
|
||||||
|
} VC_IMAGE_PARAM_T;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VC_DISPMAN_DISPLAY_SET_DESTINATION = 0,
|
||||||
|
VC_DISPMAN_DISPLAY_UPDATE_START,
|
||||||
|
VC_DISPMAN_DISPLAY_UPDATE_END,
|
||||||
|
VC_DISPMAN_DISPLAY_OBJECT_ADD,
|
||||||
|
VC_DISPMAN_DISPLAY_OBJECT_REMOVE,
|
||||||
|
VC_DISPMAN_DISPLAY_OBJECT_MODIFY,
|
||||||
|
VC_DISPMAN_DISPLAY_LOCK,
|
||||||
|
VC_DISPMAN_DISPLAY_UNLOCK,
|
||||||
|
VC_DISPMAN_DISPLAY_RESOURCE_CREATE,
|
||||||
|
VC_DISPMAN_DISPLAY_RESOURCE_DELETE,
|
||||||
|
VC_DISPMAN_DISPLAY_GET_COMPOSITE,
|
||||||
|
VC_DISPMAN_DISPLAY_APPLY_EFFECT_INSTANCE,
|
||||||
|
VC_DISPMAN_DISPLAY_RECONFIGURE,
|
||||||
|
VC_DISPMAN_DISPLAY_CREATE_EFFECTS_INSTANCE,
|
||||||
|
VC_DISPMAN_DISPLAY_DELETE_EFFECTS_INSTANCE,
|
||||||
|
VC_DISPMAN_DISPLAY_SET_EFFECT,
|
||||||
|
VC_DISPMAN_DISPLAY_RESOURCE_SET_ALPHA,
|
||||||
|
VC_DISPMAN_DISPLAY_SNAPSHOT,
|
||||||
|
VC_DISPMAN_DISPLAY_QUERY_IMAGE_FORMATS,
|
||||||
|
VC_DISPMAN_DISPLAY_GET_DISPLAY_DETAILS,
|
||||||
|
// new features - add to end of list
|
||||||
|
VC_DISPMAN_DISPLAY_RESOURCE_CREATE_FROM_IMAGE,
|
||||||
|
VC_CMD_END_OF_LIST
|
||||||
|
} VC_CMD_CODE_T;
|
||||||
|
|
||||||
|
/* The table of functions executed for each command. */
|
||||||
|
|
||||||
|
typedef void (*INTERFACE_EXECUTE_FN_T)(int, int);
|
||||||
|
|
||||||
|
extern INTERFACE_EXECUTE_FN_T interface_execute_fn[];
|
||||||
|
|
||||||
|
//Parameter sets for dispservice commands
|
||||||
|
typedef struct {
|
||||||
|
uint32_t state;
|
||||||
|
uint32_t dummy[3]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_LOCK_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t display;
|
||||||
|
uint32_t dummy[3]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_GET_DISPLAY_DETAILS_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t display;
|
||||||
|
uint32_t resource;
|
||||||
|
uint32_t dummy[2]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_SET_DEST_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t display;
|
||||||
|
uint32_t dummy[3]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_GET_COMPOSITE_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t display;
|
||||||
|
uint32_t effects_instance;
|
||||||
|
|
||||||
|
uint32_t dummy[2]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_APPLY_EFFECTS_INSTANCE_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t read_response;
|
||||||
|
uint32_t effects_instance;
|
||||||
|
} DISPMAN_CREATE_EFFECTS_INSTANCE_RESPONSE_T;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t effects_instance;
|
||||||
|
uint32_t dummy[3]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_DELETE_EFFECTS_INSTANCE_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t effects_instance;
|
||||||
|
char effect_name[ DISPMAN_MAX_EFFECT_NAME ];
|
||||||
|
//no need to pad as long as DISPMAN_MAX_EFFECT_NAME +sizeof(uint32) = 32
|
||||||
|
} DISPMAN_SET_EFFECT_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t display;
|
||||||
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
uint32_t dummy[2]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_RECONFIGURE_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t display;
|
||||||
|
uint32_t transparent_colour;
|
||||||
|
uint32_t dummy[2]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_SET_TRANSPARENT_COLOUR_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
//uint32_t object;
|
||||||
|
uint32_t display;
|
||||||
|
int32_t layer;
|
||||||
|
uint32_t transform;
|
||||||
|
uint32_t resource;
|
||||||
|
uint16_t dest_x;
|
||||||
|
uint16_t dest_y;
|
||||||
|
uint16_t dest_width;
|
||||||
|
uint16_t dest_height;
|
||||||
|
uint16_t src_x;
|
||||||
|
uint16_t src_y;
|
||||||
|
uint16_t src_width;
|
||||||
|
uint16_t src_height;
|
||||||
|
} DISPMAN_OBJECT_ADD_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t object;
|
||||||
|
uint32_t dummy[3]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_OBJECT_REMOVE_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t object;
|
||||||
|
uint16_t src_x;
|
||||||
|
uint16_t src_y;
|
||||||
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
uint32_t dummy[1]; // Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_OBJECT_MODIFY_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t *resource;
|
||||||
|
VC_IMAGE_PARAM_T image;
|
||||||
|
uint8_t type; // VC_RESOURCE_TYPE_T
|
||||||
|
//Removed padding. VC_IMAGE_T may change in size, so handle the size in the code that sends and receives the commands
|
||||||
|
//uint32_t dummy[3]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_RESOURCE_CREATE_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t native_image_ptr;
|
||||||
|
uint32_t type; // VC_RESOURCE_TYPE_T
|
||||||
|
uint32_t dummy[2]; // Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_RESOURCE_CREATE_FROM_IMAGE_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t resource;
|
||||||
|
uint32_t dummy[3]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_RESOURCE_DELETE_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t resource;
|
||||||
|
uint32_t alpha;
|
||||||
|
uint32_t dummy[2]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_RESOURCE_SET_ALPHA_PARAM_T;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t display;
|
||||||
|
uint32_t resource;
|
||||||
|
uint32_t dummy[2]; //Pad to multiple of 16 bytes
|
||||||
|
} DISPMAN_DISPLAY_SNAPSHOT_PARAM_T;
|
||||||
|
|
||||||
|
#endif //VC_DISPSERVICE_DEFS_H
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2012, Broadcom Europe Ltd
|
Copyright (c) 2012 Broadcom Europe Ltd
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2012, Broadcom Europe Ltd
|
Copyright (c) 2012 Broadcom Europe Ltd
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -13,16 +13,16 @@ modification, are permitted provided that the following conditions are met:
|
|||||||
names of its contributors may be used to endorse or promote products
|
names of its contributors may be used to endorse or promote products
|
||||||
derived from this software without specific prior written permission.
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
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
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
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
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2012, Broadcom Europe Ltd
|
* Copyright (c) 2012 Broadcom Europe Ltd
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
* Redistributions of source code must retain the above copyright
|
* Redistributions of source code must retain the above copyright
|
||||||
|
|||||||
152
interface/vmcs_host/vc_vchi_audioserv_defs.h
Normal file
152
interface/vmcs_host/vc_vchi_audioserv_defs.h
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VC_AUDIO_DEFS_H_
|
||||||
|
#define _VC_AUDIO_DEFS_H_
|
||||||
|
|
||||||
|
// FourCC code used for VCHI connection
|
||||||
|
#define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS")
|
||||||
|
|
||||||
|
// Maximum message length
|
||||||
|
#define VC_AUDIO_MAX_MSG_LEN (sizeof( VC_AUDIO_MSG_T ))
|
||||||
|
|
||||||
|
// List of screens that are currently supported
|
||||||
|
// All message types supported for HOST->VC direction
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
VC_AUDIO_MSG_TYPE_RESULT, // Generic result
|
||||||
|
VC_AUDIO_MSG_TYPE_COMPLETE, // playback of samples complete
|
||||||
|
VC_AUDIO_MSG_TYPE_CONFIG, // Configure
|
||||||
|
VC_AUDIO_MSG_TYPE_CONTROL, // control
|
||||||
|
VC_AUDIO_MSG_TYPE_OPEN, // open
|
||||||
|
VC_AUDIO_MSG_TYPE_CLOSE, // close/shutdown
|
||||||
|
VC_AUDIO_MSG_TYPE_START, // start output (i.e. resume)
|
||||||
|
VC_AUDIO_MSG_TYPE_STOP, // stop output (i.e. pause)
|
||||||
|
VC_AUDIO_MSG_TYPE_WRITE, // write samples
|
||||||
|
VC_AUDIO_MSG_TYPE_MAX
|
||||||
|
|
||||||
|
} VC_AUDIO_MSG_TYPE;
|
||||||
|
|
||||||
|
static const char *vc_audio_msg_type_names[] = {
|
||||||
|
"VC_AUDIO_MSG_TYPE_RESULT",
|
||||||
|
"VC_AUDIO_MSG_TYPE_COMPLETE",
|
||||||
|
"VC_AUDIO_MSG_TYPE_CONFIG",
|
||||||
|
"VC_AUDIO_MSG_TYPE_CONTROL",
|
||||||
|
"VC_AUDIO_MSG_TYPE_OPEN",
|
||||||
|
"VC_AUDIO_MSG_TYPE_CLOSE",
|
||||||
|
"VC_AUDIO_MSG_TYPE_START",
|
||||||
|
"VC_AUDIO_MSG_TYPE_STOP",
|
||||||
|
"VC_AUDIO_MSG_TYPE_WRITE",
|
||||||
|
"VC_AUDIO_MSG_TYPE_MAX"
|
||||||
|
};
|
||||||
|
|
||||||
|
// configure the audio
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t channels;
|
||||||
|
uint32_t samplerate;
|
||||||
|
uint32_t bps;
|
||||||
|
|
||||||
|
} VC_AUDIO_CONFIG_T;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t volume;
|
||||||
|
uint32_t dest;
|
||||||
|
|
||||||
|
} VC_AUDIO_CONTROL_T;
|
||||||
|
|
||||||
|
// audio
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t dummy;
|
||||||
|
|
||||||
|
} VC_AUDIO_OPEN_T;
|
||||||
|
|
||||||
|
// audio
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t dummy;
|
||||||
|
|
||||||
|
} VC_AUDIO_CLOSE_T;
|
||||||
|
// audio
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t dummy;
|
||||||
|
|
||||||
|
} VC_AUDIO_START_T;
|
||||||
|
// audio
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t draining;
|
||||||
|
|
||||||
|
} VC_AUDIO_STOP_T;
|
||||||
|
|
||||||
|
// configure the write audio samples
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t count; // in bytes
|
||||||
|
void *callback;
|
||||||
|
void *cookie;
|
||||||
|
uint32_t silence;
|
||||||
|
} VC_AUDIO_WRITE_T;
|
||||||
|
|
||||||
|
// Generic result for a request (VC->HOST)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int32_t success; // Success value
|
||||||
|
|
||||||
|
} VC_AUDIO_RESULT_T;
|
||||||
|
|
||||||
|
// Generic result for a request (VC->HOST)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int32_t count; // Success value
|
||||||
|
void *callback;
|
||||||
|
void *cookie;
|
||||||
|
} VC_AUDIO_COMPLETE_T;
|
||||||
|
|
||||||
|
// Message header for all messages in HOST->VC direction
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int32_t type; // Message type (VC_AUDIO_MSG_TYPE)
|
||||||
|
union
|
||||||
|
{
|
||||||
|
VC_AUDIO_CONFIG_T config;
|
||||||
|
VC_AUDIO_CONTROL_T control;
|
||||||
|
VC_AUDIO_OPEN_T open;
|
||||||
|
VC_AUDIO_CLOSE_T close;
|
||||||
|
VC_AUDIO_START_T start;
|
||||||
|
VC_AUDIO_STOP_T stop;
|
||||||
|
VC_AUDIO_WRITE_T write;
|
||||||
|
VC_AUDIO_RESULT_T result;
|
||||||
|
VC_AUDIO_COMPLETE_T complete;
|
||||||
|
} u;
|
||||||
|
} VC_AUDIO_MSG_T;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _VC_AUDIO_DEFS_H_
|
||||||
166
interface/vmcs_host/vcfilesys.h
Normal file
166
interface/vmcs_host/vcfilesys.h
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vchost_config.h"
|
||||||
|
#include "vcfilesys_defs.h"
|
||||||
|
#include "vc_fileservice_defs.h"
|
||||||
|
|
||||||
|
#ifndef VCFILESYS_H_
|
||||||
|
#define VCFILESYS_H_
|
||||||
|
|
||||||
|
#ifndef FILESYS_DIR_DEFINED
|
||||||
|
#define FILESYS_DIR_DEFINED
|
||||||
|
typedef struct DIR_tag DIR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initialises the file system for use
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_init (void);
|
||||||
|
|
||||||
|
// Stop it to prevent the functions from trying to use it.
|
||||||
|
VCHPRE_ void VCHPOST_ vc_filesys_stop(void);
|
||||||
|
|
||||||
|
// Return the service number (-1 if not running).
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_inum(void);
|
||||||
|
|
||||||
|
// Low level file system functions equivalent to close(), lseek(), open(), read() and write()
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_close(int fildes);
|
||||||
|
|
||||||
|
VCHPRE_ long VCHPOST_ vc_filesys_lseek(int fildes, long offset, int whence);
|
||||||
|
|
||||||
|
VCHPRE_ int64_t VCHPOST_ vc_filesys_lseek64(int fildes, int64_t offset, int whence);
|
||||||
|
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_open(const char *path, int vc_oflag);
|
||||||
|
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_read(int fildes, void *buf, unsigned int nbyte);
|
||||||
|
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_write(int fildes, const void *buf, unsigned int nbyte);
|
||||||
|
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_mount(const char *device, const char *mountpoint, const char *options);
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_umount(const char *mountpoint);
|
||||||
|
|
||||||
|
|
||||||
|
// Ends a directory listing iteration
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_closedir(void *dhandle);
|
||||||
|
|
||||||
|
// Formats the drive that contains the given path
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_format(const char *path);
|
||||||
|
|
||||||
|
// Returns the amount of free space on the drive that contains the given path
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_freespace(const char *path);
|
||||||
|
VCHPRE_ int64_t VCHPOST_ vc_filesys_freespace64(const char *path);
|
||||||
|
|
||||||
|
// Gets the attributes of the named file
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_get_attr(const char *path, fattributes_t *attr);
|
||||||
|
|
||||||
|
// Creates a new directory
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_mkdir(const char *path);
|
||||||
|
|
||||||
|
// Starts a directory listing iteration
|
||||||
|
VCHPRE_ void * VCHPOST_ vc_filesys_opendir(const char *dirname);
|
||||||
|
|
||||||
|
// Directory listing iterator
|
||||||
|
VCHPRE_ struct dirent * VCHPOST_ vc_filesys_readdir_r(void *dhandle, struct dirent *result);
|
||||||
|
|
||||||
|
// Deletes a file or (empty) directory
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_remove(const char *path);
|
||||||
|
|
||||||
|
// Renames a file, provided the new name is on the same file system as the old
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_rename(const char *oldfile, const char *newfile);
|
||||||
|
|
||||||
|
// Resets the co-processor side file system
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_reset(void);
|
||||||
|
|
||||||
|
// Sets the attributes of the named file
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_set_attr(const char *path, fattributes_t attr);
|
||||||
|
|
||||||
|
// Truncates a file at its current position
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_setend(int fildes);
|
||||||
|
|
||||||
|
// Checks whether there are any messages in the incoming message fifo and responds to any such messages
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_poll_message_fifo(void);
|
||||||
|
|
||||||
|
// Return the event used to wait for reads.
|
||||||
|
VCHPRE_ void * VCHPOST_ vc_filesys_read_event(void);
|
||||||
|
|
||||||
|
// Sends a command for VC01 to reset the file system
|
||||||
|
VCHPRE_ void VCHPOST_ vc_filesys_sendreset(void);
|
||||||
|
|
||||||
|
// Return the error code of the last file system error
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_errno(void);
|
||||||
|
|
||||||
|
// Invalidates any cluster chains in the FAT that are not referenced in any directory structures
|
||||||
|
VCHPRE_ void VCHPOST_ vc_filesys_scandisk(const char *path);
|
||||||
|
|
||||||
|
// Checks whether or not a FAT filesystem is corrupt or not. If fix_errors is TRUE behaves exactly as vc_filesys_scandisk.
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_chkdsk(const char *path, int fix_errors);
|
||||||
|
|
||||||
|
// Return whether a disk is writeable or not.
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_diskwritable(const char *path);
|
||||||
|
|
||||||
|
// Return file system type of a disk.
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_fstype(const char *path);
|
||||||
|
|
||||||
|
// Returns the toatl amount of space on the drive that contains the given path
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_totalspace(const char *path);
|
||||||
|
VCHPRE_ int64_t VCHPOST_ vc_filesys_totalspace64(const char *path);
|
||||||
|
|
||||||
|
// Open disk for block level access
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_open_disk_raw(const char *path);
|
||||||
|
|
||||||
|
// Close disk from block level access mode
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_close_disk_raw(const char *path);
|
||||||
|
|
||||||
|
// Open disk for normal access
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_open_disk(const char *path);
|
||||||
|
|
||||||
|
// Close disk for normal access
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_close_disk(const char *path);
|
||||||
|
|
||||||
|
// Return number of sectors.
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_numsectors(const char *path);
|
||||||
|
VCHPRE_ int64_t VCHPOST_ vc_filesys_numsectors64(const char *path);
|
||||||
|
|
||||||
|
// Begin reading sectors from VideoCore.
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_read_sectors_begin(const char *path, uint32_t sector, uint32_t count);
|
||||||
|
|
||||||
|
// Read the next sector.
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_read_sector(char *buf);
|
||||||
|
|
||||||
|
// End streaming sectors.
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_read_sectors_end(uint32_t *sectors_read);
|
||||||
|
|
||||||
|
// Begin writing sectors from VideoCore.
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_write_sectors_begin(const char *path, uint32_t sector, uint32_t count);
|
||||||
|
|
||||||
|
// Write the next sector.
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_write_sector(const char *buf);
|
||||||
|
|
||||||
|
// End streaming sectors.
|
||||||
|
VCHPRE_ int VCHPOST_ vc_filesys_write_sectors_end(uint32_t *sectors_written);
|
||||||
|
|
||||||
|
#endif //VCFILESYS_H_
|
||||||
|
|
||||||
93
interface/vmcs_host/vcgencmd.h
Normal file
93
interface/vmcs_host/vcgencmd.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GENCMD_H
|
||||||
|
#define GENCMD_H
|
||||||
|
|
||||||
|
#include "vchost_config.h"
|
||||||
|
#include "interface/vchi/vchi.h"
|
||||||
|
|
||||||
|
VCHPRE_ void VCHPOST_ vc_vchi_gencmd_init(VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections );
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialise general command service. Returns it's interface number. This initialises
|
||||||
|
the host side of the interface, it does not send anything to VideoCore. */
|
||||||
|
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd_init(void);
|
||||||
|
|
||||||
|
/* Stop the service from being used. */
|
||||||
|
|
||||||
|
VCHPRE_ void VCHPOST_ vc_gencmd_stop(void);
|
||||||
|
|
||||||
|
/* Return the service number (-1 if not running). */
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd_inum(void);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Send commands to VideoCore.
|
||||||
|
These all return 0 for success. They return VC_MSGFIFO_FIFO_FULL if there is
|
||||||
|
insufficient space for the whole message in the fifo, and none of the message is
|
||||||
|
sent.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* send command to general command serivce */
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd_send( const char *format, ... );
|
||||||
|
|
||||||
|
/* get resonse from general command serivce */
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd_read_response(char *response, int maxlen);
|
||||||
|
|
||||||
|
/* convenience function to send command and receive the response */
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd(char *response, int maxlen, const char *format, ...);
|
||||||
|
|
||||||
|
/* read part of a response from the general command service */
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd_read_response_partial(char *response, int nbytes);
|
||||||
|
|
||||||
|
/* if reading with vc_gencmd_read_response_partial end response reads with this */
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd_close_response_partial(void);
|
||||||
|
|
||||||
|
/* get state of reading of response */
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd_read_partial_state(void);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Utilities to help interpret the responses.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* Read the value of a property=value type pair from a string (typically VideoCore's
|
||||||
|
response to a general command). Return non-zero if found. */
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd_string_property(char *text, const char *property, char **value, int *length);
|
||||||
|
|
||||||
|
/* Read the numeric value of a property=number field from a response string. Return
|
||||||
|
non-zero if found. */
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd_number_property(char *text, const char *property, int *number);
|
||||||
|
|
||||||
|
/* Send a command until the desired response is received, the error message is detected, or the timeout */
|
||||||
|
VCHPRE_ int VCHPOST_ vc_gencmd_until( char *cmd,
|
||||||
|
const char *property,
|
||||||
|
char *value,
|
||||||
|
const char *error_string,
|
||||||
|
int timeout);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
|
|
||||||
# dropped into ld.so.conf.d to setup shared library path
|
|
||||||
${CMAKE_INSTALL_PREFIX}/lib
|
|
||||||
|
|
||||||
|
|
||||||
@@ -36,22 +36,42 @@ configure_file (
|
|||||||
)
|
)
|
||||||
|
|
||||||
# install an ld.so.conf file to pick up our shared libraries
|
# install an ld.so.conf file to pick up our shared libraries
|
||||||
configure_file (${vmcs_root}/makefiles/cmake/srcs/vmcs.conf.in
|
#configure_file (${vmcs_root}/makefiles/cmake/srcs/vmcs.conf.in
|
||||||
${PROJECT_BINARY_DIR}/vmcs.conf)
|
# ${PROJECT_BINARY_DIR}/vmcs.conf)
|
||||||
if(NOT DEFINED ANDROID)
|
#if(NOT DEFINED ANDROID)
|
||||||
install(FILES ${PROJECT_BINARY_DIR}/vmcs.conf DESTINATION /etc/ld.so.conf.d)
|
# install(FILES ${PROJECT_BINARY_DIR}/vmcs.conf DESTINATION /etc/ld.so.conf.d)
|
||||||
endif()
|
#endif()
|
||||||
|
|
||||||
# also put it in /opt/vc for access by install script
|
# also put it in /opt/vc for access by install script
|
||||||
install(FILES ${PROJECT_BINARY_DIR}/vmcs.conf
|
#install(FILES ${PROJECT_BINARY_DIR}/vmcs.conf
|
||||||
DESTINATION ${VMCS_INSTALL_PREFIX}/share/install)
|
# DESTINATION ${VMCS_INSTALL_PREFIX}/share/install)
|
||||||
# provide headers the libraries need in /opt/vc too
|
# provide headers the libraries need in /opt/vc too
|
||||||
install(DIRECTORY interface/khronos/include
|
#install(DIRECTORY interface/khronos/include
|
||||||
DESTINATION ${VMCS_INSTALL_PREFIX})
|
# DESTINATION ${VMCS_INSTALL_PREFIX})
|
||||||
install(DIRECTORY interface/vmcs_host/khronos/IL
|
#install(DIRECTORY interface/vmcs_host/khronos/IL
|
||||||
DESTINATION ${VMCS_INSTALL_PREFIX}/include)
|
# DESTINATION ${VMCS_INSTALL_PREFIX}/include)
|
||||||
# provide an install script
|
# provide an install script
|
||||||
install(PROGRAMS ${vmcs_root}/makefiles/cmake/scripts/install_vmcs
|
#install(PROGRAMS ${vmcs_root}/makefiles/cmake/scripts/install_vmcs
|
||||||
DESTINATION ${VMCS_INSTALL_PREFIX}/sbin
|
# DESTINATION ${VMCS_INSTALL_PREFIX}/sbin
|
||||||
PERMISSIONS OWNER_WRITE WORLD_READ)
|
# PERMISSIONS OWNER_WRITE WORLD_READ)
|
||||||
|
|
||||||
|
# provide hello_pi demos
|
||||||
|
install(DIRECTORY host_applications/linux/apps/hello_pi
|
||||||
|
DESTINATION ${VMCS_INSTALL_PREFIX}/src)
|
||||||
|
|
||||||
|
# provide header files
|
||||||
|
#install(DIRECTORY host_applications/linux/libs/bcm_host/include
|
||||||
|
# DESTINATION ${VMCS_INSTALL_PREFIX}/)
|
||||||
|
|
||||||
|
install(DIRECTORY ${vmcs_root}/interface/vcos DESTINATION ${VMCS_INSTALL_PREFIX}/include/interface FILES_MATCHING PATTERN "*.h")
|
||||||
|
install(DIRECTORY ${vmcs_root}/interface/vchiq_arm DESTINATION ${VMCS_INSTALL_PREFIX}/include/interface FILES_MATCHING PATTERN "*.h")
|
||||||
|
install(DIRECTORY ${vmcs_root}/interface/vchi DESTINATION ${VMCS_INSTALL_PREFIX}/include/interface FILES_MATCHING PATTERN "*.h")
|
||||||
|
install(DIRECTORY ${vmcs_root}/interface/vctypes DESTINATION ${VMCS_INSTALL_PREFIX}/include/interface FILES_MATCHING PATTERN "*.h")
|
||||||
|
install(DIRECTORY ${vmcs_root}/vcinclude DESTINATION ${VMCS_INSTALL_PREFIX}/include FILES_MATCHING PATTERN "*.h")
|
||||||
|
install(DIRECTORY ${vmcs_root}/interface/vmcs_host DESTINATION ${VMCS_INSTALL_PREFIX}/include/interface FILES_MATCHING PATTERN "*.h" PATTERN "${vmcs_root}/interface/vmcs_host/khronos" EXCLUDE)
|
||||||
|
|
||||||
|
install(DIRECTORY ${vmcs_root}/interface/khronos/include DESTINATION ${VMCS_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.h")
|
||||||
|
install(DIRECTORY ${vmcs_root}/interface/vmcs_host/khronos/IL DESTINATION ${VMCS_INSTALL_PREFIX}/include FILES_MATCHING PATTERN "*.h")
|
||||||
|
|
||||||
|
install(DIRECTORY ${vmcs_root}/host_applications/linux/libs/bcm_host/include DESTINATION ${VMCS_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.h")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user