rendered paste body/*! \file
*
* \brief Save to raw, headerless h264 data.
* \arg File name extension: h264
* \ingroup formats
* \arg See \ref AstVideo
*/
#ifdef HAVE_CONFIG_H
#include "confdefs.h"
#endif
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/time.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "callweaver.h"
CALLWEAVER_FILE_VERSION("$HeadURL: http://svn.callweaver.org/callweaver/branches/rel/1.2/formats/format_h264.c $", "$Revision: 9999 $")
#include "callweaver/lock.h"
#include "callweaver/channel.h"
#include "callweaver/file.h"
#include "callweaver/logger.h"
#include "callweaver/sched.h"
#include "callweaver/module.h"
//#include "callweaver/endian.h"
/* Some Ideas for this code came from makeh264e.c by Jeffrey Chilton */
/* Portions of the conversion code are by guido@sienanet.it */
/*! \todo Check this buf size estimate, it may be totally wrong for large frame video */
#define BUF_SIZE 17000//4096 /* Two Real h264 Frames */
OPBX_MUTEX_DEFINE_STATIC(h264_lock);
static int glistcnt = 0;
static char *name = "h264";
static char *desc = "Raw h264 data";
static char *exts = "h264";
struct opbx_filestream
{
void *reserved[OPBX_RESERVED_POINTERS];
/* Believe it or not, we must decode/recode to account for the
weird MS format */
/* This is what a filestream means to us */
FILE *f; /* Descriptor */
unsigned int lastts;
struct opbx_frame fr; /* Frame information */
char waste[OPBX_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */
char empty; /* Empty character */
unsigned char buf[BUF_SIZE]; /* */
};
static struct opbx_filestream *h264_open(FILE *f)
{
opbx_log(LOG_NOTICE, "h264_open\n");
struct opbx_filestream *tmp;
unsigned int ts;
int res;
if ((res = fread(&ts, 1, sizeof(ts), f)) < sizeof(ts)) {
opbx_log(LOG_WARNING, "Empty file!\n");
return NULL;
}
if ((tmp = malloc(sizeof(struct opbx_filestream))))
{
memset(tmp, 0, sizeof(struct opbx_filestream));
if (opbx_mutex_lock(&h264_lock))
{
opbx_log(LOG_WARNING, "Unable to lock h264 list\n");
free(tmp);
return NULL;
}
tmp->f = f;
opbx_fr_init_ex(&tmp->fr, OPBX_FRAME_VIDEO, OPBX_FORMAT_H264, name);
tmp->fr.data = tmp->buf;
/* datalen will vary for each frame */
glistcnt++;
opbx_mutex_unlock(&h264_lock);
opbx_update_use_count();
}
return tmp;
}
static struct opbx_frame *h264_read(struct opbx_filestream *s, int *whennext)
{
opbx_log(LOG_NOTICE, "h264_read\n");
int res;
int mark=0;
unsigned short len;
unsigned int ts;
/* Send a frame from the file to the appropriate channel */
opbx_fr_init_ex(&s->fr, OPBX_FRAME_VIDEO, OPBX_FORMAT_H264, NULL);
s->fr.offset = OPBX_FRIENDLY_OFFSET;
s->fr.data = s->buf;
if ((res = fread(&len, 1, sizeof(len), s->f)) < 1)
return NULL;
len = ntohs(len);
mark = (len & 0x8000) ? 1 : 0;
len &= 0x7fff;
if (len > BUF_SIZE) {
opbx_log(LOG_WARNING, "Length %d is too long\n", len);
len = BUF_SIZE; /* XXX truncate */
}
s->fr.frametype = OPBX_FRAME_VIDEO;
s->fr.subclass = OPBX_FORMAT_H264;
s->fr.mallocd = 0;
OPBX_FRAME_SET_BUFFER(&s->fr, s->buf, OPBX_FRIENDLY_OFFSET, len);
if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
if (res)
opbx_log(LOG_WARNING, "Short read (%d of %d) (%s)!\n", res, len, strerror(errno));
return NULL;
}
s->fr.samples = s->lastts;
s->fr.datalen = len;
s->fr.subclass |= mark;
s->fr.delivery.tv_sec = 0;
s->fr.delivery.tv_usec = 0;
if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
s->lastts = ntohl(ts);
*whennext = s->lastts * 4/45;
} else
*whennext = 0;
return &s->fr;
}
static int h264_write(struct opbx_filestream *s, struct opbx_frame *f)
{
opbx_log(LOG_NOTICE, "h264_write\n");
int res;
unsigned int ts;
unsigned short len;
int mark;
if (f->frametype != OPBX_FRAME_VIDEO) {
opbx_log(LOG_WARNING, "Asked to write non-video frame!\n");
return -1;
}
mark = (f->subclass & 0x1) ? 0x8000 : 0;
if ((f->subclass & ~0x1) != OPBX_FORMAT_H264) {
opbx_log(LOG_WARNING, "Asked to write non-h264 frame (%d)!\n", f->subclass);
return -1;
}
ts = htonl(f->samples);
if ((res = fwrite(&ts, 1, sizeof(ts), s->f)) != sizeof(ts)) {
opbx_log(LOG_WARNING, "Bad write (%d/4): %s\n", res, strerror(errno));
return -1;
}
len = htons(f->datalen | mark);
if ((res = fwrite(&len, 1, sizeof(len), s->f)) != sizeof(len)) {
opbx_log(LOG_WARNING, "Bad write (%d/2): %s\n", res, strerror(errno));
return -1;
}
if ((res = fwrite(f->data, 1, f->datalen, s->f)) != f->datalen) {
opbx_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
return -1;
}
return 0;
}
static int h264_seek(struct opbx_filestream *fs, off_t sample_offset, int whence)
{
opbx_log(LOG_NOTICE, "h264_seek\n");
/* No way Jose */
return -1;
}
static int h264_trunc(struct opbx_filestream *fs)
{
opbx_log(LOG_NOTICE, "h264_trunc\n");
/* Truncate file to current length */
if (ftruncate(fileno(fs->f), ftell(fs->f)) < 0)
return -1;
return 0;
}
static off_t h264_tell(struct opbx_filestream *fs)
{
opbx_log(LOG_NOTICE, "h264_tell\n");
off_t offset = ftell(fs->f);
return offset; /* XXX totally bogus, needs fixing */
}
static void h264_close(struct opbx_filestream *s)
{
opbx_log(LOG_NOTICE, "h264_close\n");
if (opbx_mutex_lock(&h264_lock))
{
opbx_log(LOG_WARNING, "Unable to lock h264 list\n");
return;
}
glistcnt--;
opbx_mutex_unlock(&h264_lock);
opbx_update_use_count();
fclose(s->f);
free(s);
s = NULL;
}
static struct opbx_filestream *h264_rewrite(FILE *f, const char *comment)
{
opbx_log(LOG_NOTICE, "h264_rewrite\n");
/* We don't have any header to read or anything really, but
if we did, it would go here. We also might want to check
and be sure it's a valid file. */
struct opbx_filestream *tmp;
if ((tmp = malloc(sizeof(struct opbx_filestream))))
{
memset(tmp, 0, sizeof(struct opbx_filestream));
if (opbx_mutex_lock(&h264_lock))
{
opbx_log(LOG_WARNING, "Unable to lock h264 list\n");
free(tmp);
return NULL;
}
tmp->f = f;
glistcnt++;
opbx_mutex_unlock(&h264_lock);
opbx_update_use_count();
}
else
{
opbx_log(LOG_WARNING, "Out of memory\n");
}
return tmp;
}
static char *h264_getcomment(struct opbx_filestream *s)
{
return NULL;
}
int load_module(void)
{
return opbx_format_register(name,
exts,
OPBX_FORMAT_H264,
h264_open,
h264_rewrite,
h264_write,
h264_seek,
h264_trunc,
h264_tell,
h264_read,
h264_close,
h264_getcomment);
}
int unload_module(void)
{
return opbx_format_unregister(name);
}
int usecount()
{
return glistcnt;
}
char *description()
{
return desc;
}
i compile it by executing in formats/ directory the following (actually the grep from build log sed`ed a bit):
/bin/sh ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -include ../include/confdefs.h -I. -I../include -I../include -g -O2 -I/home/buildfarm/cw/nopatch/spandsp/src/ -MT format_h264.lo -MD -MP -MF .deps/format_h264.Tpo -c -o format_h264.lo format_h264.c
echo -e "\n\n$?\n\n"
gcc -DHAVE_CONFIG_H -include ../include/confdefs.h -I. -I../include -I../include -g -O2 -I/home/buildfarm/cw/nopatch/spandsp/src/ -MT format_h264.lo -MD -MP -MF .deps/format_h264.Tpo -c format_h264.c -fPIC -DPIC -o .libs/format_h264.o
echo -e "\n\n$?\n\n"
mv -f .deps/format_h264.Tpo .deps/format_h264.Plo
echo -e "\n\n$?\n\n"
/bin/sh ../libtool --tag=CC --mode=link gcc -g -O2 -I/home/buildfarm/cw/nopatch/spandsp/src/ -module -avoid-version -no-undefined -L/usr/lib/ -o format_h264.la -rpath /usr/lib/callweaver/modules format_h264.lo ../corelib/libcallweaver.la -lrt -lresolv -lpthread -lnsl -lreadline -lncurses -lm -ldb -lc
echo -e "\n\n$?\n\n"
rm -fr .libs/format_h264.la .libs/format_h264.lai .libs/format_h264.so .libs/format_h264.soT
echo -e "\n\n$?\n\n"
gcc -shared .libs/format_h264.o -Wl,--rpath -Wl,/home/buildfarm/cw/nopatch/callweaver/corelib/.libs -Wl,--rpath -Wl,/usr/lib/callweaver -L/usr/lib/ ../corelib/.libs/libcallweaver.so -lrt -lresolv -lpthread -lnsl -lreadline -lncurses -lm -ldb -lc -Wl,-soname -Wl,format_h264.so -o .libs/format_h264.so
echo -e "\n\n$?\n\n"
(cd .libs && rm -f format_h264.la && ln -s ../format_h264.la format_h264.la)
echo -e "\n\n$?\n\n"
/bin/sh ../libtool --mode=install /usr/bin/ginstall -c 'format_h264.la' '/home/buildfarm/cw/nopatch/callweaver-package//usr/lib/callweaver/modules/format_h264.la'
echo -e "\n\n$?\n\n"
(cd /home/buildfarm/cw/nopatch/callweaver/formats; /bin/sh ../libtool --tag=CC --mode=relink gcc -g -O2 -I/home/buildfarm/cw/nopatch/spandsp/src/ -module -avoid-version -no-undefined -L/usr/lib/ -o format_h264.la -rpath /usr/lib/callweaver/modules format_h264.lo ../corelib/libcallweaver.la -lrt -lresolv -lpthread -lnsl -lreadline -lncurses -lm -ldb -lc -inst-prefix-dir /home/buildfarm/cw/nopatch/callweaver-package/)
echo -e "\n\n$?\n\n"
gcc -shared .libs/format_h264.o -Wl,--rpath -Wl,/usr/lib/callweaver -L/usr/lib/ -L/home/buildfarm/cw/nopatch/callweaver-package//usr/lib/callweaver -L/usr/lib/callweaver -lcallweaver -lrt -lresolv -lpthread -lnsl -lreadline -lncurses -lm -ldb -lc -Wl,-soname -Wl,format_h264.so -o .libs/format_h264.so
echo -e "\n\n$?\n\n"
I can`t get why it does not work at me.
If it works at somebody, please tell me.