diff -ruN ffmpeg-0.4.9-pre1/configure ffmpeg-0.4.9-pre1-patch/configure --- ffmpeg-0.4.9-pre1/configure 2004-07-05 19:06:16.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/configure 2005-08-19 12:13:18.000000000 +0100 @@ -31,6 +31,7 @@ echo " --enable-sunmlib use Sun medialib [default=no]" echo " --enable-pthreads use pthreads [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]" @@ -178,6 +179,7 @@ amr_nb_fixed="no" sunmlib="no" pthreads="no" +dirac="no" gpl="no" memalignhack="no" @@ -427,6 +429,8 @@ ;; --enable-pthreads) pthreads="yes" ;; + --enable-dirac) dirac="yes" + ;; --enable-gpl) gpl="yes" ;; --enable-memalign-hack) memalignhack="yes" @@ -434,6 +438,15 @@ 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 "$gpl" != "yes"; then if test "$pp" != "no" -o "$shared_pp" != "no"; then echo "The Postprocessing code is under GPL and --enable-gpl is not specified" @@ -979,6 +992,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 @@ -1316,6 +1330,13 @@ echo "CONFIG_RISKY=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 ffmpeg-0.4.9-pre1/ffmpeg.c ffmpeg-0.4.9-pre1-patch/ffmpeg.c --- ffmpeg-0.4.9-pre1/ffmpeg.c 2004-07-05 20:19:04.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/ffmpeg.c 2005-08-19 12:13:18.000000000 +0100 @@ -2948,6 +2948,7 @@ video_enc->gop_size = 0; if (video_qscale || same_quality) { video_enc->flags |= CODEC_FLAG_QSCALE; + video_enc->global_quality = st->quality = FF_QP2LAMBDA * video_qscale; } diff -ruN ffmpeg-0.4.9-pre1/libavcodec/allcodecs.c ffmpeg-0.4.9-pre1-patch/libavcodec/allcodecs.c --- ffmpeg-0.4.9-pre1/libavcodec/allcodecs.c 2004-06-16 03:53:12.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/libavcodec/allcodecs.c 2005-08-19 12:13:18.000000000 +0100 @@ -174,6 +174,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 ffmpeg-0.4.9-pre1/libavcodec/avcodec.h ffmpeg-0.4.9-pre1-patch/libavcodec/avcodec.h --- ffmpeg-0.4.9-pre1/libavcodec/avcodec.h 2004-07-09 13:49:55.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/libavcodec/avcodec.h 2005-08-19 12:13:18.000000000 +0100 @@ -136,6 +136,8 @@ CODEC_ID_INTERPLAY_DPCM, CODEC_ID_XAN_DPCM, + CODEC_ID_DIRAC, + CODEC_ID_FLAC, CODEC_ID_MPEG2TS, /* _FAKE_ codec to indicate a raw MPEG2 transport @@ -1747,7 +1749,8 @@ extern AVCodec mdec_encoder; extern AVCodec zlib_encoder; extern AVCodec svq1_encoder; - +extern AVCodec dirac_encoder; +extern AVCodec dirac_decoder; extern AVCodec h263_decoder; extern AVCodec h261_decoder; extern AVCodec mpeg4_decoder; diff -ruN ffmpeg-0.4.9-pre1/libavcodec/dirac.c ffmpeg-0.4.9-pre1-patch/libavcodec/dirac.c --- ffmpeg-0.4.9-pre1/libavcodec/dirac.c 1970-01-01 01:00:00.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/libavcodec/dirac.c 2005-08-19 12:18:42.000000000 +0100 @@ -0,0 +1,510 @@ +/** + * @file dirac.c + * Dirac codec support via dirac_encoder. + * @author Andrew Kennedy + * 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 Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "avcodec.h" + +#undef NDEBUG +#include + + +#include +#include + +/** ffmpeg qscale to Dirac quality conversion table */ +static const float 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->frame_rate; + p_dirac_params->enc_ctx.seq_params.frame_rate.denominator=avccontext->frame_rate_base; + 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 buf_size; + + 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->frame_rate=p_dirac_params->p_decoder->seq_params.frame_rate.numerator; + avccontext->frame_rate_base=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 buf_size; + + +} + + +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 ffmpeg-0.4.9-pre1/libavcodec/Makefile ffmpeg-0.4.9-pre1-patch/libavcodec/Makefile --- ffmpeg-0.4.9-pre1/libavcodec/Makefile 2004-06-18 14:11:15.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/libavcodec/Makefile 2005-08-19 12:13:18.000000000 +0100 @@ -106,6 +106,12 @@ EXTRALIBS += -lvorbis -lvorbisenc endif +ifeq ($(CONFIG_DIRAC),yes) +OBJS += dirac.o +EXTRALIBS+= $(DIRAC_LIB) +CFLAGS+= $(DIRAC_INC) +endif + ifeq ($(TARGET_GPROF),yes) CFLAGS+=-p LDFLAGS+=-p diff -ruN ffmpeg-0.4.9-pre1/libavformat/allformats.c ffmpeg-0.4.9-pre1-patch/libavformat/allformats.c --- ffmpeg-0.4.9-pre1/libavformat/allformats.c 2004-03-13 23:04:37.000000000 +0000 +++ ffmpeg-0.4.9-pre1-patch/libavformat/allformats.c 2005-08-19 12:13:18.000000000 +0100 @@ -81,6 +81,10 @@ ogg_init(); #endif +#ifdef CONFIG_DIRAC + drc_init(); +#endif + #ifndef CONFIG_WIN32 ffm_init(); #endif diff -ruN ffmpeg-0.4.9-pre1/libavformat/avienc.c ffmpeg-0.4.9-pre1-patch/libavformat/avienc.c --- ffmpeg-0.4.9-pre1/libavformat/avienc.c 2004-06-17 11:46:08.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/libavformat/avienc.c 2005-08-19 12:13:18.000000000 +0100 @@ -164,6 +164,7 @@ { CODEC_ID_4XM, MKTAG('4', 'X', 'M', 'V') }, { CODEC_ID_FLV1, MKTAG('F', 'L', 'V', '1') }, { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, + { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') }, { 0, 0 }, }; diff -ruN ffmpeg-0.4.9-pre1/libavformat/drc.c ffmpeg-0.4.9-pre1-patch/libavformat/drc.c --- ffmpeg-0.4.9-pre1/libavformat/drc.c 1970-01-01 01:00:00.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/libavformat/drc.c 2005-08-19 12:17:29.000000000 +0100 @@ -0,0 +1,300 @@ +/** + * @file drc.c + * Dirac streaming support + * @author Andrew Kennedy + * 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 Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "avformat.h" + +#undef NDEBUG +#include + + +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 ffmpeg-0.4.9-pre1/libavformat/Makefile ffmpeg-0.4.9-pre1-patch/libavformat/Makefile --- ffmpeg-0.4.9-pre1/libavformat/Makefile 2004-04-24 16:16:23.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/libavformat/Makefile 2005-08-19 12:13:18.000000000 +0100 @@ -39,6 +39,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 ffmpeg-0.4.9-pre1/libavformat/utils.c ffmpeg-0.4.9-pre1-patch/libavformat/utils.c --- ffmpeg-0.4.9-pre1/libavformat/utils.c 2004-06-30 18:34:14.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/libavformat/utils.c 2005-08-19 12:13:18.000000000 +0100 @@ -1641,6 +1641,7 @@ st->codec.codec_id == CODEC_ID_H264 || st->codec.codec_id == CODEC_ID_H263 || st->codec.codec_id == CODEC_ID_VORBIS || + st->codec.codec_id == CODEC_ID_DIRAC || (st->codec.codec_id == CODEC_ID_MPEG4 && !st->need_parsing))) try_decode_frame(st, pkt->data, pkt->size); diff -ruN ffmpeg-0.4.9-pre1/Makefile ffmpeg-0.4.9-pre1-patch/Makefile --- ffmpeg-0.4.9-pre1/Makefile 2004-07-08 12:02:04.000000000 +0100 +++ ffmpeg-0.4.9-pre1-patch/Makefile 2005-08-19 12:13:18.000000000 +0100 @@ -58,6 +58,11 @@ EXTRALIBS+=-lfaac endif +ifeq ($(CONFIG_DIRAC),yes) +EXTRALIBS+= $(DIRAC_LIB) +CFLAGS+= $(DIRAC_INC) +endif + ifeq ($(BUILD_VHOOK),yes) VHOOK=videohook INSTALLVHOOK=install-vhook