kopia lustrzana https://github.com/F5OEO/rpidatv
Add modified hello_video
rodzic
8e9c8cb34e
commit
e3f7950304
|
@ -0,0 +1,6 @@
|
|||
OBJS=video.o
|
||||
BIN=hello_video.bin
|
||||
LDFLAGS+=-lilclient
|
||||
|
||||
include Makefile.include
|
||||
|
|
@ -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 -lm -L$(SDKSTAGE)/opt/vc/src/hello_pi/libs/ilclient -L$(SDKSTAGE)/opt/vc/src/hello_pi/libs/vgfont
|
||||
|
||||
INCLUDES+=-I$(SDKSTAGE)/opt/vc/include/ -I$(SDKSTAGE)/opt/vc/include/interface/vcos/pthreads -I$(SDKSTAGE)/opt/vc/include/interface/vmcs_host/linux -I./ -I$(SDKSTAGE)/opt/vc/src/hello_pi/libs/ilclient -I$(SDKSTAGE)/opt/vc/src/hello_pi/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)
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
The video clip test.h264 is (c) copyright 2008, Blender Foundation / www.bigbuckbunny.org
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
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"
|
||||
|
||||
OMX_TICKS ToOMXTime(int64_t pts)
|
||||
{
|
||||
OMX_TICKS ticks;
|
||||
ticks.nLowPart = pts;
|
||||
ticks.nHighPart = pts >> 32;
|
||||
return ticks;
|
||||
}
|
||||
|
||||
static inline uint64_t FromOMXTime(OMX_TICKS ticks)
|
||||
{
|
||||
uint64_t pts = ticks.nLowPart | ((uint64_t)ticks.nHighPart << 32);
|
||||
return pts;
|
||||
}
|
||||
|
||||
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 int data_len = 0;
|
||||
|
||||
memset(list, 0, sizeof(list));
|
||||
memset(tunnel, 0, sizeof(tunnel));
|
||||
|
||||
if((in = fopen(filename, "rb")) == NULL)
|
||||
return -2;
|
||||
|
||||
if((client = ilclient_init()) == NULL)
|
||||
{
|
||||
fclose(in);
|
||||
return -3;
|
||||
}
|
||||
|
||||
if(OMX_Init() != OMX_ErrorNone)
|
||||
{
|
||||
ilclient_destroy(client);
|
||||
fclose(in);
|
||||
return -4;
|
||||
}
|
||||
|
||||
// create video_decode
|
||||
if(ilclient_create_component(client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0)
|
||||
status = -14;
|
||||
list[0] = video_decode;
|
||||
|
||||
// create video_render
|
||||
if(status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0)
|
||||
status = -14;
|
||||
list[1] = video_render;
|
||||
|
||||
// create clock
|
||||
if(status == 0 && ilclient_create_component(client, &clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0)
|
||||
status = -14;
|
||||
list[2] = clock;
|
||||
|
||||
memset(&cstate, 0, sizeof(cstate));
|
||||
cstate.nSize = sizeof(cstate);
|
||||
cstate.nVersion.nVersion = OMX_VERSION;
|
||||
cstate.eState = OMX_TIME_ClockStateWaitingForStartTime;
|
||||
cstate.nWaitMask = 1;
|
||||
if(clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(clock), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone)
|
||||
status = -13;
|
||||
|
||||
// create video_scheduler
|
||||
if(status == 0 && ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0)
|
||||
status = -14;
|
||||
list[3] = video_scheduler;
|
||||
|
||||
set_tunnel(tunnel, video_decode, 131, video_scheduler, 10);
|
||||
set_tunnel(tunnel+1, video_scheduler, 11, video_render, 90);
|
||||
set_tunnel(tunnel+2, clock, 80, video_scheduler, 12);
|
||||
|
||||
// setup clock tunnel first
|
||||
if(status == 0 && ilclient_setup_tunnel(tunnel+2, 0, 0) != 0)
|
||||
status = -15;
|
||||
else
|
||||
ilclient_change_component_state(clock, OMX_StateExecuting);
|
||||
|
||||
if(status == 0)
|
||||
ilclient_change_component_state(video_decode, OMX_StateIdle);
|
||||
|
||||
memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
|
||||
format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
|
||||
format.nVersion.nVersion = OMX_VERSION;
|
||||
format.nPortIndex = 130;
|
||||
format.eCompressionFormat = OMX_VIDEO_CodingAVC;
|
||||
|
||||
|
||||
{
|
||||
OMX_PARAM_PORTDEFINITIONTYPE portdef;
|
||||
portdef.nSize = sizeof (OMX_PARAM_PORTDEFINITIONTYPE);
|
||||
portdef.nVersion.nVersion = OMX_VERSION;
|
||||
portdef.nPortIndex = 130;
|
||||
if (OMX_GetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamPortDefinition, &portdef) == OMX_ErrorNone) {
|
||||
portdef.nBufferCountActual = 20;//portdef.nBufferCountMin;
|
||||
//portdef.nBufferSize = 16*1024 ;//32 * 1024;
|
||||
printf("OMX_GetParameter nBufferCount %d nBufferSize %d\n",portdef.nBufferCountActual,portdef.nBufferSize);
|
||||
|
||||
/*if (OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamPortDefinition, &portdef) != OMX_ErrorNone) {
|
||||
printf("OMX_SetParameter error\n");
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
if(status == 0 &&
|
||||
OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone &&
|
||||
ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0)
|
||||
{
|
||||
OMX_BUFFERHEADERTYPE *buf;
|
||||
int port_settings_changed = 0;
|
||||
int first_packet = 1;
|
||||
|
||||
ilclient_change_component_state(video_decode, OMX_StateExecuting);
|
||||
|
||||
while((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL)
|
||||
{
|
||||
// feed data and wait until we get port settings changed
|
||||
unsigned char *dest = buf->pBuffer;
|
||||
#define BURST_READ (500)
|
||||
data_len = fread(dest, 1, BURST_READ, in);
|
||||
//printf("Lu = %d\n",data_len);
|
||||
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;
|
||||
|
||||
buf->nFilledLen = data_len;
|
||||
//data_len = 0;
|
||||
|
||||
buf->nOffset = 0;
|
||||
if(first_packet)
|
||||
{
|
||||
buf->nFlags = OMX_BUFFERFLAG_STARTTIME;
|
||||
first_packet = 0;
|
||||
printf("First Packet %llu\n",FromOMXTime(buf->nTimeStamp));
|
||||
}
|
||||
else
|
||||
{ static uint64_t PTS=0;
|
||||
|
||||
//buf->nTimeStamp = ToOMXTime(PTS);
|
||||
buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
|
||||
//buf->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
|
||||
PTS+=40*90*300L;
|
||||
|
||||
}
|
||||
|
||||
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, -1);
|
||||
|
||||
// need to flush the renderer to allow video_decode to disable its input port
|
||||
ilclient_flush_tunnels(tunnel, 0);
|
||||
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
|
||||
ilclient_disable_tunnel(tunnel);
|
||||
ilclient_disable_tunnel(tunnel+1);
|
||||
ilclient_disable_tunnel(tunnel+2);
|
||||
ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL);
|
||||
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]);
|
||||
}
|
||||
|
||||
|
Ładowanie…
Reference in New Issue