[Armadeus-commitlog] armadeus branch, master, updated. release-3.3-55-g2408af1
Brought to you by:
sszy
|
From: Julien B a. A. <ar...@us...> - 2010-10-15 13:09:23
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via 2408af11ecb290b1f66a17ab1c6a18346c9a7f51 (commit)
via 9981262046d7862c2ea36cde5790b920d12796aa (commit)
from f20a4caef973f0feb6232437cd44d3f46c57eb13 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 2408af11ecb290b1f66a17ab1c6a18346c9a7f51
Merge: 9981262046d7862c2ea36cde5790b920d12796aa f20a4caef973f0feb6232437cd44d3f46c57eb13
Author: Julien Boibessot <jul...@ar...>
Date: Fri Oct 15 15:08:34 2010 +0200
Merge branch 'master' of ssh://artemys@armadeus.git.sourceforge.net/gitroot/armadeus/armadeus
commit 9981262046d7862c2ea36cde5790b920d12796aa
Author: Julien Boibessot <jul...@ar...>
Date: Fri Oct 15 11:52:18 2010 +0200
[DEMOS] capture: add i.MX27 VPU support to stream captured video over IP (not fully functionnal yet)
-----------------------------------------------------------------------
Summary of changes:
target/demos/camera/capture/Makefile | 33 ++-
target/demos/camera/capture/README | 6 +-
target/demos/camera/capture/capture.c | 117 ++++--
target/demos/camera/capture/rtp.c | 288 +++++++++++++
target/demos/camera/capture/rtp.h | 68 +++
target/demos/camera/capture/udp.c | 101 +++++
target/demos/camera/capture/udp.h | 25 ++
target/demos/camera/capture/vpu_codec.c | 688 +++++++++++++++++++++++++++++++
target/demos/camera/capture/vpu_codec.h | 134 ++++++
9 files changed, 1417 insertions(+), 43 deletions(-)
create mode 100644 target/demos/camera/capture/rtp.c
create mode 100644 target/demos/camera/capture/rtp.h
create mode 100644 target/demos/camera/capture/udp.c
create mode 100644 target/demos/camera/capture/udp.h
create mode 100644 target/demos/camera/capture/vpu_codec.c
create mode 100644 target/demos/camera/capture/vpu_codec.h
diff --git a/target/demos/camera/capture/Makefile b/target/demos/camera/capture/Makefile
index 20a62bc..2301316 100644
--- a/target/demos/camera/capture/Makefile
+++ b/target/demos/camera/capture/Makefile
@@ -2,26 +2,42 @@ ARMADEUS_BASE_DIR=../../../..
-include $(ARMADEUS_BASE_DIR)/Makefile.in
# Default values for local compiling:
-STAGING_DIR:=$(ARMADEUS_BUILD_DIR)/staging_dir/
+STAGING_DIR:=$(ARMADEUS_STAGING_DIR)
INSTALL_DIR:=$(ARMADEUS_ROOTFS_DIR)/usr/local/bin/
CC:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-gcc
STRIP:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-sstrip
SDL_DIR:=$(ARMADEUS_SDL_DIR)
-CFLAGS=$(shell STAGING_DIR=$(STAGING_DIR) sh $(SDL_DIR)/sdl-config --cflags) -g
+CFLAGS=$(shell STAGING_DIR=$(STAGING_DIR) sh $(SDL_DIR)/sdl-config --cflags)
+#CFLAGS+=-Wall -g
LDFLAGS= -lSDL -lpthread
-
-EXEC=capture
-SRC= $(wildcard *.c *.h)
+ifeq ($(VPU),yes)
+CFLAGS+=-I$(ARMADEUS_STAGING_DIR)/usr/include/ -DUSE_VPU
+LDFLAGS+= -L$(ARMADEUS_STAGING_DIR)/usr/lib/ -lvpu
+endif
+
+EXEC= capture
+SRC= capture.c
+ifeq ($(VPU),yes)
+SRC+= rtp.c udp.c vpu_codec.c
+endif
OBJ= $(SRC:.c=.o)
+Q=@
+
all: $(EXEC)
$(EXEC): $(OBJ)
- $(CC) -o $@ $^ $(LDFLAGS)
+ @echo " LD $@"
+ $(Q)$(CC) -o $@ $^ $(LDFLAGS)
+
+capture.o: capture.c vpu_codec.h
+ @echo " CC $@"
+ $(Q)$(CC) -o $@ -c $< $(CFLAGS)
-%.o: %.c
- $(CC) -o $@ -c $< $(CFLAGS)
+%.o: %.c %.h
+ @echo " CC $@"
+ $(Q)$(CC) -o $@ -c $< $(CFLAGS)
.PHONY: clean install
@@ -32,4 +48,5 @@ clean:
install: all
mkdir -p $(INSTALL_DIR)
cp $(EXEC) $(INSTALL_DIR)
+ $(STRIP) $(INSTALL_DIR)/$(EXEC)
diff --git a/target/demos/camera/capture/README b/target/demos/camera/capture/README
index 53efb9c..5422084 100644
--- a/target/demos/camera/capture/README
+++ b/target/demos/camera/capture/README
@@ -1,5 +1,7 @@
Compile me:
* native:
- $ make
+ $ make CC=gcc
* cross-compilation:
- $ make CC=/.../.../arm-linux-gcc
+ $ make
+* with i.MX27 VPU support:
+ $ make VPU=yes
diff --git a/target/demos/camera/capture/capture.c b/target/demos/camera/capture/capture.c
index 84862e7..c7cb29d 100644
--- a/target/demos/camera/capture/capture.c
+++ b/target/demos/camera/capture/capture.c
@@ -31,11 +31,15 @@
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
+#include <sys/wait.h> /* signal */
#include <asm/types.h> /* for videodev2.h */
#include <linux/videodev2.h>
#include <SDL/SDL.h> /* TODO: make it compatible with Framebuffer only */
+#ifdef USE_VPU
+#include "vpu_codec.h"
+#endif
#define CLEAR(x) memset (&(x), 0, sizeof (x))
@@ -52,8 +56,9 @@ typedef enum {
} io_method;
struct buffer {
- void * start;
- size_t length;
+ void *start;
+ size_t length;
+ size_t offset;
};
static char * dev_name = NULL;
@@ -61,6 +66,7 @@ static io_method io = IO_METHOD_MMAP;
static int fd = -1;
struct buffer * buffers = NULL;
static unsigned int n_buffers = 0;
+int g_use_codec = 0;
SDL_Surface *screen = NULL, *image = NULL;
@@ -140,7 +146,7 @@ static Uint16 inline YUV2B(int Y, int U, int V)
return B;
}
-
+#if 0
static void yuv422_to_greyscale(void *yuv, int size, void *grey)
{
unsigned int Y, Y2, yuv32;
@@ -159,7 +165,7 @@ static void yuv422_to_greyscale(void *yuv, int size, void *grey)
*(dest++) = (Uint8)Y2;
}
}
-
+#endif
static void yuv422_to_rgb565(void *yuv, int size, void *rgb)
{
unsigned int Y, Y2, U, V, yuv32, rgb32;
@@ -294,7 +300,12 @@ static int read_frame(void)
assert (buf.index < n_buffers);
- process_image(buffers[buf.index].start, buf.length);
+#ifdef USE_VPU
+ if (g_use_codec)
+ vpu_codec_encode_next_frame(buffers[buf.index].offset, buffers[buf.index].start);
+#endif
+// else
+ process_image(buffers[buf.index].start, buf.length);
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
errno_exit("VIDIOC_QBUF");
@@ -340,9 +351,11 @@ static int read_frame(void)
return 1;
}
+static int go_on = 1;
+static int pause_capture = 0;
+
static void mainloop(void)
{
- int go_on = 1;
SDL_Event event;
while (go_on) {
@@ -372,7 +385,7 @@ static void mainloop(void)
exit (EXIT_FAILURE);
}
- if (read_frame ())
+ if (read_frame())
break;
/* EAGAIN - continue select loop. */
@@ -385,7 +398,8 @@ static void mainloop(void)
go_on = 0;
}
}
-// SDL_Delay(200);
+ while (pause_capture)
+ SDL_Delay(500);
}
}
@@ -553,13 +567,14 @@ static void init_mmap(void)
errno_exit ("VIDIOC_QUERYBUF");
buffers[n_buffers].length = buf.length;
+ buffers[n_buffers].offset = (size_t) buf.m.offset;
buffers[n_buffers].start =
mmap (NULL /* start anywhere */,
buf.length,
PROT_READ | PROT_WRITE /* required */,
MAP_SHARED /* recommended */,
fd, buf.m.offset);
-
+ /*printf("### start= 0x%08x offset=0x%08x\n", (unsigned int)(buffers[n_buffers].start), buffers[n_buffers].offset);*/
if (MAP_FAILED == buffers[n_buffers].start)
errno_exit ("mmap");
}
@@ -653,7 +668,7 @@ static Uint32 get_a_supported_pix_fmt(void)
return 0;
}
-static void init_device(unsigned int capt_width, unsigned int capt_height)
+static void init_capture_device(unsigned int capt_width, unsigned int capt_height)
{
struct v4l2_capability cap;
struct v4l2_cropcap cropcap;
@@ -783,7 +798,7 @@ static void close_device(void)
fd = -1;
}
-static void open_device(void)
+static void open_capture_device(void)
{
struct stat st;
@@ -809,20 +824,21 @@ static void open_device(void)
static void usage(FILE *fp, int argc, char **argv)
{
- fprintf (fp,
- "Usage: %s [options]\n\n"
- "Options:\n"
- "-d | --device name Video device name [/dev/video0]\n"
- "-h | --help Print this message\n"
- "-m | --mmap Use memory mapped buffers\n"
- "-r | --read Use read() calls\n"
- "-u | --userp Use application allocated buffers\n"
- "--width W Use W as screen width (instead of %d)\n"
- "--height H Use H as screen height (instead of %d)\n"
- "--camwidth W Use W as camera picture width (instead of %d)\n"
- "--camheight H Use H as camera picture height (instead of %d)\n"
- "",
- argv[0], SCREEN_WIDTH, SCREEN_HEIGHT, CAM_WIDTH, CAM_HEIGHT);
+ fprintf (fp,
+ "Usage: %s [options]\n\n"
+ "Options:\n"
+ "-d | --device name Video device name [/dev/video0]\n"
+ "-h | --help Print this message\n"
+ "-m | --mmap Use memory mapped buffers\n"
+ "-r | --read Use read() calls\n"
+ "-u | --userp Use application allocated buffers\n"
+ "--width W Use W as screen width (instead of %d)\n"
+ "--height H Use H as screen height (instead of %d)\n"
+ "--cam_width W Use W as camera picture width (instead of %d)\n"
+ "--cam_height H Use H as camera picture height (instead of %d)\n"
+ "--use_vpu Uses processor VPU to encode video (at camera size)\n"
+ "",
+ argv[0], SCREEN_WIDTH, SCREEN_HEIGHT, CAM_WIDTH, CAM_HEIGHT);
}
static const char short_options [] = "d:hmruwt";
@@ -835,11 +851,28 @@ static const struct option long_options [] = {
{ "userp", no_argument, NULL, 'u' },
{ "width", required_argument, NULL, 'w' },
{ "height", required_argument, NULL, 't' },
- { "camwidth", required_argument, NULL, 'y' },
- { "camheight", required_argument, NULL, 'z' },
+ { "cam_width", required_argument, NULL, 'y' },
+ { "cam_height", required_argument, NULL, 'z' },
+ { "use_vpu", no_argument, NULL, 'v' },
{ 0, 0, 0, 0 }
};
+static void signal_handler(int signal)
+{
+ printf("Caught signal %d\n", signal);
+ if (signal == SIGINT)
+ go_on = 0;
+
+ if (signal == SIGUSR1) {
+ printf("Starting capture\n");
+ pause_capture = 0;
+ }
+ if (signal == SIGUSR2) {
+ printf("Stopping capture\n");
+ pause_capture = 1;
+ }
+}
+
int main(int argc, char **argv)
{
int ret = EXIT_SUCCESS;
@@ -851,6 +884,12 @@ int main(int argc, char **argv)
dev_name = "/dev/video0";
atexit(SDL_Quit);
+
+ /* Do something when following signals are called */
+ signal(SIGINT, signal_handler);
+ signal(SIGUSR1, signal_handler);
+ signal(SIGUSR2, signal_handler);
+
for (;;) {
int index;
int c;
@@ -886,6 +925,10 @@ int main(int argc, char **argv)
io = IO_METHOD_USERPTR;
break;
+ case 'v':
+ g_use_codec = 1;
+ break;
+
case 'w':
width = atoi(optarg);
break;
@@ -908,10 +951,8 @@ int main(int argc, char **argv)
}
}
- open_device();
camwidth = camwidth > width ? width : camwidth;
camheight = camheight > height ? height : camheight;
- init_device(camwidth, camheight);
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
@@ -927,13 +968,23 @@ int main(int argc, char **argv)
ret = EXIT_FAILURE;
goto the_end;
}
+#ifdef USE_VPU
+ if (g_use_codec)
+ vpu_codec_init(2, camwidth, camheight, 0 /* bitrate */, 2);
+#endif
+
+ open_capture_device();
+ init_capture_device(camwidth, camheight);
image = SDL_CreateRGBSurface(/*SDL_HWSURFACE*/0, mycamera.width, mycamera.height, 16, 0, 0, 0, 0);
// printf("image fmt: RGB%d%d%d\n", image->format->Rshift, image->format->Gshift, image->format->Bshift);
-
- start_capturing();
- mainloop();
- stop_capturing();
+ start_capturing();
+ mainloop();
+#ifdef USE_VPU
+ if (g_use_codec)
+ vpu_SystemShutdown();
+#endif
+ stop_capturing();
the_end:
uninit_device();
diff --git a/target/demos/camera/capture/rtp.c b/target/demos/camera/capture/rtp.c
new file mode 100644
index 0000000..15666d3
--- /dev/null
+++ b/target/demos/camera/capture/rtp.c
@@ -0,0 +1,288 @@
+/*
+ * Implements H.264 streaming over RTP (RFC 3984)
+ *
+ * Copyright (c) 2009-2010, Armadeus Systems.
+ *
+ * Based on source code which is:
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2006, Chips & Media. All rights reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <memory.h>
+#include <sys/time.h>
+#include <errno.h>
+
+#include "udp.h"
+#include "rtp.h"
+
+/* RTP Flags MSB: */
+#define RTP_VER (2 << 6)
+#define RTP_PAD (1 << 5)
+#define RTP_EXT (1 << 4)
+#define RTP_CC(count) ((count) << 0)
+/* RTP Flags LSB: */
+#define RTP_MRK (1 << 7)
+#define RTP_TYP(typ) ((typ) << 0)
+
+
+typedef struct {
+ unsigned char flag_msb;
+ unsigned char flag_lsb;
+ unsigned short seq;
+ unsigned int time;
+ unsigned int ssrc;
+} __attribute__((packed)) rtph_t;
+
+
+int rtp_init(rtp_t * t, int bufsize)
+{
+ rtph_t *h;
+ int rt;
+
+ if (t->size < 4 || t->clock < 1000) {
+ return -2;
+ }
+
+ rt = t->size + sizeof(rtph_t);
+ t->rxbuf = calloc(2, rt);
+ if (!t->rxbuf) {
+ return -1;
+ }
+ t->txbuf = t->rxbuf + rt;
+ h = (rtph_t *) t->txbuf;
+ h->flag_msb = RTP_VER;
+ h->flag_lsb = RTP_TYP(t->type);
+
+ t->sock = udp_open(t->port, t->ip, &t->to);
+ if (t->sock < 0) {
+ free(t->rxbuf);
+ return -3;
+ }
+
+ if (bufsize > 0) {
+ bufsize *= rt;
+ setsockopt(t->sock, SOL_SOCKET, SO_RCVBUF, &bufsize, 4);
+ }
+
+ return 0;
+}
+
+int rtp_exit(rtp_t * t)
+{
+ free(t->rxbuf);
+ close(t->sock);
+ return 0;
+}
+
+#define chk_gen(buf, len) 0
+
+extern int g_state;
+
+static inline int min(int a, int b)
+{
+ if (a < b)
+ return a;
+ else
+ return b;
+}
+
+#define DEBUG(fmt, args...) do { ; } while (0)
+
+#define IS_ACCESS_UNIT(x) (((x) > 0x00) && ((x) < 0x06))
+
+int rtp_tx(rtp_t * t, char *buf, int len)
+{
+ rtph_t *h;
+ int tlen, hlen;
+ int rt;
+ struct timeval tv;
+ static unsigned short seq_num = 0;
+ int nal_type, mtu;
+ unsigned char nal_header;
+ unsigned char* payload;
+ int start, end;
+
+ h = (rtph_t *) t->txbuf;
+ h->flag_lsb &= ~RTP_MRK;
+ gettimeofday(&tv, 0);
+ h->time = htonl(((tv.tv_sec * 1000000) + tv.tv_usec)/10); /* important ? */
+ hlen = t->size;
+
+ /* Here we receive NALU one by one from codec,
+ with 0x00000001 header, so skip it */
+ buf += 4;
+ len -= 4;
+
+ nal_type = buf[0] & 0x1f;
+ DEBUG("--- Processing packet with NAL type=%d\n", nal_type);
+ mtu = t->size;
+ if (len < mtu) {
+ DEBUG("NAL Unit fit in one packet datasize=%d mtu=%d\n", len, mtu);
+ memcpy(h + 1, buf, hlen);
+ rt = len + sizeof(rtph_t);
+ rt = sendto(t->sock, h, rt, 0,
+ (struct sockaddr *)&t->to, sizeof(t->to));
+ if (rt < 0) {
+ printf("%s: rtp_tx err %d %d\n", t->name, rt, errno);
+ return rt;
+ }
+
+ seq_num++;
+ h->seq = htons(seq_num);
+ return len;
+ } else {
+ /* Divide NALU according to Fragmentation Unit A spec */
+ DEBUG("NAL Unit DOES NOT fit in one packet datasize=%d mtu=%d\n", len, mtu);
+ /* We keep 2 bytes for FU indicator and FU Header */
+ hlen -= 2;
+ start = 1;
+ end = 0;
+ /* skip NAL header in first frame as it will be reconstructed */
+ nal_header = *buf;
+ buf++;
+ len--;
+ for (tlen = 0; len > 0; tlen += hlen) {
+ if (len <= t->size) {
+ hlen = len;
+ h->flag_lsb |= RTP_MRK;
+ end = 1;
+ DEBUG("Last ");
+ }
+ payload = (unsigned char*)(h+1);
+ /* FU indicator (FU-A) */
+ payload[0] = (nal_header & 0x60) | 28;
+ /* FU Header */
+ payload[1] = (start << 7) | (end << 6) | (nal_header & 0x1f);
+ memcpy(&payload[2], buf, hlen);
+
+ rt = min((len+2), t->size) + sizeof(rtph_t);
+ rt = sendto(t->sock, h, rt, 0,
+ (struct sockaddr *)&t->to, sizeof(t->to));
+ if (rt < 0) {
+ printf("%s: rtp_tx err %d %d\n", t->name, rt, errno);
+ return rt;
+ }
+ DEBUG("Packet 0x%04x of %d bytes sent (%02x %02x %02x)\n", seq_num, rt,
+ buf[0], buf[1], buf[2]);
+
+ seq_num++;
+ h->seq = htons(seq_num);
+ buf += hlen;
+ len -= hlen;
+ start = 0;
+ }
+ return tlen;
+ }
+}
+
+int rtp_rx(rtp_t * t, char *buf, int len)
+{
+ rtph_t *h;
+ int tlen;
+ int rt;
+ unsigned short seq;
+
+ tlen = 0;
+ h = (rtph_t *) t->rxbuf;
+ seq = h->seq;
+ do {
+ int slen;
+
+ slen = sizeof(t->to);
+ rt = recvfrom(t->sock, h, t->size + sizeof(rtph_t),MSG_WAITALL, (struct sockaddr *)&t->to, (unsigned int *)&slen);
+ if (rt < 0) {
+ printf("%s: rtp_rx err %d\n", t->name, rt);
+ return rt;
+ }
+ if (!rt) {
+ printf("%s: rtp_rx warn 0-size-pkt\n", t->name);
+ t->err++;
+ continue;
+ }
+
+ rt = chk_gen((char *)h, t->size + sizeof(rtph_t));
+ if (rt) {
+ t->err++;
+// lp_skip:
+ h->flag_lsb &= ~RTP_MRK;
+ continue;
+ }
+
+ if (seq != h->seq) {
+ t->skip++;
+ /* skip remaining frags of pkt */
+ while (!(h->flag_lsb & RTP_MRK)) {
+ slen = sizeof(t->to);
+ rt = recvfrom(t->sock, h,t->size + sizeof(rtph_t),MSG_WAITALL,(struct sockaddr *)&t->to,(unsigned int *)&slen);
+ if (rt < 0)
+ {
+ return rt;
+ }
+ rt = chk_gen((char *)h,
+ t->size + sizeof(rtph_t));
+ if (rt) {
+ printf("%s: rtp_rx(skip) warn pkt "
+ "corrupt chk=%02X\n",
+ t->name, rt);
+ h->flag_lsb &= ~RTP_MRK;
+ t->err++;
+ } else {
+ t->skip++;
+ }
+ }
+ tlen = 0;
+ h->flag_lsb &= ~RTP_MRK;
+ h->seq++;
+ tlen = 0; /* discard previous frags of pkt */
+ seq = h->seq;
+ continue;
+ }
+
+ h->seq++;
+ seq = h->seq;
+ if (tlen > len) {
+ /* more data to read */
+ printf("%s: rtp_rx warn size %d < %d\n",
+ t->name, len, tlen);
+ return tlen;
+ }
+ }
+ while (!(h->flag_lsb & RTP_MRK));
+ return tlen;
+}
+
+rtp_t* rtp_session_open()
+{
+ rtp_t *rtp = (rtp_t *) malloc(sizeof(rtp_t));
+ memset(rtp, 0, sizeof(rtp_t));
+ rtp->name = "rec";
+ rtp->ip = RTP_ADDRESS;
+ rtp->port = RTP_PORT;
+ rtp->type = RTP_TYPE_DYNAMIC;
+ rtp->size = 512;
+ rtp->clock = 1000000;
+ rtp_init(rtp, 0);
+ return rtp;
+}
+
+void rtp_send(char *packet, int size)
+{
+ static rtp_t* rtp_session = NULL;
+ if (rtp_session==NULL)
+ rtp_session = rtp_session_open();
+ rtp_tx(rtp_session, packet, size);
+}
+
diff --git a/target/demos/camera/capture/rtp.h b/target/demos/camera/capture/rtp.h
new file mode 100644
index 0000000..d745132
--- /dev/null
+++ b/target/demos/camera/capture/rtp.h
@@ -0,0 +1,68 @@
+/*
+ * Implements H.264 streaming over RTP (RFC 3984)
+ *
+ * Copyright (c) 2009-2010, Armadeus Systems.
+ *
+ * Based on source code which is:
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2006, Chips & Media. All rights reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _RTP_H
+#define _RTP_H
+
+#include "udp.h"
+
+#define RTP_TYPE_ULAW 0
+#define RTP_TYPE_ALAW 8
+#define RTP_TYPE_L16S44 10
+#define RTP_TYPE_L16M44 11
+#define RTP_TYPE_H263 34
+#define RTP_TYPE_DYNAMIC 96
+
+#define RTP_PORT 6666
+#define RTP_ADDRESS "192.168.0.2"
+
+typedef struct {
+ char *name; /* local session id */
+ char *ip; /* server ip */
+ short port; /* server port */
+ unsigned short size; /* rtp frame size */
+ unsigned char type; /* RTP_TYPE_xxx */
+ int clock; /* RTP clock rate */
+
+ /* stats */
+ unsigned int err; /* #corrupted pkts */
+ unsigned int skip; /* #out of seq skipped */
+
+ /* reserved - zeroed */
+ struct sockaddr_in to;
+ int sock;
+ char *rxbuf;
+ char *txbuf;
+} rtp_t;
+
+/*
+ bufsize is in # of RTP pkts to buffer in rx (to cut delays)
+ 0 - default socket buffer size
+*/
+/*int rtp_init(rtp_t *, int bufsize);
+int rtp_tx(rtp_t *, char *buf, int len);
+int rtp_rx(rtp_t *, char *buf, int len);
+int rtp_exit(rtp_t *);
+*/
+
+rtp_t* rtp_session_open();
+void rtp_send(char *packet, int size);
+
+#endif
diff --git a/target/demos/camera/capture/udp.c b/target/demos/camera/capture/udp.c
new file mode 100644
index 0000000..c43d8dc
--- /dev/null
+++ b/target/demos/camera/capture/udp.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2006, Chips & Media. All rights reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+
+/*
+ * port server port#
+ * addr NULL -> this is the server, else server INADDR for client
+ * taddr2 address returned for use in sendto by client
+ */
+int udp_open(int port, char *addr, struct sockaddr_in *taddr2)
+{
+ int rt;
+ int fd;
+ struct sockaddr_in taddr;
+
+ fd = socket(PF_INET, SOCK_DGRAM, 0);
+ if (fd == -1) {
+ return -1;
+ }
+
+ if (addr) {
+ taddr2->sin_family = AF_INET;
+ taddr2->sin_port = htons(port);
+ taddr2->sin_addr.s_addr = inet_addr(addr);
+ port = 0;
+ }
+
+ taddr.sin_family = AF_INET;
+ taddr.sin_port = htons(port);
+ taddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ rt = bind(fd, (struct sockaddr *)&taddr, sizeof(taddr));
+ if (rt) {
+ close(fd);
+ return -2;
+ }
+
+ return fd;
+}
+
+//#define TEST
+#ifdef TEST
+#include <stdio.h>
+
+int main(void)
+{
+ struct sockaddr_in taddr;
+ char buf[1024];
+ int h, h2;
+ int len;
+ int pid;
+
+ h = udp_open(6666, 0, &taddr);
+ if (h < 0)
+ {
+ printf("open failed\n");
+ return 1;
+ }
+ pid = fork();
+ if (!pid)
+ {
+ sleep(1);
+ h2 = udp_open(6666, "127.0.0.1", &taddr);
+ if (h2 < 0)
+ {
+ printf("open failed\n");
+ return 1;
+ }
+ strcpy(buf, "hello\n");
+ len = sendto(h2, buf, sizeof(buf), 0, (struct sockaddr*)&taddr, sizeof(taddr));
+ printf("sent %d bytes\n", len);
+ close(h2);
+ }
+ else
+ {
+ len = sizeof(taddr);
+ len = recvfrom(h, buf, sizeof(buf), 0,
+ (struct sockaddr *)&taddr, &len);
+ printf("rx-ed %d bytes\n", len);
+ printf(buf);
+ }
+ close(h);
+ return 0;
+}
+#endif
diff --git a/target/demos/camera/capture/udp.h b/target/demos/camera/capture/udp.h
new file mode 100644
index 0000000..32cd211
--- /dev/null
+++ b/target/demos/camera/capture/udp.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2006, Chips & Media. All rights reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _UDP_H
+#define _UDP_H
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+int udp_open(int port, char *addr, struct sockaddr_in *);
+
+#endif
diff --git a/target/demos/camera/capture/vpu_codec.c b/target/demos/camera/capture/vpu_codec.c
new file mode 100644
index 0000000..4c6166f
--- /dev/null
+++ b/target/demos/camera/capture/vpu_codec.c
@@ -0,0 +1,688 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2006, Chips & Media. All rights reserved.
+ *
+ * Copyright (c) 2010, Armadeus Systems. All rights reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file vpu_codec.h
+ *
+ * @brief This file implement codec application.
+ *
+ * @ingroup VPU
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <linux/videodev.h>
+
+#include "rtp.h"
+/*#include "vpu_voip_test.h"
+#include "vpu_display.h"
+#include "vpu_capture.h"*/
+#include "vpu_io.h"
+#include "vpu_lib.h"
+
+#include "vpu_codec.h"
+
+
+typedef struct {
+ int Index;
+ int AddrY;
+ int AddrCb;
+ int AddrCr;
+ int StrideY;
+ int StrideC; /* Stride Cb/Cr */
+
+ int DispY; /* DispY is the page aligned AddrY */
+ int DispCb; /* DispCb is the page aligned AddrCb */
+ int DispCr;
+ vpu_mem_desc CurrImage; /* Current memory descriptor for user space */
+} FRAME_BUF;
+
+// extern struct codec_file multi_yuv[MAX_NUM_INSTANCE];
+/****** Timing Stuff Begin******/
+typedef enum evType_t {
+ DEC_READ = 1,
+ DEC_RD_OVER,
+ DEC_START,
+ DEC_STOP,
+ DEC_OUT,
+ DEC_OUT_OVER,
+ ENC_READ,
+ ENC_RD_OVER,
+ ENC_START,
+ ENC_STOP,
+ ENC_OUT,
+ ENC_OUT_OVER,
+ TEST_BEGIN,
+ TEST_END,
+
+} evType;
+
+#define MEASURE_COUNT 3000
+
+typedef struct time_rec {
+ evType tag;
+ struct timeval tval;
+} time_rec_t;
+
+time_rec_t time_rec_vector[MEASURE_COUNT + 1];
+
+static unsigned long iter;
+
+unsigned int enc_core_time;
+unsigned int enc_core_time_max;
+unsigned int enc_core_time_min = 100000;
+unsigned int enc_idle_time;
+unsigned int enc_idle_time_max;
+unsigned int enc_idle_time_min = 100000;
+
+unsigned int dec_core_time;
+unsigned int dec_core_time_max;
+unsigned int dec_core_time_min = 100000;
+unsigned int dec_idle_time;
+unsigned int dec_idle_time_max;
+unsigned int dec_idle_time_min = 100000;
+
+unsigned int ttl_time = 0;
+
+#define DIFF_TIME_TV_SEC(i, j) \
+ (time_rec_vector[i].tval.tv_sec - time_rec_vector[j].tval.tv_sec)
+#define DIFF_TIME_TV_USEC(i, j) \
+ (time_rec_vector[i].tval.tv_usec - time_rec_vector[j].tval.tv_usec)
+#define DIFF_TIME_US(i, j) (DIFF_TIME_TV_SEC(i, j) * 1000000 + DIFF_TIME_TV_USEC(i, j))
+
+void timer(evType tag)
+{
+ if (iter >= MEASURE_COUNT)
+ return;
+
+ struct timeval tval;
+ gettimeofday(&tval, NULL);
+ time_rec_vector[iter].tag = tag;
+ time_rec_vector[iter].tval = tval;
+ iter++;
+}
+
+/****** Timing Stuff End******/
+
+// extern struct codec_file multi_bitstream[MAX_NUM_INSTANCE];
+#define EOSCHECK_APISCHEME
+
+int quitflag = 0;
+
+typedef struct codec_info {
+ CodecInst handle;
+ FRAME_BUF *FbPool;
+ int FbNumber;
+ vpu_mem_desc bitstream_buf;
+} codec_info;
+
+static struct codec_info enc_info;
+
+// static pthread_mutex_t codec_mutex;
+#ifdef INT_CALLBACK
+static pthread_mutex_t vpu_busy_mutex;
+static pthread_cond_t current_job_cond;
+#endif
+
+extern sigset_t mask;
+
+/* FrameBuffer is a round-robin buffer for Current buffer and reference */
+int FrameBufferInit(int strideY, int height,
+ FRAME_BUF * FrameBuf, int FrameNumber)
+{
+ int i;
+
+ for (i = 0; i < FrameNumber; i++) {
+ memset(&(FrameBuf[i].CurrImage), 0, sizeof(vpu_mem_desc));
+ FrameBuf[i].CurrImage.size = (strideY * height * 3 / 2);
+ IOGetPhyMem(&(FrameBuf[i].CurrImage));
+ if (FrameBuf[i].CurrImage.phy_addr == 0) {
+ int j;
+ for (j = 0; j < i; j++) {
+ IOFreeVirtMem(&(FrameBuf[j].CurrImage));
+ IOFreePhyMem(&(FrameBuf[j].CurrImage));
+ }
+ printf("No enough mem for framebuffer!\n");
+ return -1;
+ }
+ FrameBuf[i].Index = i;
+ FrameBuf[i].AddrY = FrameBuf[i].CurrImage.phy_addr;
+ FrameBuf[i].AddrCb = FrameBuf[i].AddrY + strideY * height;
+ FrameBuf[i].AddrCr =
+ FrameBuf[i].AddrCb + strideY / 2 * height / 2;
+ FrameBuf[i].StrideY = strideY;
+ FrameBuf[i].StrideC = strideY / 2;
+ FrameBuf[i].DispY = FrameBuf[i].AddrY;
+ FrameBuf[i].DispCb = FrameBuf[i].AddrCb;
+ FrameBuf[i].DispCr = FrameBuf[i].AddrCr;
+ FrameBuf[i].CurrImage.virt_uaddr =
+ IOGetVirtMem(&(FrameBuf[i].CurrImage));
+ }
+ return 0;
+}
+
+void FrameBufferFree(FRAME_BUF * FrameBuf, int FrameNumber)
+{
+ int i;
+ for (i = 0; i < FrameNumber; i++) {
+ IOFreeVirtMem(&(FrameBuf[i].CurrImage));
+ IOFreePhyMem(&(FrameBuf[i].CurrImage));
+ }
+ return;
+}
+
+FRAME_BUF *GetFrameBuffer(int index, FRAME_BUF * FrameBuf)
+{
+ return &FrameBuf[index];
+}
+
+int GetFrameBufIndex(FRAME_BUF ** bufPool, int poolSize, FrameBuffer * frame)
+{
+ int i;
+
+ for (i = 0; i < poolSize; ++i) {
+ if ((*bufPool)->AddrY == frame->bufY) {
+ return i;
+ }
+ bufPool++;
+ }
+ return i;
+}
+
+#ifdef INT_CALLBACK
+void vpu_test_callback(int status)
+{
+#if 1
+ if (status & IRQ_PIC_RUN) {
+#else
+ if ((status & IRQ_PIC_RUN) || (status & IRQ_DEC_BUF_EMPTY)) {
+#endif
+ pthread_mutex_lock(&vpu_busy_mutex);
+ pthread_cond_signal(¤t_job_cond);
+ pthread_mutex_unlock(&vpu_busy_mutex);
+ }
+
+ return;
+}
+#endif
+
+static int vpu_SystemInit(void)
+{
+ int ret = -1;
+// pthread_mutex_init(&codec_mutex, NULL);
+#ifdef INT_CALLBACK
+ pthread_mutex_init(&vpu_busy_mutex, NULL);
+ pthread_cond_init(¤t_job_cond, NULL);
+
+ ret = IOSystemInit((void *)(vpu_test_callback));
+#else
+ ret = IOSystemInit(NULL);
+#endif
+ if (ret < 0) {
+ printf("IO system init failed!\n");
+ return -1;
+ }
+ return ret;
+}
+
+int vpu_SystemShutdown(void)
+{
+ if (enc_info.FbNumber) {
+ vpu_EncClose(&(enc_info.handle));
+ FrameBufferFree(enc_info.FbPool, enc_info.FbNumber);
+ IOFreeVirtMem(&(enc_info.bitstream_buf));
+ IOFreePhyMem(&(enc_info.bitstream_buf));
+ memset(&enc_info, 0, sizeof(struct codec_info));
+ }
+ IOSystemShutdown();
+// PrintTimingData();
+ DPRINTF("file close end\n");
+
+ return 0;
+}
+
+static void set_encoder_opening_parameters(EncOpenParam * enc_op_params, vpu_mem_desc *bit_stream_buf,
+ int mode, int width, int height, int bitrate)
+{
+ enc_op_params->bitstreamBuffer = bit_stream_buf->phy_addr;
+ enc_op_params->bitstreamBufferSize = bit_stream_buf->size;
+ enc_op_params->bitstreamFormat = mode;
+ enc_op_params->picWidth = width;
+ enc_op_params->picHeight = height;
+ enc_op_params->frameRateInfo = 15;
+ enc_op_params->bitRate = bitrate;
+ enc_op_params->initialDelay = 0;
+ enc_op_params->vbvBufferSize = 0; /* 0 = ignore 8 */
+ enc_op_params->enableAutoSkip = 0;
+ enc_op_params->gopSize = 0; /* only first picture is I */
+ enc_op_params->slicemode.sliceMode = 0; /* 1 slice per picture */
+ enc_op_params->slicemode.sliceSizeMode = 0;
+ enc_op_params->slicemode.sliceSize = 4000; /* not used if sliceMode is 0 */
+ enc_op_params->intraRefresh = 0;
+ enc_op_params->sliceReport = 0;
+ enc_op_params->mbReport = 0;
+ enc_op_params->mbQpReport = 0;
+ enc_op_params->rcIntraQp = -1;
+ enc_op_params->ringBufferEnable = 0;
+ enc_op_params->dynamicAllocEnable = 0;
+
+ if (mode == STD_MPEG4) {
+ enc_op_params->EncStdParam.mp4Param.mp4_dataPartitionEnable = 0;
+ enc_op_params->EncStdParam.mp4Param.mp4_reversibleVlcEnable = 0;
+ enc_op_params->EncStdParam.mp4Param.mp4_intraDcVlcThr = 0;
+ enc_op_params->EncStdParam.mp4Param.mp4_hecEnable = 0;
+ enc_op_params->EncStdParam.mp4Param.mp4_verid = 2;
+ } else if (mode == STD_H263) {
+ enc_op_params->EncStdParam.h263Param.h263_annexJEnable = 0;
+ enc_op_params->EncStdParam.h263Param.h263_annexKEnable = 0;
+ enc_op_params->EncStdParam.h263Param.h263_annexTEnable = 0;
+ } else if (mode == STD_AVC){
+ enc_op_params->EncStdParam.avcParam.avc_constrainedIntraPredFlag = 0;
+ enc_op_params->EncStdParam.avcParam.avc_disableDeblk = 0;
+ enc_op_params->EncStdParam.avcParam.avc_deblkFilterOffsetAlpha = 0;
+ enc_op_params->EncStdParam.avcParam.avc_deblkFilterOffsetBeta = 0;
+ enc_op_params->EncStdParam.avcParam.avc_chromaQpOffset = 0;
+ enc_op_params->EncStdParam.avcParam.avc_audEnable = 0;
+ /* FMO(Flexible macroblock ordering) support */
+ enc_op_params->EncStdParam.avcParam.avc_fmoEnable = 0;
+ enc_op_params->EncStdParam.avcParam.avc_fmoType = 0; /* 0 - interleaved, or 1 - dispersed */
+ enc_op_params->EncStdParam.avcParam.avc_fmoSliceNum = 2;
+ } else {
+ printf("Encoder: Invalid codec standard mode \n");
+// return NULL;
+ }
+}
+
+int gdest = PATH_NET;
+
+static void export_bitstream(char *packet, int size)
+{
+ if (gdest & PATH_NET) {
+ rtp_send(packet, size);
+ }
+}
+
+void vpu_codec_stop(void)
+{
+ quitflag = 1;
+}
+
+void vpu_codec_pause(void)
+{
+ quitflag = 0; /* TBDL */
+}
+
+
+EncHandle handle = { 0 };
+EncOpenParam encOP = { 0 };
+EncParam encParam = { 0 };
+EncHeaderParam encHeaderParam = { 0 };
+EncOutputInfo outputInfo = { 0 };
+
+int virt_bit_stream_buf;
+vpu_mem_desc bit_stream_buf;
+
+ FrameBuffer frameBuf[NUM_FRAME_BUF];
+ FRAME_BUF FrameBufPool[MAX_FRAME];
+
+int frame_index;
+ int srcFrameIdx;
+int image_size;
+int g_initialized = 0;
+
+
+/* for this test, only 1 reference */ /* no rotation */
+int vpu_codec_init(int mode, int picWidth, int picHeight, int bitRate, Uint32 dest)
+{
+ EncInitialInfo initialInfo = { 0 };
+ SearchRamParam searchPa = { 0 };
+ RetCode ret = RETCODE_SUCCESS;
+ int EXTRA_FB = 1;
+ int stride = 0;
+ Uint32 framebufWidth = 0, framebufHeight = 0;
+ FRAME_BUF *pFrame[NUM_FRAME_BUF];
+ int i;
+ struct v4l2_buffer prp_buffer;
+
+ image_size = picWidth * picHeight; /* in pixels */
+
+ memset(&encParam, 0, sizeof(EncParam));
+ memset(&encHeaderParam, 0, sizeof(EncHeaderParam));
+ memset(&handle, 0, sizeof(EncHandle));
+ memset(&encOP, 0, sizeof(EncOpenParam));
+ memset(&outputInfo, 0, sizeof(EncOutputInfo));
+
+ ret = vpu_SystemInit();
+ if (ret < 0)
+ return ret;
+
+ switch (mode) {
+ case STD_MPEG4:
+ DPRINTF("Enc mode: MPEG4\n");
+ break;
+ case STD_H263:
+ DPRINTF("Enc mode: H.263\n");
+ break;
+ case STD_AVC:
+ DPRINTF("Enc mode: H.264\n");
+ break;
+ default:
+ printf("Unknown Enc mode\n");
+ return -1;
+ }
+ DPRINTF("width %d, height %d, bitrate %d Kbps\n", picWidth, picHeight, bitRate);
+
+ memset(&enc_info, 0, sizeof(struct codec_info));
+
+ /* allocate the bitstream/output buffer */
+ memset(&bit_stream_buf, 0, sizeof(vpu_mem_desc));
+ bit_stream_buf.size = STREAM_BUF_SIZE;
+ IOGetPhyMem(&bit_stream_buf);
+ virt_bit_stream_buf = IOGetVirtMem(&bit_stream_buf);
+
+ /* framebufWidth and framebufHeight must be a multiple of 16 */
+ framebufWidth = ((picWidth + 15) & ~15);
+ framebufHeight = ((picHeight + 15) & ~15);
+
+ /* set Encoder start/opening Parameters */
+ set_encoder_opening_parameters(&encOP, &bit_stream_buf, mode, picWidth, picHeight, bitRate);
+
+ ret = vpu_EncOpen(&handle, &encOP);
+ if (ret != RETCODE_SUCCESS) {
+ printf("vpu_EncOpen failed. Error code is %d \n", ret);
+ goto ERR_ENC_INIT;
+ }
+
+ searchPa.searchRamAddr = DEFAULT_SEARCHRAM_ADDR;
+ ret = vpu_EncGiveCommand(handle, ENC_SET_SEARCHRAM_PARAM, &searchPa);
+ if (ret != RETCODE_SUCCESS) {
+ printf("vpu_EncGiveCommand ( ENC_SET_SEARCHRAM_PARAM ) failed. Error code is %d \n", ret);
+ goto ERR_ENC_OPEN;
+ }
+
+ ret = vpu_EncGetInitialInfo(handle, &initialInfo);
+ if (ret != RETCODE_SUCCESS) {
+ printf("vpu_EncGetInitialInfo failed. Error code is %d \n",
+ ret);
+ goto ERR_ENC_OPEN;
+ }
+ DPRINTF("Enc: min buffer count= %d\n", initialInfo.minFrameBufferCount);
+ printf("Initial Infos: minFrameBufferCount=%d\n", initialInfo.minFrameBufferCount);
+
+ /* allocate the image buffer, rec buffer/ref buffer plus src buffer */
+ FrameBufferInit(picWidth, picHeight,
+ FrameBufPool,
+ initialInfo.minFrameBufferCount + EXTRA_FB);
+
+ enc_info.FbPool = FrameBufPool;
+ enc_info.FbNumber = initialInfo.minFrameBufferCount + EXTRA_FB;
+ memcpy(&(enc_info.bitstream_buf), &bit_stream_buf,
+ sizeof(struct vpu_mem_desc));
+ memcpy(&(enc_info.handle), &handle, sizeof(DecHandle));
+
+ srcFrameIdx = initialInfo.minFrameBufferCount;
+
+ for (i = 0; i < initialInfo.minFrameBufferCount + EXTRA_FB; ++i) {
+ pFrame[i] = GetFrameBuffer(i, FrameBufPool);
+ frameBuf[i].bufY = pFrame[i]->AddrY;
+ frameBuf[i].bufCb = pFrame[i]->AddrCb;
+ frameBuf[i].bufCr = pFrame[i]->AddrCr;
+ }
+
+ stride = framebufWidth;
+ ret = vpu_EncRegisterFrameBuffer(handle, frameBuf,
+ initialInfo.minFrameBufferCount,
+ stride);
+ if (ret != RETCODE_SUCCESS) {
+ printf("vpu_EncRegisterFrameBuffer failed.Error code is %d \n", ret);
+ goto ERR_ENC_OPEN;
+ }
+
+ DPRINTF("Disp %x, %x, %x,\n\tStore buf %x, %x, %x\n",
+ pFrame[srcFrameIdx]->DispY,
+ pFrame[srcFrameIdx]->DispCb,
+ pFrame[srcFrameIdx]->DispCr,
+ (unsigned int)frameBuf[srcFrameIdx].bufY,
+ (unsigned int)frameBuf[srcFrameIdx].bufCb,
+ (unsigned int)frameBuf[srcFrameIdx].bufCr);
+
+ frame_index = 0;
+ encParam.sourceFrame = &frameBuf[srcFrameIdx];
+ encParam.quantParam = 30;
+ encParam.forceIPicture = 0;
+ encParam.skipPicture = 0;
+
+ memset(&prp_buffer, 0, sizeof(struct v4l2_buffer));
+
+ /* Must put encode header before first picture encoding. */
+ if (mode == STD_MPEG4) {
+ encHeaderParam.headerType = VOS_HEADER;
+ vpu_EncGiveCommand(handle, ENC_PUT_MP4_HEADER, &encHeaderParam);
+ if (encOP.ringBufferEnable == 0) {
+ export_bitstream((char *)(virt_bit_stream_buf + encHeaderParam.buf - bit_stream_buf.phy_addr), encHeaderParam.size);
+ }
+
+ encHeaderParam.headerType = VIS_HEADER;
+ vpu_EncGiveCommand(handle, ENC_PUT_MP4_HEADER, &encHeaderParam);
+ if (encOP.ringBufferEnable == 0) {
+ export_bitstream((char *)(virt_bit_stream_buf + encHeaderParam.buf - bit_stream_buf.phy_addr), encHeaderParam.size);
+ }
+
+ encHeaderParam.headerType = VOL_HEADER;
+ vpu_EncGiveCommand(handle, ENC_PUT_MP4_HEADER, &encHeaderParam);
+ if (encOP.ringBufferEnable == 0) {
+ export_bitstream((char *)(virt_bit_stream_buf + encHeaderParam.buf - bit_stream_buf.phy_addr), encHeaderParam.size);
+ }
+ } else if (mode == STD_AVC) {
+ encHeaderParam.headerType = SPS_RBSP;
+ vpu_EncGiveCommand(handle, ENC_PUT_AVC_HEADER, &encHeaderParam);
+ if (encOP.ringBufferEnable == 0) {
+ export_bitstream((char *)(virt_bit_stream_buf + encHeaderParam.buf - bit_stream_buf.phy_addr), encHeaderParam.size);
+ }
+
+ encHeaderParam.headerType = PPS_RBSP;
+ vpu_EncGiveCommand(handle, ENC_PUT_AVC_HEADER, &encHeaderParam);
+ if (encOP.ringBufferEnable == 0) {
+ export_bitstream((char *)(virt_bit_stream_buf + encHeaderParam.buf - bit_stream_buf.phy_addr), encHeaderParam.size);
+ }
+ }
+
+ g_initialized = 1;
+ goto NO_ERR;
+
+ERR_ENC_OPEN:
+ ret = vpu_EncClose(handle);
+ if (ret == RETCODE_FRAME_NOT_COMPLETE) {
+ vpu_EncGetOutputInfo(handle, &outputInfo);
+ vpu_EncClose(handle);
+ }
+
+ERR_ENC_INIT:
+ FrameBufferFree(FrameBufPool,
+ initialInfo.minFrameBufferCount + EXTRA_FB);
+ IOFreeVirtMem(&bit_stream_buf);
+ IOFreePhyMem(&bit_stream_buf);
+ DPRINTF("Enc closed\n");
+ memset(&enc_info, 0, sizeof(struct codec_info));
+
+NO_ERR:
+ return ret; //&codec_thread[usr_config->index];
+}
+
+int vpu_codec_encode_next_frame(size_t frame_offset, unsigned char* image)
+{
+ int ret;
+
+ if (!g_initialized) {
+ printf("%s: please initialize codec first !\n", __func__);
+ return -1;
+ }
+
+ /* main loop */
+// while (1) {
+ /*while (frame_index < 150)*/ {
+ if (frame_index % 100 == 0) {
+ DPRINTF(" Inst %d, No. %d\n",
+ ((EncInst *) handle)->instIndex, frame_index);
+ }
+
+ if (gdest == PATH_NET) {
+ if (frame_index % 5 == 0) {
+ encParam.forceIPicture = 1;
+ } else {
+ encParam.forceIPicture = 0;
+ }
+ }
+
+ // change Rc para test
+ // GOP number change
+ if (frame_index == 10) {
+ int newGopNum = 0;
+ vpu_EncGiveCommand(handle, ENC_SET_GOP_NUMBER, &newGopNum);
+ }
+ // Intra Qp change
+ if (frame_index == 20) {
+ int newIntraQp = 0;
+ vpu_EncGiveCommand(handle, ENC_SET_INTRA_QP, &newIntraQp);
+ }
+ // Bit Rate change
+ if (frame_index == 30) {
+ int newBitrate = 384000;
+ vpu_EncGiveCommand(handle, ENC_SET_BITRATE, &newBitrate);
+ }
+ // Frame Rate change
+ if (frame_index == 40) {
+ int newFramerate = 30;
+ vpu_EncGiveCommand(handle, ENC_SET_FRAME_RATE, &newFramerate);
+ if (encOP.bitstreamFormat== STD_MPEG4) {
+ encHeaderParam.headerType = VOL_HEADER;
+ vpu_EncGiveCommand(handle, ENC_PUT_MP4_HEADER, &encHeaderParam);
+ if (encOP.ringBufferEnable == 0) {
+ DPRINTF("MPEG4 encHeaderParam(VOL_HEADER) addr:%p len:%d\n", bsBuf0, size0);
+ export_bitstream((char *)(virt_bit_stream_buf + encHeaderParam.buf - bit_stream_buf.phy_addr), encHeaderParam.size);
+ }
+ }
+ }
+ // Intra Refresh Number change
+ if (frame_index == 50) {
+ int newIntraRefreshNum = 0;
+ vpu_EncGiveCommand(handle, ENC_SET_INTRA_MB_REFRESH_NUMBER, &newIntraRefreshNum);
+ }
+ // Slice Mode change
+ if (frame_index == 60) {
+ EncSliceMode newSlice;
+ newSlice.sliceMode = 0;
+ if(!newSlice.sliceMode) {
+ newSlice.sliceSizeMode = 0;
+ newSlice.sliceSize = 0;
+ } else {
+ // New Slice Size Mode[0:bit number, 1:MB number]
+ newSlice.sliceSizeMode = 0;
+
+ newSlice.sliceSize = 3000;
+ }
+ vpu_EncGiveCommand(handle, ENC_SET_SLICE_INFO, &newSlice);
+ }
+ // HEC Mode change
+ if (frame_index == 70) {
+ int newHecMode=0;
+ if (newHecMode > 0) {
+ vpu_EncGiveCommand(handle, ENC_ENABLE_HEC, &newHecMode);
+ } else {
+ vpu_EncGiveCommand(handle, ENC_DISABLE_HEC, &newHecMode);
+ }
+ }
+#if 0
+ /* get next frame to encode */
+ /*ret =
+ FillYuvImageMulti(usr_config->src, usr_config->src_name,
+ frameBuf[srcFrameIdx].bufY +
+ FrameBufPool[srcFrameIdx].CurrImage.
+ virt_uaddr -
+ FrameBufPool[srcFrameIdx].CurrImage.
+ phy_addr, (void *)&prp_buffer, picWidth,
+ picHeight,
+ ((EncInst *) handle)->instIndex,
+ CODEC_READING, rot_en, output_ratio, 0);*/
+// if (usr_config->src == PATH_EMMA) {
+ frameBuf[srcFrameIdx].bufY = frame_offset;
+// cap_buffers[prp_buffer.index].offset;
+ frameBuf[srcFrameIdx].bufCb =
+ frameBuf[srcFrameIdx].bufY + image_size;
+ frameBuf[srcFrameIdx].bufCr =
+ frameBuf[srcFrameIdx].bufCb + (image_size >> 2);
+#endif
+ memcpy((unsigned char*)(frameBuf[srcFrameIdx].bufY + FrameBufPool[srcFrameIdx].CurrImage.virt_uaddr - FrameBufPool[srcFrameIdx].CurrImage.phy_addr),
+ image,
+ FrameBufPool[srcFrameIdx].CurrImage.size);
+// memset((unsigned char*)(frameBuf[srcFrameIdx].bufY + FrameBufPool[srcFrameIdx].CurrImage.virt_uaddr - FrameBufPool[srcFrameIdx].CurrImage.phy_addr),
+// frame_index,
+// FrameBufPool[srcFrameIdx].CurrImage.size);
+
+ /* To fix the MPEG4 issue on MX27 TO2 */
+ CodStd codStd = ((EncInst *) handle)->CodecInfo.encInfo.openParam.bitstreamFormat;
+ DPRINTF("CodStd = %d\n", codStd);
+ if (codStd == STD_MPEG4 && (getChipVersion() == MX27_REV2)) {
+ vpu_ESDMISC_LHD(1);
+ }
+
+ /* encode frame */
+ ret = vpu_EncStartOneFrame(handle, &encParam);
+ if (ret != RETCODE_SUCCESS) {
+ printf("vpu_EncStartOneFrame failed. Error code is %d \n", ret);
+ return ret;
+ }
+ timer(ENC_START);
+#ifdef INT_CALLBACK
+ pthread_mutex_lock(&vpu_busy_mutex);
+ pthread_cond_wait(¤t_job_cond, &vpu_busy_mutex);
+ pthread_mutex_unlock(&vpu_busy_mutex);
+#else
+ vpu_WaitForInt(200);
+#endif
+ timer(ENC_STOP);
+
+ /* get resulting bitstream */
+ ret = vpu_EncGetOutputInfo(handle, &outputInfo);
+ if (ret != RETCODE_SUCCESS) {
+ printf("vpu_EncGetOutputInfo failed. Error code is %d \n", ret);
+ return ret;
+ }
+
+ /* To fix the MPEG4 issue on MX27 TO2 */
+ if (codStd == STD_MPEG4 && (getChipVersion() == MX27_REV2)) {
+ vpu_ESDMISC_LHD(0);
+ }
+
+ /* send buffer to dest */
+ export_bitstream((char *)(virt_bit_stream_buf + outputInfo.bitstreamBuffer - bit_stream_buf.phy_addr), outputInfo.bitstreamSize);
+
+/* if (encOP.mbQpReport == 1) {
+ SaveQpReport(outputInfo.mbQpInfo, encOP.picWidth,
+ encOP.picHeight, frame_index, "encqpreport.dat" );
+ }*/
+
+ frame_index++;
+ }
+
+ return 0;
+}
diff --git a/target/demos/camera/capture/vpu_codec.h b/target/demos/camera/capture/vpu_codec.h
new file mode 100644
index 0000000..3bec2cc
--- /dev/null
+++ b/target/demos/camera/capture/vpu_codec.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2006, Chips & Media. All rights reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file vpu_voip_test.h
+ *
+ * @brief This file is codec test header.
+ *
+ * @ingroup VPU
+ */
+
+#ifndef __VPU__VOIP__TEST__H
+#define __VPU__VOIP__TEST__H
+
+// #include "../../lib/vpu/vpu_io.h"
+// #include "../../lib/vpu/vpu_lib.h"
+#define Uint32 unsigned int
+
+#define PAL_MODE 0
+#define NTSC_MODE 1
+
+//#define STREAM_BUF_SIZE 0x40000
+#define STREAM_BUF_SIZE 0xA0000
+
+#if 0
+#ifdef PAL_MODE
+#define MAX_WIDTH 720
+#define MAX_HEIGHT 576
+#else
+#define MAX_WIDTH 720
+#define MAX_HEIGHT 480
+#endif
+#endif
+
+//#ifdef VGA_PANEL
+#define SCREEN_MAX_WIDTH 640
+#define SCREEN_MAX_HEIGHT 480
+//#else
+//#define SCREEN_MAX_WIDTH 240
+//#define SCREEN_MAX_HEIGHT 320
+//#endif
+
+#define MAX_WIDTH 720
+#define MAX_HEIGHT 480
+
+#define STRIDE MAX_WIDTH
+
+#define STREAM_FILL_SIZE 0x8000
+#define STREAM_END_SIZE 0
+
+enum {
+ COMMAND_NONE = 0,
+ COMMAND_DECODE,
+ COMMAND_ENCODE,
+ COMMAND_MULTI_DEC,
+ COMMAND_MULTI_CODEC
+};
+
+
+#define MAX_NUM_INSTANCE 4
+
+/*display1/reference16/reconstruction1/loopfilter1/rot1 for 1 video, 20 in total*/
+/*display4/reference16/reconstruction1/loopfilter1/rot1 for multi video, 23 in total */
+/*why 22 here? */
+#define NUM_FRAME_BUF (1+17+2)
+#define MAX_FRAME (16+2+4)
+
+struct codec_config {
+ Uint32 index;
+ Uint32 src;
+ char src_name[80];
+ Uint32 dst;
+ char dst_name[80];
+ Uint32 enc_flag;
+ Uint32 fps;
+ int bps;
+ Uint32 mode;
+ Uint32 width;
+ Uint32 height;
+ Uint32 gop;
+ Uint32 frame_count;
+ Uint32 rot_angle;
+ Uint32 out_ratio;
+ Uint32 mirror_angle;
+};
+
+// void *DecodeTest(void *param);
+int vpu_codec_init(int mode, int picWidth, int picHeight, int bitRate, Uint32 dest);
+// void *sig_thread(void *arg); /* the thread is used to monitor signal */
+
+int FillBsBufMulti(int src, char *src_name, int targetAddr,
+ int bsBufStartAddr, int bsBufEndAddr, int size,
+ int index, int checkeof, int *streameof, int read_flag);
+/* Read/Write one frame raw data each time, for Encoder/Decoder respectively */
+int FillYuvImageMulti(int src, char *src_name, int buf, void *emma_buf,
+ int inwidth, int inheight, int index, int read_flag,
+ int rot_en, int output_ratio, int frame_num);
+
+int vpu_codec_encode_next_frame(Uint32 frame_offset, unsigned char* image);
+
+int vpu_SystemShutdown(void);
+void vpu_codec_stop(void);
+void vpu_codec_pause(void);
+
+#define TEST_BUFFER_NUM 3
+
+// #define CODEC_READING 0
+// #define CODEC_WRITING 1
+
+#define PATH_FILE 0
+#define PATH_EMMA 1
+#define PATH_NET 2
+
+// pthread_t codec_thread[MAX_NUM_INSTANCE];
+
+#ifdef DEBUG
+#define DPRINTF(fmt, args...) printf("%s: " fmt , __FUNCTION__, ## args)
+#else
+#define DPRINTF(fmt, args...)
+#endif
+
+#endif
hooks/post-receive
--
armadeus
|