Mercurial > audlegacy
changeset 915:5da5c262b1ef trunk
[svn] - input proposed shorten input plugin for hacking
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/Makefile Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,16 @@ +include ../../../mk/rules.mk +include ../../../mk/objective.mk + +OBJECTIVE_LIBS= libshorten.so + +SOURCES= avio.c aviobuf.c \ + common.c \ + cutils.c dsputil.c \ + fft.c file.c futils.c golomb.c init.c mdct.c \ + os_support.c \ + parser.c simple_idct.c shorten_decoder.c shorten_plugin.c \ + utils.h utils.c + +CFLAGS+= -fPIC -DPIC -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -c -I../../.. -I../../../intl $(GTK_CFLAGS) + +OBJECTS=${SOURCES:.c=.o}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/avcodec.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,1803 @@ +#ifndef AVCODEC_H +#define AVCODEC_H + +/** + * @file avcodec.h + * external api header. + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "common.h" +#include <sys/types.h> /* size_t */ + +#define FFMPEG_VERSION_INT 0x000408 +#define FFMPEG_VERSION "0.4.8" +#define LIBAVCODEC_BUILD 4701 + +#define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT +#define LIBAVCODEC_VERSION FFMPEG_VERSION + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s +#define LIBAVCODEC_IDENT "FFmpeg" LIBAVCODEC_VERSION "b" AV_STRINGIFY(LIBAVCODEC_BUILD) + +enum CodecID { + CODEC_ID_NONE, + CODEC_ID_WMAV1, + CODEC_ID_WMAV2, + + CODEC_ID_SHORTEN, + + /* various pcm "codecs" */ + CODEC_ID_PCM_S16LE, + CODEC_ID_PCM_S16BE, + CODEC_ID_PCM_U16LE, + CODEC_ID_PCM_U16BE, + CODEC_ID_PCM_S8, + CODEC_ID_PCM_U8, + CODEC_ID_PCM_MULAW, + CODEC_ID_PCM_ALAW, +}; + + +enum CodecType { + CODEC_TYPE_UNKNOWN = -1, + CODEC_TYPE_AUDIO, + CODEC_TYPE_DATA, +}; + +enum PixelFormat { + PIX_FMT_YUV420P, ///< Planar YUV 4:2:0 (1 Cr & Cb sample per 2x2 Y samples) + PIX_FMT_YUV422, + PIX_FMT_RGB24, ///< Packed pixel, 3 bytes per pixel, RGBRGB... + PIX_FMT_BGR24, ///< Packed pixel, 3 bytes per pixel, BGRBGR... + PIX_FMT_YUV422P, ///< Planar YUV 4:2:2 (1 Cr & Cb sample per 2x1 Y samples) + PIX_FMT_YUV444P, ///< Planar YUV 4:4:4 (1 Cr & Cb sample per 1x1 Y samples) + PIX_FMT_RGBA32, ///< Packed pixel, 4 bytes per pixel, BGRABGRA..., stored in cpu endianness + PIX_FMT_YUV410P, ///< Planar YUV 4:1:0 (1 Cr & Cb sample per 4x4 Y samples) + PIX_FMT_YUV411P, ///< Planar YUV 4:1:1 (1 Cr & Cb sample per 4x1 Y samples) + PIX_FMT_RGB565, ///< always stored in cpu endianness + PIX_FMT_RGB555, ///< always stored in cpu endianness, most significant bit to 1 + PIX_FMT_GRAY8, + PIX_FMT_MONOWHITE, ///< 0 is white + PIX_FMT_MONOBLACK, ///< 0 is black + PIX_FMT_PAL8, ///< 8 bit with RGBA palette + PIX_FMT_YUVJ420P, ///< Planar YUV 4:2:0 full scale (jpeg) + PIX_FMT_YUVJ422P, ///< Planar YUV 4:2:2 full scale (jpeg) + PIX_FMT_YUVJ444P, ///< Planar YUV 4:4:4 full scale (jpeg) + PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing(xvmc_render.h) + PIX_FMT_XVMC_MPEG2_IDCT, + PIX_FMT_NB, +}; + +/* currently unused, may be used if 24/32 bits samples ever supported */ +enum SampleFormat { + SAMPLE_FMT_S16 = 0, ///< signed 16 bits +}; + +/* in bytes */ +#define AVCODEC_MAX_AUDIO_FRAME_SIZE 131072 + +/** + * Required number of additionally allocated bytes at the end of the input bitstream for decoding. + * this is mainly needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end<br> + * Note, if the first 23 bits of the additional bytes are not 0 then damaged + * MPEG bitstreams could cause overread and segfault + */ +#define FF_INPUT_BUFFER_PADDING_SIZE 8 + +/* motion estimation type, EPZS by default */ +enum Motion_Est_ID { + ME_ZERO = 1, + ME_FULL, + ME_LOG, + ME_PHODS, + ME_EPZS, + ME_X1 +}; + +typedef struct RcOverride{ + int start_frame; + int end_frame; + int qscale; // if this is 0 then quality_factor will be used instead + float quality_factor; +} RcOverride; + +/* only for ME compatiblity with old apps */ +extern int motion_estimation_method; + +#define FF_MAX_B_FRAMES 8 + +/* encoding support + these flags can be passed in AVCodecContext.flags before initing + Note: note not everything is supported yet +*/ + +#define CODEC_FLAG_QSCALE 0x0002 ///< use fixed qscale +#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / Advanced prediction for H263 +#define CODEC_FLAG_QPEL 0x0010 ///< use qpel MC +#define CODEC_FLAG_GMC 0x0020 ///< use GMC +#define CODEC_FLAG_MV0 0x0040 ///< always try a MB with MV=<0,0> +#define CODEC_FLAG_PART 0x0080 ///< use data partitioning +/* parent program gurantees that the input for b-frame containing streams is not written to + for at least s->max_b_frames+1 frames, if this is not set than the input will be copied */ +#define CODEC_FLAG_INPUT_PRESERVED 0x0100 +#define CODEC_FLAG_PASS1 0x0200 ///< use internal 2pass ratecontrol in first pass mode +#define CODEC_FLAG_PASS2 0x0400 ///< use internal 2pass ratecontrol in second pass mode +#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< use external huffman table (for mjpeg) +#define CODEC_FLAG_GRAY 0x2000 ///< only decode/encode grayscale +#define CODEC_FLAG_EMU_EDGE 0x4000///< dont draw edges +#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding +#define CODEC_FLAG_TRUNCATED 0x00010000 /** input bitstream might be truncated at a random location instead + of only at frame boundaries */ +#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< normalize adaptive quantization +#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< use interlaced dct +#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< force low delay +#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< use alternate scan +#define CODEC_FLAG_TRELLIS_QUANT 0x00200000 ///< use trellis quantization +#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< place global headers in extradata instead of every keyframe +#define CODEC_FLAG_BITEXACT 0x00800000 ///< use only bitexact stuff (except (i)dct) +/* Fx : Flag for h263+ extra options */ +#define CODEC_FLAG_H263P_AIC 0x01000000 ///< H263 Advanced intra coding / MPEG4 AC prediction (remove this) +#define CODEC_FLAG_AC_PRED 0x01000000 ///< H263 Advanced intra coding / MPEG4 AC prediction +#define CODEC_FLAG_H263P_UMV 0x02000000 ///< Unlimited motion vector +#define CODEC_FLAG_CBP_RD 0x04000000 ///< use rate distortion optimization for cbp +#define CODEC_FLAG_QP_RD 0x08000000 ///< use rate distortion optimization for qp selectioon +#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H263 Alternative inter vlc +#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC +#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter +#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000 +#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation +#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< will reserve space for SVCD scan offset user data +#define CODEC_FLAG_CLOSED_GOP 0x80000000 +/* Unsupported options : + * Syntax Arithmetic coding (SAC) + * Reference Picture Selection + * Independant Segment Decoding */ +/* /Fx */ +/* codec capabilities */ + +#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< decoder can use draw_horiz_band callback +/** + * Codec uses get_buffer() for allocating buffers. + * direct rendering method 1 + */ +#define CODEC_CAP_DR1 0x0002 +/* if 'parse_only' field is true, then avcodec_parse_frame() can be + used */ +#define CODEC_CAP_PARSE_ONLY 0x0004 +#define CODEC_CAP_TRUNCATED 0x0008 + +//the following defines might change, so dont expect compatibility if u use them +#define MB_TYPE_INTRA4x4 0x0001 +#define MB_TYPE_INTRA16x16 0x0002 //FIXME h264 specific +#define MB_TYPE_INTRA_PCM 0x0004 //FIXME h264 specific +#define MB_TYPE_16x16 0x0008 +#define MB_TYPE_16x8 0x0010 +#define MB_TYPE_8x16 0x0020 +#define MB_TYPE_8x8 0x0040 +#define MB_TYPE_INTERLACED 0x0080 +#define MB_TYPE_DIRECT2 0x0100 //FIXME +#define MB_TYPE_ACPRED 0x0200 +#define MB_TYPE_GMC 0x0400 +#define MB_TYPE_SKIP 0x0800 +#define MB_TYPE_P0L0 0x1000 +#define MB_TYPE_P1L0 0x2000 +#define MB_TYPE_P0L1 0x4000 +#define MB_TYPE_P1L1 0x8000 +#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) +#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) +#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) +#define MB_TYPE_QUANT 0x00010000 +#define MB_TYPE_CBP 0x00020000 +//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...) + +/** + * Pan Scan area. + * this specifies the area which should be displayed. Note there may be multiple such areas for one frame + */ +typedef struct AVPanScan{ + /** + * id. + * - encoding: set by user. + * - decoding: set by lavc + */ + int id; + + /** + * width and height in 1/16 pel + * - encoding: set by user. + * - decoding: set by lavc + */ + int width; + int height; + + /** + * position of the top left corner in 1/16 pel for up to 3 fields/frames. + * - encoding: set by user. + * - decoding: set by lavc + */ + int16_t position[3][2]; +}AVPanScan; + +#define FF_COMMON_FRAME \ + /**\ + * pointer to the picture planes.\ + * this might be different from the first allocated byte\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *data[4];\ + int linesize[4];\ + /**\ + * pointer to the first allocated byte of the picture. can be used in get_buffer/release_buffer\ + * this isnt used by lavc unless the default get/release_buffer() is used\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *base[4];\ + /**\ + * 1 -> keyframe, 0-> not\ + * - encoding: set by lavc\ + * - decoding: set by lavc\ + */\ + int key_frame;\ +\ + /**\ + * picture type of the frame, see ?_TYPE below.\ + * - encoding: set by lavc for coded_picture (and set by user for input)\ + * - decoding: set by lavc\ + */\ + int pict_type;\ +\ + /**\ + * presentation timestamp in micro seconds (time when frame should be shown to user)\ + * if 0 then the frame_rate will be used as reference\ + * - encoding: MUST be set by user\ + * - decoding: set by lavc\ + */\ + int64_t pts;\ +\ + /**\ + * picture number in bitstream order.\ + * - encoding: set by\ + * - decoding: set by lavc\ + */\ + int coded_picture_number;\ + /**\ + * picture number in display order.\ + * - encoding: set by\ + * - decoding: set by lavc\ + */\ + int display_picture_number;\ +\ + /**\ + * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ + * - encoding: set by lavc for coded_picture (and set by user for input)\ + * - decoding: set by lavc\ + */\ + int quality; \ +\ + /**\ + * buffer age (1->was last buffer and dint change, 2->..., ...).\ + * set to INT_MAX if the buffer has not been used yet \ + * - encoding: unused\ + * - decoding: MUST be set by get_buffer()\ + */\ + int age;\ +\ + /**\ + * is this picture used as reference\ + * - encoding: unused\ + * - decoding: set by lavc (before get_buffer() call))\ + */\ + int reference;\ +\ + /**\ + * QP table\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + int8_t *qscale_table;\ + /**\ + * QP store stride\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + int qstride;\ +\ + /**\ + * mbskip_table[mb]>=1 if MB didnt change\ + * stride= mb_width = (width+15)>>4\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + uint8_t *mbskip_table;\ +\ + /**\ + * Motion vector table\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + int16_t (*motion_val[2])[2];\ +\ + /**\ + * Macroblock type table\ + * mb_type_base + mb_width + 2\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + uint32_t *mb_type;\ +\ + /**\ + * Macroblock size: (0->16x16, 1->8x8, 2-> 4x4, 3-> 2x2)\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + uint8_t motion_subsample_log2;\ +\ + /**\ + * for some private data of the user\ + * - encoding: unused\ + * - decoding: set by user\ + */\ + void *opaque;\ +\ + /**\ + * error\ + * - encoding: set by lavc if flags&CODEC_FLAG_PSNR\ + * - decoding: unused\ + */\ + uint64_t error[4];\ +\ + /**\ + * type of the buffer (to keep track of who has to dealloc data[*])\ + * - encoding: set by the one who allocs it\ + * - decoding: set by the one who allocs it\ + * Note: user allocated (direct rendering) & internal buffers can not coexist currently\ + */\ + int type;\ + \ + /**\ + * when decoding, this signal how much the picture must be delayed.\ + * extra_delay = repeat_pict / (2*fps)\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + int repeat_pict;\ + \ + /**\ + * \ + */\ + int qscale_type;\ + \ + /**\ + * The content of the picture is interlaced.\ + * - encoding: set by user\ + * - decoding: set by lavc (default 0)\ + */\ + int interlaced_frame;\ + \ + /**\ + * if the content is interlaced, is top field displayed first.\ + * - encoding: set by user\ + * - decoding: set by lavc\ + */\ + int top_field_first;\ + \ + /**\ + * Pan scan.\ + * - encoding: set by user\ + * - decoding: set by lavc\ + */\ + AVPanScan *pan_scan;\ + \ + /**\ + * tell user application that palette has changed from previous frame.\ + * - encoding: ??? (no palette-enabled encoder yet)\ + * - decoding: set by lavc (default 0)\ + */\ + int palette_has_changed;\ + \ + /**\ + * Codec suggestion on buffer type if != 0\ + * - encoding: unused\ + * - decoding: set by lavc (before get_buffer() call))\ + */\ + int buffer_hints;\ + +#define FF_QSCALE_TYPE_MPEG1 0 +#define FF_QSCALE_TYPE_MPEG2 1 + +#define FF_BUFFER_TYPE_INTERNAL 1 +#define FF_BUFFER_TYPE_USER 2 ///< Direct rendering buffers (image is (de)allocated by user) +#define FF_BUFFER_TYPE_SHARED 4 ///< buffer from somewher else, dont dealloc image (data/base) +#define FF_BUFFER_TYPE_COPY 8 ///< just a (modified) copy of some other buffer, dont dealloc anything + + +#define FF_I_TYPE 1 // Intra +#define FF_P_TYPE 2 // Predicted +#define FF_B_TYPE 3 // Bi-dir predicted +#define FF_S_TYPE 4 // S(GMC)-VOP MPEG4 +#define FF_SI_TYPE 5 +#define FF_SP_TYPE 6 + +#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore) +#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer +#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content +#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update) + +/** + * Audio Video Frame. + */ +typedef struct AVFrame { + FF_COMMON_FRAME +} AVFrame; + +#define DEFAULT_FRAME_RATE_BASE 1001000 + +/** + * main external api structure. + */ +typedef struct AVCodecContext { + /** + * the average bitrate. + * - encoding: set by user. unused for constant quantizer encoding + * - decoding: set by lavc. 0 or some bitrate if this info is available in the stream + */ + int bit_rate; + + /** + * number of bits the bitstream is allowed to diverge from the reference. + * the reference can be CBR (for CBR pass1) or VBR (for pass2) + * - encoding: set by user. unused for constant quantizer encoding + * - decoding: unused + */ + int bit_rate_tolerance; + + /** + * CODEC_FLAG_*. + * - encoding: set by user. + * - decoding: set by user. + */ + int flags; + + /** + * some codecs needs additionnal format info. It is stored here + * - encoding: set by user. + * - decoding: set by lavc. (FIXME is this ok?) + */ + int sub_id; + + /** + * motion estimation algorithm used for video coding. + * - encoding: MUST be set by user. + * - decoding: unused + */ + int me_method; + + /** + * some codecs need / can use extra-data like huffman tables. + * mjpeg: huffman tables + * rv10: additional flags + * mpeg4: global headers (they can be in the bitstream or here) + * - encoding: set/allocated/freed by lavc. + * - decoding: set/allocated/freed by user. + */ + void *extradata; + int extradata_size; + + /* video only */ + /** + * frames per sec multiplied by frame_rate_base. + * for variable fps this is the precission, so if the timestamps + * can be specified in msec precssion then this is 1000*frame_rate_base + * - encoding: MUST be set by user + * - decoding: set by lavc. 0 or the frame_rate if available + */ + int frame_rate; + + /** + * width / height. + * - encoding: MUST be set by user. + * - decoding: set by user if known, codec should override / dynamically change if needed + */ + int width, height; + +#define FF_ASPECT_SQUARE 1 +#define FF_ASPECT_4_3_625 2 +#define FF_ASPECT_4_3_525 3 +#define FF_ASPECT_16_9_625 4 +#define FF_ASPECT_16_9_525 5 +#define FF_ASPECT_EXTENDED 15 + + /** + * the number of pictures in a group of pitures, or 0 for intra_only. + * - encoding: set by user. + * - decoding: unused + */ + int gop_size; + + /** + * pixel format, see PIX_FMT_xxx. + * - encoding: FIXME: used by ffmpeg to decide whether an pix_fmt + * conversion is in order. This only works for + * codecs with one supported pix_fmt, we should + * do something for a generic case as well. + * - decoding: set by lavc. + */ + enum PixelFormat pix_fmt; + + /** + * Frame rate emulation. If not zero lower layer (i.e. format handler) + * has to read frames at native frame rate. + * - encoding: set by user. + * - decoding: unused. + */ + int rate_emu; + + /** + * if non NULL, 'draw_horiz_band' is called by the libavcodec + * decoder to draw an horizontal band. It improve cache usage. Not + * all codecs can do that. You must check the codec capabilities + * before + * - encoding: unused + * - decoding: set by user. + * @param height the height of the slice + * @param y the y position of the slice + * @param type 1->top field, 2->bottom field, 3->frame + * @param offset offset into the AVFrame.data from which the slice should be read + */ + void (*draw_horiz_band)(struct AVCodecContext *s, + const AVFrame *src, int offset[4], + int y, int type, int height); + + /* audio only */ + int sample_rate; ///< samples per sec + int channels; + int sample_fmt; ///< sample format, currenly unused + + /* the following data should not be initialized */ + int frame_size; ///< in samples, initialized when calling 'init' + int frame_number; ///< audio or video frame number + int real_pict_num; ///< returns the real picture number of previous encoded frame + + /** + * number of frames the decoded output will be delayed relative to + * the encoded input. + * - encoding: set by lavc. + * - decoding: unused + */ + int delay; + + /* - encoding parameters */ + float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) + float qblur; ///< amount of qscale smoothing over time (0.0-1.0) + + /** + * minimum quantizer. + * - encoding: set by user. + * - decoding: unused + */ + int qmin; + + /** + * maximum quantizer. + * - encoding: set by user. + * - decoding: unused + */ + int qmax; + + /** + * maximum quantizer difference etween frames. + * - encoding: set by user. + * - decoding: unused + */ + int max_qdiff; + + /** + * maximum number of b frames between non b frames. + * note: the output will be delayed by max_b_frames+1 relative to the input + * - encoding: set by user. + * - decoding: unused + */ + int max_b_frames; + + /** + * qscale factor between ip and b frames. + * - encoding: set by user. + * - decoding: unused + */ + float b_quant_factor; + + /** obsolete FIXME remove */ + int rc_strategy; + int b_frame_strategy; + + /** + * hurry up amount. + * - encoding: unused + * - decoding: set by user. 1-> skip b frames, 2-> skip idct/dequant too, 5-> skip everything except header + */ + int hurry_up; + + struct AVCodec *codec; + + void *priv_data; + + /* unused, FIXME remove*/ + int rtp_mode; + + int rtp_payload_size; /* The size of the RTP payload, the coder will */ + /* do it's best to deliver a chunk with size */ + /* below rtp_payload_size, the chunk will start */ + /* with a start code on some codecs like H.263 */ + /* This doesn't take account of any particular */ + /* headers inside the transmited RTP payload */ + + + /* The RTP callcack: This function is called */ + /* every time the encoder as a packet to send */ + /* Depends on the encoder if the data starts */ + /* with a Start Code (it should) H.263 does */ + void (*rtp_callback)(void *data, int size, int packet_number); + + /* statistics, used for 2-pass encoding */ + int mv_bits; + int header_bits; + int i_tex_bits; + int p_tex_bits; + int i_count; + int p_count; + int skip_count; + int misc_bits; + + /** + * number of bits used for the previously encoded frame. + * - encoding: set by lavc + * - decoding: unused + */ + int frame_bits; + + /** + * private data of the user, can be used to carry app specific stuff. + * - encoding: set by user + * - decoding: set by user + */ + void *opaque; + + char codec_name[32]; + enum CodecType codec_type; /* see CODEC_TYPE_xxx */ + enum CodecID codec_id; /* see CODEC_ID_xxx */ + + /** + * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * this is used to workaround some encoder bugs + * - encoding: set by user, if not then the default based on codec_id will be used + * - decoding: set by user, will be converted to upper case by lavc during init + */ + unsigned int codec_tag; + + /** + * workaround bugs in encoders which sometimes cannot be detected automatically. + * - encoding: unused + * - decoding: set by user + */ + int workaround_bugs; +#define FF_BUG_AUTODETECT 1 ///< autodetection +#define FF_BUG_OLD_MSMPEG4 2 +#define FF_BUG_XVID_ILACE 4 +#define FF_BUG_UMP4 8 +#define FF_BUG_NO_PADDING 16 +#define FF_BUG_AC_VLC 0 ///< will be removed, libavcodec can now handle these non compliant files by default +#define FF_BUG_QPEL_CHROMA 64 +#define FF_BUG_STD_QPEL 128 +#define FF_BUG_QPEL_CHROMA2 256 +#define FF_BUG_DIRECT_BLOCKSIZE 512 +#define FF_BUG_EDGE 1024 +//#define FF_BUG_FAKE_SCALABILITY 16 //autodetection should work 100% + + /** + * luma single coeff elimination threshold. + * - encoding: set by user + * - decoding: unused + */ + int luma_elim_threshold; + + /** + * chroma single coeff elimination threshold. + * - encoding: set by user + * - decoding: unused + */ + int chroma_elim_threshold; + + /** + * strictly follow the std (MPEG4, ...). + * - encoding: set by user + * - decoding: unused + */ + int strict_std_compliance; + + /** + * qscale offset between ip and b frames. + * if > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset) + * if < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset) + * - encoding: set by user. + * - decoding: unused + */ + float b_quant_offset; + + /** + * error resilience higher values will detect more errors but may missdetect + * some more or less valid parts as errors. + * - encoding: unused + * - decoding: set by user + */ + int error_resilience; +#define FF_ER_CAREFULL 1 +#define FF_ER_COMPLIANT 2 +#define FF_ER_AGGRESSIVE 3 +#define FF_ER_VERY_AGGRESSIVE 4 + + /** + * called at the beginning of each frame to get a buffer for it. + * if pic.reference is set then the frame will be read later by lavc + * width and height should be rounded up to the next multiple of 16 + * - encoding: unused + * - decoding: set by lavc, user can override + */ + int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * called to release buffers which where allocated with get_buffer. + * a released buffer can be reused in get_buffer() + * pic.data[*] must be set to NULL + * - encoding: unused + * - decoding: set by lavc, user can override + */ + void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * is 1 if the decoded stream contains b frames, 0 otherwise. + * - encoding: unused + * - decoding: set by lavc + */ + int has_b_frames; + + int block_align; ///< used by some WAV based audio codecs + + int parse_only; /* - decoding only: if true, only parsing is done + (function avcodec_parse_frame()). The frame + data is returned. Only MPEG codecs support this now. */ + + /** + * 0-> h263 quant 1-> mpeg quant. + * - encoding: set by user. + * - decoding: unused + */ + int mpeg_quant; + + /** + * pass1 encoding statistics output buffer. + * - encoding: set by lavc + * - decoding: unused + */ + char *stats_out; + + /** + * pass2 encoding statistics input buffer. + * concatenated stuff from stats_out of pass1 should be placed here + * - encoding: allocated/set/freed by user + * - decoding: unused + */ + char *stats_in; + + /** + * ratecontrol qmin qmax limiting method. + * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax + * - encoding: set by user. + * - decoding: unused + */ + float rc_qsquish; + + float rc_qmod_amp; + int rc_qmod_freq; + + /** + * ratecontrol override, see RcOverride. + * - encoding: allocated/set/freed by user. + * - decoding: unused + */ + RcOverride *rc_override; + int rc_override_count; + + /** + * rate control equation. + * - encoding: set by user + * - decoding: unused + */ + char *rc_eq; + + /** + * maximum bitrate. + * - encoding: set by user. + * - decoding: unused + */ + int rc_max_rate; + + /** + * minimum bitrate. + * - encoding: set by user. + * - decoding: unused + */ + int rc_min_rate; + + /** + * decoder bitstream buffer size. + * - encoding: set by user. + * - decoding: unused + */ + int rc_buffer_size; + float rc_buffer_aggressivity; + + /** + * qscale factor between p and i frames. + * if > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset) + * if < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset) + * - encoding: set by user. + * - decoding: unused + */ + float i_quant_factor; + + /** + * qscale offset between p and i frames. + * - encoding: set by user. + * - decoding: unused + */ + float i_quant_offset; + + /** + * initial complexity for pass1 ratecontrol. + * - encoding: set by user. + * - decoding: unused + */ + float rc_initial_cplx; + + /** + * dct algorithm, see FF_DCT_* below. + * - encoding: set by user + * - decoding: unused + */ + int dct_algo; +#define FF_DCT_AUTO 0 +#define FF_DCT_FASTINT 1 +#define FF_DCT_INT 2 +#define FF_DCT_MMX 3 +#define FF_DCT_MLIB 4 +#define FF_DCT_ALTIVEC 5 +#define FF_DCT_FAAN 6 + + /** + * luminance masking (0-> disabled). + * - encoding: set by user + * - decoding: unused + */ + float lumi_masking; + + /** + * temporary complexity masking (0-> disabled). + * - encoding: set by user + * - decoding: unused + */ + float temporal_cplx_masking; + + /** + * spatial complexity masking (0-> disabled). + * - encoding: set by user + * - decoding: unused + */ + float spatial_cplx_masking; + + /** + * p block masking (0-> disabled). + * - encoding: set by user + * - decoding: unused + */ + float p_masking; + + /** + * darkness masking (0-> disabled). + * - encoding: set by user + * - decoding: unused + */ + float dark_masking; + + + /* for binary compatibility */ + int unused; + + /** + * idct algorithm, see FF_IDCT_* below. + * - encoding: set by user + * - decoding: set by user + */ + int idct_algo; +#define FF_IDCT_AUTO 0 +#define FF_IDCT_INT 1 +#define FF_IDCT_SIMPLE 2 +#define FF_IDCT_SIMPLEMMX 3 +#define FF_IDCT_LIBMPEG2MMX 4 +#define FF_IDCT_PS2 5 +#define FF_IDCT_MLIB 6 +#define FF_IDCT_ARM 7 +#define FF_IDCT_ALTIVEC 8 +#define FF_IDCT_SH4 9 +#define FF_IDCT_SIMPLEARM 10 + + /** + * slice count. + * - encoding: set by lavc + * - decoding: set by user (or 0) + */ + int slice_count; + /** + * slice offsets in the frame in bytes. + * - encoding: set/allocated by lavc + * - decoding: set/allocated by user (or NULL) + */ + int *slice_offset; + + /** + * error concealment flags. + * - encoding: unused + * - decoding: set by user + */ + int error_concealment; +#define FF_EC_GUESS_MVS 1 +#define FF_EC_DEBLOCK 2 + + /** + * dsp_mask could be add used to disable unwanted CPU features + * CPU features (i.e. MMX, SSE. ...) + * + * with FORCE flag you may instead enable given CPU features + * (Dangerous: usable in case of misdetection, improper usage however will + * result into program crash) + */ + unsigned dsp_mask; +#define FF_MM_FORCE 0x80000000 /* force usage of selected flags (OR) */ + /* lower 16 bits - CPU features */ +#ifdef HAVE_MMX +#define FF_MM_MMX 0x0001 /* standard MMX */ +#define FF_MM_3DNOW 0x0004 /* AMD 3DNOW */ +#define FF_MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */ +#define FF_MM_SSE 0x0008 /* SSE functions */ +#define FF_MM_SSE2 0x0010 /* PIV SSE2 functions */ +#endif /* HAVE_MMX */ + + /** + * bits per sample/pixel from the demuxer (needed for huffyuv). + * - encoding: set by lavc + * - decoding: set by user + */ + int bits_per_sample; + + /** + * prediction method (needed for huffyuv). + * - encoding: set by user + * - decoding: unused + */ + int prediction_method; +#define FF_PRED_LEFT 0 +#define FF_PRED_PLANE 1 +#define FF_PRED_MEDIAN 2 + + /** + * sample aspect ratio (0 if unknown). + * numerator and denominator must be relative prime and smaller then 256 for some video standards + * - encoding: set by user. + * - decoding: set by lavc. + */ + //AVRational sample_aspect_ratio; + + /** + * the picture in the bitstream. + * - encoding: set by lavc + * - decoding: set by lavc + */ + AVFrame *coded_frame; + + /** + * debug. + * - encoding: set by user. + * - decoding: set by user. + */ + int debug; +#define FF_DEBUG_PICT_INFO 1 +#define FF_DEBUG_RC 2 +#define FF_DEBUG_BITSTREAM 4 +#define FF_DEBUG_MB_TYPE 8 +#define FF_DEBUG_QP 16 +#define FF_DEBUG_MV 32 +//#define FF_DEBUG_VIS_MV 0x00000040 +#define FF_DEBUG_SKIP 0x00000080 +#define FF_DEBUG_STARTCODE 0x00000100 +#define FF_DEBUG_PTS 0x00000200 +#define FF_DEBUG_ER 0x00000400 +#define FF_DEBUG_MMCO 0x00000800 +#define FF_DEBUG_BUGS 0x00001000 +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 + + /** + * debug. + * - encoding: set by user. + * - decoding: set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames + + /** + * error. + * - encoding: set by lavc if flags&CODEC_FLAG_PSNR + * - decoding: unused + */ + uint64_t error[4]; + + /** + * minimum MB quantizer. + * - encoding: set by user. + * - decoding: unused + */ + int mb_qmin; + + /** + * maximum MB quantizer. + * - encoding: set by user. + * - decoding: unused + */ + int mb_qmax; + + /** + * motion estimation compare function. + * - encoding: set by user. + * - decoding: unused + */ + int me_cmp; + /** + * subpixel motion estimation compare function. + * - encoding: set by user. + * - decoding: unused + */ + int me_sub_cmp; + /** + * macroblock compare function (not supported yet). + * - encoding: set by user. + * - decoding: unused + */ + int mb_cmp; + /** + * interlaced dct compare function + * - encoding: set by user. + * - decoding: unused + */ + int ildct_cmp; +#define FF_CMP_SAD 0 +#define FF_CMP_SSE 1 +#define FF_CMP_SATD 2 +#define FF_CMP_DCT 3 +#define FF_CMP_PSNR 4 +#define FF_CMP_BIT 5 +#define FF_CMP_RD 6 +#define FF_CMP_ZERO 7 +#define FF_CMP_VSAD 8 +#define FF_CMP_VSSE 9 +#define FF_CMP_CHROMA 256 + + /** + * ME diamond size & shape. + * - encoding: set by user. + * - decoding: unused + */ + int dia_size; + + /** + * amount of previous MV predictors (2a+1 x 2a+1 square). + * - encoding: set by user. + * - decoding: unused + */ + int last_predictor_count; + + /** + * pre pass for motion estimation. + * - encoding: set by user. + * - decoding: unused + */ + int pre_me; + + /** + * motion estimation pre pass compare function. + * - encoding: set by user. + * - decoding: unused + */ + int me_pre_cmp; + + /** + * ME pre pass diamond size & shape. + * - encoding: set by user. + * - decoding: unused + */ + int pre_dia_size; + + /** + * subpel ME quality. + * - encoding: set by user. + * - decoding: unused + */ + int me_subpel_quality; + + /** + * callback to negotiate the pixelFormat. + * @param fmt is the list of formats which are supported by the codec, + * its terminated by -1 as 0 is a valid format, the formats are ordered by quality + * the first is allways the native one + * @return the choosen format + * - encoding: unused + * - decoding: set by user, if not set then the native format will always be choosen + */ + enum PixelFormat (*get_format)(struct AVCodecContext *s, enum PixelFormat * fmt); + + /** + * DTG active format information (additionnal aspect ratio + * information only used in DVB MPEG2 transport streams). 0 if + * not set. + * + * - encoding: unused. + * - decoding: set by decoder + */ + int dtg_active_format; +#define FF_DTG_AFD_SAME 8 +#define FF_DTG_AFD_4_3 9 +#define FF_DTG_AFD_16_9 10 +#define FF_DTG_AFD_14_9 11 +#define FF_DTG_AFD_4_3_SP_14_9 13 +#define FF_DTG_AFD_16_9_SP_14_9 14 +#define FF_DTG_AFD_SP_4_3 15 + + /** + * Maximum motion estimation search range in subpel units. + * if 0 then no limit + * + * - encoding: set by user. + * - decoding: unused. + */ + int me_range; + + /** + * frame_rate_base. + * for variable fps this is 1 + * - encoding: set by user. + * - decoding: set by lavc. + * @todo move this after frame_rate + */ + + int frame_rate_base; + /** + * intra quantizer bias. + * - encoding: set by user. + * - decoding: unused + */ + int intra_quant_bias; +#define FF_DEFAULT_QUANT_BIAS 999999 + + /** + * inter quantizer bias. + * - encoding: set by user. + * - decoding: unused + */ + int inter_quant_bias; + + /** + * color table ID. + * - encoding: unused. + * - decoding: which clrtable should be used for 8bit RGB images + * table have to be stored somewhere FIXME + */ + int color_table_id; + + /** + * internal_buffer count. + * Dont touch, used by lavc default_get_buffer() + */ + int internal_buffer_count; + + /** + * internal_buffers. + * Dont touch, used by lavc default_get_buffer() + */ + void *internal_buffer; + +#define FF_LAMBDA_SHIFT 7 +#define FF_LAMBDA_SCALE (1<<FF_LAMBDA_SHIFT) +#define FF_QP2LAMBDA 118 ///< factor to convert from H.263 QP to lambda +#define FF_LAMBDA_MAX (256*128-1) + +#define FF_QUALITY_SCALE FF_LAMBDA_SCALE //FIXME maybe remove + /** + * global quality for codecs which cannot change it per frame. + * this should be proportional to MPEG1/2/4 qscale. + * - encoding: set by user. + * - decoding: unused + */ + int global_quality; + +#define FF_CODER_TYPE_VLC 0 +#define FF_CODER_TYPE_AC 1 + /** + * coder type + * - encoding: set by user. + * - decoding: unused + */ + int coder_type; + + /** + * context model + * - encoding: set by user. + * - decoding: unused + */ + int context_model; + + /** + * slice flags + * - encoding: unused + * - decoding: set by user. + */ + int slice_flags; +#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display +#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics) +#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1) + + /** + * XVideo Motion Acceleration + * - encoding: forbidden + * - decoding: set by decoder + */ + int xvmc_acceleration; + + /** + * macroblock decision mode + * - encoding: set by user. + * - decoding: unused + */ + int mb_decision; +#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp +#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits +#define FF_MB_DECISION_RD 2 ///< rate distoration + + /** + * custom intra quantization matrix + * - encoding: set by user, can be NULL + * - decoding: set by lavc + */ + uint16_t *intra_matrix; + + /** + * custom inter quantization matrix + * - encoding: set by user, can be NULL + * - decoding: set by lavc + */ + uint16_t *inter_matrix; + + /** + * fourcc from the AVI stream header (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * this is used to workaround some encoder bugs + * - encoding: unused + * - decoding: set by user, will be converted to upper case by lavc during init + */ + unsigned int stream_codec_tag; + + /** + * scene change detection threshold. + * 0 is default, larger means fewer detected scene changes + * - encoding: set by user. + * - decoding: unused + */ + int scenechange_threshold; + + /** + * minimum lagrange multipler + * - encoding: set by user. + * - decoding: unused + */ + int lmin; + + /** + * maximum lagrange multipler + * - encoding: set by user. + * - decoding: unused + */ + int lmax; + + /** + * Palette control structure + * - encoding: ??? (no palette-enabled encoder yet) + * - decoding: set by user. + */ + struct AVPaletteControl *palctrl; + + /** + * noise reduction strength + * - encoding: set by user. + * - decoding: unused + */ + int noise_reduction; + + /** + * called at the beginning of a frame to get cr buffer for it. + * buffer type (size, hints) must be the same. lavc won't check it. + * lavc will pass previous buffer in pic, function should return + * same buffer or new buffer with old frame "painted" into it. + * if pic.data[0] == NULL must behave like get_buffer(). + * - encoding: unused + * - decoding: set by lavc, user can override + */ + int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * number of bits which should be loaded into the rc buffer before decoding starts + * - encoding: set by user. + * - decoding: unused + */ + int rc_initial_buffer_occupancy; + + /** + * + * - encoding: set by user. + * - decoding: unused + */ + int inter_threshold; + + /** + * CODEC_FLAG2_*. + * - encoding: set by user. + * - decoding: set by user. + */ + int flags2; + + /** + * simulates errors in the bitstream to test error concealment. + * - encoding: set by user. + * - decoding: unused. + */ + int error_rate; + + /** + * MP3 antialias algorithm, see FF_AA_* below. + * - encoding: unused + * - decoding: set by user + */ + int antialias_algo; +#define FF_AA_AUTO 0 +#define FF_AA_FASTINT 1 //not implemented yet +#define FF_AA_INT 2 +#define FF_AA_FLOAT 3 + /** + * Quantizer noise shaping. + * - encoding: set by user + * - decoding: unused + */ + int quantizer_noise_shaping; +} AVCodecContext; + +/** + * Parse option(s) and sets fields in passed structure + * @param strct structure where the parsed results will be written + * @param list list with AVOptions + * @param opts string with options for parsing + */ +int avoption_parse(void* strct, const AVOption* list, const char* opts); + + +/** + * AVCodec. + */ +typedef struct AVCodec { + const char *name; + enum CodecType type; + int id; + int priv_data_size; + int (*init)(AVCodecContext *); + int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); + int (*close)(AVCodecContext *); + int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, + uint8_t *buf, int buf_size); + int capabilities; + const AVOption *options; + struct AVCodec *next; + void (*flush)(AVCodecContext *); +} AVCodec; + +/** + * four components are given, that's all. + * the last component is alpha + */ +typedef struct AVPicture { + uint8_t *data[4]; + int linesize[4]; ///< number of bytes per line +} AVPicture; + +/** + * AVPaletteControl + * This structure defines a method for communicating palette changes + * between and demuxer and a decoder. + */ +#define AVPALETTE_SIZE 1024 +#define AVPALETTE_COUNT 256 +typedef struct AVPaletteControl { + + /* demuxer sets this to 1 to indicate the palette has changed; + * decoder resets to 0 */ + int palette_changed; + + /* 4-byte ARGB palette entries, stored in native byte order; note that + * the individual palette components should be on a 8-bit scale; if + * the palette data comes from a IBM VGA native format, the component + * data is probably 6 bits in size and needs to be scaled */ + unsigned int palette[AVPALETTE_COUNT]; + +} AVPaletteControl; + +extern AVCodec shorten_decoder; + +/* pcm codecs */ +#define PCM_CODEC(id, name) \ +extern AVCodec name ## _decoder; \ +extern AVCodec name ## _encoder + +PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); +PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); +PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); +PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); +PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); +PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); +PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); +PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); + +/* adpcm codecs */ + +PCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt); +PCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); +PCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); +PCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); +PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws); +PCM_CODEC(CODEC_ID_ADPCM_SMJPEG, adpcm_ima_smjpeg); +PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); +PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); +PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); +PCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx); +PCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); + +#undef PCM_CODEC + + + +/* resample.c */ + +struct ReSampleContext; + +typedef struct ReSampleContext ReSampleContext; + +ReSampleContext *audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate); +int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); +void audio_resample_close(ReSampleContext *s); + +/* YUV420 format is assumed ! */ + +struct ImgReSampleContext; + +typedef struct ImgReSampleContext ImgReSampleContext; + +ImgReSampleContext *img_resample_init(int output_width, int output_height, + int input_width, int input_height); + +ImgReSampleContext *img_resample_full_init(int owidth, int oheight, + int iwidth, int iheight, + int topBand, int bottomBand, + int leftBand, int rightBand); + +void img_resample(ImgReSampleContext *s, + AVPicture *output, const AVPicture *input); + +void img_resample_close(ImgReSampleContext *s); + +/** + * Allocate memory for a picture. Call avpicture_free to free it. + * + * @param picture the picture to be filled in. + * @param pix_fmt the format of the picture. + * @param width the width of the picture. + * @param height the height of the picture. + * @return 0 if successful, -1 if not. + */ +int avpicture_alloc(AVPicture *picture, int pix_fmt, int width, int height); + +void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift); +const char *avcodec_get_pix_fmt_name(int pix_fmt); +enum PixelFormat avcodec_get_pix_fmt(const char* name); + +#define FF_LOSS_RESOLUTION 0x0001 /* loss due to resolution change */ +#define FF_LOSS_DEPTH 0x0002 /* loss due to color depth change */ +#define FF_LOSS_COLORSPACE 0x0004 /* loss due to color space conversion */ +#define FF_LOSS_ALPHA 0x0008 /* loss of alpha bits */ +#define FF_LOSS_COLORQUANT 0x0010 /* loss due to color quantization */ +#define FF_LOSS_CHROMA 0x0020 /* loss of chroma (e.g. rgb to gray conversion) */ + +int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, + int has_alpha); +int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt, + int has_alpha, int *loss_ptr); + +#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ +#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ +int img_get_alpha_info(const AVPicture *src, + int pix_fmt, int width, int height); + +/* convert among pixel formats */ +int img_convert(AVPicture *dst, int dst_pix_fmt, + const AVPicture *src, int pix_fmt, + int width, int height); + +/* deinterlace a picture */ +int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height); + +/* external high level API */ + +extern AVCodec *first_avcodec; + +/* returns LIBAVCODEC_VERSION_INT constant */ +unsigned avcodec_version(void); +/* returns LIBAVCODEC_BUILD constant */ +unsigned avcodec_build(void); +void avcodec_init(void); + +void register_avcodec(AVCodec *format); +AVCodec *avcodec_find_encoder(enum CodecID id); +AVCodec *avcodec_find_encoder_by_name(const char *name); +AVCodec *avcodec_find_decoder(enum CodecID id); +AVCodec *avcodec_find_decoder_by_name(const char *name); +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); + +void avcodec_get_context_defaults(AVCodecContext *s); +AVCodecContext *avcodec_alloc_context(void); +AVFrame *avcodec_alloc_frame(void); + +int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_default_free_buffers(AVCodecContext *s); + +/** + * opens / inits the AVCodecContext. + * not thread save! + */ +int avcodec_open(AVCodecContext *avctx, AVCodec *codec); + +int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + uint8_t *buf, int buf_size); +int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, + int *data_size_ptr, + uint8_t *buf, int buf_size); +int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const short *samples); + +int avcodec_close(AVCodecContext *avctx); + +void avcodec_register_all(void); + +void avcodec_flush_buffers(AVCodecContext *avctx); + +/* misc usefull functions */ + +/** + * returns a single letter to describe the picture type + */ +char av_get_pict_type_char(int pict_type); + +/** + * reduce a fraction. + * this is usefull for framerate calculations + * @param max the maximum allowed for dst_nom & dst_den + * @return 1 if exact, 0 otherwise + */ +int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max); + +/** + * rescale a 64bit integer. + * a simple a*b/c isnt possible as it can overflow + */ +int64_t av_rescale(int64_t a, int b, int c); + + +/** + * Interface for 0.5.0 version + * + * do not even think about it's usage for this moment + */ + +typedef struct { + /// compressed size used from given memory buffer + int size; + /// I/P/B frame type + int frame_type; +} avc_enc_result_t; + +/** + * Commands + * order can't be changed - once it was defined + */ +typedef enum { + // general commands + AVC_OPEN_BY_NAME = 0xACA000, + AVC_OPEN_BY_CODEC_ID, + AVC_OPEN_BY_FOURCC, + AVC_CLOSE, + + AVC_FLUSH, + // pin - struct { uint8_t* src, uint_t src_size } + // pout - struct { AVPicture* img, consumed_bytes, + AVC_DECODE, + // pin - struct { AVPicture* img, uint8_t* dest, uint_t dest_size } + // pout - uint_t used_from_dest_size + AVC_ENCODE, + + // query/get video commands + AVC_GET_VERSION = 0xACB000, + AVC_GET_WIDTH, + AVC_GET_HEIGHT, + AVC_GET_DELAY, + AVC_GET_QUANT_TABLE, + // ... + + // query/get audio commands + AVC_GET_FRAME_SIZE = 0xABC000, + + // maybe define some simple structure which + // might be passed to the user - but they can't + // contain any codec specific parts and these + // calls are usualy necessary only few times + + // set video commands + AVC_SET_WIDTH = 0xACD000, + AVC_SET_HEIGHT, + + // set video encoding commands + AVC_SET_FRAME_RATE = 0xACD800, + AVC_SET_QUALITY, + AVC_SET_HURRY_UP, + + // set audio commands + AVC_SET_SAMPLE_RATE = 0xACE000, + AVC_SET_CHANNELS, + +} avc_cmd_t; + +/** + * \param handle allocated private structure by libavcodec + * for initialization pass NULL - will be returned pout + * user is supposed to know nothing about its structure + * \param cmd type of operation to be performed + * \param pint input parameter + * \param pout output parameter + * + * \returns command status - eventually for query command it might return + * integer resulting value + */ +int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout); + +/* frame parsing */ +typedef struct AVCodecParserContext { + void *priv_data; + struct AVCodecParser *parser; + int64_t frame_offset; /* offset of the current frame */ + int64_t cur_offset; /* current offset + (incremented by each av_parser_parse()) */ + int64_t last_frame_offset; /* offset of the last frame */ + /* video info */ + int pict_type; /* XXX: put it back in AVCodecContext */ + int repeat_pict; /* XXX: put it back in AVCodecContext */ + int64_t pts; /* pts of the current frame */ + int64_t dts; /* dts of the current frame */ + + /* private data */ + int64_t last_pts; + int64_t last_dts; + +#define AV_PARSER_PTS_NB 4 + int cur_frame_start_index; + int64_t cur_frame_offset[AV_PARSER_PTS_NB]; + int64_t cur_frame_pts[AV_PARSER_PTS_NB]; + int64_t cur_frame_dts[AV_PARSER_PTS_NB]; +} AVCodecParserContext; + +typedef struct AVCodecParser { + int codec_ids[3]; /* several codec IDs are permitted */ + int priv_data_size; + int (*parser_init)(AVCodecParserContext *s); + int (*parser_parse)(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size); + void (*parser_close)(AVCodecParserContext *s); + struct AVCodecParser *next; +} AVCodecParser; + +extern AVCodecParser *av_first_parser; + +void av_register_codec_parser(AVCodecParser *parser); +AVCodecParserContext *av_parser_init(int codec_id); +int av_parser_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts); +void av_parser_close(AVCodecParserContext *s); + +extern AVCodecParser mpegvideo_parser; +extern AVCodecParser mpeg4video_parser; +extern AVCodecParser h263_parser; +extern AVCodecParser h264_parser; +extern AVCodecParser mpegaudio_parser; +extern AVCodecParser ac3_parser; + +/*char *av_strdup(const char *s);*/ +void __av_freep(void **ptr); +#define av_freep(p) __av_freep((void **)(p)) +void *av_fast_realloc(void *ptr, int *size, unsigned int min_size); +/* for static data only */ +/* call av_free_static to release all staticaly allocated tables */ +void av_free_static(void); +void *__av_mallocz_static(void** location, unsigned int size); +#define av_mallocz_static(p, s) __av_mallocz_static((void **)(p), s) + +/* add by bero : in adx.c */ +int is_adx(const unsigned char *buf,size_t bufsize); + +void img_copy(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height); + +/* av_log API */ + +#include <stdarg.h> + +#define AV_LOG_ERROR 0 +#define AV_LOG_INFO 1 +#define AV_LOG_DEBUG 2 + +extern void av_log(AVCodecContext*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); +extern void av_vlog(AVCodecContext*, int level, const char *fmt, va_list); +extern int av_log_get_level(void); +extern void av_log_set_level(int); +extern void av_log_set_callback(void (*)(AVCodecContext*, int, const char*, va_list)); + +#undef AV_LOG_TRAP_PRINTF +#ifdef AV_LOG_TRAP_PRINTF +#define printf DO NOT USE +#define fprintf DO NOT USE +#undef stderr +#define stderr DO NOT USE +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* AVCODEC_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/avformat.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,628 @@ +#ifndef AVFORMAT_H +#define AVFORMAT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBAVFORMAT_BUILD 4611 + +#define LIBAVFORMAT_VERSION_INT FFMPEG_VERSION_INT +#define LIBAVFORMAT_VERSION FFMPEG_VERSION +#define LIBAVFORMAT_IDENT "FFmpeg" FFMPEG_VERSION "b" AV_STRINGIFY(LIBAVFORMAT_BUILD) + +#include <time.h> +#include <stdio.h> /* FILE */ +#include "avcodec.h" + +#include "avio.h" + +/* packet functions */ + +#ifndef MAXINT64 +#define MAXINT64 int64_t_C(0x7fffffffffffffff) +#endif + +#ifndef MININT64 +#define MININT64 int64_t_C(0x8000000000000000) +#endif + +#define AV_NOPTS_VALUE MININT64 +#define AV_TIME_BASE 1000000 + +typedef struct AVPacket { + int64_t pts; /* presentation time stamp in AV_TIME_BASE units (or + pts_den units in muxers or demuxers) */ + int64_t dts; /* decompression time stamp in AV_TIME_BASE units (or + pts_den units in muxers or demuxers) */ + uint8_t *data; + int size; + int stream_index; + int flags; + int duration; /* presentation duration (0 if not available) */ + void (*destruct)(struct AVPacket *); + void *priv; +} AVPacket; +#define PKT_FLAG_KEY 0x0001 + +/* initialize optional fields of a packet */ +static inline void av_init_packet(AVPacket *pkt) +{ + pkt->pts = AV_NOPTS_VALUE; + pkt->dts = AV_NOPTS_VALUE; + pkt->duration = 0; + pkt->flags = 0; + pkt->stream_index = 0; +} + +int av_new_packet(AVPacket *pkt, int size); +int av_dup_packet(AVPacket *pkt); + +/** + * Free a packet + * + * @param pkt packet to free + */ +static inline void av_free_packet(AVPacket *pkt) +{ + if (pkt && pkt->destruct) { + pkt->destruct(pkt); + } +} + +/*************************************************/ +/* fractional numbers for exact pts handling */ + +/* the exact value of the fractional number is: 'val + num / den'. num + is assumed to be such as 0 <= num < den */ +typedef struct AVFrac { + int64_t val, num, den; +} AVFrac; + +void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den); +void av_frac_add(AVFrac *f, int64_t incr); +void av_frac_set(AVFrac *f, int64_t val); + +/*************************************************/ +/* input/output formats */ + +struct AVFormatContext; + +/* this structure contains the data a format has to probe a file */ +typedef struct AVProbeData { + const char *filename; + unsigned char *buf; + int buf_size; +} AVProbeData; + +#define AVPROBE_SCORE_MAX 100 + +typedef struct AVFormatParameters { + int frame_rate; + int frame_rate_base; + int sample_rate; + int channels; + int width; + int height; + enum PixelFormat pix_fmt; + struct AVImageFormat *image_format; + int channel; /* used to select dv channel */ + const char *device; /* video4linux, audio or DV device */ + const char *standard; /* tv standard, NTSC, PAL, SECAM */ + int mpeg2ts_raw:1; /* force raw MPEG2 transport stream output, if possible */ + int mpeg2ts_compute_pcr:1; /* compute exact PCR for each transport + stream packet (only meaningful if + mpeg2ts_raw is TRUE */ + int initial_pause:1; /* do not begin to play the stream + immediately (RTSP only) */ +} AVFormatParameters; + +#define AVFMT_NOFILE 0x0001 /* no file should be opened */ +#define AVFMT_NEEDNUMBER 0x0002 /* needs '%d' in filename */ +#define AVFMT_SHOW_IDS 0x0008 /* show format stream IDs numbers */ +#define AVFMT_RAWPICTURE 0x0020 /* format wants AVPicture structure for + raw picture data */ + +typedef struct AVOutputFormat { + const char *name; + const char *long_name; + const char *mime_type; + const char *extensions; /* comma separated extensions */ + /* size of private data so that it can be allocated in the wrapper */ + int priv_data_size; + /* output support */ + enum CodecID audio_codec; /* default audio codec */ + enum CodecID video_codec; /* default video codec */ + int (*write_header)(struct AVFormatContext *); + int (*write_packet)(struct AVFormatContext *, + int stream_index, + const uint8_t *buf, int size, int64_t pts); + int (*write_trailer)(struct AVFormatContext *); + /* can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER */ + int flags; + /* currently only used to set pixel format if not YUV420P */ + int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *); + /* private fields */ + struct AVOutputFormat *next; +} AVOutputFormat; + +typedef struct AVInputFormat { + const char *name; + const char *long_name; + /* size of private data so that it can be allocated in the wrapper */ + int priv_data_size; + /* tell if a given file has a chance of being parsing by this format */ + int (*read_probe)(AVProbeData *); + /* read the format header and initialize the AVFormatContext + structure. Return 0 if OK. 'ap' if non NULL contains + additionnal paramters. Only used in raw format right + now. 'av_new_stream' should be called to create new streams. */ + int (*read_header)(struct AVFormatContext *, + AVFormatParameters *ap); + /* read one packet and put it in 'pkt'. pts and flags are also + set. 'av_new_stream' can be called only if the flag + AVFMTCTX_NOHEADER is used. */ + int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); + /* close the stream. The AVFormatContext and AVStreams are not + freed by this function */ + int (*read_close)(struct AVFormatContext *); + /* seek at or before a given timestamp (given in AV_TIME_BASE + units) relative to the frames in stream component stream_index */ + int (*read_seek)(struct AVFormatContext *, + int stream_index, int64_t timestamp); + /* can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER */ + int flags; + /* if extensions are defined, then no probe is done. You should + usually not use extension format guessing because it is not + reliable enough */ + const char *extensions; + /* general purpose read only value that the format can use */ + int value; + + /* start/resume playing - only meaningful if using a network based format + (RTSP) */ + int (*read_play)(struct AVFormatContext *); + + /* pause playing - only meaningful if using a network based format + (RTSP) */ + int (*read_pause)(struct AVFormatContext *); + + /* private fields */ + struct AVInputFormat *next; +} AVInputFormat; + +typedef struct AVIndexEntry { + int64_t pos; + int64_t timestamp; +#define AVINDEX_KEYFRAME 0x0001 +/* the following 2 flags indicate that the next/prev keyframe is known, and scaning for it isnt needed */ + int flags; + int min_distance; /* min distance between this and the previous keyframe, used to avoid unneeded searching */ +} AVIndexEntry; + +typedef struct AVStream { + int index; /* stream index in AVFormatContext */ + int id; /* format specific stream id */ + AVCodecContext codec; /* codec context */ + int r_frame_rate; /* real frame rate of the stream */ + int r_frame_rate_base;/* real frame rate base of the stream */ + void *priv_data; + /* internal data used in av_find_stream_info() */ + int64_t codec_info_duration; + int codec_info_nb_frames; + /* encoding: PTS generation when outputing stream */ + AVFrac pts; + /* ffmpeg.c private use */ + int stream_copy; /* if TRUE, just copy stream */ + /* quality, as it has been removed from AVCodecContext and put in AVVideoFrame + * MN:dunno if thats the right place, for it */ + float quality; + /* decoding: position of the first frame of the component, in + AV_TIME_BASE fractional seconds. */ + int64_t start_time; + /* decoding: duration of the stream, in AV_TIME_BASE fractional + seconds. */ + int64_t duration; + + /* av_read_frame() support */ + int need_parsing; + struct AVCodecParserContext *parser; + + int64_t cur_dts; + int last_IP_duration; + /* av_seek_frame() support */ + AVIndexEntry *index_entries; /* only used if the format does not + support seeking natively */ + int nb_index_entries; + int index_entries_allocated_size; +} AVStream; + +#define AVFMTCTX_NOHEADER 0x0001 /* signal that no header is present + (streams are added dynamically) */ + +#define MAX_STREAMS 20 + +/* format I/O context */ +typedef struct AVFormatContext { + /* can only be iformat or oformat, not both at the same time */ + struct AVInputFormat *iformat; + struct AVOutputFormat *oformat; + void *priv_data; + ByteIOContext pb; + int nb_streams; + AVStream *streams[MAX_STREAMS]; + char filename[1024]; /* input or output filename */ + /* stream info */ + char title[512]; + char author[512]; + char copyright[512]; + char comment[512]; + char album[512]; + int year; /* ID3 year, 0 if none */ + int track; /* track number, 0 if none */ + char genre[32]; /* ID3 genre */ + + int ctx_flags; /* format specific flags, see AVFMTCTX_xx */ + /* private data for pts handling (do not modify directly) */ + int pts_wrap_bits; /* number of bits in pts (used for wrapping control) */ + int pts_num, pts_den; /* value to convert to seconds */ + /* This buffer is only needed when packets were already buffered but + not decoded, for example to get the codec parameters in mpeg + streams */ + struct AVPacketList *packet_buffer; + + /* decoding: position of the first frame of the component, in + AV_TIME_BASE fractional seconds. NEVER set this value directly: + it is deduced from the AVStream values. */ + int64_t start_time; + /* decoding: duration of the stream, in AV_TIME_BASE fractional + seconds. NEVER set this value directly: it is deduced from the + AVStream values. */ + int64_t duration; + /* decoding: total file size. 0 if unknown */ + int64_t file_size; + /* decoding: total stream bitrate in bit/s, 0 if not + available. Never set it directly if the file_size and the + duration are known as ffmpeg can compute it automatically. */ + int bit_rate; + + /* av_read_frame() support */ + AVStream *cur_st; + const uint8_t *cur_ptr; + int cur_len; + AVPacket cur_pkt; + + /* the following are used for pts/dts unit conversion */ + int64_t last_pkt_stream_pts; + int64_t last_pkt_stream_dts; + int64_t last_pkt_pts; + int64_t last_pkt_dts; + int last_pkt_pts_frac; + int last_pkt_dts_frac; + + /* av_seek_frame() support */ + int64_t data_offset; /* offset of the first packet */ + int index_built; +} AVFormatContext; + +typedef struct AVPacketList { + AVPacket pkt; + struct AVPacketList *next; +} AVPacketList; + +extern AVInputFormat *first_iformat; +extern AVOutputFormat *first_oformat; + +/* still image support */ +struct AVInputImageContext; +typedef struct AVInputImageContext AVInputImageContext; + +typedef struct AVImageInfo { + enum PixelFormat pix_fmt; /* requested pixel format */ + int width; /* requested width */ + int height; /* requested height */ + int interleaved; /* image is interleaved (e.g. interleaved GIF) */ + AVPicture pict; /* returned allocated image */ +} AVImageInfo; + +/* AVImageFormat.flags field constants */ +#define AVIMAGE_INTERLEAVED 0x0001 /* image format support interleaved output */ + +typedef struct AVImageFormat { + const char *name; + const char *extensions; + /* tell if a given file has a chance of being parsing by this format */ + int (*img_probe)(AVProbeData *); + /* read a whole image. 'alloc_cb' is called when the image size is + known so that the caller can allocate the image. If 'allo_cb' + returns non zero, then the parsing is aborted. Return '0' if + OK. */ + int (*img_read)(ByteIOContext *, + int (*alloc_cb)(void *, AVImageInfo *info), void *); + /* write the image */ + int supported_pixel_formats; /* mask of supported formats for output */ + int (*img_write)(ByteIOContext *, AVImageInfo *); + int flags; + struct AVImageFormat *next; +} AVImageFormat; + +void av_register_image_format(AVImageFormat *img_fmt); +AVImageFormat *av_probe_image_format(AVProbeData *pd); +AVImageFormat *guess_image_format(const char *filename); +int av_read_image(ByteIOContext *pb, const char *filename, + AVImageFormat *fmt, + int (*alloc_cb)(void *, AVImageInfo *info), void *opaque); +int av_write_image(ByteIOContext *pb, AVImageFormat *fmt, AVImageInfo *img); + +extern AVImageFormat *first_image_format; + +extern AVImageFormat pnm_image_format; +extern AVImageFormat pbm_image_format; +extern AVImageFormat pgm_image_format; +extern AVImageFormat ppm_image_format; +extern AVImageFormat pam_image_format; +extern AVImageFormat pgmyuv_image_format; +extern AVImageFormat yuv_image_format; +#ifdef CONFIG_ZLIB +extern AVImageFormat png_image_format; +#endif +extern AVImageFormat jpeg_image_format; +extern AVImageFormat gif_image_format; + +/* XXX: use automatic init with either ELF sections or C file parser */ +/* modules */ + +/* mpeg.c */ +extern AVInputFormat mpegps_demux; +int mpegps_init(void); + +/* mpegts.c */ +extern AVInputFormat mpegts_demux; +int mpegts_init(void); + +/* rm.c */ +int rm_init(void); + +/* crc.c */ +int crc_init(void); + +/* img.c */ +int img_init(void); + +/* asf.c */ +int asf_init(void); + +/* avienc.c */ +int avienc_init(void); + +/* avidec.c */ +int avidec_init(void); + +/* swf.c */ +int swf_init(void); + +/* mov.c */ +int mov_init(void); + +/* movenc.c */ +int movenc_init(void); + +/* flvenc.c */ +int flvenc_init(void); + +/* flvdec.c */ +int flvdec_init(void); + +/* jpeg.c */ +int jpeg_init(void); + +/* gif.c */ +int gif_init(void); + +/* au.c */ +int au_init(void); + +/* amr.c */ +int amr_init(void); + +/* wav.c */ +int wav_init(void); + +/* raw.c */ +int pcm_read_seek(AVFormatContext *s, + int stream_index, int64_t timestamp); +int raw_init(void); + +/* mp3.c */ +int mp3_init(void); + +/* yuv4mpeg.c */ +int yuv4mpeg_init(void); + +/* ogg.c */ +int ogg_init(void); + +/* dv.c */ +int dv_init(void); + +/* ffm.c */ +int ffm_init(void); + +/* rtsp.c */ +extern AVInputFormat redir_demux; +int redir_open(AVFormatContext **ic_ptr, ByteIOContext *f); + +/* 4xm.c */ +int fourxm_init(void); + +/* psxstr.c */ +int str_init(void); + +/* idroq.c */ +int roq_init(void); + +/* ipmovie.c */ +int ipmovie_init(void); + +/* nut.c */ +int nut_init(void); + +/* wc3movie.c */ +int wc3_init(void); + +/* westwood.c */ +int westwood_init(void); + +/* segafilm.c */ +int film_init(void); + +/* idcin.c */ +int idcin_init(void); + +/* flic.c */ +int flic_init(void); + +/* sierravmd.c */ +int vmd_init(void); + +//#include "rtp.h" + +//#include "rtsp.h" + +/* yuv4mpeg.c */ +extern AVOutputFormat yuv4mpegpipe_oformat; + +/* utils.c */ +void av_register_input_format(AVInputFormat *format); +void av_register_output_format(AVOutputFormat *format); +AVOutputFormat *guess_stream_format(const char *short_name, + const char *filename, const char *mime_type); +AVOutputFormat *guess_format(const char *short_name, + const char *filename, const char *mime_type); + +void av_hex_dump(FILE *f, uint8_t *buf, int size); +void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); + +void av_register_all(void); + +typedef struct FifoBuffer { + uint8_t *buffer; + uint8_t *rptr, *wptr, *end; +} FifoBuffer; + +int fifo_init(FifoBuffer *f, int size); +void fifo_free(FifoBuffer *f); +int fifo_size(FifoBuffer *f, uint8_t *rptr); +int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr); +void fifo_write(FifoBuffer *f, uint8_t *buf, int size, uint8_t **wptr_ptr); + +/* media file input */ +AVInputFormat *av_find_input_format(const char *short_name); +AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); +int av_open_input_stream(AVFormatContext **ic_ptr, + ByteIOContext *pb, const char *filename, + AVInputFormat *fmt, AVFormatParameters *ap); +int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, + AVInputFormat *fmt, + int buf_size, + AVFormatParameters *ap); + +#define AVERROR_UNKNOWN (-1) /* unknown error */ +#define AVERROR_IO (-2) /* i/o error */ +#define AVERROR_NUMEXPECTED (-3) /* number syntax expected in filename */ +#define AVERROR_INVALIDDATA (-4) /* invalid data found */ +#define AVERROR_NOMEM (-5) /* not enough memory */ +#define AVERROR_NOFMT (-6) /* unknown format */ +#define AVERROR_NOTSUPP (-7) /* operation not supported */ + +int av_find_stream_info(AVFormatContext *ic); +int av_read_packet(AVFormatContext *s, AVPacket *pkt); +int av_read_frame(AVFormatContext *s, AVPacket *pkt); +int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp); +int av_read_play(AVFormatContext *s); +int av_read_pause(AVFormatContext *s); +void av_close_input_file(AVFormatContext *s); +AVStream *av_new_stream(AVFormatContext *s, int id); +void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits, + int pts_num, int pts_den); + +int av_find_default_stream_index(AVFormatContext *s); +int av_index_search_timestamp(AVStream *st, int timestamp); +int av_add_index_entry(AVStream *st, + int64_t pos, int64_t timestamp, int distance, int flags); + +/* media file output */ +int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap); +int av_write_header(AVFormatContext *s); +int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, + int size); +int av_write_trailer(AVFormatContext *s); + +void dump_format(AVFormatContext *ic, + int index, + const char *url, + int is_output); +int parse_image_size(int *width_ptr, int *height_ptr, const char *str); +int parse_frame_rate(int *frame_rate, int *frame_rate_base, const char *arg); +int64_t parse_date(const char *datestr, int duration); + +int64_t av_gettime(void); + +/* ffm specific for ffserver */ +#define FFM_PACKET_SIZE 4096 +offset_t ffm_read_write_index(int fd); +void ffm_write_write_index(int fd, offset_t pos); +void ffm_set_write_index(AVFormatContext *s, offset_t pos, offset_t file_size); + +int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); + +int get_frame_filename(char *buf, int buf_size, + const char *path, int number); +int filename_number_test(const char *filename); + +/* grab specific */ +int video_grab_init(void); +int audio_init(void); + +/* DV1394 */ +int dv1394_init(void); + +#ifdef HAVE_AV_CONFIG_H + +#include "os_support.h" + +void __dynarray_add(unsigned long **tab_ptr, int *nb_ptr, unsigned long elem); + +#ifdef __GNUC__ +#define dynarray_add(tab, nb_ptr, elem)\ +do {\ + typeof(tab) _tab = (tab);\ + typeof(elem) _elem = (elem);\ + (void)sizeof(**_tab == _elem); /* check that types are compatible */\ + __dynarray_add((unsigned long **)_tab, nb_ptr, (unsigned long)_elem);\ +} while(0) +#else +#define dynarray_add(tab, nb_ptr, elem)\ +do {\ + __dynarray_add((unsigned long **)(tab), nb_ptr, (unsigned long)(elem));\ +} while(0) +#endif + +struct in_addr; +int resolve_host(struct in_addr *sin_addr, const char *hostname); + +void url_split(char *proto, int proto_size, + char *hostname, int hostname_size, + int *port_ptr, + char *path, int path_size, + const char *url); + +int match_ext(const char *filename, const char *extensions); + +#endif /* HAVE_AV_CONFIG_H */ + +#ifdef __cplusplus +} +#endif + +#endif /* AVFORMAT_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/avi.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,43 @@ +#ifndef FFMPEG_AVI_H +#define FFMPEG_AVI_H + +#include "avcodec.h" + +#define AVIF_HASINDEX 0x00000010 // Index at end of file? +#define AVIF_MUSTUSEINDEX 0x00000020 +#define AVIF_ISINTERLEAVED 0x00000100 +#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames? +#define AVIF_WASCAPTUREFILE 0x00010000 +#define AVIF_COPYRIGHTED 0x00020000 + +#define AVI_MAX_RIFF_SIZE 0x40000000LL +#define AVI_MASTER_INDEX_SIZE 256 + +/* index flags */ +#define AVIIF_INDEX 0x10 + +offset_t start_tag(ByteIOContext *pb, const char *tag); +void end_tag(ByteIOContext *pb, offset_t start); + +typedef struct CodecTag { + int id; + unsigned int tag; + unsigned int invalid_asf : 1; +} CodecTag; + +void put_bmp_header(ByteIOContext *pb, AVCodecContext *enc, const CodecTag *tags, int for_asf); +int put_wav_header(ByteIOContext *pb, AVCodecContext *enc); +int wav_codec_get_id(unsigned int tag, int bps); +void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, int size); + +extern const CodecTag codec_bmp_tags[]; +extern const CodecTag codec_wav_tags[]; + +unsigned int codec_get_tag(const CodecTag *tags, int id); +enum CodecID codec_get_id(const CodecTag *tags, unsigned int tag); +unsigned int codec_get_bmp_tag(int id); +unsigned int codec_get_wav_tag(int id); +enum CodecID codec_get_bmp_id(unsigned int tag); +enum CodecID codec_get_wav_id(unsigned int tag); + +#endif /* FFMPEG_AVI_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/avio.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,178 @@ +/* + * Unbuffered io for ffmpeg system + * Copyright (c) 2001 Fabrice Bellard + * + * 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 "avformat.h" +#include "cutils.h" + +static int default_interrupt_cb(void); + +URLProtocol *first_protocol = NULL; +URLInterruptCB *url_interrupt_cb = default_interrupt_cb; + +int register_protocol(URLProtocol *protocol) +{ + URLProtocol **p; + p = &first_protocol; + while (*p != NULL) p = &(*p)->next; + *p = protocol; + protocol->next = NULL; + return 0; +} + +int url_open(URLContext **puc, const char *filename, int flags) +{ + URLContext *uc; + URLProtocol *up; + const char *p; + char proto_str[128], *q; + int err; + + p = filename; + q = proto_str; + while (*p != '\0' && *p != ':') { + /* protocols can only contain alphabetic chars */ + if (!isalpha(*p)) + goto file_proto; + if ((size_t)(q - proto_str) < sizeof(proto_str) - 1) + *q++ = *p; + p++; + } + /* if the protocol has length 1, we consider it is a dos drive */ + if (*p == '\0' || (q - proto_str) <= 1) { + file_proto: + strcpy(proto_str, "file"); + } else { + *q = '\0'; + } + + up = first_protocol; + while (up != NULL) { + if (!strcmp(proto_str, up->name)) + goto found; + up = up->next; + } + err = -ENOENT; + goto fail; + found: + uc = malloc(sizeof(URLContext) + strlen(filename)); + if (!uc) { + err = -ENOMEM; + goto fail; + } + strcpy(uc->filename, filename); + uc->prot = up; + uc->flags = flags; + uc->is_streamed = 0; /* default = not streamed */ + uc->max_packet_size = 0; /* default: stream file */ + err = up->url_open(uc, filename, flags); + if (err < 0) { + free(uc); + *puc = NULL; + return err; + } + *puc = uc; + return 0; + fail: + *puc = NULL; + return err; +} + +int url_read(URLContext *h, unsigned char *buf, int size) +{ + int ret; + if (h->flags & URL_WRONLY) + return -EIO; + ret = h->prot->url_read(h, buf, size); + return ret; +} + +offset_t url_seek(URLContext *h, offset_t pos, int whence) +{ + offset_t ret; + + if (!h->prot->url_seek) + return -EPIPE; + ret = h->prot->url_seek(h, pos, whence); + return ret; +} + +int url_close(URLContext *h) +{ + int ret; + + ret = h->prot->url_close(h); + free(h); + + return ret; +} + +int url_exist(const char *filename) +{ + URLContext *h; + if (url_open(&h, filename, URL_RDONLY) < 0) + return 0; + url_close(h); + return 1; +} + +offset_t url_filesize(URLContext *h) +{ + offset_t pos, size; + + pos = url_seek(h, 0, SEEK_CUR); + size = url_seek(h, 0, SEEK_END); + url_seek(h, pos, SEEK_SET); + return size; +} + +/* + * Return the maximum packet size associated to packetized file + * handle. If the file is not packetized (stream like http or file on + * disk), then 0 is returned. + * + * @param h file handle + * @return maximum packet size in bytes + */ +int url_get_max_packet_size(URLContext *h) +{ + return h->max_packet_size; +} + +void url_get_filename(URLContext *h, char *buf, int buf_size) +{ + pstrcpy(buf, buf_size, h->filename); +} + + +static int default_interrupt_cb(void) +{ + return 0; +} + +/** + * The callback is called in blocking functions to test regulary if + * asynchronous interruption is needed. -EINTR is returned in this + * case by the interrupted function. 'NULL' means no interrupt + * callback is given. + */ +void url_set_interrupt_cb(URLInterruptCB *interrupt_cb) +{ + if (!interrupt_cb) + interrupt_cb = default_interrupt_cb; + url_interrupt_cb = interrupt_cb; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/avio.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,169 @@ +#ifndef AVIO_H +#define AVIO_H + +/* output byte stream handling */ + +typedef int64_t offset_t; + +/* unbuffered I/O */ + +struct URLContext { + struct URLProtocol *prot; + int flags; + int is_streamed; /* true if streamed (no seek possible), default = false */ + int max_packet_size; /* if non zero, the stream is packetized with this max packet size */ + void *priv_data; + char filename[1]; /* specified filename */ +}; + +typedef struct URLContext URLContext; + +typedef struct URLPollEntry { + URLContext *handle; + int events; + int revents; +} URLPollEntry; + +#define URL_RDONLY 0 +#define URL_WRONLY 1 +#define URL_RDWR 2 + +typedef int URLInterruptCB(void); + +int url_open(URLContext **h, const char *filename, int flags); +int url_read(URLContext *h, unsigned char *buf, int size); +int url_write(URLContext *h, unsigned char *buf, int size); +offset_t url_seek(URLContext *h, offset_t pos, int whence); +int url_close(URLContext *h); +int url_exist(const char *filename); +offset_t url_filesize(URLContext *h); +int url_get_max_packet_size(URLContext *h); +void url_get_filename(URLContext *h, char *buf, int buf_size); + +/* the callback is called in blocking functions to test regulary if + asynchronous interruption is needed. -EINTR is returned in this + case by the interrupted function. 'NULL' means no interrupt + callback is given. */ +void url_set_interrupt_cb(URLInterruptCB *interrupt_cb); + +/* not implemented */ +int url_poll(URLPollEntry *poll_table, int n, int timeout); + +typedef struct URLProtocol { + const char *name; + int (*url_open)(URLContext *h, const char *filename, int flags); + int (*url_read)(URLContext *h, unsigned char *buf, int size); + int (*url_write)(URLContext *h, unsigned char *buf, int size); + offset_t (*url_seek)(URLContext *h, offset_t pos, int whence); + int (*url_close)(URLContext *h); + struct URLProtocol *next; +} URLProtocol; + +extern URLProtocol *first_protocol; +extern URLInterruptCB *url_interrupt_cb; + +int register_protocol(URLProtocol *protocol); + +typedef struct { + unsigned char *buffer; + int buffer_size; + unsigned char *buf_ptr, *buf_end; + void *opaque; + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); + void (*write_packet)(void *opaque, uint8_t *buf, int buf_size); + int (*seek)(void *opaque, offset_t offset, int whence); + offset_t pos; /* position in the file of the current buffer */ + int must_flush; /* true if the next seek should flush */ + int eof_reached; /* true if eof reached */ + int write_flag; /* true if open for writing */ + int is_streamed; + int max_packet_size; +} ByteIOContext; + +int init_put_byte(ByteIOContext *s, + unsigned char *buffer, + int buffer_size, + int write_flag, + void *opaque, + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), + void (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*seek)(void *opaque, offset_t offset, int whence)); + +void put_byte(ByteIOContext *s, int b); +void put_buffer(ByteIOContext *s, const unsigned char *buf, int size); +void put_le64(ByteIOContext *s, uint64_t val); +void put_be64(ByteIOContext *s, uint64_t val); +void put_le32(ByteIOContext *s, unsigned int val); +void put_be32(ByteIOContext *s, unsigned int val); +void put_le16(ByteIOContext *s, unsigned int val); +void put_be16(ByteIOContext *s, unsigned int val); +void put_tag(ByteIOContext *s, const char *tag); + +void put_be64_double(ByteIOContext *s, double val); +void put_strz(ByteIOContext *s, const char *buf); + +offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence); +void url_fskip(ByteIOContext *s, offset_t offset); +offset_t url_ftell(ByteIOContext *s); +int url_feof(ByteIOContext *s); + +#define URL_EOF (-1) +int url_fgetc(ByteIOContext *s); +#ifdef __GNUC__ +int url_fprintf(ByteIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); +#else +int url_fprintf(ByteIOContext *s, const char *fmt, ...); +#endif +char *url_fgets(ByteIOContext *s, char *buf, int buf_size); + +void put_flush_packet(ByteIOContext *s); + +int get_buffer(ByteIOContext *s, unsigned char *buf, int size); +int get_byte(ByteIOContext *s); +unsigned int get_le32(ByteIOContext *s); +uint64_t get_le64(ByteIOContext *s); +unsigned int get_le16(ByteIOContext *s); + +double get_be64_double(ByteIOContext *s); +char *get_strz(ByteIOContext *s, char *buf, int maxlen); +unsigned int get_be16(ByteIOContext *s); +unsigned int get_be32(ByteIOContext *s); +uint64_t get_be64(ByteIOContext *s); + +static inline int url_is_streamed(ByteIOContext *s) +{ + return s->is_streamed; +} + +int url_fdopen(ByteIOContext *s, URLContext *h); +int url_setbufsize(ByteIOContext *s, int buf_size); +int url_fopen(ByteIOContext *s, const char *filename, int flags); +int url_fclose(ByteIOContext *s); +URLContext *url_fileno(ByteIOContext *s); +int url_fget_max_packet_size(ByteIOContext *s); + +int url_open_buf(ByteIOContext *s, uint8_t *buf, int buf_size, int flags); +int url_close_buf(ByteIOContext *s); + +int url_open_dyn_buf(ByteIOContext *s); +int url_open_dyn_packet_buf(ByteIOContext *s, int max_packet_size); +int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer); + +/* file.c */ +extern URLProtocol file_protocol; +extern URLProtocol pipe_protocol; + +/* udp.c */ +extern URLProtocol udp_protocol; +int udp_set_remote_url(URLContext *h, const char *uri); +int udp_get_local_port(URLContext *h); +int udp_get_file_handle(URLContext *h); + +/* tcp.c */ +extern URLProtocol tcp_protocol; + +/* http.c */ +extern URLProtocol http_protocol; + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/aviobuf.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,383 @@ +/* + * Buffered I/O for ffmpeg system + * Copyright (c) 2000,2001 Fabrice Bellard + * + * 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 "avformat.h" +#include "avio.h" +#include <stdarg.h> + +#define IO_BUFFER_SIZE 32768 + +int init_put_byte(ByteIOContext *s, + unsigned char *buffer, + int buffer_size, + int write_flag, + void *opaque, + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), + void (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*seek)(void *opaque, offset_t offset, int whence)) +{ + s->buffer = buffer; + s->buffer_size = buffer_size; + s->buf_ptr = buffer; + s->write_flag = write_flag; + if (!s->write_flag) + s->buf_end = buffer; + else + s->buf_end = buffer + buffer_size; + s->opaque = opaque; + s->write_packet = write_packet; + s->read_packet = read_packet; + s->seek = seek; + s->pos = 0; + s->must_flush = 0; + s->eof_reached = 0; + s->is_streamed = 0; + s->max_packet_size = 0; + return 0; +} + +offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence) +{ + offset_t offset1; + + if (whence != SEEK_CUR && whence != SEEK_SET) + return -EINVAL; + + { + if (whence == SEEK_CUR) { + offset1 = s->pos - (s->buf_end - s->buffer) + (s->buf_ptr - s->buffer); + if (offset == 0) + return offset1; + offset += offset1; + } + offset1 = offset - (s->pos - (s->buf_end - s->buffer)); + if (offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { + /* can do the seek inside the buffer */ + s->buf_ptr = s->buffer + offset1; + } else { + if (!s->seek) + return -EPIPE; + s->buf_ptr = s->buffer; + s->buf_end = s->buffer; + s->seek(s->opaque, offset, SEEK_SET); + s->pos = offset; + } + s->eof_reached = 0; + } + return offset; +} + +void url_fskip(ByteIOContext *s, offset_t offset) +{ + url_fseek(s, offset, SEEK_CUR); +} + +offset_t url_ftell(ByteIOContext *s) +{ + return url_fseek(s, 0, SEEK_CUR); +} + +int url_feof(ByteIOContext *s) +{ + return s->eof_reached; +} + +/* Input stream */ + +static void fill_buffer(ByteIOContext *s) +{ + int len; + + /* no need to do anything if EOF already reached */ + if (s->eof_reached) + return; + len = s->read_packet(s->opaque, s->buffer, s->buffer_size); + if (len <= 0) { + /* do not modify buffer if EOF reached so that a seek back can + be done without rereading data */ + s->eof_reached = 1; + } else { + s->pos += len; + s->buf_ptr = s->buffer; + s->buf_end = s->buffer + len; + } +} + +/* NOTE: return 0 if EOF, so you cannot use it if EOF handling is + necessary */ +/* XXX: put an inline version */ +int get_byte(ByteIOContext *s) +{ + if (s->buf_ptr < s->buf_end) { + return *s->buf_ptr++; + } else { + fill_buffer(s); + if (s->buf_ptr < s->buf_end) + return *s->buf_ptr++; + else + return 0; + } +} + +/* NOTE: return URL_EOF (-1) if EOF */ +int url_fgetc(ByteIOContext *s) +{ + if (s->buf_ptr < s->buf_end) { + return *s->buf_ptr++; + } else { + fill_buffer(s); + if (s->buf_ptr < s->buf_end) + return *s->buf_ptr++; + else + return URL_EOF; + } +} + +int get_buffer(ByteIOContext *s, unsigned char *buf, int size) +{ + int len, size1; + + size1 = size; + while (size > 0) { + len = s->buf_end - s->buf_ptr; + if (len > size) + len = size; + if (len == 0) { + fill_buffer(s); + len = s->buf_end - s->buf_ptr; + if (len == 0) + break; + } else { + memcpy(buf, s->buf_ptr, len); + buf += len; + s->buf_ptr += len; + size -= len; + } + } + return size1 - size; +} + +unsigned int get_le16(ByteIOContext *s) +{ + unsigned int val; + val = get_byte(s); + val |= get_byte(s) << 8; + return val; +} + +unsigned int get_le32(ByteIOContext *s) +{ + unsigned int val; + val = get_byte(s); + val |= get_byte(s) << 8; + val |= get_byte(s) << 16; + val |= get_byte(s) << 24; + return val; +} + +uint64_t get_le64(ByteIOContext *s) +{ + uint64_t val; + val = (uint64_t)get_le32(s); + val |= (uint64_t)get_le32(s) << 32; + return val; +} + +unsigned int get_be16(ByteIOContext *s) +{ + unsigned int val; + val = get_byte(s) << 8; + val |= get_byte(s); + return val; +} + +unsigned int get_be32(ByteIOContext *s) +{ + unsigned int val; + val = get_byte(s) << 24; + val |= get_byte(s) << 16; + val |= get_byte(s) << 8; + val |= get_byte(s); + return val; +} + +double get_be64_double(ByteIOContext *s) +{ + union { + double d; + uint64_t ull; + } u; + + u.ull = get_be64(s); + return u.d; +} + +char *get_strz(ByteIOContext *s, char *buf, int maxlen) +{ + int i = 0; + char c; + + while ((c = get_byte(s))) { + if (i < maxlen-1) + buf[i++] = c; + } + + buf[i] = 0; /* Ensure null terminated, but may be truncated */ + + return buf; +} + +uint64_t get_be64(ByteIOContext *s) +{ + uint64_t val; + val = (uint64_t)get_be32(s) << 32; + val |= (uint64_t)get_be32(s); + return val; +} + +/* link with avio functions */ + +#define url_write_packet NULL + +static int url_read_packet(void *opaque, uint8_t *buf, int buf_size) +{ + URLContext *h = opaque; + return url_read(h, buf, buf_size); +} + +static int url_seek_packet(void *opaque, int64_t offset, int whence) +{ + URLContext *h = opaque; + url_seek(h, offset, whence); + return 0; +} + +int url_fdopen(ByteIOContext *s, URLContext *h) +{ + uint8_t *buffer; + int buffer_size, max_packet_size; + + + max_packet_size = url_get_max_packet_size(h); + if (max_packet_size) { + buffer_size = max_packet_size; /* no need to bufferize more than one packet */ + } else { + buffer_size = IO_BUFFER_SIZE; + } + buffer = malloc(buffer_size); + if (!buffer) + return -ENOMEM; + + if (init_put_byte(s, buffer, buffer_size, + (h->flags & URL_WRONLY) != 0, h, + url_read_packet, url_write_packet, url_seek_packet) < 0) { + free(buffer); + return -EIO; + } + s->is_streamed = h->is_streamed; + s->max_packet_size = max_packet_size; + return 0; +} + +/* XXX: must be called before any I/O */ +int url_setbufsize(ByteIOContext *s, int buf_size) +{ + uint8_t *buffer; + buffer = malloc(buf_size); + if (!buffer) + return -ENOMEM; + + free(s->buffer); + s->buffer = buffer; + s->buffer_size = buf_size; + s->buf_ptr = buffer; + if (!s->write_flag) + s->buf_end = buffer; + else + s->buf_end = buffer + buf_size; + return 0; +} + +/* NOTE: when opened as read/write, the buffers are only used for + reading */ +int url_fopen(ByteIOContext *s, const char *filename, int flags) +{ + URLContext *h; + int err; + + err = url_open(&h, filename, flags); + if (err < 0) + return err; + err = url_fdopen(s, h); + if (err < 0) { + url_close(h); + return err; + } + return 0; +} + +int url_fclose(ByteIOContext *s) +{ + URLContext *h = s->opaque; + + free(s->buffer); + memset(s, 0, sizeof(ByteIOContext)); + return url_close(h); +} + +URLContext *url_fileno(ByteIOContext *s) +{ + return s->opaque; +} + +/* note: unlike fgets, the EOL character is not returned and a whole + line is parsed. return NULL if first char read was EOF */ +char *url_fgets(ByteIOContext *s, char *buf, int buf_size) +{ + int c; + char *q; + + c = url_fgetc(s); + if (c == EOF) + return NULL; + q = buf; + for(;;) { + if (c == EOF || c == '\n') + break; + if ((q - buf) < buf_size - 1) + *q++ = c; + c = url_fgetc(s); + } + if (buf_size > 0) + *q = '\0'; + return buf; +} + +/* + * Return the maximum packet size associated to packetized buffered file + * handle. If the file is not packetized (stream like http or file on + * disk), then 0 is returned. + * + * @param h buffered file handle + * @return maximum packet size in bytes + */ +int url_fget_max_packet_size(ByteIOContext *s) +{ + return s->max_packet_size; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/bswap.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,129 @@ +/** + * @file bswap.h + * byte swap. + */ + +#ifndef __BSWAP_H__ +#define __BSWAP_H__ + +#ifdef HAVE_BYTESWAP_H +#include <byteswap.h> +#else + +#ifdef ARCH_X86 +static inline unsigned short ByteSwap16(unsigned short x) +{ + __asm("xchgb %b0,%h0" : + "=q" (x) : + "0" (x)); + return x; +} +#define bswap_16(x) ByteSwap16(x) + +static inline unsigned int ByteSwap32(unsigned int x) +{ +#if __CPU__ > 386 + __asm("bswap %0": + "=r" (x) : +#else + __asm("xchgb %b0,%h0\n" + " rorl $16,%0\n" + " xchgb %b0,%h0": + "=q" (x) : +#endif + "0" (x)); + return x; +} +#define bswap_32(x) ByteSwap32(x) + +static inline unsigned long long int ByteSwap64(unsigned long long int x) +{ + register union { __extension__ uint64_t __ll; + uint32_t __l[2]; } __x; + asm("xchgl %0,%1": + "=r"(__x.__l[0]),"=r"(__x.__l[1]): + "0"(bswap_32((unsigned long)x)),"1"(bswap_32((unsigned long)(x>>32)))); + return __x.__ll; +} +#define bswap_64(x) ByteSwap64(x) + +#elif defined(ARCH_SH4) + +static inline uint16_t ByteSwap16(uint16_t x) { + __asm__("swap.b %0,%0":"=r"(x):"0"(x)); + return x; +} + +static inline uint32_t ByteSwap32(uint32_t x) { + __asm__( + "swap.b %0,%0\n" + "swap.w %0,%0\n" + "swap.b %0,%0\n" + :"=r"(x):"0"(x)); + return x; +} + +#define bswap_16(x) ByteSwap16(x) +#define bswap_32(x) ByteSwap32(x) + +static inline uint64_t ByteSwap64(uint64_t x) +{ + union { + uint64_t ll; + struct { + uint32_t l,h; + } l; + } r; + r.l.l = bswap_32 (x); + r.l.h = bswap_32 (x>>32); + return r.ll; +} +#define bswap_64(x) ByteSwap64(x) + +#else + +#define bswap_16(x) (((x) & 0x00ff) << 8 | ((x) & 0xff00) >> 8) + + +// code from bits/byteswap.h (C) 1997, 1998 Free Software Foundation, Inc. +#define bswap_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +static inline uint64_t ByteSwap64(uint64_t x) +{ + union { + uint64_t ll; + uint32_t l[2]; + } w, r; + w.ll = x; + r.l[0] = bswap_32 (w.l[1]); + r.l[1] = bswap_32 (w.l[0]); + return r.ll; +} +#define bswap_64(x) ByteSwap64(x) + +#endif /* !ARCH_X86 */ + +#endif /* !HAVE_BYTESWAP_H */ + +// be2me ... BigEndian to MachineEndian +// le2me ... LittleEndian to MachineEndian + +#ifdef WORDS_BIGENDIAN +#define be2me_16(x) (x) +#define be2me_32(x) (x) +#define be2me_64(x) (x) +#define le2me_16(x) bswap_16(x) +#define le2me_32(x) bswap_32(x) +#define le2me_64(x) bswap_64(x) +#else +#define be2me_16(x) bswap_16(x) +#define be2me_32(x) bswap_32(x) +#define be2me_64(x) bswap_64(x) +#define le2me_16(x) (x) +#define le2me_32(x) (x) +#define le2me_64(x) (x) +#endif + +#endif /* __BSWAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/common.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,311 @@ +/* + * Common bit i/o utils + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2004 Roman Bogorodskiy (bmp-wma specific stuff) + * + * 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 + * + * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at> + */ + +/** + * @file common.c + * common internal api. + */ + +#include "avcodec.h" + +const uint8_t ff_sqrt_tab[128]={ + 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11 +}; + +const uint8_t ff_log2_tab[256]={ + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size) +{ + s->buf = buffer; + s->buf_end = s->buf + buffer_size; + s->buf_ptr = s->buf; + s->bit_left=32; + s->bit_buf=0; +} + +/** + * init GetBitContext. + * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits + * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end + * @param bit_size the size of the buffer in bits + */ +void init_get_bits(GetBitContext *s, + const uint8_t *buffer, int bit_size) +{ + const int buffer_size= (bit_size+7)>>3; + + s->buffer= buffer; + s->size_in_bits= bit_size; + s->buffer_end= buffer + buffer_size; +#ifdef ALT_BITSTREAM_READER + s->index=0; +#elif defined LIBMPEG2_BITSTREAM_READER +#ifdef LIBMPEG2_BITSTREAM_READER_HACK + if ((int)buffer&1) { + /* word alignment */ + s->cache = (*buffer++)<<24; + s->buffer_ptr = buffer; + s->bit_count = 16-8; + } else +#endif + { + s->buffer_ptr = buffer; + s->bit_count = 16; + s->cache = 0; + } +#elif defined A32_BITSTREAM_READER + s->buffer_ptr = (uint32_t*)buffer; + s->bit_count = 32; + s->cache0 = 0; + s->cache1 = 0; +#endif + { + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + UPDATE_CACHE(re, s) + CLOSE_READER(re, s) + } +#ifdef A32_BITSTREAM_READER + s->cache1 = 0; +#endif +} + +/** + * reads 0-32 bits. + */ +unsigned int get_bits_long(GetBitContext *s, int n){ + if(n<=17) return get_bits(s, n); + else{ + int ret= get_bits(s, 16) << (n-16); + return ret | get_bits(s, n-16); + } +} + +/** + * shows 0-32 bits. + */ +unsigned int show_bits_long(GetBitContext *s, int n){ + if(n<=17) return show_bits(s, n); + else{ + GetBitContext gb= *s; + int ret= get_bits_long(s, n); + *s= gb; + return ret; + } +} + +void align_get_bits(GetBitContext *s) +{ + int n= (-get_bits_count(s)) & 7; + if(n) skip_bits(s, n); +} + +int check_marker(GetBitContext *s, const char *msg) +{ + int bit= get_bits1(s); + if(!bit) + av_log(NULL, AV_LOG_INFO, "Marker bit missing %s\n", msg); + + return bit; +} + +/* VLC decoding */ + +//#define DEBUG_VLC + +#define GET_DATA(v, table, i, wrap, size) \ +{\ + const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ + switch(size) {\ + case 1:\ + v = *(const uint8_t *)ptr;\ + break;\ + case 2:\ + v = *(const uint16_t *)ptr;\ + break;\ + default:\ + v = *(const uint32_t *)ptr;\ + break;\ + }\ +} + + +static int alloc_table(VLC *vlc, int size) +{ + int index; + index = vlc->table_size; + vlc->table_size += size; + if (vlc->table_size > vlc->table_allocated) { + vlc->table_allocated += (1 << vlc->bits); + vlc->table = realloc(vlc->table, + sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + if (!vlc->table) + return -1; + } + return index; +} + +static int build_table(VLC *vlc, int table_nb_bits, + int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + uint32_t code_prefix, int n_prefix) +{ + int i, j, k, n, table_size, table_index, nb, n1, index; + uint32_t code; + VLC_TYPE (*table)[2]; + + table_size = 1 << table_nb_bits; + table_index = alloc_table(vlc, table_size); + + if (table_index < 0) + return -1; + table = &vlc->table[table_index]; + + for(i=0;i<table_size;i++) { + table[i][1] = 0; //bits + table[i][0] = -1; //codes + } + + /* first pass: map codes and compute auxillary table sizes */ + for(i=0;i<nb_codes;i++) { + GET_DATA(n, bits, i, bits_wrap, bits_size); + GET_DATA(code, codes, i, codes_wrap, codes_size); + /* we accept tables with holes */ + if (n <= 0) + continue; + /* if code matches the prefix, it is in the table */ + n -= n_prefix; + if (n > 0 && (code >> n) == code_prefix) { + if (n <= table_nb_bits) { + /* no need to add another table */ + j = (code << (table_nb_bits - n)) & (table_size - 1); + nb = 1 << (table_nb_bits - n); + for(k=0;k<nb;k++) { + if (table[j][1] /*bits*/ != 0) { + av_log(NULL, AV_LOG_ERROR, "incorrect codes\n"); + av_abort(); + } + table[j][1] = n; //bits + table[j][0] = i; //code + j++; + } + } else { + n -= table_nb_bits; + j = (code >> n) & ((1 << table_nb_bits) - 1); + /* compute table size */ + n1 = -table[j][1]; //bits + if (n > n1) + n1 = n; + table[j][1] = -n1; //bits + } + } + } + + /* second pass : fill auxillary tables recursively */ + for(i=0;i<table_size;i++) { + n = table[i][1]; //bits + if (n < 0) { + n = -n; + if (n > table_nb_bits) { + n = table_nb_bits; + table[i][1] = -n; //bits + } + index = build_table(vlc, n, nb_codes, + bits, bits_wrap, bits_size, + codes, codes_wrap, codes_size, + (code_prefix << table_nb_bits) | i, + n_prefix + table_nb_bits); + if (index < 0) + return -1; + /* note: realloc has been done, so reload tables */ + table = &vlc->table[table_index]; + table[i][0] = index; //code + } + } + return table_index; +} + + +/* Build VLC decoding tables suitable for use with get_vlc(). + + 'nb_bits' set thee decoding table size (2^nb_bits) entries. The + bigger it is, the faster is the decoding. But it should not be too + big to save memory and L1 cache. '9' is a good compromise. + + 'nb_codes' : number of vlcs codes + + 'bits' : table which gives the size (in bits) of each vlc code. + + 'codes' : table which gives the bit pattern of of each vlc code. + + 'xxx_wrap' : give the number of bytes between each entry of the + 'bits' or 'codes' tables. + + 'xxx_size' : gives the number of bytes of each entry of the 'bits' + or 'codes' tables. + + 'wrap' and 'size' allows to use any memory configuration and types + (byte/word/long) to store the 'bits' and 'codes' tables. +*/ +int init_vlc(VLC *vlc, int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size) +{ + vlc->bits = nb_bits; + vlc->table = NULL; + vlc->table_allocated = 0; + vlc->table_size = 0; + + if (build_table(vlc, nb_bits, nb_codes, + bits, bits_wrap, bits_size, + codes, codes_wrap, codes_size, + 0, 0) < 0) { + free(vlc->table); + return -1; + } + return 0; +} + + +void free_vlc(VLC *vlc) +{ + free(vlc->table); +} + +int64_t ff_gcd(int64_t a, int64_t b){ + if(b) return ff_gcd(b, a%b); + else return a; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/common.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,938 @@ +/** + * @file common.h + * common internal api header. + */ + +#ifndef COMMON_H +#define COMMON_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define TUNECPU generic +#undef HAVE_MMX +#define __CPU__ 586 +#define HAVE_BUILTIN_VECTOR 1 +#define CONFIG_DECODERS 1 +/*#define CONFIG_HAVE_DLOPEN 1 +#define CONFIG_HAVE_DLFCN 1*/ +/*#undef CONFIG_AUDIO_OSS*/ +#define SIMPLE_IDCT 1 +/*#undef CONFIG_FFSERVER*/ +#define CONFIG_RISKY 1 + +#define ALT_BITSTREAM_READER +//#define LIBMPEG2_BITSTREAM_READER +//#define A32_BITSTREAM_READER +//#define LIBMPEG2_BITSTREAM_READER_HACK //add BERO + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#if 1 +/* only include the following when compiling package */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <math.h> + +# ifndef ENODATA +# define ENODATA 61 +# endif + +#include <stddef.h> +#ifndef offsetof +# define offsetof(T,F) ((unsigned int)((char *)&((T *)0)->F)) +#endif + +#define AVOPTION_CODEC_BOOL(name, help, field) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_BOOL } +#define AVOPTION_CODEC_DOUBLE(name, help, field, minv, maxv, defval) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_DOUBLE, minv, maxv, defval } +#define AVOPTION_CODEC_FLAG(name, help, field, flag, defval) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_FLAG, flag, 0, defval } +#define AVOPTION_CODEC_INT(name, help, field, minv, maxv, defval) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_INT, minv, maxv, defval } +#define AVOPTION_CODEC_STRING(name, help, field, str, val) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_STRING, .defval = val, .defstr = str } +#define AVOPTION_CODEC_RCOVERRIDE(name, help, field) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_RCOVERRIDE, .defval = 0, .defstr = NULL } +#define AVOPTION_SUB(ptr) { .name = NULL, .help = (const char*)ptr } +#define AVOPTION_END() AVOPTION_SUB(NULL) + +/** + * AVOption. + */ +typedef struct AVOption { + /** options' name */ + const char *name; /* if name is NULL, it indicates a link to next */ + /** short English text help or const struct AVOption* subpointer */ + const char *help; // const struct AVOption* sub; + /** offset to context structure where the parsed value should be stored */ + int offset; + /** options' type */ + int type; +#define FF_OPT_TYPE_BOOL 1 ///< boolean - true,1,on (or simply presence) +#define FF_OPT_TYPE_DOUBLE 2 ///< double +#define FF_OPT_TYPE_INT 3 ///< integer +#define FF_OPT_TYPE_STRING 4 ///< string (finished with \0) +#define FF_OPT_TYPE_MASK 0x1f ///< mask for types - upper bits are various flags +//#define FF_OPT_TYPE_EXPERT 0x20 // flag for expert option +#define FF_OPT_TYPE_FLAG (FF_OPT_TYPE_BOOL | 0x40) +#define FF_OPT_TYPE_RCOVERRIDE (FF_OPT_TYPE_STRING | 0x80) + /** min value (min == max -> no limits) */ + double min; + /** maximum value for double/int */ + double max; + /** default boo [0,1]l/double/int value */ + double defval; + /** + * default string value (with optional semicolon delimited extra option-list + * i.e. option1;option2;option3 + * defval might select other then first argument as default + */ + const char *defstr; +#define FF_OPT_MAX_DEPTH 10 +} AVOption; + +#ifdef HAVE_MMX +extern const struct AVOption avoptions_common[3 + 5]; +#else +extern const struct AVOption avoptions_common[3]; +#endif +extern const struct AVOption avoptions_workaround_bug[11]; + +#endif /* HAVE_AV_CONFIG_H */ + +/* Suppress restrict if it was not defined in config.h. */ +#ifndef restrict +# define restrict +#endif + +#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define always_inline __attribute__((always_inline)) inline +#else +# define always_inline inline +#endif + +#ifndef EMULATE_INTTYPES +# include <inttypes.h> +#else + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + typedef signed long long int64_t; + typedef unsigned long long uint64_t; +#endif /* HAVE_INTTYPES_H */ + +#ifndef INT64_MAX +#define INT64_MAX 9223372036854775807LL +#endif + +#ifdef EMULATE_FAST_INT +/* note that we don't emulate 64bit ints */ +typedef signed char int_fast8_t; +typedef signed int int_fast16_t; +typedef signed int int_fast32_t; +typedef unsigned char uint_fast8_t; +typedef unsigned int uint_fast16_t; +typedef unsigned int uint_fast32_t; +#endif + +#if 1 + +#include <float.h> + +#endif /* HAVE_AV_CONFIG_H */ + +/* CONFIG_OS2 end */ + +/* unix */ + +#ifndef int64_t_C +#define int64_t_C(c) (c ## LL) +#define uint64_t_C(c) (c ## ULL) + +#if 1 + +# ifdef USE_FASTMEMCPY +# include "fastmemcpy.h" +# endif +# endif /* HAVE_AV_CONFIG_H */ + +#endif /* !CONFIG_WIN32 && !CONFIG_OS2 */ + +#if 1 + +# include "bswap.h" + +# if defined(__MINGW32__) || defined(__CYGWIN__) || \ + defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__)) +# define MANGLE(a) "_" #a +# else +# define MANGLE(a) #a +# endif + +/* debug stuff */ + +# ifndef DEBUG +# define NDEBUG +# endif +# include <assert.h> + +/* dprintf macros */ +# if defined(CONFIG_WIN32) && !defined(__MINGW32__) + +inline void dprintf(const char* fmt,...) {} + +# else + +# ifdef DEBUG +# define dprintf(fmt,...) printf(fmt, __VA_ARGS__) +# else +# define dprintf(fmt,...) +# endif + +# endif /* !CONFIG_WIN32 */ + +# define av_abort() do { av_log(NULL, AV_LOG_ERROR, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0) + +//rounded divison & shift +#define RSHIFT(a,b) ((a) > 0 ? ((a) + (1<<((b)-1)))>>(b) : ((a) + (1<<((b)-1))-1)>>(b)) +/* assume b>0 */ +#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) + +#ifndef ABS +#define ABS(a) ((a) >= 0 ? (a) : (-(a))) +#endif + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) + +extern const uint32_t inverse[256]; + +#ifdef ARCH_X86 +# define FASTDIV(a,b) \ + ({\ + int ret,dmy;\ + asm volatile(\ + "mull %3"\ + :"=d"(ret),"=a"(dmy)\ + :"1"(a),"g"(inverse[b])\ + );\ + ret;\ + }) +#elif defined(CONFIG_FASTDIV) +# define FASTDIV(a,b) ((uint32_t)((((uint64_t)a)*inverse[b])>>32)) +#else +# define FASTDIV(a,b) ((a)/(b)) +#endif + +#ifdef ARCH_X86 +// avoid +32 for shift optimization (gcc should do that ...) +static inline int32_t NEG_SSR32( int32_t a, int8_t s){ + asm ("sarl %1, %0\n\t" + : "+r" (a) + : "ic" ((uint8_t)(-s)) + ); + return a; +} +static inline uint32_t NEG_USR32(uint32_t a, int8_t s){ + asm ("shrl %1, %0\n\t" + : "+r" (a) + : "ic" ((uint8_t)(-s)) + ); + return a; +} +#else +# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s))) +# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) +#endif + +/* bit output */ + +struct PutBitContext; + +typedef void (*WriteDataFunc)(void *, uint8_t *, int); + +typedef struct PutBitContext { + uint32_t bit_buf; + int bit_left; + uint8_t *buf, *buf_ptr, *buf_end; +} PutBitContext; + +void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size); + +// XXX XXX XXX +#if 0 +int get_bit_count(PutBitContext *s); /* XXX: change function name */ +void align_put_bits(PutBitContext *s); +void flush_put_bits(PutBitContext *s); +#endif + +/* bit input */ + +typedef struct GetBitContext { + const uint8_t *buffer, *buffer_end; + int index; + int size_in_bits; +} GetBitContext; + +static inline int get_bits_count(GetBitContext *s); + +#define VLC_TYPE int16_t + +typedef struct VLC { + int bits; + VLC_TYPE (*table)[2]; ///< code, bits + int table_size, table_allocated; +} VLC; + +typedef struct RL_VLC_ELEM { + int16_t level; + int8_t len; + uint8_t run; +} RL_VLC_ELEM; + +#ifdef ARCH_SPARC64 +#define UNALIGNED_STORES_ARE_BAD +#endif + +/* used to avoid missaligned exceptions on some archs (alpha, ...) */ +#ifdef ARCH_X86 +# define unaligned32(a) (*(uint32_t*)(a)) +#else +# ifdef __GNUC__ +static inline uint32_t unaligned32(const void *v) { + struct Unaligned { + uint32_t i; + } __attribute__((packed)); + + return ((const struct Unaligned *) v)->i; +} +# elif defined(__DECC) +static inline uint32_t unaligned32(const void *v) { + return *(const __unaligned uint32_t *) v; +} +# else +static inline uint32_t unaligned32(const void *v) { + return *(const uint32_t *) v; +} +# endif +#endif //!ARCH_X86 + +static inline void put_bits(PutBitContext *s, int n, unsigned int value) +{ + unsigned int bit_buf; + int bit_left; + +#ifdef STATS + st_out_bit_counts[st_current_index] += n; +#endif + // printf("put_bits=%d %x\n", n, value); + assert(n == 32 || value < (1U << n)); + + bit_buf = s->bit_buf; + bit_left = s->bit_left; + + // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf); + /* XXX: optimize */ + if (n < bit_left) { + bit_buf = (bit_buf<<n) | value; + bit_left-=n; + } else { + bit_buf<<=bit_left; + bit_buf |= value >> (n - bit_left); +#ifdef UNALIGNED_STORES_ARE_BAD + if (3 & (int) s->buf_ptr) { + s->buf_ptr[0] = bit_buf >> 24; + s->buf_ptr[1] = bit_buf >> 16; + s->buf_ptr[2] = bit_buf >> 8; + s->buf_ptr[3] = bit_buf ; + } else +#endif + *(uint32_t *)s->buf_ptr = be2me_32(bit_buf); + //printf("bitbuf = %08x\n", bit_buf); + s->buf_ptr+=4; + bit_left+=32 - n; + bit_buf = value; + } + + s->bit_buf = bit_buf; + s->bit_left = bit_left; +} + +static inline uint8_t* pbBufPtr(PutBitContext *s) +{ + return s->buf_ptr; +} + +/* Bitstream reader API docs: +name + abritary name which is used as prefix for the internal variables + +gb + getbitcontext + +OPEN_READER(name, gb) + loads gb into local variables + +CLOSE_READER(name, gb) + stores local vars in gb + +UPDATE_CACHE(name, gb) + refills the internal cache from the bitstream + after this call at least MIN_CACHE_BITS will be available, + +GET_CACHE(name, gb) + will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit) + +SHOW_UBITS(name, gb, num) + will return the nest num bits + +SHOW_SBITS(name, gb, num) + will return the nest num bits and do sign extension + +SKIP_BITS(name, gb, num) + will skip over the next num bits + note, this is equinvalent to SKIP_CACHE; SKIP_COUNTER + +SKIP_CACHE(name, gb, num) + will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER) + +SKIP_COUNTER(name, gb, num) + will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS) + +LAST_SKIP_CACHE(name, gb, num) + will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing + +LAST_SKIP_BITS(name, gb, num) + is equinvalent to SKIP_LAST_CACHE; SKIP_COUNTER + +for examples see get_bits, show_bits, skip_bits, get_vlc +*/ + +static inline int unaligned32_be(const void *v) +{ +#ifdef CONFIG_ALIGN + const uint8_t *p=v; + return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]); +#else + return be2me_32( unaligned32(v)); //original +#endif +} + +# define MIN_CACHE_BITS 25 + +# define OPEN_READER(name, gb)\ + int name##_index= (gb)->index;\ + int name##_cache= 0;\ + +# define CLOSE_READER(name, gb)\ + (gb)->index= name##_index;\ + +# define UPDATE_CACHE(name, gb)\ + name##_cache= unaligned32_be( ((uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\ + +# define SKIP_CACHE(name, gb, num)\ + name##_cache <<= (num);\ + +// FIXME name? +# define SKIP_COUNTER(name, gb, num)\ + name##_index += (num);\ + +# define SKIP_BITS(name, gb, num)\ + {\ + SKIP_CACHE(name, gb, num)\ + SKIP_COUNTER(name, gb, num)\ + }\ + +# define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num) +# define LAST_SKIP_CACHE(name, gb, num) ; + +# define SHOW_UBITS(name, gb, num)\ + NEG_USR32(name##_cache, num) + +# define SHOW_SBITS(name, gb, num)\ + NEG_SSR32(name##_cache, num) + +# define GET_CACHE(name, gb)\ + ((uint32_t)name##_cache) + +static inline int get_bits_count(GetBitContext *s){ + return s->index; +} + +/** + * read mpeg1 dc style vlc (sign bit + mantisse with no MSB). + * if MSB not set it is negative + * @param n length in bits + * @author BERO + */ +static inline int get_xbits(GetBitContext *s, int n){ + register int tmp; + register int32_t cache; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + cache = GET_CACHE(re,s); + if ((int32_t)cache<0) { //MSB=1 + tmp = NEG_USR32(cache,n); + } else { + // tmp = (-1<<n) | NEG_USR32(cache,n) + 1; mpeg12.c algo + // tmp = - (NEG_USR32(cache,n) ^ ((1 << n) - 1)); h263.c algo + tmp = - NEG_USR32(~cache,n); + } + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return tmp; +} + +static inline int get_sbits(GetBitContext *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_SBITS(re, s, n); + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return tmp; +} + +/** + * reads 0-17 bits. + * Note, the alt bitstream reader can read upto 25 bits, but the libmpeg2 reader cant + */ +static inline unsigned int get_bits(GetBitContext *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_UBITS(re, s, n); + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return tmp; +} + +unsigned int get_bits_long(GetBitContext *s, int n); + +/** + * shows 0-17 bits. + * Note, the alt bitstream reader can read upto 25 bits, but the libmpeg2 reader cant + */ +static inline unsigned int show_bits(GetBitContext *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_UBITS(re, s, n); +// CLOSE_READER(re, s) + return tmp; +} + +unsigned int show_bits_long(GetBitContext *s, int n); + +static inline void skip_bits(GetBitContext *s, int n){ + //Note gcc seems to optimize this to s->index+=n for the ALT_READER :)) + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) +} + +static inline unsigned int get_bits1(GetBitContext *s){ +#ifdef ALT_BITSTREAM_READER + int index= s->index; + uint8_t result= s->buffer[ index>>3 ]; + result<<= (index&0x07); + result>>= 8 - 1; + index++; + s->index= index; + + return result; +#else + return get_bits(s, 1); +#endif +} + +static inline unsigned int show_bits1(GetBitContext *s){ + return show_bits(s, 1); +} + +static inline void skip_bits1(GetBitContext *s){ + skip_bits(s, 1); +} + +void init_get_bits(GetBitContext *s, + const uint8_t *buffer, int buffer_size); + +int check_marker(GetBitContext *s, const char *msg); +void align_get_bits(GetBitContext *s); +int init_vlc(VLC *vlc, int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size); +void free_vlc(VLC *vlc); + +/** + * + * if the vlc code is invalid and max_depth=1 than no bits will be removed + * if the vlc code is invalid and max_depth>1 than the number of bits removed + * is undefined + */ +#define GET_VLC(code, name, gb, table, bits, max_depth)\ +{\ + int n, index, nb_bits;\ +\ + index= SHOW_UBITS(name, gb, bits);\ + code = table[index][0];\ + n = table[index][1];\ +\ + if(max_depth > 1 && n < 0){\ + LAST_SKIP_BITS(name, gb, bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + code;\ + code = table[index][0];\ + n = table[index][1];\ + if(max_depth > 2 && n < 0){\ + LAST_SKIP_BITS(name, gb, nb_bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + code;\ + code = table[index][0];\ + n = table[index][1];\ + }\ + }\ + SKIP_BITS(name, gb, n)\ +} + +#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth)\ +{\ + int n, index, nb_bits;\ +\ + index= SHOW_UBITS(name, gb, bits);\ + level = table[index].level;\ + n = table[index].len;\ +\ + if(max_depth > 1 && n < 0){\ + LAST_SKIP_BITS(name, gb, bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + level;\ + level = table[index].level;\ + n = table[index].len;\ + }\ + run= table[index].run;\ + SKIP_BITS(name, gb, n)\ +} + +// deprecated, dont use get_vlc for new code, use get_vlc2 instead or use GET_VLC directly +static inline int get_vlc(GetBitContext *s, VLC *vlc) +{ + int code; + VLC_TYPE (*table)[2]= vlc->table; + + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + + GET_VLC(code, re, s, table, vlc->bits, 3) + + CLOSE_READER(re, s) + return code; +} + +/** + * parses a vlc code, faster then get_vlc() + * @param bits is the number of bits which will be read at once, must be + * identical to nb_bits in init_vlc() + * @param max_depth is the number of times bits bits must be readed to completly + * read the longest vlc code + * = (max_vlc_length + bits - 1) / bits + */ +static always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], + int bits, int max_depth) +{ + int code; + + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + + GET_VLC(code, re, s, table, bits, max_depth) + + CLOSE_READER(re, s) + return code; +} + +//#define TRACE + +#ifdef TRACE + +static inline void print_bin(int bits, int n){ + int i; + + for(i=n-1; i>=0; i--){ + printf("%d", (bits>>i)&1); + } + for(i=n; i<24; i++) + printf(" "); +} + +static inline int get_bits_trace(GetBitContext *s, int n, char *file, char *func, int line){ + int r= get_bits(s, n); + + print_bin(r, n); + printf("%5d %2d %3d bit @%5d in %s %s:%d\n", r, n, r, get_bits_count(s)-n, file, func, line); + return r; +} +static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth, char *file, char *func, int line){ + int show= show_bits(s, 24); + int pos= get_bits_count(s); + int r= get_vlc2(s, table, bits, max_depth); + int len= get_bits_count(s) - pos; + int bits2= show>>(24-len); + + print_bin(bits2, len); + + printf("%5d %2d %3d vlc @%5d in %s %s:%d\n", bits2, len, r, pos, file, func, line); + return r; +} +static inline int get_xbits_trace(GetBitContext *s, int n, char *file, char *func, int line){ + int show= show_bits(s, n); + int r= get_xbits(s, n); + + print_bin(show, n); + printf("%5d %2d %3d xbt @%5d in %s %s:%d\n", show, n, r, get_bits_count(s)-n, file, func, line); + return r; +} + +#define get_bits(s, n) get_bits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_bits1(s) get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_vlc(s, vlc) get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__) + +#define tprintf printf + +#else //TRACE +#define tprintf(_arg...) {} +#endif + +/* define it to include statistics code (useful only for optimizing + codec efficiency */ +//#define STATS + +#ifdef STATS + +enum { + ST_UNKNOWN, + ST_DC, + ST_INTRA_AC, + ST_INTER_AC, + ST_INTRA_MB, + ST_INTER_MB, + ST_MV, + ST_NB, +}; + +extern int st_current_index; +extern unsigned int st_bit_counts[ST_NB]; +extern unsigned int st_out_bit_counts[ST_NB]; + +void print_stats(void); +#endif + +/* misc math functions */ +extern const uint8_t ff_log2_tab[256]; + +static inline int av_log2(unsigned int v) +{ + int n; + + n = 0; + if (v & 0xffff0000) { + v >>= 16; + n += 16; + } + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +static inline int av_log2_16bit(unsigned int v) +{ + int n; + + n = 0; + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +/* median of 3 */ +static inline int mid_pred(int a, int b, int c) +{ +#if 0 + int t= (a-b)&((a-b)>>31); + a-=t; + b+=t; + b-= (b-c)&((b-c)>>31); + b+= (a-b)&((a-b)>>31); + + return b; +#else + if(a>b){ + if(c>b){ + if(c>a) b=a; + else b=c; + } + }else{ + if(b>c){ + if(c>a) b=c; + else b=a; + } + } + return b; +#endif +} + +static inline int clip(int a, int amin, int amax) +{ + if (a < amin) + return amin; + else if (a > amax) + return amax; + else + return a; +} + +/* math */ +extern const uint8_t ff_sqrt_tab[128]; + +int64_t ff_gcd(int64_t a, int64_t b); + +static inline int ff_sqrt(int a) +{ + int ret=0; + int s; + int ret_sq=0; + + if(a<128) return ff_sqrt_tab[a]; + + for(s=15; s>=0; s--){ + int b= ret_sq + (1<<(s*2)) + (ret<<s)*2; + if(b<=a){ + ret_sq=b; + ret+= 1<<s; + } + } + return ret; +} + +/** + * converts fourcc string to int + */ +static inline int ff_get_fourcc(const char *s){ + assert( strlen(s)==4 ); + + return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24); +} + +#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) +#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24)) + + +#ifdef ARCH_X86 +#define MASK_ABS(mask, level)\ + asm volatile(\ + "cdq \n\t"\ + "xorl %1, %0 \n\t"\ + "subl %1, %0 \n\t"\ + : "+a" (level), "=&d" (mask)\ + ); +#else +#define MASK_ABS(mask, level)\ + mask= level>>31;\ + level= (level^mask)-mask; +#endif + + +#if __CPU__ >= 686 && !defined(RUNTIME_CPUDETECT) +#define COPY3_IF_LT(x,y,a,b,c,d)\ +asm volatile (\ + "cmpl %0, %3 \n\t"\ + "cmovl %3, %0 \n\t"\ + "cmovl %4, %1 \n\t"\ + "cmovl %5, %2 \n\t"\ + : "+r" (x), "+r" (a), "+r" (c)\ + : "r" (y), "r" (b), "r" (d)\ +); +#else +#define COPY3_IF_LT(x,y,a,b,c,d)\ +if((y)<(x)){\ + (x)=(y);\ + (a)=(b);\ + (c)=(d);\ +} +#endif + +#ifdef ARCH_X86 +static inline long long rdtsc() +{ + long long l; + asm volatile( "rdtsc\n\t" + : "=A" (l) + ); + return l; +} + +#define START_TIMER \ +static uint64_t tsum=0;\ +static int tcount=0;\ +static int tskip_count=0;\ +uint64_t tend;\ +uint64_t tstart= rdtsc();\ + +#define STOP_TIMER(id) \ +tend= rdtsc();\ +if(tcount<2 || tend - tstart < 4*tsum/tcount){\ + tsum+= tend - tstart;\ + tcount++;\ +}else\ + tskip_count++;\ +if(256*256*256*64%(tcount+tskip_count)==0){\ + fprintf(stderr, "%Ld dezicycles in %s, %d runs, %d skips\n", tsum*10/tcount, id, tcount, tskip_count);\ +} +#endif + +#define CLAMP_TO_8BIT(d) ((d > 0xff) ? 0xff : (d < 0) ? 0 : d) + +#define CHECKED_ALLOCZ(p, size)\ +{\ + p= av_mallocz(size);\ + if(p==NULL && (size)!=0){\ + perror("malloc");\ + goto fail;\ + }\ +} + +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* COMMON_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/cutils.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,239 @@ +/* + * Various simple utilities for ffmpeg system + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * 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 "avformat.h" + +#if !defined(CONFIG_NOCUTILS) +/** + * Return TRUE if val is a prefix of str. If it returns TRUE, ptr is + * set to the next character in 'str' after the prefix. + * + * @param str input string + * @param val prefix to test + * @param ptr updated after the prefix in str in there is a match + * @return TRUE if there is a match + */ +int strstart(const char *str, const char *val, const char **ptr) +{ + const char *p, *q; + p = str; + q = val; + while (*q != '\0') { + if (*p != *q) + return 0; + p++; + q++; + } + if (ptr) + *ptr = p; + return 1; +} + +/** + * Return TRUE if val is a prefix of str (case independent). If it + * returns TRUE, ptr is set to the next character in 'str' after the + * prefix. + * + * @param str input string + * @param val prefix to test + * @param ptr updated after the prefix in str in there is a match + * @return TRUE if there is a match */ +int stristart(const char *str, const char *val, const char **ptr) +{ + const char *p, *q; + p = str; + q = val; + while (*q != '\0') { + if (toupper(*(const unsigned char *)p) != toupper(*(const unsigned char *)q)) + return 0; + p++; + q++; + } + if (ptr) + *ptr = p; + return 1; +} + +/** + * Copy the string str to buf. If str length is bigger than buf_size - + * 1 then it is clamped to buf_size - 1. + * NOTE: this function does what strncpy should have done to be + * useful. NEVER use strncpy. + * + * @param buf destination buffer + * @param buf_size size of destination buffer + * @param str source string + */ +void pstrcpy(char *buf, int buf_size, const char *str) +{ + int c; + char *q = buf; + + if (buf_size <= 0) + return; + + for(;;) { + c = *str++; + if (c == 0 || q >= buf + buf_size - 1) + break; + *q++ = c; + } + *q = '\0'; +} + +/* strcat and truncate. */ +char *pstrcat(char *buf, int buf_size, const char *s) +{ + int len; + len = strlen(buf); + if (len < buf_size) + pstrcpy(buf + len, buf_size - len, s); + return buf; +} + +#endif + +/* add one element to a dynamic array */ +void __dynarray_add(unsigned long **tab_ptr, int *nb_ptr, unsigned long elem) +{ + int nb, nb_alloc; + unsigned long *tab; + + nb = *nb_ptr; + tab = *tab_ptr; + if ((nb & (nb - 1)) == 0) { + if (nb == 0) + nb_alloc = 1; + else + nb_alloc = nb * 2; + tab = realloc(tab, nb_alloc * sizeof(unsigned long)); + *tab_ptr = tab; + } + tab[nb++] = elem; + *nb_ptr = nb; +} + +time_t mktimegm(struct tm *tm) +{ + time_t t; + + int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday; + + if (m < 3) { + m += 12; + y--; + } + + t = 86400 * + (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469); + + t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; + + return t; +} + +/* get a positive number between n_min and n_max, for a maximum length + of len_max. Return -1 if error. */ +static int date_get_num(const char **pp, + int n_min, int n_max, int len_max) +{ + int i, val, c; + const char *p; + + p = *pp; + val = 0; + for(i = 0; i < len_max; i++) { + c = *p; + if (!isdigit(c)) + break; + val = (val * 10) + c - '0'; + p++; + } + /* no number read ? */ + if (p == *pp) + return -1; + if (val < n_min || val > n_max) + return -1; + *pp = p; + return val; +} + +/* small strptime for ffmpeg */ +const char *small_strptime(const char *p, const char *fmt, + struct tm *dt) +{ + int c, val; + + for(;;) { + c = *fmt++; + if (c == '\0') { + return p; + } else if (c == '%') { + c = *fmt++; + switch(c) { + case 'H': + val = date_get_num(&p, 0, 23, 2); + if (val == -1) + return NULL; + dt->tm_hour = val; + break; + case 'M': + val = date_get_num(&p, 0, 59, 2); + if (val == -1) + return NULL; + dt->tm_min = val; + break; + case 'S': + val = date_get_num(&p, 0, 59, 2); + if (val == -1) + return NULL; + dt->tm_sec = val; + break; + case 'Y': + val = date_get_num(&p, 0, 9999, 4); + if (val == -1) + return NULL; + dt->tm_year = val - 1900; + break; + case 'm': + val = date_get_num(&p, 1, 12, 2); + if (val == -1) + return NULL; + dt->tm_mon = val - 1; + break; + case 'd': + val = date_get_num(&p, 1, 31, 2); + if (val == -1) + return NULL; + dt->tm_mday = val; + break; + case '%': + goto match; + default: + return NULL; + } + } else { + match: + if (c != *p) + return NULL; + p++; + } + } + return p; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/cutils.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,14 @@ +#ifndef _CUTILS_H +#define _CUTILS_H + +int strstart(const char *str, const char *val, const char **ptr); +int stristart(const char *str, const char *val, const char **ptr); +void pstrcpy(char *buf, int buf_size, const char *str); +char *pstrcat(char *buf, int buf_size, const char *s); + +time_t mktimegm(struct tm *tm); +const char *small_strptime(const char *p, const char *fmt, + struct tm *dt); + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/dsputil.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,892 @@ +/* + * DSP utils + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 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 + * + * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at> + */ + +/** + * @file dsputil.c + * DSP utils + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "simple_idct.h" + +uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; +uint32_t squareTbl[512]; + +const uint8_t ff_zigzag_direct[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; + +/* Specific zigzag scan for 248 idct. NOTE that unlike the + specification, we interleave the fields */ +const uint8_t ff_zigzag248_direct[64] = { + 0, 8, 1, 9, 16, 24, 2, 10, + 17, 25, 32, 40, 48, 56, 33, 41, + 18, 26, 3, 11, 4, 12, 19, 27, + 34, 42, 49, 57, 50, 58, 35, 43, + 20, 28, 5, 13, 6, 14, 21, 29, + 36, 44, 51, 59, 52, 60, 37, 45, + 22, 30, 7, 15, 23, 31, 38, 46, + 53, 61, 54, 62, 39, 47, 55, 63, +}; + +/* not permutated inverse zigzag_direct + 1 for MMX quantizer */ +uint16_t __align8 inv_zigzag_direct16[64]; + +const uint8_t ff_alternate_horizontal_scan[64] = { + 0, 1, 2, 3, 8, 9, 16, 17, + 10, 11, 4, 5, 6, 7, 15, 14, + 13, 12, 19, 18, 24, 25, 32, 33, + 26, 27, 20, 21, 22, 23, 28, 29, + 30, 31, 34, 35, 40, 41, 48, 49, + 42, 43, 36, 37, 38, 39, 44, 45, + 46, 47, 50, 51, 56, 57, 58, 59, + 52, 53, 54, 55, 60, 61, 62, 63, +}; + +const uint8_t ff_alternate_vertical_scan[64] = { + 0, 8, 16, 24, 1, 9, 2, 10, + 17, 25, 32, 40, 48, 56, 57, 49, + 41, 33, 26, 18, 3, 11, 4, 12, + 19, 27, 34, 42, 50, 58, 35, 43, + 51, 59, 20, 28, 5, 13, 6, 14, + 21, 29, 36, 44, 52, 60, 37, 45, + 53, 61, 22, 30, 7, 15, 23, 31, + 38, 46, 54, 62, 39, 47, 55, 63, +}; + +/* a*inverse[b]>>32 == a/b for all 0<=a<=65536 && 2<=b<=255 */ +const uint32_t inverse[256]={ + 0, 4294967295U,2147483648U,1431655766, 1073741824, 858993460, 715827883, 613566757, + 536870912, 477218589, 429496730, 390451573, 357913942, 330382100, 306783379, 286331154, + 268435456, 252645136, 238609295, 226050911, 214748365, 204522253, 195225787, 186737709, + 178956971, 171798692, 165191050, 159072863, 153391690, 148102321, 143165577, 138547333, + 134217728, 130150525, 126322568, 122713352, 119304648, 116080198, 113025456, 110127367, + 107374183, 104755300, 102261127, 99882961, 97612894, 95443718, 93368855, 91382283, + 89478486, 87652394, 85899346, 84215046, 82595525, 81037119, 79536432, 78090315, + 76695845, 75350304, 74051161, 72796056, 71582789, 70409300, 69273667, 68174085, + 67108864, 66076420, 65075263, 64103990, 63161284, 62245903, 61356676, 60492498, + 59652324, 58835169, 58040099, 57266231, 56512728, 55778797, 55063684, 54366675, + 53687092, 53024288, 52377650, 51746594, 51130564, 50529028, 49941481, 49367441, + 48806447, 48258060, 47721859, 47197443, 46684428, 46182445, 45691142, 45210183, + 44739243, 44278014, 43826197, 43383509, 42949673, 42524429, 42107523, 41698712, + 41297763, 40904451, 40518560, 40139882, 39768216, 39403370, 39045158, 38693400, + 38347923, 38008561, 37675152, 37347542, 37025581, 36709123, 36398028, 36092163, + 35791395, 35495598, 35204650, 34918434, 34636834, 34359739, 34087043, 33818641, + 33554432, 33294321, 33038210, 32786010, 32537632, 32292988, 32051995, 31814573, + 31580642, 31350127, 31122952, 30899046, 30678338, 30460761, 30246249, 30034737, + 29826162, 29620465, 29417585, 29217465, 29020050, 28825284, 28633116, 28443493, + 28256364, 28071682, 27889399, 27709467, 27531842, 27356480, 27183338, 27012373, + 26843546, 26676816, 26512144, 26349493, 26188825, 26030105, 25873297, 25718368, + 25565282, 25414008, 25264514, 25116768, 24970741, 24826401, 24683721, 24542671, + 24403224, 24265352, 24129030, 23994231, 23860930, 23729102, 23598722, 23469767, + 23342214, 23216040, 23091223, 22967740, 22845571, 22724695, 22605092, 22486740, + 22369622, 22253717, 22139007, 22025474, 21913099, 21801865, 21691755, 21582751, + 21474837, 21367997, 21262215, 21157475, 21053762, 20951060, 20849356, 20748635, + 20648882, 20550083, 20452226, 20355296, 20259280, 20164166, 20069941, 19976593, + 19884108, 19792477, 19701685, 19611723, 19522579, 19434242, 19346700, 19259944, + 19173962, 19088744, 19004281, 18920561, 18837576, 18755316, 18673771, 18592933, + 18512791, 18433337, 18354562, 18276457, 18199014, 18122225, 18046082, 17970575, + 17895698, 17821442, 17747799, 17674763, 17602325, 17530479, 17459217, 17388532, + 17318417, 17248865, 17179870, 17111424, 17043522, 16976156, 16909321, 16843010, +}; + +/* Input permutation for the simple_idct_mmx */ +static const uint8_t simple_mmx_permutation[64]={ + 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, + 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, + 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, + 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, + 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, + 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, + 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, + 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, +}; +#if 0 +static int pix_sum_c(uint8_t * pix, int line_size) +{ + int s, i, j; + + s = 0; + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j += 8) { + s += pix[0]; + s += pix[1]; + s += pix[2]; + s += pix[3]; + s += pix[4]; + s += pix[5]; + s += pix[6]; + s += pix[7]; + pix += 8; + } + pix += line_size - 16; + } + return s; +} + +static int pix_norm1_c(uint8_t * pix, int line_size) +{ + int s, i, j; + uint32_t *sq = squareTbl + 256; + + s = 0; + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j += 8) { +#if 0 + s += sq[pix[0]]; + s += sq[pix[1]]; + s += sq[pix[2]]; + s += sq[pix[3]]; + s += sq[pix[4]]; + s += sq[pix[5]]; + s += sq[pix[6]]; + s += sq[pix[7]]; +#else +#if LONG_MAX > 2147483647 + register uint64_t x=*(uint64_t*)pix; + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; + s += sq[(x>>32)&0xff]; + s += sq[(x>>40)&0xff]; + s += sq[(x>>48)&0xff]; + s += sq[(x>>56)&0xff]; +#else + register uint32_t x=*(uint32_t*)pix; + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; + x=*(uint32_t*)(pix+4); + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; +#endif +#endif + pix += 8; + } + pix += line_size - 16; + } + return s; +} + +static void bswap_buf(uint32_t *dst, uint32_t *src, int w){ + int i; + + for(i=0; i+8<=w; i+=8){ + dst[i+0]= bswap_32(src[i+0]); + dst[i+1]= bswap_32(src[i+1]); + dst[i+2]= bswap_32(src[i+2]); + dst[i+3]= bswap_32(src[i+3]); + dst[i+4]= bswap_32(src[i+4]); + dst[i+5]= bswap_32(src[i+5]); + dst[i+6]= bswap_32(src[i+6]); + dst[i+7]= bswap_32(src[i+7]); + } + for(;i<w; i++){ + dst[i+0]= bswap_32(src[i+0]); + } +} + +static int sse8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) +{ + int s, i; + uint32_t *sq = squareTbl + 256; + + s = 0; + for (i = 0; i < h; i++) { + s += sq[pix1[0] - pix2[0]]; + s += sq[pix1[1] - pix2[1]]; + s += sq[pix1[2] - pix2[2]]; + s += sq[pix1[3] - pix2[3]]; + s += sq[pix1[4] - pix2[4]]; + s += sq[pix1[5] - pix2[5]]; + s += sq[pix1[6] - pix2[6]]; + s += sq[pix1[7] - pix2[7]]; + pix1 += line_size; + pix2 += line_size; + } + return s; +} + +static int sse16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) +{ + int s, i; + uint32_t *sq = squareTbl + 256; + + s = 0; + for (i = 0; i < h; i++) { + s += sq[pix1[ 0] - pix2[ 0]]; + s += sq[pix1[ 1] - pix2[ 1]]; + s += sq[pix1[ 2] - pix2[ 2]]; + s += sq[pix1[ 3] - pix2[ 3]]; + s += sq[pix1[ 4] - pix2[ 4]]; + s += sq[pix1[ 5] - pix2[ 5]]; + s += sq[pix1[ 6] - pix2[ 6]]; + s += sq[pix1[ 7] - pix2[ 7]]; + s += sq[pix1[ 8] - pix2[ 8]]; + s += sq[pix1[ 9] - pix2[ 9]]; + s += sq[pix1[10] - pix2[10]]; + s += sq[pix1[11] - pix2[11]]; + s += sq[pix1[12] - pix2[12]]; + s += sq[pix1[13] - pix2[13]]; + s += sq[pix1[14] - pix2[14]]; + s += sq[pix1[15] - pix2[15]]; + + pix1 += line_size; + pix2 += line_size; + } + return s; +} + +static void get_pixels_c(DCTELEM *restrict block, const uint8_t *pixels, int line_size) +{ + int i; + + /* read the pixels */ + for(i=0;i<8;i++) { + block[0] = pixels[0]; + block[1] = pixels[1]; + block[2] = pixels[2]; + block[3] = pixels[3]; + block[4] = pixels[4]; + block[5] = pixels[5]; + block[6] = pixels[6]; + block[7] = pixels[7]; + pixels += line_size; + block += 8; + } +} + +static void diff_pixels_c(DCTELEM *restrict block, const uint8_t *s1, + const uint8_t *s2, int stride){ + int i; + + /* read the pixels */ + for(i=0;i<8;i++) { + block[0] = s1[0] - s2[0]; + block[1] = s1[1] - s2[1]; + block[2] = s1[2] - s2[2]; + block[3] = s1[3] - s2[3]; + block[4] = s1[4] - s2[4]; + block[5] = s1[5] - s2[5]; + block[6] = s1[6] - s2[6]; + block[7] = s1[7] - s2[7]; + s1 += stride; + s2 += stride; + block += 8; + } +} + + +static void put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<8;i++) { + pixels[0] = cm[block[0]]; + pixels[1] = cm[block[1]]; + pixels[2] = cm[block[2]]; + pixels[3] = cm[block[3]]; + pixels[4] = cm[block[4]]; + pixels[5] = cm[block[5]]; + pixels[6] = cm[block[6]]; + pixels[7] = cm[block[7]]; + + pixels += line_size; + block += 8; + } +} + +static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<8;i++) { + pixels[0] = cm[pixels[0] + block[0]]; + pixels[1] = cm[pixels[1] + block[1]]; + pixels[2] = cm[pixels[2] + block[2]]; + pixels[3] = cm[pixels[3] + block[3]]; + pixels[4] = cm[pixels[4] + block[4]]; + pixels[5] = cm[pixels[5] + block[5]]; + pixels[6] = cm[pixels[6] + block[6]]; + pixels[7] = cm[pixels[7] + block[7]]; + pixels += line_size; + block += 8; + } +} +#endif +#if 0 + +#define PIXOP2(OPNAME, OP) \ +static void OPNAME ## _pixels(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i<h; i++){\ + OP(*((uint64_t*)block), LD64(pixels));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _no_rnd_pixels_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i<h; i++){\ + const uint64_t a= LD64(pixels );\ + const uint64_t b= LD64(pixels+1);\ + OP(*((uint64_t*)block), (a&b) + (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _pixels_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i<h; i++){\ + const uint64_t a= LD64(pixels );\ + const uint64_t b= LD64(pixels+1);\ + OP(*((uint64_t*)block), (a|b) - (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _no_rnd_pixels_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i<h; i++){\ + const uint64_t a= LD64(pixels );\ + const uint64_t b= LD64(pixels+line_size);\ + OP(*((uint64_t*)block), (a&b) + (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _pixels_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i<h; i++){\ + const uint64_t a= LD64(pixels );\ + const uint64_t b= LD64(pixels+line_size);\ + OP(*((uint64_t*)block), (a|b) - (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + const uint64_t a= LD64(pixels );\ + const uint64_t b= LD64(pixels+1);\ + uint64_t l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0202020202020202ULL;\ + uint64_t h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + uint64_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i<h; i+=2){\ + uint64_t a= LD64(pixels );\ + uint64_t b= LD64(pixels+1);\ + l1= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL);\ + h1= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + a= LD64(pixels );\ + b= LD64(pixels+1);\ + l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0202020202020202ULL;\ + h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _no_rnd_pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + const uint64_t a= LD64(pixels );\ + const uint64_t b= LD64(pixels+1);\ + uint64_t l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0101010101010101ULL;\ + uint64_t h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + uint64_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i<h; i+=2){\ + uint64_t a= LD64(pixels );\ + uint64_t b= LD64(pixels+1);\ + l1= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL);\ + h1= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + a= LD64(pixels );\ + b= LD64(pixels+1);\ + l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0101010101010101ULL;\ + h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +CALL_2X_PIXELS(OPNAME ## _pixels16_c , OPNAME ## _pixels_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_x2_c , OPNAME ## _pixels_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_y2_c , OPNAME ## _pixels_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_c, OPNAME ## _pixels_xy2_c, 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_x2_c , OPNAME ## _no_rnd_pixels_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_y2_c , OPNAME ## _no_rnd_pixels_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_c, OPNAME ## _no_rnd_pixels_xy2_c, 8) + +#define op_avg(a, b) a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEFEFEFEFEULL)>>1) ) +#else // 64 bit variant + +#define PIXOP2(OPNAME, OP) \ +static void OPNAME ## _pixels2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + int i;\ + for(i=0; i<h; i++){\ + OP(*((uint16_t*)(block )), LD16(pixels ));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +static void OPNAME ## _pixels4_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + int i;\ + for(i=0; i<h; i++){\ + OP(*((uint32_t*)(block )), LD32(pixels ));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +static void OPNAME ## _pixels8_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + int i;\ + for(i=0; i<h; i++){\ + OP(*((uint32_t*)(block )), LD32(pixels ));\ + OP(*((uint32_t*)(block+4)), LD32(pixels+4));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +static inline void OPNAME ## _no_rnd_pixels8_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels8_c(block, pixels, line_size, h);\ +}\ +\ +static inline void OPNAME ## _no_rnd_pixels8_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \ + int src_stride1, int src_stride2, int h){\ + int i;\ + for(i=0; i<h; i++){\ + uint32_t a,b;\ + a= LD32(&src1[i*src_stride1 ]);\ + b= LD32(&src2[i*src_stride2 ]);\ + OP(*((uint32_t*)&dst[i*dst_stride ]), no_rnd_avg32(a, b));\ + a= LD32(&src1[i*src_stride1+4]);\ + b= LD32(&src2[i*src_stride2+4]);\ + OP(*((uint32_t*)&dst[i*dst_stride+4]), no_rnd_avg32(a, b));\ + }\ +}\ +\ +static inline void OPNAME ## _pixels8_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \ + int src_stride1, int src_stride2, int h){\ + int i;\ + for(i=0; i<h; i++){\ + uint32_t a,b;\ + a= LD32(&src1[i*src_stride1 ]);\ + b= LD32(&src2[i*src_stride2 ]);\ + OP(*((uint32_t*)&dst[i*dst_stride ]), rnd_avg32(a, b));\ + a= LD32(&src1[i*src_stride1+4]);\ + b= LD32(&src2[i*src_stride2+4]);\ + OP(*((uint32_t*)&dst[i*dst_stride+4]), rnd_avg32(a, b));\ + }\ +}\ +\ +static inline void OPNAME ## _pixels4_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \ + int src_stride1, int src_stride2, int h){\ + int i;\ + for(i=0; i<h; i++){\ + uint32_t a,b;\ + a= LD32(&src1[i*src_stride1 ]);\ + b= LD32(&src2[i*src_stride2 ]);\ + OP(*((uint32_t*)&dst[i*dst_stride ]), rnd_avg32(a, b));\ + }\ +}\ +\ +static inline void OPNAME ## _pixels2_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \ + int src_stride1, int src_stride2, int h){\ + int i;\ + for(i=0; i<h; i++){\ + uint32_t a,b;\ + a= LD16(&src1[i*src_stride1 ]);\ + b= LD16(&src2[i*src_stride2 ]);\ + OP(*((uint16_t*)&dst[i*dst_stride ]), rnd_avg32(a, b));\ + }\ +}\ +\ +static inline void OPNAME ## _pixels16_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \ + int src_stride1, int src_stride2, int h){\ + OPNAME ## _pixels8_l2(dst , src1 , src2 , dst_stride, src_stride1, src_stride2, h);\ + OPNAME ## _pixels8_l2(dst+8, src1+8, src2+8, dst_stride, src_stride1, src_stride2, h);\ +}\ +\ +static inline void OPNAME ## _no_rnd_pixels16_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \ + int src_stride1, int src_stride2, int h){\ + OPNAME ## _no_rnd_pixels8_l2(dst , src1 , src2 , dst_stride, src_stride1, src_stride2, h);\ + OPNAME ## _no_rnd_pixels8_l2(dst+8, src1+8, src2+8, dst_stride, src_stride1, src_stride2, h);\ +}\ +\ +static inline void OPNAME ## _no_rnd_pixels8_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _no_rnd_pixels8_l2(block, pixels, pixels+1, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels8_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels8_l2(block, pixels, pixels+1, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _no_rnd_pixels8_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _no_rnd_pixels8_l2(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels8_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels8_l2(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels8_l4(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,\ + int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ + int i;\ + for(i=0; i<h; i++){\ + uint32_t a, b, c, d, l0, l1, h0, h1;\ + a= LD32(&src1[i*src_stride1]);\ + b= LD32(&src2[i*src_stride2]);\ + c= LD32(&src3[i*src_stride3]);\ + d= LD32(&src4[i*src_stride4]);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + a= LD32(&src1[i*src_stride1+4]);\ + b= LD32(&src2[i*src_stride2+4]);\ + c= LD32(&src3[i*src_stride3+4]);\ + d= LD32(&src4[i*src_stride4+4]);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride+4]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + }\ +}\ +\ +static inline void OPNAME ## _pixels4_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels4_l2(block, pixels, pixels+1, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels4_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels4_l2(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels2_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels2_l2(block, pixels, pixels+1, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels2_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels2_l2(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _no_rnd_pixels8_l4(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,\ + int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ + int i;\ + for(i=0; i<h; i++){\ + uint32_t a, b, c, d, l0, l1, h0, h1;\ + a= LD32(&src1[i*src_stride1]);\ + b= LD32(&src2[i*src_stride2]);\ + c= LD32(&src3[i*src_stride3]);\ + d= LD32(&src4[i*src_stride4]);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x01010101UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + a= LD32(&src1[i*src_stride1+4]);\ + b= LD32(&src2[i*src_stride2+4]);\ + c= LD32(&src3[i*src_stride3+4]);\ + d= LD32(&src4[i*src_stride4+4]);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x01010101UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride+4]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + }\ +}\ +static inline void OPNAME ## _pixels16_l4(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,\ + int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ + OPNAME ## _pixels8_l4(dst , src1 , src2 , src3 , src4 , dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ + OPNAME ## _pixels8_l4(dst+8, src1+8, src2+8, src3+8, src4+8, dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ +}\ +static inline void OPNAME ## _no_rnd_pixels16_l4(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,\ + int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ + OPNAME ## _no_rnd_pixels8_l4(dst , src1 , src2 , src3 , src4 , dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ + OPNAME ## _no_rnd_pixels8_l4(dst+8, src1+8, src2+8, src3+8, src4+8, dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ +}\ +\ +static inline void OPNAME ## _pixels2_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i, a0, b0, a1, b1;\ + a0= pixels[0];\ + b0= pixels[1] + 2;\ + a0 += b0;\ + b0 += pixels[2];\ +\ + pixels+=line_size;\ + for(i=0; i<h; i+=2){\ + a1= pixels[0];\ + b1= pixels[1];\ + a1 += b1;\ + b1 += pixels[2];\ +\ + block[0]= (a1+a0)>>2; /* FIXME non put */\ + block[1]= (b1+b0)>>2;\ +\ + pixels+=line_size;\ + block +=line_size;\ +\ + a0= pixels[0];\ + b0= pixels[1] + 2;\ + a0 += b0;\ + b0 += pixels[2];\ +\ + block[0]= (a1+a0)>>2;\ + block[1]= (b1+b0)>>2;\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static inline void OPNAME ## _pixels4_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + const uint32_t a= LD32(pixels );\ + const uint32_t b= LD32(pixels+1);\ + uint32_t l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + uint32_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i<h; i+=2){\ + uint32_t a= LD32(pixels );\ + uint32_t b= LD32(pixels+1);\ + l1= (a&0x03030303UL)\ + + (b&0x03030303UL);\ + h1= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + a= LD32(pixels );\ + b= LD32(pixels+1);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static inline void OPNAME ## _pixels8_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int j;\ + for(j=0; j<2; j++){\ + int i;\ + const uint32_t a= LD32(pixels );\ + const uint32_t b= LD32(pixels+1);\ + uint32_t l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + uint32_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i<h; i+=2){\ + uint32_t a= LD32(pixels );\ + uint32_t b= LD32(pixels+1);\ + l1= (a&0x03030303UL)\ + + (b&0x03030303UL);\ + h1= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + a= LD32(pixels );\ + b= LD32(pixels+1);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ + pixels+=4-line_size*(h+1);\ + block +=4-line_size*h;\ + }\ +}\ +\ +static inline void OPNAME ## _no_rnd_pixels8_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int j;\ + for(j=0; j<2; j++){\ + int i;\ + const uint32_t a= LD32(pixels );\ + const uint32_t b= LD32(pixels+1);\ + uint32_t l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x01010101UL;\ + uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + uint32_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i<h; i+=2){\ + uint32_t a= LD32(pixels );\ + uint32_t b= LD32(pixels+1);\ + l1= (a&0x03030303UL)\ + + (b&0x03030303UL);\ + h1= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + a= LD32(pixels );\ + b= LD32(pixels+1);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x01010101UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ + pixels+=4-line_size*(h+1);\ + block +=4-line_size*h;\ + }\ +}\ +\ +CALL_2X_PIXELS(OPNAME ## _pixels16_c , OPNAME ## _pixels8_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_x2_c , OPNAME ## _pixels8_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_y2_c , OPNAME ## _pixels8_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_c, OPNAME ## _pixels8_xy2_c, 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_c , OPNAME ## _pixels8_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_x2_c , OPNAME ## _no_rnd_pixels8_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_y2_c , OPNAME ## _no_rnd_pixels8_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_c, OPNAME ## _no_rnd_pixels8_xy2_c, 8)\ + +#define op_avg(a, b) a = rnd_avg32(a, b) +#endif +#define op_put(a, b) a = b + +//PIXOP2(avg, op_avg) +//PIXOP2(put, op_put) +#undef op_avg +#undef op_put + +#define avg2(a,b) ((a+b+1)>>1) +#define avg4(a,b,c,d) ((a+b+c+d+2)>>2) + +/* init static data */ +void dsputil_static_init(void) +{ + int i; + + for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; + for(i=0;i<MAX_NEG_CROP;i++) { + cropTbl[i] = 0; + cropTbl[i + MAX_NEG_CROP + 256] = 255; + } + + for(i=0;i<512;i++) { + squareTbl[i] = (i - 256) * (i - 256); + } + + for(i=0; i<64; i++) inv_zigzag_direct16[ff_zigzag_direct[i]]= i+1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/dsputil.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,522 @@ +/* + * DSP utils + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 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 + */ + +/** + * @file dsputil.h + * DSP utils. + * note, many functions in here may use MMX which trashes the FPU state, it is + * absolutely necessary to call emms_c() between dsp & float/double code + */ + +#ifndef DSPUTIL_H +#define DSPUTIL_H + +#include "common.h" +#include "avcodec.h" + + +//#define DEBUG +/* dct code */ +typedef short DCTELEM; + +void fdct_ifast (DCTELEM *data); +void fdct_ifast248 (DCTELEM *data); +void ff_jpeg_fdct_islow (DCTELEM *data); +void ff_fdct248_islow (DCTELEM *data); + +void j_rev_dct (DCTELEM *data); + +void ff_fdct_mmx(DCTELEM *block); +void ff_fdct_mmx2(DCTELEM *block); +void ff_fdct_sse2(DCTELEM *block); + +/* encoding scans */ +extern const uint8_t ff_alternate_horizontal_scan[64]; +extern const uint8_t ff_alternate_vertical_scan[64]; +extern const uint8_t ff_zigzag_direct[64]; +extern const uint8_t ff_zigzag248_direct[64]; + +/* pixel operations */ +#define MAX_NEG_CROP 384 + +/* temporary */ +extern uint32_t squareTbl[512]; +extern uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; + + +/* minimum alignment rules ;) +if u notice errors in the align stuff, need more alignment for some asm code for some cpu +or need to use a function with less aligned data then send a mail to the ffmpeg-dev list, ... + +!warning these alignments might not match reallity, (missing attribute((align)) stuff somewhere possible) +i (michael) didnt check them, these are just the alignents which i think could be reached easily ... + +!future video codecs might need functions with less strict alignment +*/ + +/* +void get_pixels_c(DCTELEM *block, const uint8_t *pixels, int line_size); +void diff_pixels_c(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride); +void put_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size); +void add_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size); +void clear_blocks_c(DCTELEM *blocks); +*/ + +/* add and put pixel (decoding) */ +// blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16 +//h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller then 4 +typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h); +typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h); +typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); +typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); + +#define DEF_OLD_QPEL(name)\ +void ff_put_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ +void ff_put_no_rnd_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ +void ff_avg_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); + +DEF_OLD_QPEL(qpel16_mc11_old_c) +DEF_OLD_QPEL(qpel16_mc31_old_c) +DEF_OLD_QPEL(qpel16_mc12_old_c) +DEF_OLD_QPEL(qpel16_mc32_old_c) +DEF_OLD_QPEL(qpel16_mc13_old_c) +DEF_OLD_QPEL(qpel16_mc33_old_c) +DEF_OLD_QPEL(qpel8_mc11_old_c) +DEF_OLD_QPEL(qpel8_mc31_old_c) +DEF_OLD_QPEL(qpel8_mc12_old_c) +DEF_OLD_QPEL(qpel8_mc32_old_c) +DEF_OLD_QPEL(qpel8_mc13_old_c) +DEF_OLD_QPEL(qpel8_mc33_old_c) + +#define CALL_2X_PIXELS(a, b, n)\ +static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + b(block , pixels , line_size, h);\ + b(block+n, pixels+n, line_size, h);\ +} + +/* motion estimation */ +// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2 +// allthough currently h<4 is not used as functions with width <8 are not used and neither implemented +typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/; + + +/** + * DSPContext. + */ +typedef struct DSPContext { + /* pixel ops : interface with DCT */ + void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size); + void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride); + void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); + void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); + /** + * translational global motion compensation. + */ + void (*gmc1)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x16, int y16, int rounder); + /** + * global motion compensation. + */ + void (*gmc )(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); + void (*clear_blocks)(DCTELEM *blocks/*align 16*/); + int (*pix_sum)(uint8_t * pix, int line_size); + int (*pix_norm1)(uint8_t * pix, int line_size); +// 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4 + + me_cmp_func sad[5]; /* identical to pix_absAxA except additional void * */ + me_cmp_func sse[5]; + me_cmp_func hadamard8_diff[5]; + me_cmp_func dct_sad[5]; + me_cmp_func quant_psnr[5]; + me_cmp_func bit[5]; + me_cmp_func rd[5]; + me_cmp_func vsad[5]; + me_cmp_func vsse[5]; + + me_cmp_func me_pre_cmp[5]; + me_cmp_func me_cmp[5]; + me_cmp_func me_sub_cmp[5]; + me_cmp_func mb_cmp[5]; + me_cmp_func ildct_cmp[5]; //only width 16 used + + /** + * Halfpel motion compensation with rounding (a+b+1)>>1. + * this is an array[4][4] of motion compensation funcions for 4 + * horizontal blocksizes (8,16) and the 4 halfpel positions<br> + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func put_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with rounding (a+b+1)>>1. + * This is an array[4][4] of motion compensation functions for 4 + * horizontal blocksizes (8,16) and the 4 halfpel positions<br> + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination into which the result is averaged (a+b+1)>>1 + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func avg_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with no rounding (a+b)>>1. + * this is an array[2][4] of motion compensation funcions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions<br> + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func put_no_rnd_pixels_tab[2][4]; + + /** + * Halfpel motion compensation with no rounding (a+b)>>1. + * this is an array[2][4] of motion compensation funcions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions<br> + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination into which the result is averaged (a+b)>>1 + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func avg_no_rnd_pixels_tab[2][4]; + + /** + * Thirdpel motion compensation with rounding (a+b+1)>>1. + * this is an array[12] of motion compensation funcions for the 9 thirdpel positions<br> + * *pixels_tab[ xthirdpel + 4*ythirdpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + tpel_mc_func put_tpel_pixels_tab[11]; //FIXME individual func ptr per width? + tpel_mc_func avg_tpel_pixels_tab[11]; //FIXME individual func ptr per width? + + qpel_mc_func put_qpel_pixels_tab[2][16]; + qpel_mc_func avg_qpel_pixels_tab[2][16]; + qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16]; + qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16]; + qpel_mc_func put_mspel_pixels_tab[8]; + + /** + * h264 Chram MC + */ + h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; + h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]; + + qpel_mc_func put_h264_qpel_pixels_tab[3][16]; + qpel_mc_func avg_h264_qpel_pixels_tab[3][16]; + + me_cmp_func pix_abs[2][4]; + + /* huffyuv specific */ + void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); + void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w); + /** + * subtract huffyuv's variant of median prediction + * note, this might read from src1[-1], src2[-1] + */ + void (*sub_hfyu_median_prediction)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top); + void (*bswap_buf)(uint32_t *dst, uint32_t *src, int w); + + void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); + void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); + + /* (I)DCT */ + void (*fdct)(DCTELEM *block/* align 16*/); + void (*fdct248)(DCTELEM *block/* align 16*/); + + /* IDCT really*/ + void (*idct)(DCTELEM *block/* align 16*/); + + /** + * block -> idct -> clip to unsigned 8 bit -> dest. + * (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...) + * @param line_size size in bytes of a horizotal line of dest + */ + void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); + + /** + * block -> idct -> add dest -> clip to unsigned 8 bit -> dest. + * @param line_size size in bytes of a horizotal line of dest + */ + void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); + + /** + * idct input permutation. + * several optimized IDCTs need a permutated input (relative to the normal order of the reference + * IDCT) + * this permutation must be performed before the idct_put/add, note, normally this can be merged + * with the zigzag/alternate scan<br> + * an example to avoid confusion: + * - (->decode coeffs -> zigzag reorder -> dequant -> reference idct ->...) + * - (x -> referece dct -> reference idct -> x) + * - (x -> referece dct -> simple_mmx_perm = idct_permutation -> simple_idct_mmx -> x) + * - (->decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant -> simple_idct_mmx ->...) + */ + uint8_t idct_permutation[64]; + int idct_permutation_type; +#define FF_NO_IDCT_PERM 1 +#define FF_LIBMPEG2_IDCT_PERM 2 +#define FF_SIMPLE_IDCT_PERM 3 +#define FF_TRANSPOSE_IDCT_PERM 4 + + int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale); + void (*add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale); +#define BASIS_SHIFT 16 +#define RECON_SHIFT 6 + +} DSPContext; + +void dsputil_static_init(void); +void dsputil_init(DSPContext* p, AVCodecContext *avctx); + +/** + * permute block according to permuatation. + * @param last last non zero element in scantable order + */ +void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last); + +void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type); + +#define BYTE_VEC32(c) ((c)*0x01010101UL) + +static inline uint32_t rnd_avg32(uint32_t a, uint32_t b) +{ + return (a | b) - (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); +} + +static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b) +{ + return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); +} + +/** + * Empty mmx state. + * this must be called between any dsp function and float/double code. + * for example sin(); dsp->idct_put(); emms_c(); cos() + */ +#define emms_c() + +/* should be defined by architectures supporting + one or more MultiMedia extension */ +int mm_support(void); + +#if defined(HAVE_MMX) + +#undef emms_c + +#define MM_MMX 0x0001 /* standard MMX */ +#define MM_3DNOW 0x0004 /* AMD 3DNOW */ +#define MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */ +#define MM_SSE 0x0008 /* SSE functions */ +#define MM_SSE2 0x0010 /* PIV SSE2 functions */ + +extern int mm_flags; + +void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); +void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); + +static inline void emms(void) +{ + __asm __volatile ("emms;":::"memory"); +} + + +#define emms_c() \ +{\ + if (mm_flags & MM_MMX)\ + emms();\ +} + +#define __align8 __attribute__ ((aligned (8))) + +void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx); + +#elif defined(ARCH_ARMV4L) + +/* This is to use 4 bytes read to the IDCT pointers for some 'zero' + line ptimizations */ +#define __align8 __attribute__ ((aligned (4))) + +void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx); + +#elif defined(HAVE_MLIB) + +/* SPARC/VIS IDCT needs 8-byte aligned DCT blocks */ +#define __align8 __attribute__ ((aligned (8))) + +void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); + +#elif defined(ARCH_ALPHA) + +#define __align8 __attribute__ ((aligned (8))) + +void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); + +#elif defined(ARCH_POWERPC) + +#define MM_ALTIVEC 0x0001 /* standard AltiVec */ + +extern int mm_flags; + +#if defined(HAVE_ALTIVEC) && !defined(CONFIG_DARWIN) +#define pixel altivec_pixel +#include <altivec.h> +#undef pixel +#endif + +#define __align8 __attribute__ ((aligned (16))) + +void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); + +#elif defined(HAVE_MMI) + +#define __align8 __attribute__ ((aligned (16))) + +void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); + +#elif defined(ARCH_SH4) + +#define __align8 __attribute__ ((aligned (8))) + +void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); + +#else + +#define __align8 + +#endif + +#ifdef __GNUC__ + +struct unaligned_64 { uint64_t l; } __attribute__((packed)); +struct unaligned_32 { uint32_t l; } __attribute__((packed)); +struct unaligned_16 { uint16_t l; } __attribute__((packed)); + +#define LD16(a) (((const struct unaligned_16 *) (a))->l) +#define LD32(a) (((const struct unaligned_32 *) (a))->l) +#define LD64(a) (((const struct unaligned_64 *) (a))->l) + +#define ST32(a, b) (((struct unaligned_32 *) (a))->l) = (b) + +#else /* __GNUC__ */ + +#define LD16(a) (*((uint16_t*)(a))) +#define LD32(a) (*((uint32_t*)(a))) +#define LD64(a) (*((uint64_t*)(a))) + +#define ST32(a, b) *((uint32_t*)(a)) = (b) + +#endif /* !__GNUC__ */ + +/* PSNR */ +void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3], + int orig_linesize[3], int coded_linesize, + AVCodecContext *avctx); + +/* FFT computation */ + +/* NOTE: soon integer code will be added, so you must use the + FFTSample type */ +typedef float FFTSample; + +typedef struct FFTComplex { + FFTSample re, im; +} FFTComplex; + +typedef struct FFTContext { + int nbits; + int inverse; + uint16_t *revtab; + FFTComplex *exptab; + FFTComplex *exptab1; /* only used by SSE code */ + void (*fft_calc)(struct FFTContext *s, FFTComplex *z); +} FFTContext; + +int fft_inits(FFTContext *s, int nbits, int inverse); +void fft_permute(FFTContext *s, FFTComplex *z); +void fft_calc_c(FFTContext *s, FFTComplex *z); +void fft_calc_sse(FFTContext *s, FFTComplex *z); +void fft_calc_altivec(FFTContext *s, FFTComplex *z); + +static inline void fft_calc(FFTContext *s, FFTComplex *z) +{ + s->fft_calc(s, z); +} +void fft_end(FFTContext *s); + +/* MDCT computation */ + +typedef struct MDCTContext { + int n; /* size of MDCT (i.e. number of input data * 2) */ + int nbits; /* n = 2^nbits */ + /* pre/post rotation tables */ + FFTSample *tcos; + FFTSample *tsin; + FFTContext fft; +} MDCTContext; + +int ff_mdct_init(MDCTContext *s, int nbits, int inverse); +void ff_imdct_calc(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp); +void ff_mdct_calc(MDCTContext *s, FFTSample *out, + const FFTSample *input, FFTSample *tmp); +void ff_mdct_end(MDCTContext *s); + +#define WARPER8_16(name8, name16)\ +static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ + return name8(s, dst , src , stride, h)\ + +name8(s, dst+8 , src+8 , stride, h);\ +} + +#define WARPER8_16_SQ(name8, name16)\ +static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ + int score=0;\ + score +=name8(s, dst , src , stride, 8);\ + score +=name8(s, dst+8 , src+8 , stride, 8);\ + if(h==16){\ + dst += 8*stride;\ + src += 8*stride;\ + score +=name8(s, dst , src , stride, 8);\ + score +=name8(s, dst+8 , src+8 , stride, 8);\ + }\ + return score;\ +} + +#ifndef HAVE_LRINTF +/* XXX: add ISOC specific test to avoid specific BSD testing. */ +/* better than nothing implementation. */ +/* btw, rintf() is existing on fbsd too -- alex */ +static inline long int lrintf(float x) +{ + return (int)(rint(x)); +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/fft.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,249 @@ +/* + * FFT/IFFT transforms + * Copyright (c) 2002 Fabrice Bellard. + * + * 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 + */ + +/** + * @file fft.c + * FFT/IFFT transforms. + */ + +#include "dsputil.h" + +/** + * The size of the FFT is 2^nbits. If inverse is TRUE, inverse FFT is + * done + */ +int fft_inits(FFTContext *s, int nbits, int inverse) +{ + int i, j, m, n; + float alpha, c1, s1, s2; + + s->nbits = nbits; + n = 1 << nbits; + + s->exptab = malloc((n / 2) * sizeof(FFTComplex)); + if (!s->exptab) + goto fail; + s->revtab = malloc(n * sizeof(uint16_t)); + if (!s->revtab) + goto fail; + s->inverse = inverse; + + s2 = inverse ? 1.0 : -1.0; + + for(i=0;i<(n/2);i++) { + alpha = 2 * M_PI * (float)i / (float)n; + c1 = cos(alpha); + s1 = sin(alpha) * s2; + s->exptab[i].re = c1; + s->exptab[i].im = s1; + } + s->fft_calc = fft_calc_c; + s->exptab1 = NULL; + /* compute constant table for HAVE_SSE version */ +#if (defined(HAVE_MMX) && defined(HAVE_BUILTIN_VECTOR)) || defined(HAVE_ALTIVEC) + { + int has_vectors = 0; + +#if defined(HAVE_MMX) + has_vectors = mm_support() & MM_SSE; +#endif +#if defined(HAVE_ALTIVEC) && !defined(ALTIVEC_USE_REFERENCE_C_CODE) + has_vectors = mm_support() & MM_ALTIVEC; +#endif + if (has_vectors) { + int np, nblocks, np2, l; + FFTComplex *q; + + np = 1 << nbits; + nblocks = np >> 3; + np2 = np >> 1; + s->exptab1 = malloc(np * 2 * sizeof(FFTComplex)); + if (!s->exptab1) + goto fail; + q = s->exptab1; + do { + for(l = 0; l < np2; l += 2 * nblocks) { + *q++ = s->exptab[l]; + *q++ = s->exptab[l + nblocks]; + + q->re = -s->exptab[l].im; + q->im = s->exptab[l].re; + q++; + q->re = -s->exptab[l + nblocks].im; + q->im = s->exptab[l + nblocks].re; + q++; + } + nblocks = nblocks >> 1; + } while (nblocks != 0); + av_freep(&s->exptab); +#if defined(HAVE_MMX) + s->fft_calc = fft_calc_sse; +#else + s->fft_calc = fft_calc_altivec; +#endif + } + } +#endif + + /* compute bit reverse table */ + + for(i=0;i<n;i++) { + m=0; + for(j=0;j<nbits;j++) { + m |= ((i >> j) & 1) << (nbits-j-1); + } + s->revtab[i]=m; + } + return 0; + fail: + av_freep(&s->revtab); + av_freep(&s->exptab); + av_freep(&s->exptab1); + return -1; +} + +/* butter fly op */ +#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \ +{\ + FFTSample ax, ay, bx, by;\ + bx=pre1;\ + by=pim1;\ + ax=qre1;\ + ay=qim1;\ + pre = (bx + ax);\ + pim = (by + ay);\ + qre = (bx - ax);\ + qim = (by - ay);\ +} + +#define MUL16(a,b) ((a) * (b)) + +#define CMUL(pre, pim, are, aim, bre, bim) \ +{\ + pre = (MUL16(are, bre) - MUL16(aim, bim));\ + pim = (MUL16(are, bim) + MUL16(bre, aim));\ +} + +/** + * Do a complex FFT with the parameters defined in fft_init(). The + * input data must be permuted before with s->revtab table. No + * 1.0/sqrt(n) normalization is done. + */ +void fft_calc_c(FFTContext *s, FFTComplex *z) +{ + int ln = s->nbits; + int j, np, np2; + int nblocks, nloops; + register FFTComplex *p, *q; + FFTComplex *exptab = s->exptab; + int l; + FFTSample tmp_re, tmp_im; + + np = 1 << ln; + + /* pass 0 */ + + p=&z[0]; + j=(np >> 1); + do { + BF(p[0].re, p[0].im, p[1].re, p[1].im, + p[0].re, p[0].im, p[1].re, p[1].im); + p+=2; + } while (--j != 0); + + /* pass 1 */ + + + p=&z[0]; + j=np >> 2; + if (s->inverse) { + do { + BF(p[0].re, p[0].im, p[2].re, p[2].im, + p[0].re, p[0].im, p[2].re, p[2].im); + BF(p[1].re, p[1].im, p[3].re, p[3].im, + p[1].re, p[1].im, -p[3].im, p[3].re); + p+=4; + } while (--j != 0); + } else { + do { + BF(p[0].re, p[0].im, p[2].re, p[2].im, + p[0].re, p[0].im, p[2].re, p[2].im); + BF(p[1].re, p[1].im, p[3].re, p[3].im, + p[1].re, p[1].im, p[3].im, -p[3].re); + p+=4; + } while (--j != 0); + } + /* pass 2 .. ln-1 */ + + nblocks = np >> 3; + nloops = 1 << 2; + np2 = np >> 1; + do { + p = z; + q = z + nloops; + for (j = 0; j < nblocks; ++j) { + BF(p->re, p->im, q->re, q->im, + p->re, p->im, q->re, q->im); + + p++; + q++; + for(l = nblocks; l < np2; l += nblocks) { + CMUL(tmp_re, tmp_im, exptab[l].re, exptab[l].im, q->re, q->im); + BF(p->re, p->im, q->re, q->im, + p->re, p->im, tmp_re, tmp_im); + p++; + q++; + } + + p += nloops; + q += nloops; + } + nblocks = nblocks >> 1; + nloops = nloops << 1; + } while (nblocks != 0); +} + +/** + * Do the permutation needed BEFORE calling fft_calc() + */ +void fft_permute(FFTContext *s, FFTComplex *z) +{ + int j, k, np; + FFTComplex tmp; + const uint16_t *revtab = s->revtab; + + /* reverse */ + np = 1 << s->nbits; + for(j=0;j<np;j++) { + k = revtab[j]; + if (k < j) { + tmp = z[k]; + z[k] = z[j]; + z[j] = tmp; + } + } +} + +void fft_end(FFTContext *s) +{ + av_freep(&s->revtab); + av_freep(&s->exptab); + av_freep(&s->exptab1); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/file.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,123 @@ +/* + * Buffered file io for ffmpeg system + * Copyright (c) 2001 Fabrice Bellard + * + * 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 "avformat.h" +#include "cutils.h" +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/time.h> + +/* standard file protocol */ + +static int file_open(URLContext *h, const char *filename, int flags) +{ + int access; + int fd; + + strstart(filename, "file:", &filename); + + if (flags & URL_WRONLY) { + access = O_CREAT | O_TRUNC | O_WRONLY; + } else { + access = O_RDONLY; + } + + fd = open(filename, access, 0666); + if (fd < 0) + return -ENOENT; + h->priv_data = (void *)(long)fd; + return 0; +} + +static int file_read(URLContext *h, unsigned char *buf, int size) +{ + int fd = (int)(long)h->priv_data; + return read(fd, buf, size); +} + +static int file_write(URLContext *h, unsigned char *buf, int size) +{ + int fd = (int)(long)h->priv_data; + return write(fd, buf, size); +} + +/* XXX: use llseek */ +static offset_t file_seek(URLContext *h, offset_t pos, int whence) +{ + int fd = (int)(long)h->priv_data; + return lseek(fd, pos, whence); +} + +static int file_close(URLContext *h) +{ + int fd = (int)(long)h->priv_data; + return close(fd); +} + +URLProtocol file_protocol = { + "file", + file_open, + file_read, + file_write, + file_seek, + file_close, + NULL +}; + +/* pipe protocol */ + +static int pipe_open(URLContext *h, const char *filename, int flags) +{ + int fd; + + if (flags & URL_WRONLY) { + fd = 1; + } else { + fd = 0; + } + h->priv_data = (void *)(long)fd; + return 0; +} + +static int pipe_read(URLContext *h, unsigned char *buf, int size) +{ + int fd = (int)(long)h->priv_data; + return read(fd, buf, size); +} + +static int pipe_write(URLContext *h, unsigned char *buf, int size) +{ + int fd = (int)(long)h->priv_data; + return write(fd, buf, size); +} + +static int pipe_close(URLContext *h) +{ + return 0; +} + +URLProtocol pipe_protocol = { + "pipe", + pipe_open, + pipe_read, + pipe_write, + NULL, + pipe_close, + NULL +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/futils.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,2243 @@ +/* + * Various utilities for ffmpeg system + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * 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 "avformat.h" +#include "avcodec.h" +#include "cutils.h" +#include "utils.h" + +#undef NDEBUG +#include <assert.h> + +AVInputFormat *first_iformat; +AVOutputFormat *first_oformat; +AVImageFormat *first_image_format; + +void av_register_input_format(AVInputFormat *format) +{ + AVInputFormat **p; + p = &first_iformat; + while (*p != NULL) p = &(*p)->next; + *p = format; + format->next = NULL; +} + +int match_ext(const char *filename, const char *extensions) +{ + const char *ext, *p; + char ext1[32], *q; + + ext = strrchr(filename, '.'); + if (ext) { + ext++; + p = extensions; + for(;;) { + q = ext1; + while (*p != '\0' && *p != ',') + *q++ = *p++; + *q = '\0'; + if (!strcasecmp(ext1, ext)) + return 1; + if (*p == '\0') + break; + p++; + } + } + return 0; +} + +AVOutputFormat *guess_format(const char *short_name, const char *filename, + const char *mime_type) +{ + AVOutputFormat *fmt, *fmt_found; + int score_max, score; + + /* specific test for image sequences */ + if (!short_name && filename && + filename_number_test(filename) >= 0 && + guess_image_format(filename)) { + return guess_format("image", NULL, NULL); + } + + /* find the proper file type */ + fmt_found = NULL; + score_max = 0; + fmt = first_oformat; + while (fmt != NULL) { + score = 0; + if (fmt->name && short_name && !strcmp(fmt->name, short_name)) + score += 100; + if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type)) + score += 10; + if (filename && fmt->extensions && + match_ext(filename, fmt->extensions)) { + score += 5; + } + if (score > score_max) { + score_max = score; + fmt_found = fmt; + } + fmt = fmt->next; + } + return fmt_found; +} + +AVOutputFormat *guess_stream_format(const char *short_name, const char *filename, + const char *mime_type) +{ + AVOutputFormat *fmt = guess_format(short_name, filename, mime_type); + + if (fmt) { + AVOutputFormat *stream_fmt; + char stream_format_name[64]; + + snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name); + stream_fmt = guess_format(stream_format_name, NULL, NULL); + + if (stream_fmt) + fmt = stream_fmt; + } + + return fmt; +} + +AVInputFormat *av_find_input_format(const char *short_name) +{ + AVInputFormat *fmt; + for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) { + if (!strcmp(fmt->name, short_name)) + return fmt; + } + return NULL; +} + +/* memory handling */ + +/** + * Default packet destructor + */ +static void av_destruct_packet(AVPacket *pkt) +{ + free(pkt->data); + pkt->data = NULL; pkt->size = 0; +} + +/** + * Allocate the payload of a packet and intialized its fields to default values. + * + * @param pkt packet + * @param size wanted payload size + * @return 0 if OK. AVERROR_xxx otherwise. + */ +int av_new_packet(AVPacket *pkt, int size) +{ + unsigned char *data = malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!data) + return AVERROR_NOMEM; + memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + + av_init_packet(pkt); + pkt->data = data; + pkt->size = size; + pkt->destruct = av_destruct_packet; + return 0; +} + +/* This is a hack - the packet memory allocation stuff is broken. The + packet is allocated if it was not really allocated */ +int av_dup_packet(AVPacket *pkt) +{ + if (pkt->destruct != av_destruct_packet) { + uint8_t *data; + /* we duplicate the packet and don't forget to put the padding + again */ + data = malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!data) { + return AVERROR_NOMEM; + } + memcpy(data, pkt->data, pkt->size); + memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + pkt->data = data; + pkt->destruct = av_destruct_packet; + } + return 0; +} + +/* fifo handling */ + +int fifo_init(FifoBuffer *f, int size) +{ + f->buffer = malloc(size); + if (!f->buffer) + return -1; + f->end = f->buffer + size; + f->wptr = f->rptr = f->buffer; + return 0; +} + +void fifo_free(FifoBuffer *f) +{ + free(f->buffer); +} + +int fifo_size(FifoBuffer *f, uint8_t *rptr) +{ + int size; + + if (f->wptr >= rptr) { + size = f->wptr - rptr; + } else { + size = (f->end - rptr) + (f->wptr - f->buffer); + } + return size; +} + +/* get data from the fifo (return -1 if not enough data) */ +int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr) +{ + uint8_t *rptr = *rptr_ptr; + int size, len; + + if (f->wptr >= rptr) { + size = f->wptr - rptr; + } else { + size = (f->end - rptr) + (f->wptr - f->buffer); + } + + if (size < buf_size) + return -1; + while (buf_size > 0) { + len = f->end - rptr; + if (len > buf_size) + len = buf_size; + memcpy(buf, rptr, len); + buf += len; + rptr += len; + if (rptr >= f->end) + rptr = f->buffer; + buf_size -= len; + } + *rptr_ptr = rptr; + return 0; +} + +void fifo_write(FifoBuffer *f, uint8_t *buf, int size, uint8_t **wptr_ptr) +{ + int len; + uint8_t *wptr; + wptr = *wptr_ptr; + while (size > 0) { + len = f->end - wptr; + if (len > size) + len = size; + memcpy(wptr, buf, len); + wptr += len; + if (wptr >= f->end) + wptr = f->buffer; + buf += len; + size -= len; + } + *wptr_ptr = wptr; +} + +int filename_number_test(const char *filename) +{ + char buf[1024]; + return get_frame_filename(buf, sizeof(buf), filename, 1); +} + +/* guess file format */ +AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened) +{ + AVInputFormat *fmt1, *fmt; + int score, score_max; + + fmt = NULL; + score_max = 0; + for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) { + if (!is_opened && !(fmt1->flags & AVFMT_NOFILE)) + continue; + score = 0; + if (fmt1->read_probe) { + score = fmt1->read_probe(pd); + } else if (fmt1->extensions) { + if (match_ext(pd->filename, fmt1->extensions)) { + score = 50; + } + } + if (score > score_max) { + score_max = score; + fmt = fmt1; + } + } + return fmt; +} + +/************************************************************/ +/* input media file */ + +/** + * open a media file from an IO stream. 'fmt' must be specified. + */ +int av_open_input_stream(AVFormatContext **ic_ptr, + ByteIOContext *pb, const char *filename, + AVInputFormat *fmt, AVFormatParameters *ap) +{ + int err; + AVFormatContext *ic; + + ic = av_mallocz(sizeof(AVFormatContext)); + if (!ic) { + err = AVERROR_NOMEM; + goto fail; + } + ic->iformat = fmt; + if (pb) + ic->pb = *pb; + ic->duration = AV_NOPTS_VALUE; + ic->start_time = AV_NOPTS_VALUE; + pstrcpy(ic->filename, sizeof(ic->filename), filename); + + /* allocate private data */ + if (fmt->priv_data_size > 0) { + ic->priv_data = av_mallocz(fmt->priv_data_size); + if (!ic->priv_data) { + err = AVERROR_NOMEM; + goto fail; + } + } else { + ic->priv_data = NULL; + } + + /* default pts settings is MPEG like */ + av_set_pts_info(ic, 33, 1, 90000); + ic->last_pkt_pts = AV_NOPTS_VALUE; + ic->last_pkt_dts = AV_NOPTS_VALUE; + ic->last_pkt_stream_pts = AV_NOPTS_VALUE; + ic->last_pkt_stream_dts = AV_NOPTS_VALUE; + + err = ic->iformat->read_header(ic, ap); + if (err < 0) + goto fail; + + if (pb) + ic->data_offset = url_ftell(&ic->pb); + + *ic_ptr = ic; + return 0; + fail: + if (ic) { + av_freep(&ic->priv_data); + } + free(ic); + *ic_ptr = NULL; + return err; +} + +#define PROBE_BUF_SIZE 2048 + +/** + * Open a media file as input. The codec are not opened. Only the file + * header (if present) is read. + * + * @param ic_ptr the opened media file handle is put here + * @param filename filename to open. + * @param fmt if non NULL, force the file format to use + * @param buf_size optional buffer size (zero if default is OK) + * @param ap additionnal parameters needed when opening the file (NULL if default) + * @return 0 if OK. AVERROR_xxx otherwise. + */ +int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, + AVInputFormat *fmt, + int buf_size, + AVFormatParameters *ap) +{ + int err, must_open_file, file_opened; + uint8_t buf[PROBE_BUF_SIZE]; + AVProbeData probe_data, *pd = &probe_data; + ByteIOContext pb1, *pb = &pb1; + + file_opened = 0; + pd->filename = ""; + if (filename) + pd->filename = filename; + pd->buf = buf; + pd->buf_size = 0; + + if (!fmt) { + /* guess format if no file can be opened */ + fmt = av_probe_input_format(pd, 0); + } + + /* do not open file if the format does not need it. XXX: specific + hack needed to handle RTSP/TCP */ + must_open_file = 1; + if (fmt && (fmt->flags & AVFMT_NOFILE)) { + must_open_file = 0; + } + + if (!fmt || must_open_file) { + /* if no file needed do not try to open one */ + if (url_fopen(pb, filename, URL_RDONLY) < 0) { + err = AVERROR_IO; + goto fail; + } + file_opened = 1; + if (buf_size > 0) { + url_setbufsize(pb, buf_size); + } + if (!fmt) { + /* read probe data */ + pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE); + url_fseek(pb, 0, SEEK_SET); + } + } + + /* guess file format */ + if (!fmt) { + fmt = av_probe_input_format(pd, 1); + } + + /* if still no format found, error */ + if (!fmt) { + err = AVERROR_NOFMT; + goto fail; + } + + /* check filename in case of an image number is expected */ + if (fmt->flags & AVFMT_NEEDNUMBER) { + if (filename_number_test(filename) < 0) { + err = AVERROR_NUMEXPECTED; + goto fail; + } + } + err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap); + if (err) + goto fail; + return 0; + fail: + if (file_opened) + url_fclose(pb); + *ic_ptr = NULL; + return err; + +} + +/*******************************************************/ + +/** + * Read a transport packet from a media file. This function is + * absolete and should never be used. Use av_read_frame() instead. + * + * @param s media file handle + * @param pkt is filled + * @return 0 if OK. AVERROR_xxx if error. + */ +int av_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + return s->iformat->read_packet(s, pkt); +} + +/**********************************************************/ + +/* convert the packet time stamp units and handle wrapping. The + wrapping is handled by considering the next PTS/DTS as a delta to + the previous value. We handle the delta as a fraction to avoid any + rounding errors. */ +static inline int64_t convert_timestamp_units(AVFormatContext *s, + int64_t *plast_pkt_pts, + int *plast_pkt_pts_frac, + int64_t *plast_pkt_stream_pts, + int64_t pts) +{ + int64_t stream_pts; + int64_t delta_pts; + int shift, pts_frac; + + if (pts != (int64_t)AV_NOPTS_VALUE) { + stream_pts = pts; + if (*plast_pkt_stream_pts != (int64_t)AV_NOPTS_VALUE) { + shift = 64 - s->pts_wrap_bits; + delta_pts = ((stream_pts - *plast_pkt_stream_pts) << shift) >> shift; + /* XXX: overflow possible but very unlikely as it is a delta */ + delta_pts = delta_pts * AV_TIME_BASE * s->pts_num; + pts = *plast_pkt_pts + (delta_pts / s->pts_den); + pts_frac = *plast_pkt_pts_frac + (delta_pts % s->pts_den); + if (pts_frac >= s->pts_den) { + pts_frac -= s->pts_den; + pts++; + } + } else { + /* no previous pts, so no wrapping possible */ + pts = (int64_t)(((double)stream_pts * AV_TIME_BASE * s->pts_num) / + (double)s->pts_den); + pts_frac = 0; + } + *plast_pkt_stream_pts = stream_pts; + *plast_pkt_pts = pts; + *plast_pkt_pts_frac = pts_frac; + } + return pts; +} + +/* get the number of samples of an audio frame. Return (-1) if error */ +static int get_audio_frame_size(AVCodecContext *enc, int size) +{ + int frame_size; + + if (enc->frame_size <= 1) { + /* specific hack for pcm codecs because no frame size is + provided */ + switch(enc->codec_id) { + case CODEC_ID_PCM_S16LE: + case CODEC_ID_PCM_S16BE: + case CODEC_ID_PCM_U16LE: + case CODEC_ID_PCM_U16BE: + if (enc->channels == 0) + return -1; + frame_size = size / (2 * enc->channels); + break; + case CODEC_ID_PCM_S8: + case CODEC_ID_PCM_U8: + case CODEC_ID_PCM_MULAW: + case CODEC_ID_PCM_ALAW: + if (enc->channels == 0) + return -1; + frame_size = size / (enc->channels); + break; + default: + /* used for example by ADPCM codecs */ + if (enc->bit_rate == 0) + return -1; + frame_size = (size * 8 * enc->sample_rate) / enc->bit_rate; + break; + } + } else { + frame_size = enc->frame_size; + } + return frame_size; +} + + +/* return the frame duration in seconds, return 0 if not available */ +static void compute_frame_duration(int *pnum, int *pden, + AVFormatContext *s, AVStream *st, + AVCodecParserContext *pc, AVPacket *pkt) +{ + int frame_size; + + *pnum = 0; + *pden = 0; + switch(st->codec.codec_type) { + case CODEC_TYPE_AUDIO: + frame_size = get_audio_frame_size(&st->codec, pkt->size); + if (frame_size < 0) + break; + *pnum = frame_size; + *pden = st->codec.sample_rate; + break; + default: + break; + } +} + +static void compute_pkt_fields(AVFormatContext *s, AVStream *st, + AVCodecParserContext *pc, AVPacket *pkt) +{ + int num, den, presentation_delayed; + + if (pkt->duration == 0) { + compute_frame_duration(&num, &den, s, st, pc, pkt); + if (den && num) { + pkt->duration = (num * (int64_t)AV_TIME_BASE) / den; + } + } + + /* do we have a video B frame ? */ + presentation_delayed = 0; + + /* interpolate PTS and DTS if they are not present */ + if (presentation_delayed) { + /* DTS = decompression time stamp */ + /* PTS = presentation time stamp */ + if (pkt->dts == (int64_t)AV_NOPTS_VALUE) { + pkt->dts = st->cur_dts; + } else { + st->cur_dts = pkt->dts; + } + /* this is tricky: the dts must be incremented by the duration + of the frame we are displaying, i.e. the last I or P frame */ + if (st->last_IP_duration == 0) + st->cur_dts += pkt->duration; + else + st->cur_dts += st->last_IP_duration; + st->last_IP_duration = pkt->duration; + /* cannot compute PTS if not present (we can compute it only + by knowing the futur */ + } else { + /* presentation is not delayed : PTS and DTS are the same */ + if (pkt->pts == (int64_t)AV_NOPTS_VALUE) { + pkt->pts = st->cur_dts; + pkt->dts = st->cur_dts; + } else { + st->cur_dts = pkt->pts; + pkt->dts = pkt->pts; + } + st->cur_dts += pkt->duration; + } + + /* update flags */ + if (pc) { + pkt->flags = 0; + /* XXX: that's odd, fix it later */ + switch(st->codec.codec_type) { + case CODEC_TYPE_AUDIO: + pkt->flags |= PKT_FLAG_KEY; + break; + default: + break; + } + } + +} + +static void av_destruct_packet_nofree(AVPacket *pkt) +{ + pkt->data = NULL; pkt->size = 0; +} + +static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt) +{ + AVStream *st; + int len, ret, i; + + for(;;) { + /* select current input stream component */ + st = s->cur_st; + if (st) { + if (!st->parser) { + /* no parsing needed: we just output the packet as is */ + /* raw data support */ + *pkt = s->cur_pkt; + compute_pkt_fields(s, st, NULL, pkt); + s->cur_st = NULL; + return 0; + } else if (s->cur_len > 0) { + len = av_parser_parse(st->parser, &st->codec, &pkt->data, &pkt->size, + s->cur_ptr, s->cur_len, + s->cur_pkt.pts, s->cur_pkt.dts); + s->cur_pkt.pts = AV_NOPTS_VALUE; + s->cur_pkt.dts = AV_NOPTS_VALUE; + /* increment read pointer */ + s->cur_ptr += len; + s->cur_len -= len; + + /* return packet if any */ + if (pkt->size) { + got_packet: + pkt->duration = 0; + pkt->stream_index = st->index; + pkt->pts = st->parser->pts; + pkt->dts = st->parser->dts; + pkt->destruct = av_destruct_packet_nofree; + compute_pkt_fields(s, st, st->parser, pkt); + return 0; + } + } else { + /* free packet */ + av_free_packet(&s->cur_pkt); + s->cur_st = NULL; + } + } else { + /* read next packet */ + ret = av_read_packet(s, &s->cur_pkt); + if (ret < 0) { + if (ret == -EAGAIN) + return ret; + /* return the last frames, if any */ + for(i = 0; i < s->nb_streams; i++) { + st = s->streams[i]; + if (st->parser) { + av_parser_parse(st->parser, &st->codec, + &pkt->data, &pkt->size, + NULL, 0, + AV_NOPTS_VALUE, AV_NOPTS_VALUE); + if (pkt->size) + goto got_packet; + } + } + /* no more packets: really terminates parsing */ + return ret; + } + + /* convert the packet time stamp units and handle wrapping */ + s->cur_pkt.pts = convert_timestamp_units(s, + &s->last_pkt_pts, &s->last_pkt_pts_frac, + &s->last_pkt_stream_pts, + s->cur_pkt.pts); + s->cur_pkt.dts = convert_timestamp_units(s, + &s->last_pkt_dts, &s->last_pkt_dts_frac, + &s->last_pkt_stream_dts, + s->cur_pkt.dts); +#if 0 + if (s->cur_pkt.stream_index == 0) { + if (s->cur_pkt.pts != AV_NOPTS_VALUE) + printf("PACKET pts=%0.3f\n", + (double)s->cur_pkt.pts / AV_TIME_BASE); + if (s->cur_pkt.dts != AV_NOPTS_VALUE) + printf("PACKET dts=%0.3f\n", + (double)s->cur_pkt.dts / AV_TIME_BASE); + } +#endif + + /* duration field */ + if (s->cur_pkt.duration != 0) { + s->cur_pkt.duration = ((int64_t)s->cur_pkt.duration * AV_TIME_BASE * s->pts_num) / + s->pts_den; + } + + st = s->streams[s->cur_pkt.stream_index]; + s->cur_st = st; + s->cur_ptr = s->cur_pkt.data; + s->cur_len = s->cur_pkt.size; + if (st->need_parsing && !st->parser) { + st->parser = av_parser_init(st->codec.codec_id); + if (!st->parser) { + /* no parser available : just output the raw packets */ + st->need_parsing = 0; + } + } + } + } +} + +/** + * Return the next frame of a stream. The returned packet is valid + * until the next av_read_frame() or until av_close_input_file() and + * must be freed with av_free_packet. For video, the packet contains + * exactly one frame. For audio, it contains an integer number of + * frames if each frame has a known fixed size (e.g. PCM or ADPCM + * data). If the audio frames have a variable size (e.g. MPEG audio), + * then it contains one frame. + * + * pkt->pts, pkt->dts and pkt->duration are always set to correct + * values in AV_TIME_BASE unit (and guessed if the format cannot + * provided them). pkt->pts can be AV_NOPTS_VALUE if the video format + * has B frames, so it is better to rely on pkt->dts if you do not + * decompress the payload. + * + * Return 0 if OK, < 0 if error or end of file. + */ +int av_read_frame(AVFormatContext *s, AVPacket *pkt) +{ + AVPacketList *pktl; + + pktl = s->packet_buffer; + if (pktl) { + /* read packet from packet buffer, if there is data */ + *pkt = pktl->pkt; + s->packet_buffer = pktl->next; + free(pktl); + return 0; + } else { + return av_read_frame_internal(s, pkt); + } +} + +/* XXX: suppress the packet queue */ +static void flush_packet_queue(AVFormatContext *s) +{ + AVPacketList *pktl; + + for(;;) { + pktl = s->packet_buffer; + if (!pktl) + break; + s->packet_buffer = pktl->next; + av_free_packet(&pktl->pkt); + free(pktl); + } +} + +/*******************************************************/ +/* seek support */ + +int av_find_default_stream_index(AVFormatContext *s) +{ + int i; + AVStream *st; + + if (s->nb_streams <= 0) + return -1; + for(i = 0; i < s->nb_streams; i++) { + st = s->streams[i]; + + } + return 0; +} + +/* flush the frame reader */ +static void av_read_frame_flush(AVFormatContext *s) +{ + AVStream *st; + int i; + + flush_packet_queue(s); + + /* free previous packet */ + if (s->cur_st) { + if (s->cur_st->parser) + av_free_packet(&s->cur_pkt); + s->cur_st = NULL; + } + /* fail safe */ + s->cur_ptr = NULL; + s->cur_len = 0; + + /* for each stream, reset read state */ + for(i = 0; i < s->nb_streams; i++) { + st = s->streams[i]; + + if (st->parser) { + av_parser_close(st->parser); + st->parser = NULL; + } + st->cur_dts = 0; /* we set the current DTS to an unspecified origin */ + } +} + +/* add a index entry into a sorted list updateing if it is already there */ +int av_add_index_entry(AVStream *st, + int64_t pos, int64_t timestamp, int distance, int flags) +{ + AVIndexEntry *entries, *ie; + int index; + + entries = av_fast_realloc(st->index_entries, + &st->index_entries_allocated_size, + (st->nb_index_entries + 1) * + sizeof(AVIndexEntry)); + st->index_entries= entries; + + if(st->nb_index_entries){ + index= av_index_search_timestamp(st, timestamp); + ie= &entries[index]; + + if(ie->timestamp != timestamp){ + if(ie->timestamp < timestamp){ + index++; //index points to next instead of previous entry, maybe nonexistant + ie= &st->index_entries[index]; + }else + assert(index==0); + + if(index != st->nb_index_entries){ + assert(index < st->nb_index_entries); + memmove(entries + index + 1, entries + index, sizeof(AVIndexEntry)*(st->nb_index_entries - index)); + } + st->nb_index_entries++; + } + }else{ + index= st->nb_index_entries++; + ie= &entries[index]; + } + + ie->pos = pos; + ie->timestamp = timestamp; + ie->min_distance= distance; + ie->flags = flags; + + return index; +} + +/* build an index for raw streams using a parser */ +static void av_build_index_raw(AVFormatContext *s) +{ + AVPacket pkt1, *pkt = &pkt1; + int ret; + AVStream *st; + + st = s->streams[0]; + av_read_frame_flush(s); + url_fseek(&s->pb, s->data_offset, SEEK_SET); + + for(;;) { + ret = av_read_frame(s, pkt); + if (ret < 0) + break; + if (pkt->stream_index == 0 && st->parser && + (pkt->flags & PKT_FLAG_KEY)) { + av_add_index_entry(st, st->parser->frame_offset, pkt->dts, + 0, AVINDEX_KEYFRAME); + } + av_free_packet(pkt); + } +} + +/* return TRUE if we deal with a raw stream (raw codec data and + parsing needed) */ +static int is_raw_stream(AVFormatContext *s) +{ + AVStream *st; + + if (s->nb_streams != 1) + return 0; + st = s->streams[0]; + if (!st->need_parsing) + return 0; + return 1; +} + +/* return the largest index entry whose timestamp is <= + wanted_timestamp */ +int av_index_search_timestamp(AVStream *st, int wanted_timestamp) +{ + AVIndexEntry *entries= st->index_entries; + int nb_entries= st->nb_index_entries; + int a, b, m; + int64_t timestamp; + + if (nb_entries <= 0) + return -1; + + a = 0; + b = nb_entries - 1; + + while (a < b) { + m = (a + b + 1) >> 1; + timestamp = entries[m].timestamp; + if (timestamp > wanted_timestamp) { + b = m - 1; + } else { + a = m; + } + } + return a; +} + +static int av_seek_frame_generic(AVFormatContext *s, + int stream_index, int64_t timestamp) +{ + int index; + AVStream *st; + AVIndexEntry *ie; + + if (!s->index_built) { + if (is_raw_stream(s)) { + av_build_index_raw(s); + } else { + return -1; + } + s->index_built = 1; + } + + if (stream_index < 0) + stream_index = 0; + st = s->streams[stream_index]; + index = av_index_search_timestamp(st, timestamp); + if (index < 0) + return -1; + + /* now we have found the index, we can seek */ + ie = &st->index_entries[index]; + av_read_frame_flush(s); + url_fseek(&s->pb, ie->pos, SEEK_SET); + st->cur_dts = ie->timestamp; + return 0; +} + +/** + * Seek to the key frame just before the frame at timestamp + * 'timestamp' in 'stream_index'. If stream_index is (-1), a default + * stream is selected + */ +int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp) +{ + int ret; + + av_read_frame_flush(s); + + /* first, we try the format specific seek */ + if (s->iformat->read_seek) + ret = s->iformat->read_seek(s, stream_index, timestamp); + else + ret = -1; + if (ret >= 0) { + return 0; + } + + return av_seek_frame_generic(s, stream_index, timestamp); +} + +/*******************************************************/ + +/* return TRUE if the stream has accurate timings for at least one component */ +//#if 0 McMCC +static int av_has_timings(AVFormatContext *ic) +{ + int i; + AVStream *st; + + for(i = 0;i < ic->nb_streams; i++) { + st = ic->streams[i]; + if (st->start_time != (int64_t)AV_NOPTS_VALUE && + st->duration != (int64_t)AV_NOPTS_VALUE) + return 1; + } + return 0; +} + +/* estimate the stream timings from the one of each components. Also + compute the global bitrate if possible */ +static void av_update_stream_timings(AVFormatContext *ic) +{ + int64_t start_time, end_time, end_time1; + int i; + AVStream *st; + + start_time = MAXINT64; + end_time = MININT64; + for(i = 0;i < ic->nb_streams; i++) { + st = ic->streams[i]; + if (st->start_time != (int64_t)AV_NOPTS_VALUE) { + if (st->start_time < start_time) + start_time = st->start_time; + if (st->duration != (int64_t)AV_NOPTS_VALUE) { + end_time1 = st->start_time + st->duration; + if (end_time1 > end_time) + end_time = end_time1; + } + } + } + if (start_time != MAXINT64) { + ic->start_time = start_time; + if (end_time != MAXINT64) { + ic->duration = end_time - start_time; + if (ic->file_size > 0) { + /* compute the bit rate */ + ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE / + (double)ic->duration; + } + } + } + +} + +static void fill_all_stream_timings(AVFormatContext *ic) +{ + int i; + AVStream *st; + + av_update_stream_timings(ic); + for(i = 0;i < ic->nb_streams; i++) { + st = ic->streams[i]; + if (st->start_time == (int64_t)AV_NOPTS_VALUE) { + st->start_time = ic->start_time; + st->duration = ic->duration; + } + } +} + +static void av_estimate_timings_from_bit_rate(AVFormatContext *ic) +{ + int64_t filesize, duration; + int bit_rate, i; + AVStream *st; + + /* if bit_rate is already set, we believe it */ + if (ic->bit_rate == 0) { + bit_rate = 0; + for(i=0;i<ic->nb_streams;i++) { + st = ic->streams[i]; + bit_rate += st->codec.bit_rate; + } + ic->bit_rate = bit_rate; + } + + /* if duration is already set, we believe it */ + if (ic->duration == (int64_t)AV_NOPTS_VALUE && + ic->bit_rate != 0 && + ic->file_size != 0) { + filesize = ic->file_size; + if (filesize > 0) { + duration = (int64_t)((8 * AV_TIME_BASE * (double)filesize) / (double)ic->bit_rate); + for(i = 0; i < ic->nb_streams; i++) { + st = ic->streams[i]; + if (st->start_time == (int64_t)AV_NOPTS_VALUE || + st->duration == (int64_t)AV_NOPTS_VALUE) { + st->start_time = 0; + st->duration = duration; + } + } + } + } +} + +#define DURATION_MAX_READ_SIZE 250000 +#if 0 +/* only usable for MPEG-PS streams */ +static void av_estimate_timings_from_pts(AVFormatContext *ic) +{ + AVPacket pkt1, *pkt = &pkt1; + AVStream *st; + int read_size, i, ret; + int64_t start_time, end_time, end_time1; + int64_t filesize, offset, duration; + + /* free previous packet */ + if (ic->cur_st && ic->cur_st->parser) + av_free_packet(&ic->cur_pkt); + ic->cur_st = NULL; + + /* flush packet queue */ + flush_packet_queue(ic); + + + /* we read the first packets to get the first PTS (not fully + accurate, but it is enough now) */ + url_fseek(&ic->pb, 0, SEEK_SET); + read_size = 0; + for(;;) { + if (read_size >= DURATION_MAX_READ_SIZE) + break; + /* if all info is available, we can stop */ + for(i = 0;i < ic->nb_streams; i++) { + st = ic->streams[i]; + if (st->start_time == AV_NOPTS_VALUE) + break; + } + if (i == ic->nb_streams) + break; + + ret = av_read_packet(ic, pkt); + if (ret != 0) + break; + read_size += pkt->size; + st = ic->streams[pkt->stream_index]; + if (pkt->pts != AV_NOPTS_VALUE) { + if (st->start_time == AV_NOPTS_VALUE) + st->start_time = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den); + } + av_free_packet(pkt); + } + + /* we compute the minimum start_time and use it as default */ + start_time = MAXINT64; + for(i = 0; i < ic->nb_streams; i++) { + st = ic->streams[i]; + if (st->start_time != AV_NOPTS_VALUE && + st->start_time < start_time) + start_time = st->start_time; + } + if (start_time != MAXINT64) + ic->start_time = start_time; + + /* estimate the end time (duration) */ + /* XXX: may need to support wrapping */ + filesize = ic->file_size; + offset = filesize - DURATION_MAX_READ_SIZE; + if (offset < 0) + offset = 0; + + url_fseek(&ic->pb, offset, SEEK_SET); + read_size = 0; + for(;;) { + if (read_size >= DURATION_MAX_READ_SIZE) + break; + /* if all info is available, we can stop */ + for(i = 0;i < ic->nb_streams; i++) { + st = ic->streams[i]; + if (st->duration == AV_NOPTS_VALUE) + break; + } + if (i == ic->nb_streams) + break; + + ret = av_read_packet(ic, pkt); + if (ret != 0) + break; + read_size += pkt->size; + st = ic->streams[pkt->stream_index]; + if (pkt->pts != AV_NOPTS_VALUE) { + end_time = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den); + duration = end_time - st->start_time; + if (duration > 0) { + if (st->duration == AV_NOPTS_VALUE || + st->duration < duration) + st->duration = duration; + } + } + av_free_packet(pkt); + } + + /* estimate total duration */ + end_time = MININT64; + for(i = 0;i < ic->nb_streams; i++) { + st = ic->streams[i]; + if (st->duration != AV_NOPTS_VALUE) { + end_time1 = st->start_time + st->duration; + if (end_time1 > end_time) + end_time = end_time1; + } + } + + /* update start_time (new stream may have been created, so we do + it at the end */ + if (ic->start_time != AV_NOPTS_VALUE) { + for(i = 0; i < ic->nb_streams; i++) { + st = ic->streams[i]; + if (st->start_time == AV_NOPTS_VALUE) + st->start_time = ic->start_time; + } + } + + if (end_time != MININT64) { + /* put dummy values for duration if needed */ + for(i = 0;i < ic->nb_streams; i++) { + st = ic->streams[i]; + if (st->duration == AV_NOPTS_VALUE && + st->start_time != AV_NOPTS_VALUE) + st->duration = end_time - st->start_time; + } + ic->duration = end_time - ic->start_time; + } + + url_fseek(&ic->pb, 0, SEEK_SET); +} +#endif +static void av_estimate_timings(AVFormatContext *ic) +{ + URLContext *h; + int64_t file_size; + + /* get the file size, if possible */ + if (ic->iformat->flags & AVFMT_NOFILE) { + file_size = 0; + } else { + h = url_fileno(&ic->pb); + file_size = url_filesize(h); + if (file_size < 0) + file_size = 0; + } + ic->file_size = file_size; + +#if 0 + if (ic->iformat == &mpegps_demux) { + /* get accurate estimate from the PTSes */ + av_estimate_timings_from_pts(ic); + } else +#endif + if (av_has_timings(ic)) { + /* at least one components has timings - we use them for all + the components */ + fill_all_stream_timings(ic); + } else { + /* less precise: use bit rate info */ + av_estimate_timings_from_bit_rate(ic); + } + av_update_stream_timings(ic); + +#if 0 + { + int i; + AVStream *st; + for(i = 0;i < ic->nb_streams; i++) { + st = ic->streams[i]; + printf("%d: start_time: %0.3f duration: %0.3f\n", + i, (double)st->start_time / AV_TIME_BASE, + (double)st->duration / AV_TIME_BASE); + } + printf("stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n", + (double)ic->start_time / AV_TIME_BASE, + (double)ic->duration / AV_TIME_BASE, + ic->bit_rate / 1000); + } +#endif +} + + +static int has_codec_parameters(AVCodecContext *enc) +{ + int val; + switch(enc->codec_type) { + case CODEC_TYPE_AUDIO: + val = enc->sample_rate; + break; + default: + val = 1; + break; + } + return (val != 0); +} + +#if 0 /* Dead code; compiler assures me it isn't used anywhere */ +static int try_decode_frame(AVStream *st, const uint8_t *data, int size) +{ + int16_t *samples; + AVCodec *codec; + int got_picture, ret; + AVFrame picture; + + codec = avcodec_find_decoder(st->codec.codec_id); + if (!codec) + return -1; + ret = avcodec_open(&st->codec, codec); + if (ret < 0) + return ret; + switch(st->codec.codec_type) { + case CODEC_TYPE_AUDIO: + samples = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); + if (!samples) + goto fail; + + ret = avcodec_decode_audio(&st->codec, samples, + &got_picture, (uint8_t *)data, size); + free(samples); + + break; + default: + break; + } + fail: + avcodec_close(&st->codec); + return ret; +} +#endif + +/* absolute maximum size we read until we abort */ +#define MAX_READ_SIZE 5000000 + +/* maximum duration until we stop analysing the stream */ +#define MAX_STREAM_DURATION ((int)(AV_TIME_BASE * 1.0)) + +/** + * Read the beginning of a media file to get stream information. This + * is useful for file formats with no headers such as MPEG. This + * function also compute the real frame rate in case of mpeg2 repeat + * frame mode. + * + * @param ic media file handle + * @return >=0 if OK. AVERROR_xxx if error. + */ +int av_find_stream_info(AVFormatContext *ic) +{ + int i, count, ret, read_size; + AVStream *st; + AVPacket pkt1, *pkt; + AVPacketList *pktl=NULL, **ppktl; + + count = 0; + read_size = 0; + ppktl = &ic->packet_buffer; + for(;;) { + /* check if one codec still needs to be handled */ + for(i=0;i<ic->nb_streams;i++) { + st = ic->streams[i]; + if (!has_codec_parameters(&st->codec)) + break; + } + if (i == ic->nb_streams) { + /* NOTE: if the format has no header, then we need to read + some packets to get most of the streams, so we cannot + stop here */ + if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) { + /* if we found the info for all the codecs, we can stop */ + ret = count; + break; + } + } else { + /* we did not get all the codec info, but we read too much data */ + if (read_size >= MAX_READ_SIZE) { + ret = count; + break; + } + } + + /* NOTE: a new stream can be added there if no header in file + (AVFMTCTX_NOHEADER) */ + ret = av_read_frame_internal(ic, &pkt1); + if (ret < 0) { + /* EOF or error */ + ret = -1; /* we could not have all the codec parameters before EOF */ + if ((ic->ctx_flags & AVFMTCTX_NOHEADER) && + i == ic->nb_streams) + ret = 0; + break; + } + + pktl = av_mallocz(sizeof(AVPacketList)); + if (!pktl) { + ret = AVERROR_NOMEM; + break; + } + + /* add the packet in the buffered packet list */ + *ppktl = pktl; + ppktl = &pktl->next; + + pkt = &pktl->pkt; + *pkt = pkt1; + + /* duplicate the packet */ + if (av_dup_packet(pkt) < 0) { + ret = AVERROR_NOMEM; + break; + } + + read_size += pkt->size; + + st = ic->streams[pkt->stream_index]; + st->codec_info_duration += pkt->duration; + if (pkt->duration != 0) + st->codec_info_nb_frames++; + + /* if still no information, we try to open the codec and to + decompress the frame. We try to avoid that in most cases as + it takes longer and uses more memory. For MPEG4, we need to + decompress for Quicktime. */ + if (st->codec_info_duration >= MAX_STREAM_DURATION) { + break; + } + count++; + } + + /* set real frame rate info */ + for(i=0;i<ic->nb_streams;i++) { + st = ic->streams[i]; + } + + av_estimate_timings(ic); + return ret; +} +//McMCC +/*******************************************************/ + +/** + * start playing a network based stream (e.g. RTSP stream) at the + * current position + */ +int av_read_play(AVFormatContext *s) +{ + if (!s->iformat->read_play) + return AVERROR_NOTSUPP; + return s->iformat->read_play(s); +} + +/** + * pause a network based stream (e.g. RTSP stream). Use av_read_play() + * to resume it. + */ +int av_read_pause(AVFormatContext *s) +{ + if (!s->iformat->read_pause) + return AVERROR_NOTSUPP; + return s->iformat->read_pause(s); +} + +/** + * Close a media file (but not its codecs) + * + * @param s media file handle + */ +void av_close_input_file(AVFormatContext *s) +{ + int i, must_open_file; + AVStream *st; + + /* free previous packet */ + if (s->cur_st && s->cur_st->parser) + av_free_packet(&s->cur_pkt); + + if (s->iformat->read_close) + s->iformat->read_close(s); + for(i=0;i<s->nb_streams;i++) { + /* free all data in a stream component */ + st = s->streams[i]; + if (st->parser) { + av_parser_close(st->parser); + } + free(st->index_entries); + free(st); + } + flush_packet_queue(s); + must_open_file = 1; + if (s->iformat->flags & AVFMT_NOFILE) { + must_open_file = 0; + } + if (must_open_file) { + url_fclose(&s->pb); + } + av_freep(&s->priv_data); + free(s); +} + +/** + * Add a new stream to a media file. Can only be called in the + * read_header function. If the flag AVFMTCTX_NOHEADER is in the + * format context, then new streams can be added in read_packet too. + * + * + * @param s media file handle + * @param id file format dependent stream id + */ +AVStream *av_new_stream(AVFormatContext *s, int id) +{ + AVStream *st; + + if (s->nb_streams >= MAX_STREAMS) + return NULL; + + st = av_mallocz(sizeof(AVStream)); + if (!st) + return NULL; + avcodec_get_context_defaults(&st->codec); + if (s->iformat) { + /* no default bitrate if decoding */ + st->codec.bit_rate = 0; + } + st->index = s->nb_streams; + st->id = id; + st->start_time = AV_NOPTS_VALUE; + st->duration = AV_NOPTS_VALUE; + s->streams[s->nb_streams++] = st; + return st; +} + +/************************************************************/ +/* output media file */ + +int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) +{ + int ret; + + if (s->oformat->priv_data_size > 0) { + s->priv_data = av_mallocz(s->oformat->priv_data_size); + if (!s->priv_data) + return AVERROR_NOMEM; + } else + s->priv_data = NULL; + + if (s->oformat->set_parameters) { + ret = s->oformat->set_parameters(s, ap); + if (ret < 0) + return ret; + } + return 0; +} + +/** + * allocate the stream private data and write the stream header to an + * output media file + * + * @param s media file handle + * @return 0 if OK. AVERROR_xxx if error. + */ +int av_write_header(AVFormatContext *s) +{ + int ret, i; + AVStream *st; + + /* default pts settings is MPEG like */ + av_set_pts_info(s, 33, 1, 90000); + ret = s->oformat->write_header(s); + if (ret < 0) + return ret; + + /* init PTS generation */ + for(i=0;i<s->nb_streams;i++) { + st = s->streams[i]; + + switch (st->codec.codec_type) { + case CODEC_TYPE_AUDIO: + av_frac_init(&st->pts, 0, 0, + (int64_t)s->pts_num * st->codec.sample_rate); + break; + default: + break; + } + } + return 0; +} + +/** + * Write a packet to an output media file. The packet shall contain + * one audio or video frame. + * + * @param s media file handle + * @param stream_index stream index + * @param buf buffer containing the frame data + * @param size size of buffer + * @return < 0 if error, = 0 if OK, 1 if end of stream wanted. + */ +int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, + int size) +{ + AVStream *st; + int64_t pts_mask; + int ret, frame_size; + + st = s->streams[stream_index]; + pts_mask = (1LL << s->pts_wrap_bits) - 1; + ret = s->oformat->write_packet(s, stream_index, buf, size, + st->pts.val & pts_mask); + if (ret < 0) + return ret; + + /* update pts */ + switch (st->codec.codec_type) { + case CODEC_TYPE_AUDIO: + frame_size = get_audio_frame_size(&st->codec, size); + if (frame_size >= 0) { + av_frac_add(&st->pts, + (int64_t)s->pts_den * frame_size); + } + break; + default: + break; + } + return ret; +} + +/** + * write the stream trailer to an output media file and and free the + * file private data. + * + * @param s media file handle + * @return 0 if OK. AVERROR_xxx if error. */ +int av_write_trailer(AVFormatContext *s) +{ + int ret; + ret = s->oformat->write_trailer(s); + av_freep(&s->priv_data); + return ret; +} + +/* "user interface" functions */ + +void dump_format(AVFormatContext *ic, + int index, + const char *url, + int is_output) +{ + int i, flags; + char buf[256]; + + fprintf(stderr, "%s #%d, %s, %s '%s':\n", + is_output ? "Output" : "Input", + index, + is_output ? ic->oformat->name : ic->iformat->name, + is_output ? "to" : "from", url); + if (!is_output) { + fprintf(stderr, " Duration: "); + if (ic->duration != (int64_t)AV_NOPTS_VALUE) { + int hours, mins, secs, us; + secs = ic->duration / AV_TIME_BASE; + us = ic->duration % AV_TIME_BASE; + mins = secs / 60; + secs %= 60; + hours = mins / 60; + mins %= 60; + fprintf(stderr, "%02d:%02d:%02d.%01d", hours, mins, secs, + (10 * us) / AV_TIME_BASE); + } else { + fprintf(stderr, "N/A"); + } + fprintf(stderr, ", bitrate: "); + if (ic->bit_rate) { + fprintf(stderr,"%d kb/s", ic->bit_rate / 1000); + } else { + fprintf(stderr, "N/A"); + } + fprintf(stderr, "\n"); + } + for(i=0;i<ic->nb_streams;i++) { + AVStream *st = ic->streams[i]; + avcodec_string(buf, sizeof(buf), &st->codec, is_output); + fprintf(stderr, " Stream #%d.%d", index, i); + /* the pid is an important information, so we display it */ + /* XXX: add a generic system */ + if (is_output) + flags = ic->oformat->flags; + else + flags = ic->iformat->flags; + if (flags & AVFMT_SHOW_IDS) { + fprintf(stderr, "[0x%x]", st->id); + } + fprintf(stderr, ": %s\n", buf); + } +} + +typedef struct { + const char *abv; + int width, height; + int frame_rate, frame_rate_base; +} AbvEntry; + +static AbvEntry frame_abvs[] = { + { "ntsc", 720, 480, 30000, 1001 }, + { "pal", 720, 576, 25, 1 }, + { "qntsc", 352, 240, 30000, 1001 }, /* VCD compliant ntsc */ + { "qpal", 352, 288, 25, 1 }, /* VCD compliant pal */ + { "sntsc", 640, 480, 30000, 1001 }, /* square pixel ntsc */ + { "spal", 768, 576, 25, 1 }, /* square pixel pal */ + { "film", 352, 240, 24, 1 }, + { "ntsc-film", 352, 240, 24000, 1001 }, + { "sqcif", 128, 96, 0, 0 }, + { "qcif", 176, 144, 0, 0 }, + { "cif", 352, 288, 0, 0 }, + { "4cif", 704, 576, 0, 0 }, +}; + +int parse_image_size(int *width_ptr, int *height_ptr, const char *str) +{ + int i; + int n = sizeof(frame_abvs) / sizeof(AbvEntry); + const char *p; + int frame_width = 0, frame_height = 0; + + for(i=0;i<n;i++) { + if (!strcmp(frame_abvs[i].abv, str)) { + frame_width = frame_abvs[i].width; + frame_height = frame_abvs[i].height; + break; + } + } + if (i == n) { + p = str; + frame_width = strtol(p, (char **)&p, 10); + if (*p) + p++; + frame_height = strtol(p, (char **)&p, 10); + } + if (frame_width <= 0 || frame_height <= 0) + return -1; + *width_ptr = frame_width; + *height_ptr = frame_height; + return 0; +} + +int parse_frame_rate(int *frame_rate, int *frame_rate_base, const char *arg) +{ + size_t i; + char* cp; + + /* First, we check our abbreviation table */ + for (i = 0; i < sizeof(frame_abvs)/sizeof(*frame_abvs); ++i) + if (!strcmp(frame_abvs[i].abv, arg)) { + *frame_rate = frame_abvs[i].frame_rate; + *frame_rate_base = frame_abvs[i].frame_rate_base; + return 0; + } + + /* Then, we try to parse it as fraction */ + cp = strchr(arg, '/'); + if (cp) { + char* cpp; + *frame_rate = strtol(arg, &cpp, 10); + if (cpp != arg || cpp == cp) + *frame_rate_base = strtol(cp+1, &cpp, 10); + else + *frame_rate = 0; + } + else { + /* Finally we give up and parse it as double */ + *frame_rate_base = DEFAULT_FRAME_RATE_BASE; + *frame_rate = (int)(strtod(arg, 0) * (*frame_rate_base) + 0.5); + } + if (!*frame_rate || !*frame_rate_base) + return -1; + else + return 0; +} + +/* Syntax: + * - If not a duration: + * [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]} + * Time is localtime unless Z is suffixed to the end. In this case GMT + * Return the date in micro seconds since 1970 + * - If duration: + * HH[:MM[:SS[.m...]]] + * S+[.m...] + */ +int64_t parse_date(const char *datestr, int duration) +{ + const char *p; + int64_t t; + struct tm dt; + size_t i; + static const char *date_fmt[] = { + "%Y-%m-%d", + "%Y%m%d", + }; + static const char *time_fmt[] = { + "%H:%M:%S", + "%H%M%S", + }; + const char *q; + int is_utc, len; + char lastch; + time_t now = time(0); + + len = strlen(datestr); + if (len > 0) + lastch = datestr[len - 1]; + else + lastch = '\0'; + is_utc = (lastch == 'z' || lastch == 'Z'); + + memset(&dt, 0, sizeof(dt)); + + p = datestr; + q = NULL; + if (!duration) { + for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) { + q = small_strptime(p, date_fmt[i], &dt); + if (q) { + break; + } + } + + if (!q) { + if (is_utc) { + dt = *gmtime(&now); + } else { + dt = *localtime(&now); + } + dt.tm_hour = dt.tm_min = dt.tm_sec = 0; + } else { + p = q; + } + + if (*p == 'T' || *p == 't' || *p == ' ') + p++; + + for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) { + q = small_strptime(p, time_fmt[i], &dt); + if (q) { + break; + } + } + } else { + q = small_strptime(p, time_fmt[0], &dt); + if (!q) { + dt.tm_sec = strtol(p, (char **)&q, 10); + dt.tm_min = 0; + dt.tm_hour = 0; + } + } + + /* Now we have all the fields that we can get */ + if (!q) { + if (duration) + return 0; + else + return now * int64_t_C(1000000); + } + + if (duration) { + t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec; + } else { + dt.tm_isdst = -1; /* unknown */ + if (is_utc) { + t = mktimegm(&dt); + } else { + t = mktime(&dt); + } + } + + t *= 1000000; + + if (*q == '.') { + int val, n; + q++; + for (val = 0, n = 100000; n >= 1; n /= 10, q++) { + if (!isdigit(*q)) + break; + val += n * (*q - '0'); + } + t += val; + } + return t; +} + +/* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return + 1 if found */ +int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info) +{ + const char *p; + char tag[128], *q; + + p = info; + if (*p == '?') + p++; + for(;;) { + q = tag; + while (*p != '\0' && *p != '=' && *p != '&') { + if ((size_t)(q - tag) < sizeof(tag) - 1) + *q++ = *p; + p++; + } + *q = '\0'; + q = arg; + if (*p == '=') { + p++; + while (*p != '&' && *p != '\0') { + if ((q - arg) < arg_size - 1) { + if (*p == '+') + *q++ = ' '; + else + *q++ = *p; + } + p++; + } + *q = '\0'; + } + if (!strcmp(tag, tag1)) + return 1; + if (*p != '&') + break; + p++; + } + return 0; +} + +/* Return in 'buf' the path with '%d' replaced by number. Also handles + the '%0nd' format where 'n' is the total number of digits and + '%%'. Return 0 if OK, and -1 if format error */ +int get_frame_filename(char *buf, int buf_size, + const char *path, int number) +{ + const char *p; + char *q, buf1[20], c; + int nd, len, percentd_found; + + q = buf; + p = path; + percentd_found = 0; + for(;;) { + c = *p++; + if (c == '\0') + break; + if (c == '%') { + do { + nd = 0; + while (isdigit(*p)) { + nd = nd * 10 + *p++ - '0'; + } + c = *p++; + } while (isdigit(c)); + + switch(c) { + case '%': + goto addchar; + case 'd': + if (percentd_found) + goto fail; + percentd_found = 1; + snprintf(buf1, sizeof(buf1), "%0*d", nd, number); + len = strlen(buf1); + if ((q - buf + len) > buf_size - 1) + goto fail; + memcpy(q, buf1, len); + q += len; + break; + default: + goto fail; + } + } else { + addchar: + if ((q - buf) < buf_size - 1) + *q++ = c; + } + } + if (!percentd_found) + goto fail; + *q = '\0'; + return 0; + fail: + *q = '\0'; + return -1; +} + +/** + * Print nice hexa dump of a buffer + * @param f stream for output + * @param buf buffer + * @param size buffer size + */ +void av_hex_dump(FILE *f, uint8_t *buf, int size) +{ + int len, i, j, c; + + for(i=0;i<size;i+=16) { + len = size - i; + if (len > 16) + len = 16; + fprintf(f, "%08x ", i); + for(j=0;j<16;j++) { + if (j < len) + fprintf(f, " %02x", buf[i+j]); + else + fprintf(f, " "); + } + fprintf(f, " "); + for(j=0;j<len;j++) { + c = buf[i+j]; + if (c < ' ' || c > '~') + c = '.'; + fprintf(f, "%c", c); + } + fprintf(f, "\n"); + } +} + +/** + * Print on 'f' a nice dump of a packet + * @param f stream for output + * @param pkt packet to dump + * @param dump_payload true if the payload must be displayed too + */ +void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload) +{ + fprintf(f, "stream #%d:\n", pkt->stream_index); + fprintf(f, " keyframe=%d\n", ((pkt->flags & PKT_FLAG_KEY) != 0)); + fprintf(f, " duration=%0.3f\n", (double)pkt->duration / AV_TIME_BASE); + /* DTS is _always_ valid after av_read_frame() */ + fprintf(f, " dts="); + if (pkt->dts == (int64_t)AV_NOPTS_VALUE) + fprintf(f, "N/A"); + else + fprintf(f, "%0.3f", (double)pkt->dts / AV_TIME_BASE); + /* PTS may be not known if B frames are present */ + fprintf(f, " pts="); + if (pkt->pts == (int64_t)AV_NOPTS_VALUE) + fprintf(f, "N/A"); + else + fprintf(f, "%0.3f", (double)pkt->pts / AV_TIME_BASE); + fprintf(f, "\n"); + fprintf(f, " size=%d\n", pkt->size); + if (dump_payload) + av_hex_dump(f, pkt->data, pkt->size); +} + +void url_split(char *proto, int proto_size, + char *hostname, int hostname_size, + int *port_ptr, + char *path, int path_size, + const char *url) +{ + const char *p; + char *q; + int port; + + port = -1; + + p = url; + q = proto; + while (*p != ':' && *p != '\0') { + if ((q - proto) < proto_size - 1) + *q++ = *p; + p++; + } + if (proto_size > 0) + *q = '\0'; + if (*p == '\0') { + if (proto_size > 0) + proto[0] = '\0'; + if (hostname_size > 0) + hostname[0] = '\0'; + p = url; + } else { + p++; + if (*p == '/') + p++; + if (*p == '/') + p++; + q = hostname; + while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') { + if ((q - hostname) < hostname_size - 1) + *q++ = *p; + p++; + } + if (hostname_size > 0) + *q = '\0'; + if (*p == ':') { + p++; + port = strtoul(p, (char **)&p, 10); + } + } + if (port_ptr) + *port_ptr = port; + pstrcpy(path, path_size, p); +} + +/** + * Set the pts for a given stream + * @param s stream + * @param pts_wrap_bits number of bits effectively used by the pts + * (used for wrap control, 33 is the value for MPEG) + * @param pts_num numerator to convert to seconds (MPEG: 1) + * @param pts_den denominator to convert to seconds (MPEG: 90000) + */ +void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits, + int pts_num, int pts_den) +{ + s->pts_wrap_bits = pts_wrap_bits; + s->pts_num = pts_num; + s->pts_den = pts_den; +} + +/* fraction handling */ + +/** + * f = val + (num / den) + 0.5. 'num' is normalized so that it is such + * as 0 <= num < den. + * + * @param f fractional number + * @param val integer value + * @param num must be >= 0 + * @param den must be >= 1 + */ +void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den) +{ + num += (den >> 1); + if (num >= den) { + val += num / den; + num = num % den; + } + f->val = val; + f->num = num; + f->den = den; +} + +/* set f to (val + 0.5) */ +void av_frac_set(AVFrac *f, int64_t val) +{ + f->val = val; + f->num = f->den >> 1; +} + +/** + * Fractionnal addition to f: f = f + (incr / f->den) + * + * @param f fractional number + * @param incr increment, can be positive or negative + */ +void av_frac_add(AVFrac *f, int64_t incr) +{ + int64_t num, den; + + num = f->num + incr; + den = f->den; + if (num < 0) { + f->val += num / den; + num = num % den; + if (num < 0) { + num += den; + f->val--; + } + } else if (num >= den) { + f->val += num / den; + num = num % den; + } + f->num = num; +} + +/** + * register a new image format + * @param img_fmt Image format descriptor + */ +void av_register_image_format(AVImageFormat *img_fmt) +{ + AVImageFormat **p; + + p = &first_image_format; + while (*p != NULL) p = &(*p)->next; + *p = img_fmt; + img_fmt->next = NULL; +} + +/* guess image format */ +AVImageFormat *av_probe_image_format(AVProbeData *pd) +{ + AVImageFormat *fmt1, *fmt; + int score, score_max; + + fmt = NULL; + score_max = 0; + for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) { + if (fmt1->img_probe) { + score = fmt1->img_probe(pd); + if (score > score_max) { + score_max = score; + fmt = fmt1; + } + } + } + return fmt; +} + +AVImageFormat *guess_image_format(const char *filename) +{ + AVImageFormat *fmt1; + + for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) { + if (fmt1->extensions && match_ext(filename, fmt1->extensions)) + return fmt1; + } + return NULL; +} + +/** + * Read an image from a stream. + * @param gb byte stream containing the image + * @param fmt image format, NULL if probing is required + */ +int av_read_image(ByteIOContext *pb, const char *filename, + AVImageFormat *fmt, + int (*alloc_cb)(void *, AVImageInfo *info), void *opaque) +{ + unsigned char buf[PROBE_BUF_SIZE]; + AVProbeData probe_data, *pd = &probe_data; + offset_t pos; + int ret; + + if (!fmt) { + pd->filename = filename; + pd->buf = buf; + pos = url_ftell(pb); + pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE); + url_fseek(pb, pos, SEEK_SET); + fmt = av_probe_image_format(pd); + } + if (!fmt) + return AVERROR_NOFMT; + ret = fmt->img_read(pb, alloc_cb, opaque); + return ret; +} + +/** + * Write an image to a stream. + * @param pb byte stream for the image output + * @param fmt image format + * @param img image data and informations + */ +int av_write_image(ByteIOContext *pb, AVImageFormat *fmt, AVImageInfo *img) +{ + return fmt->img_write(pb, img); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/golomb.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,155 @@ +/* + * exp golomb vlc stuff + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file golomb.c + * @brief + * exp golomb vlc stuff + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#include "common.h" + +const uint8_t ff_golomb_vlc_len[512]={ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, +7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, +5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +}; + +const uint8_t ff_ue_golomb_vlc_code[512]={ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +const int8_t ff_se_golomb_vlc_code[512]={ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, -8, 9, -9, 10,-10, 11,-11, 12,-12, 13,-13, 14,-14, 15,-15, + 4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, -5, -5, -5, -5, 6, 6, 6, 6, -6, -6, -6, -6, 7, 7, 7, 7, -7, -7, -7, -7, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + + +const uint8_t ff_ue_golomb_len[256]={ + 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, +11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13, +13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, +13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17, +}; + +const uint8_t ff_interleaved_golomb_vlc_len[256]={ +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +}; + +const uint8_t ff_interleaved_ue_golomb_vlc_code[256]={ + 15,16,7, 7, 17,18,8, 8, 3, 3, 3, 3, 3, 3, 3, 3, + 19,20,9, 9, 21,22,10,10,4, 4, 4, 4, 4, 4, 4, 4, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 23,24,11,11,25,26,12,12,5, 5, 5, 5, 5, 5, 5, 5, + 27,28,13,13,29,30,14,14,6, 6, 6, 6, 6, 6, 6, 6, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +const int8_t ff_interleaved_se_golomb_vlc_code[256]={ + 8, -8, 4, 4, 9, -9, -4, -4, 2, 2, 2, 2, 2, 2, 2, 2, + 10,-10, 5, 5, 11,-11, -5, -5, -2, -2, -2, -2, -2, -2, -2, -2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 12,-12, 6, 6, 13,-13, -6, -6, 3, 3, 3, 3, 3, 3, 3, 3, + 14,-14, 7, 7, 15,-15, -7, -7, -3, -3, -3, -3, -3, -3, -3, -3, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/golomb.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,470 @@ +/* + * exp golomb vlc stuff + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2004 Alex Beregszaszi + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file golomb.h + * @brief + * exp golomb vlc stuff + * @author Michael Niedermayer <michaelni@gmx.at> and Alex Beregszaszi + */ + +#define INVALID_VLC 0x80000000 + +extern const uint8_t ff_golomb_vlc_len[512]; +extern const uint8_t ff_ue_golomb_vlc_code[512]; +extern const int8_t ff_se_golomb_vlc_code[512]; +extern const uint8_t ff_ue_golomb_len[256]; + +extern const uint8_t ff_interleaved_golomb_vlc_len[256]; +extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256]; +extern const int8_t ff_interleaved_se_golomb_vlc_code[256]; + + + /** + * read unsigned exp golomb code. + */ +static inline int get_ue_golomb(GetBitContext *gb){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + if(buf >= (1<<27)){ + buf >>= 32 - 9; + LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_ue_golomb_vlc_code[buf]; + }else{ + log= 2*av_log2(buf) - 31; + buf>>= log; + buf--; + LAST_SKIP_BITS(re, gb, 32 - log); + CLOSE_READER(re, gb); + + return buf; + } +} + +static inline int svq3_get_ue_golomb(GetBitContext *gb){ + uint32_t buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + if(buf&0xAA800000){ + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_interleaved_ue_golomb_vlc_code[buf]; + }else{ + LAST_SKIP_BITS(re, gb, 8); + UPDATE_CACHE(re, gb); + buf |= 1 | (GET_CACHE(re, gb) >> 8); + + if((buf & 0xAAAAAAAA) == 0) + return INVALID_VLC; + + for(log=31; (buf & 0x80000000) == 0; log--){ + buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + } + + LAST_SKIP_BITS(re, gb, 63 - 2*log - 8); + CLOSE_READER(re, gb); + + return ((buf << log) >> log) - 1; + } +} + +/** + * read unsigned truncated exp golomb code. + */ +static inline int get_te0_golomb(GetBitContext *gb, int range){ + assert(range >= 1); + + if(range==1) return 0; + else if(range==2) return get_bits1(gb)^1; + else return get_ue_golomb(gb); +} + +/** + * read unsigned truncated exp golomb code. + */ +static inline int get_te_golomb(GetBitContext *gb, int range){ + assert(range >= 1); + + if(range==2) return get_bits1(gb)^1; + else return get_ue_golomb(gb); +} + + +/** + * read signed exp golomb code. + */ +static inline int get_se_golomb(GetBitContext *gb){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + if(buf >= (1<<27)){ + buf >>= 32 - 9; + LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_se_golomb_vlc_code[buf]; + }else{ + log= 2*av_log2(buf) - 31; + buf>>= log; + + LAST_SKIP_BITS(re, gb, 32 - log); + CLOSE_READER(re, gb); + + if(buf&1) buf= -(buf>>1); + else buf= (buf>>1); + + return buf; + } +} + +static inline int svq3_get_se_golomb(GetBitContext *gb){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + if(buf&0xAA800000){ + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_interleaved_se_golomb_vlc_code[buf]; + }else{ + LAST_SKIP_BITS(re, gb, 8); + UPDATE_CACHE(re, gb); + buf |= 1 | (GET_CACHE(re, gb) >> 8); + + if((buf & 0xAAAAAAAA) == 0) + return INVALID_VLC; + + for(log=31; (buf & 0x80000000) == 0; log--){ + buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + } + + LAST_SKIP_BITS(re, gb, 63 - 2*log - 8); + CLOSE_READER(re, gb); + + return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1; + } +} + +/** + * read unsigned golomb rice code (ffv1). + */ +static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + log= av_log2(buf); + + if(log > 31-limit){ + buf >>= log - k; + buf += (30-log)<<k; + LAST_SKIP_BITS(re, gb, 32 + k - log); + CLOSE_READER(re, gb); + + return buf; + }else{ + buf >>= 32 - limit - esc_len; + LAST_SKIP_BITS(re, gb, esc_len + limit); + CLOSE_READER(re, gb); + + return buf + limit - 1; + } +} + +/** + * read unsigned golomb rice code (jpegls). + */ +static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int esc_len){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + log= av_log2(buf); + + if(log > 31-11){ + buf >>= log - k; + buf += (30-log)<<k; + LAST_SKIP_BITS(re, gb, 32 + k - log); + CLOSE_READER(re, gb); + + return buf; + }else{ + int i; + for(i=0; SHOW_UBITS(re, gb, 1) == 0; i++){ + LAST_SKIP_BITS(re, gb, 1); + UPDATE_CACHE(re, gb); + } + SKIP_BITS(re, gb, 1); + + if(i < limit - 1){ + if(k){ + buf = SHOW_UBITS(re, gb, k); + LAST_SKIP_BITS(re, gb, k); + }else{ + buf=0; + } + + CLOSE_READER(re, gb); + return buf + (i<<k); + }else if(i == limit - 1){ + buf = SHOW_UBITS(re, gb, esc_len); + LAST_SKIP_BITS(re, gb, esc_len); + CLOSE_READER(re, gb); + + return buf + 1; + }else + return -1; + } +} + +/** + * read signed golomb rice code (ffv1). + */ +static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, int esc_len){ + int v= get_ur_golomb(gb, k, limit, esc_len); + + v++; + if (v&1) return v>>1; + else return -(v>>1); + +// return (v>>1) ^ -(v&1); +} + +/** + * read signed golomb rice code (flac). + */ +static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, int esc_len){ + int v= get_ur_golomb_jpegls(gb, k, limit, esc_len); + return (v>>1) ^ -(v&1); +} + +/** + * read unsigned golomb rice code (shorten). + */ +static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k){ + return get_ur_golomb_jpegls(gb, k, INT_MAX, 0); +} + +/** + * read signed golomb rice code (shorten). + */ +static inline int get_sr_golomb_shorten(GetBitContext* gb, int k) +{ + int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0); + if (uvar & 1) + return ~(uvar >> 1); + else + return uvar >> 1; +} + + + +#ifdef TRACE + +static inline int get_ue(GetBitContext *s, char *file, const char *func, int line){ + int show= show_bits(s, 24); + int pos= get_bits_count(s); + int i= get_ue_golomb(s); + int len= get_bits_count(s) - pos; + int bits= show>>(24-len); + + print_bin(bits, len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + + return i; +} + +static inline int get_se(GetBitContext *s, char *file, const char *func, int line){ + int show= show_bits(s, 24); + int pos= get_bits_count(s); + int i= get_se_golomb(s); + int len= get_bits_count(s) - pos; + int bits= show>>(24-len); + + print_bin(bits, len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + + return i; +} + +static inline int get_te(GetBitContext *s, int r, char *file, const char *func, int line){ + int show= show_bits(s, 24); + int pos= get_bits_count(s); + int i= get_te0_golomb(s, r); + int len= get_bits_count(s) - pos; + int bits= show>>(24-len); + + print_bin(bits, len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + + return i; +} + +#define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) + +#endif + +/** + * write unsigned exp golomb code. + */ +static inline void set_ue_golomb(PutBitContext *pb, int i){ + int e; + + assert(i>=0); + +#if 0 + if(i=0){ + put_bits(pb, 1, 1); + return; + } +#endif + if(i<256) + put_bits(pb, ff_ue_golomb_len[i], i+1); + else{ + e= av_log2(i+1); + + put_bits(pb, 2*e+1, i+1); + } +} + +/** + * write truncated unsigned exp golomb code. + */ +static inline void set_te_golomb(PutBitContext *pb, int i, int range){ + assert(range >= 1); + assert(i<=range); + + if(range==2) put_bits(pb, 1, i^1); + else set_ue_golomb(pb, i); +} + +/** + * write signed exp golomb code. 16 bits at most. + */ +static inline void set_se_golomb(PutBitContext *pb, int i){ +// if (i>32767 || i<-32767) +// av_log(NULL,AV_LOG_ERROR,"value out of range %d\n", i); +#if 0 + if(i<=0) i= -2*i; + else i= 2*i-1; +#elif 1 + i= 2*i-1; + if(i<0) i^= -1; //FIXME check if gcc does the right thing +#else + i= 2*i-1; + i^= (i>>31); +#endif + set_ue_golomb(pb, i); +} + +/** + * write unsigned golomb rice code (ffv1). + */ +static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){ + int e; + + assert(i>=0); + + e= i>>k; + if(e<limit){ + put_bits(pb, e + k + 1, (1<<k) + (i&((1<<k)-1))); + }else{ + put_bits(pb, limit + esc_len, i - limit + 1); + } +} + +/** + * write unsigned golomb rice code (jpegls). + */ +static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, int limit, int esc_len){ + int e; + + assert(i>=0); + + e= (i>>k) + 1; + if(e<limit){ + put_bits(pb, e, 1); + if(k) + put_bits(pb, k, i&((1<<k)-1)); + }else{ + put_bits(pb, limit , 1); + put_bits(pb, esc_len, i - 1); + } +} + +/** + * write signed golomb rice code (ffv1). + */ +static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){ + int v; + + v = -2*i-1; + v ^= (v>>31); + + set_ur_golomb(pb, v, k, limit, esc_len); +} + +/** + * write signed golomb rice code (flac). + */ +static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, int limit, int esc_len){ + int v; + + v = -2*i-1; + v ^= (v>>31); + + set_ur_golomb_jpegls(pb, v, k, limit, esc_len); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/init.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,48 @@ +/* + * Plugin glue for Shorten. + * Copyright (c) 2006 William Pitcock <nenolod -at- nenolod.net>. + * Copyright (c) 2006 Thomas Cort <tcort -at- cs.ubishops.ca>. + * + * Based on Plugins/Input/wma/allcodecs.c, + * Copyright (c) 2002 Fabrice Bellard. + * Copyright (c) 2004 Roman Bogorodskiy. + * + * 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" +#include "avformat.h" + +void avcodec_register_all(void) +{ + static int inited = 0; + + if (inited != 0) + return; + inited = 1; + + register_avcodec(&shorten_decoder); +} + +void av_register_all(void) +{ + avcodec_init(); + avcodec_register_all(); + + /* file protocols */ + register_protocol(&file_protocol); + register_protocol(&pipe_protocol); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/mdct.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,175 @@ +/* + * MDCT/IMDCT transforms + * Copyright (c) 2002 Fabrice Bellard. + * + * 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 "dsputil.h" + +/** + * @file mdct.c + * MDCT/IMDCT transforms. + */ + +/** + * init MDCT or IMDCT computation. + */ +int ff_mdct_init(MDCTContext *s, int nbits, int inverse) +{ + int n, n4, i; + float alpha; + + memset(s, 0, sizeof(*s)); + n = 1 << nbits; + s->nbits = nbits; + s->n = n; + n4 = n >> 2; + s->tcos = malloc(n4 * sizeof(FFTSample)); + if (!s->tcos) + goto fail; + s->tsin = malloc(n4 * sizeof(FFTSample)); + if (!s->tsin) + goto fail; + + for(i=0;i<n4;i++) { + alpha = 2 * M_PI * (i + 1.0 / 8.0) / n; + s->tcos[i] = -cos(alpha); + s->tsin[i] = -sin(alpha); + } + if (fft_inits(&s->fft, s->nbits - 2, inverse) < 0) + goto fail; + return 0; + fail: + av_freep(&s->tcos); + av_freep(&s->tsin); + return -1; +} + +/* complex multiplication: p = a * b */ +#define CMUL(pre, pim, are, aim, bre, bim) \ +{\ + float _are = (are);\ + float _aim = (aim);\ + float _bre = (bre);\ + float _bim = (bim);\ + (pre) = _are * _bre - _aim * _bim;\ + (pim) = _are * _bim + _aim * _bre;\ +} + +/** + * Compute inverse MDCT of size N = 2^nbits + * @param output N samples + * @param input N/2 samples + * @param tmp N/2 samples + */ +void ff_imdct_calc(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp) +{ + int k, n8, n4, n2, n, j; + const uint16_t *revtab = s->fft.revtab; + const FFTSample *tcos = s->tcos; + const FFTSample *tsin = s->tsin; + const FFTSample *in1, *in2; + FFTComplex *z = (FFTComplex *)tmp; + + n = 1 << s->nbits; + n2 = n >> 1; + n4 = n >> 2; + n8 = n >> 3; + + /* pre rotation */ + in1 = input; + in2 = input + n2 - 1; + for(k = 0; k < n4; k++) { + j=revtab[k]; + CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]); + in1 += 2; + in2 -= 2; + } + fft_calc(&s->fft, z); + + /* post rotation + reordering */ + /* XXX: optimize */ + for(k = 0; k < n4; k++) { + CMUL(z[k].re, z[k].im, z[k].re, z[k].im, tcos[k], tsin[k]); + } + for(k = 0; k < n8; k++) { + output[2*k] = -z[n8 + k].im; + output[n2-1-2*k] = z[n8 + k].im; + + output[2*k+1] = z[n8-1-k].re; + output[n2-1-2*k-1] = -z[n8-1-k].re; + + output[n2 + 2*k]=-z[k+n8].re; + output[n-1- 2*k]=-z[k+n8].re; + + output[n2 + 2*k+1]=z[n8-k-1].im; + output[n-2 - 2 * k] = z[n8-k-1].im; + } +} + +/** + * Compute MDCT of size N = 2^nbits + * @param input N samples + * @param out N/2 samples + * @param tmp temporary storage of N/2 samples + */ +void ff_mdct_calc(MDCTContext *s, FFTSample *out, + const FFTSample *input, FFTSample *tmp) +{ + int i, j, n, n8, n4, n2, n3; + FFTSample re, im, re1, im1; + const uint16_t *revtab = s->fft.revtab; + const FFTSample *tcos = s->tcos; + const FFTSample *tsin = s->tsin; + FFTComplex *x = (FFTComplex *)tmp; + + n = 1 << s->nbits; + n2 = n >> 1; + n4 = n >> 2; + n8 = n >> 3; + n3 = 3 * n4; + + /* pre rotation */ + for(i=0;i<n8;i++) { + re = -input[2*i+3*n4] - input[n3-1-2*i]; + im = -input[n4+2*i] + input[n4-1-2*i]; + j = revtab[i]; + CMUL(x[j].re, x[j].im, re, im, -tcos[i], tsin[i]); + + re = input[2*i] - input[n2-1-2*i]; + im = -(input[n2+2*i] + input[n-1-2*i]); + j = revtab[n8 + i]; + CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]); + } + + fft_calc(&s->fft, x); + + /* post rotation */ + for(i=0;i<n4;i++) { + re = x[i].re; + im = x[i].im; + CMUL(re1, im1, re, im, -tsin[i], -tcos[i]); + out[2*i] = im1; + out[n2-1-2*i] = re1; + } +} + +void ff_mdct_end(MDCTContext *s) +{ + av_freep(&s->tcos); + av_freep(&s->tsin); + fft_end(&s->fft); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/os_support.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,44 @@ +/* + * Various utilities for ffmpeg system + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * 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 "avformat.h" + +#include <unistd.h> +#include <fcntl.h> +#include <sys/time.h> +#include <time.h> + +int64_t av_gettime(void) +{ + struct timeval tv; + gettimeofday(&tv,NULL); + return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; +} + +#if !defined(HAVE_LOCALTIME_R) +struct tm *localtime_r(const time_t *t, struct tm *tp) +{ + struct tm *l; + + l = localtime(t); + if (!l) + return 0; + *tp = *l; + return tp; +} +#endif /* !defined(HAVE_LOCALTIME_R) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/os_support.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,33 @@ +#ifndef _OS_SUPPORT_H +#define _OS_SUPPORT_H + +/** + * @file os_support.h + * miscellaneous OS support macros and functions. + * + * - usleep() (Win32, BeOS, OS/2) + * - floatf() (OS/2) + * - strcasecmp() (OS/2) + */ + +#ifdef __MINGW32__ +# undef DATADIR /* clashes with /usr/include/w32api/objidl.h */ +__declspec(dllimport) void __stdcall Sleep(unsigned long dwMilliseconds); +// # include <windows.h> +# define usleep(t) Sleep((t) / 1000) +#endif + +#ifdef __BEOS__ +# ifndef usleep +# include <OS.h> +# define usleep(t) snooze((bigtime_t)(t)) +# endif +#endif + +#if defined(CONFIG_OS2) +#include <stdlib.h> +static inline int usleep(unsigned int t) { return _sleep2(t / 1000); } +static inline int strcasecmp(const char* s1, const char* s2) { return stricmp(s1,s2); } +#endif + +#endif /* _OS_SUPPORT_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/parser.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,135 @@ +/* + * Audio and Video frame extraction + * Copyright (c) 2003 Fabrice Bellard. + * Copyright (c) 2003 Michael Niedermayer. + * + * 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" +#include "utils.h" + +AVCodecParser *av_first_parser = NULL; + +void av_register_codec_parser(AVCodecParser *parser) +{ + parser->next = av_first_parser; + av_first_parser = parser; +} + +AVCodecParserContext *av_parser_init(int codec_id) +{ + AVCodecParserContext *s; + AVCodecParser *parser; + int ret; + + for(parser = av_first_parser; parser != NULL; parser = parser->next) { + if (parser->codec_ids[0] == codec_id || + parser->codec_ids[1] == codec_id || + parser->codec_ids[2] == codec_id) + goto found; + } + return NULL; + found: + s = av_mallocz(sizeof(AVCodecParserContext)); + if (!s) + return NULL; + s->parser = parser; + s->priv_data = av_mallocz(parser->priv_data_size); + if (!s->priv_data) { + free(s); + return NULL; + } + if (parser->parser_init) { + ret = parser->parser_init(s); + if (ret != 0) { + free(s->priv_data); + free(s); + return NULL; + } + } + return s; +} + +/* NOTE: buf_size == 0 is used to signal EOF so that the last frame + can be returned if necessary */ +int av_parser_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts) +{ + int index, i, k; + uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; + + if (buf_size == 0) { + /* padding is always necessary even if EOF, so we add it here */ + memset(dummy_buf, 0, sizeof(dummy_buf)); + buf = dummy_buf; + } else { + /* add a new packet descriptor */ + k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); + s->cur_frame_start_index = k; + s->cur_frame_offset[k] = s->cur_offset; + s->cur_frame_pts[k] = pts; + s->cur_frame_dts[k] = dts; + + /* fill first PTS/DTS */ + if (s->cur_offset == 0) { + s->last_pts = pts; + s->last_dts = dts; + } + } + + /* WARNING: the returned index can be negative */ + index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size); + /* update the file pointer */ + if (*poutbuf_size) { + /* fill the data for the current frame */ + s->frame_offset = s->last_frame_offset; + s->pts = s->last_pts; + s->dts = s->last_dts; + + /* offset of the next frame */ + s->last_frame_offset = s->cur_offset + index; + /* find the packet in which the new frame starts. It + is tricky because of MPEG video start codes + which can begin in one packet and finish in + another packet. In the worst case, an MPEG + video start code could be in 4 different + packets. */ + k = s->cur_frame_start_index; + for(i = 0; i < AV_PARSER_PTS_NB; i++) { + if (s->last_frame_offset >= s->cur_frame_offset[k]) + break; + k = (k - 1) & (AV_PARSER_PTS_NB - 1); + } + s->last_pts = s->cur_frame_pts[k]; + s->last_dts = s->cur_frame_dts[k]; + } + if (index < 0) + index = 0; + s->cur_offset += index; + return index; +} + +void av_parser_close(AVCodecParserContext *s) +{ + if (s->parser->parser_close) + s->parser->parser_close(s); + + free(s->priv_data); + free(s); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/shorten_decoder.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,522 @@ +/* + * Shorten decoder + * Copyright (c) 2005 Jeff Muizelaar + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file shorten.c + * Shorten decoder + * @author Jeff Muizelaar + * + */ + +#define DEBUG +#include <limits.h> +#include "avcodec.h" +#include "common.h" +#include "golomb.h" + +#define MAX_CHANNELS 8 +#define MAX_BLOCKSIZE 65535 + +#define OUT_BUFFER_SIZE 16384 + +#define ULONGSIZE 2 + +#define WAVE_FORMAT_PCM 0x0001 + +#define DEFAULT_BLOCK_SIZE 256 + +#define TYPESIZE 4 +#define CHANSIZE 0 +#define LPCQSIZE 2 +#define ENERGYSIZE 3 +#define BITSHIFTSIZE 2 + +#define TYPE_S16HL 3 +#define TYPE_S16LH 5 + +#define NWRAP 3 +#define NSKIPSIZE 1 + +#define LPCQUANT 5 +#define V2LPCQOFFSET (1 << LPCQUANT) + +#define FNSIZE 2 +#define FN_DIFF0 0 +#define FN_DIFF1 1 +#define FN_DIFF2 2 +#define FN_DIFF3 3 +#define FN_QUIT 4 +#define FN_BLOCKSIZE 5 +#define FN_BITSHIFT 6 +#define FN_QLPC 7 +#define FN_ZERO 8 +#define FN_VERBATIM 9 + +#define VERBATIM_CKSIZE_SIZE 5 +#define VERBATIM_BYTE_SIZE 8 +#define CANONICAL_HEADER_SIZE 44 + +typedef struct ShortenContext { + AVCodecContext *avctx; + GetBitContext gb; + + int min_framesize, max_framesize; + int channels; + + int32_t *decoded[MAX_CHANNELS]; + int32_t *offset[MAX_CHANNELS]; + uint8_t *bitstream; + int bitstream_size; + int bitstream_index; + unsigned int allocated_bitstream_size; + int header_size; + uint8_t header[OUT_BUFFER_SIZE]; + int version; + int cur_chan; + int bitshift; + int nmean; + int internal_ftype; + int nwrap; + int blocksize; + int bitindex; + int32_t lpcqoffset; +} ShortenContext; + +static int shorten_decode_init(AVCodecContext * avctx) +{ + ShortenContext *s = avctx->priv_data; + s->avctx = avctx; + + return 0; +} + +static void allocate_buffers(ShortenContext *s) +{ + int i, chan; + for (chan=0; chan<s->channels; chan++) { + s->offset[chan] = realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean)); + + s->decoded[chan] = realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); + for (i=0; i<s->nwrap; i++) + s->decoded[chan][i] = 0; + s->decoded[chan] += s->nwrap; + + } +} + + +static inline unsigned int get_uint(ShortenContext *s, int k) +{ + if (s->version != 0) + k = get_ur_golomb_shorten(&s->gb, ULONGSIZE); + return get_ur_golomb_shorten(&s->gb, k); +} + + +static void fix_bitshift(ShortenContext *s, int32_t *buffer) +{ + int i; + + if (s->bitshift != 0) + for (i = 0; i < s->blocksize; i++) + buffer[s->nwrap + i] <<= s->bitshift; +} + + +static void init_offset(ShortenContext *s) +{ + int32_t mean = 0; + int chan, i; + int nblock = FFMAX(1, s->nmean); + /* initialise offset */ + switch (s->internal_ftype) + { + case TYPE_S16HL: + case TYPE_S16LH: + mean = 0; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "unknown audio type"); + abort(); + } + + for (chan = 0; chan < s->channels; chan++) + for (i = 0; i < nblock; i++) + s->offset[chan][i] = mean; +} + +static int inline get_le32(GetBitContext *gb) +{ + return bswap_32(get_bits_long(gb, 32)); +} + +static short inline get_le16(GetBitContext *gb) +{ + return bswap_16(get_bits_long(gb, 16)); +} + +static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header_size) +{ + GetBitContext hb; + int len; + int chunk_size; + short wave_format; + + init_get_bits(&hb, header, header_size*8); + if (get_le32(&hb) != MKTAG('R','I','F','F')) { + av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n"); + return -1; + } + + chunk_size = get_le32(&hb); + + if (get_le32(&hb) != MKTAG('W','A','V','E')) { + av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n"); + return -1; + } + + while (get_le32(&hb) != MKTAG('f','m','t',' ')) { + len = get_le32(&hb); + skip_bits(&hb, 8*len); + } + len = get_le32(&hb); + + if (len < 16) { + av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n"); + return -1; + } + + wave_format = get_le16(&hb); + + switch (wave_format) { + case WAVE_FORMAT_PCM: + break; + default: + av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n"); + return -1; + } + + avctx->channels = get_le16(&hb); + avctx->sample_rate = get_le32(&hb); + avctx->bit_rate = get_le32(&hb) * 8; + avctx->block_align = get_le16(&hb); + avctx->bits_per_sample = get_le16(&hb); + + if (avctx->bits_per_sample != 16) { + av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n"); + return -1; + } + + len -= 16; + if (len > 0) + av_log(avctx, AV_LOG_INFO, "%d header bytes unparsed\n", len); + + return 0; +} + +static int16_t * interleave_buffer(int16_t *samples, int nchan, int blocksize, int32_t **buffer) { + int i, chan; + for (i=0; i<blocksize; i++) + for (chan=0; chan < nchan; chan++) + *samples++ = FFMIN(buffer[chan][i], 32768); + return samples; +} + +static void decode_subframe_lpc(ShortenContext *s, int channel, int residual_size, int pred_order) +{ + int sum, i, j; + int coeffs[pred_order]; + + for (i=0; i<pred_order; i++) + coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT); + + for (i=0; i < s->blocksize; i++) { + sum = s->lpcqoffset; + for (j=0; j<pred_order; j++) + sum += coeffs[j] * s->decoded[channel][i-j-1]; + s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> LPCQUANT); + } +} + + +static int shorten_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + ShortenContext *s = avctx->priv_data; + int i, input_buf_size = 0; + int16_t *samples = data; + if(s->max_framesize == 0){ + s->max_framesize= 1024; // should hopefully be enough for the first header + s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize); + } + + if(1 && s->max_framesize){//FIXME truncated + buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size); + input_buf_size= buf_size; + + if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){ + // printf("memmove\n"); + memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size); + s->bitstream_index=0; + } + memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size); + buf= &s->bitstream[s->bitstream_index]; + buf_size += s->bitstream_size; + s->bitstream_size= buf_size; + + if(buf_size < s->max_framesize){ + //dprintf("wanna more data ... %d\n", buf_size); + return input_buf_size; + } + } + init_get_bits(&s->gb, buf, buf_size*8); + get_bits(&s->gb, s->bitindex); + if (!s->blocksize) + { + int maxnlpc = 0; + /* shorten signature */ + if (get_bits_long(&s->gb, 32) != bswap_32(ff_get_fourcc("ajkg"))) { + av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n"); + return -1; + } + + s->lpcqoffset = 0; + s->blocksize = DEFAULT_BLOCK_SIZE; + s->channels = 1; + s->nmean = -1; + s->version = get_bits(&s->gb, 8); + s->internal_ftype = get_uint(s, TYPESIZE); + + s->channels = get_uint(s, CHANSIZE); + if (s->channels > MAX_CHANNELS) { + av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels); + return -1; + } + + /* get blocksize if version > 0 */ + if (s->version > 0) { + int skip_bytes; + s->blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE)); + maxnlpc = get_uint(s, LPCQSIZE); + s->nmean = get_uint(s, 0); + + skip_bytes = get_uint(s, NSKIPSIZE); + for (i=0; i<skip_bytes; i++) { + skip_bits(&s->gb, 8); + } + } + s->nwrap = FFMAX(NWRAP, maxnlpc); + + allocate_buffers(s); + + init_offset(s); + + if (s->version > 1) + s->lpcqoffset = V2LPCQOFFSET; + + if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) { + av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at begining of stream\n"); + return -1; + } + + s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); + if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) { + av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", s->header_size); + return -1; + } + + for (i=0; i<s->header_size; i++) + s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); + + if (decode_wave_header(avctx, s->header, s->header_size) < 0) + return -1; + + s->cur_chan = 0; + s->bitshift = 0; + } + else + { + int cmd; + int len; + cmd = get_ur_golomb_shorten(&s->gb, FNSIZE); + switch (cmd) { + case FN_ZERO: + case FN_DIFF0: + case FN_DIFF1: + case FN_DIFF2: + case FN_DIFF3: + case FN_QLPC: + { + int residual_size = 0; + int channel = s->cur_chan; + int32_t coffset; + if (cmd != FN_ZERO) { + residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE); + /* this is a hack as version 0 differed in defintion of get_sr_golomb_shorten */ + if (s->version == 0) + residual_size--; + } + + if (s->nmean == 0) + coffset = s->offset[channel][0]; + else { + int32_t sum = (s->version < 2) ? 0 : s->nmean / 2; + for (i=0; i<s->nmean; i++) + sum += s->offset[channel][i]; + coffset = sum / s->nmean; + if (s->version >= 2) + coffset >>= FFMIN(1, s->bitshift); + } + switch (cmd) { + case FN_ZERO: + for (i=0; i<s->blocksize; i++) + s->decoded[channel][i] = 0; + break; + case FN_DIFF0: + for (i=0; i<s->blocksize; i++) + s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + coffset; + break; + case FN_DIFF1: + for (i=0; i<s->blocksize; i++) + s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + s->decoded[channel][i - 1]; + break; + case FN_DIFF2: + for (i=0; i<s->blocksize; i++) + s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 2*s->decoded[channel][i-1] + - s->decoded[channel][i-2]; + break; + case FN_DIFF3: + for (i=0; i<s->blocksize; i++) + s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 3*s->decoded[channel][i-1] + - 3*s->decoded[channel][i-2] + + s->decoded[channel][i-3]; + break; + case FN_QLPC: + { + int pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE); + for (i=0; i<pred_order; i++) + s->decoded[channel][i - pred_order] -= coffset; + decode_subframe_lpc(s, channel, residual_size, pred_order); + if (coffset != 0) + for (i=0; i < s->blocksize; i++) + s->decoded[channel][i] += coffset; + } + } + if (s->nmean > 0) { + int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2; + for (i=0; i<s->blocksize; i++) + sum += s->decoded[channel][i]; + + for (i=1; i<s->nmean; i++) + s->offset[channel][i-1] = s->offset[channel][i]; + + if (s->version < 2) + s->offset[channel][s->nmean - 1] = sum / s->blocksize; + else + s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift; + } + for (i=-s->nwrap; i<0; i++) + s->decoded[channel][i] = s->decoded[channel][i + s->blocksize]; + + fix_bitshift(s, s->decoded[channel]); + + s->cur_chan++; + if (s->cur_chan == s->channels) { + samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded); + s->cur_chan = 0; + goto frame_done; + } + break; + } + break; + case FN_VERBATIM: + len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); + while (len--) { + get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); + } + break; + case FN_BITSHIFT: + s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE); + break; + case FN_BLOCKSIZE: + s->blocksize = get_uint(s, av_log2(s->blocksize)); + break; + case FN_QUIT: + return buf_size; + break; + default: + av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd); + return -1; + break; + } + } +frame_done: + *data_size = (int8_t *)samples - (int8_t *)data; + + // s->last_blocksize = s->blocksize; + s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8); + i= (get_bits_count(&s->gb))/8; + if (i > buf_size) { + av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size); + s->bitstream_size=0; + s->bitstream_index=0; + return -1; + } + if (s->bitstream_size) { + s->bitstream_index += i; + s->bitstream_size -= i; + return input_buf_size; + } else + return i; +} + +static int shorten_decode_close(AVCodecContext *avctx) +{ + ShortenContext *s = avctx->priv_data; + int i; + + for (i = 0; i < s->channels; i++) { + s->decoded[i] -= s->nwrap; + av_freep(&s->decoded[i]); + av_freep(&s->offset[i]); + } + av_freep(&s->bitstream); + return 0; +} + +static void shorten_flush(AVCodecContext *avctx){ + ShortenContext *s = avctx->priv_data; + + s->bitstream_size= + s->bitstream_index= 0; +} + +AVCodec shorten_decoder = { + "shorten", + CODEC_TYPE_AUDIO, + CODEC_ID_SHORTEN, + sizeof(ShortenContext), + shorten_decode_init, + NULL, + shorten_decode_close, + shorten_decode_frame, + .flush= shorten_flush, +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/shorten_plugin.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,801 @@ +/* + * Audacious Shorten input plugin + * Copyright (c) 2006 William Pitcock <nenolod -at- nenolod.net>. + * Copyright (c) 2006 Thomas Cort <tcort -at- cs.ubishops.ca>. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <stdlib.h> +#include <math.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <glib.h> +#include <glib/gi18n.h> + +#include <audacious/plugin.h> +#include <audacious/output.h> +#include <libaudacious/util.h> +#include <libaudacious/titlestring.h> + +#include "avcodec.h" +#include "avformat.h" + +#define ST_BUFF 1024 + +static GtkWidget *dialog; + +static int shn_decode = 0; +static gboolean shn_pause = 0; +static int shn_seekpos = -1; +static int shn_st_buff, shn_idx, shn_idx2; +static GThread *shn_decode_thread; +GStaticMutex shn_mutex = G_STATIC_MUTEX_INIT; +static AVCodecContext *c = NULL; +static AVFormatContext *ic = NULL; +static AVCodecContext *c2 = NULL; +static AVFormatContext *ic2 = NULL; +static uint8_t *shn_outbuf, *shn_s_outbuf; + +char description[64]; +static void shn_about(void); +static void shn_init(void); +static int shn_is_our_file(char *filename); +static void shn_play_file(char *filename); +static void shn_stop(void); +static void shn_seek(int time); +static void shn_do_pause(short p); +static int shn_get_time(void); +static void shn_get_song_info(char *filename, char **title, int *length); +static void shn_file_info_box(char *filename); +static char *wsong_title; +static int wsong_time; + +InputPlugin *get_iplugin_info(void); + +InputPlugin shn_ip = +{ + NULL, // Filled in by xmms + NULL, // Filled in by xmms + description, // The description that is shown in the preferences box + shn_init, // Called when the plugin is loaded + shn_about, // Show the about box + NULL, // Show the configure box + shn_is_our_file, // Return 1 if the plugin can handle the file + NULL, // Scan dir + shn_play_file, // Play file + shn_stop, // Stop + shn_do_pause, // Pause + shn_seek, // Seek + NULL, // Set the equalizer, most plugins won't be able to do this + shn_get_time, // Get the time, usually returns the output plugins output time + NULL, // Get volume + NULL, // Set volume + NULL, // OBSOLETE! + NULL, // OBSOLETE! + NULL, // Send data to the visualization plugins + NULL, // Fill in the stuff that is shown in the player window + NULL, // Show some text in the song title box. Filled in by xmms + shn_get_song_info, // Function to grab the title string + shn_file_info_box, // Bring up an info window for the filename passed in + NULL // Handle to the current output plugin. Filled in by xmms +}; + +InputPlugin *get_iplugin_info(void) +{ + memset(description, 0, 64); + shn_ip.description = g_strdup_printf(_("Shorten Player %s"), PACKAGE_VERSION); + return &shn_ip; +} + +static gchar *str_twenty_to_space(gchar * str) +{ + gchar *match, *match_end; + + g_return_val_if_fail(str != NULL, NULL); + + while ((match = strstr(str, "%20"))) { + match_end = match + 3; + *match++ = ' '; + while (*match_end) + *match++ = *match_end++; + *match = 0; + } + + return str; +} + +static void shn_about(void) +{ + static GtkWidget *aboutbox; + + if (aboutbox != NULL) + return; + + aboutbox = xmms_show_message(_("About the Shorten Plugin"), + _("Copyright (c) 2006 William Pitcock, Thomas Cort. Derived from the WMA plugin."), + _("Ok"), FALSE, NULL, NULL); + + g_signal_connect(G_OBJECT(aboutbox), "destroy", + G_CALLBACK(gtk_widget_destroyed), &aboutbox); +} + +static void shn_init(void) +{ + avcodec_init(); + avcodec_register_all(); + av_register_all(); +} + +static int shn_is_our_file(char *filename) +{ + AVCodec *codec2; + + if(av_open_input_file(&ic2, str_twenty_to_space(filename), NULL, 0, NULL) < 0) return 0; + + for(shn_idx2 = 0; shn_idx2 < ic2->nb_streams; shn_idx2++) { + c2 = &ic2->streams[shn_idx2]->codec; + if(c2->codec_type == CODEC_TYPE_AUDIO) break; + } + + av_find_stream_info(ic2); + + codec2 = avcodec_find_decoder(c2->codec_id); + + if(!codec2) { + av_close_input_file(ic2); + return 0; + } + + av_close_input_file(ic2); + return 1; +} + +static void shn_do_pause(short p) +{ + shn_pause = p; + shn_ip.output->pause(shn_pause); +} + +static void shn_seek(int time) +{ + shn_seekpos = time; + if(shn_pause) shn_ip.output->pause(0); + while(shn_decode && shn_seekpos!=-1) xmms_usleep(10000); + if(shn_pause) shn_ip.output->pause(1); +} + +static int shn_get_time(void) +{ + shn_ip.output->buffer_free(); + if(shn_decode) return shn_ip.output->output_time(); + return -1; +} + +static gchar *extname(const char *filename) +{ + gchar *ext = strrchr(filename, '.'); + if(ext != NULL) ++ext; + return ext; +} + +static char* w_getstr(char* str) +{ + if(str && strlen(str) > 0) return str; + return NULL; +} + +static gchar *get_song_title(AVFormatContext *in, gchar * filename) +{ + gchar *ret = NULL; + TitleInput *input; + + input = bmp_title_input_new(); + + if((in->title[0] != '\0') || (in->author[0] != '\0') || (in->album[0] != '\0') || + (in->comment[0] != '\0') || (in->genre[0] != '\0') || (in->year != 0) || (in->track != 0)) + { + input->performer = w_getstr(in->author); + input->album_name = w_getstr(in->album); + input->track_name = w_getstr(in->title); + input->year = in->year; + input->track_number = in->track; + input->genre = w_getstr(in->genre); + input->comment = w_getstr(in->comment); + } + input->file_name = g_path_get_basename(filename); + input->file_path = g_path_get_dirname(filename); + input->file_ext = extname(filename); + ret = xmms_get_titlestring(xmms_get_gentitle_format(), input); + if(input) g_free(input); + + if(!ret) + { + ret = g_strdup(input->file_name); + if (extname(ret) != NULL) + *(extname(ret) - 1) = '\0'; + } + return ret; +} + +static guint get_song_time(AVFormatContext *in) +{ + if(in->duration) + return in->duration/1000; + else + return 0; +} + +static void shn_get_song_info(char *filename, char **title_real, int *len_real) +{ + AVFormatContext *in = NULL; + + (*len_real) = -1; + (*title_real) = NULL; + + if (av_open_input_file(&in, str_twenty_to_space(filename), NULL, 0, NULL) < 0) + return; + + av_find_stream_info(in); + (*len_real) = get_song_time(in); + (*title_real) = get_song_title(in, filename); + av_close_input_file(in); +} + +static void shn_playbuff(int out_size) +{ + FifoBuffer f; + int sst_buff; + + fifo_init(&f, out_size*2); + fifo_write(&f, shn_outbuf, out_size, &f.wptr); + while(!fifo_read(&f, shn_s_outbuf, shn_st_buff, &f.rptr) && shn_decode) + { + sst_buff = shn_st_buff; + if(shn_pause) memset(shn_s_outbuf, 0, sst_buff); + while(shn_ip.output->buffer_free() < shn_st_buff) xmms_usleep(20000); + produce_audio(shn_ip.output->written_time(), FMT_S16_NE, + c->channels, sst_buff, (short *)shn_s_outbuf, NULL); + memset(shn_s_outbuf, 0, sst_buff); + } + fifo_free(&f); + return; +} + +static void *shn_play_loop(void *arg) +{ + uint8_t *inbuf_ptr; + int out_size, size, len; + AVPacket pkt; + + g_static_mutex_lock(&shn_mutex); + while(shn_decode){ + + if(shn_seekpos != -1) + { + av_seek_frame(ic, shn_idx, shn_seekpos * 1000000LL); + shn_ip.output->flush(shn_seekpos * 1000); + shn_seekpos = -1; + } + + if(av_read_frame(ic, &pkt) < 0) break; + + size = pkt.size; + inbuf_ptr = pkt.data; + + if(size == 0) break; + + while(size > 0){ + len = avcodec_decode_audio(c, (short *)shn_outbuf, &out_size, + inbuf_ptr, size); + if(len < 0) break; + + if(out_size <= 0) continue; + + shn_playbuff(out_size); + + size -= len; + inbuf_ptr += len; + if(pkt.data) av_free_packet(&pkt); + } + } + while(shn_decode && shn_ip.output->buffer_playing()) xmms_usleep(30000); + shn_decode = 0; + if(shn_s_outbuf) g_free(shn_s_outbuf); + if(shn_outbuf) g_free(shn_outbuf); + if(pkt.data) av_free_packet(&pkt); + if(c) avcodec_close(c); + if(ic) av_close_input_file(ic); + g_static_mutex_unlock(&shn_mutex); + g_thread_exit(NULL); + return(NULL); +} + +static void shn_play_file(char *filename) +{ + AVCodec *codec; + + if(av_open_input_file(&ic, str_twenty_to_space(filename), NULL, 0, NULL) < 0) return; + + for(shn_idx = 0; shn_idx < ic->nb_streams; shn_idx++) { + c = &ic->streams[shn_idx]->codec; + if(c->codec_type == CODEC_TYPE_AUDIO) break; + } + + av_find_stream_info(ic); + + codec = avcodec_find_decoder(c->codec_id); + + if(!codec) return; + + if(avcodec_open(c, codec) < 0) return; + + wsong_title = get_song_title(ic, filename); + wsong_time = get_song_time(ic); + + if(shn_ip.output->open_audio( FMT_S16_NE, c->sample_rate, c->channels) <= 0) return; + + shn_st_buff = ST_BUFF; + + shn_ip.set_info(wsong_title, wsong_time, c->bit_rate, c->sample_rate, c->channels); + + shn_s_outbuf = g_malloc0(shn_st_buff); + shn_outbuf = g_malloc0(AVCODEC_MAX_AUDIO_FRAME_SIZE); + shn_seekpos = -1; + shn_decode = 1; + shn_decode_thread = g_thread_create((GThreadFunc)shn_play_loop, NULL, TRUE, NULL); +} + +static void shn_stop(void) +{ + shn_decode = 0; + if(shn_pause) shn_do_pause(0); + g_thread_join(shn_decode_thread); + shn_ip.output->close_audio(); +} + +static void shn_file_info_box (char *filename) +{ + GtkWidget *dialog_vbox1; + GtkWidget *vbox1; + GtkWidget *hbox1; + GtkWidget *label_name; + GtkWidget *entry_filename; + GtkWidget *hbox2; + GtkWidget *frame_shn_info; + GtkWidget *alignment1; + GtkWidget *table1; + GtkWidget *label_album; + GtkWidget *label_year; + GtkWidget *label_track; + GtkWidget *label_genre; + GtkWidget *label_comments; + GtkWidget *label_shn_version; + GtkWidget *label_bitrate; + GtkWidget *label_rate; + GtkWidget *label_chans; + GtkWidget *label_play_time; + GtkWidget *label_filesize; + GtkWidget *label_shn_vers_val; + GtkWidget *label_bitrate_val; + GtkWidget *label_rate_val; + GtkWidget *label_chans_val; + GtkWidget *label_playtime_val; + GtkWidget *label_filesize_val; + GtkWidget *label4; + GtkWidget *frame_tags; + GtkWidget *alignment2; + GtkWidget *table2; + GtkWidget *label_artist; + GtkWidget *label_title; + GtkWidget *entry_artist; + GtkWidget *entry_album; + GtkWidget *entry_year; + GtkWidget *entry_title; + GtkWidget *entry_track; + GtkWidget *entry_genre; + GtkWidget *entry_comments; + GtkWidget *label5; + GtkWidget *dialog_action_area1; + GtkWidget *okbutton; + + AVFormatContext *in = NULL; + AVCodecContext *s = NULL; + AVCodec *codec; + gint tns, thh, tmm, tss; + gint i; + gchar *title, + *channels, + *bitrate, + *playtime, + *samplerate, + *filesize; + FILE *f; + if (dialog) { + (void)printf(_("Info dialog is already opened!\n")); + return; + } + + if(av_open_input_file(&in, filename, NULL, 0, NULL) < 0) + return; + + for(i = 0; i < in->nb_streams; i++) { + s = &in->streams[i]->codec; + if(s->codec_type == CODEC_TYPE_AUDIO) + break; + } + + av_find_stream_info(in); + codec = avcodec_find_decoder(s->codec_id); + + /* window title */ + title = g_strdup_printf(_("File Info - %s"), g_basename(filename)); + /* channels */ + if (s->channels == 1) + channels = g_strdup("MONO"); + else + channels = g_strdup("STEREO"); + + /* bitrate */ + bitrate = g_strdup_printf(_("%d Kb/s"), (s->bit_rate / 1000)); + + /* playtime */ + if (in->duration != 0) { + tns = in->duration/1000000LL; + thh = tns/3600; + tmm = (tns%3600)/60; + tss = (tns%60); + playtime = g_strdup_printf(_("%02d:%02d:%02d"), thh, tmm, tss); + } else + playtime = g_strdup("N/A"); + + /* samplerate */ + samplerate = g_strdup_printf(_("%d Hz"), s->sample_rate); + + /* filesize */ + f = fopen(filename, "rb"); + + if (f == NULL) + return; + + fseek(f, 0, SEEK_END); + filesize = g_strdup_printf(_("%lu Bytes"), ftell(f)); + fclose(f); + + dialog = gtk_dialog_new(); + + gtk_signal_connect(GTK_OBJECT(dialog), "destroy", + GTK_SIGNAL_FUNC(gtk_widget_destroyed), &dialog); + + gtk_window_set_title(GTK_WINDOW(dialog), title); + gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, FALSE); + + dialog_vbox1 = GTK_DIALOG(dialog)->vbox; + gtk_widget_show(dialog_vbox1); + + vbox1 = gtk_vbox_new(FALSE, 0); + gtk_widget_show(vbox1); + gtk_box_pack_start(GTK_BOX(dialog_vbox1), vbox1, TRUE, TRUE, 0); + + hbox1 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox1); + gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0); + + label_name = gtk_label_new(_("<b>Name:</b>")); + gtk_widget_show(label_name); + gtk_box_pack_start(GTK_BOX (hbox1), label_name, FALSE, FALSE, 0); + gtk_misc_set_alignment(GTK_MISC (label_name), 0.48, 0.51); + gtk_misc_set_padding(GTK_MISC (label_name), 10, 10); + gtk_label_set_use_markup(GTK_LABEL(label_name), TRUE); + + entry_filename = gtk_entry_new(); + gtk_widget_show(entry_filename); + gtk_box_pack_start(GTK_BOX(hbox1), entry_filename, TRUE, TRUE, 4); + gtk_editable_set_editable(GTK_EDITABLE(entry_filename), FALSE); + gtk_entry_set_text(GTK_ENTRY(entry_filename), filename); + + hbox2 = gtk_hbox_new(FALSE, 0); + gtk_widget_show(hbox2); + gtk_box_pack_start(GTK_BOX(vbox1), hbox2, TRUE, TRUE, 0); + + frame_shn_info = gtk_frame_new(NULL); + gtk_widget_show(frame_shn_info); + gtk_box_pack_start(GTK_BOX(hbox2), frame_shn_info, TRUE, TRUE, 0); + gtk_frame_set_shadow_type(GTK_FRAME (frame_shn_info), GTK_SHADOW_ETCHED_IN); + gtk_container_set_border_width (GTK_CONTAINER(frame_shn_info), 10); + + alignment1 = gtk_alignment_new(0.5, 0.5, 1, 1); + gtk_widget_show(alignment1); + gtk_container_add(GTK_CONTAINER(frame_shn_info), alignment1); + gtk_alignment_set_padding(GTK_ALIGNMENT(alignment1), 0, 0, 0, 0); + gtk_container_set_border_width(GTK_CONTAINER(alignment1), 2); + + table1 = gtk_table_new(6, 2, FALSE); + gtk_widget_show(table1); + gtk_container_add(GTK_CONTAINER(alignment1), table1); + gtk_container_set_border_width(GTK_CONTAINER(table1), 6); + gtk_table_set_row_spacings(GTK_TABLE(table1), 3); + gtk_table_set_col_spacings(GTK_TABLE(table1), 8); + /* WMA Version label */ + label_shn_version = gtk_label_new(_("<b>WMA Version:</b>")); + gtk_widget_show(label_shn_version); + gtk_table_attach(GTK_TABLE(table1), label_shn_version, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_shn_version), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_shn_version), TRUE); + + /* Bitrate */ + label_bitrate = gtk_label_new(_("<b>Bitrate:</b>")); + gtk_widget_show(label_bitrate); + gtk_table_attach(GTK_TABLE(table1), label_bitrate, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_bitrate), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_bitrate), TRUE); + + /* Samplerate */ + label_rate = gtk_label_new(_("<b>Samplerate:</b>")); + gtk_widget_show(label_rate); + gtk_table_attach(GTK_TABLE(table1), label_rate, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_rate), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_rate), TRUE); + + /* Channels */ + label_chans = gtk_label_new(_("<b>Channels:</b>")); + gtk_widget_show(label_chans); + gtk_table_attach(GTK_TABLE (table1), label_chans, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_chans), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_chans), TRUE); + + /* Play time */ + label_play_time = gtk_label_new(_("<b>Play time:</b>")); + gtk_widget_show(label_play_time); + gtk_table_attach(GTK_TABLE (table1), label_play_time, 0, 1, 4, 5, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_play_time), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_play_time), TRUE); + + /* Filesize */ + label_filesize = gtk_label_new(_("<b>Filesize:</b>")); + gtk_widget_show(label_filesize); + gtk_table_attach(GTK_TABLE(table1), label_filesize, 0, 1, 5, 6, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_filesize), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_filesize), TRUE); + + + label_shn_vers_val = gtk_label_new(codec->name); + gtk_widget_show(label_shn_vers_val); + gtk_table_attach(GTK_TABLE(table1), label_shn_vers_val, 1, 2, 0, 1, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_shn_vers_val), 0, 0.5); + + label_bitrate_val = gtk_label_new(bitrate); + gtk_widget_show(label_bitrate_val); + gtk_table_attach(GTK_TABLE(table1), label_bitrate_val, 1, 2, 1, 2, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_bitrate_val), 0, 0.5); + + label_rate_val = gtk_label_new(samplerate); + gtk_widget_show(label_rate_val); + gtk_table_attach(GTK_TABLE(table1), label_rate_val, 1, 2, 2, 3, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_rate_val), 0, 0.5); + + label_chans_val = gtk_label_new(channels); + gtk_widget_show(label_chans_val); + gtk_table_attach(GTK_TABLE(table1), label_chans_val, 1, 2, 3, 4, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC (label_chans_val), 0, 0.5); + + label_playtime_val = gtk_label_new(playtime); + gtk_widget_show(label_playtime_val); + gtk_table_attach(GTK_TABLE(table1), label_playtime_val, 1, 2, 4, 5, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_playtime_val), 0, 0.5); + + label_filesize_val = gtk_label_new(filesize); + gtk_widget_show(label_filesize_val); + gtk_table_attach(GTK_TABLE (table1), label_filesize_val, 1, 2, 5, 6, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_filesize_val), 0, 0.5); + + label4 = gtk_label_new (_("WMA Info")); + gtk_widget_show(label4); + gtk_frame_set_label_widget(GTK_FRAME(frame_shn_info), label4); + frame_tags = gtk_frame_new (NULL); + gtk_widget_show (frame_tags); + gtk_box_pack_start (GTK_BOX (hbox2), frame_tags, TRUE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (frame_tags), GTK_SHADOW_ETCHED_IN); + gtk_container_set_border_width (GTK_CONTAINER (frame_tags), 10); + + + alignment2 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment2); + gtk_container_add (GTK_CONTAINER (frame_tags), alignment2); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment2), 0, 0, 12, 0); + gtk_container_set_border_width (GTK_CONTAINER (alignment2), 2); + + + table2 = gtk_table_new(8, 2, FALSE); + gtk_widget_show(table2); + gtk_container_add(GTK_CONTAINER(alignment2), table2); + gtk_container_set_border_width(GTK_CONTAINER(table2), 6); + gtk_table_set_row_spacings(GTK_TABLE(table2), 3); + gtk_table_set_col_spacings(GTK_TABLE(table2), 8); + + /* Artist */ + label_artist = gtk_label_new(_("<b>Artist:</b>")); + gtk_widget_show(label_artist); + gtk_table_attach(GTK_TABLE (table2), label_artist, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_artist), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_artist), TRUE); + + /* Title */ + label_title = gtk_label_new(_("<b>Title:</b>")); + gtk_widget_show(label_title); + gtk_table_attach(GTK_TABLE (table2), label_title, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_title), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_title), TRUE); + + /* Album */ + label_album = gtk_label_new(_("<b>Album:</b>")); + gtk_widget_show(label_album); + gtk_table_attach(GTK_TABLE (table2), label_album, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_album), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_album), TRUE); + + /* Comments */ + label_comments = gtk_label_new(_("<b>Comments:</b>")); + gtk_widget_show(label_comments); + gtk_table_attach(GTK_TABLE(table2), label_comments, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_comments), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_comments), TRUE); + + /* Year */ + label_year = gtk_label_new(_("<b>Year:</b>")); + gtk_widget_show(label_year); + gtk_table_attach(GTK_TABLE (table2), label_year, 0, 1, 4, 5, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_year), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_year), TRUE); + + /* Track */ + label_track = gtk_label_new(_("<b>Track:</b>")); + gtk_widget_show(label_track); + gtk_table_attach(GTK_TABLE (table2), label_track, 0, 1, 5, 6, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC(label_track), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_track), TRUE); + + /* Genre */ + label_genre = gtk_label_new(_("<b>Genre:</b>")); + gtk_widget_show(label_genre); + gtk_table_attach(GTK_TABLE (table2), label_genre, 0, 1, 6, 7, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment(GTK_MISC (label_genre), 0, 0.5); + gtk_label_set_use_markup(GTK_LABEL(label_genre), TRUE); + + + entry_artist = gtk_entry_new(); + gtk_widget_show (entry_artist); + gtk_table_attach (GTK_TABLE (table2), entry_artist, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_editable_set_editable (GTK_EDITABLE (entry_artist), FALSE); + gtk_entry_set_text(GTK_ENTRY(entry_artist), in->author); + + entry_title = gtk_entry_new(); + gtk_widget_show(entry_title); + gtk_table_attach (GTK_TABLE (table2), entry_title, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_editable_set_editable(GTK_EDITABLE (entry_title), FALSE); + gtk_entry_set_text(GTK_ENTRY(entry_title), in->title); + + entry_album = gtk_entry_new(); + gtk_widget_show(entry_album); + gtk_table_attach(GTK_TABLE (table2), entry_album, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_editable_set_editable(GTK_EDITABLE (entry_album), FALSE); + gtk_entry_set_text(GTK_ENTRY(entry_album), in->album); + + entry_comments = gtk_entry_new(); + gtk_widget_show(entry_comments); + gtk_table_attach(GTK_TABLE (table2), entry_comments, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_editable_set_editable(GTK_EDITABLE (entry_comments), FALSE); + gtk_entry_set_text(GTK_ENTRY(entry_comments), in->comment); + + entry_year = gtk_entry_new(); + gtk_widget_show(entry_year); + gtk_table_attach(GTK_TABLE (table2), entry_year, 1, 2, 4, 5, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_editable_set_editable(GTK_EDITABLE (entry_year), FALSE); + gtk_entry_set_text(GTK_ENTRY(entry_year), g_strdup_printf("%d", in->year)); + + entry_track = gtk_entry_new(); + gtk_widget_show(entry_track); + gtk_table_attach(GTK_TABLE (table2), entry_track, 1, 2, 5, 6, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_editable_set_editable(GTK_EDITABLE (entry_track), FALSE); + gtk_entry_set_text(GTK_ENTRY(entry_track), g_strdup_printf("%d", in->track)); + + entry_genre = gtk_entry_new(); + gtk_widget_show(entry_genre); + gtk_table_attach(GTK_TABLE (table2), entry_genre, 1, 2, 6, 7, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_editable_set_editable(GTK_EDITABLE (entry_genre), FALSE); + gtk_entry_set_text(GTK_ENTRY(entry_genre), in->genre); + + + label5 = gtk_label_new(_("Tags")); + gtk_widget_show(label5); + gtk_frame_set_label_widget(GTK_FRAME(frame_tags), label5); + + + dialog_action_area1 = GTK_DIALOG(dialog)->action_area; + gtk_widget_show(dialog_action_area1); + gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog_action_area1), GTK_BUTTONBOX_END); + + okbutton = gtk_button_new_from_stock("gtk-ok"); + gtk_widget_show(okbutton); + gtk_dialog_add_action_widget(GTK_DIALOG(dialog), okbutton, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS(okbutton, GTK_CAN_DEFAULT); + + gtk_signal_connect_object(GTK_OBJECT(okbutton), "clicked", + GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog)); + + gtk_widget_show(dialog); + + g_free(title); + g_free(channels); + g_free(bitrate); + g_free(playtime); + g_free(samplerate); + g_free(filesize); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/simple_idct.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,585 @@ +/* + * Simple IDCT + * + * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> + * + * 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 + */ + +/** + * @file simple_idct.c + * simpleidct in C. + */ + +/* + based upon some outcommented c code from mpeg2dec (idct_mmx.c + written by Aaron Holtzman <aholtzma@ess.engr.uvic.ca>) + */ +#include "avcodec.h" +#include "dsputil.h" +#include "simple_idct.h" + +#if 0 +#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ +#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ +#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ +#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */ +#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ +#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ +#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ +#define ROW_SHIFT 8 +#define COL_SHIFT 17 +#else +#define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define ROW_SHIFT 11 +#define COL_SHIFT 20 // 6 +#endif + +#if defined(ARCH_POWERPC_405) + +/* signed 16x16 -> 32 multiply add accumulate */ +#define MAC16(rt, ra, rb) \ + asm ("maclhw %0, %2, %3" : "=r" (rt) : "0" (rt), "r" (ra), "r" (rb)); + +/* signed 16x16 -> 32 multiply */ +#define MUL16(rt, ra, rb) \ + asm ("mullhw %0, %1, %2" : "=r" (rt) : "r" (ra), "r" (rb)); + +#else + +/* signed 16x16 -> 32 multiply add accumulate */ +#define MAC16(rt, ra, rb) rt += (ra) * (rb) + +/* signed 16x16 -> 32 multiply */ +#define MUL16(rt, ra, rb) rt = (ra) * (rb) + +#endif + +static inline void idctRowCondDC (DCTELEM * row) +{ + int a0, a1, a2, a3, b0, b1, b2, b3; +#ifdef FAST_64BIT + uint64_t temp; +#else + uint32_t temp; +#endif + +#ifdef FAST_64BIT +#ifdef WORDS_BIGENDIAN +#define ROW0_MASK 0xffff000000000000LL +#else +#define ROW0_MASK 0xffffLL +#endif + if(sizeof(DCTELEM)==2){ + if ( ((((uint64_t *)row)[0] & ~ROW0_MASK) | + ((uint64_t *)row)[1]) == 0) { + temp = (row[0] << 3) & 0xffff; + temp += temp << 16; + temp += temp << 32; + ((uint64_t *)row)[0] = temp; + ((uint64_t *)row)[1] = temp; + return; + } + }else{ + if (!(row[1]|row[2]|row[3]|row[4]|row[5]|row[6]|row[7])) { + row[0]=row[1]=row[2]=row[3]=row[4]=row[5]=row[6]=row[7]= row[0] << 3; + return; + } + } +#else + if(sizeof(DCTELEM)==2){ + if (!(((uint32_t*)row)[1] | + ((uint32_t*)row)[2] | + ((uint32_t*)row)[3] | + row[1])) { + temp = (row[0] << 3) & 0xffff; + temp += temp << 16; + ((uint32_t*)row)[0]=((uint32_t*)row)[1] = + ((uint32_t*)row)[2]=((uint32_t*)row)[3] = temp; + return; + } + }else{ + if (!(row[1]|row[2]|row[3]|row[4]|row[5]|row[6]|row[7])) { + row[0]=row[1]=row[2]=row[3]=row[4]=row[5]=row[6]=row[7]= row[0] << 3; + return; + } + } +#endif + + a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1)); + a1 = a0; + a2 = a0; + a3 = a0; + + /* no need to optimize : gcc does it */ + a0 += W2 * row[2]; + a1 += W6 * row[2]; + a2 -= W6 * row[2]; + a3 -= W2 * row[2]; + + MUL16(b0, W1, row[1]); + MAC16(b0, W3, row[3]); + MUL16(b1, W3, row[1]); + MAC16(b1, -W7, row[3]); + MUL16(b2, W5, row[1]); + MAC16(b2, -W1, row[3]); + MUL16(b3, W7, row[1]); + MAC16(b3, -W5, row[3]); + +#ifdef FAST_64BIT + temp = ((uint64_t*)row)[1]; +#else + temp = ((uint32_t*)row)[2] | ((uint32_t*)row)[3]; +#endif + if (temp != 0) { + a0 += W4*row[4] + W6*row[6]; + a1 += - W4*row[4] - W2*row[6]; + a2 += - W4*row[4] + W2*row[6]; + a3 += W4*row[4] - W6*row[6]; + + MAC16(b0, W5, row[5]); + MAC16(b0, W7, row[7]); + + MAC16(b1, -W1, row[5]); + MAC16(b1, -W5, row[7]); + + MAC16(b2, W7, row[5]); + MAC16(b2, W3, row[7]); + + MAC16(b3, W3, row[5]); + MAC16(b3, -W1, row[7]); + } + + row[0] = (a0 + b0) >> ROW_SHIFT; + row[7] = (a0 - b0) >> ROW_SHIFT; + row[1] = (a1 + b1) >> ROW_SHIFT; + row[6] = (a1 - b1) >> ROW_SHIFT; + row[2] = (a2 + b2) >> ROW_SHIFT; + row[5] = (a2 - b2) >> ROW_SHIFT; + row[3] = (a3 + b3) >> ROW_SHIFT; + row[4] = (a3 - b3) >> ROW_SHIFT; +} + +static inline void idctSparseColPut (uint8_t *dest, int line_size, + DCTELEM * col) +{ + int a0, a1, a2, a3, b0, b1, b2, b3; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + /* XXX: I did that only to give same values as previous code */ + a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4)); + a1 = a0; + a2 = a0; + a3 = a0; + + a0 += + W2*col[8*2]; + a1 += + W6*col[8*2]; + a2 += - W6*col[8*2]; + a3 += - W2*col[8*2]; + + MUL16(b0, W1, col[8*1]); + MUL16(b1, W3, col[8*1]); + MUL16(b2, W5, col[8*1]); + MUL16(b3, W7, col[8*1]); + + MAC16(b0, + W3, col[8*3]); + MAC16(b1, - W7, col[8*3]); + MAC16(b2, - W1, col[8*3]); + MAC16(b3, - W5, col[8*3]); + + if(col[8*4]){ + a0 += + W4*col[8*4]; + a1 += - W4*col[8*4]; + a2 += - W4*col[8*4]; + a3 += + W4*col[8*4]; + } + + if (col[8*5]) { + MAC16(b0, + W5, col[8*5]); + MAC16(b1, - W1, col[8*5]); + MAC16(b2, + W7, col[8*5]); + MAC16(b3, + W3, col[8*5]); + } + + if(col[8*6]){ + a0 += + W6*col[8*6]; + a1 += - W2*col[8*6]; + a2 += + W2*col[8*6]; + a3 += - W6*col[8*6]; + } + + if (col[8*7]) { + MAC16(b0, + W7, col[8*7]); + MAC16(b1, - W5, col[8*7]); + MAC16(b2, + W3, col[8*7]); + MAC16(b3, - W1, col[8*7]); + } + + dest[0] = cm[(a0 + b0) >> COL_SHIFT]; + dest += line_size; + dest[0] = cm[(a1 + b1) >> COL_SHIFT]; + dest += line_size; + dest[0] = cm[(a2 + b2) >> COL_SHIFT]; + dest += line_size; + dest[0] = cm[(a3 + b3) >> COL_SHIFT]; + dest += line_size; + dest[0] = cm[(a3 - b3) >> COL_SHIFT]; + dest += line_size; + dest[0] = cm[(a2 - b2) >> COL_SHIFT]; + dest += line_size; + dest[0] = cm[(a1 - b1) >> COL_SHIFT]; + dest += line_size; + dest[0] = cm[(a0 - b0) >> COL_SHIFT]; +} + +static inline void idctSparseColAdd (uint8_t *dest, int line_size, + DCTELEM * col) +{ + int a0, a1, a2, a3, b0, b1, b2, b3; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + /* XXX: I did that only to give same values as previous code */ + a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4)); + a1 = a0; + a2 = a0; + a3 = a0; + + a0 += + W2*col[8*2]; + a1 += + W6*col[8*2]; + a2 += - W6*col[8*2]; + a3 += - W2*col[8*2]; + + MUL16(b0, W1, col[8*1]); + MUL16(b1, W3, col[8*1]); + MUL16(b2, W5, col[8*1]); + MUL16(b3, W7, col[8*1]); + + MAC16(b0, + W3, col[8*3]); + MAC16(b1, - W7, col[8*3]); + MAC16(b2, - W1, col[8*3]); + MAC16(b3, - W5, col[8*3]); + + if(col[8*4]){ + a0 += + W4*col[8*4]; + a1 += - W4*col[8*4]; + a2 += - W4*col[8*4]; + a3 += + W4*col[8*4]; + } + + if (col[8*5]) { + MAC16(b0, + W5, col[8*5]); + MAC16(b1, - W1, col[8*5]); + MAC16(b2, + W7, col[8*5]); + MAC16(b3, + W3, col[8*5]); + } + + if(col[8*6]){ + a0 += + W6*col[8*6]; + a1 += - W2*col[8*6]; + a2 += + W2*col[8*6]; + a3 += - W6*col[8*6]; + } + + if (col[8*7]) { + MAC16(b0, + W7, col[8*7]); + MAC16(b1, - W5, col[8*7]); + MAC16(b2, + W3, col[8*7]); + MAC16(b3, - W1, col[8*7]); + } + + dest[0] = cm[dest[0] + ((a0 + b0) >> COL_SHIFT)]; + dest += line_size; + dest[0] = cm[dest[0] + ((a1 + b1) >> COL_SHIFT)]; + dest += line_size; + dest[0] = cm[dest[0] + ((a2 + b2) >> COL_SHIFT)]; + dest += line_size; + dest[0] = cm[dest[0] + ((a3 + b3) >> COL_SHIFT)]; + dest += line_size; + dest[0] = cm[dest[0] + ((a3 - b3) >> COL_SHIFT)]; + dest += line_size; + dest[0] = cm[dest[0] + ((a2 - b2) >> COL_SHIFT)]; + dest += line_size; + dest[0] = cm[dest[0] + ((a1 - b1) >> COL_SHIFT)]; + dest += line_size; + dest[0] = cm[dest[0] + ((a0 - b0) >> COL_SHIFT)]; +} + +static inline void idctSparseCol (DCTELEM * col) +{ + int a0, a1, a2, a3, b0, b1, b2, b3; + + /* XXX: I did that only to give same values as previous code */ + a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4)); + a1 = a0; + a2 = a0; + a3 = a0; + + a0 += + W2*col[8*2]; + a1 += + W6*col[8*2]; + a2 += - W6*col[8*2]; + a3 += - W2*col[8*2]; + + MUL16(b0, W1, col[8*1]); + MUL16(b1, W3, col[8*1]); + MUL16(b2, W5, col[8*1]); + MUL16(b3, W7, col[8*1]); + + MAC16(b0, + W3, col[8*3]); + MAC16(b1, - W7, col[8*3]); + MAC16(b2, - W1, col[8*3]); + MAC16(b3, - W5, col[8*3]); + + if(col[8*4]){ + a0 += + W4*col[8*4]; + a1 += - W4*col[8*4]; + a2 += - W4*col[8*4]; + a3 += + W4*col[8*4]; + } + + if (col[8*5]) { + MAC16(b0, + W5, col[8*5]); + MAC16(b1, - W1, col[8*5]); + MAC16(b2, + W7, col[8*5]); + MAC16(b3, + W3, col[8*5]); + } + + if(col[8*6]){ + a0 += + W6*col[8*6]; + a1 += - W2*col[8*6]; + a2 += + W2*col[8*6]; + a3 += - W6*col[8*6]; + } + + if (col[8*7]) { + MAC16(b0, + W7, col[8*7]); + MAC16(b1, - W5, col[8*7]); + MAC16(b2, + W3, col[8*7]); + MAC16(b3, - W1, col[8*7]); + } + + col[0 ] = ((a0 + b0) >> COL_SHIFT); + col[8 ] = ((a1 + b1) >> COL_SHIFT); + col[16] = ((a2 + b2) >> COL_SHIFT); + col[24] = ((a3 + b3) >> COL_SHIFT); + col[32] = ((a3 - b3) >> COL_SHIFT); + col[40] = ((a2 - b2) >> COL_SHIFT); + col[48] = ((a1 - b1) >> COL_SHIFT); + col[56] = ((a0 - b0) >> COL_SHIFT); +} + +void simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + int i; + for(i=0; i<8; i++) + idctRowCondDC(block + i*8); + + for(i=0; i<8; i++) + idctSparseColPut(dest + i, line_size, block + i); +} + +void simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + int i; + for(i=0; i<8; i++) + idctRowCondDC(block + i*8); + + for(i=0; i<8; i++) + idctSparseColAdd(dest + i, line_size, block + i); +} + +void simple_idct(DCTELEM *block) +{ + int i; + for(i=0; i<8; i++) + idctRowCondDC(block + i*8); + + for(i=0; i<8; i++) + idctSparseCol(block + i); +} + +/* 2x4x8 idct */ + +#define CN_SHIFT 12 +#define C_FIX(x) ((int)((x) * (1 << CN_SHIFT) + 0.5)) +#define C1 C_FIX(0.6532814824) +#define C2 C_FIX(0.2705980501) + +/* row idct is multiple by 16 * sqrt(2.0), col idct4 is normalized, + and the butterfly must be multiplied by 0.5 * sqrt(2.0) */ +#define C_SHIFT (4+1+12) + +static inline void idct4col(uint8_t *dest, int line_size, const DCTELEM *col) +{ + int c0, c1, c2, c3, a0, a1, a2, a3; + const uint8_t *cm = cropTbl + MAX_NEG_CROP; + + a0 = col[8*0]; + a1 = col[8*2]; + a2 = col[8*4]; + a3 = col[8*6]; + c0 = ((a0 + a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1)); + c2 = ((a0 - a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1)); + c1 = a1 * C1 + a3 * C2; + c3 = a1 * C2 - a3 * C1; + dest[0] = cm[(c0 + c1) >> C_SHIFT]; + dest += line_size; + dest[0] = cm[(c2 + c3) >> C_SHIFT]; + dest += line_size; + dest[0] = cm[(c2 - c3) >> C_SHIFT]; + dest += line_size; + dest[0] = cm[(c0 - c1) >> C_SHIFT]; +} + +#define BF(k) \ +{\ + int a0, a1;\ + a0 = ptr[k];\ + a1 = ptr[8 + k];\ + ptr[k] = a0 + a1;\ + ptr[8 + k] = a0 - a1;\ +} + +/* only used by DV codec. The input must be interlaced. 128 is added + to the pixels before clamping to avoid systematic error + (1024*sqrt(2)) offset would be needed otherwise. */ +/* XXX: I think a 1.0/sqrt(2) normalization should be needed to + compensate the extra butterfly stage - I don't have the full DV + specification */ +void simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + int i; + DCTELEM *ptr; + + /* butterfly */ + ptr = block; + for(i=0;i<4;i++) { + BF(0); + BF(1); + BF(2); + BF(3); + BF(4); + BF(5); + BF(6); + BF(7); + ptr += 2 * 8; + } + + /* IDCT8 on each line */ + for(i=0; i<8; i++) { + idctRowCondDC(block + i*8); + } + + /* IDCT4 and store */ + for(i=0;i<8;i++) { + idct4col(dest + i, 2 * line_size, block + i); + idct4col(dest + line_size + i, 2 * line_size, block + 8 + i); + } +} + +/* 8x4 & 4x8 WMV2 IDCT */ +#undef CN_SHIFT +#undef C_SHIFT +#undef C_FIX +#undef C1 +#undef C2 +#define CN_SHIFT 12 +#define C_FIX(x) ((int)((x) * 1.414213562 * (1 << CN_SHIFT) + 0.5)) +#define C1 C_FIX(0.6532814824) +#define C2 C_FIX(0.2705980501) +#define C3 C_FIX(0.5) +#define C_SHIFT (4+1+12) +static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col) +{ + int c0, c1, c2, c3, a0, a1, a2, a3; + const uint8_t *cm = cropTbl + MAX_NEG_CROP; + + a0 = col[8*0]; + a1 = col[8*1]; + a2 = col[8*2]; + a3 = col[8*3]; + c0 = (a0 + a2)*C3 + (1 << (C_SHIFT - 1)); + c2 = (a0 - a2)*C3 + (1 << (C_SHIFT - 1)); + c1 = a1 * C1 + a3 * C2; + c3 = a1 * C2 - a3 * C1; + dest[0] = cm[dest[0] + ((c0 + c1) >> C_SHIFT)]; + dest += line_size; + dest[0] = cm[dest[0] + ((c2 + c3) >> C_SHIFT)]; + dest += line_size; + dest[0] = cm[dest[0] + ((c2 - c3) >> C_SHIFT)]; + dest += line_size; + dest[0] = cm[dest[0] + ((c0 - c1) >> C_SHIFT)]; +} + +#define RN_SHIFT 15 +#define R_FIX(x) ((int)((x) * 1.414213562 * (1 << RN_SHIFT) + 0.5)) +#define R1 R_FIX(0.6532814824) +#define R2 R_FIX(0.2705980501) +#define R3 R_FIX(0.5) +#define R_SHIFT 11 +static inline void idct4row(DCTELEM *row) +{ + int c0, c1, c2, c3, a0, a1, a2, a3; + //const uint8_t *cm = cropTbl + MAX_NEG_CROP; + + a0 = row[0]; + a1 = row[1]; + a2 = row[2]; + a3 = row[3]; + c0 = (a0 + a2)*R3 + (1 << (R_SHIFT - 1)); + c2 = (a0 - a2)*R3 + (1 << (R_SHIFT - 1)); + c1 = a1 * R1 + a3 * R2; + c3 = a1 * R2 - a3 * R1; + row[0]= (c0 + c1) >> R_SHIFT; + row[1]= (c2 + c3) >> R_SHIFT; + row[2]= (c2 - c3) >> R_SHIFT; + row[3]= (c0 - c1) >> R_SHIFT; +} + +void simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + int i; + + /* IDCT8 on each line */ + for(i=0; i<4; i++) { + idctRowCondDC(block + i*8); + } + + /* IDCT4 and store */ + for(i=0;i<8;i++) { + idct4col_add(dest + i, line_size, block + i); + } +} + +void simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + int i; + + /* IDCT4 on each line */ + for(i=0; i<8; i++) { + idct4row(block + i*8); + } + + /* IDCT8 and store */ + for(i=0; i<4; i++){ + idctSparseColAdd(dest + i, line_size, block + i); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/simple_idct.h Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,36 @@ +/* + * Simple IDCT + * + * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> + * + * 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 + */ + +/** + * @file simple_idct.h + * simple idct header. + */ + +void simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block); +void simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block); +void ff_simple_idct_mmx(int16_t *block); +void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block); +void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block); +void simple_idct(DCTELEM *block); + +void simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block); + +void simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block); +void simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/shorten/utils.c Wed Apr 05 07:50:49 2006 -0700 @@ -0,0 +1,633 @@ +/* + * utils for libavcodec + * Copyright (c) 2001 Fabrice Bellard. + * Copyright (c) 2003 Michel Bardiaux for the av_log API + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2004 Roman Bogorodskiy (bmp-wma specific stuff) + * + * 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" +#include "dsputil.h" +#include <stdarg.h> + +void *av_mallocz(unsigned int size) +{ + void *ptr; + + ptr = malloc(size); + if (!ptr) + return NULL; + + memset(ptr, 0, size); + + return ptr; +} + +/** + * realloc which does nothing if the block is large enough + */ +void *av_fast_realloc(void *ptr, int *size, unsigned int min_size) +{ + if(min_size < (unsigned int)*size) + return ptr; + + *size= min_size + 10*1024; + + return realloc(ptr, *size); +} + +/* allocation of static arrays - do not use for normal allocation */ +static unsigned int last_static = 0; +static char*** array_static = NULL; +static const unsigned int grow_static = 64; // ^2 +void *__av_mallocz_static(void** location, unsigned int size) +{ + unsigned int l = (last_static + grow_static) & ~(grow_static - 1); + void *ptr = av_mallocz(size); + if (!ptr) + return NULL; + + if (location) + { + if (l > last_static) + array_static = realloc(array_static, l); + array_static[last_static++] = (char**) location; + *location = ptr; + } + return ptr; +} +/* free all static arrays and reset pointers to 0 */ +void av_free_static(void) +{ + if (array_static) + { + unsigned i; + for (i = 0; i < last_static; i++) + { + free(*array_static[i]); + *array_static[i] = NULL; + } + free(array_static); + array_static = 0; + } + last_static = 0; +} + +/* cannot call it directly because of 'void **' casting is not automatic */ +void __av_freep(void **ptr) +{ + free(*ptr); + *ptr = NULL; +} + +/* encoder management */ +AVCodec *first_avcodec; + +void register_avcodec(AVCodec *format) +{ + AVCodec **p; + p = &first_avcodec; + while (*p != NULL) p = &(*p)->next; + *p = format; + format->next = NULL; +} + +typedef struct InternalBuffer{ + int last_pic_num; + uint8_t *base[4]; + uint8_t *data[4]; + int linesize[4]; +}InternalBuffer; + +#define INTERNAL_BUFFER_SIZE 32 + +#define ALIGN(x, a) (((x)+(a)-1)&~((a)-1)) + +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ + int w_align= 1; + int h_align= 1; + + switch(s->pix_fmt){ + case PIX_FMT_YUV420P: + case PIX_FMT_YUV422: + case PIX_FMT_YUV422P: + case PIX_FMT_YUV444P: + case PIX_FMT_GRAY8: + case PIX_FMT_YUVJ420P: + case PIX_FMT_YUVJ422P: + case PIX_FMT_YUVJ444P: + w_align= 16; //FIXME check for non mpeg style codecs and use less alignment + h_align= 16; + break; + case PIX_FMT_YUV411P: + w_align=32; + h_align=8; + break; + case PIX_FMT_YUV410P: + default: + w_align= 1; + h_align= 1; + break; + } + + *width = ALIGN(*width , w_align); + *height= ALIGN(*height, h_align); +} + +void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){ + int i; + InternalBuffer *buf, *last, temp; + + assert(pic->type==FF_BUFFER_TYPE_INTERNAL); + assert(s->internal_buffer_count); + + buf = NULL; /* avoids warning */ + for(i=0; i<s->internal_buffer_count; i++){ //just 3-5 checks so is not worth to optimize + buf= &((InternalBuffer*)s->internal_buffer)[i]; + if(buf->data[0] == pic->data[0]) + break; + } + assert(i < s->internal_buffer_count); + s->internal_buffer_count--; + last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count]; + + temp= *buf; + *buf= *last; + *last= temp; + + for(i=0; i<3; i++){ + pic->data[i]=NULL; +// pic->base[i]=NULL; + } +} + +enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, enum PixelFormat * fmt){ + return fmt[0]; +} + +void avcodec_get_context_defaults(AVCodecContext *s){ + s->bit_rate= 800*1000; + s->bit_rate_tolerance= s->bit_rate*10; + s->qmin= 2; + s->qmax= 31; + s->mb_qmin= 2; + s->mb_qmax= 31; + s->rc_eq= "tex^qComp"; + s->qcompress= 0.5; + s->max_qdiff= 3; + s->b_quant_factor=1.25; + s->b_quant_offset=1.25; + s->i_quant_factor=-0.8; + s->i_quant_offset=0.0; + s->error_concealment= 3; + s->error_resilience= 1; + s->workaround_bugs= FF_BUG_AUTODETECT; + s->frame_rate_base= 1; + s->frame_rate = 25; + s->gop_size= 50; + s->me_method= ME_EPZS; + //s->get_buffer= avcodec_default_get_buffer; + s->release_buffer= avcodec_default_release_buffer; + s->get_format= avcodec_default_get_format; + s->me_subpel_quality=8; + s->lmin= FF_QP2LAMBDA * s->qmin; + s->lmax= FF_QP2LAMBDA * s->qmax; + //s->sample_aspect_ratio= (AVRational){0,1}; + s->ildct_cmp= FF_CMP_VSAD; + + s->intra_quant_bias= FF_DEFAULT_QUANT_BIAS; + s->inter_quant_bias= FF_DEFAULT_QUANT_BIAS; + s->palctrl = NULL; + //s->reget_buffer= avcodec_default_reget_buffer; +} + +/** + * allocates a AVCodecContext and set it to defaults. + * this can be deallocated by simply calling free() + */ +AVCodecContext *avcodec_alloc_context(void){ + AVCodecContext *avctx= av_mallocz(sizeof(AVCodecContext)); + + if(avctx==NULL) return NULL; + + avcodec_get_context_defaults(avctx); + + return avctx; +} + +/** + * allocates a AVPFrame and set it to defaults. + * this can be deallocated by simply calling free() + */ +AVFrame *avcodec_alloc_frame(void){ + AVFrame *pic= av_mallocz(sizeof(AVFrame)); + + return pic; +} + +int avcodec_open(AVCodecContext *avctx, AVCodec *codec) +{ + int ret; + + if(avctx->codec) + return -1; + + avctx->codec = codec; + avctx->codec_id = codec->id; + avctx->frame_number = 0; + if (codec->priv_data_size > 0) { + avctx->priv_data = av_mallocz(codec->priv_data_size); + if (!avctx->priv_data) + return -ENOMEM; + } else { + avctx->priv_data = NULL; + } + ret = avctx->codec->init(avctx); + if (ret < 0) { + av_freep(&avctx->priv_data); + return ret; + } + return 0; +} + +int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const short *samples) +{ + int ret; + + ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples); + avctx->frame_number++; + return ret; +} + +/* decode an audio frame. return -1 if error, otherwise return the + *number of bytes used. If no frame could be decompressed, + *frame_size_ptr is zero. Otherwise, it is the decompressed frame + *size in BYTES. */ +int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + uint8_t *buf, int buf_size) +{ + int ret; + ret = avctx->codec->decode(avctx, samples, frame_size_ptr, + buf, buf_size); + avctx->frame_number++; + return ret; +} + +int avcodec_close(AVCodecContext *avctx) +{ + if (avctx->codec->close) + avctx->codec->close(avctx); + av_freep(&avctx->priv_data); + avctx->codec = NULL; + return 0; +} + +AVCodec *avcodec_find_encoder(enum CodecID id) +{ + AVCodec *p; + p = first_avcodec; + while (p) { + if (p->encode != NULL && (enum CodecID)p->id == id) + return p; + p = p->next; + } + return NULL; +} + +AVCodec *avcodec_find_encoder_by_name(const char *name) +{ + AVCodec *p; + p = first_avcodec; + while (p) { + if (p->encode != NULL && strcmp(name,p->name) == 0) + return p; + p = p->next; + } + return NULL; +} + +AVCodec *avcodec_find_decoder(enum CodecID id) +{ + AVCodec *p; + p = first_avcodec; + while (p) { + if (p->decode != NULL && (enum CodecID)p->id == id) + return p; + p = p->next; + } + return NULL; +} + +AVCodec *avcodec_find_decoder_by_name(const char *name) +{ + AVCodec *p; + p = first_avcodec; + while (p) { + if (p->decode != NULL && strcmp(name,p->name) == 0) + return p; + p = p->next; + } + return NULL; +} + +AVCodec *avcodec_find(enum CodecID id) +{ + AVCodec *p; + p = first_avcodec; + while (p) { + if ((enum CodecID)p->id == id) + return p; + p = p->next; + } + return NULL; +} + +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) +{ + const char *codec_name; + AVCodec *p; + char buf1[32]; + char channels_str[100]; + int bitrate; + + if (encode) + p = avcodec_find_encoder(enc->codec_id); + else + p = avcodec_find_decoder(enc->codec_id); + + if (p) { + codec_name = p->name; + } else if (enc->codec_name[0] != '\0') { + codec_name = enc->codec_name; + } else { + /* output avi tags */ + snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag); + codec_name = buf1; + } + + switch(enc->codec_type) { + case CODEC_TYPE_AUDIO: + snprintf(buf, buf_size, + "Audio: %s", + codec_name); + switch (enc->channels) { + case 1: + strcpy(channels_str, "mono"); + break; + case 2: + strcpy(channels_str, "stereo"); + break; + case 6: + strcpy(channels_str, "5:1"); + break; + default: + sprintf(channels_str, "%d channels", enc->channels); + break; + } + if (enc->sample_rate) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %d Hz, %s", + enc->sample_rate, + channels_str); + } + + /* for PCM codecs, compute bitrate directly */ + switch(enc->codec_id) { + case CODEC_ID_PCM_S16LE: + case CODEC_ID_PCM_S16BE: + case CODEC_ID_PCM_U16LE: + case CODEC_ID_PCM_U16BE: + bitrate = enc->sample_rate * enc->channels * 16; + break; + case CODEC_ID_PCM_S8: + case CODEC_ID_PCM_U8: + case CODEC_ID_PCM_ALAW: + case CODEC_ID_PCM_MULAW: + bitrate = enc->sample_rate * enc->channels * 8; + break; + default: + bitrate = enc->bit_rate; + break; + } + break; + case CODEC_TYPE_DATA: + snprintf(buf, buf_size, "Data: %s", codec_name); + bitrate = enc->bit_rate; + break; + default: + av_abort(); + } + if (encode) { + if (enc->flags & CODEC_FLAG_PASS1) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", pass 1"); + if (enc->flags & CODEC_FLAG_PASS2) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", pass 2"); + } + if (bitrate != 0) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %d kb/s", bitrate / 1000); + } +} + +unsigned avcodec_version( void ) +{ + return LIBAVCODEC_VERSION_INT; +} + +unsigned avcodec_build( void ) +{ + return LIBAVCODEC_BUILD; +} + +/* must be called before any other functions */ +void avcodec_init(void) +{ + static int inited = 0; + + if (inited != 0) + return; + inited = 1; + + dsputil_static_init(); +} + +/** + * Flush buffers, should be called when seeking or when swicthing to a different stream. + */ +void avcodec_flush_buffers(AVCodecContext *avctx) +{ + if(avctx->codec->flush) + avctx->codec->flush(avctx); +} + +void avcodec_default_free_buffers(AVCodecContext *s){ + int i, j; + + if(s->internal_buffer==NULL) return; + + for(i=0; i<INTERNAL_BUFFER_SIZE; i++){ + InternalBuffer *buf= &((InternalBuffer*)s->internal_buffer)[i]; + for(j=0; j<4; j++){ + av_freep(&buf->base[j]); + buf->data[j]= NULL; + } + } + av_freep(&s->internal_buffer); + + s->internal_buffer_count=0; +} +#if 0 +char av_get_pict_type_char(int pict_type){ + switch(pict_type){ + case I_TYPE: return 'I'; + case P_TYPE: return 'P'; + case B_TYPE: return 'B'; + case S_TYPE: return 'S'; + case SI_TYPE:return 'i'; + case SP_TYPE:return 'p'; + default: return '?'; + } +} + +int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ + int exact=1, sign=0; + int64_t gcd; + + assert(den != 0); + + if(den < 0){ + den= -den; + nom= -nom; + } + + if(nom < 0){ + nom= -nom; + sign= 1; + } + + gcd = ff_gcd(nom, den); + nom /= gcd; + den /= gcd; + + if(nom > max || den > max){ + AVRational a0={0,1}, a1={1,0}; + exact=0; + + for(;;){ + int64_t x= nom / den; + int64_t a2n= x*a1.num + a0.num; + int64_t a2d= x*a1.den + a0.den; + + if(a2n > max || a2d > max) break; + + nom %= den; + + a0= a1; + a1= (AVRational){a2n, a2d}; + if(nom==0) break; + x= nom; nom=den; den=x; + } + nom= a1.num; + den= a1.den; + } + + assert(ff_gcd(nom, den) == 1); + + if(sign) nom= -nom; + + *dst_nom = nom; + *dst_den = den; + + return exact; +} +#endif +int64_t av_rescale(int64_t a, int b, int c){ + uint64_t h, l; + assert(c > 0); + assert(b >=0); + + if(a<0) return -av_rescale(-a, b, c); + + h= a>>32; + if(h==0) return a*b/c; + + l= a&0xFFFFFFFF; + l *= b; + h *= b; + + l += (h%c)<<32; + + return ((h/c)<<32) + l/c; +} + +/* av_log API */ + +#ifdef AV_LOG_TRAP_PRINTF +#undef stderr +#undef fprintf +#endif + +static int av_log_level = AV_LOG_DEBUG; + +static void av_log_default_callback(AVCodecContext* avctx, int level, const char* fmt, va_list vl) +{ + static int print_prefix=1; + + if(level>av_log_level) + return; + if(avctx && print_prefix) + fprintf(stderr, "[%s @ %p]", avctx->codec ? avctx->codec->name : "?", avctx); + + print_prefix= strstr(fmt, "\n") != NULL; + + vfprintf(stderr, fmt, vl); +} + +static void (*av_log_callback)(AVCodecContext*, int, const char*, va_list) = av_log_default_callback; + +void av_log(AVCodecContext* avctx, int level, const char *fmt, ...) +{ + va_list vl; + va_start(vl, fmt); + av_vlog(avctx, level, fmt, vl); + va_end(vl); +} + +void av_vlog(AVCodecContext* avctx, int level, const char *fmt, va_list vl) +{ + av_log_callback(avctx, level, fmt, vl); +} + +int av_log_get_level(void) +{ + return av_log_level; +} + +void av_log_set_level(int level) +{ + av_log_level = level; +} + +void av_log_set_callback(void (*callback)(AVCodecContext*, int, const char*, va_list)) +{ + av_log_callback = callback; +} +