7 Jul 14:38
[PATCH] Add Dirac support to ffmpeg
Anuradha Suraparaju <anuradha <at> rd.bbc.co.uk>
2005-07-07 12:38:23 GMT
2005-07-07 12:38:23 GMT
**Dirac patch for ffmpeg
**Tested with ffmpeg cvs (as of July 7, 2007 10:00am) and
FFMpeg-20050707
**Author(s): Andrew Kennedy (dirac_dev <at> users.sourceforge.net) (main)
Anuradha Suraparaju (asuraparaju <at> users.sourceforge.net)
(minor mods)
Dirac is an open-source video codec currently under development. Both
the encoder and decoder have been integrated with ffmpeg. This patch is
only a basic integration such that only the salient paremeters are
currently passed from ffmpeg to Dirac. As Dirac develops, especially
with the integration of a formalised bit-stream syntax, then more
complex screnarios can be dealt with. Encoded Dirac files, with the
right patch, can be played back using MPlayer.
Please feel free to modify/add-to the code.
These are the instructions for enabling Dirac support in ffmpeg source
code.
1. Download Dirac from sourceforge and build and install Dirac
cvs -d:pserver:anonymous <at> cvs.sourceforge.net:/cvsroot/dirac login
cvs -z3 -d:pserver:anonymous <at> cvs.sourceforge.net:/cvsroot/dirac co
-P compress
cd compress
./bootstrap
./configure
make
make install
The last step installs the Dirac share encoder and decoder libraries
in /usr/local/lib (which is the default install point).
2. Download ffmpeg from cvs
cvs -z9 -d:pserver:anonymous <at> mplayerhq.hu:/cvsroot/ffmpeg co ffmpeg
3. Apply the patch
cd ffmpeg
patch -p1 < ffmpeg-cvs-dirac-patch.txt
4. Build and Install
./configure --enable-dirac
make
make install
The option '--enable-dirac' must be used during configuration in order
to pick-up the Dirac code during building.
Sample Usage: (encoding)
ffmpeg -s 720x576 -i input_file.yuv -vcodec dirac -qscale 15 -f rawvideo
dirac_output.drc
The output from the encoder is exactly as it is written to the .drc
encoded file ( hence the '-f rawvideo' output). Dirac bit-rate is
controlled by a quality-factor (currently a basic intepretation from
qscale. A qscale of 1 maps to dirac quality factor 10 and 30 maps to
quality factor 1). Dirac bitstreams can be wrapped in avi by using the
-f avi option.
(decoding)
ffmpeg -i input.drc output.yuv
Regards
Anuradha
--
diff -ruN --exclude CVS ffmpeg-cvs/configure ffmpeg-cvs-dirac/configure
--- ffmpeg-cvs/configure 2005-06-28 23:46:35.000000000 +0100
+++ ffmpeg-cvs-dirac/configure 2005-07-07 12:06:37.284376030 +0100
@@ -39,6 +39,7 @@
echo " --enable-pthreads use pthreads [default=no]"
echo " --enable-dc1394 enable IIDC-1394 grabbing using libdc1394 and libraw1394 [default=no]"
echo " --enable-gpl allow use of gpl code, the resulting libav* and ffmpeg will be under gpl [default=no]"
+echo " --enable-dirac enable dirac codec support via libdirac_encoder/decoder [default=no]"
echo ""
echo "Advanced options (experts only):"
echo " --source-path=PATH path of source code [$source_path]"
@@ -216,6 +217,7 @@
amr_if2="no"
sunmlib="no"
pthreads="no"
+dirac="no"
gpl="no"
memalignhack="no"
@@ -519,6 +521,8 @@
;;
--enable-pthreads) pthreads="yes"
;;
+ --enable-dirac) dirac="yes"
+ ;;
--enable-gpl) gpl="yes"
;;
--enable-memalign-hack) memalignhack="yes"
@@ -536,6 +540,14 @@
esac
done
+if test "$dirac" = "yes" ; then
+ `pkg-config --cflags dirac` `pkg-config --libs dirac` -lstdc++ > /dev/null 2>&1
+ if test $? = 0 ; then
+ echo "Could not find dirac on system."
+ dirac="no"
+ fi
+fi
+
if test "$theora" = "yes" ; then
if test "$libogg" = "no"; then
echo "libogg must be enabled to enable Theora"
@@ -1193,6 +1205,7 @@
echo "shared pp $shared_pp"
echo "Video hooking $vhook"
echo "SDL support $sdl"
+echo "dirac enabled $dirac"
if test $sdl_too_old = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have FFplay/SDL support"
fi
@@ -1602,6 +1615,13 @@
echo "CONFIG_FFPLAY=yes" >> config.mak
fi
+if test "$dirac" = "yes" ; then
+ echo "#define CONFIG_DIRAC 1" >> $TMPH
+ echo "CONFIG_DIRAC=yes" >> config.mak
+ echo "DIRAC_INC=`pkg-config --cflags dirac`" >> config.mak
+ echo "DIRAC_LIB="`pkg-config --libs dirac` -lstdc++"" >> config.mak
+fi
+
if test "$gpl" = "yes" ; then
echo "#define CONFIG_GPL 1" >> $TMPH
echo "CONFIG_GPL=yes" >> config.mak
diff -ruN --exclude CVS ffmpeg-cvs/libavcodec/allcodecs.c ffmpeg-cvs-dirac/libavcodec/allcodecs.c
--- ffmpeg-cvs/libavcodec/allcodecs.c 2005-06-03 14:59:38.000000000 +0100
+++ ffmpeg-cvs-dirac/libavcodec/allcodecs.c 2005-07-07 12:07:30.280653866 +0100
@@ -512,6 +512,14 @@
#endif //CONFIG_ENCODERS
#endif /* AMR_WB */
+/* dirac codec */
+#ifdef CONFIG_DIRAC
+ register_avcodec(&dirac_decoder);
+#ifdef CONFIG_ENCODERS
+ register_avcodec(&dirac_encoder);
+#endif
+#endif
+
/* pcm codecs */
#ifdef CONFIG_ENCODERS
diff -ruN --exclude CVS ffmpeg-cvs/libavcodec/avcodec.h ffmpeg-cvs-dirac/libavcodec/avcodec.h
--- ffmpeg-cvs/libavcodec/avcodec.h 2005-06-28 23:46:36.000000000 +0100
+++ ffmpeg-cvs-dirac/libavcodec/avcodec.h 2005-07-07 12:07:45.777103337 +0100
@@ -180,6 +180,9 @@
CODEC_ID_DVD_SUBTITLE= 0x17000,
CODEC_ID_DVB_SUBTITLE,
+ CODEC_ID_DIRAC = 0x18000,
+
+
CODEC_ID_MPEG2TS= 0x20000, /* _FAKE_ codec to indicate a raw MPEG2 transport
stream (only used by libavformat) */
};
@@ -1954,6 +1957,7 @@
extern AVCodec sonic_ls_encoder;
extern AVCodec svq1_encoder;
extern AVCodec x264_encoder;
+extern AVCodec dirac_encoder;
extern AVCodec h263_decoder;
extern AVCodec h261_decoder;
@@ -2055,6 +2059,7 @@
extern AVCodec fraps_decoder;
extern AVCodec libgsm_encoder;
extern AVCodec libgsm_decoder;
+extern AVCodec dirac_decoder;
/* pcm codecs */
#define PCM_CODEC(id, name) \
diff -ruN --exclude CVS ffmpeg-cvs/libavcodec/dirac.c ffmpeg-cvs-dirac/libavcodec/dirac.c
--- ffmpeg-cvs/libavcodec/dirac.c 1970-01-01 01:00:00.000000000 +0100
+++ ffmpeg-cvs-dirac/libavcodec/dirac.c 2005-07-07 12:07:51.400177835 +0100
@@ -0,0 +1,510 @@
+/**
+ * @file dirac.c
+ * Dirac codec support via dirac_encoder.
+ * @author Andrew Kennedy <dirac <at> rd.bbc.co.uk>
+ * www.sourceforge.net/projects/dirac
+ *
+ * This file is part of libavcodec.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "avcodec.h"
+
+#undef NDEBUG
+#include <assert.h>
+
+
+#include <libdirac_encoder/dirac_encoder.h>
+#include <libdirac_decoder/dirac_parser.h>
+
+/** ffmpeg qscale to Dirac quality conversion table */
+static const uint8_t quality_factor_conv[] = {10.0, 9.8, 9.6, 9.4, 9.2, 9.0, 8.8, 8.6, 8.4, 8.2, 8.0,
7.8, 7.6, 7.3, 7.0, 6.7, 6.4, 6.0, 5.6, 5.2, 4.8,
+ 4.4, 4.0, 3.6, 3.2, 2.8, 2.4, 2.0, 1.6, 1.2, 1.0 };
+
+/** contains a single frame returned from Dirac*/
+typedef struct FfmpegDiracOutputFrame
+{
+ /** frame data */
+ unsigned char *p_data;
+
+ /** frame size */
+ int size;
+
+ /** frame type */
+ int type;
+
+ /** next frame to be output in sequence */
+ struct FfmpegDiracOutputFrame *p_next_frame;
+
+ } FfmpegDiracOutputFrame;
+
+typedef struct FfmpegDiracParams {
+
+ /* context params */
+ dirac_encoder_context_t enc_ctx;
+
+ /* frame being encoded */
+ AVFrame picture;
+
+ /* decoder */
+ dirac_decoder_t* p_decoder;
+
+ /* encoder */
+ dirac_encoder_t* p_encoder;
+
+ /* input frame buffer */
+ unsigned char *p_in_frame_buf;
+
+ /** output frame buf */
+ unsigned char* p_out_frame_buf;
+
+ /** next frame to be output*/
+ struct FfmpegDiracOutputFrame *p_next_output_frame;
+
+ /** last frame to be output*/
+ struct FfmpegDiracOutputFrame *p_last_output_frame;
+
+} FfmpegDiracParams;
+
+
+/**
+* Works out Dirac-compatible pre-set option from file size
+*/
+dirac_encoder_presets_t GetDiracPreset(AVCodecContext *avccontext)
+{
+
+ if(avccontext->width==720 && avccontext->height==576)
+ return SD576;
+
+ if(avccontext->height==1280 && avccontext->height==720)
+ return HD720;
+
+ if(avccontext->height==1920 && avccontext->width==1080)
+ return HD1080;
+
+ if(avccontext->height==352 && avccontext->width==288)
+ return CIF;
+
+ return CIF;
+}
+
+/**
+* Works out Dirac-compatible chroma format
+*/
+ dirac_chroma_t GetDiracChromaFormat(AVCodecContext *avccontext)
+ {
+
+ switch(avccontext->pix_fmt)
+ {
+ case PIX_FMT_YUV420P:
+ return format420;
+
+ case PIX_FMT_YUV422P:
+ return format422;
+
+ case PIX_FMT_YUV444P:
+ return format444;
+
+ case PIX_FMT_YUV411P:
+ return format411;
+
+ default:
+ av_log (avccontext, AV_LOG_ERROR, "this codec supports only YUV420P\n");
+ return format420;
+
+ }
+
+ return format420;
+
+ }
+
+ /**
+ * returns Ffmppeg chroma format
+ */
+ int GetFfmpegChromaFormat(dirac_chroma_t dirac_chroma)
+ {
+ switch(dirac_chroma)
+ {
+ case format420:
+ return PIX_FMT_YUV420P;
+ case format422:
+ return PIX_FMT_YUV422P;
+ case format444:
+ return PIX_FMT_YUV444P;
+ case format411:
+ return PIX_FMT_YUV411P;
+
+ default:
+ return PIX_FMT_YUV420P;
+ }
+
+ return PIX_FMT_YUV420P;
+ }
+
+
+ /**
+ * Calculates total size of frame
+ */
+int GetFrameBufferSize (const dirac_encoder_context_t* p_enc_ctx)
+{
+
+ int xl = p_enc_ctx->seq_params.width;
+ int yl = p_enc_ctx->seq_params.height;
+
+ int size;
+
+ switch (p_enc_ctx->seq_params.chroma)
+ {
+ case format411:
+ case format420:
+ size = (xl*yl*3)/2;
+ break;
+ case format422:
+ size = (xl*yl)*2;
+ break;
+ case format444:
+ size = (xl*yl)*3;
+ break;
+ case Yonly:
+ default:
+ size = xl * yl;
+ break;
+ }
+ return size;
+}
+
+static int dirac_encode_init(AVCodecContext *avccontext) {
+
+ FfmpegDiracParams* p_dirac_params = avccontext->priv_data;
+ int no_local=0;
+ int i;
+ int verbose=avccontext->debug;
+
+ /** get dirac preset*/
+ dirac_encoder_presets_t preset = GetDiracPreset(avccontext);
+
+ /** set data to zero */
+ memset (p_dirac_params, 0, sizeof(FfmpegDiracParams));
+
+
+ /** initialise the encoder context */
+ dirac_encoder_context_init (&(p_dirac_params->enc_ctx), preset);
+
+ p_dirac_params->enc_ctx.seq_params.chroma=GetDiracChromaFormat(avccontext);
+ p_dirac_params->enc_ctx.seq_params.frame_rate.numerator=avccontext->time_base.den;
+ p_dirac_params->enc_ctx.seq_params.frame_rate.denominator=avccontext->time_base.num;
+ p_dirac_params->enc_ctx.seq_params.width=avccontext->width;
+ p_dirac_params->enc_ctx.seq_params.height=avccontext->height;
+
+ avccontext->frame_size = GetFrameBufferSize(&(p_dirac_params->enc_ctx));
+ avccontext->coded_frame= &p_dirac_params->picture;
+
+ if (no_local)
+ {
+ p_dirac_params->enc_ctx.decode_flag = 0;
+ p_dirac_params->enc_ctx.instr_flag = 0;
+ }
+ else
+ {
+ p_dirac_params->enc_ctx.decode_flag = 1;
+ p_dirac_params->enc_ctx.instr_flag = 1;
+ }
+
+ if(avccontext->global_quality!=0)
+ p_dirac_params->enc_ctx.enc_params.qf=quality_factor_conv[(avccontext->global_quality/FF_QP2LAMBDA)-1];
+
+ p_dirac_params->p_encoder = dirac_encoder_init( &(p_dirac_params->enc_ctx), verbose );
+
+
+
+ if (!p_dirac_params->p_encoder)
+ {
+ av_log(avccontext, AV_LOG_ERROR, "Unrecoverable Error: dirac_encoder_init failed. ");
+ return EXIT_FAILURE;
+ }
+
+
+ /** allocate enough memory for the incoming data */
+ p_dirac_params->p_in_frame_buf = (unsigned char*) av_malloc(avccontext->frame_size);
+
+ return 0 ;
+}
+
+
+static int dirac_encode_frame(AVCodecContext *avccontext,
+ unsigned char *frame,
+ int buf_size, void *data)
+{
+ int enc_size=0;
+ int frames_written = 0;
+ dirac_encoder_state_t state;
+ FfmpegDiracParams* p_dirac_params = avccontext->priv_data;
+ AVFrame* p_frame_src;
+ struct FfmpegDiracOutputFrame* p_frame_output=NULL;
+ struct FfmpegDiracOutputFrame* p_next_output_frame=NULL;
+
+
+ if(data==0)
+ {
+ /** look for any delayed frames at EOF*/
+ p_next_output_frame=p_dirac_params->p_next_output_frame;
+ if(p_next_output_frame==NULL)
+ {
+ /* get terminate data*/
+ p_dirac_params->p_encoder->enc_buf.buffer=frame;
+ p_dirac_params->p_encoder->enc_buf.size = buf_size;
+ if (dirac_encoder_end_sequence( p_dirac_params->p_encoder ) > 0)
+ return p_dirac_params->p_encoder->enc_buf.size;
+
+ return 0;
+ }
+
+
+ memcpy(frame, p_next_output_frame->p_data, p_next_output_frame->size);
+ enc_size=p_next_output_frame->size;
+
+ /*remove frame*/
+ p_dirac_params->p_next_output_frame=p_next_output_frame->p_next_frame;
+ av_free(p_next_output_frame->p_data);
+ av_free(p_next_output_frame);
+
+ return enc_size;
+ }
+
+ p_dirac_params->picture = *(AVFrame*)data;
+ p_frame_src=(AVFrame*)data;
+
+ /** allocate frame data to dirac input buffer */
+ /*
+ * input line size may differe from what the codec supports. Especially
+ * when transcoding from one format to another. So use avpicture_layout
+ * to copy the frame.
+ */
+ avpicture_layout ((AVPicture *)data, avccontext->pix_fmt, avccontext->width,
avccontext->height,p_dirac_params->p_in_frame_buf, avccontext->frame_size);
+
+ /** load next frame*/
+ if (dirac_encoder_load( p_dirac_params->p_encoder, p_dirac_params->p_in_frame_buf,
avccontext->frame_size ) < 0)
+ {
+ av_log(avccontext, AV_LOG_ERROR, "Unrecoverable Encoder Error. Quitting...\n");
+ return -1;
+ }
+
+
+ do {
+ p_dirac_params->p_encoder->enc_buf.buffer = frame;
+ p_dirac_params->p_encoder->enc_buf.size = buf_size;
+ /** process frame */
+ state = dirac_encoder_output ( p_dirac_params->p_encoder );
+
+ switch (state)
+ {
+ case ENC_STATE_AVAIL:
+ assert (p_dirac_params->p_encoder->enc_buf.size > 0);
+ /** create output frame*/
+ p_frame_output=(struct FfmpegDiracOutputFrame*)av_malloc(sizeof(FfmpegDiracOutputFrame));
+ memset(p_frame_output, 0, sizeof(FfmpegDiracOutputFrame));
+
+ /** set output data */
+ p_frame_output->p_data=(unsigned char*)av_malloc(p_dirac_params->p_encoder->enc_buf.size);
+ memcpy(p_frame_output->p_data,p_dirac_params->p_encoder->enc_buf.buffer,p_dirac_params->p_encoder->enc_buf.size);
+ p_frame_output->size=p_dirac_params->p_encoder->enc_buf.size;
+ p_frame_output->type=p_dirac_params->p_encoder->enc_fparams.ftype;
+ if(p_dirac_params->p_next_output_frame==NULL)
+ {
+ p_dirac_params->p_next_output_frame=p_frame_output;
+ p_dirac_params->p_last_output_frame=p_frame_output;
+ }
+ else
+ {
+ p_dirac_params->p_last_output_frame->p_next_frame=p_frame_output;
+ p_dirac_params->p_last_output_frame=p_frame_output;
+ }
+
+ break;
+
+ case ENC_STATE_BUFFER:
+ break;
+
+ case ENC_STATE_INVALID:
+ av_log(avccontext, AV_LOG_ERROR, "Unrecoverable Encoder Error. Quitting...\n");
+ return -1;
+ default:
+ av_log(avccontext, AV_LOG_ERROR, "Unknown Encoder state\n");
+ return -1;
+ }
+ }
+ while(state==ENC_STATE_AVAIL);
+
+ /* copy 'next' frame in queue */
+ p_next_output_frame=p_dirac_params->p_next_output_frame;
+ if(p_next_output_frame==NULL)
+ return 0;
+
+ memcpy(frame, p_next_output_frame->p_data, p_next_output_frame->size);
+ avccontext->coded_frame->key_frame= p_next_output_frame->type == I_frame;
+ avccontext->coded_frame->pts= 0;
+ enc_size=p_next_output_frame->size;
+
+ /*remove frame*/
+ p_dirac_params->p_next_output_frame=p_next_output_frame->p_next_frame;
+ av_free(p_next_output_frame->p_data);
+ av_free(p_next_output_frame);
+
+ return enc_size;
+}
+
+
+static int dirac_encode_close(AVCodecContext *avccontext) {
+
+
+ FfmpegDiracParams* p_dirac_params = avccontext->priv_data;
+
+ // close the encoder
+ dirac_encoder_close(p_dirac_params->p_encoder );
+
+ av_free(p_dirac_params->p_in_frame_buf);
+
+ return 0 ;
+}
+
+
+AVCodec dirac_encoder = {
+ "dirac",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_DIRAC,
+ sizeof(FfmpegDiracParams),
+ dirac_encode_init,
+ dirac_encode_frame,
+ dirac_encode_close,
+ .capabilities= CODEC_CAP_DELAY,
+} ;
+
+/**-----------------------------------------------------DECODER-----------------------------------------------------------------------------------------*/
+
+static int dirac_decode_init(AVCodecContext *avccontext) {
+
+ FfmpegDiracParams *p_dirac_params = (FfmpegDiracParams*)avccontext->priv_data ;
+ p_dirac_params->p_decoder = dirac_decoder_init(avccontext->debug);
+
+ if (!p_dirac_params->p_decoder)
+ return -1;
+
+ return 0 ;
+}
+
+static int dirac_decode_frame(AVCodecContext *avccontext,
+ void *data, int *data_size,
+ uint8_t *buf, int buf_size)
+{
+
+ FfmpegDiracParams *p_dirac_params=(FfmpegDiracParams*)avccontext->priv_data;
+ AVPicture *picture = (AVPicture*)data;
+ AVPicture pic;
+ int drop_frame, framedrop, pict_size;
+ unsigned char *buffer[3];
+
+ if(buf_size<=0)
+ return 0; /** skipped null frame */
+
+ /** set data to decode into buffer */
+ dirac_buffer (p_dirac_params->p_decoder, buf, buf+buf_size);
+ while (1)
+ {
+ /** parse data and process result */
+ DecoderState state = dirac_parse (p_dirac_params->p_decoder);
+ switch (state)
+ {
+ case STATE_BUFFER:
+ return 0;
+
+ case STATE_SEQUENCE:
+
+ /** tell ffmpeg about sequence details*/
+ avccontext->height=p_dirac_params->p_decoder->seq_params.height;
+ avccontext->width=p_dirac_params->p_decoder->seq_params.width;
+ avccontext->pix_fmt=GetFfmpegChromaFormat(p_dirac_params->p_decoder->seq_params.chroma);
+ avccontext->time_base.den =p_dirac_params->p_decoder->seq_params.frame_rate.numerator;
+ avccontext->time_base.num =p_dirac_params->p_decoder->seq_params.frame_rate.denominator;
+
+ /** calc output dimensions */
+ avpicture_fill(&pic, NULL, avccontext->pix_fmt, avccontext->width, avccontext->height);
+ pict_size = avpicture_get_size(avccontext->pix_fmt, avccontext->width, avccontext->height);
+
+ /** allocate output buffer */
+ p_dirac_params->p_out_frame_buf = (unsigned char *)av_malloc (pict_size);
+ buffer[0]=p_dirac_params->p_out_frame_buf;
+ buffer[1]=p_dirac_params->p_out_frame_buf+(pic.linesize[0]*avccontext->height);
+ buffer[2]=buffer[1]+(pic.linesize[1]*p_dirac_params->p_decoder->seq_params.chroma_height);
+
+ /** tell dirac about output destination */
+ dirac_set_buf(p_dirac_params->p_decoder, buffer, NULL);
+ break;
+
+ case STATE_SEQUENCE_END:
+ break;
+
+ case STATE_PICTURE_AVAIL:
+ /** fill pic with current buffer data from dirac*/
+ avpicture_fill(picture, p_dirac_params->p_out_frame_buf, avccontext->pix_fmt,
avccontext->width, avccontext->height);
+ *data_size=1;
+ return buf_size;
+
+ case STATE_PICTURE_START:
+ break;
+
+ case STATE_INVALID:
+ return -1;
+
+ default:
+ break;
+ }
+ }
+
+
+ return 0;
+
+
+}
+
+
+static int dirac_decode_close(AVCodecContext *avccontext) {
+
+ FfmpegDiracParams *p_dirac_params=(FfmpegDiracParams*)avccontext->priv_data;
+
+ dirac_decoder_close (p_dirac_params->p_decoder);
+
+ av_free(p_dirac_params->p_out_frame_buf);
+
+ return 0 ;
+}
+
+
+AVCodec dirac_decoder = {
+ "dirac",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_DIRAC,
+ sizeof(FfmpegDiracParams),
+ dirac_decode_init,
+ NULL,
+ dirac_decode_close,
+ dirac_decode_frame,
+ CODEC_CAP_DELAY
+} ;
+
+
+
+
diff -ruN --exclude CVS ffmpeg-cvs/libavcodec/Makefile ffmpeg-cvs-dirac/libavcodec/Makefile
--- ffmpeg-cvs/libavcodec/Makefile 2005-06-27 01:55:28.000000000 +0100
+++ ffmpeg-cvs-dirac/libavcodec/Makefile 2005-07-07 12:09:02.637452308 +0100
@@ -291,6 +291,12 @@
EXTRALIBS += -logg
endif
+ifeq ($(CONFIG_DIRAC),yes)
+OBJS += dirac.o
+EXTRALIBS += $(DIRAC_LIB)
+CFLAGS += $(DIRAC_INC)
+endif
+
ifeq ($(CONFIG_LIBGSM),yes)
OBJS += libgsm.o
EXTRALIBS += -lgsm
diff -ruN --exclude CVS ffmpeg-cvs/libavformat/allformats.c ffmpeg-cvs-dirac/libavformat/allformats.c
--- ffmpeg-cvs/libavformat/allformats.c 2005-06-25 10:04:08.000000000 +0100
+++ ffmpeg-cvs-dirac/libavformat/allformats.c 2005-07-07 12:09:23.502017843 +0100
@@ -109,6 +109,10 @@
ea_init();
nsvdec_init();
+#ifdef CONFIG_DIRAC
+ drc_init();
+#endif
+
#ifdef CONFIG_ENCODERS
/* image formats */
#if 0
diff -ruN --exclude CVS ffmpeg-cvs/libavformat/avienc.c ffmpeg-cvs-dirac/libavformat/avienc.c
--- ffmpeg-cvs/libavformat/avienc.c 2005-06-26 21:26:47.000000000 +0100
+++ ffmpeg-cvs-dirac/libavformat/avienc.c 2005-07-07 12:09:34.226252520 +0100
@@ -185,6 +185,7 @@
{ CODEC_ID_INDEO2, MKTAG('R', 'T', '2', '1') },
{ CODEC_ID_FRAPS, MKTAG('F', 'P', 'S', '1') },
{ CODEC_ID_THEORA, MKTAG('t', 'h', 'e', 'o') },
+ { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
{ CODEC_ID_RAWVIDEO, 0 },
{ 0, 0 },
};
diff -ruN --exclude CVS ffmpeg-cvs/libavformat/drc.c ffmpeg-cvs-dirac/libavformat/drc.c
--- ffmpeg-cvs/libavformat/drc.c 1970-01-01 01:00:00.000000000 +0100
+++ ffmpeg-cvs-dirac/libavformat/drc.c 2005-07-07 12:09:39.216431075 +0100
@@ -0,0 +1,300 @@
+/**
+ * @file drc.c
+ * Dirac streaming support
+ * @author Andrew Kennedy <dirac <at> rd.bbc.co.uk>
+ * www.sourceforge.net/projects/dirac
+ *
+ * This file is part of libavformat.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+
+#include "avformat.h"
+
+#undef NDEBUG
+#include <assert.h>
+
+
+typedef struct FfmpegDrcParams {
+
+ /** in initialization mode? */
+ int initializing;
+
+ /** sequence data */
+ char *p_seq_buf;
+
+ /** size of sequence buffer */
+ int seq_size;
+
+} FfmpegDrcParams ;
+
+
+
+static int drc_write_header(AVFormatContext *avfcontext)
+{
+
+ return 0 ;
+}
+
+static int drc_write_packet(AVFormatContext *avfcontext, AVPacket *pkt)
+{
+
+ put_buffer(&avfcontext->pb, pkt->data, pkt->size);
+ put_flush_packet(&avfcontext->pb);
+
+
+ return 0;
+}
+
+
+static int drc_write_trailer(AVFormatContext *avfcontext) {
+
+
+
+
+ return 0 ;
+}
+
+
+static AVOutputFormat drc_oformat = {
+ "drc",
+ "Dirac",
+ "",
+ "drc",
+ sizeof(FfmpegDrcParams),
+ 0,
+ CODEC_ID_DIRAC,
+ drc_write_header,
+ drc_write_packet,
+ drc_write_trailer,
+} ;
+
+
+/**------------------------------------------------------------input---------------------------------------------------------------------*/
+
+static int drc_read_header(AVFormatContext *avfcontext, AVFormatParameters *ap)
+{
+ AVStream *st;
+ FfmpegDrcParams *p_drc_params = (FfmpegDrcParams*)avfcontext->priv_data;
+
+ memset(p_drc_params, sizeof(FfmpegDrcParams), 0);
+
+ /** create new stream */
+ st = av_new_stream(avfcontext, 0);
+ st->codec.codec_type = CODEC_TYPE_VIDEO;
+ st->codec.codec_id = CODEC_ID_DIRAC;
+ st->start_time = 0;
+
+ p_drc_params->initializing=1;
+
+ return 0 ;
+}
+
+
+#define DIRAC_VIDEOBUFFER_SIZE 0x100000
+static unsigned char* dirac_videobuffer = 0;
+static int dirac_videobuf_len =0;
+static unsigned char dirac_videobuf_code[5];
+static int dirac_videobuf_code_len = 0;
+
+int dirac_sync_video_packet (ByteIOContext *p_byte_context)
+{
+ int skipped = 0;
+ dirac_videobuf_len = 0;
+ while(dirac_videobuf_code_len<5)
+ {
+ dirac_videobuf_code[dirac_videobuf_code_len++]=url_fgetc(p_byte_context);
+ }
+ while (1)
+ {
+ int c;
+ if(dirac_videobuf_code[0]==0x42 && dirac_videobuf_code[1]==0x42 &&
dirac_videobuf_code[2]==0x43 && dirac_videobuf_code[3]==0x44)
+ {
+ break;
+ }
+ ++skipped;
+ dirac_videobuffer[0] = dirac_videobuf_code[0]=dirac_videobuf_code[1];
+ dirac_videobuffer[1] = dirac_videobuf_code[1]=dirac_videobuf_code[2];
+ dirac_videobuffer[2] = dirac_videobuf_code[2]=dirac_videobuf_code[3];
+ dirac_videobuffer[3] = dirac_videobuf_code[3]=dirac_videobuf_code[4];
+ c = url_fgetc(p_byte_context);
+ if (c < 0 )
+ return 0;
+ dirac_videobuffer[4] = dirac_videobuf_code[4]=c;
+ dirac_videobuf_len = 5;
+ }
+
+
+ return dirac_videobuf_code[4];
+}
+
+/** RAP Frame start = 0xD7
+ Non-RAP I Frame start = 0xD6
+ L1 Frame start = 0xD4
+ L2 Frame start = 0xD7*/
+#define FRAME_START(c) ((c) == 0xD4 || (c) == 0xD5 || (c) == 0xD6 || (c) == 0xD7)
+
+static int drc_read_packet(AVFormatContext *avfcontext, AVPacket *pkt) {
+
+ int in_frame = 0;
+ int offset=0;
+ unsigned char* start;
+ unsigned int shift = 0xffffffff;
+ int msg_type = 0xFF;
+ dirac_videobuf_len=0;
+ FfmpegDrcParams *p_drc_params = (FfmpegDrcParams*)avfcontext->priv_data ;
+
+ if (!dirac_videobuffer)
+ {
+ dirac_videobuffer = (unsigned char *)av_malloc(DIRAC_VIDEOBUFFER_SIZE);
+ if(!dirac_videobuffer)
+ {
+ return 0;
+ }
+ }
+
+ start = dirac_videobuffer;
+
+ /** if we have any valid sequence data, then need to send to decoder */
+ if(p_drc_params->initializing==0 && p_drc_params->seq_size > 0)
+ {
+ memcpy(start, p_drc_params->p_seq_buf, p_drc_params->seq_size);
+ dirac_videobuf_len+=p_drc_params->seq_size;
+ av_free(p_drc_params->p_seq_buf);
+ p_drc_params->seq_size=0;
+ }
+
+ /** find start of data */
+ while (msg_type != 0 && msg_type == 0xFF)
+ msg_type = dirac_sync_video_packet(&avfcontext->pb);
+
+ if (msg_type == 0)
+ return -1;
+
+ /* find start of frame */
+ while (!in_frame)
+ {
+ int byte;
+ if (FRAME_START(msg_type))
+ {
+ in_frame = 1;
+ break;
+ }
+
+ byte = url_fgetc(&avfcontext->pb);
+ if (byte < 0)
+ {
+ dirac_videobuf_code_len = 0;
+ if (dirac_videobuf_len)
+ return dirac_videobuf_len;
+ else
+ return -1;
+ }
+
+ dirac_videobuffer[dirac_videobuf_len++] = byte;
+ if (shift == 0x42424344)
+ {
+ if (FRAME_START(byte))
+ {
+ in_frame = 1;
+ break;
+ }
+ }
+ shift = (shift << 8 ) | byte;
+ }
+
+ /* find end of frame */
+ shift = 0xffffffff;
+ dirac_videobuf_code_len = 0;
+ while (in_frame)
+ {
+ int byte;
+ byte = url_fgetc(&avfcontext->pb);
+ if (byte < 0)
+ return dirac_videobuf_len;
+
+ dirac_videobuffer[dirac_videobuf_len++] = byte;
+ if (shift == 0x42424344)
+ {
+ if (byte != 0xFF)
+ {
+ in_frame = 0;
+ dirac_videobuf_code_len = 5;
+ dirac_videobuf_code[0] = 0x42;
+ dirac_videobuf_code[1] = 0x42;
+ dirac_videobuf_code[2] = 0x43;
+ dirac_videobuf_code[3] = 0x44;
+ dirac_videobuf_code[4] = byte;
+ break;
+ }
+ }
+ shift = (shift << 8 ) | byte;
+ }
+
+ if (av_new_packet(pkt, dirac_videobuf_len))
+ return AVERROR_IO;
+
+ pkt->stream_index = 0;
+
+
+
+ /** reset input buffer to beggining if we are still initialzing*/
+ if(p_drc_params->initializing)
+ {
+ p_drc_params->p_seq_buf=(unsigned char *)av_malloc(dirac_videobuf_len);
+ memcpy(p_drc_params->p_seq_buf,start, pkt->size);
+ p_drc_params->seq_size=dirac_videobuf_len;
+ p_drc_params->initializing=0;
+ }
+
+ memcpy(pkt->data, start, dirac_videobuf_len);
+
+ return dirac_videobuf_len;
+}
+
+
+static int drc_read_close(AVFormatContext *avfcontext) {
+
+ av_free(dirac_videobuffer);
+ dirac_videobuffer=0;
+
+ return 0;
+ }
+
+
+static AVInputFormat drc_iformat = {
+ "drc",
+ "Dirac",
+ sizeof(FfmpegDrcParams),
+ NULL,
+ drc_read_header,
+ drc_read_packet,
+ drc_read_close,
+ .extensions = "drc",
+} ;
+
+
+int drc_init(void) {
+
+#ifdef CONFIG_ENCODERS
+ av_register_output_format(&drc_oformat) ;
+#endif
+ av_register_input_format(&drc_iformat);
+
+ return 0 ;
+}
+
diff -ruN --exclude CVS ffmpeg-cvs/libavformat/Makefile ffmpeg-cvs-dirac/libavformat/Makefile
--- ffmpeg-cvs/libavformat/Makefile 2005-06-27 01:55:28.000000000 +0100
+++ ffmpeg-cvs-dirac/libavformat/Makefile 2005-07-07 12:09:57.147484318 +0100
@@ -36,6 +36,12 @@
OBJS+= avio.o aviobuf.o file.o
OBJS+= framehook.o
+ifeq ($(CONFIG_DIRAC),yes)
+ OBJS+= drc.o
+ EXTRALIBS+=$(DIRAC_LIB)
+ CFLAGS+=$(DIRAC_INC)
+endif
+
ifeq ($(CONFIG_VIDEO4LINUX),yes)
OBJS+= grab.o
endif
diff -ruN --exclude CVS ffmpeg-cvs/libavformat/utils.c ffmpeg-cvs-dirac/libavformat/utils.c
--- ffmpeg-cvs/libavformat/utils.c 2005-07-05 10:07:51.000000000 +0100
+++ ffmpeg-cvs-dirac/libavformat/utils.c 2005-07-07 12:10:08.226665393 +0100
@@ -1914,6 +1914,7 @@
st->codec.codec_id == CODEC_ID_H263 ||
st->codec.codec_id == CODEC_ID_H261 ||
st->codec.codec_id == CODEC_ID_VORBIS ||
+ st->codec.codec_id == CODEC_ID_DIRAC ||
st->codec.codec_id == CODEC_ID_MJPEG ||
st->codec.codec_id == CODEC_ID_PNG ||
st->codec.codec_id == CODEC_ID_PAM ||
diff -ruN --exclude CVS ffmpeg-cvs/Makefile ffmpeg-cvs-dirac/Makefile
--- ffmpeg-cvs/Makefile 2005-05-08 16:04:59.000000000 +0100
+++ ffmpeg-cvs-dirac/Makefile 2005-07-07 12:06:56.147271632 +0100
@@ -65,6 +65,11 @@
EXTRALIBS+=-lfaac
endif
+ifeq ($(CONFIG_DIRAC),yes)
+EXTRALIBS+=$(DIRAC_LIB)
+CFLAGS+=$(DIRAC_INC)
+endif
+
ifeq ($(CONFIG_XVID),yes)
EXTRALIBS+=-lxvidcore
endif
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel <at> mplayerhq.hu http://mplayerhq.hu/mailman/listinfo/ffmpeg-devel
RSS Feed