diff -uarN ffmpeg-r12291.orig/Makefile ffmpeg-r12291/Makefile --- ffmpeg-r12291.orig/Makefile 2008-03-03 20:06:45.000000000 +0100 +++ ffmpeg-r12291/Makefile 2008-03-03 21:04:53.000000000 +0100 @@ -8,7 +8,7 @@ CFLAGS=$(OPTFLAGS) -I$(BUILD_ROOT) -I$(SRC_PATH) -I$(SRC_PATH)/libavutil \ -I$(SRC_PATH)/libavcodec -I$(SRC_PATH)/libavformat -I$(SRC_PATH)/libswscale \ - -I$(SRC_PATH)/libavdevice -I$(SRC_PATH)/libavfilter \ + -I$(SRC_PATH)/libavdevice -I$(SRC_PATH)/libavfilter $(EXTRAINCS) \ -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_ISOC9X_SOURCE -DHAVE_AV_CONFIG_H LDFLAGS+= -g diff -uarN ffmpeg-r12291.orig/configure ffmpeg-r12291/configure --- ffmpeg-r12291.orig/configure 2008-03-03 20:06:45.000000000 +0100 +++ ffmpeg-r12291/configure 2008-03-03 21:02:05.000000000 +0100 @@ -89,6 +89,8 @@ echo " --enable-libamr-wb enable libamr-wb floating point audio codec" echo " --enable-libdc1394 enable IIDC-1394 grabbing using libdc1394" echo " and libraw1394 [default=no]" + echo " --enable-dirac enable dirac codec support via " + echo " libdirac_encoder and libdirac_decoder [default=no]" echo " --enable-libfaac enable FAAC support via libfaac [default=no]" echo " --enable-libfaad enable FAAD support via libfaad [default=no]" echo " --enable-libfaadbin open libfaad.so.0 at runtime [default=no]" @@ -631,6 +633,7 @@ avfilter_lavf avisynth beos_netserver + dirac ffmpeg ffplay ffserver @@ -813,6 +816,8 @@ libamr_nb_encoder_deps="libamr_nb" libamr_wb_decoder_deps="libamr_wb" libamr_wb_encoder_deps="libamr_wb" +libdirac_encoder_deps="dirac" +libdirac_decoder_deps="dirac" libfaac_encoder_deps="libfaac" libfaad_decoder_deps="libfaad" libfaadbin_decoder_extralibs='$ldl' @@ -1670,6 +1675,7 @@ enabled libx264 && require x264 x264.h x264_encoder_open -lx264 -lm enabled libxvid && require Xvid xvid.h xvid_global -lxvidcore enabled mlib && require mediaLib mlib_types.h mlib_VectorSub_S16_U8_Mod -lmlib +enabled dirac && add_extralibs `pkg-config --libs dirac` "-lstdc++" && extraincs="$extraincs `pkg-config --cflags dirac`" # disable the native AC-3 decoder if liba52 is enabled enabled liba52 && disable ac3_decoder @@ -1880,6 +1886,7 @@ enabled libdc1394 && append pkg_requires "libraw1394" enabled libtheora && append pkg_requires "theora" enabled libvorbis && append pkg_requires "vorbisenc" +enabled dirac && append pkg_requires "dirac" echo "install prefix $PREFIX" echo "source path $source_path" @@ -1941,6 +1948,7 @@ echo "libamr-nb support ${libamr_nb-no}" echo "libamr-wb support ${libamr_wb-no}" echo "libdc1394 support ${libdc1394-no}" +echo "dirac enabled ${dirac-no}" echo "libfaac enabled ${libfaac-no}" echo "libfaad enabled ${libfaad-no}" echo "libfaad dlopened ${libfaadbin-no}" @@ -2069,6 +2077,7 @@ fi echo "LIB_INSTALL_EXTRA_CMD=${LIB_INSTALL_EXTRA_CMD}" >> config.mak echo "EXTRALIBS=$extralibs" >> config.mak +echo "EXTRAINCS=$extraincs" >> config.mak print_config ARCH_ $TMPH config.mak $ARCH_LIST print_config HAVE_ $TMPH config.mak $HAVE_LIST diff -uarN ffmpeg-r12291.orig/libavcodec/Makefile ffmpeg-r12291/libavcodec/Makefile --- ffmpeg-r12291.orig/libavcodec/Makefile 2008-03-03 20:06:44.000000000 +0100 +++ ffmpeg-r12291/libavcodec/Makefile 2008-03-03 21:03:29.000000000 +0100 @@ -4,7 +4,7 @@ # include ../config.mak -CFLAGS += -I$(SRC_PATH)/libswscale -I$(SRC_PATH)/libavcodec +CFLAGS += -I$(SRC_PATH)/libswscale -I$(SRC_PATH)/libavcodec $(EXTRAINCS) OBJS = allcodecs.o \ audioconvert.o \ @@ -306,6 +306,7 @@ OBJS-$(CONFIG_LIBA52) += liba52.o OBJS-$(CONFIG_LIBAMR_NB) += libamr.o OBJS-$(CONFIG_LIBAMR_WB) += libamr.o +OBJS-$(CONFIG_DIRAC) += dirac.o OBJS-$(CONFIG_LIBFAAC) += libfaac.o OBJS-$(CONFIG_LIBFAAD) += libfaad.o OBJS-$(CONFIG_LIBGSM) += libgsm.o diff -uarN ffmpeg-r12291.orig/libavcodec/allcodecs.c ffmpeg-r12291/libavcodec/allcodecs.c --- ffmpeg-r12291.orig/libavcodec/allcodecs.c 2008-03-03 20:06:44.000000000 +0100 +++ ffmpeg-r12291/libavcodec/allcodecs.c 2008-03-03 21:02:05.000000000 +0100 @@ -73,6 +73,7 @@ REGISTER_DECODER (CLJR, cljr); REGISTER_DECODER (CSCD, cscd); REGISTER_DECODER (CYUV, cyuv); + REGISTER_ENCDEC (DIRAC, dirac); REGISTER_ENCDEC (DNXHD, dnxhd); REGISTER_DECODER (DSICINVIDEO, dsicinvideo); REGISTER_ENCDEC (DVVIDEO, dvvideo); @@ -285,6 +286,7 @@ REGISTER_PARSER (AC3, ac3); REGISTER_PARSER (CAVSVIDEO, cavsvideo); REGISTER_PARSER (DCA, dca); + REGISTER_PARSER (DIRAC, dirac); REGISTER_PARSER (DVBSUB, dvbsub); REGISTER_PARSER (DVDSUB, dvdsub); REGISTER_PARSER (H261, h261); diff -uarN ffmpeg-r12291.orig/libavcodec/avcodec.h ffmpeg-r12291/libavcodec/avcodec.h --- ffmpeg-r12291.orig/libavcodec/avcodec.h 2008-03-03 20:06:44.000000000 +0100 +++ ffmpeg-r12291/libavcodec/avcodec.h 2008-03-03 21:02:05.000000000 +0100 @@ -299,6 +299,8 @@ /* other specific kind of codecs (generaly used for attachments) */ CODEC_ID_TTF= 0x18000, + CODEC_ID_DIRAC= 0x18000, + CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS * stream (only used by libavformat) */ }; diff -uarN ffmpeg-r12291.orig/libavcodec/dirac.c ffmpeg-r12291/libavcodec/dirac.c --- ffmpeg-r12291.orig/libavcodec/dirac.c 1970-01-01 01:00:00.000000000 +0100 +++ ffmpeg-r12291/libavcodec/dirac.c 2008-03-03 21:02:05.000000000 +0100 @@ -0,0 +1,770 @@ +/** + * @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; + + +typedef struct FfmpegDiracParseContext +{ + + /** stream buffer variables */ + unsigned char* p_dirac_videobuffer; + int dirac_videobuf_code_len; + unsigned char dirac_videobuf_code[5]; + int dirac_videobuf_len; + int in_frame; + int dirac_overread_size; + +} FfmpegDiracParseContext ; + + +/** +* Works out Dirac-compatible pre-set option from file size +*/ +static dirac_encoder_presets_t GetDiracPreset(AVCodecContext *avccontext) +{ + + if(avccontext->width==176 && avccontext->height==120) + return VIDEO_FORMAT_QSIF525; + else if(avccontext->width==176 && avccontext->height==144) + return VIDEO_FORMAT_QCIF; + else if(avccontext->width==352 && avccontext->height==240) + return VIDEO_FORMAT_SIF525; + else if(avccontext->width==352 && avccontext->height==288) + return VIDEO_FORMAT_CIF; + else if(avccontext->width==704 && avccontext->height==480) + return VIDEO_FORMAT_4SIF525; + else if(avccontext->width==704 && avccontext->height==576) + return VIDEO_FORMAT_4CIF; + else if(avccontext->width==720 && avccontext->height==480) + return VIDEO_FORMAT_SD_480I60; + else if(avccontext->width==720 && avccontext->height==576) + return VIDEO_FORMAT_SD_576I50; + else if(avccontext->height==1280 && avccontext->height==720) + { + if (avccontext->time_base.den == 60000 && + avccontext->time_base.num == 1001) + { + return VIDEO_FORMAT_HD_720P60; + } + else + { + return VIDEO_FORMAT_HD_720P50; + } + } + else if(avccontext->height==1920 && avccontext->width==1080) + { + if (avccontext->time_base.den == 30000 && + avccontext->time_base.num == 1001) + { + return VIDEO_FORMAT_HD_1080I60; + } + else if (avccontext->time_base.den == 25 && + avccontext->time_base.num == 1) + { + return VIDEO_FORMAT_HD_1080I50; + } + else if (avccontext->time_base.den == 60 && + avccontext->time_base.num == 1001) + { + return VIDEO_FORMAT_HD_1080P60; + } + else + { + return VIDEO_FORMAT_HD_1080P50; + } + } + return VIDEO_FORMAT_CUSTOM; +} + +/** +* Works out Dirac-compatible chroma format +*/ +static int GetDiracChromaFormat(AVCodecContext *avccontext) +{ + FfmpegDiracParams* p_dirac_params = avccontext->priv_data; + + switch(avccontext->pix_fmt) + { + case PIX_FMT_YUV420P: + p_dirac_params->enc_ctx.src_params.chroma = format420; + break; + + case PIX_FMT_YUV422P: + p_dirac_params->enc_ctx.src_params.chroma = format422; + break; + + case PIX_FMT_YUV444P: + p_dirac_params->enc_ctx.src_params.chroma = format444; + break; + + default: + av_log (avccontext, AV_LOG_ERROR, "this codec supports only Planar YUV formats (yuv420p, yuv422p, yuv444p\n"); + return -1; + } + return format420; +} + + /** + * returns Ffmppeg chroma format + */ +static 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; + + default: + break; + } + + return PIX_FMT_YUV420P; +} + + +static int dirac_encode_init(AVCodecContext *avccontext) +{ + + FfmpegDiracParams* p_dirac_params = avccontext->priv_data; + int no_local=1; + int verbose=avccontext->debug; + dirac_encoder_presets_t preset; + + if(avccontext->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ + av_log(avccontext, AV_LOG_ERROR, "this codec is under development, files encoded with it may not be decodable with future versions!!!\n" + "use vstrict=-2 / -strict -2 to use it anyway\n"); + return -1; + } + + /* get dirac preset*/ + 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); + + if (GetDiracChromaFormat(avccontext) == -1) + return -1; + p_dirac_params->enc_ctx.src_params.frame_rate.numerator=avccontext->time_base.den; + p_dirac_params->enc_ctx.src_params.frame_rate.denominator=avccontext->time_base.num; + p_dirac_params->enc_ctx.src_params.width=avccontext->width; + p_dirac_params->enc_ctx.src_params.height=avccontext->height; + + avccontext->frame_size = avpicture_get_size(avccontext->pix_fmt, avccontext->width, avccontext->height); + 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]; + else if(avccontext->bit_rate >= 1000) + p_dirac_params->enc_ctx.enc_params.trate=avccontext->bit_rate/1000; + + if ((preset > VIDEO_FORMAT_QCIF || preset < VIDEO_FORMAT_QSIF525) && + avccontext->bit_rate == 200000) + { + p_dirac_params->enc_ctx.enc_params.trate = 0; + } + + if (avccontext->flags & CODEC_FLAG_INTERLACED_ME) + { + // all material can be coded as interlaced or progressive + // irrespective of the type of source material + p_dirac_params->enc_ctx.enc_params.picture_coding_mode = 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; + 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 == INTRA_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 pict_size; + unsigned char *buffer[3]; + + *data_size = 0; + + if(buf_size>0) + /* 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->src_params.height; + avccontext->width=p_dirac_params->p_decoder->src_params.width; + avccontext->pix_fmt=GetFfmpegChromaFormat(p_dirac_params->p_decoder->src_params.chroma); + avccontext->time_base.den =p_dirac_params->p_decoder->src_params.frame_rate.numerator; + avccontext->time_base.num =p_dirac_params->p_decoder->src_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 */ + if(p_dirac_params->p_out_frame_buf==0) + 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->src_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=avpicture_get_size(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 +} ; + + +static int dirac_sync_video_packet (const uint8_t **buf, int buf_size, + FfmpegDiracParseContext *p_dirac_params, + int *start) +{ + int bytes_read = 0; + unsigned char* p_dirac_videobuf_code = p_dirac_params->dirac_videobuf_code; + p_dirac_params->dirac_videobuf_len=0; + + while(p_dirac_params->dirac_videobuf_code_len<5) + { + p_dirac_videobuf_code[p_dirac_params->dirac_videobuf_code_len++]=*(*buf); + (*buf)++; + ++bytes_read; + } + while (1) + { + int c; + if(p_dirac_videobuf_code[0]==0x42 && p_dirac_videobuf_code[1]==0x42 && p_dirac_videobuf_code[2]==0x43 && p_dirac_videobuf_code[3]==0x44) + break; + + if (bytes_read >= buf_size ) + return -1; + + ++(*start); + p_dirac_videobuf_code[0]=p_dirac_videobuf_code[1]; + p_dirac_videobuf_code[1]=p_dirac_videobuf_code[2]; + p_dirac_videobuf_code[2]=p_dirac_videobuf_code[3]; + p_dirac_videobuf_code[3]=p_dirac_videobuf_code[4]; + c = *(*buf); + (*buf)++; + ++bytes_read; + p_dirac_videobuf_code[4]=c; + } + + return p_dirac_videobuf_code[4]; +} + +static int dirac_find_frame_end(FfmpegDiracParseContext *p_dirac_params, + const uint8_t *buf, + const uint8_t *p_buf_end, int cur_idx) +{ + int byte; + int end_idx=cur_idx; + + /* find end of frame */ + int shift = 0xffffffff; + p_dirac_params->dirac_videobuf_code_len = 0; + while (p_dirac_params->in_frame) + { + if(buf==p_buf_end) + return -1; + + byte = *buf; + if (byte < 0) + return -1; + + if (shift == 0x42424344) + { + p_dirac_params->in_frame = 0; + p_dirac_params->dirac_videobuf_code_len = 5; + p_dirac_params->dirac_videobuf_code[0] = 0x42; + p_dirac_params->dirac_videobuf_code[1] = 0x42; + p_dirac_params->dirac_videobuf_code[2] = 0x43; + p_dirac_params->dirac_videobuf_code[3] = 0x44; + p_dirac_params->dirac_videobuf_code[4] = byte; + return end_idx; + } + shift = (shift << 8 ) | byte; + buf++; + end_idx++; + } + + return -1; + +} + +/* +* Access unit header = 0x00 +* End of sequence = 0x10 +* Auxiliary data = 0x20 +* Padding data = 0x30 +* Intra_Ref start = 0x0C (using ac) +* Intra_NonRef start = 0x08 (using ac) +* Intra_Ref start = 0x4C (not using ac) +* Intra_NonRef start = 0x48 (not using ac) +* Intra_Ref start = 0xCC (low delay syntax) +* Intra_NonRef start = 0xC8 (low delay syntax) +* Inter_Ref_1Ref start = 0x0D +* Inter_Ref_2Ref start = 0x0E +* Inter_NonRef_1Ref start = 0x09 +* Inter_NonRef_2Ref start = 0x0A +*/ +#define FRAME_START(c) (((c) == 0x00) || ((c) == 0x10) || (((c)&0xF8) == 0x20) || ((c) == 0x30) || (((c)&0x08) == 0x08)) + +static int dirac_find_frame_start(FfmpegDiracParseContext *p_dirac_params, const uint8_t **buf, int buf_size) +{ + unsigned int shift = 0xffffffff; + int msg_type = 0; + int start=0; + + /* find start of data */ + msg_type = dirac_sync_video_packet(buf, buf_size, p_dirac_params, &start); + + if (msg_type < 0) + return -1; + + + /* find start of frame */ + while (!p_dirac_params->in_frame) + { + int byte; + if (FRAME_START(msg_type)) + { + p_dirac_params->in_frame = 1; + return start; + } + + byte = *(*buf); + (*buf)++; + + if (byte < 0) + { + p_dirac_params->dirac_videobuf_code_len = 0; + return -1; + } + + if (shift == 0x42424344) + { + if (FRAME_START(byte)) + { + p_dirac_params->in_frame = 1; + return start; + } + } + shift = (shift << 8 ) | byte; + start++; + } + + return -1; + +} + + +static int parse_dirac(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + + int frame_start=0; + int frame_end; + const uint8_t *p_cur=buf; + + FfmpegDiracParseContext *p_dirac_params = (FfmpegDiracParseContext*)s->priv_data ; + + if(buf_size==0) + return 0; + + + if(!p_dirac_params->in_frame) + { + frame_start=dirac_find_frame_start(p_dirac_params, &p_cur, buf_size); + if(frame_start==-1) + { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } + + frame_end = dirac_find_frame_end(p_dirac_params, p_cur, buf+buf_size, p_cur-buf); + + /* no frame end - store data */ + if(frame_end < 0) + { + memcpy(p_dirac_params->p_dirac_videobuffer+p_dirac_params->dirac_videobuf_len, + buf+frame_start, buf_size-frame_start); + p_dirac_params->dirac_videobuf_len+=buf_size-frame_start; + + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + /* have frame end */ + memcpy(p_dirac_params->p_dirac_videobuffer+p_dirac_params->dirac_videobuf_len, + buf+frame_start, frame_end-frame_start+1); + p_dirac_params->dirac_videobuf_len+=frame_end-frame_start+1; + + /* construct new frame */ + *poutbuf=av_malloc(p_dirac_params->dirac_videobuf_len); + memcpy(*poutbuf, p_dirac_params->p_dirac_videobuffer, p_dirac_params->dirac_videobuf_len); + *poutbuf_size = p_dirac_params->dirac_videobuf_len; + + + return frame_end+1; +} + + + +static int dirac_parse_close(AVCodecParserContext *s) +{ + FfmpegDiracParseContext *pc = s->priv_data; + av_freep(&pc->p_dirac_videobuffer); + return 0; +} + +static int dirac_parse_open(AVCodecParserContext *s) +{ + FfmpegDiracParseContext *pc = s->priv_data; + pc->p_dirac_videobuffer = (unsigned char *)av_malloc(0x100000); + return 0; + +} + + +AVCodecParser dirac_parser = { + { CODEC_ID_DIRAC }, + sizeof(FfmpegDiracParseContext), + dirac_parse_open, + parse_dirac, + dirac_parse_close, +}; diff -uarN ffmpeg-r12291.orig/libavformat/allformats.c ffmpeg-r12291/libavformat/allformats.c --- ffmpeg-r12291.orig/libavformat/allformats.c 2008-03-03 20:06:45.000000000 +0100 +++ ffmpeg-r12291/libavformat/allformats.c 2008-03-03 21:02:05.000000000 +0100 @@ -68,6 +68,7 @@ REGISTER_DEMUXER (C93, c93); REGISTER_MUXER (CRC, crc); REGISTER_DEMUXER (DAUD, daud); + REGISTER_MUXDEMUX (DIRAC, dirac); REGISTER_DEMUXER (DSICIN, dsicin); REGISTER_DEMUXER (DTS, dts); REGISTER_MUXDEMUX (DV, dv); diff -uarN ffmpeg-r12291.orig/libavformat/raw.c ffmpeg-r12291/libavformat/raw.c --- ffmpeg-r12291.orig/libavformat/raw.c 2008-03-03 20:06:45.000000000 +0100 +++ ffmpeg-r12291/libavformat/raw.c 2008-03-03 21:02:05.000000000 +0100 @@ -236,6 +236,23 @@ return 0; } +/* drc read */ +static int dirac_read_header(AVFormatContext *s, + AVFormatParameters *ap) +{ + AVStream *st; + + st = av_new_stream(s, 0); + if (!st) + return AVERROR_NOMEM; + + st->codec->codec_type = CODEC_TYPE_VIDEO; + st->codec->codec_id = CODEC_ID_DIRAC; + st->need_parsing = 1; + /* the parameters will be extracted from the compressed bitstream */ + return 0; +} + static int shorten_read_header(AVFormatContext *s, AVFormatParameters *ap) { @@ -761,6 +778,33 @@ .value = CODEC_ID_VC1, }; +AVInputFormat dirac_demuxer = { + "dirac", + "raw dirac", + 0, + NULL, + dirac_read_header, + raw_read_partial_packet, + raw_read_close, + .extensions = "drc", + .value = CODEC_ID_DIRAC, +}; + +#ifdef CONFIG_MUXERS +AVOutputFormat dirac_muxer = { + "dirac", + "raw dirac", + "dirac", + "drc", + 0, + 0, + CODEC_ID_DIRAC, + NULL, + raw_write_packet, + NULL, +}; +#endif //CONFIG_MUXERS + /* pcm formats */ #define PCMINPUTDEF(name, long_name, ext, codec) \ diff -uarN ffmpeg-r12291.orig/libavformat/riff.c ffmpeg-r12291/libavformat/riff.c --- ffmpeg-r12291.orig/libavformat/riff.c 2008-03-03 20:06:45.000000000 +0100 +++ ffmpeg-r12291/libavformat/riff.c 2008-03-03 21:02:05.000000000 +0100 @@ -176,6 +176,7 @@ { CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') }, { CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') }, { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') }, + { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') }, { CODEC_ID_NONE, 0 }, };