All pastes #964689 Raw Edit

Something

public text v1 · immutable
#964689 ·published 2008-03-31 13:38 UTC
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.