diff -ruN ffmpegsvn_trunk_5470/configure ffmpegsvn_trunk_5470_dirac/configure --- ffmpegsvn_trunk_5470/configure 2006-06-13 10:51:51.000000000 +0100 +++ ffmpegsvn_trunk_5470_dirac/configure 2006-06-13 11:06:56.000000000 +0100 @@ -43,6 +43,7 @@ echo " and libraw1394 [default=no]" echo " --enable-gpl allow use of GPL code, the resulting libav*" echo " and ffmpeg will be under GPL [default=no]" + echo " --enable-dirac enable dirac codec support via libdirac_encoder [default=no]" echo "" echo "Advanced options (experts only):" echo " --source-path=PATH path to source code [$source_path]" @@ -298,6 +299,7 @@ dostrip="yes" installstrip="-s" extralibs="-lm" +extraincs="" simpleidct="yes" bigendian="no" inttypes="yes" @@ -332,6 +334,7 @@ amr_if2="no" sunmlib="no" pthreads="no" +dirac="no" gpl="no" memalignhack="no" muxers="yes" @@ -687,6 +690,11 @@ ;; --enable-pthreads) pthreads="yes" ;; + --enable-dirac) dirac="yes" + extraincs="$extraincs `pkg-config --cflags dirac`" + extralibs="$extralibs `pkg-config --libs dirac` -lstdc++" + pkg_requires="$pkg_requires dirac" + ;; --enable-gpl) gpl="yes" ;; --enable-memalign-hack) memalignhack="yes" @@ -739,6 +747,14 @@ exit 1; fi +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." @@ -1338,6 +1354,7 @@ if test $sdl_too_old = "yes"; then echo "-> Your SDL version is too old - please upgrade to have FFplay/SDL support." fi +echo "dirac enabled $dirac" if test "$vhook" = "yes"; then echo "Imlib2 support $imlib2" @@ -1570,6 +1587,7 @@ echo "SLIBNAME_WITH_MAJOR=${SLIBNAME_WITH_MAJOR}" >> config.mak fi echo "EXTRALIBS=$extralibs" >> config.mak +echo "EXTRAINCS=$extraincs" >> config.mak version=`grep '#define FFMPEG_VERSION ' "$source_path/libavcodec/avcodec.h" | cut -d '"' -f 2` echo "VERSION=$version" >>config.mak @@ -1821,6 +1839,11 @@ echo "CONFIG_FFPLAY=yes" >> config.mak fi +if test "$dirac" = "yes" ; then + echo "#define CONFIG_DIRAC 1" >> $TMPH + echo "CONFIG_DIRAC=yes" >> config.mak +fi + if test "$gpl" = "yes" ; then echo "#define CONFIG_GPL 1" >> $TMPH echo "CONFIG_GPL=yes" >> config.mak diff -ruN ffmpegsvn_trunk_5470/libavcodec/allcodecs.c ffmpegsvn_trunk_5470_dirac/libavcodec/allcodecs.c --- ffmpegsvn_trunk_5470/libavcodec/allcodecs.c 2006-06-13 10:51:51.000000000 +0100 +++ ffmpegsvn_trunk_5470_dirac/libavcodec/allcodecs.c 2006-06-13 11:06:56.000000000 +0100 @@ -564,6 +564,14 @@ register_avcodec(&mmvideo_decoder); #endif //CONFIG_MMVIDEO_DECODER +/* dirac codec */ +#ifdef CONFIG_DIRAC + register_avcodec(&dirac_decoder); +#ifdef CONFIG_ENCODERS + register_avcodec(&dirac_encoder); +#endif +#endif + /* pcm codecs */ #if defined (CONFIG_ENCODERS) && defined (CONFIG_DECODERS) #define PCM_CODEC(id, name) \ @@ -654,5 +662,8 @@ av_register_codec_parser(&dvbsub_parser); #endif av_register_codec_parser(&aac_parser); +#ifdef CONFIG_DIRAC + av_register_codec_parser(&dirac_parser); +#endif } diff -ruN ffmpegsvn_trunk_5470/libavcodec/avcodec.h ffmpegsvn_trunk_5470_dirac/libavcodec/avcodec.h --- ffmpegsvn_trunk_5470/libavcodec/avcodec.h 2006-06-13 10:51:51.000000000 +0100 +++ ffmpegsvn_trunk_5470_dirac/libavcodec/avcodec.h 2006-06-13 11:06:56.000000000 +0100 @@ -210,6 +210,8 @@ 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) */ }; @@ -2104,6 +2106,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; @@ -2220,6 +2223,7 @@ extern AVCodec smackaud_decoder; extern AVCodec kmvc_decoder; extern AVCodec flashsv_decoder; +extern AVCodec dirac_decoder; /* pcm codecs */ #define PCM_CODEC(id, name) \ @@ -2516,6 +2520,7 @@ extern AVCodecParser dvdsub_parser; extern AVCodecParser dvbsub_parser; extern AVCodecParser aac_parser; +extern AVCodecParser dirac_parser; /* memory */ void *av_malloc(unsigned int size); diff -ruN ffmpegsvn_trunk_5470/libavcodec/dirac.c ffmpegsvn_trunk_5470_dirac/libavcodec/dirac.c --- ffmpegsvn_trunk_5470/libavcodec/dirac.c 1970-01-01 01:00:00.000000000 +0100 +++ ffmpegsvn_trunk_5470_dirac/libavcodec/dirac.c 2006-06-13 11:06:56.000000000 +0100 @@ -0,0 +1,709 @@ +/** + * @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==720 && avccontext->height==576) + return VIDEO_FORMAT_SD_625_DIGITAL; + + if(avccontext->height==1280 && avccontext->height==720) + return VIDEO_FORMAT_HD_720; + + if(avccontext->height==1920 && avccontext->width==1080) + return VIDEO_FORMAT_HD_1080; + + if(avccontext->height==352 && avccontext->width==288) + return VIDEO_FORMAT_CIF; + + 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.seq_params.chroma = format420; + break; + + case PIX_FMT_YUV422P: + p_dirac_params->enc_ctx.seq_params.chroma = format422; + break; + + case PIX_FMT_YUV444P: + p_dirac_params->enc_ctx.seq_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=0; + 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.seq_params.width=avccontext->width; + p_dirac_params->enc_ctx.seq_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]; + + 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]; + + 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->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->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->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=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, + 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 +* Intra_Ref start = 0x0C +* Intra_NonRef start = 0x08 +* Inter_Ref_1Ref start = 0x0D +* Inter_Ref_2Ref start = 0x0E +* Inter_NonRef_1Ref start = 0x09 +* Inter_NonRef_2Ref start = 0x0A +* End of sequence = 0x10 +*/ +#define FRAME_START(c) ((c) == 0x00 || (c) == 0x0C || (c) == 0x08 || (c) == 0x0D || (c) == 0x0E || (c) == 0x09 || (c) == 0x0A || (c) == 0x10) + +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, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + + int frame_start=0; + int frame_end; + 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 -ruN ffmpegsvn_trunk_5470/libavcodec/Makefile ffmpegsvn_trunk_5470_dirac/libavcodec/Makefile --- ffmpegsvn_trunk_5470/libavcodec/Makefile 2006-06-13 10:51:51.000000000 +0100 +++ ffmpegsvn_trunk_5470_dirac/libavcodec/Makefile 2006-06-13 11:06:56.000000000 +0100 @@ -5,7 +5,7 @@ include ../config.mak # NOTE: -I.. is needed to include config.h -CFLAGS=$(OPTFLAGS) -DHAVE_AV_CONFIG_H -I.. -I$(SRC_PATH)/libavutil -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE $(AMR_CFLAGS) +CFLAGS=$(OPTFLAGS) -DHAVE_AV_CONFIG_H -I.. -I$(SRC_PATH)/libavutil -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE $(AMR_CFLAGS) $(EXTRAINCS) OBJS= bitstream.o utils.o mem.o allcodecs.o \ mpegvideo.o jrevdct.o jfdctfst.o jfdctint.o\ @@ -333,6 +333,12 @@ endif endif +ifeq ($(CONFIG_DIRAC), yes) +OBJS += dirac.o +EXTRALIBS += $(DIRAC_LIB) +CFLAGS += $(DIRAC_INC) +endif + ifeq ($(CONFIG_LIBGSM),yes) OBJS += libgsm.o endif diff -ruN ffmpegsvn_trunk_5470/libavformat/avienc.c ffmpegsvn_trunk_5470_dirac/libavformat/avienc.c --- ffmpegsvn_trunk_5470/libavformat/avienc.c 2006-06-13 10:51:51.000000000 +0100 +++ ffmpegsvn_trunk_5470_dirac/libavformat/avienc.c 2006-06-13 11:06:56.000000000 +0100 @@ -203,6 +203,7 @@ { CODEC_ID_CSCD, MKTAG('C', 'S', 'C', 'D') }, { CODEC_ID_ZMBV, MKTAG('Z', 'M', 'B', 'V') }, { CODEC_ID_KMVC, MKTAG('K', 'M', 'V', 'C') }, + { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') }, { CODEC_ID_RAWVIDEO, 0 }, { CODEC_ID_NONE, 0 }, }; diff -ruN ffmpegsvn_trunk_5470/libavformat/raw.c ffmpegsvn_trunk_5470_dirac/libavformat/raw.c --- ffmpegsvn_trunk_5470/libavformat/raw.c 2006-06-13 10:51:51.000000000 +0100 +++ ffmpegsvn_trunk_5470_dirac/libavformat/raw.c 2006-06-13 11:06:56.000000000 +0100 @@ -235,6 +235,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) { @@ -662,6 +679,32 @@ }; #endif //CONFIG_MUXERS +AVInputFormat dirac_iformat = { + "dirac", + "raw dirac", + 0, + NULL, + dirac_read_header, + raw_read_partial_packet, + raw_read_close, + .extensions = "drc", +}; + +#ifdef CONFIG_MUXERS +AVOutputFormat dirac_oformat = { + "dirac", + "raw dirac", + "dirac", + "drc", + 0, + CODEC_ID_DIRAC, + 0, + raw_write_header, + raw_write_packet, + raw_write_trailer, +}; +#endif //CONFIG_MUXERS + /* pcm formats */ #define PCMINPUTDEF(name, long_name, ext, codec) \ @@ -851,6 +894,9 @@ av_register_output_format(&mjpeg_oformat); av_register_input_format(&ingenient_iformat); + + av_register_input_format(&dirac_iformat); + av_register_output_format(&dirac_oformat); av_register_input_format(&pcm_s16le_iformat); av_register_output_format(&pcm_s16le_oformat); diff -ruN ffmpegsvn_trunk_5470/Makefile ffmpegsvn_trunk_5470_dirac/Makefile --- ffmpegsvn_trunk_5470/Makefile 2006-06-13 10:51:51.000000000 +0100 +++ ffmpegsvn_trunk_5470_dirac/Makefile 2006-06-13 11:06:56.000000000 +0100 @@ -6,7 +6,7 @@ VPATH=$(SRC_PATH) -CFLAGS=$(OPTFLAGS) -I. -I$(SRC_PATH) -I$(SRC_PATH)/libavutil -I$(SRC_PATH)/libavcodec -I$(SRC_PATH)/libavformat -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE +CFLAGS=$(OPTFLAGS) -I. -I$(SRC_PATH) -I$(SRC_PATH)/libavutil -I$(SRC_PATH)/libavcodec -I$(SRC_PATH)/libavformat $(EXTRAINCS) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE LDFLAGS+= -g ifeq ($(TARGET_GPROF),yes)