Updated WMA plug-in to latest ffmpeg, and enabled WMA Pro, WMA Voice, and WMA Lossless support

This commit is contained in:
Chris Moeller 2013-10-02 14:58:18 -07:00
parent 4c0cf34250
commit 965c6e2446
314 changed files with 95564 additions and 18484 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,49 +0,0 @@
/*
* Utils for libavcodec
* 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 allcodecs.c
* Utils for libavcodec.
*/
#include "avcodec.h"
/* If you do not call this function, then you can select exactly which
formats you want to support */
/**
* simple call to register all the codecs.
*/
void avcodec_register_all(void)
{
static int inited = 0;
if (inited != 0)
return;
inited = 1;
/* decoders */
#ifdef CONFIG_DECODERS
#ifdef CONFIG_RISKY
register_avcodec(&wmav1_decoder);
register_avcodec(&wmav2_decoder);
#endif
#endif
}

View file

@ -1,127 +0,0 @@
/*
* Register all the formats and protocols
* 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 you do not call this function, then you can select exactly which
formats you want to support */
/**
* Initialize libavcodec and register all the codecs and formats.
*/
void av_register_all(void)
{
avcodec_init();
avcodec_register_all();
//mpegps_init();
//mpegts_init();
#ifdef CONFIG_ENCODERS
crc_init();
img_init();
#endif //CONFIG_ENCODERS
//raw_init();
//mp3_init();
//rm_init();
#ifdef CONFIG_RISKY
asf_init();
#endif
#ifdef CONFIG_ENCODERS
avienc_init();
#endif //CONFIG_ENCODERS
//avidec_init();
//wav_init();
//swf_init();
//au_init();
#ifdef CONFIG_ENCODERS
gif_init();
#endif //CONFIG_ENCODERS
//mov_init();
#ifdef CONFIG_ENCODERS
movenc_init();
jpeg_init();
#endif //CONFIG_ENCODERS
//dv_init();
//fourxm_init();
#ifdef CONFIG_ENCODERS
flvenc_init();
#endif //CONFIG_ENCODERS
//flvdec_init();
//str_init();
//roq_init();
//ipmovie_init();
//wc3_init();
//westwood_init();
//film_init();
//idcin_init();
//flic_init();
//vmd_init();
#if defined(AMR_NB) || defined(AMR_NB_FIXED) || defined(AMR_WB)
amr_init();
#endif
//yuv4mpeg_init();
#ifdef CONFIG_VORBIS
ogg_init();
#endif
#ifndef CONFIG_WIN32
//ffm_init();
#endif
#ifdef CONFIG_VIDEO4LINUX
video_grab_init();
#endif
#if defined(CONFIG_AUDIO_OSS) || defined(CONFIG_AUDIO_BEOS)
audio_init();
#endif
#ifdef CONFIG_DV1394
dv1394_init();
#endif
//nut_init();
#ifdef CONFIG_ENCODERS
/* image formats */
av_register_image_format(&pnm_image_format);
av_register_image_format(&pbm_image_format);
av_register_image_format(&pgm_image_format);
av_register_image_format(&ppm_image_format);
av_register_image_format(&pam_image_format);
av_register_image_format(&pgmyuv_image_format);
av_register_image_format(&yuv_image_format);
#ifdef CONFIG_ZLIB
av_register_image_format(&png_image_format);
#endif
av_register_image_format(&jpeg_image_format);
av_register_image_format(&gif_image_format);
#endif //CONFIG_ENCODERS
/* file protocols */
register_protocol(&file_protocol);
register_protocol(&pipe_protocol);
#ifdef CONFIG_NETWORK
rtsp_init();
rtp_init();
register_protocol(&udp_protocol);
register_protocol(&rtp_protocol);
register_protocol(&tcp_protocol);
register_protocol(&http_protocol);
#endif
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,637 +0,0 @@
#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"
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);
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
time_t mktimegm(struct tm *tm);
const char *small_strptime(const char *p, const char *fmt,
struct tm *dt);
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 */

View file

@ -1,43 +0,0 @@
#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 */

View file

@ -1,191 +0,0 @@
/*
* 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 <errno.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 ((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 = av_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) {
av_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;
}
#ifdef CONFIG_ENCODERS
int url_write(URLContext *h, unsigned char *buf, int size)
{
int ret;
if (!(h->flags & (URL_WRONLY | URL_RDWR)))
return -EIO;
/* avoid sending too big packets */
if (h->max_packet_size && size > h->max_packet_size)
return -EIO;
ret = h->prot->url_write(h, buf, size);
return ret;
}
#endif //CONFIG_ENCODERS
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);
av_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;
}

View file

@ -1,169 +0,0 @@
#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

View file

@ -1,700 +0,0 @@
/*
* 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>
#include <errno.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;
}
#ifdef CONFIG_ENCODERS
static void flush_buffer(ByteIOContext *s)
{
if (s->buf_ptr > s->buffer) {
if (s->write_packet)
s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
s->pos += s->buf_ptr - s->buffer;
}
s->buf_ptr = s->buffer;
}
void put_byte(ByteIOContext *s, int b)
{
*(s->buf_ptr)++ = b;
if (s->buf_ptr >= s->buf_end)
flush_buffer(s);
}
void put_buffer(ByteIOContext *s, const unsigned char *buf, int size)
{
int len;
while (size > 0) {
len = (s->buf_end - s->buf_ptr);
if (len > size)
len = size;
memcpy(s->buf_ptr, buf, len);
s->buf_ptr += len;
if (s->buf_ptr >= s->buf_end)
flush_buffer(s);
buf += len;
size -= len;
}
}
void put_flush_packet(ByteIOContext *s)
{
flush_buffer(s);
s->must_flush = 0;
}
#endif //CONFIG_ENCODERS
offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence)
{
offset_t offset1;
if (whence != SEEK_CUR && whence != SEEK_SET)
return -EINVAL;
#ifdef CONFIG_ENCODERS
if (s->write_flag) {
if (whence == SEEK_CUR) {
offset1 = s->pos + (s->buf_ptr - s->buffer);
if (offset == 0)
return offset1;
offset += offset1;
}
offset1 = offset - s->pos;
if (!s->must_flush &&
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;
flush_buffer(s);
s->must_flush = 1;
s->buf_ptr = s->buffer;
s->seek(s->opaque, offset, SEEK_SET);
s->pos = offset;
}
} else
#endif //CONFIG_ENCODERS
{
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;
}
#ifdef CONFIG_ENCODERS
void put_le32(ByteIOContext *s, unsigned int val)
{
put_byte(s, val);
put_byte(s, val >> 8);
put_byte(s, val >> 16);
put_byte(s, val >> 24);
}
void put_be32(ByteIOContext *s, unsigned int val)
{
put_byte(s, val >> 24);
put_byte(s, val >> 16);
put_byte(s, val >> 8);
put_byte(s, val);
}
/* IEEE format is assumed */
void put_be64_double(ByteIOContext *s, double val)
{
union {
double d;
uint64_t ull;
} u;
u.d = val;
put_be64(s, u.ull);
}
void put_strz(ByteIOContext *s, const char *str)
{
if (str)
put_buffer(s, (const unsigned char *) str, strlen(str) + 1);
else
put_byte(s, 0);
}
void put_le64(ByteIOContext *s, uint64_t val)
{
put_le32(s, (uint32_t)(val & 0xffffffff));
put_le32(s, (uint32_t)(val >> 32));
}
void put_be64(ByteIOContext *s, uint64_t val)
{
put_be32(s, (uint32_t)(val >> 32));
put_be32(s, (uint32_t)(val & 0xffffffff));
}
void put_le16(ByteIOContext *s, unsigned int val)
{
put_byte(s, val);
put_byte(s, val >> 8);
}
void put_be16(ByteIOContext *s, unsigned int val)
{
put_byte(s, val >> 8);
put_byte(s, val);
}
void put_tag(ByteIOContext *s, const char *tag)
{
while (*tag) {
put_byte(s, *tag++);
}
}
#endif //CONFIG_ENCODERS
/* 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 */
#ifdef CONFIG_ENCODERS
static void url_write_packet(void *opaque, uint8_t *buf, int buf_size)
{
URLContext *h = opaque;
url_write(h, buf, buf_size);
}
#else
#define url_write_packet NULL
#endif //CONFIG_ENCODERS
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 = av_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) {
av_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 = av_malloc(buf_size);
if (!buffer)
return -ENOMEM;
av_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;
av_free(s->buffer);
memset(s, 0, sizeof(ByteIOContext));
return url_close(h);
}
URLContext *url_fileno(ByteIOContext *s)
{
return s->opaque;
}
#ifdef CONFIG_ENCODERS
/* XXX: currently size is limited */
int url_fprintf(ByteIOContext *s, const char *fmt, ...)
{
va_list ap;
char buf[4096];
int ret;
va_start(ap, fmt);
ret = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
put_buffer(s, buf, strlen(buf));
return ret;
}
#endif //CONFIG_ENCODERS
/* 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;
}
#ifdef CONFIG_ENCODERS
/* buffer handling */
int url_open_buf(ByteIOContext *s, uint8_t *buf, int buf_size, int flags)
{
return init_put_byte(s, buf, buf_size,
(flags & URL_WRONLY) != 0, NULL, NULL, NULL, NULL);
}
/* return the written or read size */
int url_close_buf(ByteIOContext *s)
{
put_flush_packet(s);
return s->buf_ptr - s->buffer;
}
/* output in a dynamic buffer */
typedef struct DynBuffer {
int pos, size, allocated_size;
uint8_t *buffer;
int io_buffer_size;
uint8_t io_buffer[1];
} DynBuffer;
static void dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
{
DynBuffer *d = opaque;
int new_size, new_allocated_size;
/* reallocate buffer if needed */
new_size = d->pos + buf_size;
new_allocated_size = d->allocated_size;
while (new_size > new_allocated_size) {
if (!new_allocated_size)
new_allocated_size = new_size;
else
new_allocated_size = (new_allocated_size * 3) / 2 + 1;
}
if (new_allocated_size > d->allocated_size) {
d->buffer = av_realloc(d->buffer, new_allocated_size);
if(d->buffer == NULL)
return ;
d->allocated_size = new_allocated_size;
}
memcpy(d->buffer + d->pos, buf, buf_size);
d->pos = new_size;
if (d->pos > d->size)
d->size = d->pos;
}
static void dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size)
{
unsigned char buf1[4];
/* packetized write: output the header */
buf1[0] = (buf_size >> 24);
buf1[1] = (buf_size >> 16);
buf1[2] = (buf_size >> 8);
buf1[3] = (buf_size);
dyn_buf_write(opaque, buf1, 4);
/* then the data */
dyn_buf_write(opaque, buf, buf_size);
}
static int dyn_buf_seek(void *opaque, offset_t offset, int whence)
{
DynBuffer *d = opaque;
if (whence == SEEK_CUR)
offset += d->pos;
else if (whence == SEEK_END)
offset += d->size;
if (offset < 0 || offset > 0x7fffffffLL)
return -1;
d->pos = offset;
return 0;
}
static int url_open_dyn_buf_internal(ByteIOContext *s, int max_packet_size)
{
DynBuffer *d;
int io_buffer_size, ret;
if (max_packet_size)
io_buffer_size = max_packet_size;
else
io_buffer_size = 1024;
d = av_malloc(sizeof(DynBuffer) + io_buffer_size);
if (!d)
return -1;
d->io_buffer_size = io_buffer_size;
d->buffer = NULL;
d->pos = 0;
d->size = 0;
d->allocated_size = 0;
ret = init_put_byte(s, d->io_buffer, io_buffer_size,
1, d, NULL,
max_packet_size ? dyn_packet_buf_write : dyn_buf_write,
max_packet_size ? NULL : dyn_buf_seek);
if (ret == 0) {
s->max_packet_size = max_packet_size;
}
return ret;
}
/*
* Open a write only memory stream.
*
* @param s new IO context
* @return zero if no error.
*/
int url_open_dyn_buf(ByteIOContext *s)
{
return url_open_dyn_buf_internal(s, 0);
}
/*
* Open a write only packetized memory stream with a maximum packet
* size of 'max_packet_size'. The stream is stored in a memory buffer
* with a big endian 4 byte header giving the packet size in bytes.
*
* @param s new IO context
* @param max_packet_size maximum packet size (must be > 0)
* @return zero if no error.
*/
int url_open_dyn_packet_buf(ByteIOContext *s, int max_packet_size)
{
if (max_packet_size <= 0)
return -1;
return url_open_dyn_buf_internal(s, max_packet_size);
}
/*
* Return the written size and a pointer to the buffer. The buffer
* must be freed with av_free().
* @param s IO context
* @param pointer to a byte buffer
* @return the length of the byte buffer
*/
int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer)
{
DynBuffer *d = s->opaque;
int size;
put_flush_packet(s);
*pbuffer = d->buffer;
size = d->size;
av_free(d);
return size;
}
#endif //CONFIG_ENCODERS

View file

@ -1,129 +0,0 @@
/**
* @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__ */

View file

@ -1,390 +0,0 @@
/*
* Common bit i/o 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
*
* 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;
#ifdef ALT_BITSTREAM_WRITER
s->index=0;
((uint32_t*)(s->buf))[0]=0;
// memset(buffer, 0, buffer_size);
#else
s->buf_ptr = s->buf;
s->bit_left=32;
s->bit_buf=0;
#endif
}
//#ifdef CONFIG_ENCODERS
#if 1
/* return the number of bits output */
int get_bit_count(PutBitContext *s)
{
#ifdef ALT_BITSTREAM_WRITER
return s->index;
#else
return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
#endif
}
void align_put_bits(PutBitContext *s)
{
#ifdef ALT_BITSTREAM_WRITER
put_bits(s,( - s->index) & 7,0);
#else
put_bits(s,s->bit_left & 7,0);
#endif
}
#endif //CONFIG_ENCODERS
/* pad the end of the output stream with zeros */
void flush_put_bits(PutBitContext *s)
{
#ifdef ALT_BITSTREAM_WRITER
align_put_bits(s);
#else
s->bit_buf<<= s->bit_left;
while (s->bit_left < 32) {
/* XXX: should test end of buffer */
*s->buf_ptr++=s->bit_buf >> 24;
s->bit_buf<<=8;
s->bit_left+=8;
}
s->bit_left=32;
s->bit_buf=0;
#endif
}
#ifdef CONFIG_ENCODERS
void put_string(PutBitContext * pbc, char *s)
{
while(*s){
put_bits(pbc, 8, *s);
s++;
}
put_bits(pbc, 8, 0);
}
/* bit input functions */
#endif //CONFIG_ENCODERS
/**
* 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 = av_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);
#ifdef DEBUG_VLC
printf("new table index=%d size=%d code_prefix=%x n=%d\n",
table_index, table_size, code_prefix, n_prefix);
#endif
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 defined(DEBUG_VLC) && 0
printf("i=%d n=%d code=0x%x\n", i, n, code);
#endif
/* 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++) {
#ifdef DEBUG_VLC
av_log(NULL, AV_LOG_DEBUG, "%4x: code=%d n=%d\n",
j, i, n);
#endif
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);
#ifdef DEBUG_VLC
printf("%4x: n=%d (subtable)\n",
j, n);
#endif
/* 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;
#ifdef DEBUG_VLC
printf("build table nb_codes=%d\n", nb_codes);
#endif
if (build_table(vlc, nb_bits, nb_codes,
bits, bits_wrap, bits_size,
codes, codes_wrap, codes_size,
0, 0) < 0) {
av_free(vlc->table);
return -1;
}
return 0;
}
void free_vlc(VLC *vlc)
{
av_free(vlc->table);
}
int64_t ff_gcd(int64_t a, int64_t b){
if(b) return ff_gcd(b, a%b);
else return a;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,26 @@
/*
* MSVC Compatible va_copy macro
* Copyright (c) 2012 Derek Buitenhuis
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdarg.h>
#if !defined(va_copy) && defined(_MSC_VER)
#define va_copy(dst, src) ((dst) = (src))
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,239 +0,0 @@
/*
* 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 = av_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;
}

File diff suppressed because it is too large Load diff

View file

@ -1,527 +0,0 @@
/*
* 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)
{
#ifdef CONFIG_WIN32
/* XXX: incorrect, but make it compile */
return (int)(x);
#else
return (int)(rint(x));
#endif
}
#endif
#endif

View file

@ -1,249 +0,0 @@
/*
* 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 = av_malloc((n / 2) * sizeof(FFTComplex));
if (!s->exptab)
goto fail;
s->revtab = av_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 = av_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);
}

View file

@ -1,132 +0,0 @@
/*
* 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 <fcntl.h>
#ifndef CONFIG_WIN32
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#else
#include <io.h>
#define open(fname,oflag,pmode) _open(fname,oflag,pmode)
#endif /* CONFIG_WIN32 */
/* 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;
}
#if defined(CONFIG_WIN32) || defined(CONFIG_OS2) || defined(__CYGWIN__)
access |= O_BINARY;
#endif
fd = open(filename, access, 0666);
if (fd < 0)
return -ENOENT;
h->priv_data = (void *)fd;
return 0;
}
static int file_read(URLContext *h, unsigned char *buf, int size)
{
int fd = (int)h->priv_data;
return read(fd, buf, size);
}
static int file_write(URLContext *h, unsigned char *buf, int size)
{
int fd = (int)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)h->priv_data;
#ifdef CONFIG_WIN32
return _lseeki64(fd, pos, whence);
#else
return lseek(fd, pos, whence);
#endif
}
static int file_close(URLContext *h)
{
int fd = (int)h->priv_data;
return close(fd);
}
URLProtocol file_protocol = {
"file",
file_open,
file_read,
file_write,
file_seek,
file_close,
};
/* 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 *)fd;
return 0;
}
static int pipe_read(URLContext *h, unsigned char *buf, int size)
{
int fd = (int)h->priv_data;
return read(fd, buf, size);
}
static int pipe_write(URLContext *h, unsigned char *buf, int size)
{
int fd = (int)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,
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,334 @@
/*
* AAC definitions and structures
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* AAC definitions and structures
* @author Oded Shimon ( ods15 ods15 dyndns org )
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
*/
#ifndef AVCODEC_AAC_H
#define AVCODEC_AAC_H
#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "fft.h"
#include "mpeg4audio.h"
#include "sbr.h"
#include "fmtconvert.h"
#include <stdint.h>
#define MAX_CHANNELS 64
#define MAX_ELEM_ID 16
#define TNS_MAX_ORDER 20
#define MAX_LTP_LONG_SFB 40
enum RawDataBlockType {
TYPE_SCE,
TYPE_CPE,
TYPE_CCE,
TYPE_LFE,
TYPE_DSE,
TYPE_PCE,
TYPE_FIL,
TYPE_END,
};
enum ExtensionPayloadID {
EXT_FILL,
EXT_FILL_DATA,
EXT_DATA_ELEMENT,
EXT_DYNAMIC_RANGE = 0xb,
EXT_SBR_DATA = 0xd,
EXT_SBR_DATA_CRC = 0xe,
};
enum WindowSequence {
ONLY_LONG_SEQUENCE,
LONG_START_SEQUENCE,
EIGHT_SHORT_SEQUENCE,
LONG_STOP_SEQUENCE,
};
enum BandType {
ZERO_BT = 0, ///< Scalefactors and spectral data are all zero.
FIRST_PAIR_BT = 5, ///< This and later band types encode two values (rather than four) with one code word.
ESC_BT = 11, ///< Spectral data are coded with an escape sequence.
NOISE_BT = 13, ///< Spectral data are scaled white noise not coded in the bitstream.
INTENSITY_BT2 = 14, ///< Scalefactor data are intensity stereo positions.
INTENSITY_BT = 15, ///< Scalefactor data are intensity stereo positions.
};
#define IS_CODEBOOK_UNSIGNED(x) ((x - 1) & 10)
enum ChannelPosition {
AAC_CHANNEL_OFF = 0,
AAC_CHANNEL_FRONT = 1,
AAC_CHANNEL_SIDE = 2,
AAC_CHANNEL_BACK = 3,
AAC_CHANNEL_LFE = 4,
AAC_CHANNEL_CC = 5,
};
/**
* The point during decoding at which channel coupling is applied.
*/
enum CouplingPoint {
BEFORE_TNS,
BETWEEN_TNS_AND_IMDCT,
AFTER_IMDCT = 3,
};
/**
* Output configuration status
*/
enum OCStatus {
OC_NONE, ///< Output unconfigured
OC_TRIAL_PCE, ///< Output configuration under trial specified by an inband PCE
OC_TRIAL_FRAME, ///< Output configuration under trial specified by a frame header
OC_GLOBAL_HDR, ///< Output configuration set in a global header but not yet locked
OC_LOCKED, ///< Output configuration locked in place
};
typedef struct OutputConfiguration {
MPEG4AudioConfig m4ac;
uint8_t layout_map[MAX_ELEM_ID*4][3];
int layout_map_tags;
int channels;
uint64_t channel_layout;
enum OCStatus status;
} OutputConfiguration;
/**
* Predictor State
*/
typedef struct PredictorState {
float cor0;
float cor1;
float var0;
float var1;
float r0;
float r1;
} PredictorState;
#define MAX_PREDICTORS 672
#define SCALE_DIV_512 36 ///< scalefactor difference that corresponds to scale difference in 512 times
#define SCALE_ONE_POS 140 ///< scalefactor index that corresponds to scale=1.0
#define SCALE_MAX_POS 255 ///< scalefactor index maximum value
#define SCALE_MAX_DIFF 60 ///< maximum scalefactor difference allowed by standard
#define SCALE_DIFF_ZERO 60 ///< codebook index corresponding to zero scalefactor indices difference
/**
* Long Term Prediction
*/
typedef struct LongTermPrediction {
int8_t present;
int16_t lag;
float coef;
int8_t used[MAX_LTP_LONG_SFB];
} LongTermPrediction;
/**
* Individual Channel Stream
*/
typedef struct IndividualChannelStream {
uint8_t max_sfb; ///< number of scalefactor bands per group
enum WindowSequence window_sequence[2];
uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sine window.
int num_window_groups;
uint8_t group_len[8];
LongTermPrediction ltp;
const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window
const uint8_t *swb_sizes; ///< table of scalefactor band sizes for a particular window
int num_swb; ///< number of scalefactor window bands
int num_windows;
int tns_max_bands;
int predictor_present;
int predictor_initialized;
int predictor_reset_group;
uint8_t prediction_used[41];
} IndividualChannelStream;
/**
* Temporal Noise Shaping
*/
typedef struct TemporalNoiseShaping {
int present;
int n_filt[8];
int length[8][4];
int direction[8][4];
int order[8][4];
float coef[8][4][TNS_MAX_ORDER];
} TemporalNoiseShaping;
/**
* Dynamic Range Control - decoded from the bitstream but not processed further.
*/
typedef struct DynamicRangeControl {
int pce_instance_tag; ///< Indicates with which program the DRC info is associated.
int dyn_rng_sgn[17]; ///< DRC sign information; 0 - positive, 1 - negative
int dyn_rng_ctl[17]; ///< DRC magnitude information
int exclude_mask[MAX_CHANNELS]; ///< Channels to be excluded from DRC processing.
int band_incr; ///< Number of DRC bands greater than 1 having DRC info.
int interpolation_scheme; ///< Indicates the interpolation scheme used in the SBR QMF domain.
int band_top[17]; ///< Indicates the top of the i-th DRC band in units of 4 spectral lines.
int prog_ref_level; /**< A reference level for the long-term program audio level for all
* channels combined.
*/
} DynamicRangeControl;
typedef struct Pulse {
int num_pulse;
int start;
int pos[4];
int amp[4];
} Pulse;
/**
* coupling parameters
*/
typedef struct ChannelCoupling {
enum CouplingPoint coupling_point; ///< The point during decoding at which coupling is applied.
int num_coupled; ///< number of target elements
enum RawDataBlockType type[8]; ///< Type of channel element to be coupled - SCE or CPE.
int id_select[8]; ///< element id
int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for right channel;
* [2] list of gains for left channel; [3] lists of gains for both channels
*/
float gain[16][120];
} ChannelCoupling;
/**
* Single Channel Element - used for both SCE and LFE elements.
*/
typedef struct SingleChannelElement {
IndividualChannelStream ics;
TemporalNoiseShaping tns;
Pulse pulse;
enum BandType band_type[128]; ///< band types
int band_type_run_end[120]; ///< band type run end points
float sf[120]; ///< scalefactors
int sf_idx[128]; ///< scalefactor indices (used by encoder)
uint8_t zeroes[128]; ///< band is not coded (used by encoder)
DECLARE_ALIGNED(32, float, coeffs)[1024]; ///< coefficients for IMDCT
DECLARE_ALIGNED(32, float, saved)[1024]; ///< overlap
DECLARE_ALIGNED(32, float, ret_buf)[2048]; ///< PCM output buffer
DECLARE_ALIGNED(16, float, ltp_state)[3072]; ///< time signal for LTP
PredictorState predictor_state[MAX_PREDICTORS];
float *ret; ///< PCM output
} SingleChannelElement;
/**
* channel element - generic struct for SCE/CPE/CCE/LFE
*/
typedef struct ChannelElement {
// CPE specific
int common_window; ///< Set if channels share a common 'IndividualChannelStream' in bitstream.
int ms_mode; ///< Signals mid/side stereo flags coding mode (used by encoder)
uint8_t ms_mask[128]; ///< Set if mid/side stereo is used for each scalefactor window band
// shared
SingleChannelElement ch[2];
// CCE specific
ChannelCoupling coup;
SpectralBandReplication sbr;
} ChannelElement;
/**
* main AAC context
*/
struct AACContext {
AVClass *class;
AVCodecContext *avctx;
AVFrame *frame;
int is_saved; ///< Set if elements have stored overlap from previous frame.
DynamicRangeControl che_drc;
/**
* @name Channel element related data
* @{
*/
ChannelElement *che[4][MAX_ELEM_ID];
ChannelElement *tag_che_map[4][MAX_ELEM_ID];
int tags_mapped;
/** @} */
/**
* @name temporary aligned temporary buffers
* (We do not want to have these on the stack.)
* @{
*/
DECLARE_ALIGNED(32, float, buf_mdct)[1024];
/** @} */
/**
* @name Computed / set up during initialization
* @{
*/
FFTContext mdct;
FFTContext mdct_small;
FFTContext mdct_ld;
FFTContext mdct_ltp;
FmtConvertContext fmt_conv;
AVFloatDSPContext fdsp;
int random_state;
/** @} */
/**
* @name Members used for output
* @{
*/
SingleChannelElement *output_element[MAX_CHANNELS]; ///< Points to each SingleChannelElement
/** @} */
/**
* @name Japanese DTV specific extension
* @{
*/
int force_dmono_mode;///< 0->not dmono, 1->use first channel, 2->use second channel
int dmono_mode; ///< 0->not dmono, 1->use first channel, 2->use second channel
/** @} */
DECLARE_ALIGNED(32, float, temp)[128];
OutputConfiguration oc[2];
int warned_num_aac_frames;
/* aacdec functions pointers */
void (*imdct_and_windowing)(AACContext *ac, SingleChannelElement *sce);
void (*apply_ltp)(AACContext *ac, SingleChannelElement *sce);
void (*apply_tns)(float coef[1024], TemporalNoiseShaping *tns,
IndividualChannelStream *ics, int decode);
void (*windowing_and_mdct_ltp)(AACContext *ac, float *out,
float *in, IndividualChannelStream *ics);
void (*update_ltp)(AACContext *ac, SingleChannelElement *sce);
};
void ff_aacdec_init_mips(AACContext *c);
#endif /* AVCODEC_AAC_H */

View file

@ -0,0 +1,42 @@
/*
* Header file for hardcoded AAC tables
*
* Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_AAC_TABLEGEN_H
#define AVCODEC_AAC_TABLEGEN_H
#include "aac_tablegen_decl.h"
#if CONFIG_HARDCODED_TABLES
#include "libavcodec/aac_tables.h"
#else
#include "libavutil/mathematics.h"
float ff_aac_pow2sf_tab[428];
void ff_aac_tableinit(void)
{
int i;
for (i = 0; i < 428; i++)
ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0);
}
#endif /* CONFIG_HARDCODED_TABLES */
#endif /* AVCODEC_AAC_TABLEGEN_H */

View file

@ -0,0 +1,36 @@
/*
* Header file for hardcoded AAC tables
*
* Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_AAC_TABLEGEN_DECL_H
#define AVCODEC_AAC_TABLEGEN_DECL_H
#define POW_SF2_ZERO 200 ///< ff_aac_pow2sf_tab index corresponding to pow(2, 0);
#if CONFIG_HARDCODED_TABLES
#define ff_aac_tableinit()
extern const float ff_aac_pow2sf_tab[428];
#else
void ff_aac_tableinit(void);
extern float ff_aac_pow2sf_tab[428];
#endif /* CONFIG_HARDCODED_TABLES */
#endif /* AVCODEC_AAC_TABLEGEN_DECL_H */

View file

@ -0,0 +1,84 @@
/*
* MPEG-4 Parametric Stereo definitions and declarations
* Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_PS_H
#define AVCODEC_PS_H
#include <stdint.h>
#include "aacpsdsp.h"
#include "avcodec.h"
#include "get_bits.h"
#define PS_MAX_NUM_ENV 5
#define PS_MAX_NR_IIDICC 34
#define PS_MAX_NR_IPDOPD 17
#define PS_MAX_SSB 91
#define PS_MAX_AP_BANDS 50
#define PS_QMF_TIME_SLOTS 32
#define PS_MAX_DELAY 14
#define PS_AP_LINKS 3
#define PS_MAX_AP_DELAY 5
typedef struct PSContext {
int start;
int enable_iid;
int iid_quant;
int nr_iid_par;
int nr_ipdopd_par;
int enable_icc;
int icc_mode;
int nr_icc_par;
int enable_ext;
int frame_class;
int num_env_old;
int num_env;
int enable_ipdopd;
int border_position[PS_MAX_NUM_ENV+1];
int8_t iid_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Inter-channel Intensity Difference Parameters
int8_t icc_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Inter-Channel Coherence Parameters
/* ipd/opd is iid/icc sized so that the same functions can handle both */
int8_t ipd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Inter-channel Phase Difference Parameters
int8_t opd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Overall Phase Difference Parameters
int is34bands;
int is34bands_old;
DECLARE_ALIGNED(16, float, in_buf)[5][44][2];
DECLARE_ALIGNED(16, float, delay)[PS_MAX_SSB][PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2];
DECLARE_ALIGNED(16, float, ap_delay)[PS_MAX_AP_BANDS][PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2];
DECLARE_ALIGNED(16, float, peak_decay_nrg)[34];
DECLARE_ALIGNED(16, float, power_smooth)[34];
DECLARE_ALIGNED(16, float, peak_decay_diff_smooth)[34];
DECLARE_ALIGNED(16, float, H11)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
DECLARE_ALIGNED(16, float, H12)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
DECLARE_ALIGNED(16, float, H21)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
DECLARE_ALIGNED(16, float, H22)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
int8_t opd_hist[PS_MAX_NR_IIDICC];
int8_t ipd_hist[PS_MAX_NR_IIDICC];
PSDSPContext dsp;
} PSContext;
void ff_ps_init(void);
void ff_ps_ctx_init(PSContext *ps);
int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb, PSContext *ps, int bits_left);
int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float R[2][38][64], int top);
#endif /* AVCODEC_PS_H */

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2012 Mans Rullgard
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBAVCODEC_AACPSDSP_H
#define LIBAVCODEC_AACPSDSP_H
#define PS_QMF_TIME_SLOTS 32
#define PS_AP_LINKS 3
#define PS_MAX_AP_DELAY 5
typedef struct PSDSPContext {
void (*add_squares)(float *dst, const float (*src)[2], int n);
void (*mul_pair_single)(float (*dst)[2], float (*src0)[2], float *src1,
int n);
void (*hybrid_analysis)(float (*out)[2], float (*in)[2],
const float (*filter)[8][2],
int stride, int n);
void (*hybrid_analysis_ileave)(float (*out)[32][2], float L[2][38][64],
int i, int len);
void (*hybrid_synthesis_deint)(float out[2][38][64], float (*in)[32][2],
int i, int len);
void (*decorrelate)(float (*out)[2], float (*delay)[2],
float (*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2],
const float phi_fract[2], float (*Q_fract)[2],
const float *transient_gain,
float g_decay_slope,
int len);
void (*stereo_interpolate[2])(float (*l)[2], float (*r)[2],
float h[2][4], float h_step[2][4],
int len);
} PSDSPContext;
void ff_psdsp_init(PSDSPContext *s);
void ff_psdsp_init_arm(PSDSPContext *s);
void ff_psdsp_init_mips(PSDSPContext *s);
#endif /* LIBAVCODEC_AACPSDSP_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,80 @@
/*
* AAC data declarations
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* AAC data declarations
* @author Oded Shimon ( ods15 ods15 dyndns org )
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
*/
#ifndef AVCODEC_AACTAB_H
#define AVCODEC_AACTAB_H
#include "libavutil/mem.h"
#include "aac.h"
#include "aac_tablegen_decl.h"
#include <stdint.h>
/* NOTE:
* Tables in this file are used by the AAC decoder and will be used by the AAC
* encoder.
*/
/* @name window coefficients
* @{
*/
DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_1024)[1024];
DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_512 )[512];
DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128];
// @}
/* @name number of scalefactor window bands for long and short transform windows respectively
* @{
*/
extern const uint8_t ff_aac_num_swb_1024[];
extern const uint8_t ff_aac_num_swb_512 [];
extern const uint8_t ff_aac_num_swb_128 [];
// @}
extern const uint8_t ff_aac_pred_sfb_max [];
extern const uint32_t ff_aac_scalefactor_code[121];
extern const uint8_t ff_aac_scalefactor_bits[121];
extern const uint16_t * const ff_aac_spectral_codes[11];
extern const uint8_t * const ff_aac_spectral_bits [11];
extern const uint16_t ff_aac_spectral_sizes[11];
extern const float *ff_aac_codebook_vectors[];
extern const float *ff_aac_codebook_vector_vals[];
extern const uint16_t *ff_aac_codebook_vector_idx[];
extern const uint16_t * const ff_swb_offset_1024[13];
extern const uint16_t * const ff_swb_offset_512 [13];
extern const uint16_t * const ff_swb_offset_128 [13];
extern const uint8_t ff_tns_max_bands_1024[13];
extern const uint8_t ff_tns_max_bands_128 [13];
#endif /* AVCODEC_AACTAB_H */

View file

@ -0,0 +1,157 @@
/*
* various filters for ACELP-based codecs
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include "config.h"
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "avcodec.h"
#include "acelp_filters.h"
const int16_t ff_acelp_interp_filter[61] = { /* (0.15) */
29443, 28346, 25207, 20449, 14701, 8693,
3143, -1352, -4402, -5865, -5850, -4673,
-2783, -672, 1211, 2536, 3130, 2991,
2259, 1170, 0, -1001, -1652, -1868,
-1666, -1147, -464, 218, 756, 1060,
1099, 904, 550, 135, -245, -514,
-634, -602, -451, -231, 0, 191,
308, 340, 296, 198, 78, -36,
-120, -163, -165, -132, -79, -19,
34, 73, 91, 89, 70, 38,
0,
};
void ff_acelp_interpolate(int16_t* out, const int16_t* in,
const int16_t* filter_coeffs, int precision,
int frac_pos, int filter_length, int length)
{
int n, i;
av_assert1(frac_pos >= 0 && frac_pos < precision);
for (n = 0; n < length; n++) {
int idx = 0;
int v = 0x4000;
for (i = 0; i < filter_length;) {
/* The reference G.729 and AMR fixed point code performs clipping after
each of the two following accumulations.
Since clipping affects only the synthetic OVERFLOW test without
causing an int type overflow, it was moved outside the loop. */
/* R(x):=ac_v[-k+x]
v += R(n-i)*ff_acelp_interp_filter(t+6i)
v += R(n+i+1)*ff_acelp_interp_filter(6-t+6i) */
v += in[n + i] * filter_coeffs[idx + frac_pos];
idx += precision;
i++;
v += in[n - i] * filter_coeffs[idx - frac_pos];
}
if (av_clip_int16(v >> 15) != (v >> 15))
av_log(NULL, AV_LOG_WARNING, "overflow that would need cliping in ff_acelp_interpolate()\n");
out[n] = v >> 15;
}
}
void ff_acelp_interpolatef(float *out, const float *in,
const float *filter_coeffs, int precision,
int frac_pos, int filter_length, int length)
{
int n, i;
for (n = 0; n < length; n++) {
int idx = 0;
float v = 0;
for (i = 0; i < filter_length;) {
v += in[n + i] * filter_coeffs[idx + frac_pos];
idx += precision;
i++;
v += in[n - i] * filter_coeffs[idx - frac_pos];
}
out[n] = v;
}
}
void ff_acelp_high_pass_filter(int16_t* out, int hpf_f[2],
const int16_t* in, int length)
{
int i;
int tmp;
for (i = 0; i < length; i++) {
tmp = (hpf_f[0]* 15836LL) >> 13;
tmp += (hpf_f[1]* -7667LL) >> 13;
tmp += 7699 * (in[i] - 2*in[i-1] + in[i-2]);
/* With "+0x800" rounding, clipping is needed
for ALGTHM and SPEECH tests. */
out[i] = av_clip_int16((tmp + 0x800) >> 12);
hpf_f[1] = hpf_f[0];
hpf_f[0] = tmp;
}
}
void ff_acelp_apply_order_2_transfer_function(float *out, const float *in,
const float zero_coeffs[2],
const float pole_coeffs[2],
float gain, float mem[2], int n)
{
int i;
float tmp;
for (i = 0; i < n; i++) {
tmp = gain * in[i] - pole_coeffs[0] * mem[0] - pole_coeffs[1] * mem[1];
out[i] = tmp + zero_coeffs[0] * mem[0] + zero_coeffs[1] * mem[1];
mem[1] = mem[0];
mem[0] = tmp;
}
}
void ff_tilt_compensation(float *mem, float tilt, float *samples, int size)
{
float new_tilt_mem = samples[size - 1];
int i;
for (i = size - 1; i > 0; i--)
samples[i] -= tilt * samples[i - 1];
samples[0] -= tilt * *mem;
*mem = new_tilt_mem;
}
void ff_acelp_filter_init(ACELPFContext *c)
{
c->acelp_interpolatef = ff_acelp_interpolatef;
c->acelp_apply_order_2_transfer_function = ff_acelp_apply_order_2_transfer_function;
if(HAVE_MIPSFPU)
ff_acelp_filter_init_mips(c);
}

View file

@ -0,0 +1,153 @@
/*
* various filters for ACELP-based codecs
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_ACELP_FILTERS_H
#define AVCODEC_ACELP_FILTERS_H
#include <stdint.h>
typedef struct ACELPFContext {
/**
* Floating point version of ff_acelp_interpolate()
*/
void (*acelp_interpolatef)(float *out, const float *in,
const float *filter_coeffs, int precision,
int frac_pos, int filter_length, int length);
/**
* Apply an order 2 rational transfer function in-place.
*
* @param out output buffer for filtered speech samples
* @param in input buffer containing speech data (may be the same as out)
* @param zero_coeffs z^-1 and z^-2 coefficients of the numerator
* @param pole_coeffs z^-1 and z^-2 coefficients of the denominator
* @param gain scale factor for final output
* @param mem intermediate values used by filter (should be 0 initially)
* @param n number of samples (should be a multiple of eight)
*/
void (*acelp_apply_order_2_transfer_function)(float *out, const float *in,
const float zero_coeffs[2],
const float pole_coeffs[2],
float gain,
float mem[2], int n);
}ACELPFContext;
/**
* Initialize ACELPFContext.
*/
void ff_acelp_filter_init(ACELPFContext *c);
void ff_acelp_filter_init_mips(ACELPFContext *c);
/**
* low-pass Finite Impulse Response filter coefficients.
*
* Hamming windowed sinc filter with cutoff freq 3/40 of the sampling freq,
* the coefficients are scaled by 2^15.
* This array only contains the right half of the filter.
* This filter is likely identical to the one used in G.729, though this
* could not be determined from the original comments with certainty.
*/
extern const int16_t ff_acelp_interp_filter[61];
/**
* Generic FIR interpolation routine.
* @param[out] out buffer for interpolated data
* @param in input data
* @param filter_coeffs interpolation filter coefficients (0.15)
* @param precision sub sample factor, that is the precision of the position
* @param frac_pos fractional part of position [0..precision-1]
* @param filter_length filter length
* @param length length of output
*
* filter_coeffs contains coefficients of the right half of the symmetric
* interpolation filter. filter_coeffs[0] should the central (unpaired) coefficient.
* See ff_acelp_interp_filter for an example.
*
*/
void ff_acelp_interpolate(int16_t* out, const int16_t* in,
const int16_t* filter_coeffs, int precision,
int frac_pos, int filter_length, int length);
/**
* Floating point version of ff_acelp_interpolate()
*/
void ff_acelp_interpolatef(float *out, const float *in,
const float *filter_coeffs, int precision,
int frac_pos, int filter_length, int length);
/**
* high-pass filtering and upscaling (4.2.5 of G.729).
* @param[out] out output buffer for filtered speech data
* @param[in,out] hpf_f past filtered data from previous (2 items long)
* frames (-0x20000000 <= (14.13) < 0x20000000)
* @param in speech data to process
* @param length input data size
*
* out[i] = 0.93980581 * in[i] - 1.8795834 * in[i-1] + 0.93980581 * in[i-2] +
* 1.9330735 * out[i-1] - 0.93589199 * out[i-2]
*
* The filter has a cut-off frequency of 1/80 of the sampling freq
*
* @note Two items before the top of the in buffer must contain two items from the
* tail of the previous subframe.
*
* @remark It is safe to pass the same array in in and out parameters.
*
* @remark AMR uses mostly the same filter (cut-off frequency 60Hz, same formula,
* but constants differs in 5th sign after comma). Fortunately in
* fixed-point all coefficients are the same as in G.729. Thus this
* routine can be used for the fixed-point AMR decoder, too.
*/
void ff_acelp_high_pass_filter(int16_t* out, int hpf_f[2],
const int16_t* in, int length);
/**
* Apply an order 2 rational transfer function in-place.
*
* @param out output buffer for filtered speech samples
* @param in input buffer containing speech data (may be the same as out)
* @param zero_coeffs z^-1 and z^-2 coefficients of the numerator
* @param pole_coeffs z^-1 and z^-2 coefficients of the denominator
* @param gain scale factor for final output
* @param mem intermediate values used by filter (should be 0 initially)
* @param n number of samples
*/
void ff_acelp_apply_order_2_transfer_function(float *out, const float *in,
const float zero_coeffs[2],
const float pole_coeffs[2],
float gain,
float mem[2], int n);
/**
* Apply tilt compensation filter, 1 - tilt * z-1.
*
* @param mem pointer to the filter's state (one single float)
* @param tilt tilt factor
* @param samples array where the filter is applied
* @param size the size of the samples array
*/
void ff_tilt_compensation(float *mem, float tilt, float *samples, int size);
#endif /* AVCODEC_ACELP_FILTERS_H */

View file

@ -0,0 +1,189 @@
/*
* gain code, gain pitch and pitch delay decoding
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/common.h"
#include "libavutil/float_dsp.h"
#include "libavutil/libm.h"
#include "libavutil/mathematics.h"
#include "avcodec.h"
#include "acelp_pitch_delay.h"
#include "celp_math.h"
int ff_acelp_decode_8bit_to_1st_delay3(int ac_index)
{
ac_index += 58;
if(ac_index > 254)
ac_index = 3 * ac_index - 510;
return ac_index;
}
int ff_acelp_decode_4bit_to_2nd_delay3(
int ac_index,
int pitch_delay_min)
{
if(ac_index < 4)
return 3 * (ac_index + pitch_delay_min);
else if(ac_index < 12)
return 3 * pitch_delay_min + ac_index + 6;
else
return 3 * (ac_index + pitch_delay_min) - 18;
}
int ff_acelp_decode_5_6_bit_to_2nd_delay3(
int ac_index,
int pitch_delay_min)
{
return 3 * pitch_delay_min + ac_index - 2;
}
int ff_acelp_decode_9bit_to_1st_delay6(int ac_index)
{
if(ac_index < 463)
return ac_index + 105;
else
return 6 * (ac_index - 368);
}
int ff_acelp_decode_6bit_to_2nd_delay6(
int ac_index,
int pitch_delay_min)
{
return 6 * pitch_delay_min + ac_index - 3;
}
void ff_acelp_update_past_gain(
int16_t* quant_energy,
int gain_corr_factor,
int log2_ma_pred_order,
int erasure)
{
int i;
int avg_gain=quant_energy[(1 << log2_ma_pred_order) - 1]; // (5.10)
for(i=(1 << log2_ma_pred_order) - 1; i>0; i--)
{
avg_gain += quant_energy[i-1];
quant_energy[i] = quant_energy[i-1];
}
if(erasure)
quant_energy[0] = FFMAX(avg_gain >> log2_ma_pred_order, -10240) - 4096; // -10 and -4 in (5.10)
else
quant_energy[0] = (6165 * ((ff_log2_q15(gain_corr_factor) >> 2) - (13 << 13))) >> 13;
}
int16_t ff_acelp_decode_gain_code(
DSPContext *dsp,
int gain_corr_factor,
const int16_t* fc_v,
int mr_energy,
const int16_t* quant_energy,
const int16_t* ma_prediction_coeff,
int subframe_size,
int ma_pred_order)
{
int i;
mr_energy <<= 10;
for(i=0; i<ma_pred_order; i++)
mr_energy += quant_energy[i] * ma_prediction_coeff[i];
#ifdef G729_BITEXACT
mr_energy += (((-6165LL * ff_log2(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size, 0))) >> 3) & ~0x3ff);
mr_energy = (5439 * (mr_energy >> 15)) >> 8; // (0.15) = (0.15) * (7.23)
return bidir_sal(
((ff_exp2(mr_energy & 0x7fff) + 16) >> 5) * (gain_corr_factor >> 1),
(mr_energy >> 15) - 25
);
#else
mr_energy = gain_corr_factor * exp(M_LN10 / (20 << 23) * mr_energy) /
sqrt(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size));
return mr_energy >> 12;
#endif
}
float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy,
float *prediction_error, float energy_mean,
const float *pred_table)
{
// Equations 66-69:
// ^g_c = ^gamma_gc * 100.05 (predicted dB + mean dB - dB of fixed vector)
// Note 10^(0.05 * -10log(average x2)) = 1/sqrt((average x2)).
float val = fixed_gain_factor *
exp2f(M_LOG2_10 * 0.05 *
(avpriv_scalarproduct_float_c(pred_table, prediction_error, 4) +
energy_mean)) /
sqrtf(fixed_mean_energy);
// update quantified prediction error energy history
memmove(&prediction_error[0], &prediction_error[1],
3 * sizeof(prediction_error[0]));
prediction_error[3] = 20.0 * log10f(fixed_gain_factor);
return val;
}
void ff_decode_pitch_lag(int *lag_int, int *lag_frac, int pitch_index,
const int prev_lag_int, const int subframe,
int third_as_first, int resolution)
{
/* Note n * 10923 >> 15 is floor(x/3) for 0 <= n <= 32767 */
if (subframe == 0 || (subframe == 2 && third_as_first)) {
if (pitch_index < 197)
pitch_index += 59;
else
pitch_index = 3 * pitch_index - 335;
} else {
if (resolution == 4) {
int search_range_min = av_clip(prev_lag_int - 5, PITCH_DELAY_MIN,
PITCH_DELAY_MAX - 9);
// decoding with 4-bit resolution
if (pitch_index < 4) {
// integer only precision for [search_range_min, search_range_min+3]
pitch_index = 3 * (pitch_index + search_range_min) + 1;
} else if (pitch_index < 12) {
// 1/3 fractional precision for [search_range_min+3 1/3, search_range_min+5 2/3]
pitch_index += 3 * search_range_min + 7;
} else {
// integer only precision for [search_range_min+6, search_range_min+9]
pitch_index = 3 * (pitch_index + search_range_min - 6) + 1;
}
} else {
// decoding with 5 or 6 bit resolution, 1/3 fractional precision
pitch_index--;
if (resolution == 5) {
pitch_index += 3 * av_clip(prev_lag_int - 10, PITCH_DELAY_MIN,
PITCH_DELAY_MAX - 19);
} else
pitch_index += 3 * av_clip(prev_lag_int - 5, PITCH_DELAY_MIN,
PITCH_DELAY_MAX - 9);
}
}
*lag_int = pitch_index * 10923 >> 15;
*lag_frac = pitch_index - 3 * *lag_int - 1;
}

View file

@ -0,0 +1,252 @@
/*
* gain code, gain pitch and pitch delay decoding
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_ACELP_PITCH_DELAY_H
#define AVCODEC_ACELP_PITCH_DELAY_H
#include <stdint.h>
#include "dsputil.h"
#define PITCH_DELAY_MIN 20
#define PITCH_DELAY_MAX 143
/**
* @brief Decode pitch delay of the first subframe encoded by 8 bits with 1/3
* resolution.
* @param ac_index adaptive codebook index (8 bits)
*
* @return pitch delay in 1/3 units
*
* Pitch delay is coded:
* with 1/3 resolution, 19 < pitch_delay < 85
* integers only, 85 <= pitch_delay <= 143
*/
int ff_acelp_decode_8bit_to_1st_delay3(int ac_index);
/**
* @brief Decode pitch delay of the second subframe encoded by 5 or 6 bits
* with 1/3 precision.
* @param ac_index adaptive codebook index (5 or 6 bits)
* @param pitch_delay_min lower bound (integer) of pitch delay interval
* for second subframe
*
* @return pitch delay in 1/3 units
*
* Pitch delay is coded:
* with 1/3 resolution, -6 < pitch_delay - int(prev_pitch_delay) < 5
*
* @remark The routine is used in G.729 @@8k, AMR @@10.2k, AMR @@7.95k,
* AMR @@7.4k for the second subframe.
*/
int ff_acelp_decode_5_6_bit_to_2nd_delay3(
int ac_index,
int pitch_delay_min);
/**
* @brief Decode pitch delay with 1/3 precision.
* @param ac_index adaptive codebook index (4 bits)
* @param pitch_delay_min lower bound (integer) of pitch delay interval for
* second subframe
*
* @return pitch delay in 1/3 units
*
* Pitch delay is coded:
* integers only, -6 < pitch_delay - int(prev_pitch_delay) <= -2
* with 1/3 resolution, -2 < pitch_delay - int(prev_pitch_delay) < 1
* integers only, 1 <= pitch_delay - int(prev_pitch_delay) < 5
*
* @remark The routine is used in G.729 @@6.4k, AMR @@6.7k, AMR @@5.9k,
* AMR @@5.15k, AMR @@4.75k for the second subframe.
*/
int ff_acelp_decode_4bit_to_2nd_delay3(
int ac_index,
int pitch_delay_min);
/**
* @brief Decode pitch delay of the first subframe encoded by 9 bits
* with 1/6 precision.
* @param ac_index adaptive codebook index (9 bits)
*
* @return pitch delay in 1/6 units
*
* Pitch delay is coded:
* with 1/6 resolution, 17 < pitch_delay < 95
* integers only, 95 <= pitch_delay <= 143
*
* @remark The routine is used in AMR @@12.2k for the first and third subframes.
*/
int ff_acelp_decode_9bit_to_1st_delay6(int ac_index);
/**
* @brief Decode pitch delay of the second subframe encoded by 6 bits
* with 1/6 precision.
* @param ac_index adaptive codebook index (6 bits)
* @param pitch_delay_min lower bound (integer) of pitch delay interval for
* second subframe
*
* @return pitch delay in 1/6 units
*
* Pitch delay is coded:
* with 1/6 resolution, -6 < pitch_delay - int(prev_pitch_delay) < 5
*
* @remark The routine is used in AMR @@12.2k for the second and fourth subframes.
*/
int ff_acelp_decode_6bit_to_2nd_delay6(
int ac_index,
int pitch_delay_min);
/**
* @brief Update past quantized energies
* @param[in,out] quant_energy past quantized energies (5.10)
* @param gain_corr_factor gain correction factor
* @param log2_ma_pred_order log2() of MA prediction order
* @param erasure frame erasure flag
*
* If frame erasure flag is not equal to zero, memory is updated with
* averaged energy, attenuated by 4dB:
* max(avg(quant_energy[i])-4, -14), i=0,ma_pred_order
*
* In normal mode memory is updated with
* Er - Ep = 20 * log10(gain_corr_factor)
*
* @remark The routine is used in G.729 and AMR (all modes).
*/
void ff_acelp_update_past_gain(
int16_t* quant_energy,
int gain_corr_factor,
int log2_ma_pred_order,
int erasure);
/**
* @brief Decode the adaptive codebook gain and add
* correction (4.1.5 and 3.9.1 of G.729).
* @param dsp initialized dsputil context
* @param gain_corr_factor gain correction factor (2.13)
* @param fc_v fixed-codebook vector (2.13)
* @param mr_energy mean innovation energy and fixed-point correction (7.13)
* @param[in,out] quant_energy past quantized energies (5.10)
* @param subframe_size length of subframe
*
* @return quantized fixed-codebook gain (14.1)
*
* The routine implements equations 69, 66 and 71 of the G.729 specification (3.9.1)
*
* Em - mean innovation energy (dB, constant, depends on decoding algorithm)
* Ep - mean-removed predicted energy (dB)
* Er - mean-removed innovation energy (dB)
* Ei - mean energy of the fixed-codebook contribution (dB)
* N - subframe_size
* M - MA (Moving Average) prediction order
* gc - fixed-codebook gain
* gc_p - predicted fixed-codebook gain
*
* Fixed codebook gain is computed using predicted gain gc_p and
* correction factor gain_corr_factor as shown below:
*
* gc = gc_p * gain_corr_factor
*
* The predicted fixed codebook gain gc_p is found by predicting
* the energy of the fixed-codebook contribution from the energy
* of previous fixed-codebook contributions.
*
* mean = 1/N * sum(i,0,N){ fc_v[i] * fc_v[i] }
*
* Ei = 10log(mean)
*
* Er = 10log(1/N * gc^2 * mean) - Em = 20log(gc) + Ei - Em
*
* Replacing Er with Ep and gc with gc_p we will receive:
*
* Ep = 10log(1/N * gc_p^2 * mean) - Em = 20log(gc_p) + Ei - Em
*
* and from above:
*
* gc_p = 10^((Ep - Ei + Em) / 20)
*
* Ep is predicted using past energies and prediction coefficients:
*
* Ep = sum(i,0,M){ ma_prediction_coeff[i] * quant_energy[i] }
*
* gc_p in fixed-point arithmetic is calculated as following:
*
* mean = 1/N * sum(i,0,N){ (fc_v[i] / 2^13) * (fc_v[i] / 2^13) } =
* = 1/N * sum(i,0,N) { fc_v[i] * fc_v[i] } / 2^26
*
* Ei = 10log(mean) = -10log(N) - 10log(2^26) +
* + 10log(sum(i,0,N) { fc_v[i] * fc_v[i] })
*
* Ep - Ei + Em = Ep + Em + 10log(N) + 10log(2^26) -
* - 10log(sum(i,0,N) { fc_v[i] * fc_v[i] }) =
* = Ep + mr_energy - 10log(sum(i,0,N) { fc_v[i] * fc_v[i] })
*
* gc_p = 10 ^ ((Ep - Ei + Em) / 20) =
* = 2 ^ (3.3219 * (Ep - Ei + Em) / 20) = 2 ^ (0.166 * (Ep - Ei + Em))
*
* where
*
* mr_energy = Em + 10log(N) + 10log(2^26)
*
* @remark The routine is used in G.729 and AMR (all modes).
*/
int16_t ff_acelp_decode_gain_code(
DSPContext *dsp,
int gain_corr_factor,
const int16_t* fc_v,
int mr_energy,
const int16_t* quant_energy,
const int16_t* ma_prediction_coeff,
int subframe_size,
int max_pred_order);
/**
* Calculate fixed gain (part of section 6.1.3 of AMR spec)
*
* @param fixed_gain_factor gain correction factor
* @param fixed_mean_energy mean decoded algebraic codebook vector energy
* @param prediction_error vector of the quantified predictor errors of
* the four previous subframes. It is updated by this function.
* @param energy_mean desired mean innovation energy
* @param pred_table table of four moving average coefficients
*/
float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy,
float *prediction_error, float energy_mean,
const float *pred_table);
/**
* Decode the adaptive codebook index to the integer and fractional parts
* of the pitch lag for one subframe at 1/3 fractional precision.
*
* The choice of pitch lag is described in 3GPP TS 26.090 section 5.6.1.
*
* @param lag_int integer part of pitch lag of the current subframe
* @param lag_frac fractional part of pitch lag of the current subframe
* @param pitch_index parsed adaptive codebook (pitch) index
* @param prev_lag_int integer part of pitch lag for the previous subframe
* @param subframe current subframe number
* @param third_as_first treat the third frame the same way as the first
*/
void ff_decode_pitch_lag(int *lag_int, int *lag_frac, int pitch_index,
const int prev_lag_int, const int subframe,
int third_as_first, int resolution);
#endif /* AVCODEC_ACELP_PITCH_DELAY_H */

View file

@ -0,0 +1,272 @@
/*
* adaptive and fixed codebook vector operations for ACELP-based codecs
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include "libavutil/common.h"
#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "acelp_vectors.h"
const uint8_t ff_fc_2pulses_9bits_track1[16] =
{
1, 3,
6, 8,
11, 13,
16, 18,
21, 23,
26, 28,
31, 33,
36, 38
};
const uint8_t ff_fc_2pulses_9bits_track1_gray[16] =
{
1, 3,
8, 6,
18, 16,
11, 13,
38, 36,
31, 33,
21, 23,
28, 26,
};
const uint8_t ff_fc_2pulses_9bits_track2_gray[32] =
{
0, 2,
5, 4,
12, 10,
7, 9,
25, 24,
20, 22,
14, 15,
19, 17,
36, 31,
21, 26,
1, 6,
16, 11,
27, 29,
32, 30,
39, 37,
34, 35,
};
const uint8_t ff_fc_4pulses_8bits_tracks_13[16] =
{
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
};
const uint8_t ff_fc_4pulses_8bits_track_4[32] =
{
3, 4,
8, 9,
13, 14,
18, 19,
23, 24,
28, 29,
33, 34,
38, 39,
43, 44,
48, 49,
53, 54,
58, 59,
63, 64,
68, 69,
73, 74,
78, 79,
};
const float ff_pow_0_7[10] = {
0.700000, 0.490000, 0.343000, 0.240100, 0.168070,
0.117649, 0.082354, 0.057648, 0.040354, 0.028248
};
const float ff_pow_0_75[10] = {
0.750000, 0.562500, 0.421875, 0.316406, 0.237305,
0.177979, 0.133484, 0.100113, 0.075085, 0.056314
};
const float ff_pow_0_55[10] = {
0.550000, 0.302500, 0.166375, 0.091506, 0.050328,
0.027681, 0.015224, 0.008373, 0.004605, 0.002533
};
const float ff_b60_sinc[61] = {
0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 ,
0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 ,
-0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 ,
0.0689392 , 0.0357056 , 0.0 , -0.0305481 , -0.0504150 , -0.0570068 ,
-0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 ,
0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 ,
-0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0.0 , 0.00582886 ,
0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 ,
-0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 ,
0.
};
void ff_acelp_fc_pulse_per_track(
int16_t* fc_v,
const uint8_t *tab1,
const uint8_t *tab2,
int pulse_indexes,
int pulse_signs,
int pulse_count,
int bits)
{
int mask = (1 << bits) - 1;
int i;
for(i=0; i<pulse_count; i++)
{
fc_v[i + tab1[pulse_indexes & mask]] +=
(pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
pulse_indexes >>= bits;
pulse_signs >>= 1;
}
fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192;
}
void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
AMRFixed *fixed_sparse,
const uint8_t *gray_decode,
int half_pulse_count, int bits)
{
int i;
int mask = (1 << bits) - 1;
fixed_sparse->no_repeat_mask = 0;
fixed_sparse->n = 2 * half_pulse_count;
for (i = 0; i < half_pulse_count; i++) {
const int pos1 = gray_decode[fixed_index[2*i+1] & mask] + i;
const int pos2 = gray_decode[fixed_index[2*i ] & mask] + i;
const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0;
fixed_sparse->x[2*i+1] = pos1;
fixed_sparse->x[2*i ] = pos2;
fixed_sparse->y[2*i+1] = sign;
fixed_sparse->y[2*i ] = pos2 < pos1 ? -sign : sign;
}
}
void ff_acelp_weighted_vector_sum(
int16_t* out,
const int16_t *in_a,
const int16_t *in_b,
int16_t weight_coeff_a,
int16_t weight_coeff_b,
int16_t rounder,
int shift,
int length)
{
int i;
// Clipping required here; breaks OVERFLOW test.
for(i=0; i<length; i++)
out[i] = av_clip_int16((
in_a[i] * weight_coeff_a +
in_b[i] * weight_coeff_b +
rounder) >> shift);
}
void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
float weight_coeff_a, float weight_coeff_b, int length)
{
int i;
for(i=0; i<length; i++)
out[i] = weight_coeff_a * in_a[i]
+ weight_coeff_b * in_b[i];
}
void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
int size, float alpha, float *gain_mem)
{
int i;
float postfilter_energ = avpriv_scalarproduct_float_c(in, in, size);
float gain_scale_factor = 1.0;
float mem = *gain_mem;
if (postfilter_energ)
gain_scale_factor = sqrt(speech_energ / postfilter_energ);
gain_scale_factor *= 1.0 - alpha;
for (i = 0; i < size; i++) {
mem = alpha * mem + gain_scale_factor;
out[i] = in[i] * mem;
}
*gain_mem = mem;
}
void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
float sum_of_squares, const int n)
{
int i;
float scalefactor = avpriv_scalarproduct_float_c(in, in, n);
if (scalefactor)
scalefactor = sqrt(sum_of_squares / scalefactor);
for (i = 0; i < n; i++)
out[i] = in[i] * scalefactor;
}
void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
{
int i;
for (i=0; i < in->n; i++) {
int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
float y = in->y[i] * scale;
if (in->pitch_lag > 0)
do {
out[x] += y;
y *= in->pitch_fac;
x += in->pitch_lag;
} while (x < size && repeats);
}
}
void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
{
int i;
for (i=0; i < in->n; i++) {
int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
if (in->pitch_lag > 0)
do {
out[x] = 0.0;
x += in->pitch_lag;
} while (x < size && repeats);
}
}
void ff_acelp_vectors_init(ACELPVContext *c)
{
c->weighted_vector_sumf = ff_weighted_vector_sumf;
if(HAVE_MIPSFPU)
ff_acelp_vectors_init_mips(c);
}

View file

@ -0,0 +1,288 @@
/*
* adaptive and fixed codebook vector operations for ACELP-based codecs
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_ACELP_VECTORS_H
#define AVCODEC_ACELP_VECTORS_H
#include <stdint.h>
typedef struct ACELPVContext {
/**
* float implementation of weighted sum of two vectors.
* @param[out] out result of addition
* @param in_a first vector
* @param in_b second vector
* @param weight_coeff_a first vector weight coefficient
* @param weight_coeff_a second vector weight coefficient
* @param length vectors length (should be a multiple of two)
*
* @note It is safe to pass the same buffer for out and in_a or in_b.
*/
void (*weighted_vector_sumf)(float *out, const float *in_a, const float *in_b,
float weight_coeff_a, float weight_coeff_b,
int length);
}ACELPVContext;
/**
* Initialize ACELPVContext.
*/
void ff_acelp_vectors_init(ACELPVContext *c);
void ff_acelp_vectors_init_mips(ACELPVContext *c);
/** Sparse representation for the algebraic codebook (fixed) vector */
typedef struct AMRFixed {
int n;
int x[10];
float y[10];
int no_repeat_mask;
int pitch_lag;
float pitch_fac;
} AMRFixed;
/**
* Track|Pulse| Positions
* -------------------------------------------------------------------------
* 1 | 0 | 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75
* -------------------------------------------------------------------------
* 2 | 1 | 1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76
* -------------------------------------------------------------------------
* 3 | 2 | 2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77
* -------------------------------------------------------------------------
*
* Table contains only first the pulse indexes.
*
* Used in G.729 @@8k, G.729 @@4.4k, AMR @@7.95k, AMR @@7.40k
*/
extern const uint8_t ff_fc_4pulses_8bits_tracks_13[16];
/**
* Track|Pulse| Positions
* -------------------------------------------------------------------------
* 4 | 3 | 3, 8, 13, 18, 23, 28, 33, 38, 43, 48, 53, 58, 63, 68, 73, 78
* | | 4, 9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64, 69, 74, 79
* -------------------------------------------------------------------------
*
* @remark Track in the table should be read top-to-bottom, left-to-right.
*
* Used in G.729 @@8k, G.729 @@4.4k, AMR @@7.95k, AMR @@7.40k
*/
extern const uint8_t ff_fc_4pulses_8bits_track_4[32];
/**
* Track|Pulse| Positions
* -----------------------------------------
* 1 | 0 | 1, 6, 11, 16, 21, 26, 31, 36
* | | 3, 8, 13, 18, 23, 28, 33, 38
* -----------------------------------------
*
* @remark Track in the table should be read top-to-bottom, left-to-right.
*
* @note (EE) Reference G.729D code also uses gray decoding for each
* pulse index before looking up the value in the table.
*
* Used in G.729 @@6.4k (with gray coding), AMR @@5.9k (without gray coding)
*/
extern const uint8_t ff_fc_2pulses_9bits_track1[16];
extern const uint8_t ff_fc_2pulses_9bits_track1_gray[16];
/**
* Track|Pulse| Positions
* -----------------------------------------
* 2 | 1 | 0, 7, 14, 20, 27, 34, 1, 21
* | | 2, 9, 15, 22, 29, 35, 6, 26
* | | 4,10, 17, 24, 30, 37, 11, 31
* | | 5,12, 19, 25, 32, 39, 16, 36
* -----------------------------------------
*
* @remark Track in the table should be read top-to-bottom, left-to-right.
*
* @note (EE.1) This table (from the reference code) does not comply with
* the specification.
* The specification contains the following table:
*
* Track|Pulse| Positions
* -----------------------------------------
* 2 | 1 | 0, 5, 10, 15, 20, 25, 30, 35
* | | 1, 6, 11, 16, 21, 26, 31, 36
* | | 2, 7, 12, 17, 22, 27, 32, 37
* | | 4, 9, 14, 19, 24, 29, 34, 39
*
* -----------------------------------------
*
* @note (EE.2) Reference G.729D code also uses gray decoding for each
* pulse index before looking up the value in the table.
*
* Used in G.729 @@6.4k (with gray coding)
*/
extern const uint8_t ff_fc_2pulses_9bits_track2_gray[32];
/**
* b60 hamming windowed sinc function coefficients
*/
extern const float ff_b60_sinc[61];
/**
* Table of pow(0.7,n)
*/
extern const float ff_pow_0_7[10];
/**
* Table of pow(0.75,n)
*/
extern const float ff_pow_0_75[10];
/**
* Table of pow(0.55,n)
*/
extern const float ff_pow_0_55[10];
/**
* Decode fixed-codebook vector (3.8 and D.5.8 of G.729, 5.7.1 of AMR).
* @param[out] fc_v decoded fixed codebook vector (2.13)
* @param tab1 table used for first pulse_count pulses
* @param tab2 table used for last pulse
* @param pulse_indexes fixed codebook indexes
* @param pulse_signs signs of the excitation pulses (0 bit value
* means negative sign)
* @param bits number of bits per one pulse index
* @param pulse_count number of pulses decoded using first table
* @param bits length of one pulse index in bits
*
* Used in G.729 @@8k, G.729 @@4.4k, G.729 @@6.4k, AMR @@7.95k, AMR @@7.40k
*/
void ff_acelp_fc_pulse_per_track(int16_t* fc_v,
const uint8_t *tab1,
const uint8_t *tab2,
int pulse_indexes,
int pulse_signs,
int pulse_count,
int bits);
/**
* Decode the algebraic codebook index to pulse positions and signs and
* construct the algebraic codebook vector for MODE_12k2.
*
* @note: The positions and signs are explicitly coded in MODE_12k2.
*
* @param fixed_index positions of the ten pulses
* @param fixed_sparse pointer to the algebraic codebook vector
* @param gray_decode gray decoding table
* @param half_pulse_count number of couples of pulses
* @param bits length of one pulse index in bits
*/
void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
AMRFixed *fixed_sparse,
const uint8_t *gray_decode,
int half_pulse_count, int bits);
/**
* weighted sum of two vectors with rounding.
* @param[out] out result of addition
* @param in_a first vector
* @param in_b second vector
* @param weight_coeff_a first vector weight coefficient
* @param weight_coeff_a second vector weight coefficient
* @param rounder this value will be added to the sum of the two vectors
* @param shift result will be shifted to right by this value
* @param length vectors length
*
* @note It is safe to pass the same buffer for out and in_a or in_b.
*
* out[i] = (in_a[i]*weight_a + in_b[i]*weight_b + rounder) >> shift
*/
void ff_acelp_weighted_vector_sum(int16_t* out,
const int16_t *in_a,
const int16_t *in_b,
int16_t weight_coeff_a,
int16_t weight_coeff_b,
int16_t rounder,
int shift,
int length);
/**
* float implementation of weighted sum of two vectors.
* @param[out] out result of addition
* @param in_a first vector
* @param in_b second vector
* @param weight_coeff_a first vector weight coefficient
* @param weight_coeff_a second vector weight coefficient
* @param length vectors length
*
* @note It is safe to pass the same buffer for out and in_a or in_b.
*/
void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
float weight_coeff_a, float weight_coeff_b,
int length);
/**
* Adaptive gain control (as used in AMR postfiltering)
*
* @param out output buffer for filtered speech data
* @param in the input speech buffer (may be the same as out)
* @param speech_energ input energy
* @param size the input buffer size
* @param alpha exponential filter factor
* @param gain_mem a pointer to the filter memory (single float of size)
*/
void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
int size, float alpha, float *gain_mem);
/**
* Set the sum of squares of a signal by scaling
*
* @param out output samples
* @param in input samples
* @param sum_of_squares new sum of squares
* @param n number of samples
*
* @note If the input is zero (or its energy underflows), the output is zero.
* This is the behavior of AGC in the AMR reference decoder. The QCELP
* reference decoder seems to have undefined behavior.
*
* TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6
* 3GPP TS 26.090 6.1 (6)
*/
void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
float sum_of_squares, const int n);
/**
* Add fixed vector to an array from a sparse representation
*
* @param out fixed vector with pitch sharpening
* @param in sparse fixed vector
* @param scale number to multiply the fixed vector by
* @param size the output vector size
*/
void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size);
/**
* Clear array values set by set_fixed_vector
*
* @param out fixed vector to be cleared
* @param in sparse fixed vector
* @param size the output vector size
*/
void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size);
#endif /* AVCODEC_ACELP_VECTORS_H */

View file

@ -0,0 +1,564 @@
/*
* Provide registration of all codecs, parsers and bitstream filters for libavcodec.
* Copyright (c) 2002 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Provide registration of all codecs, parsers and bitstream filters for libavcodec.
*/
#include "avcodec.h"
#include "config.h"
#define REGISTER_HWACCEL(X, x) \
{ \
extern AVHWAccel ff_##x##_hwaccel; \
if (CONFIG_##X##_HWACCEL) \
av_register_hwaccel(&ff_##x##_hwaccel); \
}
#define REGISTER_ENCODER(X, x) \
{ \
extern AVCodec ff_##x##_encoder; \
if (CONFIG_##X##_ENCODER) \
avcodec_register(&ff_##x##_encoder); \
}
#define REGISTER_DECODER(X, x) \
{ \
extern AVCodec ff_##x##_decoder; \
if (CONFIG_##X##_DECODER) \
avcodec_register(&ff_##x##_decoder); \
}
#define REGISTER_ENCDEC(X, x) REGISTER_ENCODER(X, x); REGISTER_DECODER(X, x)
#define REGISTER_PARSER(X, x) \
{ \
extern AVCodecParser ff_##x##_parser; \
if (CONFIG_##X##_PARSER) \
av_register_codec_parser(&ff_##x##_parser); \
}
#define REGISTER_BSF(X, x) \
{ \
extern AVBitStreamFilter ff_##x##_bsf; \
if (CONFIG_##X##_BSF) \
av_register_bitstream_filter(&ff_##x##_bsf); \
}
void avcodec_register_all(void)
{
static int initialized;
if (initialized)
return;
initialized = 1;
/* hardware accelerators */
REGISTER_HWACCEL(H263_VAAPI, h263_vaapi);
REGISTER_HWACCEL(H263_VDPAU, h263_vdpau);
REGISTER_HWACCEL(H264_DXVA2, h264_dxva2);
REGISTER_HWACCEL(H264_VAAPI, h264_vaapi);
REGISTER_HWACCEL(H264_VDA, h264_vda);
REGISTER_HWACCEL(H264_VDPAU, h264_vdpau);
REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau);
REGISTER_HWACCEL(MPEG2_DXVA2, mpeg2_dxva2);
REGISTER_HWACCEL(MPEG2_VAAPI, mpeg2_vaapi);
REGISTER_HWACCEL(MPEG2_VDPAU, mpeg2_vdpau);
REGISTER_HWACCEL(MPEG4_VAAPI, mpeg4_vaapi);
REGISTER_HWACCEL(MPEG4_VDPAU, mpeg4_vdpau);
REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2);
REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi);
REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau);
REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2);
REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi);
REGISTER_HWACCEL(WMV3_VDPAU, wmv3_vdpau);
/* video codecs */
REGISTER_ENCODER(A64MULTI, a64multi);
REGISTER_ENCODER(A64MULTI5, a64multi5);
REGISTER_DECODER(AASC, aasc);
REGISTER_DECODER(AIC, aic);
REGISTER_ENCDEC (AMV, amv);
REGISTER_DECODER(ANM, anm);
REGISTER_DECODER(ANSI, ansi);
REGISTER_ENCDEC (ASV1, asv1);
REGISTER_ENCDEC (ASV2, asv2);
REGISTER_DECODER(AURA, aura);
REGISTER_DECODER(AURA2, aura2);
REGISTER_ENCDEC (AVRP, avrp);
REGISTER_DECODER(AVRN, avrn);
REGISTER_DECODER(AVS, avs);
REGISTER_ENCDEC (AVUI, avui);
REGISTER_ENCDEC (AYUV, ayuv);
REGISTER_DECODER(BETHSOFTVID, bethsoftvid);
REGISTER_DECODER(BFI, bfi);
REGISTER_DECODER(BINK, bink);
REGISTER_ENCDEC (BMP, bmp);
REGISTER_DECODER(BMV_VIDEO, bmv_video);
REGISTER_DECODER(BRENDER_PIX, brender_pix);
REGISTER_DECODER(C93, c93);
REGISTER_DECODER(CAVS, cavs);
REGISTER_DECODER(CDGRAPHICS, cdgraphics);
REGISTER_DECODER(CDXL, cdxl);
REGISTER_DECODER(CINEPAK, cinepak);
REGISTER_ENCDEC (CLJR, cljr);
REGISTER_DECODER(CLLC, cllc);
REGISTER_ENCDEC (COMFORTNOISE, comfortnoise);
REGISTER_DECODER(CPIA, cpia);
REGISTER_DECODER(CSCD, cscd);
REGISTER_DECODER(CYUV, cyuv);
REGISTER_DECODER(DFA, dfa);
REGISTER_DECODER(DIRAC, dirac);
REGISTER_ENCDEC (DNXHD, dnxhd);
REGISTER_ENCDEC (DPX, dpx);
REGISTER_DECODER(DSICINVIDEO, dsicinvideo);
REGISTER_ENCDEC (DVVIDEO, dvvideo);
REGISTER_DECODER(DXA, dxa);
REGISTER_DECODER(DXTORY, dxtory);
REGISTER_DECODER(EACMV, eacmv);
REGISTER_DECODER(EAMAD, eamad);
REGISTER_DECODER(EATGQ, eatgq);
REGISTER_DECODER(EATGV, eatgv);
REGISTER_DECODER(EATQI, eatqi);
REGISTER_DECODER(EIGHTBPS, eightbps);
REGISTER_DECODER(EIGHTSVX_EXP, eightsvx_exp);
REGISTER_DECODER(EIGHTSVX_FIB, eightsvx_fib);
REGISTER_DECODER(ESCAPE124, escape124);
REGISTER_DECODER(ESCAPE130, escape130);
REGISTER_DECODER(EXR, exr);
REGISTER_ENCDEC (FFV1, ffv1);
REGISTER_ENCDEC (FFVHUFF, ffvhuff);
REGISTER_ENCDEC (FLASHSV, flashsv);
REGISTER_ENCDEC (FLASHSV2, flashsv2);
REGISTER_DECODER(FLIC, flic);
REGISTER_ENCDEC (FLV, flv);
REGISTER_DECODER(FOURXM, fourxm);
REGISTER_DECODER(FRAPS, fraps);
REGISTER_DECODER(FRWU, frwu);
REGISTER_DECODER(G2M, g2m);
REGISTER_ENCDEC (GIF, gif);
REGISTER_ENCDEC (H261, h261);
REGISTER_ENCDEC (H263, h263);
REGISTER_DECODER(H263I, h263i);
REGISTER_ENCDEC (H263P, h263p);
REGISTER_DECODER(H264, h264);
REGISTER_DECODER(H264_CRYSTALHD, h264_crystalhd);
REGISTER_DECODER(H264_VDA, h264_vda);
REGISTER_DECODER(H264_VDPAU, h264_vdpau);
REGISTER_ENCDEC (HUFFYUV, huffyuv);
REGISTER_DECODER(IDCIN, idcin);
REGISTER_DECODER(IFF_BYTERUN1, iff_byterun1);
REGISTER_DECODER(IFF_ILBM, iff_ilbm);
REGISTER_DECODER(INDEO2, indeo2);
REGISTER_DECODER(INDEO3, indeo3);
REGISTER_DECODER(INDEO4, indeo4);
REGISTER_DECODER(INDEO5, indeo5);
REGISTER_DECODER(INTERPLAY_VIDEO, interplay_video);
REGISTER_ENCDEC (JPEG2000, jpeg2000);
REGISTER_ENCDEC (JPEGLS, jpegls);
REGISTER_DECODER(JV, jv);
REGISTER_DECODER(KGV1, kgv1);
REGISTER_DECODER(KMVC, kmvc);
REGISTER_DECODER(LAGARITH, lagarith);
REGISTER_ENCODER(LJPEG, ljpeg);
REGISTER_DECODER(LOCO, loco);
REGISTER_DECODER(MDEC, mdec);
REGISTER_DECODER(MIMIC, mimic);
REGISTER_ENCDEC (MJPEG, mjpeg);
REGISTER_DECODER(MJPEGB, mjpegb);
REGISTER_DECODER(MMVIDEO, mmvideo);
REGISTER_DECODER(MOTIONPIXELS, motionpixels);
REGISTER_DECODER(MPEG_XVMC, mpeg_xvmc);
REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video);
REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video);
REGISTER_ENCDEC (MPEG4, mpeg4);
REGISTER_DECODER(MPEG4_CRYSTALHD, mpeg4_crystalhd);
REGISTER_DECODER(MPEG4_VDPAU, mpeg4_vdpau);
REGISTER_DECODER(MPEGVIDEO, mpegvideo);
REGISTER_DECODER(MPEG_VDPAU, mpeg_vdpau);
REGISTER_DECODER(MPEG1_VDPAU, mpeg1_vdpau);
REGISTER_DECODER(MPEG2_CRYSTALHD, mpeg2_crystalhd);
REGISTER_DECODER(MSA1, msa1);
REGISTER_DECODER(MSMPEG4_CRYSTALHD, msmpeg4_crystalhd);
REGISTER_DECODER(MSMPEG4V1, msmpeg4v1);
REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2);
REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3);
REGISTER_DECODER(MSRLE, msrle);
REGISTER_DECODER(MSS1, mss1);
REGISTER_DECODER(MSS2, mss2);
REGISTER_ENCDEC (MSVIDEO1, msvideo1);
REGISTER_DECODER(MSZH, mszh);
REGISTER_DECODER(MTS2, mts2);
REGISTER_DECODER(MVC1, mvc1);
REGISTER_DECODER(MVC2, mvc2);
REGISTER_DECODER(MXPEG, mxpeg);
REGISTER_DECODER(NUV, nuv);
REGISTER_DECODER(PAF_VIDEO, paf_video);
REGISTER_ENCDEC (PAM, pam);
REGISTER_ENCDEC (PBM, pbm);
REGISTER_ENCDEC (PCX, pcx);
REGISTER_ENCDEC (PGM, pgm);
REGISTER_ENCDEC (PGMYUV, pgmyuv);
REGISTER_DECODER(PICTOR, pictor);
REGISTER_ENCDEC (PNG, png);
REGISTER_ENCDEC (PPM, ppm);
REGISTER_ENCDEC (PRORES, prores);
REGISTER_ENCODER(PRORES_AW, prores_aw);
REGISTER_ENCODER(PRORES_KS, prores_ks);
REGISTER_DECODER(PRORES_LGPL, prores_lgpl);
REGISTER_DECODER(PTX, ptx);
REGISTER_DECODER(QDRAW, qdraw);
REGISTER_DECODER(QPEG, qpeg);
REGISTER_ENCDEC (QTRLE, qtrle);
REGISTER_ENCDEC (R10K, r10k);
REGISTER_ENCDEC (R210, r210);
REGISTER_ENCDEC (RAWVIDEO, rawvideo);
REGISTER_DECODER(RL2, rl2);
REGISTER_ENCDEC (ROQ, roq);
REGISTER_DECODER(RPZA, rpza);
REGISTER_ENCDEC (RV10, rv10);
REGISTER_ENCDEC (RV20, rv20);
REGISTER_DECODER(RV30, rv30);
REGISTER_DECODER(RV40, rv40);
REGISTER_ENCDEC (S302M, s302m);
REGISTER_DECODER(SANM, sanm);
REGISTER_ENCDEC (SGI, sgi);
REGISTER_DECODER(SGIRLE, sgirle);
REGISTER_DECODER(SMACKER, smacker);
REGISTER_DECODER(SMC, smc);
REGISTER_DECODER(SMVJPEG, smvjpeg);
REGISTER_ENCDEC (SNOW, snow);
REGISTER_DECODER(SP5X, sp5x);
REGISTER_ENCDEC (SUNRAST, sunrast);
REGISTER_ENCDEC (SVQ1, svq1);
REGISTER_DECODER(SVQ3, svq3);
REGISTER_ENCDEC (TARGA, targa);
REGISTER_DECODER(TARGA_Y216, targa_y216);
REGISTER_DECODER(THEORA, theora);
REGISTER_DECODER(THP, thp);
REGISTER_DECODER(TIERTEXSEQVIDEO, tiertexseqvideo);
REGISTER_ENCDEC (TIFF, tiff);
REGISTER_DECODER(TMV, tmv);
REGISTER_DECODER(TRUEMOTION1, truemotion1);
REGISTER_DECODER(TRUEMOTION2, truemotion2);
REGISTER_DECODER(TSCC, tscc);
REGISTER_DECODER(TSCC2, tscc2);
REGISTER_DECODER(TXD, txd);
REGISTER_DECODER(ULTI, ulti);
REGISTER_ENCDEC (UTVIDEO, utvideo);
REGISTER_ENCDEC (V210, v210);
REGISTER_DECODER(V210X, v210x);
REGISTER_ENCDEC (V308, v308);
REGISTER_ENCDEC (V408, v408);
REGISTER_ENCDEC (V410, v410);
REGISTER_DECODER(VB, vb);
REGISTER_DECODER(VBLE, vble);
REGISTER_DECODER(VC1, vc1);
REGISTER_DECODER(VC1_CRYSTALHD, vc1_crystalhd);
REGISTER_DECODER(VC1_VDPAU, vc1_vdpau);
REGISTER_DECODER(VC1IMAGE, vc1image);
REGISTER_DECODER(VCR1, vcr1);
REGISTER_DECODER(VMDVIDEO, vmdvideo);
REGISTER_DECODER(VMNC, vmnc);
REGISTER_DECODER(VP3, vp3);
REGISTER_DECODER(VP5, vp5);
REGISTER_DECODER(VP6, vp6);
REGISTER_DECODER(VP6A, vp6a);
REGISTER_DECODER(VP6F, vp6f);
REGISTER_DECODER(VP8, vp8);
REGISTER_DECODER(VQA, vqa);
REGISTER_DECODER(WEBP, webp);
REGISTER_ENCDEC (WMV1, wmv1);
REGISTER_ENCDEC (WMV2, wmv2);
REGISTER_DECODER(WMV3, wmv3);
REGISTER_DECODER(WMV3_CRYSTALHD, wmv3_crystalhd);
REGISTER_DECODER(WMV3_VDPAU, wmv3_vdpau);
REGISTER_DECODER(WMV3IMAGE, wmv3image);
REGISTER_DECODER(WNV1, wnv1);
REGISTER_DECODER(XAN_WC3, xan_wc3);
REGISTER_DECODER(XAN_WC4, xan_wc4);
REGISTER_ENCDEC (XBM, xbm);
REGISTER_ENCDEC (XFACE, xface);
REGISTER_DECODER(XL, xl);
REGISTER_ENCDEC (XWD, xwd);
REGISTER_ENCDEC (Y41P, y41p);
REGISTER_DECODER(YOP, yop);
REGISTER_ENCDEC (YUV4, yuv4);
REGISTER_DECODER(ZERO12V, zero12v);
REGISTER_DECODER(ZEROCODEC, zerocodec);
REGISTER_ENCDEC (ZLIB, zlib);
REGISTER_ENCDEC (ZMBV, zmbv);
/* audio codecs */
REGISTER_ENCDEC (AAC, aac);
REGISTER_DECODER(AAC_LATM, aac_latm);
REGISTER_ENCDEC (AC3, ac3);
REGISTER_ENCODER(AC3_FIXED, ac3_fixed);
REGISTER_ENCDEC (ALAC, alac);
REGISTER_DECODER(ALS, als);
REGISTER_DECODER(AMRNB, amrnb);
REGISTER_DECODER(AMRWB, amrwb);
REGISTER_DECODER(APE, ape);
REGISTER_DECODER(ATRAC1, atrac1);
REGISTER_DECODER(ATRAC3, atrac3);
REGISTER_DECODER(BINKAUDIO_DCT, binkaudio_dct);
REGISTER_DECODER(BINKAUDIO_RDFT, binkaudio_rdft);
REGISTER_DECODER(BMV_AUDIO, bmv_audio);
REGISTER_DECODER(COOK, cook);
REGISTER_ENCDEC (DCA, dca);
REGISTER_DECODER(DSICINAUDIO, dsicinaudio);
REGISTER_ENCDEC (EAC3, eac3);
REGISTER_DECODER(EVRC, evrc);
REGISTER_DECODER(FFWAVESYNTH, ffwavesynth);
REGISTER_ENCDEC (FLAC, flac);
REGISTER_ENCDEC (G723_1, g723_1);
REGISTER_DECODER(G729, g729);
REGISTER_DECODER(GSM, gsm);
REGISTER_DECODER(GSM_MS, gsm_ms);
REGISTER_DECODER(IAC, iac);
REGISTER_DECODER(IMC, imc);
REGISTER_DECODER(MACE3, mace3);
REGISTER_DECODER(MACE6, mace6);
REGISTER_DECODER(METASOUND, metasound);
REGISTER_DECODER(MLP, mlp);
REGISTER_DECODER(MP1, mp1);
REGISTER_DECODER(MP1FLOAT, mp1float);
REGISTER_ENCDEC (MP2, mp2);
REGISTER_DECODER(MP2FLOAT, mp2float);
REGISTER_DECODER(MP3, mp3);
REGISTER_DECODER(MP3FLOAT, mp3float);
REGISTER_DECODER(MP3ADU, mp3adu);
REGISTER_DECODER(MP3ADUFLOAT, mp3adufloat);
REGISTER_DECODER(MP3ON4, mp3on4);
REGISTER_DECODER(MP3ON4FLOAT, mp3on4float);
REGISTER_DECODER(MPC7, mpc7);
REGISTER_DECODER(MPC8, mpc8);
REGISTER_ENCDEC (NELLYMOSER, nellymoser);
REGISTER_DECODER(PAF_AUDIO, paf_audio);
REGISTER_DECODER(QCELP, qcelp);
REGISTER_DECODER(QDM2, qdm2);
REGISTER_ENCDEC (RA_144, ra_144);
REGISTER_DECODER(RA_288, ra_288);
REGISTER_DECODER(RALF, ralf);
REGISTER_DECODER(SHORTEN, shorten);
REGISTER_DECODER(SIPR, sipr);
REGISTER_DECODER(SMACKAUD, smackaud);
REGISTER_ENCDEC (SONIC, sonic);
REGISTER_ENCODER(SONIC_LS, sonic_ls);
REGISTER_DECODER(TAK, tak);
REGISTER_DECODER(TRUEHD, truehd);
REGISTER_DECODER(TRUESPEECH, truespeech);
REGISTER_ENCDEC (TTA, tta);
REGISTER_DECODER(TWINVQ, twinvq);
REGISTER_DECODER(VMDAUDIO, vmdaudio);
REGISTER_ENCDEC (VORBIS, vorbis);
REGISTER_ENCDEC (WAVPACK, wavpack);
REGISTER_DECODER(WMALOSSLESS, wmalossless);
REGISTER_DECODER(WMAPRO, wmapro);
REGISTER_ENCDEC (WMAV1, wmav1);
REGISTER_ENCDEC (WMAV2, wmav2);
REGISTER_DECODER(WMAVOICE, wmavoice);
REGISTER_DECODER(WS_SND1, ws_snd1);
/* PCM codecs */
REGISTER_ENCDEC (PCM_ALAW, pcm_alaw);
REGISTER_DECODER(PCM_BLURAY, pcm_bluray);
REGISTER_DECODER(PCM_DVD, pcm_dvd);
REGISTER_ENCDEC (PCM_F32BE, pcm_f32be);
REGISTER_ENCDEC (PCM_F32LE, pcm_f32le);
REGISTER_ENCDEC (PCM_F64BE, pcm_f64be);
REGISTER_ENCDEC (PCM_F64LE, pcm_f64le);
REGISTER_DECODER(PCM_LXF, pcm_lxf);
REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw);
REGISTER_ENCDEC (PCM_S8, pcm_s8);
REGISTER_ENCDEC (PCM_S8_PLANAR, pcm_s8_planar);
REGISTER_ENCDEC (PCM_S16BE, pcm_s16be);
REGISTER_ENCDEC (PCM_S16BE_PLANAR, pcm_s16be_planar);
REGISTER_ENCDEC (PCM_S16LE, pcm_s16le);
REGISTER_ENCDEC (PCM_S16LE_PLANAR, pcm_s16le_planar);
REGISTER_ENCDEC (PCM_S24BE, pcm_s24be);
REGISTER_ENCDEC (PCM_S24DAUD, pcm_s24daud);
REGISTER_ENCDEC (PCM_S24LE, pcm_s24le);
REGISTER_ENCDEC (PCM_S24LE_PLANAR, pcm_s24le_planar);
REGISTER_ENCDEC (PCM_S32BE, pcm_s32be);
REGISTER_ENCDEC (PCM_S32LE, pcm_s32le);
REGISTER_ENCDEC (PCM_S32LE_PLANAR, pcm_s32le_planar);
REGISTER_ENCDEC (PCM_U8, pcm_u8);
REGISTER_ENCDEC (PCM_U16BE, pcm_u16be);
REGISTER_ENCDEC (PCM_U16LE, pcm_u16le);
REGISTER_ENCDEC (PCM_U24BE, pcm_u24be);
REGISTER_ENCDEC (PCM_U24LE, pcm_u24le);
REGISTER_ENCDEC (PCM_U32BE, pcm_u32be);
REGISTER_ENCDEC (PCM_U32LE, pcm_u32le);
REGISTER_DECODER(PCM_ZORK, pcm_zork);
/* DPCM codecs */
REGISTER_DECODER(INTERPLAY_DPCM, interplay_dpcm);
REGISTER_ENCDEC (ROQ_DPCM, roq_dpcm);
REGISTER_DECODER(SOL_DPCM, sol_dpcm);
REGISTER_DECODER(XAN_DPCM, xan_dpcm);
/* ADPCM codecs */
REGISTER_DECODER(ADPCM_4XM, adpcm_4xm);
REGISTER_ENCDEC (ADPCM_ADX, adpcm_adx);
REGISTER_DECODER(ADPCM_AFC, adpcm_afc);
REGISTER_DECODER(ADPCM_CT, adpcm_ct);
REGISTER_DECODER(ADPCM_DTK, adpcm_dtk);
REGISTER_DECODER(ADPCM_EA, adpcm_ea);
REGISTER_DECODER(ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa);
REGISTER_DECODER(ADPCM_EA_R1, adpcm_ea_r1);
REGISTER_DECODER(ADPCM_EA_R2, adpcm_ea_r2);
REGISTER_DECODER(ADPCM_EA_R3, adpcm_ea_r3);
REGISTER_DECODER(ADPCM_EA_XAS, adpcm_ea_xas);
REGISTER_ENCDEC (ADPCM_G722, adpcm_g722);
REGISTER_ENCDEC (ADPCM_G726, adpcm_g726);
REGISTER_DECODER(ADPCM_IMA_AMV, adpcm_ima_amv);
REGISTER_DECODER(ADPCM_IMA_APC, adpcm_ima_apc);
REGISTER_DECODER(ADPCM_IMA_DK3, adpcm_ima_dk3);
REGISTER_DECODER(ADPCM_IMA_DK4, adpcm_ima_dk4);
REGISTER_DECODER(ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs);
REGISTER_DECODER(ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead);
REGISTER_DECODER(ADPCM_IMA_ISS, adpcm_ima_iss);
REGISTER_DECODER(ADPCM_IMA_OKI, adpcm_ima_oki);
REGISTER_ENCDEC (ADPCM_IMA_QT, adpcm_ima_qt);
REGISTER_DECODER(ADPCM_IMA_RAD, adpcm_ima_rad);
REGISTER_DECODER(ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg);
REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav);
REGISTER_DECODER(ADPCM_IMA_WS, adpcm_ima_ws);
REGISTER_ENCDEC (ADPCM_MS, adpcm_ms);
REGISTER_DECODER(ADPCM_SBPRO_2, adpcm_sbpro_2);
REGISTER_DECODER(ADPCM_SBPRO_3, adpcm_sbpro_3);
REGISTER_DECODER(ADPCM_SBPRO_4, adpcm_sbpro_4);
REGISTER_ENCDEC (ADPCM_SWF, adpcm_swf);
REGISTER_DECODER(ADPCM_THP, adpcm_thp);
REGISTER_DECODER(ADPCM_XA, adpcm_xa);
REGISTER_ENCDEC (ADPCM_YAMAHA, adpcm_yamaha);
REGISTER_DECODER(VIMA, vima);
/* subtitles */
REGISTER_ENCDEC (SSA, ssa);
REGISTER_ENCDEC (ASS, ass);
REGISTER_ENCDEC (DVBSUB, dvbsub);
REGISTER_ENCDEC (DVDSUB, dvdsub);
REGISTER_DECODER(JACOSUB, jacosub);
REGISTER_DECODER(MICRODVD, microdvd);
REGISTER_ENCDEC (MOVTEXT, movtext);
REGISTER_DECODER(MPL2, mpl2);
REGISTER_DECODER(PGSSUB, pgssub);
REGISTER_DECODER(PJS, pjs);
REGISTER_DECODER(REALTEXT, realtext);
REGISTER_DECODER(SAMI, sami);
REGISTER_ENCDEC (SRT, srt);
REGISTER_ENCDEC (SUBRIP, subrip);
REGISTER_DECODER(SUBVIEWER, subviewer);
REGISTER_DECODER(SUBVIEWER1, subviewer1);
REGISTER_DECODER(TEXT, text);
REGISTER_DECODER(VPLAYER, vplayer);
REGISTER_DECODER(WEBVTT, webvtt);
REGISTER_ENCDEC (XSUB, xsub);
/* external libraries */
REGISTER_DECODER(LIBCELT, libcelt);
REGISTER_ENCODER(LIBFAAC, libfaac);
REGISTER_ENCDEC (LIBFDK_AAC, libfdk_aac);
REGISTER_ENCDEC (LIBGSM, libgsm);
REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms);
REGISTER_ENCDEC (LIBILBC, libilbc);
REGISTER_ENCODER(LIBMP3LAME, libmp3lame);
REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb);
REGISTER_DECODER(LIBOPENCORE_AMRWB, libopencore_amrwb);
REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg);
REGISTER_ENCDEC (LIBOPUS, libopus);
REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger);
REGISTER_ENCODER(LIBSHINE, libshine);
REGISTER_ENCDEC (LIBSPEEX, libspeex);
REGISTER_DECODER(LIBSTAGEFRIGHT_H264, libstagefright_h264);
REGISTER_ENCODER(LIBTHEORA, libtheora);
REGISTER_ENCODER(LIBTWOLAME, libtwolame);
REGISTER_ENCDEC (LIBUTVIDEO, libutvideo);
REGISTER_ENCODER(LIBVO_AACENC, libvo_aacenc);
REGISTER_ENCODER(LIBVO_AMRWBENC, libvo_amrwbenc);
REGISTER_ENCDEC (LIBVORBIS, libvorbis);
REGISTER_ENCDEC (LIBVPX_VP8, libvpx_vp8);
REGISTER_ENCDEC (LIBVPX_VP9, libvpx_vp9);
REGISTER_ENCODER(LIBWAVPACK, libwavpack);
REGISTER_ENCODER(LIBX264, libx264);
REGISTER_ENCODER(LIBX264RGB, libx264rgb);
REGISTER_ENCODER(LIBXAVS, libxavs);
REGISTER_ENCODER(LIBXVID, libxvid);
REGISTER_DECODER(LIBZVBI_TELETEXT, libzvbi_teletext);
REGISTER_ENCODER(LIBAACPLUS, libaacplus);
/* text */
REGISTER_DECODER(BINTEXT, bintext);
REGISTER_DECODER(XBIN, xbin);
REGISTER_DECODER(IDF, idf);
/* parsers */
REGISTER_PARSER(AAC, aac);
REGISTER_PARSER(AAC_LATM, aac_latm);
REGISTER_PARSER(AC3, ac3);
REGISTER_PARSER(ADX, adx);
REGISTER_PARSER(BMP, bmp);
REGISTER_PARSER(CAVSVIDEO, cavsvideo);
REGISTER_PARSER(COOK, cook);
REGISTER_PARSER(DCA, dca);
REGISTER_PARSER(DIRAC, dirac);
REGISTER_PARSER(DNXHD, dnxhd);
REGISTER_PARSER(DVBSUB, dvbsub);
REGISTER_PARSER(DVDSUB, dvdsub);
REGISTER_PARSER(DVD_NAV, dvd_nav);
REGISTER_PARSER(FLAC, flac);
REGISTER_PARSER(GSM, gsm);
REGISTER_PARSER(H261, h261);
REGISTER_PARSER(H263, h263);
REGISTER_PARSER(H264, h264);
REGISTER_PARSER(MJPEG, mjpeg);
REGISTER_PARSER(MLP, mlp);
REGISTER_PARSER(MPEG4VIDEO, mpeg4video);
REGISTER_PARSER(MPEGAUDIO, mpegaudio);
REGISTER_PARSER(MPEGVIDEO, mpegvideo);
REGISTER_PARSER(PNG, png);
REGISTER_PARSER(PNM, pnm);
REGISTER_PARSER(RV30, rv30);
REGISTER_PARSER(RV40, rv40);
REGISTER_PARSER(TAK, tak);
REGISTER_PARSER(VC1, vc1);
REGISTER_PARSER(VORBIS, vorbis);
REGISTER_PARSER(VP3, vp3);
REGISTER_PARSER(VP8, vp8);
/* bitstream filters */
REGISTER_BSF(AAC_ADTSTOASC, aac_adtstoasc);
REGISTER_BSF(CHOMP, chomp);
REGISTER_BSF(DUMP_EXTRADATA, dump_extradata);
REGISTER_BSF(H264_MP4TOANNEXB, h264_mp4toannexb);
REGISTER_BSF(IMX_DUMP_HEADER, imx_dump_header);
REGISTER_BSF(MJPEG2JPEG, mjpeg2jpeg);
REGISTER_BSF(MJPEGA_DUMP_HEADER, mjpega_dump_header);
REGISTER_BSF(MP3_HEADER_COMPRESS, mp3_header_compress);
REGISTER_BSF(MP3_HEADER_DECOMPRESS, mp3_header_decompress);
REGISTER_BSF(MOV2TEXTSUB, mov2textsub);
REGISTER_BSF(NOISE, noise);
REGISTER_BSF(REMOVE_EXTRADATA, remove_extradata);
REGISTER_BSF(TEXT2MOVSUB, text2movsub);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,145 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/attributes.h"
#include "libavutil/mem.h"
#include "avfft.h"
#include "fft.h"
#include "rdft.h"
#include "dct.h"
/* FFT */
FFTContext *av_fft_init(int nbits, int inverse)
{
FFTContext *s = av_mallocz(sizeof(*s));
if (s && ff_fft_init(s, nbits, inverse))
av_freep(&s);
return s;
}
void av_fft_permute(FFTContext *s, FFTComplex *z)
{
s->fft_permute(s, z);
}
void av_fft_calc(FFTContext *s, FFTComplex *z)
{
s->fft_calc(s, z);
}
av_cold void av_fft_end(FFTContext *s)
{
if (s) {
ff_fft_end(s);
av_free(s);
}
}
#if CONFIG_MDCT
FFTContext *av_mdct_init(int nbits, int inverse, double scale)
{
FFTContext *s = av_malloc(sizeof(*s));
if (s && ff_mdct_init(s, nbits, inverse, scale))
av_freep(&s);
return s;
}
void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
{
s->imdct_calc(s, output, input);
}
void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input)
{
s->imdct_half(s, output, input);
}
void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
{
s->mdct_calc(s, output, input);
}
av_cold void av_mdct_end(FFTContext *s)
{
if (s) {
ff_mdct_end(s);
av_free(s);
}
}
#endif /* CONFIG_MDCT */
#if CONFIG_RDFT
RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans)
{
RDFTContext *s = av_malloc(sizeof(*s));
if (s && ff_rdft_init(s, nbits, trans))
av_freep(&s);
return s;
}
void av_rdft_calc(RDFTContext *s, FFTSample *data)
{
s->rdft_calc(s, data);
}
av_cold void av_rdft_end(RDFTContext *s)
{
if (s) {
ff_rdft_end(s);
av_free(s);
}
}
#endif /* CONFIG_RDFT */
#if CONFIG_DCT
DCTContext *av_dct_init(int nbits, enum DCTTransformType inverse)
{
DCTContext *s = av_malloc(sizeof(*s));
if (s && ff_dct_init(s, nbits, inverse))
av_freep(&s);
return s;
}
void av_dct_calc(DCTContext *s, FFTSample *data)
{
s->dct_calc(s, data);
}
av_cold void av_dct_end(DCTContext *s)
{
if (s) {
ff_dct_end(s);
av_free(s);
}
}
#endif /* CONFIG_DCT */

View file

@ -0,0 +1,116 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_AVFFT_H
#define AVCODEC_AVFFT_H
/**
* @file
* @ingroup lavc_fft
* FFT functions
*/
/**
* @defgroup lavc_fft FFT functions
* @ingroup lavc_misc
*
* @{
*/
typedef float FFTSample;
typedef struct FFTComplex {
FFTSample re, im;
} FFTComplex;
typedef struct FFTContext FFTContext;
/**
* Set up a complex FFT.
* @param nbits log2 of the length of the input array
* @param inverse if 0 perform the forward transform, if 1 perform the inverse
*/
FFTContext *av_fft_init(int nbits, int inverse);
/**
* Do the permutation needed BEFORE calling ff_fft_calc().
*/
void av_fft_permute(FFTContext *s, FFTComplex *z);
/**
* Do a complex FFT with the parameters defined in av_fft_init(). The
* input data must be permuted before. No 1.0/sqrt(n) normalization is done.
*/
void av_fft_calc(FFTContext *s, FFTComplex *z);
void av_fft_end(FFTContext *s);
FFTContext *av_mdct_init(int nbits, int inverse, double scale);
void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input);
void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
void av_mdct_end(FFTContext *s);
/* Real Discrete Fourier Transform */
enum RDFTransformType {
DFT_R2C,
IDFT_C2R,
IDFT_R2C,
DFT_C2R,
};
typedef struct RDFTContext RDFTContext;
/**
* Set up a real FFT.
* @param nbits log2 of the length of the input array
* @param trans the type of transform
*/
RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans);
void av_rdft_calc(RDFTContext *s, FFTSample *data);
void av_rdft_end(RDFTContext *s);
/* Discrete Cosine Transform */
typedef struct DCTContext DCTContext;
enum DCTTransformType {
DCT_II = 0,
DCT_III,
DCT_I,
DST_I,
};
/**
* Set up DCT.
* @param nbits size of the input array:
* (1 << nbits) for DCT-II, DCT-III and DST-I
* (1 << nbits) + 1 for DCT-I
*
* @note the first element of the input of DST-I is ignored
*/
DCTContext *av_dct_init(int nbits, enum DCTTransformType type);
void av_dct_calc(DCTContext *s, FFTSample *data);
void av_dct_end (DCTContext *s);
/**
* @}
*/
#endif /* AVCODEC_AVFFT_H */

View file

@ -0,0 +1,511 @@
/*
* AVPacket functions for libavcodec
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/internal.h"
#include "libavutil/mem.h"
#include "avcodec.h"
#include "bytestream.h"
#include "internal.h"
#if FF_API_DESTRUCT_PACKET
void av_destruct_packet(AVPacket *pkt)
{
av_free(pkt->data);
pkt->data = NULL;
pkt->size = 0;
}
/* a dummy destruct callback for the callers that assume AVPacket.destruct ==
* NULL => static data */
static void dummy_destruct_packet(AVPacket *pkt)
{
av_assert0(0);
}
#endif
void av_init_packet(AVPacket *pkt)
{
pkt->pts = AV_NOPTS_VALUE;
pkt->dts = AV_NOPTS_VALUE;
pkt->pos = -1;
pkt->duration = 0;
pkt->convergence_duration = 0;
pkt->flags = 0;
pkt->stream_index = 0;
#if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = NULL;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
pkt->buf = NULL;
pkt->side_data = NULL;
pkt->side_data_elems = 0;
}
static int packet_alloc(AVBufferRef **buf, int size)
{
int ret;
if ((unsigned)size >= (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
return AVERROR(EINVAL);
ret = av_buffer_realloc(buf, size + FF_INPUT_BUFFER_PADDING_SIZE);
if (ret < 0)
return ret;
memset((*buf)->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
return 0;
}
int av_new_packet(AVPacket *pkt, int size)
{
AVBufferRef *buf = NULL;
int ret = packet_alloc(&buf, size);
if (ret < 0)
return ret;
av_init_packet(pkt);
pkt->buf = buf;
pkt->data = buf->data;
pkt->size = size;
#if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = dummy_destruct_packet;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
return 0;
}
void av_shrink_packet(AVPacket *pkt, int size)
{
if (pkt->size <= size)
return;
pkt->size = size;
memset(pkt->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
}
int av_grow_packet(AVPacket *pkt, int grow_by)
{
int new_size;
av_assert0((unsigned)pkt->size <= INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE);
if (!pkt->size)
return av_new_packet(pkt, grow_by);
if ((unsigned)grow_by >
INT_MAX - (pkt->size + FF_INPUT_BUFFER_PADDING_SIZE))
return -1;
new_size = pkt->size + grow_by + FF_INPUT_BUFFER_PADDING_SIZE;
if (pkt->buf) {
int ret = av_buffer_realloc(&pkt->buf, new_size);
if (ret < 0)
return ret;
} else {
pkt->buf = av_buffer_alloc(new_size);
if (!pkt->buf)
return AVERROR(ENOMEM);
memcpy(pkt->buf->data, pkt->data, FFMIN(pkt->size, pkt->size + grow_by));
#if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = dummy_destruct_packet;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
}
pkt->data = pkt->buf->data;
pkt->size += grow_by;
memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
return 0;
}
int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
{
if (size >= INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
return AVERROR(EINVAL);
pkt->buf = av_buffer_create(data, size + FF_INPUT_BUFFER_PADDING_SIZE,
av_buffer_default_free, NULL, 0);
if (!pkt->buf)
return AVERROR(ENOMEM);
pkt->data = data;
pkt->size = size;
#if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = dummy_destruct_packet;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
return 0;
}
#define ALLOC_MALLOC(data, size) data = av_malloc(size)
#define ALLOC_BUF(data, size) \
do { \
av_buffer_realloc(&pkt->buf, size); \
data = pkt->buf ? pkt->buf->data : NULL; \
} while (0)
#define DUP_DATA(dst, src, size, padding, ALLOC) \
do { \
void *data; \
if (padding) { \
if ((unsigned)(size) > \
(unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE) \
goto failed_alloc; \
ALLOC(data, size + FF_INPUT_BUFFER_PADDING_SIZE); \
} else { \
ALLOC(data, size); \
} \
if (!data) \
goto failed_alloc; \
memcpy(data, src, size); \
if (padding) \
memset((uint8_t *)data + size, 0, \
FF_INPUT_BUFFER_PADDING_SIZE); \
dst = data; \
} while (0)
/* Makes duplicates of data, side_data, but does not copy any other fields */
static int copy_packet_data(AVPacket *pkt, AVPacket *src, int dup)
{
pkt->data = NULL;
pkt->side_data = NULL;
if (pkt->buf) {
AVBufferRef *ref = av_buffer_ref(src->buf);
if (!ref)
return AVERROR(ENOMEM);
pkt->buf = ref;
pkt->data = ref->data;
} else {
DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF);
}
#if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = dummy_destruct_packet;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
if (pkt->side_data_elems && dup)
pkt->side_data = src->side_data;
if (pkt->side_data_elems && !dup) {
return av_copy_packet_side_data(pkt, src);
}
return 0;
failed_alloc:
av_free_packet(pkt);
return AVERROR(ENOMEM);
}
int av_copy_packet_side_data(AVPacket *pkt, AVPacket *src)
{
if (src->side_data_elems) {
int i;
DUP_DATA(pkt->side_data, src->side_data,
src->side_data_elems * sizeof(*src->side_data), 0, ALLOC_MALLOC);
if (src != pkt) {
memset(pkt->side_data, 0,
src->side_data_elems * sizeof(*src->side_data));
}
for (i = 0; i < src->side_data_elems; i++) {
DUP_DATA(pkt->side_data[i].data, src->side_data[i].data,
src->side_data[i].size, 1, ALLOC_MALLOC);
pkt->side_data[i].size = src->side_data[i].size;
pkt->side_data[i].type = src->side_data[i].type;
}
}
return 0;
failed_alloc:
av_free_packet(pkt);
return AVERROR(ENOMEM);
}
int av_dup_packet(AVPacket *pkt)
{
AVPacket tmp_pkt;
FF_DISABLE_DEPRECATION_WARNINGS
if (!pkt->buf && pkt->data
#if FF_API_DESTRUCT_PACKET
&& !pkt->destruct
#endif
) {
FF_ENABLE_DEPRECATION_WARNINGS
tmp_pkt = *pkt;
return copy_packet_data(pkt, &tmp_pkt, 1);
}
return 0;
}
int av_copy_packet(AVPacket *dst, AVPacket *src)
{
*dst = *src;
return copy_packet_data(dst, src, 0);
}
void av_packet_free_side_data(AVPacket *pkt)
{
int i;
for (i = 0; i < pkt->side_data_elems; i++)
av_free(pkt->side_data[i].data);
av_freep(&pkt->side_data);
pkt->side_data_elems = 0;
}
void av_free_packet(AVPacket *pkt)
{
if (pkt) {
FF_DISABLE_DEPRECATION_WARNINGS
if (pkt->buf)
av_buffer_unref(&pkt->buf);
#if FF_API_DESTRUCT_PACKET
else if (pkt->destruct)
pkt->destruct(pkt);
pkt->destruct = NULL;
#endif
FF_ENABLE_DEPRECATION_WARNINGS
pkt->data = NULL;
pkt->size = 0;
av_packet_free_side_data(pkt);
}
}
uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int size)
{
int elems = pkt->side_data_elems;
if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
return NULL;
if ((unsigned)size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
return NULL;
pkt->side_data = av_realloc(pkt->side_data,
(elems + 1) * sizeof(*pkt->side_data));
if (!pkt->side_data)
return NULL;
pkt->side_data[elems].data = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!pkt->side_data[elems].data)
return NULL;
pkt->side_data[elems].size = size;
pkt->side_data[elems].type = type;
pkt->side_data_elems++;
return pkt->side_data[elems].data;
}
uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int *size)
{
int i;
for (i = 0; i < pkt->side_data_elems; i++) {
if (pkt->side_data[i].type == type) {
if (size)
*size = pkt->side_data[i].size;
return pkt->side_data[i].data;
}
}
return NULL;
}
#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
int av_packet_merge_side_data(AVPacket *pkt){
if(pkt->side_data_elems){
AVBufferRef *buf;
int i;
uint8_t *p;
uint64_t size= pkt->size + 8LL + FF_INPUT_BUFFER_PADDING_SIZE;
AVPacket old= *pkt;
for (i=0; i<old.side_data_elems; i++) {
size += old.side_data[i].size + 5LL;
}
if (size > INT_MAX)
return AVERROR(EINVAL);
buf = av_buffer_alloc(size);
if (!buf)
return AVERROR(ENOMEM);
pkt->buf = buf;
pkt->data = p = buf->data;
#if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
pkt->destruct = dummy_destruct_packet;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
pkt->size = size - FF_INPUT_BUFFER_PADDING_SIZE;
bytestream_put_buffer(&p, old.data, old.size);
for (i=old.side_data_elems-1; i>=0; i--) {
bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size);
bytestream_put_be32(&p, old.side_data[i].size);
*p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128);
}
bytestream_put_be64(&p, FF_MERGE_MARKER);
av_assert0(p-pkt->data == pkt->size);
memset(p, 0, FF_INPUT_BUFFER_PADDING_SIZE);
av_free_packet(&old);
pkt->side_data_elems = 0;
pkt->side_data = NULL;
return 1;
}
return 0;
}
int av_packet_split_side_data(AVPacket *pkt){
if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
int i;
unsigned int size, orig_pktsize = pkt->size;
uint8_t *p;
p = pkt->data + pkt->size - 8 - 5;
for (i=1; ; i++){
size = AV_RB32(p);
if (size>INT_MAX || p - pkt->data < size)
return 0;
if (p[4]&128)
break;
p-= size+5;
}
pkt->side_data = av_malloc(i * sizeof(*pkt->side_data));
if (!pkt->side_data)
return AVERROR(ENOMEM);
p= pkt->data + pkt->size - 8 - 5;
for (i=0; ; i++){
size= AV_RB32(p);
av_assert0(size<=INT_MAX && p - pkt->data >= size);
pkt->side_data[i].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
pkt->side_data[i].size = size;
pkt->side_data[i].type = p[4]&127;
if (!pkt->side_data[i].data)
return AVERROR(ENOMEM);
memcpy(pkt->side_data[i].data, p-size, size);
pkt->size -= size + 5;
if(p[4]&128)
break;
p-= size+5;
}
pkt->size -= 8;
/* FFMIN() prevents overflow in case the packet wasn't allocated with
* proper padding.
* If the side data is smaller than the buffer padding size, the
* remaining bytes should have already been filled with zeros by the
* original packet allocation anyway. */
memset(pkt->data + pkt->size, 0,
FFMIN(orig_pktsize - pkt->size, FF_INPUT_BUFFER_PADDING_SIZE));
pkt->side_data_elems = i+1;
return 1;
}
return 0;
}
int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int size)
{
int i;
for (i = 0; i < pkt->side_data_elems; i++) {
if (pkt->side_data[i].type == type) {
if (size > pkt->side_data[i].size)
return AVERROR(ENOMEM);
pkt->side_data[i].size = size;
return 0;
}
}
return AVERROR(ENOENT);
}
int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
{
int i;
dst->pts = src->pts;
dst->dts = src->dts;
dst->pos = src->pos;
dst->duration = src->duration;
dst->convergence_duration = src->convergence_duration;
dst->flags = src->flags;
dst->stream_index = src->stream_index;
dst->side_data_elems = src->side_data_elems;
for (i = 0; i < src->side_data_elems; i++) {
enum AVPacketSideDataType type = src->side_data[i].type;
int size = src->side_data[i].size;
uint8_t *src_data = src->side_data[i].data;
uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
if (!dst_data) {
av_packet_free_side_data(dst);
return AVERROR(ENOMEM);
}
memcpy(dst_data, src_data, size);
}
return 0;
}
void av_packet_unref(AVPacket *pkt)
{
av_packet_free_side_data(pkt);
av_buffer_unref(&pkt->buf);
av_init_packet(pkt);
pkt->data = NULL;
pkt->size = 0;
}
int av_packet_ref(AVPacket *dst, AVPacket *src)
{
int ret;
ret = av_packet_copy_props(dst, src);
if (ret < 0)
return ret;
if (!src->buf) {
ret = packet_alloc(&dst->buf, src->size);
if (ret < 0)
goto fail;
memcpy(dst->buf->data, src->data, src->size);
} else
dst->buf = av_buffer_ref(src->buf);
dst->size = src->size;
dst->data = dst->buf->data;
return 0;
fail:
av_packet_free_side_data(dst);
return ret;
}
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
{
*dst = *src;
av_init_packet(src);
}

View file

@ -0,0 +1,78 @@
/*
* AVPicture management routines
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* AVPicture management routines
*/
#include "avcodec.h"
#include "internal.h"
#include "libavutil/common.h"
#include "libavutil/pixdesc.h"
#include "libavutil/imgutils.h"
#include "libavutil/colorspace.h"
int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
enum AVPixelFormat pix_fmt, int width, int height)
{
return av_image_fill_arrays(picture->data, picture->linesize,
ptr, pix_fmt, width, height, 1);
}
int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt, int width, int height,
unsigned char *dest, int dest_size)
{
return av_image_copy_to_buffer(dest, dest_size,
(const uint8_t * const*)src->data, src->linesize,
pix_fmt, width, height, 1);
}
int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
{
return av_image_get_buffer_size(pix_fmt, width, height, 1);
}
int avpicture_alloc(AVPicture *picture,
enum AVPixelFormat pix_fmt, int width, int height)
{
int ret = av_image_alloc(picture->data, picture->linesize,
width, height, pix_fmt, 1);
if (ret < 0) {
memset(picture, 0, sizeof(AVPicture));
return ret;
}
return 0;
}
void avpicture_free(AVPicture *picture)
{
av_free(picture->data[0]);
}
void av_picture_copy(AVPicture *dst, const AVPicture *src,
enum AVPixelFormat pix_fmt, int width, int height)
{
av_image_copy(dst->data, dst->linesize, (const uint8_t **)src->data,
src->linesize, pix_fmt, width, height);
}

View file

@ -0,0 +1,92 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "rnd_avg.h"
#include "libavutil/intreadwrite.h"
#ifndef BIT_DEPTH
#define BIT_DEPTH 8
#endif
#ifdef AVCODEC_H264_HIGH_DEPTH_H
# undef pixel
# undef pixel2
# undef pixel4
# undef dctcoef
# undef INIT_CLIP
# undef no_rnd_avg_pixel4
# undef rnd_avg_pixel4
# undef AV_RN2P
# undef AV_RN4P
# undef AV_RN4PA
# undef AV_WN2P
# undef AV_WN4P
# undef AV_WN4PA
# undef CLIP
# undef FUNC
# undef FUNCC
# undef av_clip_pixel
# undef PIXEL_SPLAT_X4
#else
# define AVCODEC_H264_HIGH_DEPTH_H
#endif
#if BIT_DEPTH > 8
# define pixel uint16_t
# define pixel2 uint32_t
# define pixel4 uint64_t
# define dctcoef int32_t
# define INIT_CLIP
# define no_rnd_avg_pixel4 no_rnd_avg64
# define rnd_avg_pixel4 rnd_avg64
# define AV_RN2P AV_RN32
# define AV_RN4P AV_RN64
# define AV_RN4PA AV_RN64A
# define AV_WN2P AV_WN32
# define AV_WN4P AV_WN64
# define AV_WN4PA AV_WN64A
# define PIXEL_SPLAT_X4(x) ((x)*0x0001000100010001ULL)
# define av_clip_pixel(a) av_clip_uintp2(a, BIT_DEPTH)
# define CLIP(a) av_clip_uintp2(a, BIT_DEPTH)
#else
# define pixel uint8_t
# define pixel2 uint16_t
# define pixel4 uint32_t
# define dctcoef int16_t
# define INIT_CLIP
# define no_rnd_avg_pixel4 no_rnd_avg32
# define rnd_avg_pixel4 rnd_avg32
# define AV_RN2P AV_RN16
# define AV_RN4P AV_RN32
# define AV_RN4PA AV_RN32A
# define AV_WN2P AV_WN16
# define AV_WN4P AV_WN32
# define AV_WN4PA AV_WN32A
# define PIXEL_SPLAT_X4(x) ((x)*0x01010101U)
# define av_clip_pixel(a) av_clip_uint8(a)
# define CLIP(a) av_clip_uint8(a)
#endif
#define FUNC3(a, b, c) a ## _ ## b ## c
#define FUNC2(a, b, c) FUNC3(a, b, c)
#define FUNC(a) FUNC2(a, BIT_DEPTH,)
#define FUNCC(a) FUNC2(a, BIT_DEPTH, _c)

View file

@ -0,0 +1,356 @@
/*
* Common bit i/o utils
* Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2010 Loren Merritt
*
* alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* bitstream api.
*/
#include "libavutil/atomic.h"
#include "libavutil/avassert.h"
#include "avcodec.h"
#include "mathops.h"
#include "get_bits.h"
#include "put_bits.h"
const uint8_t ff_log2_run[41]={
0, 0, 0, 0, 1, 1, 1, 1,
2, 2, 2, 2, 3, 3, 3, 3,
4, 4, 5, 5, 6, 6, 7, 7,
8, 9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,
24,
};
void avpriv_align_put_bits(PutBitContext *s)
{
put_bits(s, s->bit_left & 7, 0);
}
void avpriv_put_string(PutBitContext *pb, const char *string,
int terminate_string)
{
while (*string) {
put_bits(pb, 8, *string);
string++;
}
if (terminate_string)
put_bits(pb, 8, 0);
}
void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
{
int words = length >> 4;
int bits = length & 15;
int i;
if (length == 0)
return;
if (CONFIG_SMALL || words < 16 || put_bits_count(pb) & 7) {
for (i = 0; i < words; i++)
put_bits(pb, 16, AV_RB16(src + 2 * i));
} else {
for (i = 0; put_bits_count(pb) & 31; i++)
put_bits(pb, 8, src[i]);
flush_put_bits(pb);
memcpy(put_bits_ptr(pb), src + i, 2 * words - i);
skip_put_bytes(pb, 2 * words - i);
}
put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits));
}
/* VLC decoding */
#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 use_static)
{
int index = vlc->table_size;
vlc->table_size += size;
if (vlc->table_size > vlc->table_allocated) {
if (use_static)
abort(); // cannot do anything, init_vlc() is used with too little memory
vlc->table_allocated += (1 << vlc->bits);
vlc->table = av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2);
if (!vlc->table)
return AVERROR(ENOMEM);
}
return index;
}
static av_always_inline uint32_t bitswap_32(uint32_t x)
{
return (uint32_t)ff_reverse[ x & 0xFF] << 24 |
(uint32_t)ff_reverse[(x >> 8) & 0xFF] << 16 |
(uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8 |
(uint32_t)ff_reverse[ x >> 24];
}
typedef struct {
uint8_t bits;
uint16_t symbol;
/** codeword, with the first bit-to-be-read in the msb
* (even if intended for a little-endian bitstream reader) */
uint32_t code;
} VLCcode;
static int compare_vlcspec(const void *a, const void *b)
{
const VLCcode *sa = a, *sb = b;
return (sa->code >> 1) - (sb->code >> 1);
}
/**
* Build VLC decoding tables suitable for use with get_vlc().
*
* @param vlc the context to be initted
*
* @param table_nb_bits max length of vlc codes to store directly in this table
* (Longer codes are delegated to subtables.)
*
* @param nb_codes number of elements in codes[]
*
* @param codes descriptions of the vlc codes
* These must be ordered such that codes going into the same subtable are contiguous.
* Sorting by VLCcode.code is sufficient, though not necessary.
*/
static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
VLCcode *codes, int flags)
{
int table_size, table_index, index, code_prefix, symbol, subtable_bits;
int i, j, k, n, nb, inc;
uint32_t code;
VLC_TYPE (*table)[2];
table_size = 1 << table_nb_bits;
if (table_nb_bits > 30)
return -1;
table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
av_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);
if (table_index < 0)
return table_index;
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 auxiliary table sizes */
for (i = 0; i < nb_codes; i++) {
n = codes[i].bits;
code = codes[i].code;
symbol = codes[i].symbol;
av_dlog(NULL, "i=%d n=%d code=0x%x\n", i, n, code);
if (n <= table_nb_bits) {
/* no need to add another table */
j = code >> (32 - table_nb_bits);
nb = 1 << (table_nb_bits - n);
inc = 1;
if (flags & INIT_VLC_LE) {
j = bitswap_32(code);
inc = 1 << n;
}
for (k = 0; k < nb; k++) {
av_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n);
if (table[j][1] /*bits*/ != 0) {
av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
return AVERROR_INVALIDDATA;
}
table[j][1] = n; //bits
table[j][0] = symbol;
j += inc;
}
} else {
/* fill auxiliary table recursively */
n -= table_nb_bits;
code_prefix = code >> (32 - table_nb_bits);
subtable_bits = n;
codes[i].bits = n;
codes[i].code = code << table_nb_bits;
for (k = i+1; k < nb_codes; k++) {
n = codes[k].bits - table_nb_bits;
if (n <= 0)
break;
code = codes[k].code;
if (code >> (32 - table_nb_bits) != code_prefix)
break;
codes[k].bits = n;
codes[k].code = code << table_nb_bits;
subtable_bits = FFMAX(subtable_bits, n);
}
subtable_bits = FFMIN(subtable_bits, table_nb_bits);
j = (flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix;
table[j][1] = -subtable_bits;
av_dlog(NULL, "%4x: n=%d (subtable)\n",
j, codes[i].bits + table_nb_bits);
index = build_table(vlc, subtable_bits, k-i, codes+i, flags);
if (index < 0)
return index;
/* note: realloc has been done, so reload tables */
table = &vlc->table[table_index];
table[j][0] = index; //code
i = k-1;
}
}
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.
'symbols' : table which gives the values to be returned from get_vlc().
'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', 'codes', and 'symbols' tables.
'use_static' should be set to 1 for tables, which should be freed
with av_free_static(), 0 if ff_free_vlc() will be used.
*/
int ff_init_vlc_sparse(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,
const void *symbols, int symbols_wrap, int symbols_size,
int flags)
{
VLCcode *buf;
int i, j, ret;
VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34
void *state;
vlc->bits = nb_bits;
if (flags & INIT_VLC_USE_NEW_STATIC) {
while (state = avpriv_atomic_ptr_cas(&vlc->init_state, NULL, vlc)) {
if (state == vlc + 1) {
av_assert0(vlc->table_size && vlc->table_size == vlc->table_allocated);
return 0;
}
}
av_assert0(!vlc->table_size);
av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf));
buf = localbuf;
} else {
vlc->table = NULL;
vlc->table_allocated = 0;
vlc->table_size = 0;
buf = av_malloc((nb_codes + 1) * sizeof(VLCcode));
if (!buf)
return AVERROR(ENOMEM);
}
av_assert0(symbols_size <= 2 || !symbols);
j = 0;
#define COPY(condition)\
for (i = 0; i < nb_codes; i++) { \
GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size); \
if (!(condition)) \
continue; \
if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \
av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\
if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
av_free(buf); \
return -1; \
} \
GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \
if (buf[j].code >= (1LL<<buf[j].bits)) { \
av_log(NULL, AV_LOG_ERROR, "Invalid code in init_vlc\n"); \
if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
av_free(buf); \
return -1; \
} \
if (flags & INIT_VLC_LE) \
buf[j].code = bitswap_32(buf[j].code); \
else \
buf[j].code <<= 32 - buf[j].bits; \
if (symbols) \
GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size) \
else \
buf[j].symbol = i; \
j++; \
}
COPY(buf[j].bits > nb_bits);
// qsort is the slowest part of init_vlc, and could probably be improved or avoided
qsort(buf, j, sizeof(VLCcode), compare_vlcspec);
COPY(buf[j].bits && buf[j].bits <= nb_bits);
nb_codes = j;
ret = build_table(vlc, nb_bits, nb_codes, buf, flags);
if (flags & INIT_VLC_USE_NEW_STATIC) {
if(vlc->table_size != vlc->table_allocated)
av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
state = avpriv_atomic_ptr_cas(&vlc->init_state, vlc, vlc+1);
av_assert0(state == vlc);
av_assert0(ret >= 0);
} else {
av_free(buf);
if (ret < 0) {
av_freep(&vlc->table);
return ret;
}
}
return 0;
}
void ff_free_vlc(VLC *vlc)
{
av_freep(&vlc->table);
}

View file

@ -0,0 +1,348 @@
/*
* Bytestream functions
* copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
* Copyright (c) 2012 Aneesh Dogra (lionaneesh) <lionaneesh@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_BYTESTREAM_H
#define AVCODEC_BYTESTREAM_H
#include <stdint.h>
#include <string.h>
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
typedef struct GetByteContext {
const uint8_t *buffer, *buffer_end, *buffer_start;
} GetByteContext;
typedef struct PutByteContext {
uint8_t *buffer, *buffer_end, *buffer_start;
int eof;
} PutByteContext;
#define DEF(type, name, bytes, read, write) \
static av_always_inline type bytestream_get_ ## name(const uint8_t **b) \
{ \
(*b) += bytes; \
return read(*b - bytes); \
} \
static av_always_inline void bytestream_put_ ## name(uint8_t **b, \
const type value) \
{ \
write(*b, value); \
(*b) += bytes; \
} \
static av_always_inline void bytestream2_put_ ## name ## u(PutByteContext *p, \
const type value) \
{ \
bytestream_put_ ## name(&p->buffer, value); \
} \
static av_always_inline void bytestream2_put_ ## name(PutByteContext *p, \
const type value) \
{ \
if (!p->eof && (p->buffer_end - p->buffer >= bytes)) { \
write(p->buffer, value); \
p->buffer += bytes; \
} else \
p->eof = 1; \
} \
static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g) \
{ \
return bytestream_get_ ## name(&g->buffer); \
} \
static av_always_inline type bytestream2_get_ ## name(GetByteContext *g) \
{ \
if (g->buffer_end - g->buffer < bytes) \
return 0; \
return bytestream2_get_ ## name ## u(g); \
} \
static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g) \
{ \
if (g->buffer_end - g->buffer < bytes) \
return 0; \
return read(g->buffer); \
}
DEF(uint64_t, le64, 8, AV_RL64, AV_WL64)
DEF(unsigned int, le32, 4, AV_RL32, AV_WL32)
DEF(unsigned int, le24, 3, AV_RL24, AV_WL24)
DEF(unsigned int, le16, 2, AV_RL16, AV_WL16)
DEF(uint64_t, be64, 8, AV_RB64, AV_WB64)
DEF(unsigned int, be32, 4, AV_RB32, AV_WB32)
DEF(unsigned int, be24, 3, AV_RB24, AV_WB24)
DEF(unsigned int, be16, 2, AV_RB16, AV_WB16)
DEF(unsigned int, byte, 1, AV_RB8 , AV_WB8)
#if HAVE_BIGENDIAN
# define bytestream2_get_ne16 bytestream2_get_be16
# define bytestream2_get_ne24 bytestream2_get_be24
# define bytestream2_get_ne32 bytestream2_get_be32
# define bytestream2_get_ne64 bytestream2_get_be64
# define bytestream2_get_ne16u bytestream2_get_be16u
# define bytestream2_get_ne24u bytestream2_get_be24u
# define bytestream2_get_ne32u bytestream2_get_be32u
# define bytestream2_get_ne64u bytestream2_get_be64u
# define bytestream2_put_ne16 bytestream2_put_be16
# define bytestream2_put_ne24 bytestream2_put_be24
# define bytestream2_put_ne32 bytestream2_put_be32
# define bytestream2_put_ne64 bytestream2_put_be64
# define bytestream2_peek_ne16 bytestream2_peek_be16
# define bytestream2_peek_ne24 bytestream2_peek_be24
# define bytestream2_peek_ne32 bytestream2_peek_be32
# define bytestream2_peek_ne64 bytestream2_peek_be64
#else
# define bytestream2_get_ne16 bytestream2_get_le16
# define bytestream2_get_ne24 bytestream2_get_le24
# define bytestream2_get_ne32 bytestream2_get_le32
# define bytestream2_get_ne64 bytestream2_get_le64
# define bytestream2_get_ne16u bytestream2_get_le16u
# define bytestream2_get_ne24u bytestream2_get_le24u
# define bytestream2_get_ne32u bytestream2_get_le32u
# define bytestream2_get_ne64u bytestream2_get_le64u
# define bytestream2_put_ne16 bytestream2_put_le16
# define bytestream2_put_ne24 bytestream2_put_le24
# define bytestream2_put_ne32 bytestream2_put_le32
# define bytestream2_put_ne64 bytestream2_put_le64
# define bytestream2_peek_ne16 bytestream2_peek_le16
# define bytestream2_peek_ne24 bytestream2_peek_le24
# define bytestream2_peek_ne32 bytestream2_peek_le32
# define bytestream2_peek_ne64 bytestream2_peek_le64
#endif
static av_always_inline void bytestream2_init(GetByteContext *g,
const uint8_t *buf,
int buf_size)
{
av_assert0(buf_size >= 0);
g->buffer = buf;
g->buffer_start = buf;
g->buffer_end = buf + buf_size;
}
static av_always_inline void bytestream2_init_writer(PutByteContext *p,
uint8_t *buf,
int buf_size)
{
av_assert0(buf_size >= 0);
p->buffer = buf;
p->buffer_start = buf;
p->buffer_end = buf + buf_size;
p->eof = 0;
}
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
{
return g->buffer_end - g->buffer;
}
static av_always_inline unsigned int bytestream2_get_bytes_left_p(PutByteContext *p)
{
return p->buffer_end - p->buffer;
}
static av_always_inline void bytestream2_skip(GetByteContext *g,
unsigned int size)
{
g->buffer += FFMIN(g->buffer_end - g->buffer, size);
}
static av_always_inline void bytestream2_skipu(GetByteContext *g,
unsigned int size)
{
g->buffer += size;
}
static av_always_inline void bytestream2_skip_p(PutByteContext *p,
unsigned int size)
{
int size2;
if (p->eof)
return;
size2 = FFMIN(p->buffer_end - p->buffer, size);
if (size2 != size)
p->eof = 1;
p->buffer += size2;
}
static av_always_inline int bytestream2_tell(GetByteContext *g)
{
return (int)(g->buffer - g->buffer_start);
}
static av_always_inline int bytestream2_tell_p(PutByteContext *p)
{
return (int)(p->buffer - p->buffer_start);
}
static av_always_inline int bytestream2_size(GetByteContext *g)
{
return (int)(g->buffer_end - g->buffer_start);
}
static av_always_inline int bytestream2_size_p(PutByteContext *p)
{
return (int)(p->buffer_end - p->buffer_start);
}
static av_always_inline int bytestream2_seek(GetByteContext *g,
int offset,
int whence)
{
switch (whence) {
case SEEK_CUR:
offset = av_clip(offset, -(g->buffer - g->buffer_start),
g->buffer_end - g->buffer);
g->buffer += offset;
break;
case SEEK_END:
offset = av_clip(offset, -(g->buffer_end - g->buffer_start), 0);
g->buffer = g->buffer_end + offset;
break;
case SEEK_SET:
offset = av_clip(offset, 0, g->buffer_end - g->buffer_start);
g->buffer = g->buffer_start + offset;
break;
default:
return AVERROR(EINVAL);
}
return bytestream2_tell(g);
}
static av_always_inline int bytestream2_seek_p(PutByteContext *p,
int offset,
int whence)
{
p->eof = 0;
switch (whence) {
case SEEK_CUR:
if (p->buffer_end - p->buffer < offset)
p->eof = 1;
offset = av_clip(offset, -(p->buffer - p->buffer_start),
p->buffer_end - p->buffer);
p->buffer += offset;
break;
case SEEK_END:
if (offset > 0)
p->eof = 1;
offset = av_clip(offset, -(p->buffer_end - p->buffer_start), 0);
p->buffer = p->buffer_end + offset;
break;
case SEEK_SET:
if (p->buffer_end - p->buffer_start < offset)
p->eof = 1;
offset = av_clip(offset, 0, p->buffer_end - p->buffer_start);
p->buffer = p->buffer_start + offset;
break;
default:
return AVERROR(EINVAL);
}
return bytestream2_tell_p(p);
}
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
uint8_t *dst,
unsigned int size)
{
int size2 = FFMIN(g->buffer_end - g->buffer, size);
memcpy(dst, g->buffer, size2);
g->buffer += size2;
return size2;
}
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g,
uint8_t *dst,
unsigned int size)
{
memcpy(dst, g->buffer, size);
g->buffer += size;
return size;
}
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p,
const uint8_t *src,
unsigned int size)
{
int size2;
if (p->eof)
return 0;
size2 = FFMIN(p->buffer_end - p->buffer, size);
if (size2 != size)
p->eof = 1;
memcpy(p->buffer, src, size2);
p->buffer += size2;
return size2;
}
static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p,
const uint8_t *src,
unsigned int size)
{
memcpy(p->buffer, src, size);
p->buffer += size;
return size;
}
static av_always_inline void bytestream2_set_buffer(PutByteContext *p,
const uint8_t c,
unsigned int size)
{
int size2;
if (p->eof)
return;
size2 = FFMIN(p->buffer_end - p->buffer, size);
if (size2 != size)
p->eof = 1;
memset(p->buffer, c, size2);
p->buffer += size2;
}
static av_always_inline void bytestream2_set_bufferu(PutByteContext *p,
const uint8_t c,
unsigned int size)
{
memset(p->buffer, c, size);
p->buffer += size;
}
static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
{
return p->eof;
}
static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b,
uint8_t *dst,
unsigned int size)
{
memcpy(dst, *b, size);
(*b) += size;
return size;
}
static av_always_inline void bytestream_put_buffer(uint8_t **b,
const uint8_t *src,
unsigned int size)
{
memcpy(*b, src, size);
(*b) += size;
}
#endif /* AVCODEC_BYTESTREAM_H */

View file

@ -0,0 +1,221 @@
/*
* various filters for ACELP-based codecs
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include "config.h"
#include "avcodec.h"
#include "celp_filters.h"
#include "libavutil/avassert.h"
#include "libavutil/common.h"
void ff_celp_convolve_circ(int16_t* fc_out, const int16_t* fc_in,
const int16_t* filter, int len)
{
int i, k;
memset(fc_out, 0, len * sizeof(int16_t));
/* Since there are few pulses over an entire subframe (i.e. almost
all fc_in[i] are zero) it is faster to loop over fc_in first. */
for (i = 0; i < len; i++) {
if (fc_in[i]) {
for (k = 0; k < i; k++)
fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15;
for (k = i; k < len; k++)
fc_out[k] += (fc_in[i] * filter[ k - i]) >> 15;
}
}
}
void ff_celp_circ_addf(float *out, const float *in,
const float *lagged, int lag, float fac, int n)
{
int k;
for (k = 0; k < lag; k++)
out[k] = in[k] + fac * lagged[n + k - lag];
for (; k < n; k++)
out[k] = in[k] + fac * lagged[ k - lag];
}
int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs,
const int16_t *in, int buffer_length,
int filter_length, int stop_on_overflow,
int shift, int rounder)
{
int i,n;
for (n = 0; n < buffer_length; n++) {
int sum = -rounder, sum1;
for (i = 1; i <= filter_length; i++)
sum += filter_coeffs[i-1] * out[n-i];
sum1 = ((-sum >> 12) + in[n]) >> shift;
sum = av_clip_int16(sum1);
if (stop_on_overflow && sum != sum1)
return 1;
out[n] = sum;
}
return 0;
}
void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs,
const float* in, int buffer_length,
int filter_length)
{
int i,n;
#if 0 // Unoptimized code path for improved readability
for (n = 0; n < buffer_length; n++) {
out[n] = in[n];
for (i = 1; i <= filter_length; i++)
out[n] -= filter_coeffs[i-1] * out[n-i];
}
#else
float out0, out1, out2, out3;
float old_out0, old_out1, old_out2, old_out3;
float a,b,c;
a = filter_coeffs[0];
b = filter_coeffs[1];
c = filter_coeffs[2];
b -= filter_coeffs[0] * filter_coeffs[0];
c -= filter_coeffs[1] * filter_coeffs[0];
c -= filter_coeffs[0] * b;
av_assert2((filter_length&1)==0 && filter_length>=4);
old_out0 = out[-4];
old_out1 = out[-3];
old_out2 = out[-2];
old_out3 = out[-1];
for (n = 0; n <= buffer_length - 4; n+=4) {
float tmp0,tmp1,tmp2;
float val;
out0 = in[0];
out1 = in[1];
out2 = in[2];
out3 = in[3];
out0 -= filter_coeffs[2] * old_out1;
out1 -= filter_coeffs[2] * old_out2;
out2 -= filter_coeffs[2] * old_out3;
out0 -= filter_coeffs[1] * old_out2;
out1 -= filter_coeffs[1] * old_out3;
out0 -= filter_coeffs[0] * old_out3;
val = filter_coeffs[3];
out0 -= val * old_out0;
out1 -= val * old_out1;
out2 -= val * old_out2;
out3 -= val * old_out3;
for (i = 5; i < filter_length; i += 2) {
old_out3 = out[-i];
val = filter_coeffs[i-1];
out0 -= val * old_out3;
out1 -= val * old_out0;
out2 -= val * old_out1;
out3 -= val * old_out2;
old_out2 = out[-i-1];
val = filter_coeffs[i];
out0 -= val * old_out2;
out1 -= val * old_out3;
out2 -= val * old_out0;
out3 -= val * old_out1;
FFSWAP(float, old_out0, old_out2);
old_out1 = old_out3;
}
tmp0 = out0;
tmp1 = out1;
tmp2 = out2;
out3 -= a * tmp2;
out2 -= a * tmp1;
out1 -= a * tmp0;
out3 -= b * tmp1;
out2 -= b * tmp0;
out3 -= c * tmp0;
out[0] = out0;
out[1] = out1;
out[2] = out2;
out[3] = out3;
old_out0 = out0;
old_out1 = out1;
old_out2 = out2;
old_out3 = out3;
out += 4;
in += 4;
}
out -= n;
in -= n;
for (; n < buffer_length; n++) {
out[n] = in[n];
for (i = 1; i <= filter_length; i++)
out[n] -= filter_coeffs[i-1] * out[n-i];
}
#endif
}
void ff_celp_lp_zero_synthesis_filterf(float *out, const float *filter_coeffs,
const float *in, int buffer_length,
int filter_length)
{
int i,n;
for (n = 0; n < buffer_length; n++) {
out[n] = in[n];
for (i = 1; i <= filter_length; i++)
out[n] += filter_coeffs[i-1] * in[n-i];
}
}
void ff_celp_filter_init(CELPFContext *c)
{
c->celp_lp_synthesis_filterf = ff_celp_lp_synthesis_filterf;
c->celp_lp_zero_synthesis_filterf = ff_celp_lp_zero_synthesis_filterf;
if(HAVE_MIPSFPU)
ff_celp_filter_init_mips(c);
}

View file

@ -0,0 +1,169 @@
/*
* various filters for CELP-based codecs
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_CELP_FILTERS_H
#define AVCODEC_CELP_FILTERS_H
#include <stdint.h>
typedef struct CELPFContext {
/**
* LP synthesis filter.
* @param[out] out pointer to output buffer
* - the array out[-filter_length, -1] must
* contain the previous result of this filter
* @param filter_coeffs filter coefficients.
* @param in input signal
* @param buffer_length amount of data to process
* @param filter_length filter length (10 for 10th order LP filter). Must be
* greater than 4 and even.
*
* @note Output buffer must contain filter_length samples of past
* speech data before pointer.
*
* Routine applies 1/A(z) filter to given speech data.
*/
void (*celp_lp_synthesis_filterf)(float *out, const float *filter_coeffs,
const float *in, int buffer_length,
int filter_length);
/**
* LP zero synthesis filter.
* @param[out] out pointer to output buffer
* @param filter_coeffs filter coefficients.
* @param in input signal
* - the array in[-filter_length, -1] must
* contain the previous input of this filter
* @param buffer_length amount of data to process (should be a multiple of eight)
* @param filter_length filter length (10 for 10th order LP filter;
* should be a multiple of two)
*
* @note Output buffer must contain filter_length samples of past
* speech data before pointer.
*
* Routine applies A(z) filter to given speech data.
*/
void (*celp_lp_zero_synthesis_filterf)(float *out, const float *filter_coeffs,
const float *in, int buffer_length,
int filter_length);
}CELPFContext;
/**
* Initialize CELPFContext.
*/
void ff_celp_filter_init(CELPFContext *c);
void ff_celp_filter_init_mips(CELPFContext *c);
/**
* Circularly convolve fixed vector with a phase dispersion impulse
* response filter (D.6.2 of G.729 and 6.1.5 of AMR).
* @param fc_out vector with filter applied
* @param fc_in source vector
* @param filter phase filter coefficients
*
* fc_out[n] = sum(i,0,len-1){ fc_in[i] * filter[(len + n - i)%len] }
*
* @note fc_in and fc_out should not overlap!
*/
void ff_celp_convolve_circ(int16_t *fc_out, const int16_t *fc_in,
const int16_t *filter, int len);
/**
* Add an array to a rotated array.
*
* out[k] = in[k] + fac * lagged[k-lag] with wrap-around
*
* @param out result vector
* @param in samples to be added unfiltered
* @param lagged samples to be rotated, multiplied and added
* @param lag lagged vector delay in the range [0, n]
* @param fac scalefactor for lagged samples
* @param n number of samples
*/
void ff_celp_circ_addf(float *out, const float *in,
const float *lagged, int lag, float fac, int n);
/**
* LP synthesis filter.
* @param[out] out pointer to output buffer
* @param filter_coeffs filter coefficients (-0x8000 <= (3.12) < 0x8000)
* @param in input signal
* @param buffer_length amount of data to process
* @param filter_length filter length (10 for 10th order LP filter)
* @param stop_on_overflow 1 - return immediately if overflow occurs
* 0 - ignore overflows
* @param shift the result is shifted right by this value
* @param rounder the amount to add for rounding (usually 0x800 or 0xfff)
*
* @return 1 if overflow occurred, 0 - otherwise
*
* @note Output buffer must contain filter_length samples of past
* speech data before pointer.
*
* Routine applies 1/A(z) filter to given speech data.
*/
int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs,
const int16_t *in, int buffer_length,
int filter_length, int stop_on_overflow,
int shift, int rounder);
/**
* LP synthesis filter.
* @param[out] out pointer to output buffer
* - the array out[-filter_length, -1] must
* contain the previous result of this filter
* @param filter_coeffs filter coefficients.
* @param in input signal
* @param buffer_length amount of data to process
* @param filter_length filter length (10 for 10th order LP filter). Must be
* greater than 4 and even.
*
* @note Output buffer must contain filter_length samples of past
* speech data before pointer.
*
* Routine applies 1/A(z) filter to given speech data.
*/
void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs,
const float *in, int buffer_length,
int filter_length);
/**
* LP zero synthesis filter.
* @param[out] out pointer to output buffer
* @param filter_coeffs filter coefficients.
* @param in input signal
* - the array in[-filter_length, -1] must
* contain the previous input of this filter
* @param buffer_length amount of data to process
* @param filter_length filter length (10 for 10th order LP filter)
*
* @note Output buffer must contain filter_length samples of past
* speech data before pointer.
*
* Routine applies A(z) filter to given speech data.
*/
void ff_celp_lp_zero_synthesis_filterf(float *out, const float *filter_coeffs,
const float *in, int buffer_length,
int filter_length);
#endif /* AVCODEC_CELP_FILTERS_H */

View file

@ -0,0 +1,126 @@
/*
* Various fixed-point math operations
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include <limits.h>
#include "libavutil/avassert.h"
#include "avcodec.h"
#include "mathops.h"
#include "celp_math.h"
#include "libavutil/common.h"
static const uint16_t exp2a[]=
{
0, 1435, 2901, 4400, 5931, 7496, 9096, 10730,
12400, 14106, 15850, 17632, 19454, 21315, 23216, 25160,
27146, 29175, 31249, 33368, 35534, 37747, 40009, 42320,
44682, 47095, 49562, 52082, 54657, 57289, 59979, 62727,
};
static const uint16_t exp2b[]=
{
3, 712, 1424, 2134, 2845, 3557, 4270, 4982,
5696, 6409, 7124, 7839, 8554, 9270, 9986, 10704,
11421, 12138, 12857, 13576, 14295, 15014, 15734, 16455,
17176, 17898, 18620, 19343, 20066, 20790, 21514, 22238,
};
int ff_exp2(uint16_t power)
{
unsigned int result= exp2a[power>>10] + 0x10000;
av_assert2(power <= 0x7fff);
result= (result<<3) + ((result*exp2b[(power>>5)&31])>>17);
return result + ((result*(power&31)*89)>>22);
}
/**
* Table used to compute log2(x)
*
* tab_log2[i] = (1<<15) * log2(1 + i/32), i=0..32
*/
static const uint16_t tab_log2[33] =
{
#ifdef G729_BITEXACT
0, 1455, 2866, 4236, 5568, 6863, 8124, 9352,
10549, 11716, 12855, 13967, 15054, 16117, 17156, 18172,
19167, 20142, 21097, 22033, 22951, 23852, 24735, 25603,
26455, 27291, 28113, 28922, 29716, 30497, 31266, 32023, 32767,
#else
4, 1459, 2870, 4240, 5572, 6867, 8127, 9355,
10552, 11719, 12858, 13971, 15057, 16120, 17158, 18175,
19170, 20145, 21100, 22036, 22954, 23854, 24738, 25605,
26457, 27294, 28116, 28924, 29719, 30500, 31269, 32025, 32769,
#endif
};
int ff_log2_q15(uint32_t value)
{
uint8_t power_int;
uint8_t frac_x0;
uint16_t frac_dx;
// Stripping zeros from beginning
power_int = av_log2(value);
value <<= (31 - power_int);
// b31 is always non-zero now
frac_x0 = (value & 0x7c000000) >> 26; // b26-b31 and [32..63] -> [0..31]
frac_dx = (value & 0x03fff800) >> 11;
value = tab_log2[frac_x0];
value += (frac_dx * (tab_log2[frac_x0+1] - tab_log2[frac_x0])) >> 15;
return (power_int << 15) + value;
}
int64_t ff_dot_product(const int16_t *a, const int16_t *b, int length)
{
int i;
int64_t sum = 0;
for (i = 0; i < length; i++)
sum += MUL16(a[i], b[i]);
return sum;
}
float ff_dot_productf(const float* a, const float* b, int length)
{
float sum = 0;
int i;
for(i=0; i<length; i++)
sum += a[i] * b[i];
return sum;
}
void ff_celp_math_init(CELPMContext *c)
{
c->dot_productf = ff_dot_productf;
if(HAVE_MIPSFPU)
ff_celp_math_init_mips(c);
}

View file

@ -0,0 +1,97 @@
/*
* Various fixed-point math operations
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_CELP_MATH_H
#define AVCODEC_CELP_MATH_H
#include <stdint.h>
typedef struct CELPMContext {
/**
* Return the dot product.
* @param a input data array
* @param b input data array
* @param length number of elements
*
* @return dot product = sum of elementwise products
*/
float (*dot_productf)(const float* a, const float* b, int length);
}CELPMContext;
/**
* Initialize CELPMContext.
*/
void ff_celp_math_init(CELPMContext *c);
void ff_celp_math_init_mips(CELPMContext *c);
/**
* fixed-point implementation of exp2(x) in [0; 1] domain.
* @param power argument to exp2, 0 <= power <= 0x7fff
*
* @return value of (1<<20) * exp2(power / (1<<15))
* 0x8000c <= result <= 0xfffea
*/
int ff_exp2(uint16_t power);
/**
* Calculate log2(x).
* @param value function argument, 0 < value <= 7fff ffff
*
* @return value of (1<<15) * log2(value)
*/
int ff_log2_q15(uint32_t value);
/**
* Shift value left or right depending on sign of offset parameter.
* @param value value to shift
* @param offset shift offset
*
* @return value << offset, if offset>=0; value >> -offset - otherwise
*/
static inline int bidir_sal(int value, int offset)
{
if(offset < 0) return value >> -offset;
else return value << offset;
}
/**
* returns the dot product of 2 int16_t vectors.
* @param a input data array
* @param b input data array
* @param length number of elements
*
* @return dot product = sum of elementwise products
*/
int64_t ff_dot_product(const int16_t *a, const int16_t *b, int length);
/**
* Return the dot product.
* @param a input data array
* @param b input data array
* @param length number of elements
*
* @return dot product = sum of elementwise products
*/
float ff_dot_productf(const float* a, const float* b, int length);
#endif /* AVCODEC_CELP_MATH_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,94 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_COPY_BLOCK_H
#define AVCODEC_COPY_BLOCK_H
#include <stdint.h>
#include "libavutil/intreadwrite.h"
static inline void copy_block2(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_COPY16U(dst, src);
dst+=dstStride;
src+=srcStride;
}
}
static inline void copy_block4(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_COPY32U(dst, src);
dst+=dstStride;
src+=srcStride;
}
}
static inline void copy_block8(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_COPY64U(dst, src);
dst+=dstStride;
src+=srcStride;
}
}
static inline void copy_block16(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_COPY128U(dst, src);
dst+=dstStride;
src+=srcStride;
}
}
static inline void copy_block9(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_COPY64U(dst, src);
dst[8]= src[8];
dst+=dstStride;
src+=srcStride;
}
}
static inline void copy_block17(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_COPY128U(dst, src);
dst[16]= src[16];
dst+=dstStride;
src+=srcStride;
}
}
#endif /* AVCODEC_COPY_BLOCK_H */

View file

@ -0,0 +1,222 @@
/*
* (I)DCT Transforms
* Copyright (c) 2009 Peter Ross <pross@xvid.org>
* Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
* Copyright (c) 2010 Vitor Sessak
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* (Inverse) Discrete Cosine Transforms. These are also known as the
* type II and type III DCTs respectively.
*/
#include <math.h>
#include <string.h>
#include "libavutil/mathematics.h"
#include "dct.h"
#include "dct32.h"
/* sin((M_PI * x / (2 * n)) */
#define SIN(s, n, x) (s->costab[(n) - (x)])
/* cos((M_PI * x / (2 * n)) */
#define COS(s, n, x) (s->costab[x])
static void dst_calc_I_c(DCTContext *ctx, FFTSample *data)
{
int n = 1 << ctx->nbits;
int i;
data[0] = 0;
for (i = 1; i < n / 2; i++) {
float tmp1 = data[i ];
float tmp2 = data[n - i];
float s = SIN(ctx, n, 2 * i);
s *= tmp1 + tmp2;
tmp1 = (tmp1 - tmp2) * 0.5f;
data[i] = s + tmp1;
data[n - i] = s - tmp1;
}
data[n / 2] *= 2;
ctx->rdft.rdft_calc(&ctx->rdft, data);
data[0] *= 0.5f;
for (i = 1; i < n - 2; i += 2) {
data[i + 1] += data[i - 1];
data[i] = -data[i + 2];
}
data[n - 1] = 0;
}
static void dct_calc_I_c(DCTContext *ctx, FFTSample *data)
{
int n = 1 << ctx->nbits;
int i;
float next = -0.5f * (data[0] - data[n]);
for (i = 0; i < n / 2; i++) {
float tmp1 = data[i];
float tmp2 = data[n - i];
float s = SIN(ctx, n, 2 * i);
float c = COS(ctx, n, 2 * i);
c *= tmp1 - tmp2;
s *= tmp1 - tmp2;
next += c;
tmp1 = (tmp1 + tmp2) * 0.5f;
data[i] = tmp1 - s;
data[n - i] = tmp1 + s;
}
ctx->rdft.rdft_calc(&ctx->rdft, data);
data[n] = data[1];
data[1] = next;
for (i = 3; i <= n; i += 2)
data[i] = data[i - 2] - data[i];
}
static void dct_calc_III_c(DCTContext *ctx, FFTSample *data)
{
int n = 1 << ctx->nbits;
int i;
float next = data[n - 1];
float inv_n = 1.0f / n;
for (i = n - 2; i >= 2; i -= 2) {
float val1 = data[i];
float val2 = data[i - 1] - data[i + 1];
float c = COS(ctx, n, i);
float s = SIN(ctx, n, i);
data[i] = c * val1 + s * val2;
data[i + 1] = s * val1 - c * val2;
}
data[1] = 2 * next;
ctx->rdft.rdft_calc(&ctx->rdft, data);
for (i = 0; i < n / 2; i++) {
float tmp1 = data[i] * inv_n;
float tmp2 = data[n - i - 1] * inv_n;
float csc = ctx->csc2[i] * (tmp1 - tmp2);
tmp1 += tmp2;
data[i] = tmp1 + csc;
data[n - i - 1] = tmp1 - csc;
}
}
static void dct_calc_II_c(DCTContext *ctx, FFTSample *data)
{
int n = 1 << ctx->nbits;
int i;
float next;
for (i = 0; i < n / 2; i++) {
float tmp1 = data[i];
float tmp2 = data[n - i - 1];
float s = SIN(ctx, n, 2 * i + 1);
s *= tmp1 - tmp2;
tmp1 = (tmp1 + tmp2) * 0.5f;
data[i] = tmp1 + s;
data[n-i-1] = tmp1 - s;
}
ctx->rdft.rdft_calc(&ctx->rdft, data);
next = data[1] * 0.5;
data[1] *= -1;
for (i = n - 2; i >= 0; i -= 2) {
float inr = data[i ];
float ini = data[i + 1];
float c = COS(ctx, n, i);
float s = SIN(ctx, n, i);
data[i] = c * inr + s * ini;
data[i + 1] = next;
next += s * inr - c * ini;
}
}
static void dct32_func(DCTContext *ctx, FFTSample *data)
{
ctx->dct32(data, data);
}
av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse)
{
int n = 1 << nbits;
int i;
memset(s, 0, sizeof(*s));
s->nbits = nbits;
s->inverse = inverse;
if (inverse == DCT_II && nbits == 5) {
s->dct_calc = dct32_func;
} else {
ff_init_ff_cos_tabs(nbits + 2);
s->costab = ff_cos_tabs[nbits + 2];
s->csc2 = av_malloc(n / 2 * sizeof(FFTSample));
if (ff_rdft_init(&s->rdft, nbits, inverse == DCT_III) < 0) {
av_free(s->csc2);
return -1;
}
for (i = 0; i < n / 2; i++)
s->csc2[i] = 0.5 / sin((M_PI / (2 * n) * (2 * i + 1)));
switch (inverse) {
case DCT_I : s->dct_calc = dct_calc_I_c; break;
case DCT_II : s->dct_calc = dct_calc_II_c; break;
case DCT_III: s->dct_calc = dct_calc_III_c; break;
case DST_I : s->dct_calc = dst_calc_I_c; break;
}
}
s->dct32 = ff_dct32_float;
if (ARCH_X86)
ff_dct_init_x86(s);
return 0;
}
av_cold void ff_dct_end(DCTContext *s)
{
ff_rdft_end(&s->rdft);
av_free(s->csc2);
}

View file

@ -0,0 +1,70 @@
/*
* (I)DCT Transforms
* Copyright (c) 2009 Peter Ross <pross@xvid.org>
* Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
* Copyright (c) 2010 Vitor Sessak
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_DCT_H
#define AVCODEC_DCT_H
#include <stdint.h>
#include "rdft.h"
struct DCTContext {
int nbits;
int inverse;
RDFTContext rdft;
const float *costab;
FFTSample *csc2;
void (*dct_calc)(struct DCTContext *s, FFTSample *data);
void (*dct32)(FFTSample *out, const FFTSample *in);
};
/**
* Set up DCT.
* @param nbits size of the input array:
* (1 << nbits) for DCT-II, DCT-III and DST-I
* (1 << nbits) + 1 for DCT-I
*
* @note the first element of the input of DST-I is ignored
*/
int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType type);
void ff_dct_end (DCTContext *s);
void ff_dct_init_x86(DCTContext *s);
void ff_fdct_ifast(int16_t *data);
void ff_fdct_ifast248(int16_t *data);
void ff_jpeg_fdct_islow_8(int16_t *data);
void ff_jpeg_fdct_islow_10(int16_t *data);
void ff_fdct248_islow_8(int16_t *data);
void ff_fdct248_islow_10(int16_t *data);
void ff_j_rev_dct(int16_t *data);
void ff_j_rev_dct4(int16_t *data);
void ff_j_rev_dct2(int16_t *data);
void ff_j_rev_dct1(int16_t *data);
void ff_fdct_mmx(int16_t *block);
void ff_fdct_mmxext(int16_t *block);
void ff_fdct_sse2(int16_t *block);
#endif /* AVCODEC_DCT_H */

View file

@ -0,0 +1,276 @@
/*
* Template for the Discrete Cosine Transform for 32 samples
* Copyright (c) 2001, 2002 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dct32.h"
#include "mathops.h"
#if DCT32_FLOAT
# define dct32 ff_dct32_float
# define FIXHR(x) ((float)(x))
# define MULH3(x, y, s) ((s)*(y)*(x))
# define INTFLOAT float
#else
# define dct32 ff_dct32_fixed
# define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5))
# define MULH3(x, y, s) MULH((s)*(x), y)
# define INTFLOAT int
#endif
/* tab[i][j] = 1.0 / (2.0 * cos(pi*(2*k+1) / 2^(6 - j))) */
/* cos(i*pi/64) */
#define COS0_0 FIXHR(0.50060299823519630134/2)
#define COS0_1 FIXHR(0.50547095989754365998/2)
#define COS0_2 FIXHR(0.51544730992262454697/2)
#define COS0_3 FIXHR(0.53104259108978417447/2)
#define COS0_4 FIXHR(0.55310389603444452782/2)
#define COS0_5 FIXHR(0.58293496820613387367/2)
#define COS0_6 FIXHR(0.62250412303566481615/2)
#define COS0_7 FIXHR(0.67480834145500574602/2)
#define COS0_8 FIXHR(0.74453627100229844977/2)
#define COS0_9 FIXHR(0.83934964541552703873/2)
#define COS0_10 FIXHR(0.97256823786196069369/2)
#define COS0_11 FIXHR(1.16943993343288495515/4)
#define COS0_12 FIXHR(1.48416461631416627724/4)
#define COS0_13 FIXHR(2.05778100995341155085/8)
#define COS0_14 FIXHR(3.40760841846871878570/8)
#define COS0_15 FIXHR(10.19000812354805681150/32)
#define COS1_0 FIXHR(0.50241928618815570551/2)
#define COS1_1 FIXHR(0.52249861493968888062/2)
#define COS1_2 FIXHR(0.56694403481635770368/2)
#define COS1_3 FIXHR(0.64682178335999012954/2)
#define COS1_4 FIXHR(0.78815462345125022473/2)
#define COS1_5 FIXHR(1.06067768599034747134/4)
#define COS1_6 FIXHR(1.72244709823833392782/4)
#define COS1_7 FIXHR(5.10114861868916385802/16)
#define COS2_0 FIXHR(0.50979557910415916894/2)
#define COS2_1 FIXHR(0.60134488693504528054/2)
#define COS2_2 FIXHR(0.89997622313641570463/2)
#define COS2_3 FIXHR(2.56291544774150617881/8)
#define COS3_0 FIXHR(0.54119610014619698439/2)
#define COS3_1 FIXHR(1.30656296487637652785/4)
#define COS4_0 FIXHR(0.70710678118654752439/2)
/* butterfly operator */
#define BF(a, b, c, s)\
{\
tmp0 = val##a + val##b;\
tmp1 = val##a - val##b;\
val##a = tmp0;\
val##b = MULH3(tmp1, c, 1<<(s));\
}
#define BF0(a, b, c, s)\
{\
tmp0 = tab[a] + tab[b];\
tmp1 = tab[a] - tab[b];\
val##a = tmp0;\
val##b = MULH3(tmp1, c, 1<<(s));\
}
#define BF1(a, b, c, d)\
{\
BF(a, b, COS4_0, 1);\
BF(c, d,-COS4_0, 1);\
val##c += val##d;\
}
#define BF2(a, b, c, d)\
{\
BF(a, b, COS4_0, 1);\
BF(c, d,-COS4_0, 1);\
val##c += val##d;\
val##a += val##c;\
val##c += val##b;\
val##b += val##d;\
}
#define ADD(a, b) val##a += val##b
/* DCT32 without 1/sqrt(2) coef zero scaling. */
void dct32(INTFLOAT *out, const INTFLOAT *tab)
{
INTFLOAT tmp0, tmp1;
INTFLOAT val0 , val1 , val2 , val3 , val4 , val5 , val6 , val7 ,
val8 , val9 , val10, val11, val12, val13, val14, val15,
val16, val17, val18, val19, val20, val21, val22, val23,
val24, val25, val26, val27, val28, val29, val30, val31;
/* pass 1 */
BF0( 0, 31, COS0_0 , 1);
BF0(15, 16, COS0_15, 5);
/* pass 2 */
BF( 0, 15, COS1_0 , 1);
BF(16, 31,-COS1_0 , 1);
/* pass 1 */
BF0( 7, 24, COS0_7 , 1);
BF0( 8, 23, COS0_8 , 1);
/* pass 2 */
BF( 7, 8, COS1_7 , 4);
BF(23, 24,-COS1_7 , 4);
/* pass 3 */
BF( 0, 7, COS2_0 , 1);
BF( 8, 15,-COS2_0 , 1);
BF(16, 23, COS2_0 , 1);
BF(24, 31,-COS2_0 , 1);
/* pass 1 */
BF0( 3, 28, COS0_3 , 1);
BF0(12, 19, COS0_12, 2);
/* pass 2 */
BF( 3, 12, COS1_3 , 1);
BF(19, 28,-COS1_3 , 1);
/* pass 1 */
BF0( 4, 27, COS0_4 , 1);
BF0(11, 20, COS0_11, 2);
/* pass 2 */
BF( 4, 11, COS1_4 , 1);
BF(20, 27,-COS1_4 , 1);
/* pass 3 */
BF( 3, 4, COS2_3 , 3);
BF(11, 12,-COS2_3 , 3);
BF(19, 20, COS2_3 , 3);
BF(27, 28,-COS2_3 , 3);
/* pass 4 */
BF( 0, 3, COS3_0 , 1);
BF( 4, 7,-COS3_0 , 1);
BF( 8, 11, COS3_0 , 1);
BF(12, 15,-COS3_0 , 1);
BF(16, 19, COS3_0 , 1);
BF(20, 23,-COS3_0 , 1);
BF(24, 27, COS3_0 , 1);
BF(28, 31,-COS3_0 , 1);
/* pass 1 */
BF0( 1, 30, COS0_1 , 1);
BF0(14, 17, COS0_14, 3);
/* pass 2 */
BF( 1, 14, COS1_1 , 1);
BF(17, 30,-COS1_1 , 1);
/* pass 1 */
BF0( 6, 25, COS0_6 , 1);
BF0( 9, 22, COS0_9 , 1);
/* pass 2 */
BF( 6, 9, COS1_6 , 2);
BF(22, 25,-COS1_6 , 2);
/* pass 3 */
BF( 1, 6, COS2_1 , 1);
BF( 9, 14,-COS2_1 , 1);
BF(17, 22, COS2_1 , 1);
BF(25, 30,-COS2_1 , 1);
/* pass 1 */
BF0( 2, 29, COS0_2 , 1);
BF0(13, 18, COS0_13, 3);
/* pass 2 */
BF( 2, 13, COS1_2 , 1);
BF(18, 29,-COS1_2 , 1);
/* pass 1 */
BF0( 5, 26, COS0_5 , 1);
BF0(10, 21, COS0_10, 1);
/* pass 2 */
BF( 5, 10, COS1_5 , 2);
BF(21, 26,-COS1_5 , 2);
/* pass 3 */
BF( 2, 5, COS2_2 , 1);
BF(10, 13,-COS2_2 , 1);
BF(18, 21, COS2_2 , 1);
BF(26, 29,-COS2_2 , 1);
/* pass 4 */
BF( 1, 2, COS3_1 , 2);
BF( 5, 6,-COS3_1 , 2);
BF( 9, 10, COS3_1 , 2);
BF(13, 14,-COS3_1 , 2);
BF(17, 18, COS3_1 , 2);
BF(21, 22,-COS3_1 , 2);
BF(25, 26, COS3_1 , 2);
BF(29, 30,-COS3_1 , 2);
/* pass 5 */
BF1( 0, 1, 2, 3);
BF2( 4, 5, 6, 7);
BF1( 8, 9, 10, 11);
BF2(12, 13, 14, 15);
BF1(16, 17, 18, 19);
BF2(20, 21, 22, 23);
BF1(24, 25, 26, 27);
BF2(28, 29, 30, 31);
/* pass 6 */
ADD( 8, 12);
ADD(12, 10);
ADD(10, 14);
ADD(14, 9);
ADD( 9, 13);
ADD(13, 11);
ADD(11, 15);
out[ 0] = val0;
out[16] = val1;
out[ 8] = val2;
out[24] = val3;
out[ 4] = val4;
out[20] = val5;
out[12] = val6;
out[28] = val7;
out[ 2] = val8;
out[18] = val9;
out[10] = val10;
out[26] = val11;
out[ 6] = val12;
out[22] = val13;
out[14] = val14;
out[30] = val15;
ADD(24, 28);
ADD(28, 26);
ADD(26, 30);
ADD(30, 25);
ADD(25, 29);
ADD(29, 27);
ADD(27, 31);
out[ 1] = val16 + val24;
out[17] = val17 + val25;
out[ 9] = val18 + val26;
out[25] = val19 + val27;
out[ 5] = val20 + val28;
out[21] = val21 + val29;
out[13] = val22 + val30;
out[29] = val23 + val31;
out[ 3] = val24 + val20;
out[19] = val25 + val21;
out[11] = val26 + val22;
out[27] = val27 + val23;
out[ 7] = val28 + val18;
out[23] = val29 + val19;
out[15] = val30 + val17;
out[31] = val31;
}

View file

@ -0,0 +1,25 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_DCT32_H
#define AVCODEC_DCT32_H
void ff_dct32_float(float *dst, const float *src);
void ff_dct32_fixed(int *dst, const int *src);
#endif

View file

@ -0,0 +1,20 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define DCT32_FLOAT 1
#include "dct32.c"

View file

@ -0,0 +1,123 @@
/*
* reference discrete cosine transform (double precision)
* Copyright (C) 2009 Dylan Yudaken
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* reference discrete cosine transform (double precision)
*
* @author Dylan Yudaken (dyudaken at gmail)
*
* @note This file could be optimized a lot, but is for
* reference and so readability is better.
*/
#include "libavutil/mathematics.h"
#include "dctref.h"
static double coefficients[8 * 8];
/**
* Initialize the double precision discrete cosine transform
* functions fdct & idct.
*/
av_cold void ff_ref_dct_init(void)
{
unsigned int i, j;
for (j = 0; j < 8; ++j) {
coefficients[j] = sqrt(0.125);
for (i = 8; i < 64; i += 8) {
coefficients[i + j] = 0.5 * cos(i * (j + 0.5) * M_PI / 64.0);
}
}
}
/**
* Transform 8x8 block of data with a double precision forward DCT <br>
* This is a reference implementation.
*
* @param block pointer to 8x8 block of data to transform
*/
void ff_ref_fdct(short *block)
{
/* implement the equation: block = coefficients * block * coefficients' */
unsigned int i, j, k;
double out[8 * 8];
/* out = coefficients * block */
for (i = 0; i < 64; i += 8) {
for (j = 0; j < 8; ++j) {
double tmp = 0;
for (k = 0; k < 8; ++k) {
tmp += coefficients[i + k] * block[k * 8 + j];
}
out[i + j] = tmp * 8;
}
}
/* block = out * (coefficients') */
for (j = 0; j < 8; ++j) {
for (i = 0; i < 64; i += 8) {
double tmp = 0;
for (k = 0; k < 8; ++k) {
tmp += out[i + k] * coefficients[j * 8 + k];
}
block[i + j] = floor(tmp + 0.499999999999);
}
}
}
/**
* Transform 8x8 block of data with a double precision inverse DCT <br>
* This is a reference implementation.
*
* @param block pointer to 8x8 block of data to transform
*/
void ff_ref_idct(short *block)
{
/* implement the equation: block = (coefficients') * block * coefficients */
unsigned int i, j, k;
double out[8 * 8];
/* out = block * coefficients */
for (i = 0; i < 64; i += 8) {
for (j = 0; j < 8; ++j) {
double tmp = 0;
for (k = 0; k < 8; ++k) {
tmp += block[i + k] * coefficients[k * 8 + j];
}
out[i + j] = tmp;
}
}
/* block = (coefficients') * out */
for (i = 0; i < 8; ++i) {
for (j = 0; j < 8; ++j) {
double tmp = 0;
for (k = 0; k < 64; k += 8) {
tmp += coefficients[k + i] * out[k + j];
}
block[i * 8 + j] = floor(tmp + 0.5);
}
}
}

View file

@ -0,0 +1,29 @@
/*
* reference discrete cosine transform (double precision)
* Copyright (C) 2009 Dylan Yudaken
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_DCTREF_H
#define AVCODEC_DCTREF_H
void ff_ref_fdct(short *block);
void ff_ref_idct(short *block);
void ff_ref_dct_init(void);
#endif /* AVCODEC_DCTREF_H */

View file

@ -0,0 +1,203 @@
/*
* Copyright (C) 2009 David Conrad
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "dsputil.h"
#include "diracdsp.h"
#include "libavcodec/x86/diracdsp_mmx.h"
#define FILTER(src, stride) \
((21*((src)[ 0*stride] + (src)[1*stride]) \
-7*((src)[-1*stride] + (src)[2*stride]) \
+3*((src)[-2*stride] + (src)[3*stride]) \
-1*((src)[-3*stride] + (src)[4*stride]) + 16) >> 5)
static void dirac_hpel_filter(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, const uint8_t *src,
int stride, int width, int height)
{
int x, y;
for (y = 0; y < height; y++) {
for (x = -3; x < width+5; x++)
dstv[x] = av_clip_uint8(FILTER(src+x, stride));
for (x = 0; x < width; x++)
dstc[x] = av_clip_uint8(FILTER(dstv+x, 1));
for (x = 0; x < width; x++)
dsth[x] = av_clip_uint8(FILTER(src+x, 1));
src += stride;
dsth += stride;
dstv += stride;
dstc += stride;
}
}
#define PIXOP_BILINEAR(PFX, OP, WIDTH) \
static void ff_ ## PFX ## _dirac_pixels ## WIDTH ## _bilinear_c(uint8_t *dst, const uint8_t *src[5], int stride, int h) \
{ \
int x; \
const uint8_t *s0 = src[0]; \
const uint8_t *s1 = src[1]; \
const uint8_t *s2 = src[2]; \
const uint8_t *s3 = src[3]; \
const uint8_t *w = src[4]; \
\
while (h--) { \
for (x = 0; x < WIDTH; x++) { \
OP(dst[x], (s0[x]*w[0] + s1[x]*w[1] + s2[x]*w[2] + s3[x]*w[3] + 8) >> 4); \
} \
\
dst += stride; \
s0 += stride; \
s1 += stride; \
s2 += stride; \
s3 += stride; \
} \
}
#define OP_PUT(dst, val) (dst) = (val)
#define OP_AVG(dst, val) (dst) = (((dst) + (val) + 1)>>1)
PIXOP_BILINEAR(put, OP_PUT, 8)
PIXOP_BILINEAR(put, OP_PUT, 16)
PIXOP_BILINEAR(put, OP_PUT, 32)
PIXOP_BILINEAR(avg, OP_AVG, 8)
PIXOP_BILINEAR(avg, OP_AVG, 16)
PIXOP_BILINEAR(avg, OP_AVG, 32)
#define op_scale1(x) block[x] = av_clip_uint8( (block[x]*weight + (1<<(log2_denom-1))) >> log2_denom)
#define op_scale2(x) dst[x] = av_clip_uint8( (src[x]*weights + dst[x]*weightd + (1<<(log2_denom-1))) >> log2_denom)
#define DIRAC_WEIGHT(W) \
static void weight_dirac_pixels ## W ## _c(uint8_t *block, int stride, int log2_denom, \
int weight, int h) { \
int x; \
while (h--) { \
for (x = 0; x < W; x++) { \
op_scale1(x); \
op_scale1(x+1); \
} \
block += stride; \
} \
} \
static void biweight_dirac_pixels ## W ## _c(uint8_t *dst, const uint8_t *src, int stride, int log2_denom, \
int weightd, int weights, int h) { \
int x; \
while (h--) { \
for (x = 0; x < W; x++) { \
op_scale2(x); \
op_scale2(x+1); \
} \
dst += stride; \
src += stride; \
} \
}
DIRAC_WEIGHT(8)
DIRAC_WEIGHT(16)
DIRAC_WEIGHT(32)
#define ADD_OBMC(xblen) \
static void add_obmc ## xblen ## _c(uint16_t *dst, const uint8_t *src, int stride, \
const uint8_t *obmc_weight, int yblen) \
{ \
int x; \
while (yblen--) { \
for (x = 0; x < xblen; x += 2) { \
dst[x ] += src[x ] * obmc_weight[x ]; \
dst[x+1] += src[x+1] * obmc_weight[x+1]; \
} \
dst += stride; \
src += stride; \
obmc_weight += 32; \
} \
}
ADD_OBMC(8)
ADD_OBMC(16)
ADD_OBMC(32)
static void put_signed_rect_clamped_c(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height)
{
int x, y;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x+=4) {
dst[x ] = av_clip_uint8(src[x ] + 128);
dst[x+1] = av_clip_uint8(src[x+1] + 128);
dst[x+2] = av_clip_uint8(src[x+2] + 128);
dst[x+3] = av_clip_uint8(src[x+3] + 128);
}
dst += dst_stride;
src += src_stride;
}
}
static void add_rect_clamped_c(uint8_t *dst, const uint16_t *src, int stride,
const int16_t *idwt, int idwt_stride,
int width, int height)
{
int x, y;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x+=2) {
dst[x ] = av_clip_uint8(((src[x ]+32)>>6) + idwt[x ]);
dst[x+1] = av_clip_uint8(((src[x+1]+32)>>6) + idwt[x+1]);
}
dst += stride;
src += stride;
idwt += idwt_stride;
}
}
#define PIXFUNC(PFX, WIDTH) \
c->PFX ## _dirac_pixels_tab[WIDTH>>4][0] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _c; \
c->PFX ## _dirac_pixels_tab[WIDTH>>4][1] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _l2_c; \
c->PFX ## _dirac_pixels_tab[WIDTH>>4][2] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _l4_c; \
c->PFX ## _dirac_pixels_tab[WIDTH>>4][3] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _bilinear_c
void ff_diracdsp_init(DiracDSPContext *c)
{
c->dirac_hpel_filter = dirac_hpel_filter;
c->add_rect_clamped = add_rect_clamped_c;
c->put_signed_rect_clamped = put_signed_rect_clamped_c;
c->add_dirac_obmc[0] = add_obmc8_c;
c->add_dirac_obmc[1] = add_obmc16_c;
c->add_dirac_obmc[2] = add_obmc32_c;
c->weight_dirac_pixels_tab[0] = weight_dirac_pixels8_c;
c->weight_dirac_pixels_tab[1] = weight_dirac_pixels16_c;
c->weight_dirac_pixels_tab[2] = weight_dirac_pixels32_c;
c->biweight_dirac_pixels_tab[0] = biweight_dirac_pixels8_c;
c->biweight_dirac_pixels_tab[1] = biweight_dirac_pixels16_c;
c->biweight_dirac_pixels_tab[2] = biweight_dirac_pixels32_c;
PIXFUNC(put, 8);
PIXFUNC(put, 16);
PIXFUNC(put, 32);
PIXFUNC(avg, 8);
PIXFUNC(avg, 16);
PIXFUNC(avg, 32);
if (HAVE_MMX && HAVE_YASM) ff_diracdsp_init_mmx(c);
}

View file

@ -0,0 +1,67 @@
/*
* Copyright (C) 2010 David Conrad
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_DIRACDSP_H
#define AVCODEC_DIRACDSP_H
#include <stdint.h>
typedef void (*dirac_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int h);
typedef void (*dirac_biweight_func)(uint8_t *dst, const uint8_t *src, int stride, int log2_denom, int weightd, int weights, int h);
typedef struct {
void (*dirac_hpel_filter)(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, const uint8_t *src, int stride, int width, int height);
/**
* dirac_pixels_tab[width][subpel]
* width is 2 for 32, 1 for 16, 0 for 8
* subpel is 0 for fpel and hpel (only need to copy from the first plane in src)
* 1 if an average of the first 2 planes is needed (TODO: worth it?)
* 2 for general qpel (avg of 4)
* 3 for general epel (biweight of 4 using the weights in src[4])
* src[0-3] is each of the hpel planes
* src[4] is the 1/8 pel weights if needed
*/
void (*put_dirac_pixels_tab[3][4])(uint8_t *dst, const uint8_t *src[5], int stride, int h);
void (*avg_dirac_pixels_tab[3][4])(uint8_t *dst, const uint8_t *src[5], int stride, int h);
void (*put_signed_rect_clamped)(uint8_t *dst/*align 16*/, int dst_stride, const int16_t *src/*align 16*/, int src_stride, int width, int height/*mod 2*/);
void (*put_rect_clamped)(uint8_t *dst/*align 16*/, int dst_stride, const int16_t *src/*align 16*/, int src_stride, int width, int height/*mod 2*/);
void (*add_rect_clamped)(uint8_t *dst/*align 16*/, const uint16_t *src/*align 16*/, int stride, const int16_t *idwt/*align 16*/, int idwt_stride, int width, int height/*mod 2*/);
void (*add_dirac_obmc[3])(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen);
dirac_weight_func weight_dirac_pixels_tab[3];
dirac_biweight_func biweight_dirac_pixels_tab[3];
} DiracDSPContext;
#define DECL_DIRAC_PIXOP(PFX, EXT) \
void ff_ ## PFX ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h); \
void ff_ ## PFX ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h); \
void ff_ ## PFX ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)
DECL_DIRAC_PIXOP(put, c);
DECL_DIRAC_PIXOP(avg, c);
DECL_DIRAC_PIXOP(put, l2_c);
DECL_DIRAC_PIXOP(avg, l2_c);
DECL_DIRAC_PIXOP(put, l4_c);
DECL_DIRAC_PIXOP(avg, l4_c);
void ff_diracdsp_init(DiracDSPContext *c);
#endif /* AVCODEC_DIRACDSP_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,332 @@
/*
* DSP utils
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* 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 AVCODEC_DSPUTIL_H
#define AVCODEC_DSPUTIL_H
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "rnd_avg.h"
/* 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 1024
/* temporary */
extern uint32_t ff_squareTbl[512];
extern const uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP];
void ff_put_pixels8x8_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
void ff_avg_pixels8x8_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
void ff_put_pixels16x16_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
void ff_avg_pixels16x16_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
/* RV40 functions */
void ff_put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
void ff_avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
void ff_put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy,
int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height);
/* minimum alignment rules ;)
If you 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-devel mailing list, ...
!warning These alignments might not match reality, (missing attribute((align))
stuff somewhere possible).
I (Michael) did not check them, these are just the alignments which I think
could be reached easily ...
!future video codecs might need functions with less strict alignment
*/
/* 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 than 4
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*/, ptrdiff_t stride);
typedef void (*op_fill_func)(uint8_t *block/*align width (8 or 16)*/, uint8_t value, int line_size, int h);
#define DEF_OLD_QPEL(name)\
void ff_put_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, ptrdiff_t stride);\
void ff_put_no_rnd_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, ptrdiff_t stride);\
void ff_avg_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, ptrdiff_t 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)
/* motion estimation */
// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller than 2
// although currently h<4 is not used as functions with width <8 are neither used nor 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))*/;
/**
* Scantable.
*/
typedef struct ScanTable{
const uint8_t *scantable;
uint8_t permutated[64];
uint8_t raster_end[64];
} ScanTable;
void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable);
void ff_init_scantable_permutation(uint8_t *idct_permutation,
int idct_permutation_type);
/**
* DSPContext.
*/
typedef struct DSPContext {
/* pixel ops : interface with DCT */
void (*get_pixels)(int16_t *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size);
void (*diff_pixels)(int16_t *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride);
void (*put_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
void (*put_signed_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
void (*add_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
void (*add_pixels8)(uint8_t *pixels, int16_t *block, int line_size);
int (*sum_abs_dctelem)(int16_t *block/*align 16*/);
/**
* 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_block)(int16_t *block/*align 16*/);
void (*clear_blocks)(int16_t *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[6]; /* identical to pix_absAxA except additional void * */
me_cmp_func sse[6];
me_cmp_func hadamard8_diff[6];
me_cmp_func dct_sad[6];
me_cmp_func quant_psnr[6];
me_cmp_func bit[6];
me_cmp_func rd[6];
me_cmp_func vsad[6];
me_cmp_func vsse[6];
me_cmp_func nsse[6];
me_cmp_func w53[6];
me_cmp_func w97[6];
me_cmp_func dct_max[6];
me_cmp_func dct264_sad[6];
me_cmp_func me_pre_cmp[6];
me_cmp_func me_cmp[6];
me_cmp_func me_sub_cmp[6];
me_cmp_func mb_cmp[6];
me_cmp_func ildct_cmp[6]; //only width 16 used
me_cmp_func frame_skip_cmp[6]; //only width 8 used
int (*ssd_int8_vs_int16)(const int8_t *pix1, const int16_t *pix2,
int size);
/**
* Thirdpel motion compensation with rounding (a+b+1)>>1.
* this is an array[12] of motion compensation functions for the 9 thirdpe
* 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 put_mspel_pixels_tab[8];
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*/, const uint8_t *src1/*align 16*/, const 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, const uint8_t *src1, const uint8_t *src2, int w, int *left, int *left_top);
void (*add_hfyu_median_prediction)(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top);
int (*add_hfyu_left_prediction)(uint8_t *dst, const uint8_t *src, int w, int left);
void (*add_hfyu_left_prediction_bgr32)(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue, int *alpha);
/* this might write to dst[w] */
void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w);
void (*bswap16_buf)(uint16_t *dst, const uint16_t *src, int len);
void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale);
void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale);
/* assume len is a multiple of 8, and arrays are 16-byte aligned */
void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */);
/* (I)DCT */
void (*fdct)(int16_t *block/* align 16*/);
void (*fdct248)(int16_t *block/* align 16*/);
/* IDCT really*/
void (*idct)(int16_t *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 horizontal line of dest
*/
void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, int16_t *block/*align 16*/);
/**
* block -> idct -> add dest -> clip to unsigned 8 bit -> dest.
* @param line_size size in bytes of a horizontal line of dest
*/
void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, int16_t *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 -> reference dct -> reference idct -> x)
* - (x -> reference 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
#define FF_PARTTRANS_IDCT_PERM 5
#define FF_SSE2_IDCT_PERM 6
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
void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w, int h, int sides);
#define EDGE_WIDTH 16
#define EDGE_TOP 1
#define EDGE_BOTTOM 2
void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
/**
* Calculate scalar product of two vectors.
* @param len length of vectors, should be multiple of 16
*/
int32_t (*scalarproduct_int16)(const int16_t *v1, const int16_t *v2/*align 16*/, int len);
/* ape functions */
/**
* Calculate scalar product of v1 and v2,
* and v1[i] += v3[i] * mul
* @param len length of vectors, should be multiple of 16
*/
int32_t (*scalarproduct_and_madd_int16)(int16_t *v1/*align 16*/, const int16_t *v2, const int16_t *v3, int len, int mul);
/**
* Apply symmetric window in 16-bit fixed-point.
* @param output destination array
* constraints: 16-byte aligned
* @param input source array
* constraints: 16-byte aligned
* @param window window array
* constraints: 16-byte aligned, at least len/2 elements
* @param len full window length
* constraints: multiple of ? greater than zero
*/
void (*apply_window_int16)(int16_t *output, const int16_t *input,
const int16_t *window, unsigned int len);
/**
* Clip each element in an array of int32_t to a given minimum and maximum value.
* @param dst destination array
* constraints: 16-byte aligned
* @param src source array
* constraints: 16-byte aligned
* @param min minimum value
* constraints: must be in the range [-(1 << 24), 1 << 24]
* @param max maximum value
* constraints: must be in the range [-(1 << 24), 1 << 24]
* @param len number of elements in the array
* constraints: multiple of 32 greater than zero
*/
void (*vector_clip_int32)(int32_t *dst, const int32_t *src, int32_t min,
int32_t max, unsigned int len);
op_fill_func fill_block_tab[2];
} DSPContext;
void ff_dsputil_static_init(void);
void ff_dsputil_init(DSPContext* p, AVCodecContext *avctx);
void avpriv_dsputil_init(DSPContext* p, AVCodecContext *avctx);
attribute_deprecated void dsputil_init(DSPContext* c, AVCodecContext *avctx);
int ff_check_alignment(void);
void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type);
void ff_dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx);
void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx);
void ff_dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx);
void ff_dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx);
void ff_dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx);
void ff_dsputil_init_vis(DSPContext* c, AVCodecContext *avctx);
void ff_dsputil_init_x86(DSPContext* c, AVCodecContext *avctx);
void ff_dsputil_init_dwt(DSPContext *c);
#endif /* AVCODEC_DSPUTIL_H */

View file

@ -0,0 +1,257 @@
/*
* DSP utils
* Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* DSP utils
*/
#include "bit_depth_template.c"
#if BIT_DEPTH == 8
/* draw the edges of width 'w' of an image of size width, height */
//FIXME check that this is ok for mpeg4 interlaced
static void FUNCC(draw_edges)(uint8_t *p_buf, int p_wrap, int width, int height, int w, int h, int sides)
{
pixel *buf = (pixel*)p_buf;
int wrap = p_wrap / sizeof(pixel);
pixel *ptr, *last_line;
int i;
/* left and right */
ptr = buf;
for(i=0;i<height;i++) {
memset(ptr - w, ptr[0], w);
memset(ptr + width, ptr[width-1], w);
ptr += wrap;
}
/* top and bottom + corners */
buf -= w;
last_line = buf + (height - 1) * wrap;
if (sides & EDGE_TOP)
for(i = 0; i < h; i++)
memcpy(buf - (i + 1) * wrap, buf, (width + w + w) * sizeof(pixel)); // top
if (sides & EDGE_BOTTOM)
for (i = 0; i < h; i++)
memcpy(last_line + (i + 1) * wrap, last_line, (width + w + w) * sizeof(pixel)); // bottom
}
#endif
static void FUNCC(get_pixels)(int16_t *av_restrict block,
const uint8_t *_pixels,
int line_size)
{
const pixel *pixels = (const pixel *) _pixels;
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 / sizeof(pixel);
block += 8;
}
}
#if BIT_DEPTH == 8
static void FUNCC(clear_block)(int16_t *block)
{
memset(block, 0, sizeof(int16_t)*64);
}
static void FUNCC(clear_blocks)(int16_t *blocks)
{
memset(blocks, 0, sizeof(int16_t)*6*64);
}
#endif
#if BIT_DEPTH == 8
#include "hpel_template.c"
#endif
#define PIXOP2(OPNAME, OP) \
static inline void FUNC(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++){\
pixel4 a,b;\
a= AV_RN4P(&src1[i*src_stride1 ]);\
b= AV_RN4P(&src2[i*src_stride2 ]);\
OP(*((pixel4*)&dst[i*dst_stride ]), no_rnd_avg_pixel4(a, b));\
a= AV_RN4P(&src1[i*src_stride1+4*sizeof(pixel)]);\
b= AV_RN4P(&src2[i*src_stride2+4*sizeof(pixel)]);\
OP(*((pixel4*)&dst[i*dst_stride+4*sizeof(pixel)]), no_rnd_avg_pixel4(a, b));\
}\
}\
\
static inline void FUNC(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){\
FUNC(OPNAME ## _no_rnd_pixels8_l2)(dst , src1 , src2 , dst_stride, src_stride1, src_stride2, h);\
FUNC(OPNAME ## _no_rnd_pixels8_l2)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, h);\
}\
\
static inline void FUNC(OPNAME ## _pixels8_l4)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, const uint8_t *src4,\
int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
/* FIXME HIGH BIT DEPTH */\
int i;\
for(i=0; i<h; i++){\
uint32_t a, b, c, d, l0, l1, h0, h1;\
a= AV_RN32(&src1[i*src_stride1]);\
b= AV_RN32(&src2[i*src_stride2]);\
c= AV_RN32(&src3[i*src_stride3]);\
d= AV_RN32(&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= AV_RN32(&src1[i*src_stride1+4]);\
b= AV_RN32(&src2[i*src_stride2+4]);\
c= AV_RN32(&src3[i*src_stride3+4]);\
d= AV_RN32(&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 FUNC(OPNAME ## _no_rnd_pixels8_l4)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, const uint8_t *src4,\
int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
/* FIXME HIGH BIT DEPTH*/\
int i;\
for(i=0; i<h; i++){\
uint32_t a, b, c, d, l0, l1, h0, h1;\
a= AV_RN32(&src1[i*src_stride1]);\
b= AV_RN32(&src2[i*src_stride2]);\
c= AV_RN32(&src3[i*src_stride3]);\
d= AV_RN32(&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= AV_RN32(&src1[i*src_stride1+4]);\
b= AV_RN32(&src2[i*src_stride2+4]);\
c= AV_RN32(&src3[i*src_stride3+4]);\
d= AV_RN32(&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 FUNC(OPNAME ## _pixels16_l4)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, const uint8_t *src4,\
int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
FUNC(OPNAME ## _pixels8_l4)(dst , src1 , src2 , src3 , src4 , dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\
FUNC(OPNAME ## _pixels8_l4)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), src3+8*sizeof(pixel), src4+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\
}\
static inline void FUNC(OPNAME ## _no_rnd_pixels16_l4)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, const uint8_t *src4,\
int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
FUNC(OPNAME ## _no_rnd_pixels8_l4)(dst , src1 , src2 , src3 , src4 , dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\
FUNC(OPNAME ## _no_rnd_pixels8_l4)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), src3+8*sizeof(pixel), src4+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\
}\
\
static inline void FUNCC(OPNAME ## _pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
{\
/* FIXME HIGH BIT DEPTH */\
int j;\
for(j=0; j<2; j++){\
int i;\
const uint32_t a= AV_RN32(pixels );\
const uint32_t b= AV_RN32(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= AV_RN32(pixels );\
uint32_t b= AV_RN32(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= AV_RN32(pixels );\
b= AV_RN32(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;\
}\
}\
\
CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_xy2), FUNCC(OPNAME ## _pixels8_xy2), 8*sizeof(pixel))\
#define op_avg(a, b) a = rnd_avg_pixel4(a, b)
#define op_put(a, b) a = b
#if BIT_DEPTH == 8
#define put_no_rnd_pixels8_8_c put_pixels8_8_c
PIXOP2(avg, op_avg)
PIXOP2(put, op_put)
#endif
#undef op_avg
#undef op_put

View file

@ -0,0 +1,360 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/pixdesc.h"
#include "avcodec.h"
#include "dv_profile.h"
static DVwork_chunk work_chunks_dv25pal [1*12*27];
static DVwork_chunk work_chunks_dv25pal411[1*12*27];
static DVwork_chunk work_chunks_dv25ntsc [1*10*27];
static DVwork_chunk work_chunks_dv50pal [2*12*27];
static DVwork_chunk work_chunks_dv50ntsc [2*10*27];
static DVwork_chunk work_chunks_dv100palp [2*12*27];
static DVwork_chunk work_chunks_dv100ntscp[2*10*27];
static DVwork_chunk work_chunks_dv100pali [4*12*27];
static DVwork_chunk work_chunks_dv100ntsci[4*10*27];
static uint32_t dv_idct_factor_sd [2*2*22*64];
static uint32_t dv_idct_factor_hd1080[2*4*16*64];
static uint32_t dv_idct_factor_hd720 [2*4*16*64];
static const uint8_t dv_audio_shuffle525[10][9] = {
{ 0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */
{ 6, 36, 66, 26, 56, 86, 16, 46, 76 },
{ 12, 42, 72, 2, 32, 62, 22, 52, 82 },
{ 18, 48, 78, 8, 38, 68, 28, 58, 88 },
{ 24, 54, 84, 14, 44, 74, 4, 34, 64 },
{ 1, 31, 61, 21, 51, 81, 11, 41, 71 }, /* 2nd channel */
{ 7, 37, 67, 27, 57, 87, 17, 47, 77 },
{ 13, 43, 73, 3, 33, 63, 23, 53, 83 },
{ 19, 49, 79, 9, 39, 69, 29, 59, 89 },
{ 25, 55, 85, 15, 45, 75, 5, 35, 65 },
};
static const uint8_t dv_audio_shuffle625[12][9] = {
{ 0, 36, 72, 26, 62, 98, 16, 52, 88}, /* 1st channel */
{ 6, 42, 78, 32, 68, 104, 22, 58, 94},
{ 12, 48, 84, 2, 38, 74, 28, 64, 100},
{ 18, 54, 90, 8, 44, 80, 34, 70, 106},
{ 24, 60, 96, 14, 50, 86, 4, 40, 76},
{ 30, 66, 102, 20, 56, 92, 10, 46, 82},
{ 1, 37, 73, 27, 63, 99, 17, 53, 89}, /* 2nd channel */
{ 7, 43, 79, 33, 69, 105, 23, 59, 95},
{ 13, 49, 85, 3, 39, 75, 29, 65, 101},
{ 19, 55, 91, 9, 45, 81, 35, 71, 107},
{ 25, 61, 97, 15, 51, 87, 5, 41, 77},
{ 31, 67, 103, 21, 57, 93, 11, 47, 83},
};
/* macroblock bit budgets */
static const uint8_t block_sizes_dv2550[8] = {
112, 112, 112, 112, 80, 80, 0, 0,
};
static const uint8_t block_sizes_dv100[8] = {
80, 80, 80, 80, 80, 80, 64, 64,
};
static const DVprofile dv_profiles[] = {
{ .dsf = 0,
.video_stype = 0x0,
.frame_size = 120000, /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */
.difseg_size = 10,
.n_difchan = 1,
.time_base = { 1001, 30000 },
.ltc_divisor = 30,
.height = 480,
.width = 720,
.sar = {{8, 9}, {32, 27}},
.work_chunks = &work_chunks_dv25ntsc[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV411P,
.bpm = 6,
.block_sizes = block_sizes_dv2550,
.audio_stride = 90,
.audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
.audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
.audio_shuffle = dv_audio_shuffle525,
},
{ .dsf = 1,
.video_stype = 0x0,
.frame_size = 144000, /* IEC 61834 - 625/50 (PAL) */
.difseg_size = 12,
.n_difchan = 1,
.time_base = { 1, 25 },
.ltc_divisor = 25,
.height = 576,
.width = 720,
.sar = {{16, 15}, {64, 45}},
.work_chunks = &work_chunks_dv25pal[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV420P,
.bpm = 6,
.block_sizes = block_sizes_dv2550,
.audio_stride = 108,
.audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
.audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
.audio_shuffle = dv_audio_shuffle625,
},
{ .dsf = 1,
.video_stype = 0x0,
.frame_size = 144000, /* SMPTE-314M - 625/50 (PAL) */
.difseg_size = 12,
.n_difchan = 1,
.time_base = { 1, 25 },
.ltc_divisor = 25,
.height = 576,
.width = 720,
.sar = {{16, 15}, {64, 45}},
.work_chunks = &work_chunks_dv25pal411[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV411P,
.bpm = 6,
.block_sizes = block_sizes_dv2550,
.audio_stride = 108,
.audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
.audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
.audio_shuffle = dv_audio_shuffle625,
},
{ .dsf = 0,
.video_stype = 0x4,
.frame_size = 240000, /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */
.difseg_size = 10, /* also known as "DVCPRO50" */
.n_difchan = 2,
.time_base = { 1001, 30000 },
.ltc_divisor = 30,
.height = 480,
.width = 720,
.sar = {{8, 9}, {32, 27}},
.work_chunks = &work_chunks_dv50ntsc[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 6,
.block_sizes = block_sizes_dv2550,
.audio_stride = 90,
.audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
.audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
.audio_shuffle = dv_audio_shuffle525,
},
{ .dsf = 1,
.video_stype = 0x4,
.frame_size = 288000, /* SMPTE-314M - 625/50 (PAL) 50 Mbps */
.difseg_size = 12, /* also known as "DVCPRO50" */
.n_difchan = 2,
.time_base = { 1, 25 },
.ltc_divisor = 25,
.height = 576,
.width = 720,
.sar = {{16, 15}, {64, 45}},
.work_chunks = &work_chunks_dv50pal[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 6,
.block_sizes = block_sizes_dv2550,
.audio_stride = 108,
.audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
.audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
.audio_shuffle = dv_audio_shuffle625,
},
{ .dsf = 0,
.video_stype = 0x14,
.frame_size = 480000, /* SMPTE-370M - 1080i60 100 Mbps */
.difseg_size = 10, /* also known as "DVCPRO HD" */
.n_difchan = 4,
.time_base = { 1001, 30000 },
.ltc_divisor = 30,
.height = 1080,
.width = 1280,
.sar = {{1, 1}, {3, 2}},
.work_chunks = &work_chunks_dv100ntsci[0],
.idct_factor = &dv_idct_factor_hd1080[0],
.pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 8,
.block_sizes = block_sizes_dv100,
.audio_stride = 90,
.audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
.audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
.audio_shuffle = dv_audio_shuffle525,
},
{ .dsf = 1,
.video_stype = 0x14,
.frame_size = 576000, /* SMPTE-370M - 1080i50 100 Mbps */
.difseg_size = 12, /* also known as "DVCPRO HD" */
.n_difchan = 4,
.time_base = { 1, 25 },
.ltc_divisor = 25,
.height = 1080,
.width = 1440,
.sar = {{1, 1}, {4, 3}},
.work_chunks = &work_chunks_dv100pali[0],
.idct_factor = &dv_idct_factor_hd1080[0],
.pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 8,
.block_sizes = block_sizes_dv100,
.audio_stride = 108,
.audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
.audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
.audio_shuffle = dv_audio_shuffle625,
},
{ .dsf = 0,
.video_stype = 0x18,
.frame_size = 240000, /* SMPTE-370M - 720p60 100 Mbps */
.difseg_size = 10, /* also known as "DVCPRO HD" */
.n_difchan = 2,
.time_base = { 1001, 60000 },
.ltc_divisor = 60,
.height = 720,
.width = 960,
.sar = {{1, 1}, {4, 3}},
.work_chunks = &work_chunks_dv100ntscp[0],
.idct_factor = &dv_idct_factor_hd720[0],
.pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 8,
.block_sizes = block_sizes_dv100,
.audio_stride = 90,
.audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
.audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
.audio_shuffle = dv_audio_shuffle525,
},
{ .dsf = 1,
.video_stype = 0x18,
.frame_size = 288000, /* SMPTE-370M - 720p50 100 Mbps */
.difseg_size = 12, /* also known as "DVCPRO HD" */
.n_difchan = 2,
.time_base = { 1, 50 },
.ltc_divisor = 50,
.height = 720,
.width = 960,
.sar = {{1, 1}, {4, 3}},
.work_chunks = &work_chunks_dv100palp[0],
.idct_factor = &dv_idct_factor_hd720[0],
.pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 8,
.block_sizes = block_sizes_dv100,
.audio_stride = 90,
.audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
.audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
.audio_shuffle = dv_audio_shuffle625,
},
{ .dsf = 1,
.video_stype = 0x1,
.frame_size = 144000, /* IEC 61883-5 - 625/50 (PAL) */
.difseg_size = 12,
.n_difchan = 1,
.time_base = { 1, 25 },
.ltc_divisor = 25,
.height = 576,
.width = 720,
.sar = {{16, 15}, {64, 45}},
.work_chunks = &work_chunks_dv25pal[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV420P,
.bpm = 6,
.block_sizes = block_sizes_dv2550,
.audio_stride = 108,
.audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
.audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
.audio_shuffle = dv_audio_shuffle625,
}
};
const DVprofile* avpriv_dv_frame_profile2(AVCodecContext* codec, const DVprofile *sys,
const uint8_t* frame, unsigned buf_size)
{
int i, dsf, stype;
if(buf_size < DV_PROFILE_BYTES)
return NULL;
dsf = (frame[3] & 0x80) >> 7;
stype = frame[80 * 5 + 48 + 3] & 0x1f;
/* 576i50 25Mbps 4:1:1 is a special case */
if ((dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) ||
(stype == 31 && codec && codec->codec_tag==AV_RL32("SL25") && codec->coded_width==720 && codec->coded_height==576)) {
return &dv_profiles[2];
}
if( stype == 0
&& codec
&& (codec->codec_tag==AV_RL32("dvsd") || codec->codec_tag==AV_RL32("CDVC"))
&& codec->coded_width ==720
&& codec->coded_height==576)
return &dv_profiles[1];
for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++)
if (dsf == dv_profiles[i].dsf && stype == dv_profiles[i].video_stype)
return &dv_profiles[i];
/* check if old sys matches and assumes corrupted input */
if (sys && buf_size == sys->frame_size)
return sys;
/* hack for trac issue #217, dv files created with QuickTime 3 */
if ((frame[3] & 0x7f) == 0x3f && frame[80 * 5 + 48 + 3] == 0xff)
return &dv_profiles[dsf];
return NULL;
}
const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
const uint8_t* frame, unsigned buf_size)
{
return avpriv_dv_frame_profile2(NULL, sys, frame, buf_size);
}
const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec)
{
int i;
int w, h;
if (codec->coded_width || codec->coded_height) {
w = codec->coded_width;
h = codec->coded_height;
} else {
w = codec->width;
h = codec->height;
}
for (i=0; i<FF_ARRAY_ELEMS(dv_profiles); i++)
if (h == dv_profiles[i].height &&
codec->pix_fmt == dv_profiles[i].pix_fmt &&
w == dv_profiles[i].width)
return &dv_profiles[i];
return NULL;
}
void ff_dv_print_profiles(void *logctx, int loglevel)
{
int i;
for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++) {
const DVprofile *p = &dv_profiles[i];
av_log(logctx, loglevel, "Frame size: %dx%d; pixel format: %s, "
"framerate: %d/%d\n", p->width, p->height, av_get_pix_fmt_name(p->pix_fmt),
p->time_base.den, p->time_base.num);
}
}

View file

@ -0,0 +1,78 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_DV_PROFILE_H
#define AVCODEC_DV_PROFILE_H
#include <stdint.h>
#include "libavutil/pixfmt.h"
#include "libavutil/rational.h"
#include "avcodec.h"
/* minimum number of bytes to read from a DV stream in order to
determine the profile */
#define DV_PROFILE_BYTES (6*80) /* 6 DIF blocks */
typedef struct DVwork_chunk {
uint16_t buf_offset;
uint16_t mb_coordinates[5];
} DVwork_chunk;
/*
* DVprofile is used to express the differences between various
* DV flavors. For now it's primarily used for differentiating
* 525/60 and 625/50, but the plans are to use it for various
* DV specs as well (e.g. SMPTE314M vs. IEC 61834).
*/
typedef struct DVprofile {
int dsf; /* value of the dsf in the DV header */
int video_stype; /* stype for VAUX source pack */
int frame_size; /* total size of one frame in bytes */
int difseg_size; /* number of DIF segments per DIF channel */
int n_difchan; /* number of DIF channels per frame */
AVRational time_base; /* 1/framerate */
int ltc_divisor; /* FPS from the LTS standpoint */
int height; /* picture height in pixels */
int width; /* picture width in pixels */
AVRational sar[2]; /* sample aspect ratios for 4:3 and 16:9 */
DVwork_chunk *work_chunks; /* each thread gets its own chunk of frame to work on */
uint32_t *idct_factor; /* set of iDCT factor tables */
enum AVPixelFormat pix_fmt; /* picture pixel format */
int bpm; /* blocks per macroblock */
const uint8_t *block_sizes; /* AC block sizes, in bits */
int audio_stride; /* size of audio_shuffle table */
int audio_min_samples[3]; /* min amount of audio samples */
/* for 48kHz, 44.1kHz and 32kHz */
int audio_samples_dist[5]; /* how many samples are supposed to be */
/* in each frame in a 5 frames window */
const uint8_t (*audio_shuffle)[9]; /* PCM shuffling table */
} DVprofile;
const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
const uint8_t* frame, unsigned buf_size);
const DVprofile* avpriv_dv_frame_profile2(AVCodecContext* codec, const DVprofile *sys,
const uint8_t* frame, unsigned buf_size);
const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec);
/**
* Print all allowed DV profiles into logctx at specified logging level.
*/
void ff_dv_print_profiles(void *logctx, int loglevel);
#endif /* AVCODEC_DV_PROFILE_H */

View file

@ -0,0 +1,122 @@
/*
* Constants for DV codec
* Copyright (c) 2002 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Constants for DV codec.
*/
#include "avcodec.h"
#include "dvdata.h"
/* unquant tables (not used directly) */
const uint8_t ff_dv_quant_shifts[22][4] = {
{ 3,3,4,4 },
{ 3,3,4,4 },
{ 2,3,3,4 },
{ 2,3,3,4 },
{ 2,2,3,3 },
{ 2,2,3,3 },
{ 1,2,2,3 },
{ 1,2,2,3 },
{ 1,1,2,2 },
{ 1,1,2,2 },
{ 0,1,1,2 },
{ 0,1,1,2 },
{ 0,0,1,1 },
{ 0,0,1,1 },
{ 0,0,0,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 },
};
const uint8_t ff_dv_quant_offset[4] = { 6, 3, 0, 1 };
const int ff_dv_iweight_88[64] = {
32768, 16710, 16710, 17735, 17015, 17735, 18197, 18079,
18079, 18197, 18725, 18559, 19196, 18559, 18725, 19284,
19108, 19692, 19692, 19108, 19284, 21400, 19645, 20262,
20214, 20262, 19645, 21400, 22733, 21845, 20867, 20815,
20815, 20867, 21845, 22733, 23173, 23173, 21400, 21400,
21400, 23173, 23173, 24600, 23764, 22017, 22017, 23764,
24600, 25267, 24457, 22672, 24457, 25267, 25971, 25191,
25191, 25971, 26715, 27962, 26715, 29642, 29642, 31536,
};
const int ff_dv_iweight_248[64] = {
32768, 17735, 16710, 18079, 18725, 21400, 17735, 19196,
19108, 21845, 16384, 17735, 18725, 21400, 16710, 18079,
20262, 23173, 18197, 19692, 18725, 20262, 20815, 23764,
17735, 19196, 19108, 21845, 20262, 23173, 18197, 19692,
21400, 24457, 19284, 20867, 21400, 23173, 22017, 25191,
18725, 20262, 20815, 23764, 21400, 24457, 19284, 20867,
24457, 27962, 22733, 24600, 25971, 29642, 21400, 23173,
22017, 25191, 24457, 27962, 22733, 24600, 25971, 29642,
};
/**
* The "inverse" DV100 weights are actually just the spec weights (zig-zagged).
*/
const int ff_dv_iweight_1080_y[64] = {
128, 16, 16, 17, 17, 17, 18, 18,
18, 18, 18, 18, 19, 18, 18, 19,
19, 19, 19, 19, 19, 42, 38, 40,
40, 40, 38, 42, 44, 43, 41, 41,
41, 41, 43, 44, 45, 45, 42, 42,
42, 45, 45, 48, 46, 43, 43, 46,
48, 49, 48, 44, 48, 49, 101, 98,
98, 101, 104, 109, 104, 116, 116, 123,
};
const int ff_dv_iweight_1080_c[64] = {
128, 16, 16, 17, 17, 17, 25, 25,
25, 25, 26, 25, 26, 25, 26, 26,
26, 27, 27, 26, 26, 42, 38, 40,
40, 40, 38, 42, 44, 43, 41, 41,
41, 41, 43, 44, 91, 91, 84, 84,
84, 91, 91, 96, 93, 86, 86, 93,
96, 197, 191, 177, 191, 197, 203, 197,
197, 203, 209, 219, 209, 232, 232, 246,
};
const int ff_dv_iweight_720_y[64] = {
128, 16, 16, 17, 17, 17, 18, 18,
18, 18, 18, 18, 19, 18, 18, 19,
19, 19, 19, 19, 19, 42, 38, 40,
40, 40, 38, 42, 44, 43, 41, 41,
41, 41, 43, 44, 68, 68, 63, 63,
63, 68, 68, 96, 92, 86, 86, 92,
96, 98, 96, 88, 96, 98, 202, 196,
196, 202, 208, 218, 208, 232, 232, 246,
};
const int ff_dv_iweight_720_c[64] = {
128, 24, 24, 26, 26, 26, 36, 36,
36, 36, 36, 36, 38, 36, 36, 38,
38, 38, 38, 38, 38, 84, 76, 80,
80, 80, 76, 84, 88, 86, 82, 82,
82, 82, 86, 88, 182, 182, 168, 168,
168, 182, 182, 192, 186, 192, 172, 186,
192, 394, 382, 354, 382, 394, 406, 394,
394, 406, 418, 438, 418, 464, 464, 492,
};

View file

@ -0,0 +1,124 @@
/*
* Constants for DV codec
* Copyright (c) 2002 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Constants for DV codec.
*/
#ifndef AVCODEC_DVDATA_H
#define AVCODEC_DVDATA_H
#include "avcodec.h"
#include "dsputil.h"
#include "get_bits.h"
#include "dv_profile.h"
typedef struct DVVideoContext {
const DVprofile *sys;
AVFrame picture;
AVCodecContext *avctx;
uint8_t *buf;
uint8_t dv_zigzag[2][64];
void (*get_pixels)(int16_t *block, const uint8_t *pixels, int line_size);
void (*fdct[2])(int16_t *block);
void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block);
me_cmp_func ildct_cmp;
} DVVideoContext;
enum dv_section_type {
dv_sect_header = 0x1f,
dv_sect_subcode = 0x3f,
dv_sect_vaux = 0x56,
dv_sect_audio = 0x76,
dv_sect_video = 0x96,
};
enum dv_pack_type {
dv_header525 = 0x3f, /* see dv_write_pack for important details on */
dv_header625 = 0xbf, /* these two packs */
dv_timecode = 0x13,
dv_audio_source = 0x50,
dv_audio_control = 0x51,
dv_audio_recdate = 0x52,
dv_audio_rectime = 0x53,
dv_video_source = 0x60,
dv_video_control = 0x61,
dv_video_recdate = 0x62,
dv_video_rectime = 0x63,
dv_unknown_pack = 0xff,
};
extern const uint8_t ff_dv_quant_shifts[22][4];
extern const uint8_t ff_dv_quant_offset[4];
extern const int ff_dv_iweight_88[64];
extern const int ff_dv_iweight_248[64];
extern const int ff_dv_iweight_1080_y[64];
extern const int ff_dv_iweight_1080_c[64];
extern const int ff_dv_iweight_720_y[64];
extern const int ff_dv_iweight_720_c[64];
#define DV_PROFILE_IS_HD(p) ((p)->video_stype & 0x10)
#define DV_PROFILE_IS_1080i50(p) (((p)->video_stype == 0x14) && ((p)->dsf == 1))
#define DV_PROFILE_IS_720p50(p) (((p)->video_stype == 0x18) && ((p)->dsf == 1))
/**
* largest possible DV frame, in bytes (1080i50)
*/
#define DV_MAX_FRAME_SIZE 576000
/**
* maximum number of blocks per macroblock in any DV format
*/
#define DV_MAX_BPM 8
#define TEX_VLC_BITS 9
extern RL_VLC_ELEM ff_dv_rl_vlc[1184];
int ff_dv_init_dynamic_tables(const DVprofile *d);
int ff_dvvideo_init(AVCodecContext *avctx);
static inline int dv_work_pool_size(const DVprofile *d)
{
int size = d->n_difchan*d->difseg_size*27;
if (DV_PROFILE_IS_1080i50(d))
size -= 3*27;
if (DV_PROFILE_IS_720p50(d))
size -= 4*27;
return size;
}
static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y)
{
*mb_x = work_chunk->mb_coordinates[m] & 0xff;
*mb_y = work_chunk->mb_coordinates[m] >> 8;
/* We work with 720p frames split in half. The odd half-frame (chan==2,3) is displaced :-( */
if (s->sys->height == 720 && !(s->buf[1]&0x0C)) {
*mb_y -= (*mb_y>17)?18:-72; /* shifting the Y coordinate down by 72/2 macro blocks */
}
}
#endif /* AVCODEC_DVDATA_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,79 @@
/*
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_ERROR_RESILIENCE_H
#define AVCODEC_ERROR_RESILIENCE_H
#include <stdint.h>
#include "avcodec.h"
#include "dsputil.h"
///< current MB is the first after a resync marker
#define VP_START 1
#define ER_AC_ERROR 2
#define ER_DC_ERROR 4
#define ER_MV_ERROR 8
#define ER_AC_END 16
#define ER_DC_END 32
#define ER_MV_END 64
#define ER_MB_ERROR (ER_AC_ERROR|ER_DC_ERROR|ER_MV_ERROR)
#define ER_MB_END (ER_AC_END|ER_DC_END|ER_MV_END)
typedef struct ERContext {
AVCodecContext *avctx;
DSPContext *dsp;
int *mb_index2xy;
int mb_num;
int mb_width, mb_height;
int mb_stride;
int b8_stride;
int error_count, error_occurred;
uint8_t *error_status_table;
uint8_t *er_temp_buffer;
int16_t *dc_val[3];
uint8_t *mbskip_table;
uint8_t *mbintra_table;
int mv[2][4][2];
struct Picture *cur_pic;
struct Picture *last_pic;
struct Picture *next_pic;
uint16_t pp_time;
uint16_t pb_time;
int quarter_sample;
int partitioned_frame;
int ref_count;
void (*decode_mb)(void *opaque, int ref, int mv_dir, int mv_type,
int (*mv)[2][4][2],
int mb_x, int mb_y, int mb_intra, int mb_skipped);
void *opaque;
} ERContext;
void ff_er_frame_start(ERContext *s);
void ff_er_frame_end(ERContext *s);
void ff_er_add_slice(ERContext *s, int startx, int starty, int endx, int endy,
int status);
#endif /* AVCODEC_ERROR_RESILIENCE_H */

View file

@ -0,0 +1,228 @@
/*
* Floating point AAN DCT
* this implementation is based upon the IJG integer AAN DCT (see jfdctfst.c)
*
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2003 Roman Shaposhnik
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file
* @brief
* Floating point AAN DCT
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#include "faandct.h"
#include "libavutil/internal.h"
#include "libavutil/libm.h"
#define FLOAT float
//numbers generated by simple c code (not as accurate as they could be)
/*
for(i=0; i<8; i++){
printf("#define B%d %1.20llf\n", i, (long double)1.0/(cosl(i*acosl(-1.0)/(long double)16.0)*sqrtl(2)));
}
*/
#define B0 1.00000000000000000000
#define B1 0.72095982200694791383 // (cos(pi*1/16)sqrt(2))^-1
#define B2 0.76536686473017954350 // (cos(pi*2/16)sqrt(2))^-1
#define B3 0.85043009476725644878 // (cos(pi*3/16)sqrt(2))^-1
#define B4 1.00000000000000000000 // (cos(pi*4/16)sqrt(2))^-1
#define B5 1.27275858057283393842 // (cos(pi*5/16)sqrt(2))^-1
#define B6 1.84775906502257351242 // (cos(pi*6/16)sqrt(2))^-1
#define B7 3.62450978541155137218 // (cos(pi*7/16)sqrt(2))^-1
#define A1 0.70710678118654752438 // cos(pi*4/16)
#define A2 0.54119610014619698435 // cos(pi*6/16)sqrt(2)
#define A5 0.38268343236508977170 // cos(pi*6/16)
#define A4 1.30656296487637652774 // cos(pi*2/16)sqrt(2)
static const FLOAT postscale[64]={
B0*B0, B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B6, B0*B7,
B1*B0, B1*B1, B1*B2, B1*B3, B1*B4, B1*B5, B1*B6, B1*B7,
B2*B0, B2*B1, B2*B2, B2*B3, B2*B4, B2*B5, B2*B6, B2*B7,
B3*B0, B3*B1, B3*B2, B3*B3, B3*B4, B3*B5, B3*B6, B3*B7,
B4*B0, B4*B1, B4*B2, B4*B3, B4*B4, B4*B5, B4*B6, B4*B7,
B5*B0, B5*B1, B5*B2, B5*B3, B5*B4, B5*B5, B5*B6, B5*B7,
B6*B0, B6*B1, B6*B2, B6*B3, B6*B4, B6*B5, B6*B6, B6*B7,
B7*B0, B7*B1, B7*B2, B7*B3, B7*B4, B7*B5, B7*B6, B7*B7,
};
static av_always_inline void row_fdct(FLOAT temp[64], int16_t *data)
{
FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
FLOAT tmp10, tmp11, tmp12, tmp13;
FLOAT z2, z4, z11, z13;
FLOAT av_unused z5;
int i;
for (i=0; i<8*8; i+=8) {
tmp0= data[0 + i] + data[7 + i];
tmp7= data[0 + i] - data[7 + i];
tmp1= data[1 + i] + data[6 + i];
tmp6= data[1 + i] - data[6 + i];
tmp2= data[2 + i] + data[5 + i];
tmp5= data[2 + i] - data[5 + i];
tmp3= data[3 + i] + data[4 + i];
tmp4= data[3 + i] - data[4 + i];
tmp10= tmp0 + tmp3;
tmp13= tmp0 - tmp3;
tmp11= tmp1 + tmp2;
tmp12= tmp1 - tmp2;
temp[0 + i]= tmp10 + tmp11;
temp[4 + i]= tmp10 - tmp11;
tmp12 += tmp13;
tmp12 *= A1;
temp[2 + i]= tmp13 + tmp12;
temp[6 + i]= tmp13 - tmp12;
tmp4 += tmp5;
tmp5 += tmp6;
tmp6 += tmp7;
#if 0
z5= (tmp4 - tmp6) * A5;
z2= tmp4*A2 + z5;
z4= tmp6*A4 + z5;
#else
z2= tmp4*(A2+A5) - tmp6*A5;
z4= tmp6*(A4-A5) + tmp4*A5;
#endif
tmp5*=A1;
z11= tmp7 + tmp5;
z13= tmp7 - tmp5;
temp[5 + i]= z13 + z2;
temp[3 + i]= z13 - z2;
temp[1 + i]= z11 + z4;
temp[7 + i]= z11 - z4;
}
}
void ff_faandct(int16_t *data)
{
FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
FLOAT tmp10, tmp11, tmp12, tmp13;
FLOAT z2, z4, z11, z13;
FLOAT av_unused z5;
FLOAT temp[64];
int i;
emms_c();
row_fdct(temp, data);
for (i=0; i<8; i++) {
tmp0= temp[8*0 + i] + temp[8*7 + i];
tmp7= temp[8*0 + i] - temp[8*7 + i];
tmp1= temp[8*1 + i] + temp[8*6 + i];
tmp6= temp[8*1 + i] - temp[8*6 + i];
tmp2= temp[8*2 + i] + temp[8*5 + i];
tmp5= temp[8*2 + i] - temp[8*5 + i];
tmp3= temp[8*3 + i] + temp[8*4 + i];
tmp4= temp[8*3 + i] - temp[8*4 + i];
tmp10= tmp0 + tmp3;
tmp13= tmp0 - tmp3;
tmp11= tmp1 + tmp2;
tmp12= tmp1 - tmp2;
data[8*0 + i]= lrintf(postscale[8*0 + i] * (tmp10 + tmp11));
data[8*4 + i]= lrintf(postscale[8*4 + i] * (tmp10 - tmp11));
tmp12 += tmp13;
tmp12 *= A1;
data[8*2 + i]= lrintf(postscale[8*2 + i] * (tmp13 + tmp12));
data[8*6 + i]= lrintf(postscale[8*6 + i] * (tmp13 - tmp12));
tmp4 += tmp5;
tmp5 += tmp6;
tmp6 += tmp7;
#if 0
z5= (tmp4 - tmp6) * A5;
z2= tmp4*A2 + z5;
z4= tmp6*A4 + z5;
#else
z2= tmp4*(A2+A5) - tmp6*A5;
z4= tmp6*(A4-A5) + tmp4*A5;
#endif
tmp5*=A1;
z11= tmp7 + tmp5;
z13= tmp7 - tmp5;
data[8*5 + i]= lrintf(postscale[8*5 + i] * (z13 + z2));
data[8*3 + i]= lrintf(postscale[8*3 + i] * (z13 - z2));
data[8*1 + i]= lrintf(postscale[8*1 + i] * (z11 + z4));
data[8*7 + i]= lrintf(postscale[8*7 + i] * (z11 - z4));
}
}
void ff_faandct248(int16_t *data)
{
FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
FLOAT tmp10, tmp11, tmp12, tmp13;
FLOAT temp[64];
int i;
emms_c();
row_fdct(temp, data);
for (i=0; i<8; i++) {
tmp0 = temp[8*0 + i] + temp[8*1 + i];
tmp1 = temp[8*2 + i] + temp[8*3 + i];
tmp2 = temp[8*4 + i] + temp[8*5 + i];
tmp3 = temp[8*6 + i] + temp[8*7 + i];
tmp4 = temp[8*0 + i] - temp[8*1 + i];
tmp5 = temp[8*2 + i] - temp[8*3 + i];
tmp6 = temp[8*4 + i] - temp[8*5 + i];
tmp7 = temp[8*6 + i] - temp[8*7 + i];
tmp10 = tmp0 + tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
tmp13 = tmp0 - tmp3;
data[8*0 + i] = lrintf(postscale[8*0 + i] * (tmp10 + tmp11));
data[8*4 + i] = lrintf(postscale[8*4 + i] * (tmp10 - tmp11));
tmp12 += tmp13;
tmp12 *= A1;
data[8*2 + i] = lrintf(postscale[8*2 + i] * (tmp13 + tmp12));
data[8*6 + i] = lrintf(postscale[8*6 + i] * (tmp13 - tmp12));
tmp10 = tmp4 + tmp7;
tmp11 = tmp5 + tmp6;
tmp12 = tmp5 - tmp6;
tmp13 = tmp4 - tmp7;
data[8*1 + i] = lrintf(postscale[8*0 + i] * (tmp10 + tmp11));
data[8*5 + i] = lrintf(postscale[8*4 + i] * (tmp10 - tmp11));
tmp12 += tmp13;
tmp12 *= A1;
data[8*3 + i] = lrintf(postscale[8*2 + i] * (tmp13 + tmp12));
data[8*7 + i] = lrintf(postscale[8*6 + i] * (tmp13 - tmp12));
}
}

View file

@ -0,0 +1,37 @@
/*
* Floating point AAN DCT
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* @brief
* Floating point AAN DCT
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#ifndef AVCODEC_FAANDCT_H
#define AVCODEC_FAANDCT_H
#include <stdint.h>
void ff_faandct(int16_t *data);
void ff_faandct248(int16_t *data);
#endif /* AVCODEC_FAANDCT_H */

View file

@ -0,0 +1,170 @@
/*
* Floating point AAN IDCT
* Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "faanidct.h"
#include "libavutil/common.h"
/* To allow switching to double. */
#define FLOAT float
#define B0 1.0000000000000000000000
#define B1 1.3870398453221474618216 // cos(pi*1/16)sqrt(2)
#define B2 1.3065629648763765278566 // cos(pi*2/16)sqrt(2)
#define B3 1.1758756024193587169745 // cos(pi*3/16)sqrt(2)
#define B4 1.0000000000000000000000 // cos(pi*4/16)sqrt(2)
#define B5 0.7856949583871021812779 // cos(pi*5/16)sqrt(2)
#define B6 0.5411961001461969843997 // cos(pi*6/16)sqrt(2)
#define B7 0.2758993792829430123360 // cos(pi*7/16)sqrt(2)
#define A4 0.70710678118654752438 // cos(pi*4/16)
#define A2 0.92387953251128675613 // cos(pi*2/16)
static const FLOAT prescale[64]={
B0*B0/8, B0*B1/8, B0*B2/8, B0*B3/8, B0*B4/8, B0*B5/8, B0*B6/8, B0*B7/8,
B1*B0/8, B1*B1/8, B1*B2/8, B1*B3/8, B1*B4/8, B1*B5/8, B1*B6/8, B1*B7/8,
B2*B0/8, B2*B1/8, B2*B2/8, B2*B3/8, B2*B4/8, B2*B5/8, B2*B6/8, B2*B7/8,
B3*B0/8, B3*B1/8, B3*B2/8, B3*B3/8, B3*B4/8, B3*B5/8, B3*B6/8, B3*B7/8,
B4*B0/8, B4*B1/8, B4*B2/8, B4*B3/8, B4*B4/8, B4*B5/8, B4*B6/8, B4*B7/8,
B5*B0/8, B5*B1/8, B5*B2/8, B5*B3/8, B5*B4/8, B5*B5/8, B5*B6/8, B5*B7/8,
B6*B0/8, B6*B1/8, B6*B2/8, B6*B3/8, B6*B4/8, B6*B5/8, B6*B6/8, B6*B7/8,
B7*B0/8, B7*B1/8, B7*B2/8, B7*B3/8, B7*B4/8, B7*B5/8, B7*B6/8, B7*B7/8,
};
static inline void p8idct(int16_t data[64], FLOAT temp[64], uint8_t *dest, int stride, int x, int y, int type){
int i;
FLOAT av_unused tmp0;
FLOAT s04, d04, s17, d17, s26, d26, s53, d53;
FLOAT os07, os16, os25, os34;
FLOAT od07, od16, od25, od34;
for(i=0; i<y*8; i+=y){
s17= temp[1*x + i] + temp[7*x + i];
d17= temp[1*x + i] - temp[7*x + i];
s53= temp[5*x + i] + temp[3*x + i];
d53= temp[5*x + i] - temp[3*x + i];
od07= s17 + s53;
od25= (s17 - s53)*(2*A4);
#if 0 //these 2 are equivalent
tmp0= (d17 + d53)*(2*A2);
od34= d17*( 2*B6) - tmp0;
od16= d53*(-2*B2) + tmp0;
#else
od34= d17*(2*(B6-A2)) - d53*(2*A2);
od16= d53*(2*(A2-B2)) + d17*(2*A2);
#endif
od16 -= od07;
od25 -= od16;
od34 += od25;
s26 = temp[2*x + i] + temp[6*x + i];
d26 = temp[2*x + i] - temp[6*x + i];
d26*= 2*A4;
d26-= s26;
s04= temp[0*x + i] + temp[4*x + i];
d04= temp[0*x + i] - temp[4*x + i];
os07= s04 + s26;
os34= s04 - s26;
os16= d04 + d26;
os25= d04 - d26;
if(type==0){
temp[0*x + i]= os07 + od07;
temp[7*x + i]= os07 - od07;
temp[1*x + i]= os16 + od16;
temp[6*x + i]= os16 - od16;
temp[2*x + i]= os25 + od25;
temp[5*x + i]= os25 - od25;
temp[3*x + i]= os34 - od34;
temp[4*x + i]= os34 + od34;
}else if(type==1){
data[0*x + i]= lrintf(os07 + od07);
data[7*x + i]= lrintf(os07 - od07);
data[1*x + i]= lrintf(os16 + od16);
data[6*x + i]= lrintf(os16 - od16);
data[2*x + i]= lrintf(os25 + od25);
data[5*x + i]= lrintf(os25 - od25);
data[3*x + i]= lrintf(os34 - od34);
data[4*x + i]= lrintf(os34 + od34);
}else if(type==2){
dest[0*stride + i]= av_clip_uint8(((int)dest[0*stride + i]) + lrintf(os07 + od07));
dest[7*stride + i]= av_clip_uint8(((int)dest[7*stride + i]) + lrintf(os07 - od07));
dest[1*stride + i]= av_clip_uint8(((int)dest[1*stride + i]) + lrintf(os16 + od16));
dest[6*stride + i]= av_clip_uint8(((int)dest[6*stride + i]) + lrintf(os16 - od16));
dest[2*stride + i]= av_clip_uint8(((int)dest[2*stride + i]) + lrintf(os25 + od25));
dest[5*stride + i]= av_clip_uint8(((int)dest[5*stride + i]) + lrintf(os25 - od25));
dest[3*stride + i]= av_clip_uint8(((int)dest[3*stride + i]) + lrintf(os34 - od34));
dest[4*stride + i]= av_clip_uint8(((int)dest[4*stride + i]) + lrintf(os34 + od34));
}else{
dest[0*stride + i]= av_clip_uint8(lrintf(os07 + od07));
dest[7*stride + i]= av_clip_uint8(lrintf(os07 - od07));
dest[1*stride + i]= av_clip_uint8(lrintf(os16 + od16));
dest[6*stride + i]= av_clip_uint8(lrintf(os16 - od16));
dest[2*stride + i]= av_clip_uint8(lrintf(os25 + od25));
dest[5*stride + i]= av_clip_uint8(lrintf(os25 - od25));
dest[3*stride + i]= av_clip_uint8(lrintf(os34 - od34));
dest[4*stride + i]= av_clip_uint8(lrintf(os34 + od34));
}
}
}
void ff_faanidct(int16_t block[64]){
FLOAT temp[64];
int i;
emms_c();
for(i=0; i<64; i++)
temp[i] = block[i] * prescale[i];
p8idct(block, temp, NULL, 0, 1, 8, 0);
p8idct(block, temp, NULL, 0, 8, 1, 1);
}
void ff_faanidct_add(uint8_t *dest, int line_size, int16_t block[64]){
FLOAT temp[64];
int i;
emms_c();
for(i=0; i<64; i++)
temp[i] = block[i] * prescale[i];
p8idct(block, temp, NULL, 0, 1, 8, 0);
p8idct(NULL , temp, dest, line_size, 8, 1, 2);
}
void ff_faanidct_put(uint8_t *dest, int line_size, int16_t block[64]){
FLOAT temp[64];
int i;
emms_c();
for(i=0; i<64; i++)
temp[i] = block[i] * prescale[i];
p8idct(block, temp, NULL, 0, 1, 8, 0);
p8idct(NULL , temp, dest, line_size, 8, 1, 3);
}

View file

@ -0,0 +1,31 @@
/*
* Floating point AAN IDCT
* Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_FAANIDCT_H
#define AVCODEC_FAANIDCT_H
#include <stdint.h>
void ff_faanidct(int16_t block[64]);
void ff_faanidct_add(uint8_t *dest, int line_size, int16_t block[64]);
void ff_faanidct_put(uint8_t *dest, int line_size, int16_t block[64]);
#endif /* AVCODEC_FAANIDCT_H */

View file

@ -0,0 +1,94 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_FFT_INTERNAL_H
#define AVCODEC_FFT_INTERNAL_H
#if CONFIG_FFT_FLOAT
#define FIX15(v) (v)
#define sqrthalf (float)M_SQRT1_2
#define BF(x, y, a, b) do { \
x = a - b; \
y = a + b; \
} while (0)
#define CMUL(dre, dim, are, aim, bre, bim) do { \
(dre) = (are) * (bre) - (aim) * (bim); \
(dim) = (are) * (bim) + (aim) * (bre); \
} while (0)
#else
#define SCALE_FLOAT(a, bits) lrint((a) * (double)(1 << (bits)))
#if CONFIG_FFT_FIXED_32
#define CMUL(dre, dim, are, aim, bre, bim) do { \
int64_t accu; \
(accu) = (int64_t)(bre) * (are); \
(accu) -= (int64_t)(bim) * (aim); \
(dre) = (int)(((accu) + 0x40000000) >> 31); \
(accu) = (int64_t)(bre) * (aim); \
(accu) += (int64_t)(bim) * (are); \
(dim) = (int)(((accu) + 0x40000000) >> 31); \
} while (0)
#define FIX15(a) av_clip(SCALE_FLOAT(a, 31), -2147483647, 2147483647)
#else /* CONFIG_FFT_FIXED_32 */
#include "fft.h"
#include "mathops.h"
void ff_mdct_calcw_c(FFTContext *s, FFTDouble *output, const FFTSample *input);
#define FIX15(a) av_clip(SCALE_FLOAT(a, 15), -32767, 32767)
#define sqrthalf ((int16_t)((1<<15)*M_SQRT1_2))
#define BF(x, y, a, b) do { \
x = (a - b) >> 1; \
y = (a + b) >> 1; \
} while (0)
#define CMULS(dre, dim, are, aim, bre, bim, sh) do { \
(dre) = (MUL16(are, bre) - MUL16(aim, bim)) >> sh; \
(dim) = (MUL16(are, bim) + MUL16(aim, bre)) >> sh; \
} while (0)
#define CMUL(dre, dim, are, aim, bre, bim) \
CMULS(dre, dim, are, aim, bre, bim, 15)
#define CMULL(dre, dim, are, aim, bre, bim) \
CMULS(dre, dim, are, aim, bre, bim, 0)
#endif /* CONFIG_FFT_FIXED_32 */
#endif /* CONFIG_FFT_FLOAT */
#define ff_imdct_calc_c FFT_NAME(ff_imdct_calc_c)
#define ff_imdct_half_c FFT_NAME(ff_imdct_half_c)
#define ff_mdct_calc_c FFT_NAME(ff_mdct_calc_c)
void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input);
void ff_mdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input);
#endif /* AVCODEC_FFT_INTERNAL_H */

View file

@ -0,0 +1,530 @@
/*
* FFT/IFFT transforms
* Copyright (c) 2008 Loren Merritt
* Copyright (c) 2002 Fabrice Bellard
* Partly based on libdjbfft by D. J. Bernstein
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* FFT/IFFT transforms.
*/
#include <stdlib.h>
#include <string.h>
#include "libavutil/mathematics.h"
#include "fft.h"
#include "fft-internal.h"
#if CONFIG_FFT_FIXED_32
#include "fft_table.h"
#else /* CONFIG_FFT_FIXED_32 */
/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */
#if !CONFIG_HARDCODED_TABLES
COSTABLE(16);
COSTABLE(32);
COSTABLE(64);
COSTABLE(128);
COSTABLE(256);
COSTABLE(512);
COSTABLE(1024);
COSTABLE(2048);
COSTABLE(4096);
COSTABLE(8192);
COSTABLE(16384);
COSTABLE(32768);
COSTABLE(65536);
#endif
COSTABLE_CONST FFTSample * const FFT_NAME(ff_cos_tabs)[] = {
NULL, NULL, NULL, NULL,
FFT_NAME(ff_cos_16),
FFT_NAME(ff_cos_32),
FFT_NAME(ff_cos_64),
FFT_NAME(ff_cos_128),
FFT_NAME(ff_cos_256),
FFT_NAME(ff_cos_512),
FFT_NAME(ff_cos_1024),
FFT_NAME(ff_cos_2048),
FFT_NAME(ff_cos_4096),
FFT_NAME(ff_cos_8192),
FFT_NAME(ff_cos_16384),
FFT_NAME(ff_cos_32768),
FFT_NAME(ff_cos_65536),
};
#endif /* CONFIG_FFT_FIXED_32 */
static void fft_permute_c(FFTContext *s, FFTComplex *z);
static void fft_calc_c(FFTContext *s, FFTComplex *z);
static int split_radix_permutation(int i, int n, int inverse)
{
int m;
if(n <= 2) return i&1;
m = n >> 1;
if(!(i&m)) return split_radix_permutation(i, m, inverse)*2;
m >>= 1;
if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1;
else return split_radix_permutation(i, m, inverse)*4 - 1;
}
av_cold void ff_init_ff_cos_tabs(int index)
{
#if (!CONFIG_HARDCODED_TABLES) && (!CONFIG_FFT_FIXED_32)
int i;
int m = 1<<index;
double freq = 2*M_PI/m;
FFTSample *tab = FFT_NAME(ff_cos_tabs)[index];
for(i=0; i<=m/4; i++)
tab[i] = FIX15(cos(i*freq));
for(i=1; i<m/4; i++)
tab[m/2-i] = tab[i];
#endif
}
static const int avx_tab[] = {
0, 4, 1, 5, 8, 12, 9, 13, 2, 6, 3, 7, 10, 14, 11, 15
};
static int is_second_half_of_fft32(int i, int n)
{
if (n <= 32)
return i >= 16;
else if (i < n/2)
return is_second_half_of_fft32(i, n/2);
else if (i < 3*n/4)
return is_second_half_of_fft32(i - n/2, n/4);
else
return is_second_half_of_fft32(i - 3*n/4, n/4);
}
static av_cold void fft_perm_avx(FFTContext *s)
{
int i;
int n = 1 << s->nbits;
for (i = 0; i < n; i += 16) {
int k;
if (is_second_half_of_fft32(i, n)) {
for (k = 0; k < 16; k++)
s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] =
i + avx_tab[k];
} else {
for (k = 0; k < 16; k++) {
int j = i + k;
j = (j & ~7) | ((j >> 1) & 3) | ((j << 2) & 4);
s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] = j;
}
}
}
}
av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse)
{
int i, j, n;
if (nbits < 2 || nbits > 16)
goto fail;
s->nbits = nbits;
n = 1 << nbits;
s->revtab = av_malloc(n * sizeof(uint16_t));
if (!s->revtab)
goto fail;
s->tmp_buf = av_malloc(n * sizeof(FFTComplex));
if (!s->tmp_buf)
goto fail;
s->inverse = inverse;
s->fft_permutation = FF_FFT_PERM_DEFAULT;
s->fft_permute = fft_permute_c;
s->fft_calc = fft_calc_c;
#if CONFIG_MDCT
s->imdct_calc = ff_imdct_calc_c;
s->imdct_half = ff_imdct_half_c;
s->mdct_calc = ff_mdct_calc_c;
#endif
#if CONFIG_FFT_FIXED_32
{
int n=0;
ff_fft_lut_init(fft_offsets_lut, 0, 1 << 16, &n);
}
#else /* CONFIG_FFT_FIXED_32 */
#if CONFIG_FFT_FLOAT
if (ARCH_ARM) ff_fft_init_arm(s);
if (ARCH_PPC) ff_fft_init_ppc(s);
if (ARCH_X86) ff_fft_init_x86(s);
if (CONFIG_MDCT) s->mdct_calcw = s->mdct_calc;
if (HAVE_MIPSFPU) ff_fft_init_mips(s);
#else
if (CONFIG_MDCT) s->mdct_calcw = ff_mdct_calcw_c;
if (ARCH_ARM) ff_fft_fixed_init_arm(s);
#endif
for(j=4; j<=nbits; j++) {
ff_init_ff_cos_tabs(j);
}
#endif /* CONFIG_FFT_FIXED_32 */
if (s->fft_permutation == FF_FFT_PERM_AVX) {
fft_perm_avx(s);
} else {
for(i=0; i<n; i++) {
j = i;
if (s->fft_permutation == FF_FFT_PERM_SWAP_LSBS)
j = (j&~3) | ((j>>1)&1) | ((j<<1)&2);
s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = j;
}
}
return 0;
fail:
av_freep(&s->revtab);
av_freep(&s->tmp_buf);
return -1;
}
static void fft_permute_c(FFTContext *s, FFTComplex *z)
{
int j, np;
const uint16_t *revtab = s->revtab;
np = 1 << s->nbits;
/* TODO: handle split-radix permute in a more optimal way, probably in-place */
for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j];
memcpy(z, s->tmp_buf, np * sizeof(FFTComplex));
}
av_cold void ff_fft_end(FFTContext *s)
{
av_freep(&s->revtab);
av_freep(&s->tmp_buf);
}
#if CONFIG_FFT_FIXED_32
static void fft_calc_c(FFTContext *s, FFTComplex *z) {
int nbits, i, n, num_transforms, offset, step;
int n4, n2, n34;
FFTSample tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
FFTComplex *tmpz;
FFTSample w_re, w_im;
FFTSample *w_re_ptr, *w_im_ptr;
const int fft_size = (1 << s->nbits);
int64_t accu;
num_transforms = (0x2aab >> (16 - s->nbits)) | 1;
for (n=0; n<num_transforms; n++){
offset = fft_offsets_lut[n] << 2;
tmpz = z + offset;
tmp1 = tmpz[0].re + tmpz[1].re;
tmp5 = tmpz[2].re + tmpz[3].re;
tmp2 = tmpz[0].im + tmpz[1].im;
tmp6 = tmpz[2].im + tmpz[3].im;
tmp3 = tmpz[0].re - tmpz[1].re;
tmp8 = tmpz[2].im - tmpz[3].im;
tmp4 = tmpz[0].im - tmpz[1].im;
tmp7 = tmpz[2].re - tmpz[3].re;
tmpz[0].re = tmp1 + tmp5;
tmpz[2].re = tmp1 - tmp5;
tmpz[0].im = tmp2 + tmp6;
tmpz[2].im = tmp2 - tmp6;
tmpz[1].re = tmp3 + tmp8;
tmpz[3].re = tmp3 - tmp8;
tmpz[1].im = tmp4 - tmp7;
tmpz[3].im = tmp4 + tmp7;
}
if (fft_size < 8)
return;
num_transforms = (num_transforms >> 1) | 1;
for (n=0; n<num_transforms; n++){
offset = fft_offsets_lut[n] << 3;
tmpz = z + offset;
tmp1 = tmpz[4].re + tmpz[5].re;
tmp3 = tmpz[6].re + tmpz[7].re;
tmp2 = tmpz[4].im + tmpz[5].im;
tmp4 = tmpz[6].im + tmpz[7].im;
tmp5 = tmp1 + tmp3;
tmp7 = tmp1 - tmp3;
tmp6 = tmp2 + tmp4;
tmp8 = tmp2 - tmp4;
tmp1 = tmpz[4].re - tmpz[5].re;
tmp2 = tmpz[4].im - tmpz[5].im;
tmp3 = tmpz[6].re - tmpz[7].re;
tmp4 = tmpz[6].im - tmpz[7].im;
tmpz[4].re = tmpz[0].re - tmp5;
tmpz[0].re = tmpz[0].re + tmp5;
tmpz[4].im = tmpz[0].im - tmp6;
tmpz[0].im = tmpz[0].im + tmp6;
tmpz[6].re = tmpz[2].re - tmp8;
tmpz[2].re = tmpz[2].re + tmp8;
tmpz[6].im = tmpz[2].im + tmp7;
tmpz[2].im = tmpz[2].im - tmp7;
accu = (int64_t)Q31(M_SQRT1_2)*(tmp1 + tmp2);
tmp5 = (int32_t)((accu + 0x40000000) >> 31);
accu = (int64_t)Q31(M_SQRT1_2)*(tmp3 - tmp4);
tmp7 = (int32_t)((accu + 0x40000000) >> 31);
accu = (int64_t)Q31(M_SQRT1_2)*(tmp2 - tmp1);
tmp6 = (int32_t)((accu + 0x40000000) >> 31);
accu = (int64_t)Q31(M_SQRT1_2)*(tmp3 + tmp4);
tmp8 = (int32_t)((accu + 0x40000000) >> 31);
tmp1 = tmp5 + tmp7;
tmp3 = tmp5 - tmp7;
tmp2 = tmp6 + tmp8;
tmp4 = tmp6 - tmp8;
tmpz[5].re = tmpz[1].re - tmp1;
tmpz[1].re = tmpz[1].re + tmp1;
tmpz[5].im = tmpz[1].im - tmp2;
tmpz[1].im = tmpz[1].im + tmp2;
tmpz[7].re = tmpz[3].re - tmp4;
tmpz[3].re = tmpz[3].re + tmp4;
tmpz[7].im = tmpz[3].im + tmp3;
tmpz[3].im = tmpz[3].im - tmp3;
}
step = 1 << ((MAX_LOG2_NFFT-4) - 4);
n4 = 4;
for (nbits=4; nbits<=s->nbits; nbits++){
n2 = 2*n4;
n34 = 3*n4;
num_transforms = (num_transforms >> 1) | 1;
for (n=0; n<num_transforms; n++){
offset = fft_offsets_lut[n] << nbits;
tmpz = z + offset;
tmp5 = tmpz[ n2].re + tmpz[n34].re;
tmp1 = tmpz[ n2].re - tmpz[n34].re;
tmp6 = tmpz[ n2].im + tmpz[n34].im;
tmp2 = tmpz[ n2].im - tmpz[n34].im;
tmpz[ n2].re = tmpz[ 0].re - tmp5;
tmpz[ 0].re = tmpz[ 0].re + tmp5;
tmpz[ n2].im = tmpz[ 0].im - tmp6;
tmpz[ 0].im = tmpz[ 0].im + tmp6;
tmpz[n34].re = tmpz[n4].re - tmp2;
tmpz[ n4].re = tmpz[n4].re + tmp2;
tmpz[n34].im = tmpz[n4].im + tmp1;
tmpz[ n4].im = tmpz[n4].im - tmp1;
w_re_ptr = w_tab_sr + step;
w_im_ptr = w_tab_sr + MAX_FFT_SIZE/(4*16) - step;
for (i=1; i<n4; i++){
w_re = w_re_ptr[0];
w_im = w_im_ptr[0];
accu = (int64_t)w_re*tmpz[ n2+i].re;
accu += (int64_t)w_im*tmpz[ n2+i].im;
tmp1 = (int32_t)((accu + 0x40000000) >> 31);
accu = (int64_t)w_re*tmpz[ n2+i].im;
accu -= (int64_t)w_im*tmpz[ n2+i].re;
tmp2 = (int32_t)((accu + 0x40000000) >> 31);
accu = (int64_t)w_re*tmpz[n34+i].re;
accu -= (int64_t)w_im*tmpz[n34+i].im;
tmp3 = (int32_t)((accu + 0x40000000) >> 31);
accu = (int64_t)w_re*tmpz[n34+i].im;
accu += (int64_t)w_im*tmpz[n34+i].re;
tmp4 = (int32_t)((accu + 0x40000000) >> 31);
tmp5 = tmp1 + tmp3;
tmp1 = tmp1 - tmp3;
tmp6 = tmp2 + tmp4;
tmp2 = tmp2 - tmp4;
tmpz[ n2+i].re = tmpz[ i].re - tmp5;
tmpz[ i].re = tmpz[ i].re + tmp5;
tmpz[ n2+i].im = tmpz[ i].im - tmp6;
tmpz[ i].im = tmpz[ i].im + tmp6;
tmpz[n34+i].re = tmpz[n4+i].re - tmp2;
tmpz[ n4+i].re = tmpz[n4+i].re + tmp2;
tmpz[n34+i].im = tmpz[n4+i].im + tmp1;
tmpz[ n4+i].im = tmpz[n4+i].im - tmp1;
w_re_ptr += step;
w_im_ptr -= step;
}
}
step >>= 1;
n4 <<= 1;
}
}
#else /* CONFIG_FFT_FIXED_32 */
#define BUTTERFLIES(a0,a1,a2,a3) {\
BF(t3, t5, t5, t1);\
BF(a2.re, a0.re, a0.re, t5);\
BF(a3.im, a1.im, a1.im, t3);\
BF(t4, t6, t2, t6);\
BF(a3.re, a1.re, a1.re, t4);\
BF(a2.im, a0.im, a0.im, t6);\
}
// force loading all the inputs before storing any.
// this is slightly slower for small data, but avoids store->load aliasing
// for addresses separated by large powers of 2.
#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\
FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\
BF(t3, t5, t5, t1);\
BF(a2.re, a0.re, r0, t5);\
BF(a3.im, a1.im, i1, t3);\
BF(t4, t6, t2, t6);\
BF(a3.re, a1.re, r1, t4);\
BF(a2.im, a0.im, i0, t6);\
}
#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\
CMUL(t1, t2, a2.re, a2.im, wre, -wim);\
CMUL(t5, t6, a3.re, a3.im, wre, wim);\
BUTTERFLIES(a0,a1,a2,a3)\
}
#define TRANSFORM_ZERO(a0,a1,a2,a3) {\
t1 = a2.re;\
t2 = a2.im;\
t5 = a3.re;\
t6 = a3.im;\
BUTTERFLIES(a0,a1,a2,a3)\
}
/* z[0...8n-1], w[1...2n-1] */
#define PASS(name)\
static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\
{\
FFTDouble t1, t2, t3, t4, t5, t6;\
int o1 = 2*n;\
int o2 = 4*n;\
int o3 = 6*n;\
const FFTSample *wim = wre+o1;\
n--;\
\
TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\
TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
do {\
z += 2;\
wre += 2;\
wim -= 2;\
TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\
TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
} while(--n);\
}
PASS(pass)
#undef BUTTERFLIES
#define BUTTERFLIES BUTTERFLIES_BIG
PASS(pass_big)
#define DECL_FFT(n,n2,n4)\
static void fft##n(FFTComplex *z)\
{\
fft##n2(z);\
fft##n4(z+n4*2);\
fft##n4(z+n4*3);\
pass(z,FFT_NAME(ff_cos_##n),n4/2);\
}
static void fft4(FFTComplex *z)
{
FFTDouble t1, t2, t3, t4, t5, t6, t7, t8;
BF(t3, t1, z[0].re, z[1].re);
BF(t8, t6, z[3].re, z[2].re);
BF(z[2].re, z[0].re, t1, t6);
BF(t4, t2, z[0].im, z[1].im);
BF(t7, t5, z[2].im, z[3].im);
BF(z[3].im, z[1].im, t4, t8);
BF(z[3].re, z[1].re, t3, t7);
BF(z[2].im, z[0].im, t2, t5);
}
static void fft8(FFTComplex *z)
{
FFTDouble t1, t2, t3, t4, t5, t6;
fft4(z);
BF(t1, z[5].re, z[4].re, -z[5].re);
BF(t2, z[5].im, z[4].im, -z[5].im);
BF(t5, z[7].re, z[6].re, -z[7].re);
BF(t6, z[7].im, z[6].im, -z[7].im);
BUTTERFLIES(z[0],z[2],z[4],z[6]);
TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf);
}
#if !CONFIG_SMALL
static void fft16(FFTComplex *z)
{
FFTDouble t1, t2, t3, t4, t5, t6;
FFTSample cos_16_1 = FFT_NAME(ff_cos_16)[1];
FFTSample cos_16_3 = FFT_NAME(ff_cos_16)[3];
fft8(z);
fft4(z+8);
fft4(z+12);
TRANSFORM_ZERO(z[0],z[4],z[8],z[12]);
TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf);
TRANSFORM(z[1],z[5],z[9],z[13],cos_16_1,cos_16_3);
TRANSFORM(z[3],z[7],z[11],z[15],cos_16_3,cos_16_1);
}
#else
DECL_FFT(16,8,4)
#endif
DECL_FFT(32,16,8)
DECL_FFT(64,32,16)
DECL_FFT(128,64,32)
DECL_FFT(256,128,64)
DECL_FFT(512,256,128)
#if !CONFIG_SMALL
#define pass pass_big
#endif
DECL_FFT(1024,512,256)
DECL_FFT(2048,1024,512)
DECL_FFT(4096,2048,1024)
DECL_FFT(8192,4096,2048)
DECL_FFT(16384,8192,4096)
DECL_FFT(32768,16384,8192)
DECL_FFT(65536,32768,16384)
static void (* const fft_dispatch[])(FFTComplex*) = {
fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
};
static void fft_calc_c(FFTContext *s, FFTComplex *z)
{
fft_dispatch[s->nbits-2](z);
}
#endif /* CONFIG_FFT_FIXED_32 */

View file

@ -0,0 +1,166 @@
/*
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_FFT_H
#define AVCODEC_FFT_H
#ifndef CONFIG_FFT_FLOAT
#define CONFIG_FFT_FLOAT 1
#endif
#ifndef CONFIG_FFT_FIXED_32
#define CONFIG_FFT_FIXED_32 0
#endif
#include <stdint.h>
#include "config.h"
#include "libavutil/mem.h"
#if CONFIG_FFT_FLOAT
#include "avfft.h"
#define FFT_NAME(x) x
typedef float FFTDouble;
#else
#if CONFIG_FFT_FIXED_32
#define Q31(x) (int)((x)*2147483648.0 + 0.5)
#define FFT_NAME(x) x ## _fixed_32
typedef int32_t FFTSample;
#else /* CONFIG_FFT_FIXED_32 */
#define FFT_NAME(x) x ## _fixed
typedef int16_t FFTSample;
#endif /* CONFIG_FFT_FIXED_32 */
typedef struct FFTComplex {
FFTSample re, im;
} FFTComplex;
typedef int FFTDouble;
typedef struct FFTContext FFTContext;
#endif /* CONFIG_FFT_FLOAT */
typedef struct FFTDComplex {
FFTDouble re, im;
} FFTDComplex;
/* FFT computation */
struct FFTContext {
int nbits;
int inverse;
uint16_t *revtab;
FFTComplex *tmp_buf;
int mdct_size; /* size of MDCT (i.e. number of input data * 2) */
int mdct_bits; /* n = 2^nbits */
/* pre/post rotation tables */
FFTSample *tcos;
FFTSample *tsin;
/**
* Do the permutation needed BEFORE calling fft_calc().
*/
void (*fft_permute)(struct FFTContext *s, FFTComplex *z);
/**
* Do a complex FFT with the parameters defined in ff_fft_init(). The
* input data must be permuted before. No 1.0/sqrt(n) normalization is done.
*/
void (*fft_calc)(struct FFTContext *s, FFTComplex *z);
void (*imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
void (*imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
void (*mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
void (*mdct_calcw)(struct FFTContext *s, FFTDouble *output, const FFTSample *input);
int fft_permutation;
#define FF_FFT_PERM_DEFAULT 0
#define FF_FFT_PERM_SWAP_LSBS 1
#define FF_FFT_PERM_AVX 2
int mdct_permutation;
#define FF_MDCT_PERM_NONE 0
#define FF_MDCT_PERM_INTERLEAVE 1
};
#if CONFIG_HARDCODED_TABLES
#define COSTABLE_CONST const
#else
#define COSTABLE_CONST
#endif
#define COSTABLE(size) \
COSTABLE_CONST DECLARE_ALIGNED(32, FFTSample, FFT_NAME(ff_cos_##size))[size/2]
extern COSTABLE(16);
extern COSTABLE(32);
extern COSTABLE(64);
extern COSTABLE(128);
extern COSTABLE(256);
extern COSTABLE(512);
extern COSTABLE(1024);
extern COSTABLE(2048);
extern COSTABLE(4096);
extern COSTABLE(8192);
extern COSTABLE(16384);
extern COSTABLE(32768);
extern COSTABLE(65536);
extern COSTABLE_CONST FFTSample* const FFT_NAME(ff_cos_tabs)[17];
#define ff_init_ff_cos_tabs FFT_NAME(ff_init_ff_cos_tabs)
/**
* Initialize the cosine table in ff_cos_tabs[index]
* @param index index in ff_cos_tabs array of the table to initialize
*/
void ff_init_ff_cos_tabs(int index);
#define ff_fft_init FFT_NAME(ff_fft_init)
#define ff_fft_end FFT_NAME(ff_fft_end)
/**
* Set up a complex FFT.
* @param nbits log2 of the length of the input array
* @param inverse if 0 perform the forward transform, if 1 perform the inverse
*/
int ff_fft_init(FFTContext *s, int nbits, int inverse);
void ff_fft_init_x86(FFTContext *s);
void ff_fft_init_arm(FFTContext *s);
void ff_fft_init_mips(FFTContext *s);
void ff_fft_init_ppc(FFTContext *s);
void ff_fft_fixed_init_arm(FFTContext *s);
void ff_fft_end(FFTContext *s);
#define ff_mdct_init FFT_NAME(ff_mdct_init)
#define ff_mdct_end FFT_NAME(ff_mdct_end)
int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale);
void ff_mdct_end(FFTContext *s);
#endif /* AVCODEC_FFT_H */

View file

@ -0,0 +1,135 @@
/*
* Format Conversion Utils
* Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "avcodec.h"
#include "fmtconvert.h"
#include "libavutil/common.h"
static void int32_to_float_fmul_scalar_c(float *dst, const int32_t *src,
float mul, int len)
{
int i;
for(i=0; i<len; i++)
dst[i] = src[i] * mul;
}
static void int32_to_float_fmul_array8_c(FmtConvertContext *c, float *dst,
const int32_t *src, const float *mul,
int len)
{
int i;
for (i = 0; i < len; i += 8)
c->int32_to_float_fmul_scalar(&dst[i], &src[i], *mul++, 8);
}
static av_always_inline int float_to_int16_one(const float *src){
return av_clip_int16(lrintf(*src));
}
static void float_to_int16_c(int16_t *dst, const float *src, long len)
{
int i;
for(i=0; i<len; i++)
dst[i] = float_to_int16_one(src+i);
}
static void float_to_int16_interleave_c(int16_t *dst, const float **src,
long len, int channels)
{
int i,j,c;
if(channels==2){
for(i=0; i<len; i++){
dst[2*i] = float_to_int16_one(src[0]+i);
dst[2*i+1] = float_to_int16_one(src[1]+i);
}
}else{
for(c=0; c<channels; c++)
for(i=0, j=c; i<len; i++, j+=channels)
dst[j] = float_to_int16_one(src[c]+i);
}
}
void ff_float_interleave_c(float *dst, const float **src, unsigned int len,
int channels)
{
int j, c;
unsigned int i;
if (channels == 2) {
for (i = 0; i < len; i++) {
dst[2*i] = src[0][i];
dst[2*i+1] = src[1][i];
}
} else if (channels == 1 && len < INT_MAX / sizeof(float)) {
memcpy(dst, src[0], len * sizeof(float));
} else {
for (c = 0; c < channels; c++)
for (i = 0, j = c; i < len; i++, j += channels)
dst[j] = src[c][i];
}
}
av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx)
{
c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c;
c->int32_to_float_fmul_array8 = int32_to_float_fmul_array8_c;
c->float_to_int16 = float_to_int16_c;
c->float_to_int16_interleave = float_to_int16_interleave_c;
c->float_interleave = ff_float_interleave_c;
if (ARCH_ARM) ff_fmt_convert_init_arm(c, avctx);
if (ARCH_PPC) ff_fmt_convert_init_ppc(c, avctx);
if (ARCH_X86) ff_fmt_convert_init_x86(c, avctx);
if (HAVE_MIPSFPU) ff_fmt_convert_init_mips(c);
}
/* ffdshow custom code */
void float_interleave(float *dst, const float **src, long len, int channels)
{
int i,j,c;
if(channels==2){
for(i=0; i<len; i++){
dst[2*i] = src[0][i] / 32768.0f;
dst[2*i+1] = src[1][i] / 32768.0f;
}
}else{
for(c=0; c<channels; c++)
for(i=0, j=c; i<len; i++, j+=channels)
dst[j] = src[c][i] / 32768.0f;
}
}
void float_interleave_noscale(float *dst, const float **src, long len, int channels)
{
int i,j,c;
if(channels==2){
for(i=0; i<len; i++){
dst[2*i] = src[0][i];
dst[2*i+1] = src[1][i];
}
}else{
for(c=0; c<channels; c++)
for(i=0, j=c; i<len; i++, j+=channels)
dst[j] = src[c][i];
}
}

View file

@ -0,0 +1,118 @@
/*
* Format Conversion Utils
* Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_FMTCONVERT_H
#define AVCODEC_FMTCONVERT_H
#include "avcodec.h"
typedef struct FmtConvertContext {
/**
* Convert an array of int32_t to float and multiply by a float value.
* @param dst destination array of float.
* constraints: 16-byte aligned
* @param src source array of int32_t.
* constraints: 16-byte aligned
* @param len number of elements to convert.
* constraints: multiple of 8
*/
void (*int32_to_float_fmul_scalar)(float *dst, const int32_t *src,
float mul, int len);
/**
* Convert an array of int32_t to float and multiply by a float value from another array,
* stepping along the float array once for each 8 integers.
* @param c pointer to FmtConvertContext.
* @param dst destination array of float.
* constraints: 16-byte aligned
* @param src source array of int32_t.
* constraints: 16-byte aligned
* @param mul source array of float multipliers.
* @param len number of elements to convert.
* constraints: multiple of 8
*/
void (*int32_to_float_fmul_array8)(struct FmtConvertContext *c,
float *dst, const int32_t *src,
const float *mul, int len);
/**
* Convert an array of float to an array of int16_t.
*
* Convert floats from in the range [-32768.0,32767.0] to ints
* without rescaling
*
* @param dst destination array of int16_t.
* constraints: 16-byte aligned
* @param src source array of float.
* constraints: 16-byte aligned
* @param len number of elements to convert.
* constraints: multiple of 8
*/
void (*float_to_int16)(int16_t *dst, const float *src, long len);
/**
* Convert multiple arrays of float to an interleaved array of int16_t.
*
* Convert floats from in the range [-32768.0,32767.0] to ints
* without rescaling
*
* @param dst destination array of interleaved int16_t.
* constraints: 16-byte aligned
* @param src source array of float arrays, one for each channel.
* constraints: 16-byte aligned
* @param len number of elements to convert.
* constraints: multiple of 8
* @param channels number of channels
*/
void (*float_to_int16_interleave)(int16_t *dst, const float **src,
long len, int channels);
/**
* Convert multiple arrays of float to an array of interleaved float.
*
* @param dst destination array of interleaved float.
* constraints: 16-byte aligned
* @param src source array of float arrays, one for each channel.
* constraints: 16-byte aligned
* @param len number of elements to convert.
* constraints: multiple of 8
* @param channels number of channels
*/
void (*float_interleave)(float *dst, const float **src, unsigned int len,
int channels);
} FmtConvertContext;
void ff_float_interleave_c(float *dst, const float **src, unsigned int len,
int channels);
void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx);
void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx);
void ff_fmt_convert_init_ppc(FmtConvertContext *c, AVCodecContext *avctx);
void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx);
void ff_fmt_convert_init_mips(FmtConvertContext *c);
/* ffdshow custom code */
void float_interleave(float *dst, const float **src, long len, int channels);
void float_interleave_noscale(float *dst, const float **src, long len, int channels);
#endif /* AVCODEC_FMTCONVERT_H */

View file

@ -0,0 +1,271 @@
/*
* Copyright (c) 2012 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "frame_thread_encoder.h"
#include "libavutil/fifo.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/internal.h"
#include "avcodec.h"
#include "internal.h"
#include "thread.h"
#if HAVE_PTHREADS
#include <pthread.h>
#elif HAVE_W32THREADS
#include "compat/w32pthreads.h"
#elif HAVE_OS2THREADS
#include "compat/os2threads.h"
#endif
#define MAX_THREADS 64
#define BUFFER_SIZE (2*MAX_THREADS)
typedef struct{
void *indata;
void *outdata;
int64_t return_code;
unsigned index;
} Task;
typedef struct{
AVCodecContext *parent_avctx;
pthread_mutex_t buffer_mutex;
AVFifoBuffer *task_fifo;
pthread_mutex_t task_fifo_mutex;
pthread_cond_t task_fifo_cond;
Task finished_tasks[BUFFER_SIZE];
pthread_mutex_t finished_task_mutex;
pthread_cond_t finished_task_cond;
unsigned task_index;
unsigned finished_task_index;
pthread_t worker[MAX_THREADS];
int exit;
} ThreadContext;
static void * attribute_align_arg worker(void *v){
AVCodecContext *avctx = v;
ThreadContext *c = avctx->internal->frame_thread_encoder;
AVPacket *pkt = NULL;
while(!c->exit){
int got_packet, ret;
AVFrame *frame;
Task task;
if(!pkt) pkt= av_mallocz(sizeof(*pkt));
if(!pkt) continue;
av_init_packet(pkt);
pthread_mutex_lock(&c->task_fifo_mutex);
while (av_fifo_size(c->task_fifo) <= 0 || c->exit) {
if(c->exit){
pthread_mutex_unlock(&c->task_fifo_mutex);
goto end;
}
pthread_cond_wait(&c->task_fifo_cond, &c->task_fifo_mutex);
}
av_fifo_generic_read(c->task_fifo, &task, sizeof(task), NULL);
pthread_mutex_unlock(&c->task_fifo_mutex);
frame = task.indata;
ret = avcodec_encode_video2(avctx, pkt, frame, &got_packet);
pthread_mutex_lock(&c->buffer_mutex);
av_frame_unref(frame);
pthread_mutex_unlock(&c->buffer_mutex);
av_frame_free(&frame);
if(got_packet) {
av_dup_packet(pkt);
} else {
pkt->data = NULL;
pkt->size = 0;
}
pthread_mutex_lock(&c->finished_task_mutex);
c->finished_tasks[task.index].outdata = pkt; pkt = NULL;
c->finished_tasks[task.index].return_code = ret;
pthread_cond_signal(&c->finished_task_cond);
pthread_mutex_unlock(&c->finished_task_mutex);
}
end:
av_free(pkt);
pthread_mutex_lock(&c->buffer_mutex);
avcodec_close(avctx);
pthread_mutex_unlock(&c->buffer_mutex);
av_freep(&avctx);
return NULL;
}
int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){
int i=0;
ThreadContext *c;
if( !(avctx->thread_type & FF_THREAD_FRAME)
|| !(avctx->codec->capabilities & CODEC_CAP_INTRA_ONLY))
return 0;
if(!avctx->thread_count) {
avctx->thread_count = av_cpu_count();
avctx->thread_count = FFMIN(avctx->thread_count, MAX_THREADS);
}
if(avctx->thread_count <= 1)
return 0;
if(avctx->thread_count > MAX_THREADS)
return AVERROR(EINVAL);
av_assert0(!avctx->internal->frame_thread_encoder);
c = avctx->internal->frame_thread_encoder = av_mallocz(sizeof(ThreadContext));
if(!c)
return AVERROR(ENOMEM);
c->parent_avctx = avctx;
c->task_fifo = av_fifo_alloc(sizeof(Task) * BUFFER_SIZE);
if(!c->task_fifo)
goto fail;
pthread_mutex_init(&c->task_fifo_mutex, NULL);
pthread_mutex_init(&c->finished_task_mutex, NULL);
pthread_mutex_init(&c->buffer_mutex, NULL);
pthread_cond_init(&c->task_fifo_cond, NULL);
pthread_cond_init(&c->finished_task_cond, NULL);
for(i=0; i<avctx->thread_count ; i++){
AVDictionary *tmp = NULL;
void *tmpv;
AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec);
if(!thread_avctx)
goto fail;
tmpv = thread_avctx->priv_data;
*thread_avctx = *avctx;
thread_avctx->priv_data = tmpv;
thread_avctx->internal = NULL;
memcpy(thread_avctx->priv_data, avctx->priv_data, avctx->codec->priv_data_size);
thread_avctx->thread_count = 1;
thread_avctx->active_thread_type &= ~FF_THREAD_FRAME;
av_dict_copy(&tmp, options, 0);
av_dict_set(&tmp, "threads", "1", 0);
if(avcodec_open2(thread_avctx, avctx->codec, &tmp) < 0) {
av_dict_free(&tmp);
goto fail;
}
av_dict_free(&tmp);
av_assert0(!thread_avctx->internal->frame_thread_encoder);
thread_avctx->internal->frame_thread_encoder = c;
if(pthread_create(&c->worker[i], NULL, worker, thread_avctx)) {
goto fail;
}
}
avctx->active_thread_type = FF_THREAD_FRAME;
return 0;
fail:
avctx->thread_count = i;
av_log(avctx, AV_LOG_ERROR, "ff_frame_thread_encoder_init failed\n");
ff_frame_thread_encoder_free(avctx);
return -1;
}
void ff_frame_thread_encoder_free(AVCodecContext *avctx){
int i;
ThreadContext *c= avctx->internal->frame_thread_encoder;
pthread_mutex_lock(&c->task_fifo_mutex);
c->exit = 1;
pthread_cond_broadcast(&c->task_fifo_cond);
pthread_mutex_unlock(&c->task_fifo_mutex);
for (i=0; i<avctx->thread_count; i++) {
pthread_join(c->worker[i], NULL);
}
pthread_mutex_destroy(&c->task_fifo_mutex);
pthread_mutex_destroy(&c->finished_task_mutex);
pthread_mutex_destroy(&c->buffer_mutex);
pthread_cond_destroy(&c->task_fifo_cond);
pthread_cond_destroy(&c->finished_task_cond);
av_fifo_free(c->task_fifo); c->task_fifo = NULL;
av_freep(&avctx->internal->frame_thread_encoder);
}
int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr){
ThreadContext *c = avctx->internal->frame_thread_encoder;
Task task;
int ret;
av_assert1(!*got_packet_ptr);
if(frame){
if(!(avctx->flags & CODEC_FLAG_INPUT_PRESERVED)){
AVFrame *new = av_frame_alloc();
if(!new)
return AVERROR(ENOMEM);
pthread_mutex_lock(&c->buffer_mutex);
ret = ff_get_buffer(c->parent_avctx, new, 0);
pthread_mutex_unlock(&c->buffer_mutex);
if(ret<0)
return ret;
new->pts = frame->pts;
new->quality = frame->quality;
new->pict_type = frame->pict_type;
av_image_copy(new->data, new->linesize, (const uint8_t **)frame->data, frame->linesize,
avctx->pix_fmt, avctx->width, avctx->height);
frame = new;
}
task.index = c->task_index;
task.indata = (void*)frame;
pthread_mutex_lock(&c->task_fifo_mutex);
av_fifo_generic_write(c->task_fifo, &task, sizeof(task), NULL);
pthread_cond_signal(&c->task_fifo_cond);
pthread_mutex_unlock(&c->task_fifo_mutex);
c->task_index = (c->task_index+1) % BUFFER_SIZE;
if(!c->finished_tasks[c->finished_task_index].outdata && (c->task_index - c->finished_task_index) % BUFFER_SIZE <= avctx->thread_count)
return 0;
}
if(c->task_index == c->finished_task_index)
return 0;
pthread_mutex_lock(&c->finished_task_mutex);
while (!c->finished_tasks[c->finished_task_index].outdata) {
pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex);
}
task = c->finished_tasks[c->finished_task_index];
*pkt = *(AVPacket*)(task.outdata);
if(pkt->data)
*got_packet_ptr = 1;
av_freep(&c->finished_tasks[c->finished_task_index].outdata);
c->finished_task_index = (c->finished_task_index+1) % BUFFER_SIZE;
pthread_mutex_unlock(&c->finished_task_mutex);
return task.return_code;
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2012 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avcodec.h"
int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options);
void ff_frame_thread_encoder_free(AVCodecContext *avctx);
int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr);

View file

@ -0,0 +1,657 @@
/*
* copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* bitstream reader API header.
*/
#ifndef AVCODEC_GET_BITS_H
#define AVCODEC_GET_BITS_H
#include <stdint.h>
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/avassert.h"
#include "mathops.h"
/*
* Safe bitstream reading:
* optionally, the get_bits API can check to ensure that we
* don't read past input buffer boundaries. This is protected
* with CONFIG_SAFE_BITSTREAM_READER at the global level, and
* then below that with UNCHECKED_BITSTREAM_READER at the per-
* decoder level. This means that decoders that check internally
* can "#define UNCHECKED_BITSTREAM_READER 1" to disable
* overread checks.
* Boundary checking causes a minor performance penalty so for
* applications that won't want/need this, it can be disabled
* globally using "#define CONFIG_SAFE_BITSTREAM_READER 0".
*/
#ifndef UNCHECKED_BITSTREAM_READER
#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER
#endif
typedef struct GetBitContext {
const uint8_t *buffer, *buffer_end;
int index;
int size_in_bits;
int size_in_bits_plus8;
} GetBitContext;
#define VLC_TYPE int16_t
typedef struct VLC {
int bits;
VLC_TYPE (*table)[2]; ///< code, bits
int table_size, table_allocated;
void * volatile init_state;
} VLC;
typedef struct RL_VLC_ELEM {
int16_t level;
int8_t len;
uint8_t run;
} RL_VLC_ELEM;
/* Bitstream reader API docs:
* name
* arbitrary name which is used as prefix for the internal variables
*
* gb
* getbitcontext
*
* OPEN_READER(name, gb)
* load gb into local variables
*
* CLOSE_READER(name, gb)
* store local vars in gb
*
* UPDATE_CACHE(name, gb)
* Refill 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 next num bits.
*
* SHOW_SBITS(name, gb, num)
* Will return the next num bits and do sign extension.
*
* SKIP_BITS(name, gb, num)
* Will skip over the next num bits.
* Note, this is equivalent 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_BITS(name, gb, num)
* Like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER.
*
* For examples see get_bits, show_bits, skip_bits, get_vlc.
*/
#ifdef LONG_BITSTREAM_READER
# define MIN_CACHE_BITS 32
#else
# define MIN_CACHE_BITS 25
#endif
#if UNCHECKED_BITSTREAM_READER
#define OPEN_READER(name, gb) \
unsigned int name ## _index = (gb)->index; \
unsigned int av_unused name ## _cache
#define HAVE_BITS_REMAINING(name, gb) 1
#else
#define OPEN_READER(name, gb) \
unsigned int name ## _index = (gb)->index; \
unsigned int av_unused name ## _cache = 0; \
unsigned int av_unused name ## _size_plus8 = (gb)->size_in_bits_plus8
#define HAVE_BITS_REMAINING(name, gb) name ## _index < name ## _size_plus8
#endif
#define CLOSE_READER(name, gb) (gb)->index = name ## _index
# ifdef LONG_BITSTREAM_READER
# define UPDATE_CACHE_LE(name, gb) name ## _cache = \
AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
# define UPDATE_CACHE_BE(name, gb) name ## _cache = \
AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7))
#else
# define UPDATE_CACHE_LE(name, gb) name ## _cache = \
AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
# define UPDATE_CACHE_BE(name, gb) name ## _cache = \
AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7)
#endif
#ifdef BITSTREAM_READER_LE
# define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb)
# define SKIP_CACHE(name, gb, num) name ## _cache >>= (num)
#else
# define UPDATE_CACHE(name, gb) UPDATE_CACHE_BE(name, gb)
# define SKIP_CACHE(name, gb, num) name ## _cache <<= (num)
#endif
#if UNCHECKED_BITSTREAM_READER
# define SKIP_COUNTER(name, gb, num) name ## _index += (num)
#else
# define SKIP_COUNTER(name, gb, num) \
name ## _index = FFMIN(name ## _size_plus8, name ## _index + (num))
#endif
#define SKIP_BITS(name, gb, num) \
do { \
SKIP_CACHE(name, gb, num); \
SKIP_COUNTER(name, gb, num); \
} while (0)
#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
#define SHOW_UBITS_LE(name, gb, num) zero_extend(name ## _cache, num)
#define SHOW_SBITS_LE(name, gb, num) sign_extend(name ## _cache, num)
#define SHOW_UBITS_BE(name, gb, num) NEG_USR32(name ## _cache, num)
#define SHOW_SBITS_BE(name, gb, num) NEG_SSR32(name ## _cache, num)
#ifdef BITSTREAM_READER_LE
# define SHOW_UBITS(name, gb, num) SHOW_UBITS_LE(name, gb, num)
# define SHOW_SBITS(name, gb, num) SHOW_SBITS_LE(name, gb, num)
#else
# define SHOW_UBITS(name, gb, num) SHOW_UBITS_BE(name, gb, num)
# define SHOW_SBITS(name, gb, num) SHOW_SBITS_BE(name, gb, num)
#endif
#define GET_CACHE(name, gb) ((uint32_t) name ## _cache)
static inline int get_bits_count(const GetBitContext *s)
{
return s->index;
}
static inline void skip_bits_long(GetBitContext *s, int n)
{
#if UNCHECKED_BITSTREAM_READER
s->index += n;
#else
s->index += av_clip(n, -s->index, s->size_in_bits_plus8 - s->index);
#endif
}
/**
* read mpeg1 dc style vlc (sign bit + mantisse with no MSB).
* if MSB not set it is negative
* @param n length in bits
*/
static inline int get_xbits(GetBitContext *s, int n)
{
register int sign;
register int32_t cache;
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
cache = GET_CACHE(re, s);
sign = ~cache >> 31;
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return (NEG_USR32(sign ^ cache, n) ^ sign) - sign;
}
static inline int get_sbits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
tmp = SHOW_SBITS(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return tmp;
}
/**
* Read 1-25 bits.
*/
static inline unsigned int get_bits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
tmp = SHOW_UBITS(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return tmp;
}
static inline unsigned int get_bits_le(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE_LE(re, s);
tmp = SHOW_UBITS_LE(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return tmp;
}
/**
* Show 1-25 bits.
*/
static inline unsigned int show_bits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
tmp = SHOW_UBITS(re, s, n);
return tmp;
}
static inline void skip_bits(GetBitContext *s, int n)
{
OPEN_READER(re, s);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
}
static inline unsigned int get_bits1(GetBitContext *s)
{
unsigned int index = s->index;
uint8_t result = s->buffer[index >> 3];
#ifdef BITSTREAM_READER_LE
result >>= index & 7;
result &= 1;
#else
result <<= index & 7;
result >>= 8 - 1;
#endif
#if !UNCHECKED_BITSTREAM_READER
if (s->index < s->size_in_bits_plus8)
#endif
index++;
s->index = index;
return result;
}
static inline unsigned int show_bits1(GetBitContext *s)
{
return show_bits(s, 1);
}
static inline void skip_bits1(GetBitContext *s)
{
skip_bits(s, 1);
}
/**
* Read 0-32 bits.
*/
static inline unsigned int get_bits_long(GetBitContext *s, int n)
{
if (!n) {
return 0;
} else if (n <= MIN_CACHE_BITS) {
return get_bits(s, n);
} else {
#ifdef BITSTREAM_READER_LE
unsigned ret = get_bits(s, 16);
return ret | (get_bits(s, n - 16) << 16);
#else
unsigned ret = get_bits(s, 16) << (n - 16);
return ret | get_bits(s, n - 16);
#endif
}
}
/**
* Read 0-64 bits.
*/
static inline uint64_t get_bits64(GetBitContext *s, int n)
{
if (n <= 32) {
return get_bits_long(s, n);
} else {
#ifdef BITSTREAM_READER_LE
uint64_t ret = get_bits_long(s, 32);
return ret | (uint64_t) get_bits_long(s, n - 32) << 32;
#else
uint64_t ret = (uint64_t) get_bits_long(s, n - 32) << 32;
return ret | get_bits_long(s, 32);
#endif
}
}
/**
* Read 0-32 bits as a signed integer.
*/
static inline int get_sbits_long(GetBitContext *s, int n)
{
return sign_extend(get_bits_long(s, n), n);
}
/**
* Show 0-32 bits.
*/
static inline unsigned int show_bits_long(GetBitContext *s, int n)
{
if (n <= MIN_CACHE_BITS) {
return show_bits(s, n);
} else {
GetBitContext gb = *s;
return get_bits_long(&gb, n);
}
}
static inline 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;
}
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes
* larger than 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
* @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
*/
static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
int bit_size)
{
int buffer_size;
int ret = 0;
if (bit_size >= INT_MAX - 7 || bit_size < 0 || !buffer) {
buffer_size = bit_size = 0;
buffer = NULL;
ret = AVERROR_INVALIDDATA;
}
buffer_size = (bit_size + 7) >> 3;
s->buffer = buffer;
s->size_in_bits = bit_size;
s->size_in_bits_plus8 = bit_size + 8;
s->buffer_end = buffer + buffer_size;
s->index = 0;
return ret;
}
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes
* larger than the actual read bits because some optimized bitstream
* readers read 32 or 64 bit at once and could read over the end
* @param byte_size the size of the buffer in bytes
* @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
*/
static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer,
int byte_size)
{
if (byte_size > INT_MAX / 8 || byte_size < 0)
byte_size = -1;
return init_get_bits(s, buffer, byte_size * 8);
}
static inline const uint8_t *align_get_bits(GetBitContext *s)
{
int n = -get_bits_count(s) & 7;
if (n)
skip_bits(s, n);
return s->buffer + (s->index >> 3);
}
#define init_vlc(vlc, nb_bits, nb_codes, \
bits, bits_wrap, bits_size, \
codes, codes_wrap, codes_size, \
flags) \
ff_init_vlc_sparse(vlc, nb_bits, nb_codes, \
bits, bits_wrap, bits_size, \
codes, codes_wrap, codes_size, \
NULL, 0, 0, flags)
int ff_init_vlc_sparse(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,
const void *symbols, int symbols_wrap, int symbols_size,
int flags);
void ff_free_vlc(VLC *vlc);
#define INIT_VLC_LE 2
#define INIT_VLC_USE_NEW_STATIC 4
#define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \
do { \
static VLC_TYPE table[static_size][2]; \
(vlc)->table = table; \
(vlc)->table_allocated = static_size; \
init_vlc(vlc, bits, a, b, c, d, e, f, g, INIT_VLC_USE_NEW_STATIC); \
} while (0)
/**
* If the vlc code is invalid and max_depth=1, then no bits will be removed.
* If the vlc code is invalid and max_depth>1, then the number of bits removed
* is undefined.
*/
#define GET_VLC(code, name, gb, table, bits, max_depth) \
do { \
int n, nb_bits; \
unsigned int index; \
\
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); \
} while (0)
#define GET_RL_VLC(level, run, name, gb, table, bits, \
max_depth, need_update) \
do { \
int n, nb_bits; \
unsigned int index; \
\
index = SHOW_UBITS(name, gb, bits); \
level = table[index].level; \
n = table[index].len; \
\
if (max_depth > 1 && n < 0) { \
SKIP_BITS(name, gb, bits); \
if (need_update) { \
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); \
} while (0)
/**
* Parse a vlc code.
* @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 read to completely
* read the longest vlc code
* = (max_vlc_length + bits - 1) / bits
*/
static av_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;
}
static inline int decode012(GetBitContext *gb)
{
int n;
n = get_bits1(gb);
if (n == 0)
return 0;
else
return get_bits1(gb) + 1;
}
static inline int decode210(GetBitContext *gb)
{
if (get_bits1(gb))
return 0;
else
return 2 - get_bits1(gb);
}
static inline int get_bits_left(GetBitContext *gb)
{
return gb->size_in_bits - get_bits_count(gb);
}
//#define TRACE
#ifdef TRACE
static inline void print_bin(int bits, int n)
{
int i;
for (i = n - 1; i >= 0; i--)
av_log(NULL, AV_LOG_DEBUG, "%d", (bits >> i) & 1);
for (i = n; i < 24; i++)
av_log(NULL, AV_LOG_DEBUG, " ");
}
static inline int get_bits_trace(GetBitContext *s, int n, const char *file,
const char *func, int line)
{
int r = get_bits(s, n);
print_bin(r, n);
av_log(NULL, AV_LOG_DEBUG, "%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, const char *file,
const 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);
av_log(NULL, AV_LOG_DEBUG, "%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, const char *file,
const char *func, int line)
{
int show = show_bits(s, n);
int r = get_xbits(s, n);
print_bin(show, n);
av_log(NULL, AV_LOG_DEBUG, "%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(p, ...) av_log(p, AV_LOG_DEBUG, __VA_ARGS__)
#else //TRACE
#define tprintf(p, ...) { }
#endif
#endif /* AVCODEC_GET_BITS_H */

View file

@ -0,0 +1,55 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libavutil/attributes.h"
#include "h264chroma.h"
#define BIT_DEPTH 8
#include "h264chroma_template.c"
#undef BIT_DEPTH
#define BIT_DEPTH 16
#include "h264chroma_template.c"
#undef BIT_DEPTH
#define SET_CHROMA(depth) \
c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_ ## depth ## _c; \
c->put_h264_chroma_pixels_tab[1] = put_h264_chroma_mc4_ ## depth ## _c; \
c->put_h264_chroma_pixels_tab[2] = put_h264_chroma_mc2_ ## depth ## _c; \
c->put_h264_chroma_pixels_tab[3] = put_h264_chroma_mc1_ ## depth ## _c; \
c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_ ## depth ## _c; \
c->avg_h264_chroma_pixels_tab[1] = avg_h264_chroma_mc4_ ## depth ## _c; \
c->avg_h264_chroma_pixels_tab[2] = avg_h264_chroma_mc2_ ## depth ## _c; \
c->avg_h264_chroma_pixels_tab[3] = avg_h264_chroma_mc1_ ## depth ## _c; \
av_cold void ff_h264chroma_init(H264ChromaContext *c, int bit_depth)
{
if (bit_depth > 8 && bit_depth <= 16) {
SET_CHROMA(16);
} else {
SET_CHROMA(8);
}
if (ARCH_ARM)
ff_h264chroma_init_arm(c, bit_depth);
if (ARCH_PPC)
ff_h264chroma_init_ppc(c, bit_depth);
if (ARCH_X86)
ff_h264chroma_init_x86(c, bit_depth);
}

View file

@ -0,0 +1,37 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_H264CHROMA_H
#define AVCODEC_H264CHROMA_H
#include <stdint.h>
typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
typedef struct H264ChromaContext {
h264_chroma_mc_func put_h264_chroma_pixels_tab[4];
h264_chroma_mc_func avg_h264_chroma_pixels_tab[4];
} H264ChromaContext;
void ff_h264chroma_init(H264ChromaContext *c, int bit_depth);
void ff_h264chroma_init_arm(H264ChromaContext *c, int bit_depth);
void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth);
void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth);
#endif /* AVCODEC_H264CHROMA_H */

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/avassert.h"
#include "bit_depth_template.c"
#define H264_CHROMA_MC(OPNAME, OP)\
static void FUNCC(OPNAME ## h264_chroma_mc1)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
pixel *dst = (pixel*)_dst;\
pixel *src = (pixel*)_src;\
const int A=(8-x)*(8-y);\
const int B=( x)*(8-y);\
const int C=(8-x)*( y);\
const int D=( x)*( y);\
int i;\
stride >>= sizeof(pixel)-1;\
\
av_assert2(x<8 && y<8 && x>=0 && y>=0);\
\
if(D){\
for(i=0; i<h; i++){\
OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
dst+= stride;\
src+= stride;\
}\
}else{\
const int E= B+C;\
const int step= C ? stride : 1;\
for(i=0; i<h; i++){\
OP(dst[0], (A*src[0] + E*src[step+0]));\
dst+= stride;\
src+= stride;\
}\
}\
}\
static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
pixel *dst = (pixel*)_dst;\
pixel *src = (pixel*)_src;\
const int A=(8-x)*(8-y);\
const int B=( x)*(8-y);\
const int C=(8-x)*( y);\
const int D=( x)*( y);\
int i;\
stride >>= sizeof(pixel)-1;\
\
av_assert2(x<8 && y<8 && x>=0 && y>=0);\
\
if(D){\
for(i=0; i<h; i++){\
OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
dst+= stride;\
src+= stride;\
}\
}else{\
const int E= B+C;\
const int step= C ? stride : 1;\
for(i=0; i<h; i++){\
OP(dst[0], (A*src[0] + E*src[step+0]));\
OP(dst[1], (A*src[1] + E*src[step+1]));\
dst+= stride;\
src+= stride;\
}\
}\
}\
\
static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
pixel *dst = (pixel*)_dst;\
pixel *src = (pixel*)_src;\
const int A=(8-x)*(8-y);\
const int B=( x)*(8-y);\
const int C=(8-x)*( y);\
const int D=( x)*( y);\
int i;\
stride >>= sizeof(pixel)-1;\
\
av_assert2(x<8 && y<8 && x>=0 && y>=0);\
\
if(D){\
for(i=0; i<h; i++){\
OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\
OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\
dst+= stride;\
src+= stride;\
}\
}else{\
const int E= B+C;\
const int step= C ? stride : 1;\
for(i=0; i<h; i++){\
OP(dst[0], (A*src[0] + E*src[step+0]));\
OP(dst[1], (A*src[1] + E*src[step+1]));\
OP(dst[2], (A*src[2] + E*src[step+2]));\
OP(dst[3], (A*src[3] + E*src[step+3]));\
dst+= stride;\
src+= stride;\
}\
}\
}\
\
static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
pixel *dst = (pixel*)_dst;\
pixel *src = (pixel*)_src;\
const int A=(8-x)*(8-y);\
const int B=( x)*(8-y);\
const int C=(8-x)*( y);\
const int D=( x)*( y);\
int i;\
stride >>= sizeof(pixel)-1;\
\
av_assert2(x<8 && y<8 && x>=0 && y>=0);\
\
if(D){\
for(i=0; i<h; i++){\
OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\
OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\
OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5]));\
OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6]));\
OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7]));\
OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8]));\
dst+= stride;\
src+= stride;\
}\
}else{\
const int E= B+C;\
const int step= C ? stride : 1;\
for(i=0; i<h; i++){\
OP(dst[0], (A*src[0] + E*src[step+0]));\
OP(dst[1], (A*src[1] + E*src[step+1]));\
OP(dst[2], (A*src[2] + E*src[step+2]));\
OP(dst[3], (A*src[3] + E*src[step+3]));\
OP(dst[4], (A*src[4] + E*src[step+4]));\
OP(dst[5], (A*src[5] + E*src[step+5]));\
OP(dst[6], (A*src[6] + E*src[step+6]));\
OP(dst[7], (A*src[7] + E*src[step+7]));\
dst+= stride;\
src+= stride;\
}\
}\
}
#define op_avg(a, b) a = (((a)+(((b) + 32)>>6)+1)>>1)
#define op_put(a, b) a = (((b) + 32)>>6)
H264_CHROMA_MC(put_ , op_put)
H264_CHROMA_MC(avg_ , op_avg)
#undef op_avg
#undef op_put

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define DEF_HPEL(OPNAME, OP) \
static inline void FUNCC(OPNAME ## _pixels2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
int i;\
for(i=0; i<h; i++){\
OP(*((pixel2*)(block )), AV_RN2P(pixels ));\
pixels+=line_size;\
block +=line_size;\
}\
}\
static inline void FUNCC(OPNAME ## _pixels4)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
int i;\
for(i=0; i<h; i++){\
OP(*((pixel4*)(block )), AV_RN4P(pixels ));\
pixels+=line_size;\
block +=line_size;\
}\
}\
static inline void FUNCC(OPNAME ## _pixels8)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
int i;\
for(i=0; i<h; i++){\
OP(*((pixel4*)(block )), AV_RN4P(pixels ));\
OP(*((pixel4*)(block+4*sizeof(pixel))), AV_RN4P(pixels+4*sizeof(pixel)));\
pixels+=line_size;\
block +=line_size;\
}\
}\
\
static inline void FUNC(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++){\
pixel4 a,b;\
a= AV_RN4P(&src1[i*src_stride1 ]);\
b= AV_RN4P(&src2[i*src_stride2 ]);\
OP(*((pixel4*)&dst[i*dst_stride ]), rnd_avg_pixel4(a, b));\
a= AV_RN4P(&src1[i*src_stride1+4*sizeof(pixel)]);\
b= AV_RN4P(&src2[i*src_stride2+4*sizeof(pixel)]);\
OP(*((pixel4*)&dst[i*dst_stride+4*sizeof(pixel)]), rnd_avg_pixel4(a, b));\
}\
}\
\
static inline void FUNC(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++){\
pixel4 a,b;\
a= AV_RN4P(&src1[i*src_stride1 ]);\
b= AV_RN4P(&src2[i*src_stride2 ]);\
OP(*((pixel4*)&dst[i*dst_stride ]), rnd_avg_pixel4(a, b));\
}\
}\
\
static inline void FUNC(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++){\
pixel4 a,b;\
a= AV_RN2P(&src1[i*src_stride1 ]);\
b= AV_RN2P(&src2[i*src_stride2 ]);\
OP(*((pixel2*)&dst[i*dst_stride ]), rnd_avg_pixel4(a, b));\
}\
}\
\
static inline void FUNC(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){\
FUNC(OPNAME ## _pixels8_l2)(dst , src1 , src2 , dst_stride, src_stride1, src_stride2, h);\
FUNC(OPNAME ## _pixels8_l2)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, h);\
}\
\
CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16) , FUNCC(OPNAME ## _pixels8) , 8*sizeof(pixel))
#define op_avg(a, b) a = rnd_avg_pixel4(a, b)
#define op_put(a, b) a = b
DEF_HPEL(avg, op_avg)
DEF_HPEL(put, op_put)
#undef op_avg
#undef op_put

View file

@ -0,0 +1,71 @@
/*
* Half-pel DSP functions.
* Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Half-pel DSP functions.
*/
#include "config.h"
#include "libavutil/attributes.h"
#include "libavutil/intreadwrite.h"
#include "hpeldsp.h"
#define BIT_DEPTH 8
#include "hpeldsp_template.c"
av_cold void ff_hpeldsp_init(HpelDSPContext *c, int flags)
{
#define hpel_funcs(prefix, idx, num) \
c->prefix ## _pixels_tab idx [0] = prefix ## _pixels ## num ## _8_c; \
c->prefix ## _pixels_tab idx [1] = prefix ## _pixels ## num ## _x2_8_c; \
c->prefix ## _pixels_tab idx [2] = prefix ## _pixels ## num ## _y2_8_c; \
c->prefix ## _pixels_tab idx [3] = prefix ## _pixels ## num ## _xy2_8_c
hpel_funcs(put, [0], 16);
hpel_funcs(put, [1], 8);
hpel_funcs(put, [2], 4);
hpel_funcs(put, [3], 2);
hpel_funcs(put_no_rnd, [0], 16);
hpel_funcs(put_no_rnd, [1], 8);
hpel_funcs(avg, [0], 16);
hpel_funcs(avg, [1], 8);
hpel_funcs(avg, [2], 4);
hpel_funcs(avg, [3], 2);
hpel_funcs(avg_no_rnd,, 16);
if (ARCH_ALPHA)
ff_hpeldsp_init_alpha(c, flags);
if (ARCH_ARM)
ff_hpeldsp_init_arm(c, flags);
if (ARCH_BFIN)
ff_hpeldsp_init_bfin(c, flags);
if (ARCH_PPC)
ff_hpeldsp_init_ppc(c, flags);
if (HAVE_VIS)
ff_hpeldsp_init_vis(c, flags);
if (ARCH_X86)
ff_hpeldsp_init_x86(c, flags);
}

View file

@ -0,0 +1,104 @@
/*
* Half-pel DSP functions.
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Half-pel DSP functions.
*/
#ifndef AVCODEC_HPELDSP_H
#define AVCODEC_HPELDSP_H
#include <stdint.h>
#include <stddef.h>
/* add and put pixel (decoding) */
// blocksizes for hpel_pixels_func are 8x4,8x8 16x8 16x16
// h for hpel_pixels_func is limited to {width/2, width} but never larger
// than 16 and never smaller than 4
typedef void (*op_pixels_func)(uint8_t *block /*align width (8 or 16)*/,
const uint8_t *pixels /*align 1*/,
ptrdiff_t line_size, int h);
/**
* Half-pel DSP context.
*/
typedef struct HpelDSPContext {
/**
* 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 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[4][4] of motion compensation functions 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[4][4];
/**
* Halfpel motion compensation with no rounding (a+b)>>1.
* this is an array[4] of motion compensation functions for 1
* horizontal blocksize (16) and the 4 halfpel positions<br>
* *pixels_tab[0][ 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[4];
} HpelDSPContext;
void ff_hpeldsp_init(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_alpha(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_arm(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_bfin(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_vis(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags);
#endif /* AVCODEC_HPELDSP_H */

View file

@ -0,0 +1,254 @@
/*
* Half-pel DSP functions.
* Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Half-pel DSP functions.
*/
#include "bit_depth_template.c"
#include "hpel_template.c"
#define PIXOP2(OPNAME, OP) \
static inline void FUNC(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++){\
pixel4 a,b;\
a= AV_RN4P(&src1[i*src_stride1 ]);\
b= AV_RN4P(&src2[i*src_stride2 ]);\
OP(*((pixel4*)&dst[i*dst_stride ]), no_rnd_avg_pixel4(a, b));\
a= AV_RN4P(&src1[i*src_stride1+4*sizeof(pixel)]);\
b= AV_RN4P(&src2[i*src_stride2+4*sizeof(pixel)]);\
OP(*((pixel4*)&dst[i*dst_stride+4*sizeof(pixel)]), no_rnd_avg_pixel4(a, b));\
}\
}\
\
static inline void FUNCC(OPNAME ## _no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
FUNC(OPNAME ## _no_rnd_pixels8_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
}\
\
static inline void FUNCC(OPNAME ## _pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
FUNC(OPNAME ## _pixels8_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
}\
\
static inline void FUNCC(OPNAME ## _no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
FUNC(OPNAME ## _no_rnd_pixels8_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
}\
\
static inline void FUNCC(OPNAME ## _pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
FUNC(OPNAME ## _pixels8_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
}\
\
static inline void FUNCC(OPNAME ## _pixels4_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
FUNC(OPNAME ## _pixels4_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
}\
\
static inline void FUNCC(OPNAME ## _pixels4_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
FUNC(OPNAME ## _pixels4_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
}\
\
static inline void FUNCC(OPNAME ## _pixels2_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
FUNC(OPNAME ## _pixels2_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
}\
\
static inline void FUNCC(OPNAME ## _pixels2_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
FUNC(OPNAME ## _pixels2_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
}\
\
static inline void FUNCC(OPNAME ## _pixels2_xy2)(uint8_t *_block, const uint8_t *_pixels, ptrdiff_t line_size, int h)\
{\
int i, a0, b0, a1, b1;\
pixel *block = (pixel*)_block;\
const pixel *pixels = (const pixel*)_pixels;\
line_size >>= sizeof(pixel)-1;\
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 FUNCC(OPNAME ## _pixels4_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
{\
/* FIXME HIGH BIT DEPTH */\
int i;\
const uint32_t a= AV_RN32(pixels );\
const uint32_t b= AV_RN32(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= AV_RN32(pixels );\
uint32_t b= AV_RN32(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= AV_RN32(pixels );\
b= AV_RN32(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 FUNCC(OPNAME ## _pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
{\
/* FIXME HIGH BIT DEPTH */\
int j;\
for(j=0; j<2; j++){\
int i;\
const uint32_t a= AV_RN32(pixels );\
const uint32_t b= AV_RN32(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= AV_RN32(pixels );\
uint32_t b= AV_RN32(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= AV_RN32(pixels );\
b= AV_RN32(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 FUNCC(OPNAME ## _no_rnd_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
{\
/* FIXME HIGH BIT DEPTH */\
int j;\
for(j=0; j<2; j++){\
int i;\
const uint32_t a= AV_RN32(pixels );\
const uint32_t b= AV_RN32(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= AV_RN32(pixels );\
uint32_t b= AV_RN32(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= AV_RN32(pixels );\
b= AV_RN32(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(FUNCC(OPNAME ## _pixels16_x2) , FUNCC(OPNAME ## _pixels8_x2) , 8*sizeof(pixel))\
CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_y2) , FUNCC(OPNAME ## _pixels8_y2) , 8*sizeof(pixel))\
CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_xy2), FUNCC(OPNAME ## _pixels8_xy2), 8*sizeof(pixel))\
av_unused CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16) , FUNCC(OPNAME ## _pixels8) , 8*sizeof(pixel))\
CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_x2) , FUNCC(OPNAME ## _no_rnd_pixels8_x2) , 8*sizeof(pixel))\
CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_y2) , FUNCC(OPNAME ## _no_rnd_pixels8_y2) , 8*sizeof(pixel))\
CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_xy2), FUNCC(OPNAME ## _no_rnd_pixels8_xy2), 8*sizeof(pixel))\
#define op_avg(a, b) a = rnd_avg_pixel4(a, b)
#define op_put(a, b) a = b
#if BIT_DEPTH == 8
#define put_no_rnd_pixels8_8_c put_pixels8_8_c
PIXOP2(avg, op_avg)
PIXOP2(put, op_put)
#endif
#undef op_avg
#undef op_put

View file

@ -0,0 +1,665 @@
/*
* Misc image conversion routines
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* misc image conversion routines
*/
/* TODO:
* - write 'ffimg' program to test all the image related stuff
* - move all api to slice based system
* - integrate deinterlacing, postprocessing and scaling in the conversion process
*/
#include "avcodec.h"
#include "dsputil.h"
#include "imgconvert.h"
#include "internal.h"
#include "libavutil/avassert.h"
#include "libavutil/colorspace.h"
#include "libavutil/common.h"
#include "libavutil/pixdesc.h"
#include "libavutil/imgutils.h"
#if HAVE_MMX_EXTERNAL
#include "x86/dsputil_x86.h"
#endif
#define FF_COLOR_NA -1
#define FF_COLOR_RGB 0 /**< RGB color space */
#define FF_COLOR_GRAY 1 /**< gray color space */
#define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
#define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
#if HAVE_MMX_EXTERNAL
#define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx
#define deinterlace_line ff_deinterlace_line_mmx
#else
#define deinterlace_line_inplace deinterlace_line_inplace_c
#define deinterlace_line deinterlace_line_c
#endif
#define pixdesc_has_alpha(pixdesc) \
((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & AV_PIX_FMT_FLAG_PAL)
void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
av_assert0(desc);
*h_shift = desc->log2_chroma_w;
*v_shift = desc->log2_chroma_h;
}
static int get_color_type(const AVPixFmtDescriptor *desc) {
if(desc->nb_components == 1 || desc->nb_components == 2)
return FF_COLOR_GRAY;
if(desc->name && !strncmp(desc->name, "yuvj", 4))
return FF_COLOR_YUV_JPEG;
if(desc->flags & AV_PIX_FMT_FLAG_RGB)
return FF_COLOR_RGB;
if(desc->nb_components == 0)
return FF_COLOR_NA;
return FF_COLOR_YUV;
}
static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
int i;
if (!desc || !desc->nb_components) {
*min = *max = 0;
return AVERROR(EINVAL);
}
*min = INT_MAX, *max = -INT_MAX;
for (i = 0; i < desc->nb_components; i++) {
*min = FFMIN(desc->comp[i].depth_minus1+1, *min);
*max = FFMAX(desc->comp[i].depth_minus1+1, *max);
}
return 0;
}
static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt,
enum AVPixelFormat src_pix_fmt,
unsigned *lossp, unsigned consider)
{
const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt);
const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt);
int src_color, dst_color;
int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth;
int ret, loss, i, nb_components;
int score = INT_MAX - 1;
if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE)
return ~0;
/* compute loss */
*lossp = loss = 0;
if (dst_pix_fmt == src_pix_fmt)
return INT_MAX;
if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0)
return ret;
if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0)
return ret;
src_color = get_color_type(src_desc);
dst_color = get_color_type(dst_desc);
nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components);
for (i = 0; i < nb_components; i++)
if (src_desc->comp[i].depth_minus1 > dst_desc->comp[i].depth_minus1 && (consider & FF_LOSS_DEPTH)) {
loss |= FF_LOSS_DEPTH;
score -= 65536 >> dst_desc->comp[i].depth_minus1;
}
if (consider & FF_LOSS_RESOLUTION) {
if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w) {
loss |= FF_LOSS_RESOLUTION;
score -= 256 << dst_desc->log2_chroma_w;
}
if (dst_desc->log2_chroma_h > src_desc->log2_chroma_h) {
loss |= FF_LOSS_RESOLUTION;
score -= 256 << dst_desc->log2_chroma_h;
}
// don't favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side
if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 0 &&
dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 0 ) {
score += 512;
}
}
if(consider & FF_LOSS_COLORSPACE)
switch(dst_color) {
case FF_COLOR_RGB:
if (src_color != FF_COLOR_RGB &&
src_color != FF_COLOR_GRAY)
loss |= FF_LOSS_COLORSPACE;
break;
case FF_COLOR_GRAY:
if (src_color != FF_COLOR_GRAY)
loss |= FF_LOSS_COLORSPACE;
break;
case FF_COLOR_YUV:
if (src_color != FF_COLOR_YUV)
loss |= FF_LOSS_COLORSPACE;
break;
case FF_COLOR_YUV_JPEG:
if (src_color != FF_COLOR_YUV_JPEG &&
src_color != FF_COLOR_YUV &&
src_color != FF_COLOR_GRAY)
loss |= FF_LOSS_COLORSPACE;
break;
default:
/* fail safe test */
if (src_color != dst_color)
loss |= FF_LOSS_COLORSPACE;
break;
}
if(loss & FF_LOSS_COLORSPACE)
score -= (nb_components * 65536) >> FFMIN(dst_desc->comp[0].depth_minus1, src_desc->comp[0].depth_minus1);
if (dst_color == FF_COLOR_GRAY &&
src_color != FF_COLOR_GRAY && (consider & FF_LOSS_CHROMA)) {
loss |= FF_LOSS_CHROMA;
score -= 2 * 65536;
}
if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))) {
loss |= FF_LOSS_ALPHA;
score -= 65536;
}
if (dst_pix_fmt == AV_PIX_FMT_PAL8 && (consider & FF_LOSS_COLORQUANT) &&
(src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))))) {
loss |= FF_LOSS_COLORQUANT;
score -= 65536;
}
*lossp = loss;
return score;
}
int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
enum AVPixelFormat src_pix_fmt,
int has_alpha)
{
int loss;
int ret = get_pix_fmt_score(dst_pix_fmt, src_pix_fmt, &loss, has_alpha ? ~0 : ~FF_LOSS_ALPHA);
if (ret < 0)
return ret;
return loss;
}
enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
{
enum AVPixelFormat dst_pix_fmt;
int loss1, loss2, loss_mask;
const AVPixFmtDescriptor *desc1 = av_pix_fmt_desc_get(dst_pix_fmt1);
const AVPixFmtDescriptor *desc2 = av_pix_fmt_desc_get(dst_pix_fmt2);
int score1, score2;
loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */
if(!has_alpha)
loss_mask &= ~FF_LOSS_ALPHA;
dst_pix_fmt = AV_PIX_FMT_NONE;
score1 = get_pix_fmt_score(dst_pix_fmt1, src_pix_fmt, &loss1, loss_mask);
score2 = get_pix_fmt_score(dst_pix_fmt2, src_pix_fmt, &loss2, loss_mask);
if (score1 == score2) {
if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) {
dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1;
} else {
dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1;
}
} else {
dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1;
}
if (loss_ptr)
*loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
return dst_pix_fmt;
}
#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI
enum AVPixelFormat avcodec_find_best_pix_fmt2(const enum AVPixelFormat *pix_fmt_list,
enum AVPixelFormat src_pix_fmt,
int has_alpha, int *loss_ptr){
return avcodec_find_best_pix_fmt_of_list(pix_fmt_list, src_pix_fmt, has_alpha, loss_ptr);
}
#else
enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
{
return avcodec_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr);
}
#endif
enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list,
enum AVPixelFormat src_pix_fmt,
int has_alpha, int *loss_ptr){
int i;
enum AVPixelFormat best = AV_PIX_FMT_NONE;
for(i=0; pix_fmt_list[i] != AV_PIX_FMT_NONE; i++)
best = avcodec_find_best_pix_fmt_of_2(best, pix_fmt_list[i], src_pix_fmt, has_alpha, loss_ptr);
return best;
}
/* 2x2 -> 1x1 */
void ff_shrink22(uint8_t *dst, int dst_wrap,
const uint8_t *src, int src_wrap,
int width, int height)
{
int w;
const uint8_t *s1, *s2;
uint8_t *d;
for(;height > 0; height--) {
s1 = src;
s2 = s1 + src_wrap;
d = dst;
for(w = width;w >= 4; w-=4) {
d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
s1 += 8;
s2 += 8;
d += 4;
}
for(;w > 0; w--) {
d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
s1 += 2;
s2 += 2;
d++;
}
src += 2 * src_wrap;
dst += dst_wrap;
}
}
/* 4x4 -> 1x1 */
void ff_shrink44(uint8_t *dst, int dst_wrap,
const uint8_t *src, int src_wrap,
int width, int height)
{
int w;
const uint8_t *s1, *s2, *s3, *s4;
uint8_t *d;
for(;height > 0; height--) {
s1 = src;
s2 = s1 + src_wrap;
s3 = s2 + src_wrap;
s4 = s3 + src_wrap;
d = dst;
for(w = width;w > 0; w--) {
d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
s2[0] + s2[1] + s2[2] + s2[3] +
s3[0] + s3[1] + s3[2] + s3[3] +
s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
s1 += 4;
s2 += 4;
s3 += 4;
s4 += 4;
d++;
}
src += 4 * src_wrap;
dst += dst_wrap;
}
}
/* 8x8 -> 1x1 */
void ff_shrink88(uint8_t *dst, int dst_wrap,
const uint8_t *src, int src_wrap,
int width, int height)
{
int w, i;
for(;height > 0; height--) {
for(w = width;w > 0; w--) {
int tmp=0;
for(i=0; i<8; i++){
tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
src += src_wrap;
}
*(dst++) = (tmp + 32)>>6;
src += 8 - 8*src_wrap;
}
src += 8*src_wrap - 8*width;
dst += dst_wrap - width;
}
}
/* return true if yuv planar */
static inline int is_yuv_planar(const AVPixFmtDescriptor *desc)
{
int i;
int planes[4] = { 0 };
if ( desc->flags & AV_PIX_FMT_FLAG_RGB
|| !(desc->flags & AV_PIX_FMT_FLAG_PLANAR))
return 0;
/* set the used planes */
for (i = 0; i < desc->nb_components; i++)
planes[desc->comp[i].plane] = 1;
/* if there is an unused plane, the format is not planar */
for (i = 0; i < desc->nb_components; i++)
if (!planes[i])
return 0;
return 1;
}
int av_picture_crop(AVPicture *dst, const AVPicture *src,
enum AVPixelFormat pix_fmt, int top_band, int left_band)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
int y_shift;
int x_shift;
if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
return -1;
y_shift = desc->log2_chroma_h;
x_shift = desc->log2_chroma_w;
if (is_yuv_planar(desc)) {
dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
} else{
if(top_band % (1<<y_shift) || left_band % (1<<x_shift))
return -1;
if(left_band) //FIXME add support for this too
return -1;
dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
}
dst->linesize[0] = src->linesize[0];
dst->linesize[1] = src->linesize[1];
dst->linesize[2] = src->linesize[2];
return 0;
}
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
enum AVPixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
int *color)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
uint8_t *optr;
int y_shift;
int x_shift;
int yheight;
int i, y;
if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB ||
!is_yuv_planar(desc)) return -1;
for (i = 0; i < 3; i++) {
x_shift = i ? desc->log2_chroma_w : 0;
y_shift = i ? desc->log2_chroma_h : 0;
if (padtop || padleft) {
memset(dst->data[i], color[i],
dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
}
if (padleft || padright) {
optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
(dst->linesize[i] - (padright >> x_shift));
yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
for (y = 0; y < yheight; y++) {
memset(optr, color[i], (padleft + padright) >> x_shift);
optr += dst->linesize[i];
}
}
if (src) { /* first line */
uint8_t *iptr = src->data[i];
optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
(padleft >> x_shift);
memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
iptr += src->linesize[i];
optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
(dst->linesize[i] - (padright >> x_shift));
yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
for (y = 0; y < yheight; y++) {
memset(optr, color[i], (padleft + padright) >> x_shift);
memcpy(optr + ((padleft + padright) >> x_shift), iptr,
(width - padleft - padright) >> x_shift);
iptr += src->linesize[i];
optr += dst->linesize[i];
}
}
if (padbottom || padright) {
optr = dst->data[i] + dst->linesize[i] *
((height - padbottom) >> y_shift) - (padright >> x_shift);
memset(optr, color[i],dst->linesize[i] *
(padbottom >> y_shift) + (padright >> x_shift));
}
}
return 0;
}
#if FF_API_DEINTERLACE
#if !HAVE_MMX_EXTERNAL
/* filter parameters: [-1 4 2 4 -1] // 8 */
static void deinterlace_line_c(uint8_t *dst,
const uint8_t *lum_m4, const uint8_t *lum_m3,
const uint8_t *lum_m2, const uint8_t *lum_m1,
const uint8_t *lum,
int size)
{
const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
int sum;
for(;size > 0;size--) {
sum = -lum_m4[0];
sum += lum_m3[0] << 2;
sum += lum_m2[0] << 1;
sum += lum_m1[0] << 2;
sum += -lum[0];
dst[0] = cm[(sum + 4) >> 3];
lum_m4++;
lum_m3++;
lum_m2++;
lum_m1++;
lum++;
dst++;
}
}
static void deinterlace_line_inplace_c(uint8_t *lum_m4, uint8_t *lum_m3,
uint8_t *lum_m2, uint8_t *lum_m1,
uint8_t *lum, int size)
{
const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
int sum;
for(;size > 0;size--) {
sum = -lum_m4[0];
sum += lum_m3[0] << 2;
sum += lum_m2[0] << 1;
lum_m4[0]=lum_m2[0];
sum += lum_m1[0] << 2;
sum += -lum[0];
lum_m2[0] = cm[(sum + 4) >> 3];
lum_m4++;
lum_m3++;
lum_m2++;
lum_m1++;
lum++;
}
}
#endif /* !HAVE_MMX_EXTERNAL */
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
top field is copied as is, but the bottom field is deinterlaced
against the top field. */
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
const uint8_t *src1, int src_wrap,
int width, int height)
{
const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
int y;
src_m2 = src1;
src_m1 = src1;
src_0=&src_m1[src_wrap];
src_p1=&src_0[src_wrap];
src_p2=&src_p1[src_wrap];
for(y=0;y<(height-2);y+=2) {
memcpy(dst,src_m1,width);
dst += dst_wrap;
deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
src_m2 = src_0;
src_m1 = src_p1;
src_0 = src_p2;
src_p1 += 2*src_wrap;
src_p2 += 2*src_wrap;
dst += dst_wrap;
}
memcpy(dst,src_m1,width);
dst += dst_wrap;
/* do last line */
deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
}
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
int width, int height)
{
uint8_t *src_m1, *src_0, *src_p1, *src_p2;
int y;
uint8_t *buf;
buf = av_malloc(width);
src_m1 = src1;
memcpy(buf,src_m1,width);
src_0=&src_m1[src_wrap];
src_p1=&src_0[src_wrap];
src_p2=&src_p1[src_wrap];
for(y=0;y<(height-2);y+=2) {
deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
src_m1 = src_p1;
src_0 = src_p2;
src_p1 += 2*src_wrap;
src_p2 += 2*src_wrap;
}
/* do last line */
deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
av_free(buf);
}
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
enum AVPixelFormat pix_fmt, int width, int height)
{
int i;
if (pix_fmt != AV_PIX_FMT_YUV420P &&
pix_fmt != AV_PIX_FMT_YUVJ420P &&
pix_fmt != AV_PIX_FMT_YUV422P &&
pix_fmt != AV_PIX_FMT_YUVJ422P &&
pix_fmt != AV_PIX_FMT_YUV444P &&
pix_fmt != AV_PIX_FMT_YUV411P &&
pix_fmt != AV_PIX_FMT_GRAY8)
return -1;
if ((width & 3) != 0 || (height & 3) != 0)
return -1;
for(i=0;i<3;i++) {
if (i == 1) {
switch(pix_fmt) {
case AV_PIX_FMT_YUVJ420P:
case AV_PIX_FMT_YUV420P:
width >>= 1;
height >>= 1;
break;
case AV_PIX_FMT_YUV422P:
case AV_PIX_FMT_YUVJ422P:
width >>= 1;
break;
case AV_PIX_FMT_YUV411P:
width >>= 2;
break;
default:
break;
}
if (pix_fmt == AV_PIX_FMT_GRAY8) {
break;
}
}
if (src == dst) {
deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
width, height);
} else {
deinterlace_bottom_field(dst->data[i],dst->linesize[i],
src->data[i], src->linesize[i],
width, height);
}
}
emms_c();
return 0;
}
#endif /* FF_API_DEINTERLACE */
#ifdef TEST
int main(void){
int i;
int err=0;
int skip = 0;
for (i=0; i<AV_PIX_FMT_NB*2; i++) {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
if(!desc || !desc->name) {
skip ++;
continue;
}
if (skip) {
av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip);
skip = 0;
}
av_log(NULL, AV_LOG_INFO, "pix fmt %s yuv_plan:%d avg_bpp:%d colortype:%d\n", desc->name, is_yuv_planar(desc), av_get_padded_bits_per_pixel(desc), get_color_type(desc));
if ((!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) {
av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n");
err = 1;
}
}
return err;
}
#endif

View file

@ -0,0 +1,29 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_IMGCONVERT_H
#define AVCODEC_IMGCONVERT_H
#include <stdint.h>
/* 1/2^n downscaling functions */
void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
#endif /* AVCODEC_IMGCONVERT_H */

View file

@ -0,0 +1,228 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* common internal api header.
*/
#ifndef AVCODEC_INTERNAL_H
#define AVCODEC_INTERNAL_H
#include <stdint.h>
#include "libavutil/buffer.h"
#include "libavutil/mathematics.h"
#include "libavutil/pixfmt.h"
#include "avcodec.h"
#include "config.h"
#define FF_SANE_NB_CHANNELS 63U
typedef struct FramePool {
/**
* Pools for each data plane. For audio all the planes have the same size,
* so only pools[0] is used.
*/
AVBufferPool *pools[4];
/*
* Pool parameters
*/
int format;
int width, height;
int stride_align[AV_NUM_DATA_POINTERS];
int linesize[4];
int planes;
int channels;
int samples;
} FramePool;
typedef struct AVCodecInternal {
/**
* Whether the parent AVCodecContext is a copy of the context which had
* init() called on it.
* This is used by multithreading - shared tables and picture pointers
* should be freed from the original context only.
*/
int is_copy;
/**
* Whether to allocate progress for frame threading.
*
* The codec must set it to 1 if it uses ff_thread_await/report_progress(),
* then progress will be allocated in ff_thread_get_buffer(). The frames
* then MUST be freed with ff_thread_release_buffer().
*
* If the codec does not need to call the progress functions (there are no
* dependencies between the frames), it should leave this at 0. Then it can
* decode straight to the user-provided frames (which the user will then
* free with av_frame_unref()), there is no need to call
* ff_thread_release_buffer().
*/
int allocate_progress;
#if FF_API_OLD_ENCODE_AUDIO
/**
* Internal sample count used by avcodec_encode_audio() to fabricate pts.
* Can be removed along with avcodec_encode_audio().
*/
int64_t sample_count;
#endif
/**
* An audio frame with less than required samples has been submitted and
* padded with silence. Reject all subsequent frames.
*/
int last_audio_frame;
AVFrame to_free;
FramePool *pool;
/**
* temporary buffer used for encoders to store their bitstream
*/
uint8_t *byte_buffer;
unsigned int byte_buffer_size;
void *frame_thread_encoder;
/**
* Number of audio samples to skip at the start of the next decoded frame
*/
int skip_samples;
} AVCodecInternal;
struct AVCodecDefault {
const uint8_t *key;
const uint8_t *value;
};
/**
* Return the hardware accelerated codec for codec codec_id and
* pixel format pix_fmt.
*
* @param codec_id the codec to match
* @param pix_fmt the pixel format to match
* @return the hardware accelerated codec, or NULL if none was found.
*/
AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt);
/**
* Return the index into tab at which {a,b} match elements {[0],[1]} of tab.
* If there is no such matching pair then size is returned.
*/
int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b);
unsigned int avpriv_toupper4(unsigned int x);
/**
* does needed setup of pkt_pts/pos and such for (re)get_buffer();
*/
int ff_init_buffer_info(AVCodecContext *s, AVFrame *frame);
void avpriv_color_frame(AVFrame *frame, const int color[4]);
extern volatile int ff_avcodec_locked;
int ff_lock_avcodec(AVCodecContext *log_ctx);
int ff_unlock_avcodec(void);
int avpriv_lock_avformat(void);
int avpriv_unlock_avformat(void);
/**
* Maximum size in bytes of extradata.
* This value was chosen such that every bit of the buffer is
* addressable by a 32-bit signed integer as used by get_bits.
*/
#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE)
/**
* Check AVPacket size and/or allocate data.
*
* Encoders supporting AVCodec.encode2() can use this as a convenience to
* ensure the output packet data is large enough, whether provided by the user
* or allocated in this function.
*
* @param avctx the AVCodecContext of the encoder
* @param avpkt the AVPacket
* If avpkt->data is already set, avpkt->size is checked
* to ensure it is large enough.
* If avpkt->data is NULL, a new buffer is allocated.
* avpkt->size is set to the specified size.
* All other AVPacket fields will be reset with av_init_packet().
* @param size the minimum required packet size
* @return 0 on success, negative error code on failure
*/
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size);
int ff_alloc_packet(AVPacket *avpkt, int size);
/**
* Rescale from sample rate to AVCodecContext.time_base.
*/
static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx,
int64_t samples)
{
if(samples == AV_NOPTS_VALUE)
return AV_NOPTS_VALUE;
return av_rescale_q(samples, (AVRational){ 1, avctx->sample_rate },
avctx->time_base);
}
/**
* Get a buffer for a frame. This is a wrapper around
* AVCodecContext.get_buffer() and should be used instead calling get_buffer()
* directly.
*/
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags);
/**
* Identical in function to av_frame_make_writable(), except it uses
* ff_get_buffer() to allocate the buffer when needed.
*/
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame);
int ff_thread_can_start_frame(AVCodecContext *avctx);
int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx);
/**
* Call avcodec_open2 recursively by decrementing counter, unlocking mutex,
* calling the function and then restoring again. Assumes the mutex is
* already locked
*/
int ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
/**
* Call avcodec_close recursively, counterpart to avcodec_open2_recursive.
*/
int ff_codec_close_recursive(AVCodecContext *avctx);
/**
* Finalize buf into extradata and set its size appropriately.
*/
int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf);
const uint8_t *avpriv_find_start_code(const uint8_t *p,
const uint8_t *end,
uint32_t *state);
#endif /* AVCODEC_INTERNAL_H */

View file

@ -0,0 +1,235 @@
/*
* LSP routines for ACELP-based codecs
*
* Copyright (c) 2007 Reynaldo H. Verdejo Pinochet (QCELP decoder)
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include "avcodec.h"
#define FRAC_BITS 14
#include "mathops.h"
#include "lsp.h"
#include "libavcodec/mips/lsp_mips.h"
#include "libavutil/avassert.h"
void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order)
{
int i, j;
/* sort lsfq in ascending order. float bubble agorithm,
O(n) if data already sorted, O(n^2) - otherwise */
for(i=0; i<lp_order-1; i++)
for(j=i; j>=0 && lsfq[j] > lsfq[j+1]; j--)
FFSWAP(int16_t, lsfq[j], lsfq[j+1]);
for(i=0; i<lp_order; i++)
{
lsfq[i] = FFMAX(lsfq[i], lsfq_min);
lsfq_min = lsfq[i] + lsfq_min_distance;
}
lsfq[lp_order-1] = FFMIN(lsfq[lp_order-1], lsfq_max);//Is warning required ?
}
void ff_set_min_dist_lsf(float *lsf, double min_spacing, int size)
{
int i;
float prev = 0.0;
for (i = 0; i < size; i++)
prev = lsf[i] = FFMAX(lsf[i], prev + min_spacing);
}
/* Cosine table: base_cos[i] = (1 << 15) * cos(i * PI / 64) */
static const int16_t tab_cos[65] =
{
32767, 32738, 32617, 32421, 32145, 31793, 31364, 30860,
30280, 29629, 28905, 28113, 27252, 26326, 25336, 24285,
23176, 22011, 20793, 19525, 18210, 16851, 15451, 14014,
12543, 11043, 9515, 7965, 6395, 4810, 3214, 1609,
1, -1607, -3211, -4808, -6393, -7962, -9513, -11040,
-12541, -14012, -15449, -16848, -18207, -19523, -20791, -22009,
-23174, -24283, -25334, -26324, -27250, -28111, -28904, -29627,
-30279, -30858, -31363, -31792, -32144, -32419, -32616, -32736, -32768,
};
static int16_t ff_cos(uint16_t arg)
{
uint8_t offset= arg;
uint8_t ind = arg >> 8;
av_assert2(arg <= 0x3fff);
return tab_cos[ind] + (offset * (tab_cos[ind+1] - tab_cos[ind]) >> 8);
}
void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order)
{
int i;
/* Convert LSF to LSP, lsp=cos(lsf) */
for(i=0; i<lp_order; i++)
// 20861 = 2.0 / PI in (0.15)
lsp[i] = ff_cos(lsf[i] * 20861 >> 15); // divide by PI and (0,13) -> (0,14)
}
void ff_acelp_lsf2lspd(double *lsp, const float *lsf, int lp_order)
{
int i;
for(i = 0; i < lp_order; i++)
lsp[i] = cos(2.0 * M_PI * lsf[i]);
}
/**
* @brief decodes polynomial coefficients from LSP
* @param[out] f decoded polynomial coefficients (-0x20000000 <= (3.22) <= 0x1fffffff)
* @param lsp LSP coefficients (-0x8000 <= (0.15) <= 0x7fff)
*/
static void lsp2poly(int* f, const int16_t* lsp, int lp_half_order)
{
int i, j;
f[0] = 0x400000; // 1.0 in (3.22)
f[1] = -lsp[0] << 8; // *2 and (0.15) -> (3.22)
for(i=2; i<=lp_half_order; i++)
{
f[i] = f[i-2];
for(j=i; j>1; j--)
f[j] -= MULL(f[j-1], lsp[2*i-2], FRAC_BITS) - f[j-2];
f[1] -= lsp[2*i-2] << 8;
}
}
void ff_acelp_lsp2lpc(int16_t* lp, const int16_t* lsp, int lp_half_order)
{
int i;
int f1[MAX_LP_HALF_ORDER+1]; // (3.22)
int f2[MAX_LP_HALF_ORDER+1]; // (3.22)
lsp2poly(f1, lsp , lp_half_order);
lsp2poly(f2, lsp+1, lp_half_order);
/* 3.2.6 of G.729, Equations 25 and 26*/
lp[0] = 4096;
for(i=1; i<lp_half_order+1; i++)
{
int ff1 = f1[i] + f1[i-1]; // (3.22)
int ff2 = f2[i] - f2[i-1]; // (3.22)
ff1 += 1 << 10; // for rounding
lp[i] = (ff1 + ff2) >> 11; // divide by 2 and (3.22) -> (3.12)
lp[(lp_half_order << 1) + 1 - i] = (ff1 - ff2) >> 11; // divide by 2 and (3.22) -> (3.12)
}
}
void ff_amrwb_lsp2lpc(const double *lsp, float *lp, int lp_order)
{
int lp_half_order = lp_order >> 1;
double buf[MAX_LP_HALF_ORDER + 1];
double pa[MAX_LP_HALF_ORDER + 1];
double *qa = buf + 1;
int i,j;
qa[-1] = 0.0;
ff_lsp2polyf(lsp , pa, lp_half_order );
ff_lsp2polyf(lsp + 1, qa, lp_half_order - 1);
for (i = 1, j = lp_order - 1; i < lp_half_order; i++, j--) {
double paf = pa[i] * (1 + lsp[lp_order - 1]);
double qaf = (qa[i] - qa[i-2]) * (1 - lsp[lp_order - 1]);
lp[i-1] = (paf + qaf) * 0.5;
lp[j-1] = (paf - qaf) * 0.5;
}
lp[lp_half_order - 1] = (1.0 + lsp[lp_order - 1]) *
pa[lp_half_order] * 0.5;
lp[lp_order - 1] = lsp[lp_order - 1];
}
void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd, const int16_t* lsp_prev, int lp_order)
{
int16_t lsp_1st[MAX_LP_ORDER]; // (0.15)
int i;
/* LSP values for first subframe (3.2.5 of G.729, Equation 24)*/
for(i=0; i<lp_order; i++)
#ifdef G729_BITEXACT
lsp_1st[i] = (lsp_2nd[i] >> 1) + (lsp_prev[i] >> 1);
#else
lsp_1st[i] = (lsp_2nd[i] + lsp_prev[i]) >> 1;
#endif
ff_acelp_lsp2lpc(lp_1st, lsp_1st, lp_order >> 1);
/* LSP values for second subframe (3.2.5 of G.729)*/
ff_acelp_lsp2lpc(lp_2nd, lsp_2nd, lp_order >> 1);
}
#ifndef ff_lsp2polyf
void ff_lsp2polyf(const double *lsp, double *f, int lp_half_order)
{
int i, j;
f[0] = 1.0;
f[1] = -2 * lsp[0];
lsp -= 2;
for(i=2; i<=lp_half_order; i++)
{
double val = -2 * lsp[2*i];
f[i] = val * f[i-1] + 2*f[i-2];
for(j=i-1; j>1; j--)
f[j] += f[j-1] * val + f[j-2];
f[1] += val;
}
}
#endif /* ff_lsp2polyf */
void ff_acelp_lspd2lpc(const double *lsp, float *lpc, int lp_half_order)
{
double pa[MAX_LP_HALF_ORDER+1], qa[MAX_LP_HALF_ORDER+1];
float *lpc2 = lpc + (lp_half_order << 1) - 1;
av_assert2(lp_half_order <= MAX_LP_HALF_ORDER);
ff_lsp2polyf(lsp, pa, lp_half_order);
ff_lsp2polyf(lsp + 1, qa, lp_half_order);
while (lp_half_order--) {
double paf = pa[lp_half_order+1] + pa[lp_half_order];
double qaf = qa[lp_half_order+1] - qa[lp_half_order];
lpc [ lp_half_order] = 0.5*(paf+qaf);
lpc2[-lp_half_order] = 0.5*(paf-qaf);
}
}
void ff_sort_nearly_sorted_floats(float *vals, int len)
{
int i,j;
for (i = 0; i < len - 1; i++)
for (j = i; j >= 0 && vals[j] > vals[j+1]; j--)
FFSWAP(float, vals[j], vals[j+1]);
}

View file

@ -0,0 +1,130 @@
/*
* LSP computing for ACELP-based codecs
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_LSP_H
#define AVCODEC_LSP_H
#include <stdint.h>
/**
(I.F) means fixed-point value with F fractional and I integer bits
*/
/**
* @brief ensure a minimum distance between LSFs
* @param[in,out] lsfq LSF to check and adjust
* @param lsfq_min_distance minimum distance between LSFs
* @param lsfq_min minimum allowed LSF value
* @param lsfq_max maximum allowed LSF value
* @param lp_order LP filter order
*/
void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order);
/**
* Adjust the quantized LSFs so they are increasing and not too close.
*
* This step is not mentioned in the AMR spec but is in the reference C decoder.
* Omitting this step creates audible distortion on the sinusoidal sweep
* test vectors in 3GPP TS 26.074.
*
* @param[in,out] lsf LSFs in Hertz
* @param min_spacing minimum distance between two consecutive lsf values
* @param size size of the lsf vector
*/
void ff_set_min_dist_lsf(float *lsf, double min_spacing, int size);
/**
* @brief Convert LSF to LSP
* @param[out] lsp LSP coefficients (-0x8000 <= (0.15) < 0x8000)
* @param lsf normalized LSF coefficients (0 <= (2.13) < 0x2000 * PI)
* @param lp_order LP filter order
*
* @remark It is safe to pass the same array into the lsf and lsp parameters.
*/
void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order);
/**
* Floating point version of ff_acelp_lsf2lsp()
*/
void ff_acelp_lsf2lspd(double *lsp, const float *lsf, int lp_order);
/**
* @brief LSP to LP conversion (3.2.6 of G.729)
* @param[out] lp decoded LP coefficients (-0x8000 <= (3.12) < 0x8000)
* @param lsp LSP coefficients (-0x8000 <= (0.15) < 0x8000)
* @param lp_half_order LP filter order, divided by 2
*/
void ff_acelp_lsp2lpc(int16_t* lp, const int16_t* lsp, int lp_half_order);
/**
* LSP to LP conversion (5.2.4 of AMR-WB)
*/
void ff_amrwb_lsp2lpc(const double *lsp, float *lp, int lp_order);
/**
* @brief Interpolate LSP for the first subframe and convert LSP -> LP for both subframes (3.2.5 and 3.2.6 of G.729)
* @param[out] lp_1st decoded LP coefficients for first subframe (-0x8000 <= (3.12) < 0x8000)
* @param[out] lp_2nd decoded LP coefficients for second subframe (-0x8000 <= (3.12) < 0x8000)
* @param lsp_2nd LSP coefficients of the second subframe (-0x8000 <= (0.15) < 0x8000)
* @param lsp_prev LSP coefficients from the second subframe of the previous frame (-0x8000 <= (0.15) < 0x8000)
* @param lp_order LP filter order
*/
void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd, const int16_t* lsp_prev, int lp_order);
#define MAX_LP_HALF_ORDER 10
#define MAX_LP_ORDER (2*MAX_LP_HALF_ORDER)
/**
* Reconstruct LPC coefficients from the line spectral pair frequencies.
*
* @param lsp line spectral pairs in cosine domain
* @param lpc linear predictive coding coefficients
* @param lp_half_order half the number of the amount of LPCs to be
* reconstructed, need to be smaller or equal to MAX_LP_HALF_ORDER
*
* @note buffers should have a minimux size of 2*lp_half_order elements.
*
* TIA/EIA/IS-733 2.4.3.3.5
*/
void ff_acelp_lspd2lpc(const double *lsp, float *lpc, int lp_half_order);
/**
* Sort values in ascending order.
*
* @note O(n) if data already sorted, O(n^2) - otherwise
*/
void ff_sort_nearly_sorted_floats(float *vals, int len);
/**
* Compute the Pa / (1 + z(-1)) or Qa / (1 - z(-1)) coefficients
* needed for LSP to LPC conversion.
* We only need to calculate the 6 first elements of the polynomial.
*
* @param lsp line spectral pairs in cosine domain
* @param[out] f polynomial input/output as a vector
*
* TIA/EIA/IS-733 2.4.3.3.5-1/2
*/
void ff_lsp2polyf(const double *lsp, double *f, int lp_half_order);
#endif /* AVCODEC_LSP_H */

View file

@ -0,0 +1,237 @@
/*
* simple math operations
* Copyright (c) 2001, 2002 Fabrice Bellard
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MATHOPS_H
#define AVCODEC_MATHOPS_H
#include <stdint.h>
#include "libavutil/common.h"
#include "config.h"
extern const uint32_t ff_inverse[257];
extern const uint8_t ff_reverse[256];
extern const uint8_t ff_sqrt_tab[256];
#if ARCH_ARM
# include "arm/mathops.h"
#elif ARCH_AVR32
# include "avr32/mathops.h"
#elif ARCH_BFIN
# include "bfin/mathops.h"
#elif ARCH_MIPS
# include "mips/mathops.h"
#elif ARCH_PPC
# include "ppc/mathops.h"
#elif ARCH_X86
# include "x86/mathops.h"
#endif
/* generic implementation */
#ifndef MUL64
# define MUL64(a,b) ((int64_t)(a) * (int64_t)(b))
#endif
#ifndef MULL
# define MULL(a,b,s) (MUL64(a, b) >> (s))
#endif
#ifndef MULH
static av_always_inline int MULH(int a, int b){
return MUL64(a, b) >> 32;
}
#endif
#ifndef UMULH
static av_always_inline unsigned UMULH(unsigned a, unsigned b){
return ((uint64_t)(a) * (uint64_t)(b))>>32;
}
#endif
#ifndef MAC64
# define MAC64(d, a, b) ((d) += MUL64(a, b))
#endif
#ifndef MLS64
# define MLS64(d, a, b) ((d) -= MUL64(a, b))
#endif
/* signed 16x16 -> 32 multiply add accumulate */
#ifndef MAC16
# define MAC16(rt, ra, rb) rt += (ra) * (rb)
#endif
/* signed 16x16 -> 32 multiply */
#ifndef MUL16
# define MUL16(ra, rb) ((ra) * (rb))
#endif
#ifndef MLS16
# define MLS16(rt, ra, rb) ((rt) -= (ra) * (rb))
#endif
/* median of 3 */
#ifndef mid_pred
#define mid_pred mid_pred
static inline av_const 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
}
#endif
#ifndef sign_extend
static inline av_const int sign_extend(int val, unsigned bits)
{
unsigned shift = 8 * sizeof(int) - bits;
union { unsigned u; int s; } v = { (unsigned) val << shift };
return v.s >> shift;
}
#endif
#ifndef zero_extend
static inline av_const unsigned zero_extend(unsigned val, unsigned bits)
{
return (val << ((8 * sizeof(int)) - bits)) >> ((8 * sizeof(int)) - bits);
}
#endif
#ifndef COPY3_IF_LT
#define COPY3_IF_LT(x, y, a, b, c, d)\
if ((y) < (x)) {\
(x) = (y);\
(a) = (b);\
(c) = (d);\
}
#endif
#ifndef MASK_ABS
#define MASK_ABS(mask, level) do { \
mask = level >> 31; \
level = (level ^ mask) - mask; \
} while (0)
#endif
#ifndef NEG_SSR32
# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
#endif
#ifndef NEG_USR32
# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
#endif
#if HAVE_BIGENDIAN
# ifndef PACK_2U8
# define PACK_2U8(a,b) (((a) << 8) | (b))
# endif
# ifndef PACK_4U8
# define PACK_4U8(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
# endif
# ifndef PACK_2U16
# define PACK_2U16(a,b) (((a) << 16) | (b))
# endif
#else
# ifndef PACK_2U8
# define PACK_2U8(a,b) (((b) << 8) | (a))
# endif
# ifndef PACK_4U2
# define PACK_4U8(a,b,c,d) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a))
# endif
# ifndef PACK_2U16
# define PACK_2U16(a,b) (((b) << 16) | (a))
# endif
#endif
#ifndef PACK_2S8
# define PACK_2S8(a,b) PACK_2U8((a)&255, (b)&255)
#endif
#ifndef PACK_4S8
# define PACK_4S8(a,b,c,d) PACK_4U8((a)&255, (b)&255, (c)&255, (d)&255)
#endif
#ifndef PACK_2S16
# define PACK_2S16(a,b) PACK_2U16((a)&0xffff, (b)&0xffff)
#endif
#ifndef FASTDIV
# define FASTDIV(a,b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32))
#endif /* FASTDIV */
#ifndef MOD_UNLIKELY
# define MOD_UNLIKELY(modulus, dividend, divisor, prev_dividend) \
do { \
if ((prev_dividend) == 0 || (dividend) - (prev_dividend) != (divisor)) \
(modulus) = (dividend) % (divisor); \
(prev_dividend) = (dividend); \
} while (0)
#endif
static inline av_const unsigned int ff_sqrt(unsigned int a)
{
unsigned int b;
if (a < 255) return (ff_sqrt_tab[a + 1] - 1) >> 4;
else if (a < (1 << 12)) b = ff_sqrt_tab[a >> 4] >> 2;
#if !CONFIG_SMALL
else if (a < (1 << 14)) b = ff_sqrt_tab[a >> 6] >> 1;
else if (a < (1 << 16)) b = ff_sqrt_tab[a >> 8] ;
#endif
else {
int s = av_log2_16bit(a >> 16) >> 1;
unsigned int c = a >> (s + 2);
b = ff_sqrt_tab[c >> (s + 8)];
b = FASTDIV(c,b) + (b << s);
}
return b - (a < b * b);
}
static inline int8_t ff_u8_to_s8(uint8_t a)
{
union {
uint8_t u8;
int8_t s8;
} b;
b.u8 = a;
return b.s8;
}
#endif /* AVCODEC_MATHOPS_H */

View file

@ -0,0 +1,124 @@
/*
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
/* a*inverse[b]>>32 == a/b for all 0<=a<=16909558 && 2<=b<=256
* for a>16909558, is an overestimate by less than 1 part in 1<<24 */
const uint32_t ff_inverse[257]={
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,
16777216
};
const uint8_t ff_sqrt_tab[256]={
0, 16, 23, 28, 32, 36, 40, 43, 46, 48, 51, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 77, 79, 80, 82, 84, 85, 87, 88, 90,
91, 92, 94, 95, 96, 98, 99,100,102,103,104,105,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,144,145,146,147,148,149,150,151,151,152,153,154,155,156,156,
157,158,159,160,160,161,162,163,164,164,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176,176,177,178,179,179,180,181,
182,182,183,184,184,185,186,186,187,188,188,189,190,190,191,192,192,193,194,194,195,196,196,197,198,198,199,200,200,201,202,202,
203,204,204,205,205,206,207,207,208,208,209,210,210,211,212,212,213,213,214,215,215,216,216,217,218,218,219,219,220,220,221,222,
222,223,223,224,224,225,226,226,227,227,228,228,229,230,230,231,231,232,232,233,233,234,235,235,236,236,237,237,238,238,239,239,
240,240,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,253,254,254,255,255,255
};
const uint8_t ff_reverse[256] = {
0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF,
};
#define times4(x) x, x, x, x
#define times256(x) times4(times4(times4(times4(times4(x)))))
const uint8_t ff_cropTbl[256 + 2 * 1024] = {
times256(0x00),
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
times256(0xFF)
};
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
};

View file

@ -0,0 +1,207 @@
/*
* MDCT/IMDCT transforms
* Copyright (c) 2002 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <string.h>
#include "libavutil/common.h"
#include "libavutil/mathematics.h"
#include "fft.h"
#include "fft-internal.h"
/**
* @file
* MDCT/IMDCT transforms.
*/
#if CONFIG_FFT_FLOAT
# define RSCALE(x) (x)
#else
#if CONFIG_FFT_FIXED_32
# define RSCALE(x) (((x) + 32) >> 6)
#else /* CONFIG_FFT_FIXED_32 */
# define RSCALE(x) ((x) >> 1)
#endif /* CONFIG_FFT_FIXED_32 */
#endif
/**
* init MDCT or IMDCT computation.
*/
av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
{
int n, n4, i;
double alpha, theta;
int tstep;
memset(s, 0, sizeof(*s));
n = 1 << nbits;
s->mdct_bits = nbits;
s->mdct_size = n;
n4 = n >> 2;
s->mdct_permutation = FF_MDCT_PERM_NONE;
if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0)
goto fail;
s->tcos = av_malloc(n/2 * sizeof(FFTSample));
if (!s->tcos)
goto fail;
switch (s->mdct_permutation) {
case FF_MDCT_PERM_NONE:
s->tsin = s->tcos + n4;
tstep = 1;
break;
case FF_MDCT_PERM_INTERLEAVE:
s->tsin = s->tcos + 1;
tstep = 2;
break;
default:
goto fail;
}
theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0);
scale = sqrt(fabs(scale));
for(i=0;i<n4;i++) {
alpha = 2 * M_PI * (i + theta) / n;
s->tcos[i*tstep] = FIX15(-cos(alpha) * scale);
s->tsin[i*tstep] = FIX15(-sin(alpha) * scale);
}
return 0;
fail:
ff_mdct_end(s);
return -1;
}
/**
* Compute the middle half of the inverse MDCT of size N = 2^nbits,
* thus excluding the parts that can be derived by symmetry
* @param output N/2 samples
* @param input N/2 samples
*/
void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
{
int k, n8, n4, n2, n, j;
const uint16_t *revtab = s->revtab;
const FFTSample *tcos = s->tcos;
const FFTSample *tsin = s->tsin;
const FFTSample *in1, *in2;
FFTComplex *z = (FFTComplex *)output;
n = 1 << s->mdct_bits;
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;
}
s->fft_calc(s, z);
/* post rotation + reordering */
for(k = 0; k < n8; k++) {
FFTSample r0, i0, r1, i1;
CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]);
CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]);
z[n8-k-1].re = r0;
z[n8-k-1].im = i0;
z[n8+k ].re = r1;
z[n8+k ].im = i1;
}
}
/**
* Compute inverse MDCT of size N = 2^nbits
* @param output N samples
* @param input N/2 samples
*/
void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input)
{
int k;
int n = 1 << s->mdct_bits;
int n2 = n >> 1;
int n4 = n >> 2;
ff_imdct_half_c(s, output+n4, input);
for(k = 0; k < n4; k++) {
output[k] = -output[n2-k-1];
output[n-k-1] = output[n2+k];
}
}
/**
* Compute MDCT of size N = 2^nbits
* @param input N samples
* @param out N/2 samples
*/
void ff_mdct_calc_c(FFTContext *s, FFTSample *out, const FFTSample *input)
{
int i, j, n, n8, n4, n2, n3;
FFTDouble re, im;
const uint16_t *revtab = s->revtab;
const FFTSample *tcos = s->tcos;
const FFTSample *tsin = s->tsin;
FFTComplex *x = (FFTComplex *)out;
n = 1 << s->mdct_bits;
n2 = n >> 1;
n4 = n >> 2;
n8 = n >> 3;
n3 = 3 * n4;
/* pre rotation */
for(i=0;i<n8;i++) {
re = RSCALE(-input[2*i+n3] - input[n3-1-2*i]);
im = RSCALE(-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 = RSCALE( input[2*i] - input[n2-1-2*i]);
im = RSCALE(-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]);
}
s->fft_calc(s, x);
/* post rotation */
for(i=0;i<n8;i++) {
FFTSample r0, i0, r1, i1;
CMUL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]);
CMUL(i0, r1, x[n8+i ].re, x[n8+i ].im, -tsin[n8+i ], -tcos[n8+i ]);
x[n8-i-1].re = r0;
x[n8-i-1].im = i0;
x[n8+i ].re = r1;
x[n8+i ].im = i1;
}
}
av_cold void ff_mdct_end(FFTContext *s)
{
av_freep(&s->tcos);
ff_fft_end(s);
}

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Nedeljko Babic (nbabic@mips.com)
*
* LSP routines for ACELP-based codecs optimized for MIPS
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/lsp.c
*/
#ifndef AVCODEC_LSP_MIPS_H
#define AVCODEC_LSP_MIPS_H
#if HAVE_MIPSFPU && HAVE_INLINE_ASM
static av_always_inline void ff_lsp2polyf_mips(const double *lsp, double *f, int lp_half_order)
{
int i, j = 0;
double * p_fi = f;
double * p_f = 0;
f[0] = 1.0;
f[1] = -2 * lsp[0];
lsp -= 2;
for(i=2; i<=lp_half_order; i++)
{
double tmp, f_j_2, f_j_1, f_j;
double val = lsp[2*i];
__asm__ volatile(
"move %[p_f], %[p_fi] \n\t"
"add.d %[val], %[val], %[val] \n\t"
"addiu %[p_fi], 8 \n\t"
"ldc1 %[f_j_1], 0(%[p_f]) \n\t"
"ldc1 %[f_j], 8(%[p_f]) \n\t"
"neg.d %[val], %[val] \n\t"
"add.d %[tmp], %[f_j_1], %[f_j_1] \n\t"
"madd.d %[tmp], %[tmp], %[f_j], %[val] \n\t"
"addiu %[j], %[i], -2 \n\t"
"ldc1 %[f_j_2], -8(%[p_f]) \n\t"
"sdc1 %[tmp], 16(%[p_f]) \n\t"
"beqz %[j], ff_lsp2polyf_lp_j_end%= \n\t"
"ff_lsp2polyf_lp_j%=: \n\t"
"add.d %[tmp], %[f_j], %[f_j_2] \n\t"
"madd.d %[tmp], %[tmp], %[f_j_1], %[val] \n\t"
"mov.d %[f_j], %[f_j_1] \n\t"
"addiu %[j], -1 \n\t"
"mov.d %[f_j_1], %[f_j_2] \n\t"
"ldc1 %[f_j_2], -16(%[p_f]) \n\t"
"sdc1 %[tmp], 8(%[p_f]) \n\t"
"addiu %[p_f], -8 \n\t"
"bgtz %[j], ff_lsp2polyf_lp_j%= \n\t"
"ff_lsp2polyf_lp_j_end%=: \n\t"
: [f_j_2]"=&f"(f_j_2), [f_j_1]"=&f"(f_j_1), [val]"+f"(val),
[tmp]"=&f"(tmp), [f_j]"=&f"(f_j), [p_f]"+r"(p_f),
[j]"+r"(j), [p_fi]"+r"(p_fi)
: [i]"r"(i)
: "memory"
);
f[1] += val;
}
}
#define ff_lsp2polyf ff_lsp2polyf_mips
#endif /* HAVE_MIPSFPU && HAVE_INLINE_ASM */
#endif /* AVCODEC_LSP_MIPS_H */

View file

@ -0,0 +1,432 @@
/*
* MPEG1/2 tables
* copyright (c) 2000,2001 Fabrice Bellard
* copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* MPEG1/2 tables.
*/
#include "mpeg12data.h"
const uint16_t ff_mpeg1_default_intra_matrix[256] = {
8, 16, 19, 22, 26, 27, 29, 34,
16, 16, 22, 24, 27, 29, 34, 37,
19, 22, 26, 27, 29, 34, 34, 38,
22, 22, 26, 27, 29, 34, 37, 40,
22, 26, 27, 29, 32, 35, 40, 48,
26, 27, 29, 32, 35, 40, 48, 58,
26, 27, 29, 34, 38, 46, 56, 69,
27, 29, 35, 38, 46, 56, 69, 83
};
const uint16_t ff_mpeg1_default_non_intra_matrix[64] = {
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
};
const uint16_t ff_mpeg12_vlc_dc_lum_code[12] = {
0x4, 0x0, 0x1, 0x5, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x1ff,
};
const unsigned char ff_mpeg12_vlc_dc_lum_bits[12] = {
3, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 9,
};
const uint16_t ff_mpeg12_vlc_dc_chroma_code[12] = {
0x0, 0x1, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x3fe, 0x3ff,
};
const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12] = {
2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10,
};
static const uint16_t mpeg1_vlc[113][2] = {
{ 0x3, 2 }, { 0x4, 4 }, { 0x5, 5 }, { 0x6, 7 },
{ 0x26, 8 }, { 0x21, 8 }, { 0xa, 10 }, { 0x1d, 12 },
{ 0x18, 12 }, { 0x13, 12 }, { 0x10, 12 }, { 0x1a, 13 },
{ 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 }, { 0x1f, 14 },
{ 0x1e, 14 }, { 0x1d, 14 }, { 0x1c, 14 }, { 0x1b, 14 },
{ 0x1a, 14 }, { 0x19, 14 }, { 0x18, 14 }, { 0x17, 14 },
{ 0x16, 14 }, { 0x15, 14 }, { 0x14, 14 }, { 0x13, 14 },
{ 0x12, 14 }, { 0x11, 14 }, { 0x10, 14 }, { 0x18, 15 },
{ 0x17, 15 }, { 0x16, 15 }, { 0x15, 15 }, { 0x14, 15 },
{ 0x13, 15 }, { 0x12, 15 }, { 0x11, 15 }, { 0x10, 15 },
{ 0x3, 3 }, { 0x6, 6 }, { 0x25, 8 }, { 0xc, 10 },
{ 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x1f, 15 },
{ 0x1e, 15 }, { 0x1d, 15 }, { 0x1c, 15 }, { 0x1b, 15 },
{ 0x1a, 15 }, { 0x19, 15 }, { 0x13, 16 }, { 0x12, 16 },
{ 0x11, 16 }, { 0x10, 16 }, { 0x5, 4 }, { 0x4, 7 },
{ 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 }, { 0x7, 5 },
{ 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 }, { 0x6, 5 },
{ 0xf, 10 }, { 0x12, 12 }, { 0x7, 6 }, { 0x9, 10 },
{ 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 }, { 0x14, 16 },
{ 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12 },
{ 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 },
{ 0x23, 8 }, { 0x1a, 16 }, { 0x22, 8 }, { 0x19, 16 },
{ 0x20, 8 }, { 0x18, 16 }, { 0xe, 10 }, { 0x17, 16 },
{ 0xd, 10 }, { 0x16, 16 }, { 0x8, 10 }, { 0x15, 16 },
{ 0x1f, 12 }, { 0x1a, 12 }, { 0x19, 12 }, { 0x17, 12 },
{ 0x16, 12 }, { 0x1f, 13 }, { 0x1e, 13 }, { 0x1d, 13 },
{ 0x1c, 13 }, { 0x1b, 13 }, { 0x1f, 16 }, { 0x1e, 16 },
{ 0x1d, 16 }, { 0x1c, 16 }, { 0x1b, 16 },
{ 0x1, 6 }, /* escape */
{ 0x2, 2 }, /* EOB */
};
static const uint16_t mpeg2_vlc[113][2] = {
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},
{0x11,16}, {0x10,16}, {0x05, 5}, {0x07, 7},
{0xfc, 8}, {0x0c,10}, {0x14,13}, {0x07, 5},
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x06, 6},
{0xfd, 8}, {0x12,12}, {0x07, 6}, {0x04, 9},
{0x12,13}, {0x06, 7}, {0x1e,12}, {0x14,16},
{0x04, 7}, {0x15,12}, {0x05, 7}, {0x11,12},
{0x78, 7}, {0x11,13}, {0x7a, 7}, {0x10,13},
{0x21, 8}, {0x1a,16}, {0x25, 8}, {0x19,16},
{0x24, 8}, {0x18,16}, {0x05, 9}, {0x17,16},
{0x07, 9}, {0x16,16}, {0x0d,10}, {0x15,16},
{0x1f,12}, {0x1a,12}, {0x19,12}, {0x17,12},
{0x16,12}, {0x1f,13}, {0x1e,13}, {0x1d,13},
{0x1c,13}, {0x1b,13}, {0x1f,16}, {0x1e,16},
{0x1d,16}, {0x1c,16}, {0x1b,16},
{0x01,6}, /* escape */
{0x06,4}, /* EOB */
};
static const int8_t mpeg1_level[111] = {
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40,
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 1, 2, 3, 4, 5, 1,
2, 3, 4, 1, 2, 3, 1, 2,
3, 1, 2, 3, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1,
};
static const int8_t mpeg1_run[111] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 2, 2, 2, 2, 3,
3, 3, 3, 4, 4, 4, 5, 5,
5, 6, 6, 6, 7, 7, 8, 8,
9, 9, 10, 10, 11, 11, 12, 12,
13, 13, 14, 14, 15, 15, 16, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31,
};
RLTable ff_rl_mpeg1 = {
111,
111,
mpeg1_vlc,
mpeg1_run,
mpeg1_level,
};
RLTable ff_rl_mpeg2 = {
111,
111,
mpeg2_vlc,
mpeg1_run,
mpeg1_level,
};
const uint8_t ff_mpeg12_mbAddrIncrTable[36][2] = {
{0x1, 1},
{0x3, 3},
{0x2, 3},
{0x3, 4},
{0x2, 4},
{0x3, 5},
{0x2, 5},
{0x7, 7},
{0x6, 7},
{0xb, 8},
{0xa, 8},
{0x9, 8},
{0x8, 8},
{0x7, 8},
{0x6, 8},
{0x17, 10},
{0x16, 10},
{0x15, 10},
{0x14, 10},
{0x13, 10},
{0x12, 10},
{0x23, 11},
{0x22, 11},
{0x21, 11},
{0x20, 11},
{0x1f, 11},
{0x1e, 11},
{0x1d, 11},
{0x1c, 11},
{0x1b, 11},
{0x1a, 11},
{0x19, 11},
{0x18, 11},
{0x8, 11}, /* escape */
{0xf, 11}, /* stuffing */
{0x0, 8}, /* end (and 15 more 0 bits should follow) */
};
const uint8_t ff_mpeg12_mbPatTable[64][2] = {
{0x1, 9},
{0xb, 5},
{0x9, 5},
{0xd, 6},
{0xd, 4},
{0x17, 7},
{0x13, 7},
{0x1f, 8},
{0xc, 4},
{0x16, 7},
{0x12, 7},
{0x1e, 8},
{0x13, 5},
{0x1b, 8},
{0x17, 8},
{0x13, 8},
{0xb, 4},
{0x15, 7},
{0x11, 7},
{0x1d, 8},
{0x11, 5},
{0x19, 8},
{0x15, 8},
{0x11, 8},
{0xf, 6},
{0xf, 8},
{0xd, 8},
{0x3, 9},
{0xf, 5},
{0xb, 8},
{0x7, 8},
{0x7, 9},
{0xa, 4},
{0x14, 7},
{0x10, 7},
{0x1c, 8},
{0xe, 6},
{0xe, 8},
{0xc, 8},
{0x2, 9},
{0x10, 5},
{0x18, 8},
{0x14, 8},
{0x10, 8},
{0xe, 5},
{0xa, 8},
{0x6, 8},
{0x6, 9},
{0x12, 5},
{0x1a, 8},
{0x16, 8},
{0x12, 8},
{0xd, 5},
{0x9, 8},
{0x5, 8},
{0x5, 9},
{0xc, 5},
{0x8, 8},
{0x4, 8},
{0x4, 9},
{0x7, 3},
{0xa, 5},
{0x8, 5},
{0xc, 6}
};
const uint8_t ff_mpeg12_mbMotionVectorTable[17][2] = {
{ 0x1, 1 },
{ 0x1, 2 },
{ 0x1, 3 },
{ 0x1, 4 },
{ 0x3, 6 },
{ 0x5, 7 },
{ 0x4, 7 },
{ 0x3, 7 },
{ 0xb, 9 },
{ 0xa, 9 },
{ 0x9, 9 },
{ 0x11, 10 },
{ 0x10, 10 },
{ 0xf, 10 },
{ 0xe, 10 },
{ 0xd, 10 },
{ 0xc, 10 },
};
const AVRational ff_mpeg12_frame_rate_tab[16] = {
{ 0, 0},
{24000, 1001},
{ 24, 1},
{ 25, 1},
{30000, 1001},
{ 30, 1},
{ 50, 1},
{60000, 1001},
{ 60, 1},
// Xing's 15fps: (9)
{ 15, 1},
// libmpeg3's "Unofficial economy rates": (10-13)
{ 5, 1},
{ 10, 1},
{ 12, 1},
{ 15, 1},
{ 0, 0},
};
const AVRational ff_mpeg2_frame_rate_tab[] = {
{ 1, 1},
{ 2, 1},
{ 3, 1},
{ 4, 1},
{ 5, 1},
{ 6, 1},
{ 8, 1},
{ 9, 1},
{ 10, 1},
{ 12, 1},
{ 15, 1},
{ 16, 1},
{ 18, 1},
{ 20, 1},
{ 24, 1},
{ 25, 1},
{ 30, 1},
{ 32, 1},
{ 36, 1},
{ 40, 1},
{ 45, 1},
{ 48, 1},
{ 50, 1},
{ 60, 1},
{ 72, 1},
{ 75, 1},
{ 80, 1},
{ 90, 1},
{ 96, 1},
{ 100, 1},
{ 120, 1},
{ 150, 1},
{ 180, 1},
{ 200, 1},
{ 240, 1},
{ 750, 1001},
{ 800, 1001},
{ 960, 1001},
{ 1000, 1001},
{ 1200, 1001},
{ 1250, 1001},
{ 1500, 1001},
{ 1600, 1001},
{ 1875, 1001},
{ 2000, 1001},
{ 2400, 1001},
{ 2500, 1001},
{ 3000, 1001},
{ 3750, 1001},
{ 4000, 1001},
{ 4800, 1001},
{ 5000, 1001},
{ 6000, 1001},
{ 7500, 1001},
{ 8000, 1001},
{ 10000, 1001},
{ 12000, 1001},
{ 15000, 1001},
{ 20000, 1001},
{ 24000, 1001},
{ 30000, 1001},
{ 60000, 1001},
{ 0, 0},
};
const float ff_mpeg1_aspect[16]={
0.0000,
1.0000,
0.6735,
0.7031,
0.7615,
0.8055,
0.8437,
0.8935,
0.9157,
0.9815,
1.0255,
1.0695,
1.0950,
1.1575,
1.2015,
};
const AVRational ff_mpeg2_aspect[16]={
{0,1},
{1,1},
{4,3},
{16,9},
{221,100},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
};

View file

@ -0,0 +1,57 @@
/*
* MPEG1/2 tables
* copyright (c) 2000,2001 Fabrice Bellard
* copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* MPEG1/2 tables.
*/
#ifndef AVCODEC_MPEG12DATA_H
#define AVCODEC_MPEG12DATA_H
#include <stdint.h>
#include "libavutil/rational.h"
#include "rl.h"
extern const uint16_t ff_mpeg1_default_intra_matrix[];
extern const uint16_t ff_mpeg1_default_non_intra_matrix[64];
extern const uint16_t ff_mpeg12_vlc_dc_lum_code[12];
extern const unsigned char ff_mpeg12_vlc_dc_lum_bits[12];
extern const uint16_t ff_mpeg12_vlc_dc_chroma_code[12];
extern const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12];
extern RLTable ff_rl_mpeg1;
extern RLTable ff_rl_mpeg2;
extern const uint8_t ff_mpeg12_mbAddrIncrTable[36][2];
extern const uint8_t ff_mpeg12_mbPatTable[64][2];
extern const uint8_t ff_mpeg12_mbMotionVectorTable[17][2];
extern const AVRational ff_mpeg12_frame_rate_tab[];
extern const AVRational ff_mpeg2_frame_rate_tab[];
extern const float ff_mpeg1_aspect[16];
extern const AVRational ff_mpeg2_aspect[16];
#endif /* AVCODEC_MPEG12DATA_H */

View file

@ -0,0 +1,190 @@
/*
* MPEG-4 Audio common code
* Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr>
* Copyright (c) 2009 Alex Converse <alex.converse@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "get_bits.h"
#include "put_bits.h"
#include "mpeg4audio.h"
/**
* Parse MPEG-4 audio configuration for ALS object type.
* @param[in] gb bit reader context
* @param[in] c MPEG4AudioConfig structure to fill
* @return on success 0 is returned, otherwise a value < 0
*/
static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c)
{
if (get_bits_left(gb) < 112)
return -1;
if (get_bits_long(gb, 32) != MKBETAG('A','L','S','\0'))
return -1;
// override AudioSpecificConfig channel configuration and sample rate
// which are buggy in old ALS conformance files
c->sample_rate = get_bits_long(gb, 32);
// skip number of samples
skip_bits_long(gb, 32);
// read number of channels
c->chan_config = 0;
c->channels = get_bits(gb, 16) + 1;
return 0;
}
/* XXX: make sure to update the copies in the different encoders if you change
* this table */
const int avpriv_mpeg4audio_sample_rates[16] = {
96000, 88200, 64000, 48000, 44100, 32000,
24000, 22050, 16000, 12000, 11025, 8000, 7350
};
const uint8_t ff_mpeg4audio_channels[8] = {
0, 1, 2, 3, 4, 5, 6, 8
};
static inline int get_object_type(GetBitContext *gb)
{
int object_type = get_bits(gb, 5);
if (object_type == AOT_ESCAPE)
object_type = 32 + get_bits(gb, 6);
return object_type;
}
static inline int get_sample_rate(GetBitContext *gb, int *index)
{
*index = get_bits(gb, 4);
return *index == 0x0f ? get_bits(gb, 24) :
avpriv_mpeg4audio_sample_rates[*index];
}
int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
int bit_size, int sync_extension)
{
GetBitContext gb;
int specific_config_bitindex;
if (bit_size <= 0 || init_get_bits(&gb, buf, bit_size) < 0)
return AVERROR_INVALIDDATA;
c->object_type = get_object_type(&gb);
c->sample_rate = get_sample_rate(&gb, &c->sampling_index);
c->chan_config = get_bits(&gb, 4);
if (c->chan_config < FF_ARRAY_ELEMS(ff_mpeg4audio_channels))
c->channels = ff_mpeg4audio_channels[c->chan_config];
c->sbr = -1;
c->ps = -1;
if (c->object_type == AOT_SBR || (c->object_type == AOT_PS &&
// check for W6132 Annex YYYY draft MP3onMP4
!(show_bits(&gb, 3) & 0x03 && !(show_bits(&gb, 9) & 0x3F)))) {
if (c->object_type == AOT_PS)
c->ps = 1;
c->ext_object_type = AOT_SBR;
c->sbr = 1;
c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index);
c->object_type = get_object_type(&gb);
if (c->object_type == AOT_ER_BSAC)
c->ext_chan_config = get_bits(&gb, 4);
} else {
c->ext_object_type = AOT_NULL;
c->ext_sample_rate = 0;
}
specific_config_bitindex = get_bits_count(&gb);
if (c->object_type == AOT_ALS) {
skip_bits(&gb, 5);
if (show_bits_long(&gb, 24) != MKBETAG('\0','A','L','S'))
skip_bits_long(&gb, 24);
specific_config_bitindex = get_bits_count(&gb);
if (parse_config_ALS(&gb, c))
return -1;
}
if (c->ext_object_type != AOT_SBR && sync_extension) {
while (get_bits_left(&gb) > 15) {
if (show_bits(&gb, 11) == 0x2b7) { // sync extension
get_bits(&gb, 11);
c->ext_object_type = get_object_type(&gb);
if (c->ext_object_type == AOT_SBR && (c->sbr = get_bits1(&gb)) == 1) {
c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index);
if (c->ext_sample_rate == c->sample_rate)
c->sbr = -1;
}
if (get_bits_left(&gb) > 11 && get_bits(&gb, 11) == 0x548)
c->ps = get_bits1(&gb);
break;
} else
get_bits1(&gb); // skip 1 bit
}
}
//PS requires SBR
if (!c->sbr)
c->ps = 0;
//Limit implicit PS to the HE-AACv2 Profile
if ((c->ps == -1 && c->object_type != AOT_AAC_LC) || c->channels & ~0x01)
c->ps = 0;
return specific_config_bitindex;
}
static av_always_inline unsigned int copy_bits(PutBitContext *pb,
GetBitContext *gb,
int bits)
{
unsigned int el = get_bits(gb, bits);
put_bits(pb, bits, el);
return el;
}
int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb)
{
int five_bit_ch, four_bit_ch, comment_size, bits;
int offset = put_bits_count(pb);
copy_bits(pb, gb, 10); //Tag, Object Type, Frequency
five_bit_ch = copy_bits(pb, gb, 4); //Front
five_bit_ch += copy_bits(pb, gb, 4); //Side
five_bit_ch += copy_bits(pb, gb, 4); //Back
four_bit_ch = copy_bits(pb, gb, 2); //LFE
four_bit_ch += copy_bits(pb, gb, 3); //Data
five_bit_ch += copy_bits(pb, gb, 4); //Coupling
if (copy_bits(pb, gb, 1)) //Mono Mixdown
copy_bits(pb, gb, 4);
if (copy_bits(pb, gb, 1)) //Stereo Mixdown
copy_bits(pb, gb, 4);
if (copy_bits(pb, gb, 1)) //Matrix Mixdown
copy_bits(pb, gb, 3);
for (bits = five_bit_ch*5+four_bit_ch*4; bits > 16; bits -= 16)
copy_bits(pb, gb, 16);
if (bits)
copy_bits(pb, gb, bits);
avpriv_align_put_bits(pb);
align_get_bits(gb);
comment_size = copy_bits(pb, gb, 8);
for (; comment_size > 0; comment_size--)
copy_bits(pb, gb, 8);
return put_bits_count(pb) - offset;
}

View file

@ -0,0 +1,111 @@
/*
* MPEG-4 Audio common header
* Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MPEG4AUDIO_H
#define AVCODEC_MPEG4AUDIO_H
#include "config.h"
#include <stdint.h>
#include "get_bits.h"
#include "put_bits.h"
typedef struct MPEG4AudioConfig {
int object_type;
int sampling_index;
int sample_rate;
int chan_config;
int sbr; ///< -1 implicit, 1 presence
int ext_object_type;
int ext_sampling_index;
int ext_sample_rate;
int ext_chan_config;
int channels;
int ps; ///< -1 implicit, 1 presence
} MPEG4AudioConfig;
extern av_export const int avpriv_mpeg4audio_sample_rates[16];
extern const uint8_t ff_mpeg4audio_channels[8];
/**
* Parse MPEG-4 systems extradata to retrieve audio configuration.
* @param[in] c MPEG4AudioConfig structure to fill.
* @param[in] buf Extradata from container.
* @param[in] bit_size Extradata size in bits.
* @param[in] sync_extension look for a sync extension after config if true.
* @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata.
*/
int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
int bit_size, int sync_extension);
enum AudioObjectType {
AOT_NULL,
// Support? Name
AOT_AAC_MAIN, ///< Y Main
AOT_AAC_LC, ///< Y Low Complexity
AOT_AAC_SSR, ///< N (code in SoC repo) Scalable Sample Rate
AOT_AAC_LTP, ///< Y Long Term Prediction
AOT_SBR, ///< Y Spectral Band Replication
AOT_AAC_SCALABLE, ///< N Scalable
AOT_TWINVQ, ///< N Twin Vector Quantizer
AOT_CELP, ///< N Code Excited Linear Prediction
AOT_HVXC, ///< N Harmonic Vector eXcitation Coding
AOT_TTSI = 12, ///< N Text-To-Speech Interface
AOT_MAINSYNTH, ///< N Main Synthesis
AOT_WAVESYNTH, ///< N Wavetable Synthesis
AOT_MIDI, ///< N General MIDI
AOT_SAFX, ///< N Algorithmic Synthesis and Audio Effects
AOT_ER_AAC_LC, ///< N Error Resilient Low Complexity
AOT_ER_AAC_LTP = 19, ///< N Error Resilient Long Term Prediction
AOT_ER_AAC_SCALABLE, ///< N Error Resilient Scalable
AOT_ER_TWINVQ, ///< N Error Resilient Twin Vector Quantizer
AOT_ER_BSAC, ///< N Error Resilient Bit-Sliced Arithmetic Coding
AOT_ER_AAC_LD, ///< N Error Resilient Low Delay
AOT_ER_CELP, ///< N Error Resilient Code Excited Linear Prediction
AOT_ER_HVXC, ///< N Error Resilient Harmonic Vector eXcitation Coding
AOT_ER_HILN, ///< N Error Resilient Harmonic and Individual Lines plus Noise
AOT_ER_PARAM, ///< N Error Resilient Parametric
AOT_SSC, ///< N SinuSoidal Coding
AOT_PS, ///< N Parametric Stereo
AOT_SURROUND, ///< N MPEG Surround
AOT_ESCAPE, ///< Y Escape Value
AOT_L1, ///< Y Layer 1
AOT_L2, ///< Y Layer 2
AOT_L3, ///< Y Layer 3
AOT_DST, ///< N Direct Stream Transfer
AOT_ALS, ///< Y Audio LosslesS
AOT_SLS, ///< N Scalable LosslesS
AOT_SLS_NON_CORE, ///< N Scalable LosslesS (non core)
AOT_ER_AAC_ELD, ///< N Error Resilient Enhanced Low Delay
AOT_SMR_SIMPLE, ///< N Symbolic Music Representation Simple
AOT_SMR_MAIN, ///< N Symbolic Music Representation Main
AOT_USAC_NOSBR, ///< N Unified Speech and Audio Coding (no SBR)
AOT_SAOC, ///< N Spatial Audio Object Coding
AOT_LD_SURROUND, ///< N Low Delay MPEG Surround
AOT_USAC, ///< N Unified Speech and Audio Coding
};
#define MAX_PCE_SIZE 304 ///<Maximum size of a PCE including the 3-bit ID_PCE
///<marker and the comment
int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb);
#endif /* AVCODEC_MPEG4AUDIO_H */

View file

@ -0,0 +1,961 @@
/*
* Generic DCT based hybrid video encoder
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg 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.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* mpegvideo header.
*/
#ifndef AVCODEC_MPEGVIDEO_H
#define AVCODEC_MPEGVIDEO_H
#include "avcodec.h"
#include "dsputil.h"
#include "error_resilience.h"
#include "get_bits.h"
#include "h264chroma.h"
#include "hpeldsp.h"
#include "put_bits.h"
#include "ratecontrol.h"
#include "parser.h"
#include "mpeg12data.h"
#include "rl.h"
#include "thread.h"
#include "videodsp.h"
#include "libavutil/opt.h"
#include "libavutil/timecode.h"
#define FRAME_SKIPPED 100 ///< return value for header parsers if frame is not coded
enum OutputFormat {
FMT_MPEG1,
FMT_H261,
FMT_H263,
FMT_MJPEG,
};
#define MPEG_BUF_SIZE (16 * 1024)
#define QMAT_SHIFT_MMX 16
#define QMAT_SHIFT 21
#define MAX_FCODE 7
#define MAX_MV 4096
#define MAX_THREADS 32
#define MAX_PICTURE_COUNT 36
#define ME_MAP_SIZE 64
#define ME_MAP_SHIFT 3
#define ME_MAP_MV_BITS 11
#define MAX_MB_BYTES (30*16*16*3/8 + 120)
#define INPLACE_OFFSET 16
/* Start codes. */
#define SEQ_END_CODE 0x000001b7
#define SEQ_START_CODE 0x000001b3
#define GOP_START_CODE 0x000001b8
#define PICTURE_START_CODE 0x00000100
#define SLICE_MIN_START_CODE 0x00000101
#define SLICE_MAX_START_CODE 0x000001af
#define EXT_START_CODE 0x000001b5
#define USER_START_CODE 0x000001b2
/**
* Value of Picture.reference when Picture is not a reference picture, but
* is held for delayed output.
*/
#define DELAYED_PIC_REF 4
struct MpegEncContext;
/**
* Picture.
*/
typedef struct Picture{
struct AVFrame f;
ThreadFrame tf;
AVBufferRef *qscale_table_buf;
int8_t *qscale_table;
AVBufferRef *motion_val_buf[2];
int16_t (*motion_val[2])[2];
AVBufferRef *mb_type_buf;
uint32_t *mb_type;
AVBufferRef *mbskip_table_buf;
uint8_t *mbskip_table;
AVBufferRef *ref_index_buf[2];
int8_t *ref_index[2];
AVBufferRef *mb_var_buf;
uint16_t *mb_var; ///< Table for MB variances
AVBufferRef *mc_mb_var_buf;
uint16_t *mc_mb_var; ///< Table for motion compensated MB variances
int alloc_mb_width; ///< mb_width used to allocate tables
int alloc_mb_height; ///< mb_height used to allocate tables
AVBufferRef *mb_mean_buf;
uint8_t *mb_mean; ///< Table for MB luminance
AVBufferRef *hwaccel_priv_buf;
/**
* hardware accelerator private data
*/
void *hwaccel_picture_private;
#define MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if there is just one type
#define IS_INTRA4x4(a) ((a)&MB_TYPE_INTRA4x4)
#define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16)
#define IS_PCM(a) ((a)&MB_TYPE_INTRA_PCM)
#define IS_INTRA(a) ((a)&7)
#define IS_INTER(a) ((a)&(MB_TYPE_16x16|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8))
#define IS_SKIP(a) ((a)&MB_TYPE_SKIP)
#define IS_INTRA_PCM(a) ((a)&MB_TYPE_INTRA_PCM)
#define IS_INTERLACED(a) ((a)&MB_TYPE_INTERLACED)
#define IS_DIRECT(a) ((a)&MB_TYPE_DIRECT2)
#define IS_GMC(a) ((a)&MB_TYPE_GMC)
#define IS_16X16(a) ((a)&MB_TYPE_16x16)
#define IS_16X8(a) ((a)&MB_TYPE_16x8)
#define IS_8X16(a) ((a)&MB_TYPE_8x16)
#define IS_8X8(a) ((a)&MB_TYPE_8x8)
#define IS_SUB_8X8(a) ((a)&MB_TYPE_16x16) //note reused
#define IS_SUB_8X4(a) ((a)&MB_TYPE_16x8) //note reused
#define IS_SUB_4X8(a) ((a)&MB_TYPE_8x16) //note reused
#define IS_SUB_4X4(a) ((a)&MB_TYPE_8x8) //note reused
#define IS_ACPRED(a) ((a)&MB_TYPE_ACPRED)
#define IS_QUANT(a) ((a)&MB_TYPE_QUANT)
#define IS_DIR(a, part, list) ((a) & (MB_TYPE_P0L0<<((part)+2*(list))))
#define USES_LIST(a, list) ((a) & ((MB_TYPE_P0L0|MB_TYPE_P1L0)<<(2*(list)))) ///< does this mb use listX, note does not work if subMBs
#define HAS_CBP(a) ((a)&MB_TYPE_CBP)
int field_poc[2]; ///< h264 top/bottom POC
int poc; ///< h264 frame POC
int frame_num; ///< h264 frame_num (raw frame_num from slice header)
int mmco_reset; ///< h264 MMCO_RESET set this 1. Reordering code must not mix pictures before and after MMCO_RESET.
int pic_id; /**< h264 pic_num (short -> no wrap version of pic_num,
pic_num & max_pic_num; long -> long_pic_num) */
int long_ref; ///< 1->long term reference 0->short term reference
int ref_poc[2][2][32]; ///< h264 POCs of the frames/fields used as reference (FIXME need per slice)
int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice)
int mbaff; ///< h264 1 -> MBAFF frame 0-> not MBAFF
int field_picture; ///< whether or not the picture was encoded in separate fields
int sync; ///< has been decoded after a keyframe
int mb_var_sum; ///< sum of MB variance for current frame
int mc_mb_var_sum; ///< motion compensated MB variance for current frame
int b_frame_score;
int needs_realloc; ///< Picture needs to be reallocated (eg due to a frame size change)
int reference;
int shared;
int crop;
int crop_left;
int crop_top;
} Picture;
/**
* Motion estimation context.
*/
typedef struct MotionEstContext{
AVCodecContext *avctx;
int skip; ///< set if ME is skipped for the current MB
int co_located_mv[4][2]; ///< mv from last P-frame for direct mode ME
int direct_basis_mv[4][2];
uint8_t *scratchpad; ///< data area for the ME algo, so that the ME does not need to malloc/free
uint8_t *best_mb;
uint8_t *temp_mb[2];
uint8_t *temp;
int best_bits;
uint32_t *map; ///< map to avoid duplicate evaluations
uint32_t *score_map; ///< map to store the scores
unsigned map_generation;
int pre_penalty_factor;
int penalty_factor; /**< an estimate of the bits required to
code a given mv value, e.g. (1,0) takes
more bits than (0,0). We have to
estimate whether any reduction in
residual is worth the extra bits. */
int sub_penalty_factor;
int mb_penalty_factor;
int flags;
int sub_flags;
int mb_flags;
int pre_pass; ///< = 1 for the pre pass
int dia_size;
int xmin;
int xmax;
int ymin;
int ymax;
int pred_x;
int pred_y;
uint8_t *src[4][4];
uint8_t *ref[4][4];
int stride;
int uvstride;
/* temp variables for picture complexity calculation */
int mc_mb_var_sum_temp;
int mb_var_sum_temp;
int scene_change_score;
/* cmp, chroma_cmp;*/
op_pixels_func (*hpel_put)[4];
op_pixels_func (*hpel_avg)[4];
qpel_mc_func (*qpel_put)[16];
qpel_mc_func (*qpel_avg)[16];
uint8_t (*mv_penalty)[MAX_MV*2+1]; ///< amount of bits needed to encode a MV
uint8_t *current_mv_penalty;
int (*sub_motion_search)(struct MpegEncContext * s,
int *mx_ptr, int *my_ptr, int dmin,
int src_index, int ref_index,
int size, int h);
}MotionEstContext;
/**
* MpegEncContext.
*/
typedef struct MpegEncContext {
AVClass *class;
struct AVCodecContext *avctx;
/* the following parameters must be initialized before encoding */
int width, height;///< picture size. must be a multiple of 16
int gop_size;
int intra_only; ///< if true, only intra pictures are generated
int bit_rate; ///< wanted bit rate
enum OutputFormat out_format; ///< output format
int h263_pred; ///< use mpeg4/h263 ac/dc predictions
int pb_frame; ///< PB frame mode (0 = none, 1 = base, 2 = improved)
/* the following codec id fields are deprecated in favor of codec_id */
int h263_plus; ///< h263 plus headers
int h263_flv; ///< use flv h263 header
enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */
int fixed_qscale; ///< fixed qscale if non zero
int encoding; ///< true if we are encoding (vs decoding)
int flags; ///< AVCodecContext.flags (HQ, MV4, ...)
int flags2; ///< AVCodecContext.flags2
int max_b_frames; ///< max number of b-frames for encoding
int luma_elim_threshold;
int chroma_elim_threshold;
int strict_std_compliance; ///< strictly follow the std (MPEG4, ...)
int workaround_bugs; ///< workaround bugs in encoders which cannot be detected automatically
int codec_tag; ///< internal codec_tag upper case converted from avctx codec_tag
int stream_codec_tag; ///< internal stream_codec_tag upper case converted from avctx stream_codec_tag
/* the following fields are managed internally by the encoder */
/* sequence parameters */
int context_initialized;
int input_picture_number; ///< used to set pic->display_picture_number, should not be used for/by anything else
int coded_picture_number; ///< used to set pic->coded_picture_number, should not be used for/by anything else
int picture_number; //FIXME remove, unclear definition
int picture_in_gop_number; ///< 0-> first pic in gop, ...
int mb_width, mb_height; ///< number of MBs horizontally & vertically
int mb_stride; ///< mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11
int b8_stride; ///< 2*mb_width+1 used for some 8x8 block arrays to allow simple addressing
int b4_stride; ///< 4*mb_width+1 used for some 4x4 block arrays to allow simple addressing
int h_edge_pos, v_edge_pos;///< horizontal / vertical position of the right/bottom edge (pixel replication)
int mb_num; ///< number of MBs of a picture
ptrdiff_t linesize; ///< line size, in bytes, may be different from width
ptrdiff_t uvlinesize; ///< line size, for chroma in bytes, may be different from width
Picture *picture; ///< main picture buffer
Picture **input_picture; ///< next pictures on display order for encoding
Picture **reordered_input_picture; ///< pointer to the next pictures in codedorder for encoding
int y_dc_scale, c_dc_scale;
int ac_pred;
int block_last_index[12]; ///< last non zero coefficient in block
int h263_aic; ///< Advanded INTRA Coding (AIC)
/* scantables */
ScanTable inter_scantable; ///< if inter == intra then intra should be used to reduce tha cache usage
ScanTable intra_scantable;
ScanTable intra_h_scantable;
ScanTable intra_v_scantable;
/* WARNING: changes above this line require updates to hardcoded
* offsets used in asm. */
int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_encode_video2()
/**
* pts difference between the first and second input frame, used for
* calculating dts of the first frame when there's a delay */
int64_t dts_delta;
/**
* reordered pts to be used as dts for the next output frame when there's
* a delay */
int64_t reordered_pts;
/** bit output */
PutBitContext pb;
int start_mb_y; ///< start mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y)
int end_mb_y; ///< end mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y)
struct MpegEncContext *thread_context[MAX_THREADS];
int slice_context_count; ///< number of used thread_contexts
/**
* copy of the previous picture structure.
* note, linesize & data, might not match the previous picture (for field pictures)
*/
Picture last_picture;
/**
* copy of the next picture structure.
* note, linesize & data, might not match the next picture (for field pictures)
*/
Picture next_picture;
/**
* copy of the source picture structure for encoding.
* note, linesize & data, might not match the source picture (for field pictures)
*/
Picture new_picture;
/**
* copy of the current picture structure.
* note, linesize & data, might not match the current picture (for field pictures)
*/
Picture current_picture; ///< buffer to store the decompressed current picture
Picture *last_picture_ptr; ///< pointer to the previous picture.
Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred)
Picture *current_picture_ptr; ///< pointer to the current picture
int last_dc[3]; ///< last DC values for MPEG1
int16_t *dc_val_base;
int16_t *dc_val[3]; ///< used for mpeg4 DC prediction, all 3 arrays must be continuous
const uint8_t *y_dc_scale_table; ///< qscale -> y_dc_scale table
const uint8_t *c_dc_scale_table; ///< qscale -> c_dc_scale table
const uint8_t *chroma_qscale_table; ///< qscale -> chroma_qscale (h263)
uint8_t *coded_block_base;
uint8_t *coded_block; ///< used for coded block pattern prediction (msmpeg4v3, wmv1)
int16_t (*ac_val_base)[16];
int16_t (*ac_val[3])[16]; ///< used for mpeg4 AC prediction, all 3 arrays must be continuous
int mb_skipped; ///< MUST BE SET only during DECODING
uint8_t *mbskip_table; /**< used to avoid copy if macroblock skipped (for black regions for example)
and used for b-frame encoding & decoding (contains skip table of next P Frame) */
uint8_t *mbintra_table; ///< used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding
uint8_t *cbp_table; ///< used to store cbp, ac_pred for partitioned decoding
uint8_t *pred_dir_table; ///< used to store pred_dir for partitioned decoding
uint8_t *edge_emu_buffer; ///< temporary buffer for if MVs point to out-of-frame data
uint8_t *rd_scratchpad; ///< scratchpad for rate distortion mb decision
uint8_t *obmc_scratchpad;
uint8_t *b_scratchpad; ///< scratchpad used for writing into write only buffers
int qscale; ///< QP
int chroma_qscale; ///< chroma QP
unsigned int lambda; ///< lagrange multipler used in rate distortion
unsigned int lambda2; ///< (lambda*lambda) >> FF_LAMBDA_SHIFT
int *lambda_table;
int adaptive_quant; ///< use adaptive quantization
int dquant; ///< qscale difference to prev qscale
int closed_gop; ///< MPEG1/2 GOP is closed
int pict_type; ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
int vbv_delay;
int last_pict_type; //FIXME removes
int last_non_b_pict_type; ///< used for mpeg4 gmc b-frames & ratecontrol
int droppable;
int frame_rate_index;
AVRational mpeg2_frame_rate_ext;
int last_lambda_for[5]; ///< last lambda for a specific pict type
int skipdct; ///< skip dct and code zero residual
/* motion compensation */
int unrestricted_mv; ///< mv can point outside of the coded picture
int h263_long_vectors; ///< use horrible h263v1 long vector mode
DSPContext dsp; ///< pointers for accelerated dsp functions
H264ChromaContext h264chroma;
HpelDSPContext hdsp;
VideoDSPContext vdsp;
int f_code; ///< forward MV resolution
int b_code; ///< backward MV resolution for B Frames (mpeg4)
int16_t (*p_mv_table_base)[2];
int16_t (*b_forw_mv_table_base)[2];
int16_t (*b_back_mv_table_base)[2];
int16_t (*b_bidir_forw_mv_table_base)[2];
int16_t (*b_bidir_back_mv_table_base)[2];
int16_t (*b_direct_mv_table_base)[2];
int16_t (*p_field_mv_table_base[2][2])[2];
int16_t (*b_field_mv_table_base[2][2][2])[2];
int16_t (*p_mv_table)[2]; ///< MV table (1MV per MB) p-frame encoding
int16_t (*b_forw_mv_table)[2]; ///< MV table (1MV per MB) forward mode b-frame encoding
int16_t (*b_back_mv_table)[2]; ///< MV table (1MV per MB) backward mode b-frame encoding
int16_t (*b_bidir_forw_mv_table)[2]; ///< MV table (1MV per MB) bidir mode b-frame encoding
int16_t (*b_bidir_back_mv_table)[2]; ///< MV table (1MV per MB) bidir mode b-frame encoding
int16_t (*b_direct_mv_table)[2]; ///< MV table (1MV per MB) direct mode b-frame encoding
int16_t (*p_field_mv_table[2][2])[2]; ///< MV table (2MV per MB) interlaced p-frame encoding
int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced b-frame encoding
uint8_t (*p_field_select_table[2]);
uint8_t (*b_field_select_table[2][2]);
int me_method; ///< ME algorithm
int mv_dir;
#define MV_DIR_FORWARD 1
#define MV_DIR_BACKWARD 2
#define MV_DIRECT 4 ///< bidirectional mode where the difference equals the MV of the last P/S/I-Frame (mpeg4)
int mv_type;
#define MV_TYPE_16X16 0 ///< 1 vector for the whole mb
#define MV_TYPE_8X8 1 ///< 4 vectors (h263, mpeg4 4MV)
#define MV_TYPE_16X8 2 ///< 2 vectors, one per 16x8 block
#define MV_TYPE_FIELD 3 ///< 2 vectors, one per field
#define MV_TYPE_DMV 4 ///< 2 vectors, special mpeg2 Dual Prime Vectors
/**motion vectors for a macroblock
first coordinate : 0 = forward 1 = backward
second " : depend on type
third " : 0 = x, 1 = y
*/
int mv[2][4][2];
int field_select[2][2];
int last_mv[2][2][2]; ///< last MV, used for MV prediction in MPEG1 & B-frame MPEG4
uint8_t *fcode_tab; ///< smallest fcode needed for each MV
int16_t direct_scale_mv[2][64]; ///< precomputed to avoid divisions in ff_mpeg4_set_direct_mv
MotionEstContext me;
int no_rounding; /**< apply no rounding to motion compensation (MPEG4, msmpeg4, ...)
for b-frames rounding mode is always 0 */
/* macroblock layer */
int mb_x, mb_y;
int mb_skip_run;
int mb_intra;
uint16_t *mb_type; ///< Table for candidate MB types for encoding
#define CANDIDATE_MB_TYPE_INTRA 0x01
#define CANDIDATE_MB_TYPE_INTER 0x02
#define CANDIDATE_MB_TYPE_INTER4V 0x04
#define CANDIDATE_MB_TYPE_SKIPPED 0x08
//#define MB_TYPE_GMC 0x10
#define CANDIDATE_MB_TYPE_DIRECT 0x10
#define CANDIDATE_MB_TYPE_FORWARD 0x20
#define CANDIDATE_MB_TYPE_BACKWARD 0x40
#define CANDIDATE_MB_TYPE_BIDIR 0x80
#define CANDIDATE_MB_TYPE_INTER_I 0x100
#define CANDIDATE_MB_TYPE_FORWARD_I 0x200
#define CANDIDATE_MB_TYPE_BACKWARD_I 0x400
#define CANDIDATE_MB_TYPE_BIDIR_I 0x800
#define CANDIDATE_MB_TYPE_DIRECT0 0x1000
int block_index[6]; ///< index to current MB in block based arrays with edges
int block_wrap[6];
uint8_t *dest[3];
int *mb_index2xy; ///< mb_index -> mb_x + mb_y*mb_stride
/** matrix transmitted in the bitstream */
uint16_t intra_matrix[64];
uint16_t chroma_intra_matrix[64];
uint16_t inter_matrix[64];
uint16_t chroma_inter_matrix[64];
#define QUANT_BIAS_SHIFT 8
int intra_quant_bias; ///< bias for the quantizer
int inter_quant_bias; ///< bias for the quantizer
int min_qcoeff; ///< minimum encodable coefficient
int max_qcoeff; ///< maximum encodable coefficient
int ac_esc_length; ///< num of bits needed to encode the longest esc
uint8_t *intra_ac_vlc_length;
uint8_t *intra_ac_vlc_last_length;
uint8_t *inter_ac_vlc_length;
uint8_t *inter_ac_vlc_last_length;
uint8_t *luma_dc_vlc_length;
#define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level))
int coded_score[12];
/** precomputed matrix (combine qscale and DCT renorm) */
int (*q_intra_matrix)[64];
int (*q_chroma_intra_matrix)[64];
int (*q_inter_matrix)[64];
/** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/
uint16_t (*q_intra_matrix16)[2][64];
uint16_t (*q_chroma_intra_matrix16)[2][64];
uint16_t (*q_inter_matrix16)[2][64];
/* noise reduction */
int (*dct_error_sum)[64];
int dct_count[2];
uint16_t (*dct_offset)[64];
void *opaque; ///< private data for the user
/* bit rate control */
int64_t total_bits;
int frame_bits; ///< bits used for the current frame
int stuffing_bits; ///< bits used for stuffing
int next_lambda; ///< next lambda used for retrying to encode a frame
RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
/* statistics, used for 2-pass encoding */
int mv_bits;
int header_bits;
int i_tex_bits;
int p_tex_bits;
int i_count;
int f_count;
int b_count;
int skip_count;
int misc_bits; ///< cbp, mb_type
int last_bits; ///< temp var used for calculating the above vars
/* error concealment / resync */
int resync_mb_x; ///< x position of last resync marker
int resync_mb_y; ///< y position of last resync marker
GetBitContext last_resync_gb; ///< used to search for the next resync marker
int mb_num_left; ///< number of MBs left in this video packet (for partitioned Slices only)
int next_p_frame_damaged; ///< set if the next p frame is damaged, to avoid showing trashed b frames
int err_recognition;
ParseContext parse_context;
/* H.263 specific */
int gob_index;
int obmc; ///< overlapped block motion compensation
int showed_packed_warning; ///< flag for having shown the warning about divxs invalid b frames
int mb_info; ///< interval for outputting info about mb offsets as side data
int prev_mb_info, last_mb_info;
uint8_t *mb_info_ptr;
int mb_info_size;
int ehc_mode;
/* H.263+ specific */
int umvplus; ///< == H263+ && unrestricted_mv
int h263_aic_dir; ///< AIC direction: 0 = left, 1 = top
int h263_slice_structured;
int alt_inter_vlc; ///< alternative inter vlc
int modified_quant;
int loop_filter;
int custom_pcf;
/* mpeg4 specific */
int time_increment_bits; ///< number of bits to represent the fractional part of time
int last_time_base;
int time_base; ///< time in seconds of last I,P,S Frame
int64_t time; ///< time of current frame
int64_t last_non_b_time;
uint16_t pp_time; ///< time distance between the last 2 p,s,i frames
uint16_t pb_time; ///< time distance between the last b and p,s,i frame
uint16_t pp_field_time;
uint16_t pb_field_time; ///< like above, just for interlaced
int shape;
int vol_sprite_usage;
int sprite_width;
int sprite_height;
int sprite_left;
int sprite_top;
int sprite_brightness_change;
int num_sprite_warping_points;
int real_sprite_warping_points;
uint16_t sprite_traj[4][2]; ///< sprite trajectory points
int sprite_offset[2][2]; ///< sprite offset[isChroma][isMVY]
int sprite_delta[2][2]; ///< sprite_delta [isY][isMVY]
int sprite_shift[2]; ///< sprite shift [isChroma]
int mcsel;
int quant_precision;
int quarter_sample; ///< 1->qpel, 0->half pel ME/MC
int scalability;
int hierachy_type;
int enhancement_type;
int new_pred;
int reduced_res_vop;
int aspect_ratio_info; //FIXME remove
int sprite_warping_accuracy;
int low_latency_sprite;
int data_partitioning; ///< data partitioning flag from header
int partitioned_frame; ///< is current frame partitioned
int rvlc; ///< reversible vlc
int resync_marker; ///< could this stream contain resync markers
int low_delay; ///< no reordering needed / has no b-frames
int vo_type;
int vol_control_parameters; ///< does the stream contain the low_delay flag, used to workaround buggy encoders
int intra_dc_threshold; ///< QP above whch the ac VLC should be used for intra dc
int use_intra_dc_vlc;
PutBitContext tex_pb; ///< used for data partitioned VOPs
PutBitContext pb2; ///< used for data partitioned VOPs
int mpeg_quant;
int t_frame; ///< time distance of first I -> B, used for interlaced b frames
int padding_bug_score; ///< used to detect the VERY common padding bug in MPEG4
int cplx_estimation_trash_i;
int cplx_estimation_trash_p;
int cplx_estimation_trash_b;
/* divx specific, used to workaround (many) bugs in divx5 */
int divx_version;
int divx_build;
int divx_packed;
uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them
int bitstream_buffer_size;
unsigned int allocated_bitstream_buffer_size;
int xvid_build;
/* lavc specific stuff, used to workaround bugs in libavcodec */
int lavc_build;
/* RV10 specific */
int rv10_version; ///< RV10 version: 0 or 3
int rv10_first_dc_coded[3];
int orig_width, orig_height;
/* MJPEG specific */
struct MJpegContext *mjpeg_ctx;
int mjpeg_vsample[3]; ///< vertical sampling factors, default = {2, 1, 1}
int mjpeg_hsample[3]; ///< horizontal sampling factors, default = {2, 1, 1}
int esc_pos;
/* MSMPEG4 specific */
int mv_table_index;
int rl_table_index;
int rl_chroma_table_index;
int dc_table_index;
int use_skip_mb_code;
int slice_height; ///< in macroblocks
int first_slice_line; ///< used in mpeg4 too to handle resync markers
int flipflop_rounding;
int msmpeg4_version; ///< 0=not msmpeg4, 1=mp41, 2=mp42, 3=mp43/divx3 4=wmv1/7 5=wmv2/8
int per_mb_rl_table;
int esc3_level_length;
int esc3_run_length;
/** [mb_intra][isChroma][level][run][last] */
int (*ac_stats)[2][MAX_LEVEL+1][MAX_RUN+1][2];
int inter_intra_pred;
int mspel;
/* decompression specific */
GetBitContext gb;
/* Mpeg1 specific */
int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & mpeg1 specific
int last_mv_dir; ///< last mv_dir, used for b frame encoding
int broken_link; ///< no_output_of_prior_pics_flag
uint8_t *vbv_delay_ptr; ///< pointer to vbv_delay in the bitstream
/* MPEG-2-specific - I wished not to have to support this mess. */
int progressive_sequence;
int mpeg_f_code[2][2];
int picture_structure;
/* picture type */
#define PICT_TOP_FIELD 1
#define PICT_BOTTOM_FIELD 2
#define PICT_FRAME 3
int intra_dc_precision;
int frame_pred_frame_dct;
int top_field_first;
int concealment_motion_vectors;
int q_scale_type;
int intra_vlc_format;
int alternate_scan;
int repeat_first_field;
int chroma_420_type;
int chroma_format;
#define CHROMA_420 1
#define CHROMA_422 2
#define CHROMA_444 3
int chroma_x_shift;//depend on pix_format, that depend on chroma_format
int chroma_y_shift;
int progressive_frame;
int full_pel[2];
int interlaced_dct;
int first_slice;
int first_field; ///< is 1 for the first field of a field picture 0 otherwise
int drop_frame_timecode; ///< timecode is in drop frame format.
int scan_offset; ///< reserve space for SVCD scan offset user data.
/* RTP specific */
int rtp_mode;
char *tc_opt_str; ///< timecode option string
AVTimecode tc; ///< timecode context
uint8_t *ptr_lastgob;
int swap_uv; //vcr2 codec is an MPEG-2 variant with U and V swapped
int16_t (*pblocks[12])[64];
int16_t (*block)[64]; ///< points to one of the following blocks
int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block
int (*decode_mb)(struct MpegEncContext *s, int16_t block[6][64]); // used by some codecs to avoid a switch()
#define SLICE_OK 0
#define SLICE_ERROR -1
#define SLICE_END -2 ///<end marker found
#define SLICE_NOEND -3 ///<no end marker or error found but mb count exceeded
void (*dct_unquantize_mpeg1_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg1_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg2_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg2_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h263_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h263_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h261_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h261_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_intra)(struct MpegEncContext *s, // unquantizer to use (mpeg4 can use both)
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_inter)(struct MpegEncContext *s, // unquantizer to use (mpeg4 can use both)
int16_t *block/*align 16*/, int n, int qscale);
int (*dct_quantize)(struct MpegEncContext *s, int16_t *block/*align 16*/, int n, int qscale, int *overflow);
int (*fast_dct_quantize)(struct MpegEncContext *s, int16_t *block/*align 16*/, int n, int qscale, int *overflow);
void (*denoise_dct)(struct MpegEncContext *s, int16_t *block);
int mpv_flags; ///< flags set by private options
int quantizer_noise_shaping;
/* temp buffers for rate control */
float *cplx_tab, *bits_tab;
/* flag to indicate a reinitialization is required, e.g. after
* a frame size change */
int context_reinit;
ERContext er;
} MpegEncContext;
#define REBASE_PICTURE(pic, new_ctx, old_ctx) \
((pic && pic >= old_ctx->picture && \
pic < old_ctx->picture + MAX_PICTURE_COUNT) ? \
&new_ctx->picture[pic - old_ctx->picture] : NULL)
/* mpegvideo_enc common options */
#define FF_MPV_FLAG_SKIP_RD 0x0001
#define FF_MPV_FLAG_STRICT_GOP 0x0002
#define FF_MPV_FLAG_QP_RD 0x0004
#define FF_MPV_FLAG_CBP_RD 0x0008
#define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
#define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
#define FF_MPV_COMMON_OPTS \
{ "mpv_flags", "Flags common for all mpegvideo-based encoders.", FF_MPV_OFFSET(mpv_flags), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "skip_rd", "RD optimal MB level residual skipping", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_SKIP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "strict_gop", "Strictly enforce gop size", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_STRICT_GOP }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "qp_rd", "Use rate distortion optimization for qp selection", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_QP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "cbp_rd", "use rate distortion optimization for CBP", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_CBP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "luma_elim_threshold", "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)",\
FF_MPV_OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\
{ "chroma_elim_threshold", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)",\
FF_MPV_OFFSET(chroma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\
{ "quantizer_noise_shaping", NULL, FF_MPV_OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS },
extern const AVOption ff_mpv_generic_options[];
#define FF_MPV_GENERIC_CLASS(name) \
static const AVClass name ## _class = {\
.class_name = #name " encoder",\
.item_name = av_default_item_name,\
.option = ff_mpv_generic_options,\
.version = LIBAVUTIL_VERSION_INT,\
};
/**
* Set the given MpegEncContext to common defaults (same for encoding
* and decoding). The changed fields will not depend upon the prior
* state of the MpegEncContext.
*/
void ff_MPV_common_defaults(MpegEncContext *s);
void ff_MPV_decode_defaults(MpegEncContext *s);
int ff_MPV_common_init(MpegEncContext *s);
int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize);
int ff_MPV_common_frame_size_change(MpegEncContext *s);
void ff_MPV_common_end(MpegEncContext *s);
void ff_MPV_decode_mb(MpegEncContext *s, int16_t block[12][64]);
int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx);
void ff_MPV_frame_end(MpegEncContext *s);
int ff_MPV_encode_init(AVCodecContext *avctx);
int ff_MPV_encode_end(AVCodecContext *avctx);
int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
AVFrame *frame, int *got_packet);
void ff_dct_encode_init_x86(MpegEncContext *s);
void ff_MPV_common_init_x86(MpegEncContext *s);
void ff_MPV_common_init_axp(MpegEncContext *s);
void ff_MPV_common_init_arm(MpegEncContext *s);
void ff_MPV_common_init_bfin(MpegEncContext *s);
void ff_MPV_common_init_ppc(MpegEncContext *s);
void ff_clean_intra_table_entries(MpegEncContext *s);
void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur,
Picture *last, int y, int h, int picture_structure,
int first_field, int draw_edges, int low_delay,
int v_edge_pos, int h_edge_pos);
void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h);
void ff_mpeg_flush(AVCodecContext *avctx);
void ff_print_debug_info(MpegEncContext *s, Picture *p, AVFrame *pict);
void ff_print_debug_info2(AVCodecContext *avctx, Picture *p, AVFrame *pict, uint8_t *mbskip_table,
int *low_delay,
int mb_width, int mb_height, int mb_stride, int quarter_sample);
int ff_mpv_export_qp_table(MpegEncContext *s, AVFrame *f, Picture *p, int qp_type);
void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix);
void ff_release_unused_pictures(MpegEncContext *s, int remove_current);
int ff_find_unused_picture(MpegEncContext *s, int shared);
void ff_denoise_dct(MpegEncContext *s, int16_t *block);
int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);
int ff_MPV_lowest_referenced_row(MpegEncContext *s, int dir);
void ff_MPV_report_decode_progress(MpegEncContext *s);
int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src);
void ff_set_qscale(MpegEncContext * s, int qscale);
void ff_mpeg_er_frame_start(MpegEncContext *s);
int ff_dct_common_init(MpegEncContext *s);
int ff_dct_encode_init(MpegEncContext *s);
void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64],
const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra);
int ff_dct_quantize_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);
void ff_init_block_index(MpegEncContext *s);
void ff_MPV_motion(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb,
uint8_t *dest_cr, int dir,
uint8_t **ref_picture,
op_pixels_func (*pix_op)[4],
qpel_mc_func (*qpix_op)[16]);
/**
* Allocate a Picture.
* The pixels are allocated/set by calling get_buffer() if shared = 0.
*/
int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared);
extern const enum AVPixelFormat ff_pixfmt_list_420[];
/**
* permute block according to permuatation.
* @param last last non zero element in scantable order
*/
void ff_block_permute(int16_t *block, uint8_t *permutation, const uint8_t *scantable, int last);
static inline void ff_update_block_index(MpegEncContext *s){
const int block_size= 8 >> s->avctx->lowres;
s->block_index[0]+=2;
s->block_index[1]+=2;
s->block_index[2]+=2;
s->block_index[3]+=2;
s->block_index[4]++;
s->block_index[5]++;
s->dest[0]+= 2*block_size;
s->dest[1]+= block_size;
s->dest[2]+= block_size;
}
static inline int get_bits_diff(MpegEncContext *s){
const int bits= put_bits_count(&s->pb);
const int last= s->last_bits;
s->last_bits = bits;
return bits - last;
}
static inline int ff_h263_round_chroma(int x){
static const uint8_t h263_chroma_roundtab[16] = {
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
};
return h263_chroma_roundtab[x & 0xf] + (x >> 3);
}
/* motion_est.c */
void ff_estimate_p_frame_motion(MpegEncContext * s,
int mb_x, int mb_y);
void ff_estimate_b_frame_motion(MpegEncContext * s,
int mb_x, int mb_y);
int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type);
void ff_fix_long_p_mvs(MpegEncContext * s);
void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select,
int16_t (*mv_table)[2], int f_code, int type, int truncate);
int ff_init_me(MpegEncContext *s);
int ff_pre_estimate_p_frame_motion(MpegEncContext * s, int mb_x, int mb_y);
int ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr,
int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2],
int ref_mv_scale, int size, int h);
int ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index,
int ref_index, int size, int h, int add_rate);
/* mpeg12.c */
extern const uint8_t ff_mpeg1_dc_scale_table[128];
extern const uint8_t * const ff_mpeg2_dc_scale_table[4];
void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number);
void ff_mpeg1_encode_mb(MpegEncContext *s,
int16_t block[6][64],
int motion_x, int motion_y);
void ff_mpeg1_encode_init(MpegEncContext *s);
void ff_mpeg1_encode_slice_header(MpegEncContext *s);
extern const uint8_t ff_aic_dc_scale_table[32];
extern const uint8_t ff_h263_chroma_qscale_table[32];
extern const uint8_t ff_h263_loop_filter_strength[32];
/* rv10.c */
void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number);
int ff_rv_decode_dc(MpegEncContext *s, int n);
void ff_rv20_encode_picture_header(MpegEncContext *s, int picture_number);
/* msmpeg4.c */
void ff_msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number);
void ff_msmpeg4_encode_ext_header(MpegEncContext * s);
void ff_msmpeg4_encode_mb(MpegEncContext * s,
int16_t block[6][64],
int motion_x, int motion_y);
int ff_msmpeg4_decode_picture_header(MpegEncContext * s);
int ff_msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size);
int ff_msmpeg4_decode_init(AVCodecContext *avctx);
void ff_msmpeg4_encode_init(MpegEncContext *s);
int ff_wmv2_decode_picture_header(MpegEncContext * s);
int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s);
void ff_wmv2_add_mb(MpegEncContext *s, int16_t block[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr);
void ff_mspel_motion(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
int motion_x, int motion_y, int h);
int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number);
void ff_wmv2_encode_mb(MpegEncContext * s,
int16_t block[6][64],
int motion_x, int motion_y);
int ff_mpeg_ref_picture(MpegEncContext *s, Picture *dst, Picture *src);
void ff_mpeg_unref_picture(MpegEncContext *s, Picture *picture);
#endif /* AVCODEC_MPEGVIDEO_H */

Some files were not shown because too many files have changed in this diff Show more