[Ffmpeg-devel] [PATCH] dirac 0.6 support.
Pavlov Konstantin
thresh
Sat Feb 17 00:59:47 CET 2007
Hi guys. The attached file contains dirac-0.6 support to ffmpeg-7881.
It's a bit outdated, but anyway is better than the one provided by dirac
authors themselves.
Thanks Led (led at altlinux dot ru) for a nice work.
-------------- next part --------------
diff -urN ffmpeg-svn-r7881.orig/configure ffmpeg-svn-r7881/configure
--- ffmpeg-svn-r7881.orig/configure 2007-02-08 12:24:31 +0200
+++ ffmpeg-svn-r7881/configure 2007-02-08 12:39:01 +0200
@@ -100,6 +100,7 @@
echo " --enable-amr_nb-fixed use fixed point for amr-nb codec"
echo " --enable-amr_wb enable amr_wb float audio codec"
echo " --enable-amr_if2 enable amr_wb IF2 audio codec"
+ echo " --enable-dirac enable dirac codec support via libdirac_encoder [default=no]"
echo " --enable-gpl allow use of GPL code, the resulting libav*"
echo " and ffmpeg will be under GPL [default=no]"
echo ""
@@ -427,6 +428,13 @@
check_lib $header $func "$@" || die "ERROR: $name not found"
}
+require_pkg(){
+ pkg="$1"
+ pkg-config --exists "$pkg" || die "ERROR: $pkg.pc not found"
+ add_extralibs `pkg-config --libs "$pkg"`
+ add_cflags `pkg-config --cflags "$pkg"`
+}
+
apply(){
file=$1
shift
@@ -481,6 +489,7 @@
x264
xvid
zlib
+ dirac
'
HAVE_LIST='
@@ -556,6 +565,8 @@
mp3lame_encoder_deps="libmp3lame"
oggvorbis_decoder_deps="libvorbis"
oggvorbis_encoder_deps="libvorbis"
+dirac_decoder_deps="dirac"
+dirac_encoder_deps="dirac"
audio_demuxer_deps_any="audio_oss audio_beos"
audio_muxer_deps_any="audio_oss audio_beos"
@@ -701,6 +712,7 @@
amr_wb="no"
avisynth="no"
dc1394="no"
+dirac="no"
dlfcn_h="no"
dlopen="no"
liba52="no"
@@ -1172,6 +1184,11 @@
;;
--disable-parsers) disable $PARSER_LIST
;;
+ --enable-dirac) dirac="yes"
+ pkg_requires="$pkg_requires dirac"
+ ;;
+ --disable-dirac) dirac="no"
+ ;;
--help) show_help
;;
*)
@@ -1584,6 +1601,7 @@
enabled x264 && require x264 x264.h x264_encoder_open -lx264
enabled dc1394 && require libdc1394 libdc1394/dc1394_control.h dc1394_create_handle -ldc1394_control -lraw1394
enabled mlib && require mediaLib mlib_types.h mlib_VectorSub_S16_U8_Mod -lmlib
+enabled dirac && require_pkg dirac
# Ugh, libfaac uses stdcall calling convention on win32 so we can't use
# the generic test functions
@@ -1927,6 +1945,7 @@
echo "AMR-NB fixed support $amr_nb_fixed"
echo "AMR-WB float support $amr_wb"
echo "AMR-WB IF2 support $amr_if2"
+echo "Dirac support" $dirac
if disabled gpl; then
echo "License: LGPL"
else
diff -urN ffmpeg-svn-r7881.orig/libavcodec/allcodecs.c ffmpeg-svn-r7881/libavcodec/allcodecs.c
--- ffmpeg-svn-r7881.orig/libavcodec/allcodecs.c 2007-02-08 12:24:30 +0200
+++ ffmpeg-svn-r7881/libavcodec/allcodecs.c 2007-02-08 12:33:17 +0200
@@ -60,6 +60,7 @@
REGISTER_DECODER(CLJR, cljr);
REGISTER_DECODER(CSCD, cscd);
REGISTER_DECODER(CYUV, cyuv);
+ REGISTER_ENCDEC (DIRAC, dirac);
REGISTER_DECODER(DSICINVIDEO, dsicinvideo);
REGISTER_ENCDEC (DVVIDEO, dvvideo);
REGISTER_DECODER(EIGHTBPS, eightbps);
@@ -244,6 +245,7 @@
REGISTER_PARSER (AAC, aac);
REGISTER_PARSER (AC3, ac3);
REGISTER_PARSER (CAVSVIDEO, cavsvideo);
+ REGISTER_PARSER (DIRAC, dirac);
REGISTER_PARSER (DVBSUB, dvbsub);
REGISTER_PARSER (DVDSUB, dvdsub);
REGISTER_PARSER (H261, h261);
diff -urN ffmpeg-svn-r7881.orig/libavcodec/avcodec.h ffmpeg-svn-r7881/libavcodec/avcodec.h
--- ffmpeg-svn-r7881.orig/libavcodec/avcodec.h 2007-02-08 12:24:30 +0200
+++ ffmpeg-svn-r7881/libavcodec/avcodec.h 2007-02-08 12:33:17 +0200
@@ -243,6 +243,7 @@
/* subtitle codecs */
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) */
@@ -2197,6 +2198,7 @@
extern AVCodec wmv1_encoder;
extern AVCodec wmv2_encoder;
extern AVCodec x264_encoder;
+extern AVCodec dirac_encoder;
extern AVCodec xvid_encoder;
extern AVCodec zlib_encoder;
extern AVCodec zmbv_encoder;
@@ -2224,6 +2226,7 @@
extern AVCodec ffvhuff_decoder;
extern AVCodec flac_decoder;
extern AVCodec flashsv_decoder;
+extern AVCodec dirac_decoder;
extern AVCodec flic_decoder;
extern AVCodec flv_decoder;
extern AVCodec fourxm_decoder;
@@ -2636,6 +2639,7 @@
extern AVCodecParser h261_parser;
extern AVCodecParser h263_parser;
extern AVCodecParser h264_parser;
+extern AVCodecParser dirac_parser;
extern AVCodecParser mjpeg_parser;
extern AVCodecParser mpeg4video_parser;
extern AVCodecParser mpegaudio_parser;
diff -urN ffmpeg-svn-r7881.orig/libavcodec/dirac.c ffmpeg-svn-r7881/libavcodec/dirac.c
--- ffmpeg-svn-r7881.orig/libavcodec/dirac.c 1970-01-01 03:00:00 +0300
+++ ffmpeg-svn-r7881/libavcodec/dirac.c 2007-02-08 12:33:17 +0200
@@ -0,0 +1,709 @@
+/**
+ * @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 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 <assert.h>
+
+
+#include <libdirac_encoder/dirac_encoder.h>
+#include <libdirac_decoder/dirac_parser.h>
+
+/** 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 -urN ffmpeg-svn-r7881.orig/libavcodec/Makefile ffmpeg-svn-r7881/libavcodec/Makefile
--- ffmpeg-svn-r7881.orig/libavcodec/Makefile 2007-02-08 12:24:30 +0200
+++ ffmpeg-svn-r7881/libavcodec/Makefile 2007-02-08 12:33:17 +0200
@@ -63,6 +63,8 @@
OBJS-$(CONFIG_COOK_DECODER) += cook.o
OBJS-$(CONFIG_CSCD_DECODER) += cscd.o
OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o
+OBJS-$(CONFIG_DIRAC_DECODER) += dirac.o
+OBJS-$(CONFIG_DIRAC_ENCODER) += dirac.o
OBJS-$(CONFIG_DSICINVIDEO_DECODER) += dsicinav.o
OBJS-$(CONFIG_DSICINAUDIO_DECODER) += dsicinav.o
OBJS-$(CONFIG_DVBSUB_DECODER) += dvbsubdec.o
@@ -298,6 +300,7 @@
OBJS-$(CONFIG_AAC_PARSER) += parser.o
OBJS-$(CONFIG_AC3_PARSER) += parser.o
OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs.o parser.o
+OBJS-$(CONFIG_DIRAC_PARSER) += dirac.o
OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsubdec.o
OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsubdec.o
OBJS-$(CONFIG_H261_PARSER) += h261.o
diff -urN ffmpeg-svn-r7881.orig/libavformat/raw.c ffmpeg-svn-r7881/libavformat/raw.c
--- ffmpeg-svn-r7881.orig/libavformat/raw.c 2007-02-06 12:54:29 +0200
+++ ffmpeg-svn-r7881/libavformat/raw.c 2007-02-08 12:33:17 +0200
@@ -222,6 +222,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)
{
@@ -700,6 +717,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) \
diff -urN ffmpeg-svn-r7881.orig/libavformat/riff.c ffmpeg-svn-r7881/libavformat/riff.c
--- ffmpeg-svn-r7881.orig/libavformat/riff.c 2007-01-26 14:25:21 +0200
+++ ffmpeg-svn-r7881/libavformat/riff.c 2007-02-08 12:33:17 +0200
@@ -166,6 +166,7 @@
{ CODEC_ID_CAVS, MKTAG('C', 'A', 'V', 'S') },
{ CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') },
{ CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') },
+ { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
{ CODEC_ID_NONE, 0 },
};
diff -urN ffmpeg-svn-r7881.orig/libavformat/utils.c ffmpeg-svn-r7881/libavformat/utils.c
--- ffmpeg-svn-r7881.orig/libavformat/utils.c 2007-02-06 12:54:29 +0200
+++ ffmpeg-svn-r7881/libavformat/utils.c 2007-02-08 12:33:17 +0200
@@ -1969,6 +1969,7 @@
st->codec->codec_id == CODEC_ID_PBM ||
st->codec->codec_id == CODEC_ID_PPM ||
st->codec->codec_id == CODEC_ID_SHORTEN ||
+ 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);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070217/71737601/attachment.pgp>
More information about the ffmpeg-devel
mailing list