Add hello_pi apps and bcm_host.h to userland. Merge with latest code.

This commit is contained in:
Dom Cobley
2012-11-13 01:59:50 +00:00
parent ef62d33406
commit 61232b4033
77 changed files with 13577 additions and 72 deletions

View File

@@ -3,5 +3,10 @@ mkdir -p build/arm-linux/release/
pushd build/arm-linux/release/
cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=Release ../../..
make -j 6
if [ "$1" != "" ]; then
sudo make install DESTDIR=$1
fi
popd

View File

@@ -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_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/...
#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_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_CODE_T;

View File

@@ -50,9 +50,9 @@ typedef struct vc_metadata_item_s {
typedef struct vc_metadata_header_s {
int size;
#ifdef VCMODS_LCC
char readonly;
unsigned char readonly;
#else
char readonly:1;
unsigned char readonly:1;
#endif
int offset_next;
RTOS_LATCH_T latch;

View 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)

View 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)

View 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.

View File

@@ -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)

View File

@@ -0,0 +1,6 @@
OBJS=audio.o sinewave.o
BIN=hello_audio.bin
LDFLAGS+=-lilclient
include ../Makefile.include

View 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(&param, 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, &param);
assert(error == OMX_ErrorNone);
param.nBufferSize = size;
param.nBufferCountActual = num_buffers;
error = OMX_SetParameter(ILC_GET_HANDLE(st->audio_render), OMX_IndexParamPortDefinition, &param);
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(&param, 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, &param);
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;
}

View 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 */

View 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,
};

View File

@@ -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)

View File

@@ -0,0 +1,5 @@
OBJS=dispmanx.o
BIN=hello_dispmanx.bin
include ../Makefile.include

View 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;
}

View File

@@ -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)

View File

@@ -0,0 +1,6 @@
OBJS=encode.o
BIN=hello_encode.bin
LDFLAGS+=-lilclient
include ../Makefile.include

View 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]);
}

View File

@@ -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)

View File

@@ -0,0 +1,7 @@
OBJS=main.o
BIN=hello_font.bin
LDFLAGS+=-lvgfont -lfreetype -lz
include ../Makefile.include

View 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;
}

View File

@@ -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)

View File

@@ -0,0 +1,6 @@
OBJS=jpeg.o
BIN=hello_jpeg.bin
LDFLAGS+=-lilclient
include ../Makefile.include

View 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;
}

View 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

View File

@@ -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)

View File

@@ -0,0 +1,8 @@
OBJS=main.o tiger.o
BIN=hello_tiger.bin
#LDFLAGS+=
CFLAGS+=-D__RASPBERRYPI__
include ../Makefile.include

View File

@@ -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."

View 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

View 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.

File diff suppressed because it is too large Load Diff

View 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 */

View File

@@ -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)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
OBJS=triangle.o
BIN=hello_triangle.bin
include ../Makefile.include

View 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
};

View 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;
}

View File

@@ -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)

View File

@@ -0,0 +1,5 @@
OBJS=triangle2.o
BIN=hello_triangle2.bin
include ../Makefile.include

View 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;
}

View File

@@ -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)

View File

@@ -0,0 +1,6 @@
OBJS=video.o
BIN=hello_video.bin
LDFLAGS+=-lilclient
include ../Makefile.include

View File

@@ -0,0 +1 @@
The video clip test.h264 is (c) copyright 2008, Blender Foundation / www.bigbuckbunny.org

Binary file not shown.

View 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]);
}

View File

@@ -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)

View File

@@ -0,0 +1,5 @@
OBJS=world.o
BIN=hello_world.bin
include ../Makefile.include

View 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.
*/
#ifndef VCHOST_CONFIG_H
#define VCHOST_CONFIG_H
// Classic Hello World
#include "interface/vcos/vcos.h"
#include <stdio.h>
#if 0
/* Types that map onto VideoCore's types of the same name. */
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
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
int main(void)
{
printf("Hello world!\n");
return 0;
}

View File

@@ -0,0 +1,5 @@
OBJS=ilclient.o ilcore.o
LIB=libilclient.a
include ../../Makefile.include

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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 */

View 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

View 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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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

View 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

View 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;
}

View 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

View 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

View 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.
*/

View File

@@ -6,7 +6,7 @@ add_library(vchiq_arm SHARED
target_link_libraries(vchiq_arm)
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(../..)

View File

@@ -65,4 +65,4 @@ if (WIN32)
configure_file (build_all.bat.in build_all.bat @ONLY)
endif ()
install (FILES ${HEADERS} DESTINATION include/interface/vcos)
#install (FILES ${HEADERS} DESTINATION include/interface/vcos)

View File

@@ -42,5 +42,5 @@ else ()
endif ()
install(FILES ${HEADERS} DESTINATION include)
#install(FILES ${HEADERS} DESTINATION include)
install(TARGETS vcos DESTINATION lib)

View 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.
*/

View File

@@ -50,6 +50,7 @@ typedef enum
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_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_T;
@@ -94,6 +95,12 @@ typedef struct
uint32_t line_rate;
// Format required for image data for 3D displays
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;
#endif /* __VC_INCLUDE_IMAGE_TYPES_H__ */

View 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

View File

@@ -1,5 +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

View File

@@ -1,5 +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
@@ -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
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.
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.
*/
/*

View File

@@ -1,7 +1,5 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
* Copyright (c) 2012 Broadcom Europe Ltd
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

View 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_

View 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_

View 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

View File

@@ -1,5 +0,0 @@
# dropped into ld.so.conf.d to setup shared library path
${CMAKE_INSTALL_PREFIX}/lib

View File

@@ -36,22 +36,42 @@ configure_file (
)
# install an ld.so.conf file to pick up our shared libraries
configure_file (${vmcs_root}/makefiles/cmake/srcs/vmcs.conf.in
${PROJECT_BINARY_DIR}/vmcs.conf)
if(NOT DEFINED ANDROID)
install(FILES ${PROJECT_BINARY_DIR}/vmcs.conf DESTINATION /etc/ld.so.conf.d)
endif()
#configure_file (${vmcs_root}/makefiles/cmake/srcs/vmcs.conf.in
# ${PROJECT_BINARY_DIR}/vmcs.conf)
#if(NOT DEFINED ANDROID)
# install(FILES ${PROJECT_BINARY_DIR}/vmcs.conf DESTINATION /etc/ld.so.conf.d)
#endif()
# also put it in /opt/vc for access by install script
install(FILES ${PROJECT_BINARY_DIR}/vmcs.conf
DESTINATION ${VMCS_INSTALL_PREFIX}/share/install)
#install(FILES ${PROJECT_BINARY_DIR}/vmcs.conf
# DESTINATION ${VMCS_INSTALL_PREFIX}/share/install)
# provide headers the libraries need in /opt/vc too
install(DIRECTORY interface/khronos/include
DESTINATION ${VMCS_INSTALL_PREFIX})
install(DIRECTORY interface/vmcs_host/khronos/IL
DESTINATION ${VMCS_INSTALL_PREFIX}/include)
#install(DIRECTORY interface/khronos/include
# DESTINATION ${VMCS_INSTALL_PREFIX})
#install(DIRECTORY interface/vmcs_host/khronos/IL
# DESTINATION ${VMCS_INSTALL_PREFIX}/include)
# provide an install script
install(PROGRAMS ${vmcs_root}/makefiles/cmake/scripts/install_vmcs
DESTINATION ${VMCS_INSTALL_PREFIX}/sbin
PERMISSIONS OWNER_WRITE WORLD_READ)
#install(PROGRAMS ${vmcs_root}/makefiles/cmake/scripts/install_vmcs
# DESTINATION ${VMCS_INSTALL_PREFIX}/sbin
# 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")