mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Merge remote-tracking branch 'qatar/master'
* qatar/master: (46 commits) mtv: Make sure audio_subsegments is not 0 v4l2: use V4L2_FMT_FLAG_EMULATED only if it is defined avconv: add symbolic names for -vsync parameters flvdec: Fix compiler warning for uninitialized variables rtsp: Fix compiler warning for uninitialized variable ulti: convert to new bytestream API. swscale: Use standard multiple inclusion guards in ppc/ header files. Place some START_TIMER invocations in separate blocks. v4l2: list available formats v4l2: set the proper codec_tag v4l2: refactor device_open v4l2: simplify away io_method v4l2: cosmetics v4l2: uniform and format options v4l2: do not force interlaced mode avio: exit early in fill_buffer without read_packet vc1dec: fix invalid memory access for small video dimensions rv34: fix invalid memory access for small video dimensions rv34: joint coefficient decoding and dequantization avplay: Don't call avio_set_interrupt_cb(NULL) ... Conflicts: Changelog avconv.c doc/APIchanges doc/indevs.texi libavcodec/adxenc.c libavcodec/dnxhdenc.c libavcodec/h264.c libavdevice/v4l2.c libavformat/flvdec.c libavformat/mtv.c libswscale/utils.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
7f83db3124
@ -145,7 +145,7 @@ easier to use. The changes are:
|
|||||||
- pan audio filter
|
- pan audio filter
|
||||||
- IFF Amiga Continuous Bitmap (ACBM) decoder
|
- IFF Amiga Continuous Bitmap (ACBM) decoder
|
||||||
- ass filter
|
- ass filter
|
||||||
- CRI ADX audio format demuxer
|
- CRI ADX audio format muxer and demuxer
|
||||||
- Playstation Portable PMP format demuxer
|
- Playstation Portable PMP format demuxer
|
||||||
- Microsoft Windows ICO demuxer
|
- Microsoft Windows ICO demuxer
|
||||||
- life source
|
- life source
|
||||||
|
30
avconv.c
30
avconv.c
@ -88,6 +88,11 @@
|
|||||||
|
|
||||||
#include "libavutil/avassert.h"
|
#include "libavutil/avassert.h"
|
||||||
|
|
||||||
|
#define VSYNC_AUTO -1
|
||||||
|
#define VSYNC_PASSTHROUGH 0
|
||||||
|
#define VSYNC_CFR 1
|
||||||
|
#define VSYNC_VFR 2
|
||||||
|
|
||||||
const char program_name[] = "avconv";
|
const char program_name[] = "avconv";
|
||||||
const int program_birth_year = 2000;
|
const int program_birth_year = 2000;
|
||||||
|
|
||||||
@ -127,7 +132,7 @@ static int do_hex_dump = 0;
|
|||||||
static int do_pkt_dump = 0;
|
static int do_pkt_dump = 0;
|
||||||
static int do_pass = 0;
|
static int do_pass = 0;
|
||||||
static const char *pass_logfilename_prefix;
|
static const char *pass_logfilename_prefix;
|
||||||
static int video_sync_method = -1;
|
static int video_sync_method = VSYNC_AUTO;
|
||||||
static int audio_sync_method = 0;
|
static int audio_sync_method = 0;
|
||||||
static float audio_drift_threshold = 0.1;
|
static float audio_drift_threshold = 0.1;
|
||||||
static int copy_ts = 0;
|
static int copy_ts = 0;
|
||||||
@ -1390,16 +1395,16 @@ static void do_video_out(AVFormatContext *s,
|
|||||||
*frame_size = 0;
|
*frame_size = 0;
|
||||||
|
|
||||||
format_video_sync = video_sync_method;
|
format_video_sync = video_sync_method;
|
||||||
if (format_video_sync < 0)
|
if (format_video_sync == VSYNC_AUTO)
|
||||||
format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? 0 :
|
format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH :
|
||||||
(s->oformat->flags & AVFMT_VARIABLE_FPS) ? 2 : 1;
|
(s->oformat->flags & AVFMT_VARIABLE_FPS) ? VSYNC_VFR : VSYNC_CFR;
|
||||||
|
|
||||||
if (format_video_sync) {
|
if (format_video_sync != VSYNC_PASSTHROUGH) {
|
||||||
double vdelta = sync_ipts - ost->sync_opts;
|
double vdelta = sync_ipts - ost->sync_opts;
|
||||||
// FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
|
// FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
|
||||||
if (vdelta < -1.1)
|
if (vdelta < -1.1)
|
||||||
nb_frames = 0;
|
nb_frames = 0;
|
||||||
else if (format_video_sync == 2) {
|
else if (format_video_sync == VSYNC_VFR) {
|
||||||
if (vdelta <= -0.6) {
|
if (vdelta <= -0.6) {
|
||||||
nb_frames = 0;
|
nb_frames = 0;
|
||||||
} else if (vdelta > 0.6)
|
} else if (vdelta > 0.6)
|
||||||
@ -4426,6 +4431,17 @@ static int opt_video_filters(OptionsContext *o, const char *opt, const char *arg
|
|||||||
return parse_option(o, "filter:v", arg, options);
|
return parse_option(o, "filter:v", arg, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int opt_vsync(const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR;
|
||||||
|
else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR;
|
||||||
|
else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
|
||||||
|
|
||||||
|
if (video_sync_method == VSYNC_AUTO)
|
||||||
|
video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(OptionsContext, x)
|
#define OFFSET(x) offsetof(OptionsContext, x)
|
||||||
static const OptionDef options[] = {
|
static const OptionDef options[] = {
|
||||||
/* main options */
|
/* main options */
|
||||||
@ -4457,7 +4473,7 @@ static const OptionDef options[] = {
|
|||||||
"when dumping packets, also dump the payload" },
|
"when dumping packets, also dump the payload" },
|
||||||
{ "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(rate_emu)}, "read input at native frame rate", "" },
|
{ "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(rate_emu)}, "read input at native frame rate", "" },
|
||||||
{ "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
|
{ "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
|
||||||
{ "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
|
{ "vsync", HAS_ARG | OPT_EXPERT, {(void*)opt_vsync}, "video sync method", "" },
|
||||||
{ "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
|
{ "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
|
||||||
{ "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" },
|
{ "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" },
|
||||||
{ "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" },
|
{ "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" },
|
||||||
|
3
configure
vendored
3
configure
vendored
@ -1226,6 +1226,7 @@ HAVE_LIST="
|
|||||||
struct_sockaddr_in6
|
struct_sockaddr_in6
|
||||||
struct_sockaddr_sa_len
|
struct_sockaddr_sa_len
|
||||||
struct_sockaddr_storage
|
struct_sockaddr_storage
|
||||||
|
struct_v4l2_frmivalenum_discrete
|
||||||
symver
|
symver
|
||||||
symver_asm_label
|
symver_asm_label
|
||||||
symver_gnu_asm
|
symver_gnu_asm
|
||||||
@ -3174,6 +3175,8 @@ makeinfo --version > /dev/null 2>&1 && enable makeinfo || disable makeinfo
|
|||||||
check_header linux/fb.h
|
check_header linux/fb.h
|
||||||
check_header linux/videodev.h
|
check_header linux/videodev.h
|
||||||
check_header linux/videodev2.h
|
check_header linux/videodev2.h
|
||||||
|
check_struct linux/videodev2.h "struct v4l2_frmivalenum" discrete
|
||||||
|
|
||||||
check_header sys/videoio.h
|
check_header sys/videoio.h
|
||||||
|
|
||||||
check_func_headers "windows.h vfw.h" capCreateCaptureWindow "$vfwcap_indev_extralibs"
|
check_func_headers "windows.h vfw.h" capCreateCaptureWindow "$vfwcap_indev_extralibs"
|
||||||
|
@ -174,6 +174,10 @@ API changes, most recent first:
|
|||||||
2011-08-14 - 323b930 - lavu 51.12.0
|
2011-08-14 - 323b930 - lavu 51.12.0
|
||||||
Add av_fifo_peek2(), deprecate av_fifo_peek().
|
Add av_fifo_peek2(), deprecate av_fifo_peek().
|
||||||
|
|
||||||
|
2011-08-26 - lavu 51.9.0
|
||||||
|
- add41de..abc78a5 Do not include intfloat_readwrite.h,
|
||||||
|
mathematics.h, rational.h, pixfmt.h, or log.h from avutil.h.
|
||||||
|
|
||||||
2011-08-16 - 48f9e45 - lavf 53.8.0
|
2011-08-16 - 48f9e45 - lavf 53.8.0
|
||||||
Add avformat_query_codec().
|
Add avformat_query_codec().
|
||||||
|
|
||||||
|
@ -749,15 +749,15 @@ Thread count.
|
|||||||
Video sync method.
|
Video sync method.
|
||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
@item 0
|
@item passthrough
|
||||||
Each frame is passed with its timestamp from the demuxer to the muxer.
|
Each frame is passed with its timestamp from the demuxer to the muxer.
|
||||||
@item 1
|
@item cfr
|
||||||
Frames will be duplicated and dropped to achieve exactly the requested
|
Frames will be duplicated and dropped to achieve exactly the requested
|
||||||
constant framerate.
|
constant framerate.
|
||||||
@item 2
|
@item vfr
|
||||||
Frames are passed through with their timestamp or dropped so as to
|
Frames are passed through with their timestamp or dropped so as to
|
||||||
prevent 2 frames from having the same timestamp.
|
prevent 2 frames from having the same timestamp.
|
||||||
@item -1
|
@item auto
|
||||||
Chooses between 1 and 2 depending on muxer capabilities. This is the
|
Chooses between 1 and 2 depending on muxer capabilities. This is the
|
||||||
default method.
|
default method.
|
||||||
@end table
|
@end table
|
||||||
|
@ -134,7 +134,7 @@ library:
|
|||||||
@item Brute Force & Ignorance @tab @tab X
|
@item Brute Force & Ignorance @tab @tab X
|
||||||
@tab Used in the game Flash Traffic: City of Angels.
|
@tab Used in the game Flash Traffic: City of Angels.
|
||||||
@item BWF @tab X @tab X
|
@item BWF @tab X @tab X
|
||||||
@item CRI ADX @tab @tab X
|
@item CRI ADX @tab X @tab X
|
||||||
@tab Audio-only format used in console video games.
|
@tab Audio-only format used in console video games.
|
||||||
@item Discworld II BMV @tab @tab X
|
@item Discworld II BMV @tab @tab X
|
||||||
@item Interplay C93 @tab @tab X
|
@item Interplay C93 @tab @tab X
|
||||||
|
@ -517,7 +517,7 @@ the device.
|
|||||||
Video4Linux and Video4Linux2 devices only support a limited set of
|
Video4Linux and Video4Linux2 devices only support a limited set of
|
||||||
@var{width}x@var{height} sizes and framerates. You can check which are
|
@var{width}x@var{height} sizes and framerates. You can check which are
|
||||||
supported for example with the command @command{dov4l} for Video4Linux
|
supported for example with the command @command{dov4l} for Video4Linux
|
||||||
devices and the command @command{v4l-info} for Video4Linux2 devices.
|
devices and using @command{-list_formats all} for Video4Linux2 devices.
|
||||||
|
|
||||||
If the size for the device is set to 0x0, the input device will
|
If the size for the device is set to 0x0, the input device will
|
||||||
try to auto-detect the size to use.
|
try to auto-detect the size to use.
|
||||||
|
28
ffmpeg.c
28
ffmpeg.c
@ -93,6 +93,11 @@
|
|||||||
|
|
||||||
#include "libavutil/avassert.h"
|
#include "libavutil/avassert.h"
|
||||||
|
|
||||||
|
#define VSYNC_AUTO -1
|
||||||
|
#define VSYNC_PASSTHROUGH 0
|
||||||
|
#define VSYNC_CFR 1
|
||||||
|
#define VSYNC_VFR 2
|
||||||
|
|
||||||
const char program_name[] = "ffmpeg";
|
const char program_name[] = "ffmpeg";
|
||||||
const int program_birth_year = 2000;
|
const int program_birth_year = 2000;
|
||||||
|
|
||||||
@ -144,7 +149,7 @@ static int do_pkt_dump = 0;
|
|||||||
static int do_psnr = 0;
|
static int do_psnr = 0;
|
||||||
static int do_pass = 0;
|
static int do_pass = 0;
|
||||||
static const char *pass_logfilename_prefix;
|
static const char *pass_logfilename_prefix;
|
||||||
static int video_sync_method = -1;
|
static int video_sync_method = VSYNC_AUTO;
|
||||||
static int audio_sync_method = 0;
|
static int audio_sync_method = 0;
|
||||||
static float audio_drift_threshold = 0.1;
|
static float audio_drift_threshold = 0.1;
|
||||||
static int copy_ts = 0;
|
static int copy_ts = 0;
|
||||||
@ -1433,15 +1438,15 @@ static void do_video_out(AVFormatContext *s,
|
|||||||
*frame_size = 0;
|
*frame_size = 0;
|
||||||
|
|
||||||
format_video_sync = video_sync_method;
|
format_video_sync = video_sync_method;
|
||||||
if (format_video_sync < 0)
|
if (format_video_sync == VSYNC_AUTO)
|
||||||
format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? 0 : 2) : 1;
|
format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : 1;
|
||||||
|
|
||||||
if (format_video_sync) {
|
if (format_video_sync != VSYNC_PASSTHROUGH) {
|
||||||
double vdelta = sync_ipts - ost->sync_opts + duration;
|
double vdelta = sync_ipts - ost->sync_opts + duration;
|
||||||
// FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
|
// FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
|
||||||
if (vdelta < -1.1)
|
if (vdelta < -1.1)
|
||||||
nb_frames = 0;
|
nb_frames = 0;
|
||||||
else if (format_video_sync == 2) {
|
else if (format_video_sync == VSYNC_VFR) {
|
||||||
if (vdelta <= -0.6) {
|
if (vdelta <= -0.6) {
|
||||||
nb_frames = 0;
|
nb_frames = 0;
|
||||||
} else if (vdelta > 0.6)
|
} else if (vdelta > 0.6)
|
||||||
@ -4873,6 +4878,17 @@ static int opt_video_filters(OptionsContext *o, const char *opt, const char *arg
|
|||||||
return parse_option(o, "filter:v", arg, options);
|
return parse_option(o, "filter:v", arg, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int opt_vsync(const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR;
|
||||||
|
else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR;
|
||||||
|
else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
|
||||||
|
|
||||||
|
if (video_sync_method == VSYNC_AUTO)
|
||||||
|
video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(OptionsContext, x)
|
#define OFFSET(x) offsetof(OptionsContext, x)
|
||||||
static const OptionDef options[] = {
|
static const OptionDef options[] = {
|
||||||
/* main options */
|
/* main options */
|
||||||
@ -4908,7 +4924,7 @@ static const OptionDef options[] = {
|
|||||||
{ "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "deprecated, use -loop" },
|
{ "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "deprecated, use -loop" },
|
||||||
{ "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "deprecated, use -loop", "" },
|
{ "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "deprecated, use -loop", "" },
|
||||||
{ "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
|
{ "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
|
||||||
{ "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
|
{ "vsync", HAS_ARG | OPT_EXPERT, {(void*)opt_vsync}, "video sync method", "" },
|
||||||
{ "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
|
{ "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
|
||||||
{ "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" },
|
{ "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" },
|
||||||
{ "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" },
|
{ "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" },
|
||||||
|
@ -165,6 +165,13 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
return buf - avpkt->data;
|
return buf - avpkt->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void adx_decode_flush(AVCodecContext *avctx)
|
||||||
|
{
|
||||||
|
ADXContext *c = avctx->priv_data;
|
||||||
|
memset(c->prev, 0, sizeof(c->prev));
|
||||||
|
c->eof = 0;
|
||||||
|
}
|
||||||
|
|
||||||
AVCodec ff_adpcm_adx_decoder = {
|
AVCodec ff_adpcm_adx_decoder = {
|
||||||
.name = "adpcm_adx",
|
.name = "adpcm_adx",
|
||||||
.type = AVMEDIA_TYPE_AUDIO,
|
.type = AVMEDIA_TYPE_AUDIO,
|
||||||
@ -172,6 +179,7 @@ AVCodec ff_adpcm_adx_decoder = {
|
|||||||
.priv_data_size = sizeof(ADXContext),
|
.priv_data_size = sizeof(ADXContext),
|
||||||
.init = adx_decode_init,
|
.init = adx_decode_init,
|
||||||
.decode = adx_decode_frame,
|
.decode = adx_decode_frame,
|
||||||
|
.flush = adx_decode_flush,
|
||||||
.capabilities = CODEC_CAP_DR1,
|
.capabilities = CODEC_CAP_DR1,
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
|
.long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
|
||||||
};
|
};
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libavutil/intreadwrite.h"
|
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#include "adx.h"
|
#include "adx.h"
|
||||||
|
#include "bytestream.h"
|
||||||
#include "put_bits.h"
|
#include "put_bits.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,165 +33,133 @@
|
|||||||
* adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
|
* adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 18 bytes <-> 32 samples */
|
static void adx_encode(ADXContext *c, uint8_t *adx, const int16_t *wav,
|
||||||
|
ADXChannelState *prev, int channels)
|
||||||
static void adx_encode(ADXContext *c, unsigned char *adx, const short *wav,
|
|
||||||
ADXChannelState *prev)
|
|
||||||
{
|
{
|
||||||
PutBitContext pb;
|
PutBitContext pb;
|
||||||
int scale;
|
int scale;
|
||||||
int i;
|
int i, j;
|
||||||
int s0, s1, s2, d;
|
int s0, s1, s2, d;
|
||||||
int max = 0;
|
int max = 0;
|
||||||
int min = 0;
|
int min = 0;
|
||||||
int data[32];
|
int data[BLOCK_SAMPLES];
|
||||||
|
|
||||||
s1 = prev->s1;
|
s1 = prev->s1;
|
||||||
s2 = prev->s2;
|
s2 = prev->s2;
|
||||||
for(i=0;i<32;i++) {
|
for (i = 0, j = 0; j < 32; i += channels, j++) {
|
||||||
s0 = wav[i];
|
s0 = wav[i];
|
||||||
d = ((s0 << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS;
|
d = ((s0 << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS;
|
||||||
data[i]=d;
|
data[j] = d;
|
||||||
if (max<d) max=d;
|
if (max < d)
|
||||||
if (min>d) min=d;
|
max = d;
|
||||||
|
if (min > d)
|
||||||
|
min = d;
|
||||||
s2 = s1;
|
s2 = s1;
|
||||||
s1 = s0;
|
s1 = s0;
|
||||||
}
|
}
|
||||||
prev->s1 = s1;
|
prev->s1 = s1;
|
||||||
prev->s2 = s2;
|
prev->s2 = s2;
|
||||||
|
|
||||||
/* -8..+7 */
|
|
||||||
|
|
||||||
if (max == 0 && min == 0) {
|
if (max == 0 && min == 0) {
|
||||||
memset(adx,0,18);
|
memset(adx, 0, BLOCK_SIZE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max/7>-min/8) scale = max/7;
|
if (max / 7 > -min / 8)
|
||||||
else scale = -min/8;
|
scale = max / 7;
|
||||||
|
else
|
||||||
|
scale = -min / 8;
|
||||||
|
|
||||||
if (scale==0) scale=1;
|
if (scale == 0)
|
||||||
|
scale = 1;
|
||||||
|
|
||||||
AV_WB16(adx, scale);
|
AV_WB16(adx, scale);
|
||||||
|
|
||||||
init_put_bits(&pb, adx + 2, 16);
|
init_put_bits(&pb, adx + 2, 16);
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < BLOCK_SAMPLES; i++)
|
||||||
put_sbits(&pb, 4, av_clip(data[i] / scale, -8, 7));
|
put_sbits(&pb, 4, av_clip(data[i] / scale, -8, 7));
|
||||||
flush_put_bits(&pb);
|
flush_put_bits(&pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize)
|
#define HEADER_SIZE 36
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
struct {
|
|
||||||
uint32_t offset; /* 0x80000000 + sample start - 4 */
|
|
||||||
unsigned char unknown1[3]; /* 03 12 04 */
|
|
||||||
unsigned char channel; /* 1 or 2 */
|
|
||||||
uint32_t freq;
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t unknown2; /* 01 f4 03 00 */
|
|
||||||
uint32_t unknown3; /* 00 00 00 00 */
|
|
||||||
uint32_t unknown4; /* 00 00 00 00 */
|
|
||||||
|
|
||||||
/* if loop
|
static int adx_encode_header(AVCodecContext *avctx, uint8_t *buf, int bufsize)
|
||||||
unknown3 00 15 00 01
|
{
|
||||||
unknown4 00 00 00 01
|
|
||||||
long loop_start_sample;
|
|
||||||
long loop_start_byte;
|
|
||||||
long loop_end_sample;
|
|
||||||
long loop_end_byte;
|
|
||||||
long
|
|
||||||
*/
|
|
||||||
} adxhdr; /* big endian */
|
|
||||||
/* offset-6 "(c)CRI" */
|
|
||||||
#endif
|
|
||||||
ADXContext *c = avctx->priv_data;
|
ADXContext *c = avctx->priv_data;
|
||||||
|
|
||||||
AV_WB32(buf+0x00,0x80000000|0x20);
|
if (bufsize < HEADER_SIZE)
|
||||||
AV_WB32(buf+0x04,0x03120400|avctx->channels);
|
return AVERROR(EINVAL);
|
||||||
AV_WB32(buf+0x08,avctx->sample_rate);
|
|
||||||
AV_WB32(buf+0x0c,0); /* FIXME: set after */
|
bytestream_put_be16(&buf, 0x8000); /* header signature */
|
||||||
AV_WB16(buf + 0x10, c->cutoff);
|
bytestream_put_be16(&buf, HEADER_SIZE - 4); /* copyright offset */
|
||||||
AV_WB32(buf + 0x12, 0x03000000);
|
bytestream_put_byte(&buf, 3); /* encoding */
|
||||||
AV_WB32(buf + 0x16, 0x00000000);
|
bytestream_put_byte(&buf, BLOCK_SIZE); /* block size */
|
||||||
AV_WB32(buf + 0x1a, 0x00000000);
|
bytestream_put_byte(&buf, 4); /* sample size */
|
||||||
memcpy (buf + 0x1e, "(c)CRI", 6);
|
bytestream_put_byte(&buf, avctx->channels); /* channels */
|
||||||
return 0x20+4;
|
bytestream_put_be32(&buf, avctx->sample_rate); /* sample rate */
|
||||||
|
bytestream_put_be32(&buf, 0); /* total sample count */
|
||||||
|
bytestream_put_be16(&buf, c->cutoff); /* cutoff frequency */
|
||||||
|
bytestream_put_byte(&buf, 3); /* version */
|
||||||
|
bytestream_put_byte(&buf, 0); /* flags */
|
||||||
|
bytestream_put_be32(&buf, 0); /* unknown */
|
||||||
|
bytestream_put_be32(&buf, 0); /* loop enabled */
|
||||||
|
bytestream_put_be16(&buf, 0); /* padding */
|
||||||
|
bytestream_put_buffer(&buf, "(c)CRI", 6); /* copyright signature */
|
||||||
|
|
||||||
|
return HEADER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_cold int adx_encode_init(AVCodecContext *avctx)
|
static av_cold int adx_encode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
ADXContext *c = avctx->priv_data;
|
ADXContext *c = avctx->priv_data;
|
||||||
|
|
||||||
if (avctx->channels > 2)
|
if (avctx->channels > 2) {
|
||||||
return -1; /* only stereo or mono =) */
|
av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
|
||||||
avctx->frame_size = 32;
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
avctx->frame_size = BLOCK_SAMPLES;
|
||||||
|
|
||||||
avctx->coded_frame = avcodec_alloc_frame();
|
avctx->coded_frame = avcodec_alloc_frame();
|
||||||
avctx->coded_frame->key_frame= 1;
|
|
||||||
|
|
||||||
// avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32;
|
|
||||||
|
|
||||||
/* the cutoff can be adjusted, but this seems to work pretty well */
|
/* the cutoff can be adjusted, but this seems to work pretty well */
|
||||||
c->cutoff = 500;
|
c->cutoff = 500;
|
||||||
ff_adx_calculate_coeffs(c->cutoff, avctx->sample_rate, COEFF_BITS, c->coeff);
|
ff_adx_calculate_coeffs(c->cutoff, avctx->sample_rate, COEFF_BITS, c->coeff);
|
||||||
|
|
||||||
av_log(avctx, AV_LOG_DEBUG, "adx encode init\n");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_cold int adx_encode_close(AVCodecContext *avctx)
|
static av_cold int adx_encode_close(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
av_freep(&avctx->coded_frame);
|
av_freep(&avctx->coded_frame);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int adx_encode_frame(AVCodecContext *avctx,
|
static int adx_encode_frame(AVCodecContext *avctx, uint8_t *frame,
|
||||||
uint8_t *frame, int buf_size, void *data)
|
int buf_size, void *data)
|
||||||
{
|
{
|
||||||
ADXContext *c = avctx->priv_data;
|
ADXContext *c = avctx->priv_data;
|
||||||
const short *samples = data;
|
const int16_t *samples = data;
|
||||||
unsigned char *dst = frame;
|
uint8_t *dst = frame;
|
||||||
int rest = avctx->frame_size;
|
int ch;
|
||||||
|
|
||||||
/*
|
|
||||||
input data size =
|
|
||||||
ffmpeg.c: do_audio_out()
|
|
||||||
frame_bytes = enc->frame_size * 2 * enc->channels;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// printf("sz=%d ",buf_size); fflush(stdout);
|
|
||||||
if (!c->header_parsed) {
|
if (!c->header_parsed) {
|
||||||
int hdrsize = adx_encode_header(avctx,dst,buf_size);
|
int hdrsize;
|
||||||
|
if ((hdrsize = adx_encode_header(avctx, dst, buf_size)) < 0) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
dst += hdrsize;
|
dst += hdrsize;
|
||||||
|
buf_size -= hdrsize;
|
||||||
c->header_parsed = 1;
|
c->header_parsed = 1;
|
||||||
}
|
}
|
||||||
|
if (buf_size < BLOCK_SIZE * avctx->channels) {
|
||||||
if (avctx->channels==1) {
|
av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
|
||||||
while(rest>=32) {
|
return AVERROR(EINVAL);
|
||||||
adx_encode(c, dst, samples, c->prev);
|
|
||||||
dst+=18;
|
|
||||||
samples+=32;
|
|
||||||
rest-=32;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while(rest>=32*2) {
|
|
||||||
short tmpbuf[32*2];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=0;i<32;i++) {
|
|
||||||
tmpbuf[i] = samples[i*2];
|
|
||||||
tmpbuf[i+32] = samples[i*2+1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
adx_encode(c, dst, tmpbuf, c->prev);
|
for (ch = 0; ch < avctx->channels; ch++) {
|
||||||
adx_encode(c, dst + 18, tmpbuf + 32, c->prev + 1);
|
adx_encode(c, dst, samples + ch, &c->prev[ch], avctx->channels);
|
||||||
dst+=18*2;
|
dst += BLOCK_SIZE;
|
||||||
samples+=32*2;
|
|
||||||
rest-=32*2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return dst - frame;
|
return dst - frame;
|
||||||
}
|
}
|
||||||
@ -204,6 +172,7 @@ AVCodec ff_adpcm_adx_encoder = {
|
|||||||
.init = adx_encode_init,
|
.init = adx_encode_init,
|
||||||
.encode = adx_encode_frame,
|
.encode = adx_encode_frame,
|
||||||
.close = adx_encode_close,
|
.close = adx_encode_close,
|
||||||
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
|
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
|
||||||
|
AV_SAMPLE_FMT_NONE },
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
|
.long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
|
||||||
};
|
};
|
||||||
|
@ -25,12 +25,9 @@
|
|||||||
|
|
||||||
void ff_rv34_inv_transform_neon(DCTELEM *block);
|
void ff_rv34_inv_transform_neon(DCTELEM *block);
|
||||||
void ff_rv34_inv_transform_noround_neon(DCTELEM *block);
|
void ff_rv34_inv_transform_noround_neon(DCTELEM *block);
|
||||||
void ff_rv34_dequant4x4_neon(DCTELEM *block, int Qdc, int Q);
|
|
||||||
|
|
||||||
void ff_rv34dsp_init_neon(RV34DSPContext *c, DSPContext* dsp)
|
void ff_rv34dsp_init_neon(RV34DSPContext *c, DSPContext* dsp)
|
||||||
{
|
{
|
||||||
c->rv34_inv_transform_tab[0] = ff_rv34_inv_transform_neon;
|
c->rv34_inv_transform_tab[0] = ff_rv34_inv_transform_neon;
|
||||||
c->rv34_inv_transform_tab[1] = ff_rv34_inv_transform_noround_neon;
|
c->rv34_inv_transform_tab[1] = ff_rv34_inv_transform_noround_neon;
|
||||||
|
|
||||||
c->rv34_dequant4x4 = ff_rv34_dequant4x4_neon;
|
|
||||||
}
|
}
|
||||||
|
@ -107,27 +107,3 @@ function ff_rv34_inv_transform_noround_neon, export=1
|
|||||||
vst4.16 {d0[3], d1[3], d2[3], d3[3]}, [r2,:64], r1
|
vst4.16 {d0[3], d1[3], d2[3], d3[3]}, [r2,:64], r1
|
||||||
bx lr
|
bx lr
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
function ff_rv34_dequant4x4_neon, export=1
|
|
||||||
mov r3, r0
|
|
||||||
mov r12, #16
|
|
||||||
vdup.16 q0, r2
|
|
||||||
vmov.16 d0[0], r1
|
|
||||||
vld1.16 {d2}, [r0,:64], r12
|
|
||||||
vld1.16 {d4}, [r0,:64], r12
|
|
||||||
vld1.16 {d6}, [r0,:64], r12
|
|
||||||
vld1.16 {d16}, [r0,:64], r12
|
|
||||||
vmull.s16 q1, d2, d0
|
|
||||||
vmull.s16 q2, d4, d1
|
|
||||||
vmull.s16 q3, d6, d1
|
|
||||||
vmull.s16 q8, d16, d1
|
|
||||||
vqrshrn.s32 d2, q1, #4
|
|
||||||
vqrshrn.s32 d4, q2, #4
|
|
||||||
vqrshrn.s32 d6, q3, #4
|
|
||||||
vqrshrn.s32 d16, q8, #4
|
|
||||||
vst1.16 {d2}, [r3,:64], r12
|
|
||||||
vst1.16 {d4}, [r3,:64], r12
|
|
||||||
vst1.16 {d6}, [r3,:64], r12
|
|
||||||
vst1.16 {d16}, [r3,:64], r12
|
|
||||||
bx lr
|
|
||||||
endfunc
|
|
||||||
|
@ -39,11 +39,15 @@ static av_always_inline void bytestream_put_ ##name(uint8_t **b, const type valu
|
|||||||
write(*b, value);\
|
write(*b, value);\
|
||||||
(*b) += bytes;\
|
(*b) += bytes;\
|
||||||
}\
|
}\
|
||||||
|
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)\
|
static av_always_inline type bytestream2_get_ ## name(GetByteContext *g)\
|
||||||
{\
|
{\
|
||||||
if (g->buffer_end - g->buffer < bytes)\
|
if (g->buffer_end - g->buffer < bytes)\
|
||||||
return 0;\
|
return 0;\
|
||||||
return bytestream_get_ ## name(&g->buffer);\
|
return bytestream2_get_ ## name ## u(g);\
|
||||||
}\
|
}\
|
||||||
static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g)\
|
static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g)\
|
||||||
{\
|
{\
|
||||||
|
@ -109,10 +109,6 @@ void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){
|
|||||||
c->low= 0;
|
c->low= 0;
|
||||||
c->range= 0x1FE;
|
c->range= 0x1FE;
|
||||||
c->outstanding_count= 0;
|
c->outstanding_count= 0;
|
||||||
#ifdef STRICT_LIMITS
|
|
||||||
c->sym_count =0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
c->pb.bit_left++; //avoids firstBitFlag
|
c->pb.bit_left++; //avoids firstBitFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,10 +179,6 @@ static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
|
|||||||
}
|
}
|
||||||
|
|
||||||
renorm_cabac_encoder(c);
|
renorm_cabac_encoder(c);
|
||||||
|
|
||||||
#ifdef STRICT_LIMITS
|
|
||||||
c->symCount++;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,10 +200,6 @@ static void put_cabac_bypass(CABACContext *c, int bit){
|
|||||||
put_cabac_bit(c, 1);
|
put_cabac_bit(c, 1);
|
||||||
c->low -= 0x400;
|
c->low -= 0x400;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STRICT_LIMITS
|
|
||||||
c->symCount++;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -236,10 +224,6 @@ static int put_cabac_terminate(CABACContext *c, int bit){
|
|||||||
flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
|
flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STRICT_LIMITS
|
|
||||||
c->symCount++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (put_bits_count(&c->pb)+7)>>3;
|
return (put_bits_count(&c->pb)+7)>>3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,21 +349,6 @@ START_TIMER
|
|||||||
av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
|
av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
|
||||||
STOP_TIMER("get_cabac")
|
STOP_TIMER("get_cabac")
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
for(i=0; i<SIZE; i++){
|
|
||||||
START_TIMER
|
|
||||||
if( r[i] != get_cabac_u(&c, state, (i&1) ? 6 : 7, 3, i&1) )
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i);
|
|
||||||
STOP_TIMER("get_cabac_u")
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0; i<SIZE; i++){
|
|
||||||
START_TIMER
|
|
||||||
if( r[i] != get_cabac_ueg(&c, state, 3, 0, 1, 2))
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i);
|
|
||||||
STOP_TIMER("get_cabac_ueg")
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(!get_cabac_terminate(&c))
|
if(!get_cabac_terminate(&c))
|
||||||
av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
|
av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
|
||||||
|
|
||||||
|
@ -41,9 +41,6 @@ typedef struct CABACContext{
|
|||||||
int low;
|
int low;
|
||||||
int range;
|
int range;
|
||||||
int outstanding_count;
|
int outstanding_count;
|
||||||
#ifdef STRICT_LIMITS
|
|
||||||
int symCount;
|
|
||||||
#endif
|
|
||||||
const uint8_t *bytestream_start;
|
const uint8_t *bytestream_start;
|
||||||
const uint8_t *bytestream;
|
const uint8_t *bytestream;
|
||||||
const uint8_t *bytestream_end;
|
const uint8_t *bytestream_end;
|
||||||
@ -216,62 +213,4 @@ static int av_unused get_cabac_terminate(CABACContext *c){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/**
|
|
||||||
* Get (truncated) unary binarization.
|
|
||||||
*/
|
|
||||||
static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=0; i<max; i++){
|
|
||||||
if(get_cabac(c, state)==0)
|
|
||||||
return i;
|
|
||||||
|
|
||||||
if(i< max_index) state++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return truncated ? max : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get unary exp golomb k-th order binarization.
|
|
||||||
*/
|
|
||||||
static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){
|
|
||||||
int i, v;
|
|
||||||
int m= 1<<k;
|
|
||||||
|
|
||||||
if(get_cabac(c, state)==0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(0 < max_index) state++;
|
|
||||||
|
|
||||||
for(i=1; i<max; i++){
|
|
||||||
if(get_cabac(c, state)==0){
|
|
||||||
if(is_signed && get_cabac_bypass(c)){
|
|
||||||
return -i;
|
|
||||||
}else
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i < max_index) state++;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(get_cabac_bypass(c)){
|
|
||||||
i+= m;
|
|
||||||
m+= m;
|
|
||||||
}
|
|
||||||
|
|
||||||
v=0;
|
|
||||||
while(m>>=1){
|
|
||||||
v+= v + get_cabac_bypass(c);
|
|
||||||
}
|
|
||||||
i += v;
|
|
||||||
|
|
||||||
if(is_signed && get_cabac_bypass(c)){
|
|
||||||
return -i;
|
|
||||||
}else
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
#endif /* 0 */
|
|
||||||
|
|
||||||
#endif /* AVCODEC_CABAC_H */
|
#endif /* AVCODEC_CABAC_H */
|
||||||
|
@ -578,9 +578,8 @@ static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, int jobnr, int
|
|||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
DCTELEM *block = ctx->blocks[i];
|
DCTELEM *block = ctx->blocks[i];
|
||||||
int last_index, overflow;
|
int overflow, n = dnxhd_switch_matrix(ctx, i);
|
||||||
int n = dnxhd_switch_matrix(ctx, i);
|
int last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow);
|
||||||
last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow);
|
|
||||||
//START_TIMER;
|
//START_TIMER;
|
||||||
dnxhd_encode_block(ctx, block, last_index, n);
|
dnxhd_encode_block(ctx, block, last_index, n);
|
||||||
//STOP_TIMER("encode_block");
|
//STOP_TIMER("encode_block");
|
||||||
|
@ -4051,7 +4051,7 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
H264Context *h = avctx->priv_data;
|
H264Context *h = avctx->priv_data;
|
||||||
MpegEncContext *s = &h->s;
|
MpegEncContext *s = &h->s;
|
||||||
AVFrame *pict = data;
|
AVFrame *pict = data;
|
||||||
int buf_index;
|
int buf_index = 0;
|
||||||
Picture *out;
|
Picture *out;
|
||||||
int i, out_idx;
|
int i, out_idx;
|
||||||
|
|
||||||
@ -4081,7 +4081,7 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
*pict= *(AVFrame*)out;
|
*pict= *(AVFrame*)out;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf_size;
|
return buf_index;
|
||||||
}
|
}
|
||||||
if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){
|
if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){
|
||||||
int cnt= buf[5]&0x1f;
|
int cnt= buf[5]&0x1f;
|
||||||
@ -4112,7 +4112,6 @@ not_extra:
|
|||||||
|
|
||||||
if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
|
if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
|
||||||
av_assert0(buf_index <= buf_size);
|
av_assert0(buf_index <= buf_size);
|
||||||
buf_size = buf_index;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4193,9 +4192,7 @@ int main(void){
|
|||||||
|
|
||||||
init_get_bits(&gb, temp, 8*SIZE);
|
init_get_bits(&gb, temp, 8*SIZE);
|
||||||
for(i=0; i<COUNT; i++){
|
for(i=0; i<COUNT; i++){
|
||||||
int j, s;
|
int j, s = show_bits(&gb, 24);
|
||||||
|
|
||||||
s= show_bits(&gb, 24);
|
|
||||||
|
|
||||||
{START_TIMER
|
{START_TIMER
|
||||||
j= get_ue_golomb(&gb);
|
j= get_ue_golomb(&gb);
|
||||||
@ -4218,9 +4215,7 @@ int main(void){
|
|||||||
|
|
||||||
init_get_bits(&gb, temp, 8*SIZE);
|
init_get_bits(&gb, temp, 8*SIZE);
|
||||||
for(i=0; i<COUNT; i++){
|
for(i=0; i<COUNT; i++){
|
||||||
int j, s;
|
int j, s = show_bits(&gb, 24);
|
||||||
|
|
||||||
s= show_bits(&gb, 24);
|
|
||||||
|
|
||||||
{START_TIMER
|
{START_TIMER
|
||||||
j= get_se_golomb(&gb);
|
j= get_se_golomb(&gb);
|
||||||
|
@ -760,7 +760,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
|
|||||||
|
|
||||||
switch_buffers(ctx);
|
switch_buffers(ctx);
|
||||||
|
|
||||||
//START_TIMER;
|
//{ START_TIMER;
|
||||||
|
|
||||||
if (ctx->frame_type != FRAMETYPE_NULL) {
|
if (ctx->frame_type != FRAMETYPE_NULL) {
|
||||||
for (p = 0; p < 3; p++) {
|
for (p = 0; p < 3; p++) {
|
||||||
@ -775,7 +775,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//STOP_TIMER("decode_planes");
|
//STOP_TIMER("decode_planes"); }
|
||||||
|
|
||||||
if (ctx->frame.data[0])
|
if (ctx->frame.data[0])
|
||||||
avctx->release_buffer(avctx, &ctx->frame);
|
avctx->release_buffer(avctx, &ctx->frame);
|
||||||
|
@ -83,7 +83,8 @@ typedef struct {
|
|||||||
int abr; ///< flag to enable ABR
|
int abr; ///< flag to enable ABR
|
||||||
int pkt_frame_count; ///< frame count for the current packet
|
int pkt_frame_count; ///< frame count for the current packet
|
||||||
int lookahead; ///< encoder delay
|
int lookahead; ///< encoder delay
|
||||||
int sample_count; ///< total sample count (used for pts)
|
int64_t next_pts; ///< next pts, in sample_rate time base
|
||||||
|
int pkt_sample_count; ///< sample count in the current packet
|
||||||
} LibSpeexEncContext;
|
} LibSpeexEncContext;
|
||||||
|
|
||||||
static av_cold void print_enc_params(AVCodecContext *avctx,
|
static av_cold void print_enc_params(AVCodecContext *avctx,
|
||||||
@ -201,7 +202,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
|
|||||||
|
|
||||||
/* set encoding delay */
|
/* set encoding delay */
|
||||||
speex_encoder_ctl(s->enc_state, SPEEX_GET_LOOKAHEAD, &s->lookahead);
|
speex_encoder_ctl(s->enc_state, SPEEX_GET_LOOKAHEAD, &s->lookahead);
|
||||||
s->sample_count = -s->lookahead;
|
s->next_pts = -s->lookahead;
|
||||||
|
|
||||||
/* create header packet bytes from header struct */
|
/* create header packet bytes from header struct */
|
||||||
/* note: libspeex allocates the memory for header_data, which is freed
|
/* note: libspeex allocates the memory for header_data, which is freed
|
||||||
@ -235,7 +236,6 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size,
|
|||||||
{
|
{
|
||||||
LibSpeexEncContext *s = avctx->priv_data;
|
LibSpeexEncContext *s = avctx->priv_data;
|
||||||
int16_t *samples = data;
|
int16_t *samples = data;
|
||||||
int sample_count = s->sample_count;
|
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
/* encode Speex frame */
|
/* encode Speex frame */
|
||||||
@ -243,7 +243,7 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size,
|
|||||||
speex_encode_stereo_int(samples, s->header.frame_size, &s->bits);
|
speex_encode_stereo_int(samples, s->header.frame_size, &s->bits);
|
||||||
speex_encode_int(s->enc_state, samples, &s->bits);
|
speex_encode_int(s->enc_state, samples, &s->bits);
|
||||||
s->pkt_frame_count++;
|
s->pkt_frame_count++;
|
||||||
s->sample_count += avctx->frame_size;
|
s->pkt_sample_count += avctx->frame_size;
|
||||||
} else {
|
} else {
|
||||||
/* handle end-of-stream */
|
/* handle end-of-stream */
|
||||||
if (!s->pkt_frame_count)
|
if (!s->pkt_frame_count)
|
||||||
@ -259,8 +259,10 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size,
|
|||||||
if (s->pkt_frame_count == s->frames_per_packet) {
|
if (s->pkt_frame_count == s->frames_per_packet) {
|
||||||
s->pkt_frame_count = 0;
|
s->pkt_frame_count = 0;
|
||||||
avctx->coded_frame->pts =
|
avctx->coded_frame->pts =
|
||||||
av_rescale_q(sample_count, (AVRational){ 1, avctx->sample_rate },
|
av_rescale_q(s->next_pts, (AVRational){ 1, avctx->sample_rate },
|
||||||
avctx->time_base);
|
avctx->time_base);
|
||||||
|
s->next_pts += s->pkt_sample_count;
|
||||||
|
s->pkt_sample_count = 0;
|
||||||
if (buf_size > speex_bits_nbytes(&s->bits)) {
|
if (buf_size > speex_bits_nbytes(&s->bits)) {
|
||||||
int ret = speex_bits_write(&s->bits, frame, buf_size);
|
int ret = speex_bits_write(&s->bits, frame, buf_size);
|
||||||
speex_bits_reset(&s->bits);
|
speex_bits_reset(&s->bits);
|
||||||
|
@ -212,7 +212,7 @@ static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table)
|
|||||||
/**
|
/**
|
||||||
* Get one coefficient value from the bistream and store it.
|
* Get one coefficient value from the bistream and store it.
|
||||||
*/
|
*/
|
||||||
static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc)
|
static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q)
|
||||||
{
|
{
|
||||||
if(coef){
|
if(coef){
|
||||||
if(coef == esc){
|
if(coef == esc){
|
||||||
@ -225,14 +225,14 @@ static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *
|
|||||||
}
|
}
|
||||||
if(get_bits1(gb))
|
if(get_bits1(gb))
|
||||||
coef = -coef;
|
coef = -coef;
|
||||||
*dst = coef;
|
*dst = (coef*q + 8) >> 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode 2x2 subblock of coefficients.
|
* Decode 2x2 subblock of coefficients.
|
||||||
*/
|
*/
|
||||||
static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc)
|
static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q)
|
||||||
{
|
{
|
||||||
int coeffs[4];
|
int coeffs[4];
|
||||||
|
|
||||||
@ -240,15 +240,35 @@ static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2,
|
|||||||
coeffs[1] = modulo_three_table[code][1];
|
coeffs[1] = modulo_three_table[code][1];
|
||||||
coeffs[2] = modulo_three_table[code][2];
|
coeffs[2] = modulo_three_table[code][2];
|
||||||
coeffs[3] = modulo_three_table[code][3];
|
coeffs[3] = modulo_three_table[code][3];
|
||||||
decode_coeff(dst , coeffs[0], 3, gb, vlc);
|
decode_coeff(dst , coeffs[0], 3, gb, vlc, q);
|
||||||
if(is_block2){
|
if(is_block2){
|
||||||
decode_coeff(dst+8, coeffs[1], 2, gb, vlc);
|
decode_coeff(dst+8, coeffs[1], 2, gb, vlc, q);
|
||||||
decode_coeff(dst+1, coeffs[2], 2, gb, vlc);
|
decode_coeff(dst+1, coeffs[2], 2, gb, vlc, q);
|
||||||
}else{
|
}else{
|
||||||
decode_coeff(dst+1, coeffs[1], 2, gb, vlc);
|
decode_coeff(dst+1, coeffs[1], 2, gb, vlc, q);
|
||||||
decode_coeff(dst+8, coeffs[2], 2, gb, vlc);
|
decode_coeff(dst+8, coeffs[2], 2, gb, vlc, q);
|
||||||
}
|
}
|
||||||
decode_coeff(dst+9, coeffs[3], 2, gb, vlc);
|
decode_coeff(dst+9, coeffs[3], 2, gb, vlc, q);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void decode_subblock3(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc,
|
||||||
|
int q_dc, int q_ac1, int q_ac2)
|
||||||
|
{
|
||||||
|
int coeffs[4];
|
||||||
|
|
||||||
|
coeffs[0] = modulo_three_table[code][0];
|
||||||
|
coeffs[1] = modulo_three_table[code][1];
|
||||||
|
coeffs[2] = modulo_three_table[code][2];
|
||||||
|
coeffs[3] = modulo_three_table[code][3];
|
||||||
|
decode_coeff(dst , coeffs[0], 3, gb, vlc, q_dc);
|
||||||
|
if(is_block2){
|
||||||
|
decode_coeff(dst+8, coeffs[1], 2, gb, vlc, q_ac1);
|
||||||
|
decode_coeff(dst+1, coeffs[2], 2, gb, vlc, q_ac1);
|
||||||
|
}else{
|
||||||
|
decode_coeff(dst+1, coeffs[1], 2, gb, vlc, q_ac1);
|
||||||
|
decode_coeff(dst+8, coeffs[2], 2, gb, vlc, q_ac1);
|
||||||
|
}
|
||||||
|
decode_coeff(dst+9, coeffs[3], 2, gb, vlc, q_ac2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,7 +282,7 @@ static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2,
|
|||||||
* o--o
|
* o--o
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc)
|
static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc, int q_dc, int q_ac1, int q_ac2)
|
||||||
{
|
{
|
||||||
int code, pattern;
|
int code, pattern;
|
||||||
|
|
||||||
@ -271,39 +291,23 @@ static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *r
|
|||||||
pattern = code & 0x7;
|
pattern = code & 0x7;
|
||||||
|
|
||||||
code >>= 3;
|
code >>= 3;
|
||||||
decode_subblock(dst, code, 0, gb, &rvlc->coefficient);
|
decode_subblock3(dst, code, 0, gb, &rvlc->coefficient, q_dc, q_ac1, q_ac2);
|
||||||
|
|
||||||
if(pattern & 4){
|
if(pattern & 4){
|
||||||
code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
|
code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
|
||||||
decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient);
|
decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient, q_ac2);
|
||||||
}
|
}
|
||||||
if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block
|
if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block
|
||||||
code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
|
code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
|
||||||
decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient);
|
decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient, q_ac2);
|
||||||
}
|
}
|
||||||
if(pattern & 1){
|
if(pattern & 1){
|
||||||
code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
|
code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
|
||||||
decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient);
|
decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient, q_ac2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Dequantize 4x4 block of DC values for 16x16 macroblock.
|
|
||||||
* @todo optimize
|
|
||||||
*/
|
|
||||||
static inline void rv34_dequant4x4_16x16(DCTELEM *block, int Qdc, int Q)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i = 0; i < 3; i++)
|
|
||||||
block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Qdc + 8) >> 4;
|
|
||||||
for(; i < 16; i++)
|
|
||||||
block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Q + 8) >> 4;
|
|
||||||
}
|
|
||||||
/** @} */ //block functions
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name RV30/40 bitstream parsing
|
* @name RV30/40 bitstream parsing
|
||||||
* @{
|
* @{
|
||||||
@ -676,8 +680,9 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
|
|||||||
srcY += src_y * s->linesize + src_x;
|
srcY += src_y * s->linesize + src_x;
|
||||||
srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
|
srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
|
||||||
srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
|
srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
|
||||||
if( (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4
|
if(s->h_edge_pos - (width << 3) < 6 || s->v_edge_pos - (height << 3) < 6 ||
|
||||||
|| (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4){
|
(unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 ||
|
||||||
|
(unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4) {
|
||||||
uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize;
|
uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize;
|
||||||
|
|
||||||
srcY -= 2 + 2*s->linesize;
|
srcY -= 2 + 2*s->linesize;
|
||||||
@ -1097,6 +1102,7 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
|
|||||||
MpegEncContext *s = &r->s;
|
MpegEncContext *s = &r->s;
|
||||||
GetBitContext *gb = &s->gb;
|
GetBitContext *gb = &s->gb;
|
||||||
int cbp, cbp2;
|
int cbp, cbp2;
|
||||||
|
int q_dc, q_ac;
|
||||||
int i, blknum, blkoff;
|
int i, blknum, blkoff;
|
||||||
LOCAL_ALIGNED_16(DCTELEM, block16, [64]);
|
LOCAL_ALIGNED_16(DCTELEM, block16, [64]);
|
||||||
int luma_dc_quant;
|
int luma_dc_quant;
|
||||||
@ -1133,31 +1139,34 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
|
|||||||
|
|
||||||
luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16 ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale];
|
luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16 ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale];
|
||||||
if(r->is16){
|
if(r->is16){
|
||||||
|
q_dc = rv34_qscale_tab[luma_dc_quant];
|
||||||
|
q_ac = rv34_qscale_tab[s->qscale];
|
||||||
memset(block16, 0, 64 * sizeof(*block16));
|
memset(block16, 0, 64 * sizeof(*block16));
|
||||||
rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0);
|
rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac);
|
||||||
rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
|
|
||||||
r->rdsp.rv34_inv_transform_tab[1](block16);
|
r->rdsp.rv34_inv_transform_tab[1](block16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
q_ac = rv34_qscale_tab[s->qscale];
|
||||||
for(i = 0; i < 16; i++, cbp >>= 1){
|
for(i = 0; i < 16; i++, cbp >>= 1){
|
||||||
if(!r->is16 && !(cbp & 1)) continue;
|
if(!r->is16 && !(cbp & 1)) continue;
|
||||||
blknum = ((i & 2) >> 1) + ((i & 8) >> 2);
|
blknum = ((i & 2) >> 1) + ((i & 8) >> 2);
|
||||||
blkoff = ((i & 1) << 2) + ((i & 4) << 3);
|
blkoff = ((i & 1) << 2) + ((i & 4) << 3);
|
||||||
if(cbp & 1)
|
if(cbp & 1)
|
||||||
rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0);
|
rv34_decode_block(s->block[blknum] + blkoff, gb,
|
||||||
r->rdsp.rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]);
|
r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
|
||||||
if(r->is16) //FIXME: optimize
|
if(r->is16) //FIXME: optimize
|
||||||
s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)];
|
s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)];
|
||||||
r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
|
r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
|
||||||
}
|
}
|
||||||
if(r->block_type == RV34_MB_P_MIX16x16)
|
if(r->block_type == RV34_MB_P_MIX16x16)
|
||||||
r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
|
r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
|
||||||
|
q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
|
||||||
|
q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
|
||||||
for(; i < 24; i++, cbp >>= 1){
|
for(; i < 24; i++, cbp >>= 1){
|
||||||
if(!(cbp & 1)) continue;
|
if(!(cbp & 1)) continue;
|
||||||
blknum = ((i & 4) >> 2) + 4;
|
blknum = ((i & 4) >> 2) + 4;
|
||||||
blkoff = ((i & 1) << 2) + ((i & 2) << 4);
|
blkoff = ((i & 1) << 2) + ((i & 2) << 4);
|
||||||
rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1);
|
rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1, q_dc, q_ac, q_ac);
|
||||||
r->rdsp.rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
|
|
||||||
r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
|
r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
|
||||||
}
|
}
|
||||||
if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos]))
|
if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos]))
|
||||||
|
@ -100,16 +100,6 @@ static const uint16_t rv34_qscale_tab[32] = {
|
|||||||
963, 1074, 1212, 1392, 1566, 1708, 1978, 2211
|
963, 1074, 1212, 1392, 1566, 1708, 1978, 2211
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 4x4 dezigzag pattern
|
|
||||||
*/
|
|
||||||
static const uint8_t rv34_dezigzag[16] = {
|
|
||||||
0, 1, 8, 16,
|
|
||||||
9, 2, 3, 10,
|
|
||||||
17, 24, 25, 18,
|
|
||||||
11, 19, 26, 27
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tables used to translate a quantizer value into a VLC set for decoding
|
* tables used to translate a quantizer value into a VLC set for decoding
|
||||||
* The first table is used for intraframes.
|
* The first table is used for intraframes.
|
||||||
|
@ -100,26 +100,10 @@ static void rv34_inv_transform_noround_c(DCTELEM *block){
|
|||||||
/** @} */ // transform
|
/** @} */ // transform
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dequantize ordinary 4x4 block.
|
|
||||||
*/
|
|
||||||
void ff_rv34_dequant4x4_neon(DCTELEM *block, int Qdc, int Q);
|
|
||||||
static void rv34_dequant4x4_c(DCTELEM *block, int Qdc, int Q)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
block[0] = (block[0] * Qdc + 8) >> 4;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
for (j = !i; j < 4; j++)
|
|
||||||
block[j + i*8] = (block[j + i*8] * Q + 8) >> 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) {
|
av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) {
|
||||||
c->rv34_inv_transform_tab[0] = rv34_inv_transform_c;
|
c->rv34_inv_transform_tab[0] = rv34_inv_transform_c;
|
||||||
c->rv34_inv_transform_tab[1] = rv34_inv_transform_noround_c;
|
c->rv34_inv_transform_tab[1] = rv34_inv_transform_noround_c;
|
||||||
|
|
||||||
c->rv34_dequant4x4 = rv34_dequant4x4_c;
|
|
||||||
|
|
||||||
if (HAVE_NEON)
|
if (HAVE_NEON)
|
||||||
ff_rv34dsp_init_neon(c, dsp);
|
ff_rv34dsp_init_neon(c, dsp);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@ typedef struct RV34DSPContext {
|
|||||||
h264_chroma_mc_func avg_chroma_pixels_tab[3];
|
h264_chroma_mc_func avg_chroma_pixels_tab[3];
|
||||||
rv40_weight_func rv40_weight_pixels_tab[2];
|
rv40_weight_func rv40_weight_pixels_tab[2];
|
||||||
rv34_inv_transform_func rv34_inv_transform_tab[2];
|
rv34_inv_transform_func rv34_inv_transform_tab[2];
|
||||||
void (*rv34_dequant4x4)(DCTELEM *block, int Qdc, int Q);
|
|
||||||
rv40_weak_loop_filter_func rv40_weak_loop_filter[2];
|
rv40_weak_loop_filter_func rv40_weak_loop_filter[2];
|
||||||
rv40_strong_loop_filter_func rv40_strong_loop_filter[2];
|
rv40_strong_loop_filter_func rv40_strong_loop_filter[2];
|
||||||
rv40_loop_filter_strength_func rv40_loop_filter_strength[2];
|
rv40_loop_filter_strength_func rv40_loop_filter_strength[2];
|
||||||
|
@ -38,16 +38,9 @@ typedef struct UltimotionDecodeContext {
|
|||||||
int width, height, blocks;
|
int width, height, blocks;
|
||||||
AVFrame frame;
|
AVFrame frame;
|
||||||
const uint8_t *ulti_codebook;
|
const uint8_t *ulti_codebook;
|
||||||
|
GetByteContext gb;
|
||||||
} UltimotionDecodeContext;
|
} UltimotionDecodeContext;
|
||||||
|
|
||||||
#define CHECK_OVERREAD_SIZE(size) \
|
|
||||||
do { \
|
|
||||||
if (buf_end - buf < (size)) { \
|
|
||||||
av_log(avctx, AV_LOG_ERROR, "Insufficient data\n"); \
|
|
||||||
return AVERROR_INVALIDDATA; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
static av_cold int ulti_decode_init(AVCodecContext *avctx)
|
static av_cold int ulti_decode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
UltimotionDecodeContext *s = avctx->priv_data;
|
UltimotionDecodeContext *s = avctx->priv_data;
|
||||||
@ -232,7 +225,6 @@ static int ulti_decode_frame(AVCodecContext *avctx,
|
|||||||
int i;
|
int i;
|
||||||
int skip;
|
int skip;
|
||||||
int tmp;
|
int tmp;
|
||||||
const uint8_t *buf_end = buf + buf_size;
|
|
||||||
|
|
||||||
s->frame.reference = 3;
|
s->frame.reference = 3;
|
||||||
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
|
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
|
||||||
@ -241,18 +233,20 @@ static int ulti_decode_frame(AVCodecContext *avctx,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bytestream2_init(&s->gb, buf, buf_size);
|
||||||
|
|
||||||
while(!done) {
|
while(!done) {
|
||||||
int idx;
|
int idx;
|
||||||
if(blocks >= s->blocks || y >= s->height)
|
if(blocks >= s->blocks || y >= s->height)
|
||||||
break;//all blocks decoded
|
break;//all blocks decoded
|
||||||
|
|
||||||
CHECK_OVERREAD_SIZE(1);
|
if (bytestream2_get_bytes_left(&s->gb) < 1)
|
||||||
idx = *buf++;
|
goto err;
|
||||||
|
idx = bytestream2_get_byteu(&s->gb);
|
||||||
if((idx & 0xF8) == 0x70) {
|
if((idx & 0xF8) == 0x70) {
|
||||||
switch(idx) {
|
switch(idx) {
|
||||||
case 0x70: //change modifier
|
case 0x70: //change modifier
|
||||||
CHECK_OVERREAD_SIZE(1);
|
modifier = bytestream2_get_byte(&s->gb);
|
||||||
modifier = *buf++;
|
|
||||||
if(modifier>1)
|
if(modifier>1)
|
||||||
av_log(avctx, AV_LOG_INFO, "warning: modifier must be 0 or 1, got %i\n", modifier);
|
av_log(avctx, AV_LOG_INFO, "warning: modifier must be 0 or 1, got %i\n", modifier);
|
||||||
break;
|
break;
|
||||||
@ -266,8 +260,7 @@ static int ulti_decode_frame(AVCodecContext *avctx,
|
|||||||
done = 1;
|
done = 1;
|
||||||
break;
|
break;
|
||||||
case 0x74: //skip some blocks
|
case 0x74: //skip some blocks
|
||||||
CHECK_OVERREAD_SIZE(1);
|
skip = bytestream2_get_byte(&s->gb);
|
||||||
skip = *buf++;
|
|
||||||
if ((blocks + skip) >= s->blocks)
|
if ((blocks + skip) >= s->blocks)
|
||||||
break;
|
break;
|
||||||
blocks += skip;
|
blocks += skip;
|
||||||
@ -294,8 +287,7 @@ static int ulti_decode_frame(AVCodecContext *avctx,
|
|||||||
} else {
|
} else {
|
||||||
cf = 0;
|
cf = 0;
|
||||||
if (idx) {
|
if (idx) {
|
||||||
CHECK_OVERREAD_SIZE(1);
|
chroma = bytestream2_get_byte(&s->gb);
|
||||||
chroma = *buf++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < 4; i++) { // for every subblock
|
for (i = 0; i < 4; i++) { // for every subblock
|
||||||
@ -303,15 +295,13 @@ static int ulti_decode_frame(AVCodecContext *avctx,
|
|||||||
if(!code) //skip subblock
|
if(!code) //skip subblock
|
||||||
continue;
|
continue;
|
||||||
if(cf) {
|
if(cf) {
|
||||||
CHECK_OVERREAD_SIZE(1);
|
chroma = bytestream2_get_byte(&s->gb);
|
||||||
chroma = *buf++;
|
|
||||||
}
|
}
|
||||||
tx = x + block_coords[i * 2];
|
tx = x + block_coords[i * 2];
|
||||||
ty = y + block_coords[(i * 2) + 1];
|
ty = y + block_coords[(i * 2) + 1];
|
||||||
switch(code) {
|
switch(code) {
|
||||||
case 1:
|
case 1:
|
||||||
CHECK_OVERREAD_SIZE(1);
|
tmp = bytestream2_get_byte(&s->gb);
|
||||||
tmp = *buf++;
|
|
||||||
|
|
||||||
angle = angle_by_index[(tmp >> 6) & 0x3];
|
angle = angle_by_index[(tmp >> 6) & 0x3];
|
||||||
|
|
||||||
@ -331,8 +321,7 @@ static int ulti_decode_frame(AVCodecContext *avctx,
|
|||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if (modifier) { // unpack four luma samples
|
if (modifier) { // unpack four luma samples
|
||||||
CHECK_OVERREAD_SIZE(3);
|
tmp = bytestream2_get_be24(&s->gb);
|
||||||
tmp = bytestream_get_be24(&buf);
|
|
||||||
|
|
||||||
Y[0] = (tmp >> 18) & 0x3F;
|
Y[0] = (tmp >> 18) & 0x3F;
|
||||||
Y[1] = (tmp >> 12) & 0x3F;
|
Y[1] = (tmp >> 12) & 0x3F;
|
||||||
@ -340,8 +329,7 @@ static int ulti_decode_frame(AVCodecContext *avctx,
|
|||||||
Y[3] = tmp & 0x3F;
|
Y[3] = tmp & 0x3F;
|
||||||
angle = 16;
|
angle = 16;
|
||||||
} else { // retrieve luma samples from codebook
|
} else { // retrieve luma samples from codebook
|
||||||
CHECK_OVERREAD_SIZE(2);
|
tmp = bytestream2_get_be16(&s->gb);
|
||||||
tmp = bytestream_get_be16(&buf);
|
|
||||||
|
|
||||||
angle = (tmp >> 12) & 0xF;
|
angle = (tmp >> 12) & 0xF;
|
||||||
tmp &= 0xFFF;
|
tmp &= 0xFFF;
|
||||||
@ -357,27 +345,27 @@ static int ulti_decode_frame(AVCodecContext *avctx,
|
|||||||
if (modifier) { // all 16 luma samples
|
if (modifier) { // all 16 luma samples
|
||||||
uint8_t Luma[16];
|
uint8_t Luma[16];
|
||||||
|
|
||||||
CHECK_OVERREAD_SIZE(12);
|
if (bytestream2_get_bytes_left(&s->gb) < 12)
|
||||||
|
goto err;
|
||||||
tmp = bytestream_get_be24(&buf);
|
tmp = bytestream2_get_be24u(&s->gb);
|
||||||
Luma[0] = (tmp >> 18) & 0x3F;
|
Luma[0] = (tmp >> 18) & 0x3F;
|
||||||
Luma[1] = (tmp >> 12) & 0x3F;
|
Luma[1] = (tmp >> 12) & 0x3F;
|
||||||
Luma[2] = (tmp >> 6) & 0x3F;
|
Luma[2] = (tmp >> 6) & 0x3F;
|
||||||
Luma[3] = tmp & 0x3F;
|
Luma[3] = tmp & 0x3F;
|
||||||
|
|
||||||
tmp = bytestream_get_be24(&buf);
|
tmp = bytestream2_get_be24u(&s->gb);
|
||||||
Luma[4] = (tmp >> 18) & 0x3F;
|
Luma[4] = (tmp >> 18) & 0x3F;
|
||||||
Luma[5] = (tmp >> 12) & 0x3F;
|
Luma[5] = (tmp >> 12) & 0x3F;
|
||||||
Luma[6] = (tmp >> 6) & 0x3F;
|
Luma[6] = (tmp >> 6) & 0x3F;
|
||||||
Luma[7] = tmp & 0x3F;
|
Luma[7] = tmp & 0x3F;
|
||||||
|
|
||||||
tmp = bytestream_get_be24(&buf);
|
tmp = bytestream2_get_be24u(&s->gb);
|
||||||
Luma[8] = (tmp >> 18) & 0x3F;
|
Luma[8] = (tmp >> 18) & 0x3F;
|
||||||
Luma[9] = (tmp >> 12) & 0x3F;
|
Luma[9] = (tmp >> 12) & 0x3F;
|
||||||
Luma[10] = (tmp >> 6) & 0x3F;
|
Luma[10] = (tmp >> 6) & 0x3F;
|
||||||
Luma[11] = tmp & 0x3F;
|
Luma[11] = tmp & 0x3F;
|
||||||
|
|
||||||
tmp = bytestream_get_be24(&buf);
|
tmp = bytestream2_get_be24u(&s->gb);
|
||||||
Luma[12] = (tmp >> 18) & 0x3F;
|
Luma[12] = (tmp >> 18) & 0x3F;
|
||||||
Luma[13] = (tmp >> 12) & 0x3F;
|
Luma[13] = (tmp >> 12) & 0x3F;
|
||||||
Luma[14] = (tmp >> 6) & 0x3F;
|
Luma[14] = (tmp >> 6) & 0x3F;
|
||||||
@ -385,22 +373,23 @@ static int ulti_decode_frame(AVCodecContext *avctx,
|
|||||||
|
|
||||||
ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma);
|
ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma);
|
||||||
} else {
|
} else {
|
||||||
CHECK_OVERREAD_SIZE(4);
|
if (bytestream2_get_bytes_left(&s->gb) < 4)
|
||||||
tmp = *buf++;
|
goto err;
|
||||||
|
tmp = bytestream2_get_byteu(&s->gb);
|
||||||
if(tmp & 0x80) {
|
if(tmp & 0x80) {
|
||||||
angle = (tmp >> 4) & 0x7;
|
angle = (tmp >> 4) & 0x7;
|
||||||
tmp = (tmp << 8) + *buf++;
|
tmp = (tmp << 8) + bytestream2_get_byteu(&s->gb);
|
||||||
Y[0] = (tmp >> 6) & 0x3F;
|
Y[0] = (tmp >> 6) & 0x3F;
|
||||||
Y[1] = tmp & 0x3F;
|
Y[1] = tmp & 0x3F;
|
||||||
Y[2] = (*buf++) & 0x3F;
|
Y[2] = bytestream2_get_byteu(&s->gb) & 0x3F;
|
||||||
Y[3] = (*buf++) & 0x3F;
|
Y[3] = bytestream2_get_byteu(&s->gb) & 0x3F;
|
||||||
ulti_grad(&s->frame, tx, ty, Y, chroma, angle); //draw block
|
ulti_grad(&s->frame, tx, ty, Y, chroma, angle); //draw block
|
||||||
} else { // some patterns
|
} else { // some patterns
|
||||||
int f0, f1;
|
int f0, f1;
|
||||||
f0 = *buf++;
|
f0 = bytestream2_get_byteu(&s->gb);
|
||||||
f1 = tmp;
|
f1 = tmp;
|
||||||
Y[0] = (*buf++) & 0x3F;
|
Y[0] = bytestream2_get_byteu(&s->gb) & 0x3F;
|
||||||
Y[1] = (*buf++) & 0x3F;
|
Y[1] = bytestream2_get_byteu(&s->gb) & 0x3F;
|
||||||
ulti_pattern(&s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma);
|
ulti_pattern(&s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -422,6 +411,11 @@ static int ulti_decode_frame(AVCodecContext *avctx,
|
|||||||
*(AVFrame*)data= s->frame;
|
*(AVFrame*)data= s->frame;
|
||||||
|
|
||||||
return buf_size;
|
return buf_size;
|
||||||
|
|
||||||
|
err:
|
||||||
|
av_log(avctx, AV_LOG_ERROR,
|
||||||
|
"Insufficient data\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
AVCodec ff_ulti_decoder = {
|
AVCodec ff_ulti_decoder = {
|
||||||
|
@ -568,6 +568,7 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
|
if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
|
||||||
|
|| s->h_edge_pos < 22 || v_edge_pos < 22
|
||||||
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
|
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
|
||||||
|| (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel * 3) {
|
|| (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel * 3) {
|
||||||
uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
|
uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
|
||||||
@ -799,6 +800,7 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
|
|||||||
if (fieldmv && (src_y & 1) && src_y < 4)
|
if (fieldmv && (src_y & 1) && src_y < 4)
|
||||||
src_y--;
|
src_y--;
|
||||||
if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
|
if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
|
||||||
|
|| s->h_edge_pos < 13 || v_edge_pos < 23
|
||||||
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
|
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
|
||||||
|| (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
|
|| (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
|
||||||
srcY -= s->mspel * (1 + (s->linesize << fieldmv));
|
srcY -= s->mspel * (1 + (s->linesize << fieldmv));
|
||||||
@ -998,6 +1000,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
|
if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
|
||||||
|
|| s->h_edge_pos < 18 || v_edge_pos < 18
|
||||||
|| (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
|
|| (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
|
||||||
|| (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) {
|
|| (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) {
|
||||||
s->dsp.emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize,
|
s->dsp.emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize,
|
||||||
@ -1102,6 +1105,7 @@ static void vc1_mc_4mv_chroma4(VC1Context *v)
|
|||||||
if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
|
if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
|
||||||
uvsrc_y--;
|
uvsrc_y--;
|
||||||
if ((v->mv_mode == MV_PMODE_INTENSITY_COMP)
|
if ((v->mv_mode == MV_PMODE_INTENSITY_COMP)
|
||||||
|
|| s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
|
||||||
|| (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
|
|| (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
|
||||||
|| (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
|
|| (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
|
||||||
s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize,
|
s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize,
|
||||||
@ -2006,7 +2010,7 @@ static void vc1_interp_mc(VC1Context *v)
|
|||||||
srcV = s->edge_emu_buffer + 18 * s->linesize;
|
srcV = s->edge_emu_buffer + 18 * s->linesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->rangeredfrm
|
if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22
|
||||||
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 16 - s->mspel * 3
|
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 16 - s->mspel * 3
|
||||||
|| (unsigned)(src_y - s->mspel) > v_edge_pos - (my & 3) - 16 - s->mspel * 3) {
|
|| (unsigned)(src_y - s->mspel) > v_edge_pos - (my & 3) - 16 - s->mspel * 3) {
|
||||||
uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
|
uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
|
||||||
|
@ -69,19 +69,17 @@
|
|||||||
|
|
||||||
static const int desired_video_buffers = 256;
|
static const int desired_video_buffers = 256;
|
||||||
|
|
||||||
enum io_method {
|
#define V4L_ALLFORMATS 3
|
||||||
io_read,
|
#define V4L_RAWFORMATS 1
|
||||||
io_mmap,
|
#define V4L_COMPFORMATS 2
|
||||||
io_userptr
|
|
||||||
};
|
|
||||||
|
|
||||||
struct video_data {
|
struct video_data {
|
||||||
AVClass *class;
|
AVClass *class;
|
||||||
int fd;
|
int fd;
|
||||||
int frame_format; /* V4L2_PIX_FMT_* */
|
int frame_format; /* V4L2_PIX_FMT_* */
|
||||||
enum io_method io_method;
|
|
||||||
int width, height;
|
int width, height;
|
||||||
int frame_size;
|
int frame_size;
|
||||||
|
int interlaced;
|
||||||
int top_field_first;
|
int top_field_first;
|
||||||
|
|
||||||
int buffers;
|
int buffers;
|
||||||
@ -89,8 +87,10 @@ struct video_data {
|
|||||||
unsigned int *buf_len;
|
unsigned int *buf_len;
|
||||||
char *standard;
|
char *standard;
|
||||||
int channel;
|
int channel;
|
||||||
char *video_size; /**< String describing video size, set by a private option. */
|
char *video_size; /**< String describing video size,
|
||||||
|
set by a private option. */
|
||||||
char *pixel_format; /**< Set by a private option. */
|
char *pixel_format; /**< Set by a private option. */
|
||||||
|
int list_format; /**< Set by a private option. */
|
||||||
char *framerate; /**< Set by a private option. */
|
char *framerate; /**< Set by a private option. */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ static struct fmt_map fmt_conversion_table[] = {
|
|||||||
{ PIX_FMT_NONE, CODEC_ID_MJPEG, V4L2_PIX_FMT_JPEG },
|
{ PIX_FMT_NONE, CODEC_ID_MJPEG, V4L2_PIX_FMT_JPEG },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int device_open(AVFormatContext *ctx, uint32_t *capabilities)
|
static int device_open(AVFormatContext *ctx)
|
||||||
{
|
{
|
||||||
struct v4l2_capability cap;
|
struct v4l2_capability cap;
|
||||||
int fd;
|
int fd;
|
||||||
@ -137,11 +137,15 @@ static int device_open(AVFormatContext *ctx, uint32_t *capabilities)
|
|||||||
if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
|
if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
|
||||||
flags |= O_NONBLOCK;
|
flags |= O_NONBLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = v4l2_open(ctx->filename, flags, 0);
|
fd = v4l2_open(ctx->filename, flags, 0);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
err = errno;
|
||||||
|
|
||||||
av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
|
av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
|
||||||
ctx->filename, strerror(errno));
|
ctx->filename, strerror(err));
|
||||||
return AVERROR(errno);
|
|
||||||
|
return AVERROR(err);
|
||||||
}
|
}
|
||||||
#if CONFIG_LIBV4L2
|
#if CONFIG_LIBV4L2
|
||||||
fd_libv4l = v4l2_fd_open(fd, 0);
|
fd_libv4l = v4l2_fd_open(fd, 0);
|
||||||
@ -155,53 +159,80 @@ static int device_open(AVFormatContext *ctx, uint32_t *capabilities)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
res = v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap);
|
res = v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap);
|
||||||
// ENOIOCTLCMD definition only availble on __KERNEL__
|
|
||||||
if (res < 0 && ((err = errno) == 515)) {
|
|
||||||
av_log(ctx, AV_LOG_ERROR, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n");
|
|
||||||
v4l2_close(fd);
|
|
||||||
|
|
||||||
return AVERROR(515);
|
|
||||||
}
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
err = errno;
|
||||||
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
|
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
|
||||||
strerror(errno));
|
strerror(err));
|
||||||
|
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
av_log(ctx, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n",
|
||||||
|
fd, cap.capabilities);
|
||||||
|
|
||||||
|
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Not a video capture device.\n");
|
||||||
|
err = ENODEV;
|
||||||
|
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR,
|
||||||
|
"The device does not support the streaming I/O method.\n");
|
||||||
|
err = ENOSYS;
|
||||||
|
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
fail:
|
||||||
v4l2_close(fd);
|
v4l2_close(fd);
|
||||||
return AVERROR(err);
|
return AVERROR(err);
|
||||||
}
|
}
|
||||||
if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
|
|
||||||
av_log(ctx, AV_LOG_ERROR, "Not a video capture device\n");
|
|
||||||
v4l2_close(fd);
|
|
||||||
return AVERROR(ENODEV);
|
|
||||||
}
|
|
||||||
*capabilities = cap.capabilities;
|
|
||||||
|
|
||||||
return fd;
|
static int device_init(AVFormatContext *ctx, int *width, int *height,
|
||||||
}
|
uint32_t pix_fmt)
|
||||||
|
|
||||||
static int device_init(AVFormatContext *ctx, int *width, int *height, uint32_t pix_fmt)
|
|
||||||
{
|
{
|
||||||
struct video_data *s = ctx->priv_data;
|
struct video_data *s = ctx->priv_data;
|
||||||
int fd = s->fd;
|
int fd = s->fd;
|
||||||
struct v4l2_format fmt = {0};
|
struct v4l2_format fmt;
|
||||||
|
struct v4l2_pix_format *pix = &fmt.fmt.pix;
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
memset(&fmt, 0, sizeof(struct v4l2_format));
|
||||||
|
|
||||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
fmt.fmt.pix.width = *width;
|
pix->width = *width;
|
||||||
fmt.fmt.pix.height = *height;
|
pix->height = *height;
|
||||||
fmt.fmt.pix.pixelformat = pix_fmt;
|
pix->pixelformat = pix_fmt;
|
||||||
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
pix->field = V4L2_FIELD_ANY;
|
||||||
|
|
||||||
res = v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt);
|
res = v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt);
|
||||||
|
|
||||||
if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
|
if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
|
||||||
av_log(ctx, AV_LOG_INFO, "The V4L2 driver changed the video from %dx%d to %dx%d\n", *width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height);
|
av_log(ctx, AV_LOG_INFO,
|
||||||
|
"The V4L2 driver changed the video from %dx%d to %dx%d\n",
|
||||||
|
*width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height);
|
||||||
*width = fmt.fmt.pix.width;
|
*width = fmt.fmt.pix.width;
|
||||||
*height = fmt.fmt.pix.height;
|
*height = fmt.fmt.pix.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pix_fmt != fmt.fmt.pix.pixelformat) {
|
if (pix_fmt != fmt.fmt.pix.pixelformat) {
|
||||||
av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver changed the pixel format from 0x%08X to 0x%08X\n", pix_fmt, fmt.fmt.pix.pixelformat);
|
av_log(ctx, AV_LOG_DEBUG,
|
||||||
|
"The V4L2 driver changed the pixel format "
|
||||||
|
"from 0x%08X to 0x%08X\n",
|
||||||
|
pix_fmt, fmt.fmt.pix.pixelformat);
|
||||||
res = -1;
|
res = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
|
||||||
|
av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver using the interlaced mode");
|
||||||
|
s->interlaced = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +295,71 @@ static enum CodecID fmt_v4l2codec(uint32_t v4l2_fmt)
|
|||||||
return CODEC_ID_NONE;
|
return CODEC_ID_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
|
||||||
|
static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t pixelformat)
|
||||||
|
{
|
||||||
|
struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };
|
||||||
|
|
||||||
|
while(!ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
|
||||||
|
switch (vfse.type) {
|
||||||
|
case V4L2_FRMSIZE_TYPE_DISCRETE:
|
||||||
|
av_log(ctx, AV_LOG_INFO, " %ux%u",
|
||||||
|
vfse.discrete.width, vfse.discrete.height);
|
||||||
|
break;
|
||||||
|
case V4L2_FRMSIZE_TYPE_CONTINUOUS:
|
||||||
|
case V4L2_FRMSIZE_TYPE_STEPWISE:
|
||||||
|
av_log(ctx, AV_LOG_INFO, " {%u-%u, %u}x{%u-%u, %u}",
|
||||||
|
vfse.stepwise.min_width,
|
||||||
|
vfse.stepwise.max_width,
|
||||||
|
vfse.stepwise.step_width,
|
||||||
|
vfse.stepwise.min_height,
|
||||||
|
vfse.stepwise.max_height,
|
||||||
|
vfse.stepwise.step_height);
|
||||||
|
}
|
||||||
|
vfse.index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void list_formats(AVFormatContext *ctx, int fd, int type)
|
||||||
|
{
|
||||||
|
struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
|
||||||
|
|
||||||
|
while(!ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) {
|
||||||
|
enum CodecID codec_id = fmt_v4l2codec(vfd.pixelformat);
|
||||||
|
enum PixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id);
|
||||||
|
|
||||||
|
vfd.index++;
|
||||||
|
|
||||||
|
if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
|
||||||
|
type & V4L_RAWFORMATS) {
|
||||||
|
const char *fmt_name = av_get_pix_fmt_name(pix_fmt);
|
||||||
|
av_log(ctx, AV_LOG_INFO, "R : %9s : %20s :",
|
||||||
|
fmt_name ? fmt_name : "Unsupported",
|
||||||
|
vfd.description);
|
||||||
|
} else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
|
||||||
|
type & V4L_COMPFORMATS) {
|
||||||
|
AVCodec *codec = avcodec_find_encoder(codec_id);
|
||||||
|
av_log(ctx, AV_LOG_INFO, "C : %9s : %20s :",
|
||||||
|
codec ? codec->name : "Unsupported",
|
||||||
|
vfd.description);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef V4L2_FMT_FLAG_EMULATED
|
||||||
|
if (vfd.flags & V4L2_FMT_FLAG_EMULATED) {
|
||||||
|
av_log(ctx, AV_LOG_WARNING, "%s", "Emulated");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
|
||||||
|
list_framesizes(ctx, fd, vfd.pixelformat);
|
||||||
|
#endif
|
||||||
|
av_log(ctx, AV_LOG_INFO, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int mmap_init(AVFormatContext *ctx)
|
static int mmap_init(AVFormatContext *ctx)
|
||||||
{
|
{
|
||||||
struct video_data *s = ctx->priv_data;
|
struct video_data *s = ctx->priv_data;
|
||||||
@ -314,12 +410,16 @@ static int mmap_init(AVFormatContext *ctx)
|
|||||||
|
|
||||||
s->buf_len[i] = buf.length;
|
s->buf_len[i] = buf.length;
|
||||||
if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) {
|
if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "Buffer len [%d] = %d != %d\n", i, s->buf_len[i], s->frame_size);
|
av_log(ctx, AV_LOG_ERROR,
|
||||||
|
"Buffer len [%d] = %d != %d\n",
|
||||||
|
i, s->buf_len[i], s->frame_size);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
s->buf_start[i] = v4l2_mmap(NULL, buf.length,
|
s->buf_start[i] = v4l2_mmap(NULL, buf.length,
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset);
|
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||||
|
s->fd, buf.m.offset);
|
||||||
|
|
||||||
if (s->buf_start[i] == MAP_FAILED) {
|
if (s->buf_start[i] == MAP_FAILED) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
|
av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
|
||||||
return AVERROR(errno);
|
return AVERROR(errno);
|
||||||
@ -329,20 +429,14 @@ static int mmap_init(AVFormatContext *ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_init(AVFormatContext *ctx)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mmap_release_buffer(AVPacket *pkt)
|
static void mmap_release_buffer(AVPacket *pkt)
|
||||||
{
|
{
|
||||||
struct v4l2_buffer buf = {0};
|
struct v4l2_buffer buf = {0};
|
||||||
int res, fd;
|
int res, fd;
|
||||||
struct buff_data *buf_descriptor = pkt->priv;
|
struct buff_data *buf_descriptor = pkt->priv;
|
||||||
|
|
||||||
if (pkt->data == NULL) {
|
if (pkt->data == NULL)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
buf.memory = V4L2_MEMORY_MMAP;
|
buf.memory = V4L2_MEMORY_MMAP;
|
||||||
@ -351,9 +445,10 @@ static void mmap_release_buffer(AVPacket *pkt)
|
|||||||
av_free(buf_descriptor);
|
av_free(buf_descriptor);
|
||||||
|
|
||||||
res = v4l2_ioctl(fd, VIDIOC_QBUF, &buf);
|
res = v4l2_ioctl(fd, VIDIOC_QBUF, &buf);
|
||||||
if (res < 0) {
|
if (res < 0)
|
||||||
av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno));
|
av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
|
||||||
}
|
strerror(errno));
|
||||||
|
|
||||||
pkt->data = NULL;
|
pkt->data = NULL;
|
||||||
pkt->size = 0;
|
pkt->size = 0;
|
||||||
}
|
}
|
||||||
@ -375,13 +470,17 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
|
|||||||
pkt->size = 0;
|
pkt->size = 0;
|
||||||
return AVERROR(EAGAIN);
|
return AVERROR(EAGAIN);
|
||||||
}
|
}
|
||||||
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno));
|
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
|
||||||
return AVERROR(errno);
|
return AVERROR(errno);
|
||||||
}
|
}
|
||||||
assert(buf.index < s->buffers);
|
assert(buf.index < s->buffers);
|
||||||
if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
|
if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "The v4l2 frame is %d bytes, but %d bytes are expected\n", buf.bytesused, s->frame_size);
|
av_log(ctx, AV_LOG_ERROR,
|
||||||
|
"The v4l2 frame is %d bytes, but %d bytes are expected\n",
|
||||||
|
buf.bytesused, s->frame_size);
|
||||||
|
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,11 +506,6 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
|
|||||||
return s->buf_len[buf.index];
|
return s->buf_len[buf.index];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_frame(AVFormatContext *ctx, AVPacket *pkt)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mmap_start(AVFormatContext *ctx)
|
static int mmap_start(AVFormatContext *ctx)
|
||||||
{
|
{
|
||||||
struct video_data *s = ctx->priv_data;
|
struct video_data *s = ctx->priv_data;
|
||||||
@ -427,7 +521,9 @@ static int mmap_start(AVFormatContext *ctx)
|
|||||||
|
|
||||||
res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
|
res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno));
|
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
|
||||||
return AVERROR(errno);
|
return AVERROR(errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,7 +531,9 @@ static int mmap_start(AVFormatContext *ctx)
|
|||||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
res = v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type);
|
res = v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", strerror(errno));
|
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
|
||||||
return AVERROR(errno);
|
return AVERROR(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,8 +569,10 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
|
|||||||
|
|
||||||
streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
|
||||||
if (s->framerate && (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
|
if (s->framerate &&
|
||||||
av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", s->framerate);
|
(ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
|
||||||
|
av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n",
|
||||||
|
s->framerate);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,7 +586,8 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
|
|||||||
av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",
|
av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",
|
||||||
s->channel, input.name);
|
s->channel, input.name);
|
||||||
if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {
|
if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {
|
||||||
av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set input(%d) failed\n",
|
av_log(s1, AV_LOG_ERROR,
|
||||||
|
"The V4L2 driver ioctl set input(%d) failed\n",
|
||||||
s->channel);
|
s->channel);
|
||||||
return AVERROR(EIO);
|
return AVERROR(EIO);
|
||||||
}
|
}
|
||||||
@ -506,10 +607,12 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
|
av_log(s1, AV_LOG_DEBUG,
|
||||||
|
"The V4L2 driver set standard: %s, id: %"PRIu64"\n",
|
||||||
s->standard, (uint64_t)standard.id);
|
s->standard, (uint64_t)standard.id);
|
||||||
if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
|
if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
|
||||||
av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n",
|
av_log(s1, AV_LOG_ERROR,
|
||||||
|
"The V4L2 driver ioctl set standard(%s) failed\n",
|
||||||
s->standard);
|
s->standard);
|
||||||
return AVERROR(EIO);
|
return AVERROR(EIO);
|
||||||
}
|
}
|
||||||
@ -520,6 +623,7 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
|
|||||||
framerate_q.den, framerate_q.num);
|
framerate_q.den, framerate_q.num);
|
||||||
tpf->numerator = framerate_q.den;
|
tpf->numerator = framerate_q.den;
|
||||||
tpf->denominator = framerate_q.num;
|
tpf->denominator = framerate_q.num;
|
||||||
|
|
||||||
if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
|
if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
|
||||||
av_log(s1, AV_LOG_ERROR,
|
av_log(s1, AV_LOG_ERROR,
|
||||||
"ioctl set time per frame(%d/%d) failed\n",
|
"ioctl set time per frame(%d/%d) failed\n",
|
||||||
@ -530,14 +634,15 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
|
|||||||
if (framerate_q.num != tpf->denominator ||
|
if (framerate_q.num != tpf->denominator ||
|
||||||
framerate_q.den != tpf->numerator) {
|
framerate_q.den != tpf->numerator) {
|
||||||
av_log(s1, AV_LOG_INFO,
|
av_log(s1, AV_LOG_INFO,
|
||||||
"The driver changed the time per frame from %d/%d to %d/%d\n",
|
"The driver changed the time per frame from "
|
||||||
|
"%d/%d to %d/%d\n",
|
||||||
framerate_q.den, framerate_q.num,
|
framerate_q.den, framerate_q.num,
|
||||||
tpf->numerator, tpf->denominator);
|
tpf->numerator, tpf->denominator);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* if timebase value is not set, read the timebase value from the driver */
|
|
||||||
if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
|
if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
|
||||||
av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n", strerror(errno));
|
av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n",
|
||||||
|
strerror(errno));
|
||||||
return AVERROR(errno);
|
return AVERROR(errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -571,6 +676,7 @@ static uint32_t device_try_init(AVFormatContext *s1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desired_format != 0) {
|
if (desired_format != 0) {
|
||||||
*codec_id = fmt_v4l2codec(desired_format);
|
*codec_id = fmt_v4l2codec(desired_format);
|
||||||
assert(*codec_id != CODEC_ID_NONE);
|
assert(*codec_id != CODEC_ID_NONE);
|
||||||
@ -584,7 +690,7 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
|
|||||||
struct video_data *s = s1->priv_data;
|
struct video_data *s = s1->priv_data;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
uint32_t desired_format, capabilities;
|
uint32_t desired_format;
|
||||||
enum CodecID codec_id;
|
enum CodecID codec_id;
|
||||||
enum PixelFormat pix_fmt = PIX_FMT_NONE;
|
enum PixelFormat pix_fmt = PIX_FMT_NONE;
|
||||||
|
|
||||||
@ -593,42 +699,62 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
|
|||||||
res = AVERROR(ENOMEM);
|
res = AVERROR(ENOMEM);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
|
|
||||||
|
|
||||||
if (s->video_size && (res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) {
|
s->fd = device_open(s1);
|
||||||
av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n", s->video_size);
|
if (s->fd < 0) {
|
||||||
|
res = s->fd;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) {
|
|
||||||
av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format);
|
if (s->list_format) {
|
||||||
|
list_formats(s1, s->fd, s->list_format);
|
||||||
|
res = AVERROR_EXIT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
|
||||||
|
|
||||||
|
if (s->video_size &&
|
||||||
|
(res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) {
|
||||||
|
av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n",
|
||||||
|
s->video_size);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->pixel_format) {
|
||||||
|
|
||||||
|
pix_fmt = av_get_pix_fmt(s->pixel_format);
|
||||||
|
|
||||||
|
if (pix_fmt == PIX_FMT_NONE) {
|
||||||
|
av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n",
|
||||||
|
s->pixel_format);
|
||||||
|
|
||||||
res = AVERROR(EINVAL);
|
res = AVERROR(EINVAL);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
capabilities = 0;
|
|
||||||
s->fd = device_open(s1, &capabilities);
|
|
||||||
if (s->fd < 0) {
|
|
||||||
res = AVERROR(EIO);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
av_log(s1, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n", s->fd, capabilities);
|
|
||||||
|
|
||||||
if (!s->width && !s->height) {
|
if (!s->width && !s->height) {
|
||||||
struct v4l2_format fmt;
|
struct v4l2_format fmt;
|
||||||
|
|
||||||
av_log(s1, AV_LOG_VERBOSE, "Querying the device for the current frame size\n");
|
av_log(s1, AV_LOG_VERBOSE,
|
||||||
|
"Querying the device for the current frame size\n");
|
||||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
|
if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
|
||||||
av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", strerror(errno));
|
av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
|
||||||
|
strerror(errno));
|
||||||
res = AVERROR(errno);
|
res = AVERROR(errno);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->width = fmt.fmt.pix.width;
|
s->width = fmt.fmt.pix.width;
|
||||||
s->height = fmt.fmt.pix.height;
|
s->height = fmt.fmt.pix.height;
|
||||||
av_log(s1, AV_LOG_VERBOSE, "Setting frame size to %dx%d\n", s->width, s->height);
|
av_log(s1, AV_LOG_VERBOSE,
|
||||||
|
"Setting frame size to %dx%d\n", s->width, s->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height, &codec_id);
|
desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,
|
||||||
|
&codec_id);
|
||||||
if (desired_format == 0) {
|
if (desired_format == 0) {
|
||||||
av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
|
av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
|
||||||
"codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
|
"codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
|
||||||
@ -639,32 +765,29 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
|
|||||||
}
|
}
|
||||||
if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0)
|
if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
s->frame_format = desired_format;
|
s->frame_format = desired_format;
|
||||||
|
|
||||||
if ((res = v4l2_set_parameters(s1, ap)) < 0)
|
if ((res = v4l2_set_parameters(s1, ap)) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
|
st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
|
||||||
s->frame_size = avpicture_get_size(st->codec->pix_fmt, s->width, s->height);
|
s->frame_size =
|
||||||
if (capabilities & V4L2_CAP_STREAMING) {
|
avpicture_get_size(st->codec->pix_fmt, s->width, s->height);
|
||||||
s->io_method = io_mmap;
|
|
||||||
res = mmap_init(s1);
|
if ((res = mmap_init(s1)) ||
|
||||||
if (res == 0) {
|
(res = mmap_start(s1)) < 0) {
|
||||||
res = mmap_start(s1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
s->io_method = io_read;
|
|
||||||
res = read_init(s1);
|
|
||||||
}
|
|
||||||
if (res < 0) {
|
|
||||||
v4l2_close(s->fd);
|
v4l2_close(s->fd);
|
||||||
res = AVERROR(EIO);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->top_field_first = first_field(s->fd);
|
s->top_field_first = first_field(s->fd);
|
||||||
|
|
||||||
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||||
st->codec->codec_id = codec_id;
|
st->codec->codec_id = codec_id;
|
||||||
|
if (codec_id == CODEC_ID_RAWVIDEO)
|
||||||
|
st->codec->codec_tag =
|
||||||
|
avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
|
||||||
st->codec->width = s->width;
|
st->codec->width = s->width;
|
||||||
st->codec->height = s->height;
|
st->codec->height = s->height;
|
||||||
st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
|
st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
|
||||||
@ -676,26 +799,17 @@ out:
|
|||||||
static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
|
static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
|
||||||
{
|
{
|
||||||
struct video_data *s = s1->priv_data;
|
struct video_data *s = s1->priv_data;
|
||||||
|
AVFrame *frame = s1->streams[0]->codec->coded_frame;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (s->io_method == io_mmap) {
|
|
||||||
av_init_packet(pkt);
|
av_init_packet(pkt);
|
||||||
res = mmap_read_frame(s1, pkt);
|
if ((res = mmap_read_frame(s1, pkt)) < 0) {
|
||||||
} else if (s->io_method == io_read) {
|
|
||||||
if (av_new_packet(pkt, s->frame_size) < 0)
|
|
||||||
return AVERROR(EIO);
|
|
||||||
|
|
||||||
res = read_frame(s1, pkt);
|
|
||||||
} else {
|
|
||||||
return AVERROR(EIO);
|
|
||||||
}
|
|
||||||
if (res < 0) {
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s1->streams[0]->codec->coded_frame) {
|
if (frame && s->interlaced) {
|
||||||
s1->streams[0]->codec->coded_frame->interlaced_frame = 1;
|
frame->interlaced_frame = 1;
|
||||||
s1->streams[0]->codec->coded_frame->top_field_first = s->top_field_first;
|
frame->top_field_first = s->top_field_first;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pkt->size;
|
return pkt->size;
|
||||||
@ -705,9 +819,7 @@ static int v4l2_read_close(AVFormatContext *s1)
|
|||||||
{
|
{
|
||||||
struct video_data *s = s1->priv_data;
|
struct video_data *s = s1->priv_data;
|
||||||
|
|
||||||
if (s->io_method == io_mmap) {
|
|
||||||
mmap_close(s);
|
mmap_close(s);
|
||||||
}
|
|
||||||
|
|
||||||
v4l2_close(s->fd);
|
v4l2_close(s->fd);
|
||||||
return 0;
|
return 0;
|
||||||
@ -717,11 +829,15 @@ static int v4l2_read_close(AVFormatContext *s1)
|
|||||||
#define DEC AV_OPT_FLAG_DECODING_PARAM
|
#define DEC AV_OPT_FLAG_DECODING_PARAM
|
||||||
|
|
||||||
static const AVOption options[] = {
|
static const AVOption options[] = {
|
||||||
{ "standard", "", OFFSET(standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
|
{ "standard", "TV standard, used only by analog frame grabber", OFFSET(standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC },
|
||||||
{ "channel", "", OFFSET(channel), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
|
{ "channel", "TV channel, used only by frame grabber", OFFSET(channel), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, DEC },
|
||||||
{ "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
|
{ "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
|
||||||
{ "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
|
{ "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
|
||||||
{ "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
|
{ "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
|
||||||
|
{ "list_formats", "List available formats and exit", OFFSET(list_format), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, DEC, "list_formats" },
|
||||||
|
{ "all", "Show all available formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_ALLFORMATS }, 0, INT_MAX, DEC, "list_formats" },
|
||||||
|
{ "raw", "Show only non-compressed formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_RAWFORMATS }, 0, INT_MAX, DEC, "list_formats" },
|
||||||
|
{ "compressed", "Show only compressed formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_COMPFORMATS }, 0, INT_MAX, DEC, "list_formats" },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ OBJS-$(CONFIG_AC3_MUXER) += rawenc.o
|
|||||||
OBJS-$(CONFIG_ACT_DEMUXER) += act.o
|
OBJS-$(CONFIG_ACT_DEMUXER) += act.o
|
||||||
OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o
|
OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o
|
||||||
OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o
|
OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o
|
||||||
|
OBJS-$(CONFIG_ADX_MUXER) += rawenc.o
|
||||||
OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o
|
OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o
|
||||||
OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o
|
OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o
|
||||||
OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o isom.o
|
OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o isom.o
|
||||||
|
@ -109,4 +109,5 @@ AVInputFormat ff_adx_demuxer = {
|
|||||||
.read_packet = adx_read_packet,
|
.read_packet = adx_read_packet,
|
||||||
.extensions = "adx",
|
.extensions = "adx",
|
||||||
.value = CODEC_ID_ADPCM_ADX,
|
.value = CODEC_ID_ADPCM_ADX,
|
||||||
|
.flags = AVFMT_GENERIC_INDEX,
|
||||||
};
|
};
|
||||||
|
@ -54,7 +54,7 @@ void av_register_all(void)
|
|||||||
REGISTER_DEMUXER (ACT, act);
|
REGISTER_DEMUXER (ACT, act);
|
||||||
REGISTER_DEMUXER (ADF, adf);
|
REGISTER_DEMUXER (ADF, adf);
|
||||||
REGISTER_MUXER (ADTS, adts);
|
REGISTER_MUXER (ADTS, adts);
|
||||||
REGISTER_DEMUXER (ADX, adx);
|
REGISTER_MUXDEMUX (ADX, adx);
|
||||||
REGISTER_DEMUXER (AEA, aea);
|
REGISTER_DEMUXER (AEA, aea);
|
||||||
REGISTER_MUXDEMUX (AIFF, aiff);
|
REGISTER_MUXDEMUX (AIFF, aiff);
|
||||||
REGISTER_MUXDEMUX (AMR, amr);
|
REGISTER_MUXDEMUX (AMR, amr);
|
||||||
|
@ -574,6 +574,10 @@ static void fill_buffer(AVIOContext *s)
|
|||||||
int len= s->buffer_size - (dst - s->buffer);
|
int len= s->buffer_size - (dst - s->buffer);
|
||||||
int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE;
|
int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE;
|
||||||
|
|
||||||
|
/* can't fill the buffer without read_packet, just set EOF if appropiate */
|
||||||
|
if (!s->read_packet && s->buf_ptr >= s->buf_end)
|
||||||
|
s->eof_reached = 1;
|
||||||
|
|
||||||
/* no need to do anything if EOF already reached */
|
/* no need to do anything if EOF already reached */
|
||||||
if (s->eof_reached)
|
if (s->eof_reached)
|
||||||
return;
|
return;
|
||||||
|
@ -112,10 +112,12 @@ static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
|||||||
|
|
||||||
avio_skip(pb, 4);
|
avio_skip(pb, 4);
|
||||||
audio_subsegments = avio_rl16(pb);
|
audio_subsegments = avio_rl16(pb);
|
||||||
if(!audio_subsegments){
|
|
||||||
av_log(s, AV_LOG_ERROR, "audio_subsegments is 0\n");
|
if (audio_subsegments == 0) {
|
||||||
return AVERROR(EINVAL);
|
av_log_ask_for_sample(s, "MTV files without audio are not supported\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtv->full_segment_size =
|
mtv->full_segment_size =
|
||||||
audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) +
|
audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) +
|
||||||
mtv->img_segment_size;
|
mtv->img_segment_size;
|
||||||
|
@ -45,6 +45,18 @@ AVOutputFormat ff_ac3_muxer = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_ADX_MUXER
|
||||||
|
AVOutputFormat ff_adx_muxer = {
|
||||||
|
.name = "adx",
|
||||||
|
.long_name = NULL_IF_CONFIG_SMALL("CRI ADX"),
|
||||||
|
.extensions = "adx",
|
||||||
|
.audio_codec = CODEC_ID_ADPCM_ADX,
|
||||||
|
.video_codec = CODEC_ID_NONE,
|
||||||
|
.write_packet = ff_raw_write_packet,
|
||||||
|
.flags = AVFMT_NOTIMESTAMPS,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_DIRAC_MUXER
|
#if CONFIG_DIRAC_MUXER
|
||||||
AVOutputFormat ff_dirac_muxer = {
|
AVOutputFormat ff_dirac_muxer = {
|
||||||
.name = "dirac",
|
.name = "dirac",
|
||||||
|
@ -2470,7 +2470,7 @@ static av_always_inline void RENAME(do_a_deblock)(uint8_t *src, int step, int st
|
|||||||
int64_t dc_mask, eq_mask, both_masks;
|
int64_t dc_mask, eq_mask, both_masks;
|
||||||
int64_t sums[10*8*2];
|
int64_t sums[10*8*2];
|
||||||
src+= step*3; // src points to begin of the 8x8 Block
|
src+= step*3; // src points to begin of the 8x8 Block
|
||||||
//START_TIMER
|
//{ START_TIMER
|
||||||
__asm__ volatile(
|
__asm__ volatile(
|
||||||
"movq %0, %%mm7 \n\t"
|
"movq %0, %%mm7 \n\t"
|
||||||
"movq %1, %%mm6 \n\t"
|
"movq %1, %%mm6 \n\t"
|
||||||
@ -2995,6 +2995,7 @@ static av_always_inline void RENAME(do_a_deblock)(uint8_t *src, int step, int st
|
|||||||
STOP_TIMER("step16")
|
STOP_TIMER("step16")
|
||||||
}else{
|
}else{
|
||||||
STOP_TIMER("stepX")
|
STOP_TIMER("stepX")
|
||||||
|
}
|
||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
#endif //HAVE_MMX
|
#endif //HAVE_MMX
|
||||||
|
@ -19,7 +19,8 @@ OBJS-$(HAVE_MMX) += x86/rgb2rgb.o \
|
|||||||
x86/swscale_mmx.o \
|
x86/swscale_mmx.o \
|
||||||
x86/yuv2rgb_mmx.o
|
x86/yuv2rgb_mmx.o
|
||||||
OBJS-$(HAVE_VIS) += sparc/yuv2rgb_vis.o
|
OBJS-$(HAVE_VIS) += sparc/yuv2rgb_vis.o
|
||||||
OBJS-$(HAVE_YASM) += x86/scale.o
|
MMX-OBJS-$(HAVE_YASM) += x86/output.o \
|
||||||
|
x86/scale.o
|
||||||
|
|
||||||
$(SUBDIR)x86/swscale_mmx.o: CFLAGS += $(NOREDZONE_FLAGS)
|
$(SUBDIR)x86/swscale_mmx.o: CFLAGS += $(NOREDZONE_FLAGS)
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PPC_YUV2RGB_ALTIVEC_H
|
#ifndef SWSCALE_PPC_YUV2RGB_ALTIVEC_H
|
||||||
#define PPC_YUV2RGB_ALTIVEC_H 1
|
#define SWSCALE_PPC_YUV2RGB_ALTIVEC_H
|
||||||
|
|
||||||
#define YUV2PACKEDX_HEADER(suffix) \
|
#define YUV2PACKEDX_HEADER(suffix) \
|
||||||
void ff_yuv2 ## suffix ## _X_altivec(SwsContext *c, const int16_t *lumFilter, \
|
void ff_yuv2 ## suffix ## _X_altivec(SwsContext *c, const int16_t *lumFilter, \
|
||||||
@ -39,4 +39,4 @@ YUV2PACKEDX_HEADER(rgba);
|
|||||||
YUV2PACKEDX_HEADER(rgb24);
|
YUV2PACKEDX_HEADER(rgb24);
|
||||||
YUV2PACKEDX_HEADER(bgr24);
|
YUV2PACKEDX_HEADER(bgr24);
|
||||||
|
|
||||||
#endif /* PPC_YUV2RGB_ALTIVEC_H */
|
#endif /* SWSCALE_PPC_YUV2RGB_ALTIVEC_H */
|
||||||
|
@ -18,39 +18,6 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
supported Input formats: YV12, I420/IYUV, YUY2, UYVY, BGR32, BGR32_1, BGR24, BGR16, BGR15, RGB32, RGB32_1, RGB24, Y8/Y800, YVU9/IF09, PAL8
|
|
||||||
supported output formats: YV12, I420/IYUV, YUY2, UYVY, {BGR,RGB}{1,4,8,15,16,24,32}, Y8/Y800, YVU9/IF09
|
|
||||||
{BGR,RGB}{1,4,8,15,16} support dithering
|
|
||||||
|
|
||||||
unscaled special converters (YV12=I420=IYUV, Y800=Y8)
|
|
||||||
YV12 -> {BGR,RGB}{1,4,8,12,15,16,24,32}
|
|
||||||
x -> x
|
|
||||||
YUV9 -> YV12
|
|
||||||
YUV9/YV12 -> Y800
|
|
||||||
Y800 -> YUV9/YV12
|
|
||||||
BGR24 -> BGR32 & RGB24 -> RGB32
|
|
||||||
BGR32 -> BGR24 & RGB32 -> RGB24
|
|
||||||
BGR15 -> BGR16
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
tested special converters (most are tested actually, but I did not write it down ...)
|
|
||||||
YV12 -> BGR12/BGR16
|
|
||||||
YV12 -> YV12
|
|
||||||
BGR15 -> BGR16
|
|
||||||
BGR16 -> BGR16
|
|
||||||
YVU9 -> YV12
|
|
||||||
|
|
||||||
untested special converters
|
|
||||||
YV12/I420 -> BGR15/BGR24/BGR32 (it is the yuv2rgb stuff, so it should be OK)
|
|
||||||
YV12/I420 -> YV12/I420
|
|
||||||
YUY2/BGR15/BGR24/BGR32/RGB24/RGB32 -> same format
|
|
||||||
BGR24 -> BGR32 & RGB24 -> RGB32
|
|
||||||
BGR32 -> BGR24 & RGB32 -> RGB24
|
|
||||||
BGR24 -> YV12
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -2371,36 +2338,6 @@ find_c_packed_planar_out_funcs(SwsContext *c,
|
|||||||
} else {
|
} else {
|
||||||
YUV_PACKED:
|
YUV_PACKED:
|
||||||
switch (dstFormat) {
|
switch (dstFormat) {
|
||||||
case PIX_FMT_GRAY16BE:
|
|
||||||
*yuv2packed1 = yuv2gray16BE_1_c;
|
|
||||||
*yuv2packed2 = yuv2gray16BE_2_c;
|
|
||||||
*yuv2packedX = yuv2gray16BE_X_c;
|
|
||||||
break;
|
|
||||||
case PIX_FMT_GRAY16LE:
|
|
||||||
*yuv2packed1 = yuv2gray16LE_1_c;
|
|
||||||
*yuv2packed2 = yuv2gray16LE_2_c;
|
|
||||||
*yuv2packedX = yuv2gray16LE_X_c;
|
|
||||||
break;
|
|
||||||
case PIX_FMT_MONOWHITE:
|
|
||||||
*yuv2packed1 = yuv2monowhite_1_c;
|
|
||||||
*yuv2packed2 = yuv2monowhite_2_c;
|
|
||||||
*yuv2packedX = yuv2monowhite_X_c;
|
|
||||||
break;
|
|
||||||
case PIX_FMT_MONOBLACK:
|
|
||||||
*yuv2packed1 = yuv2monoblack_1_c;
|
|
||||||
*yuv2packed2 = yuv2monoblack_2_c;
|
|
||||||
*yuv2packedX = yuv2monoblack_X_c;
|
|
||||||
break;
|
|
||||||
case PIX_FMT_YUYV422:
|
|
||||||
*yuv2packed1 = yuv2yuyv422_1_c;
|
|
||||||
*yuv2packed2 = yuv2yuyv422_2_c;
|
|
||||||
*yuv2packedX = yuv2yuyv422_X_c;
|
|
||||||
break;
|
|
||||||
case PIX_FMT_UYVY422:
|
|
||||||
*yuv2packed1 = yuv2uyvy422_1_c;
|
|
||||||
*yuv2packed2 = yuv2uyvy422_2_c;
|
|
||||||
*yuv2packedX = yuv2uyvy422_X_c;
|
|
||||||
break;
|
|
||||||
case PIX_FMT_RGB48LE:
|
case PIX_FMT_RGB48LE:
|
||||||
*yuv2packed1 = yuv2rgb48le_1_c;
|
*yuv2packed1 = yuv2rgb48le_1_c;
|
||||||
*yuv2packed2 = yuv2rgb48le_2_c;
|
*yuv2packed2 = yuv2rgb48le_2_c;
|
||||||
@ -2517,6 +2454,38 @@ find_c_packed_planar_out_funcs(SwsContext *c,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switch (dstFormat) {
|
||||||
|
case PIX_FMT_GRAY16BE:
|
||||||
|
*yuv2packed1 = yuv2gray16BE_1_c;
|
||||||
|
*yuv2packed2 = yuv2gray16BE_2_c;
|
||||||
|
*yuv2packedX = yuv2gray16BE_X_c;
|
||||||
|
break;
|
||||||
|
case PIX_FMT_GRAY16LE:
|
||||||
|
*yuv2packed1 = yuv2gray16LE_1_c;
|
||||||
|
*yuv2packed2 = yuv2gray16LE_2_c;
|
||||||
|
*yuv2packedX = yuv2gray16LE_X_c;
|
||||||
|
break;
|
||||||
|
case PIX_FMT_MONOWHITE:
|
||||||
|
*yuv2packed1 = yuv2monowhite_1_c;
|
||||||
|
*yuv2packed2 = yuv2monowhite_2_c;
|
||||||
|
*yuv2packedX = yuv2monowhite_X_c;
|
||||||
|
break;
|
||||||
|
case PIX_FMT_MONOBLACK:
|
||||||
|
*yuv2packed1 = yuv2monoblack_1_c;
|
||||||
|
*yuv2packed2 = yuv2monoblack_2_c;
|
||||||
|
*yuv2packedX = yuv2monoblack_X_c;
|
||||||
|
break;
|
||||||
|
case PIX_FMT_YUYV422:
|
||||||
|
*yuv2packed1 = yuv2yuyv422_1_c;
|
||||||
|
*yuv2packed2 = yuv2yuyv422_2_c;
|
||||||
|
*yuv2packedX = yuv2yuyv422_X_c;
|
||||||
|
break;
|
||||||
|
case PIX_FMT_UYVY422:
|
||||||
|
*yuv2packed1 = yuv2uyvy422_1_c;
|
||||||
|
*yuv2packed2 = yuv2uyvy422_2_c;
|
||||||
|
*yuv2packedX = yuv2uyvy422_X_c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEBUG_SWSCALE_BUFFERS 0
|
#define DEBUG_SWSCALE_BUFFERS 0
|
||||||
|
409
libswscale/x86/output.asm
Normal file
409
libswscale/x86/output.asm
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
;******************************************************************************
|
||||||
|
;* x86-optimized vertical line scaling functions
|
||||||
|
;* Copyright (c) 2011 Ronald S. Bultje <rsbultje@gmail.com>
|
||||||
|
;* Kieran Kunhya <kieran@kunhya.com>
|
||||||
|
;*
|
||||||
|
;* This file is part of Libav.
|
||||||
|
;*
|
||||||
|
;* Libav 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.
|
||||||
|
;*
|
||||||
|
;* Libav 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 Libav; if not, write to the Free Software
|
||||||
|
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
;******************************************************************************
|
||||||
|
|
||||||
|
%include "x86inc.asm"
|
||||||
|
%include "x86util.asm"
|
||||||
|
|
||||||
|
SECTION_RODATA
|
||||||
|
|
||||||
|
minshort: times 8 dw 0x8000
|
||||||
|
yuv2yuvX_16_start: times 4 dd 0x4000 - 0x40000000
|
||||||
|
yuv2yuvX_10_start: times 4 dd 0x10000
|
||||||
|
yuv2yuvX_9_start: times 4 dd 0x20000
|
||||||
|
yuv2yuvX_10_upper: times 8 dw 0x3ff
|
||||||
|
yuv2yuvX_9_upper: times 8 dw 0x1ff
|
||||||
|
pd_4: times 4 dd 4
|
||||||
|
pd_4min0x40000:times 4 dd 4 - (0x40000)
|
||||||
|
pw_16: times 8 dw 16
|
||||||
|
pw_32: times 8 dw 32
|
||||||
|
pw_512: times 8 dw 512
|
||||||
|
pw_1024: times 8 dw 1024
|
||||||
|
|
||||||
|
SECTION .text
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
; vertical line scaling
|
||||||
|
;
|
||||||
|
; void yuv2plane1_<output_size>_<opt>(const int16_t *src, uint8_t *dst, int dstW,
|
||||||
|
; const uint8_t *dither, int offset)
|
||||||
|
; and
|
||||||
|
; void yuv2planeX_<output_size>_<opt>(const int16_t *filter, int filterSize,
|
||||||
|
; const int16_t **src, uint8_t *dst, int dstW,
|
||||||
|
; const uint8_t *dither, int offset)
|
||||||
|
;
|
||||||
|
; Scale one or $filterSize lines of source data to generate one line of output
|
||||||
|
; data. The input is 15-bit in int16_t if $output_size is [8,10] and 19-bit in
|
||||||
|
; int32_t if $output_size is 16. $filter is 12-bits. $filterSize is a multiple
|
||||||
|
; of 2. $offset is either 0 or 3. $dither holds 8 values.
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
%macro yuv2planeX_fn 4
|
||||||
|
|
||||||
|
%ifdef ARCH_X86_32
|
||||||
|
%define cntr_reg r1
|
||||||
|
%define movsx mov
|
||||||
|
%else
|
||||||
|
%define cntr_reg r11
|
||||||
|
%define movsx movsxd
|
||||||
|
%endif
|
||||||
|
|
||||||
|
cglobal yuv2planeX_%2_%1, %4, 7, %3
|
||||||
|
%if %2 == 8 || %2 == 9 || %2 == 10
|
||||||
|
pxor m6, m6
|
||||||
|
%endif ; %2 == 8/9/10
|
||||||
|
|
||||||
|
%if %2 == 8
|
||||||
|
%ifdef ARCH_X86_32
|
||||||
|
%assign pad 0x2c - (stack_offset & 15)
|
||||||
|
SUB rsp, pad
|
||||||
|
%define m_dith m7
|
||||||
|
%else ; x86-64
|
||||||
|
%define m_dith m9
|
||||||
|
%endif ; x86-32
|
||||||
|
|
||||||
|
; create registers holding dither
|
||||||
|
movq m_dith, [r5] ; dither
|
||||||
|
test r6d, r6d
|
||||||
|
jz .no_rot
|
||||||
|
%if mmsize == 16
|
||||||
|
punpcklqdq m_dith, m_dith
|
||||||
|
%endif ; mmsize == 16
|
||||||
|
PALIGNR m_dith, m_dith, 3, m0
|
||||||
|
.no_rot:
|
||||||
|
%if mmsize == 16
|
||||||
|
punpcklbw m_dith, m6
|
||||||
|
%ifdef ARCH_X86_64
|
||||||
|
punpcklwd m8, m_dith, m6
|
||||||
|
pslld m8, 12
|
||||||
|
%else ; x86-32
|
||||||
|
punpcklwd m5, m_dith, m6
|
||||||
|
pslld m5, 12
|
||||||
|
%endif ; x86-32/64
|
||||||
|
punpckhwd m_dith, m6
|
||||||
|
pslld m_dith, 12
|
||||||
|
%ifdef ARCH_X86_32
|
||||||
|
mova [rsp+ 0], m5
|
||||||
|
mova [rsp+16], m_dith
|
||||||
|
%endif
|
||||||
|
%else ; mmsize == 8
|
||||||
|
punpcklbw m5, m_dith, m6
|
||||||
|
punpckhbw m_dith, m6
|
||||||
|
punpcklwd m4, m5, m6
|
||||||
|
punpckhwd m5, m6
|
||||||
|
punpcklwd m3, m_dith, m6
|
||||||
|
punpckhwd m_dith, m6
|
||||||
|
pslld m4, 12
|
||||||
|
pslld m5, 12
|
||||||
|
pslld m3, 12
|
||||||
|
pslld m_dith, 12
|
||||||
|
mova [rsp+ 0], m4
|
||||||
|
mova [rsp+ 8], m5
|
||||||
|
mova [rsp+16], m3
|
||||||
|
mova [rsp+24], m_dith
|
||||||
|
%endif ; mmsize == 8/16
|
||||||
|
%endif ; %2 == 8
|
||||||
|
|
||||||
|
xor r5, r5
|
||||||
|
|
||||||
|
.pixelloop:
|
||||||
|
%assign %%i 0
|
||||||
|
; the rep here is for the 8bit output mmx case, where dither covers
|
||||||
|
; 8 pixels but we can only handle 2 pixels per register, and thus 4
|
||||||
|
; pixels per iteration. In order to not have to keep track of where
|
||||||
|
; we are w.r.t. dithering, we unroll the mmx/8bit loop x2.
|
||||||
|
%if %2 == 8
|
||||||
|
%rep 16/mmsize
|
||||||
|
%endif ; %2 == 8
|
||||||
|
|
||||||
|
%if %2 == 8
|
||||||
|
%ifdef ARCH_X86_32
|
||||||
|
mova m2, [rsp+mmsize*(0+%%i)]
|
||||||
|
mova m1, [rsp+mmsize*(1+%%i)]
|
||||||
|
%else ; x86-64
|
||||||
|
mova m2, m8
|
||||||
|
mova m1, m_dith
|
||||||
|
%endif ; x86-32/64
|
||||||
|
%else ; %2 == 9/10/16
|
||||||
|
mova m1, [yuv2yuvX_%2_start]
|
||||||
|
mova m2, m1
|
||||||
|
%endif ; %2 == 8/9/10/16
|
||||||
|
movsx cntr_reg, r1m
|
||||||
|
.filterloop_ %+ %%i:
|
||||||
|
; input pixels
|
||||||
|
mov r6, [r2+gprsize*cntr_reg-2*gprsize]
|
||||||
|
%if %2 == 16
|
||||||
|
mova m3, [r6+r5*4]
|
||||||
|
mova m5, [r6+r5*4+mmsize]
|
||||||
|
%else ; %2 == 8/9/10
|
||||||
|
mova m3, [r6+r5*2]
|
||||||
|
%endif ; %2 == 8/9/10/16
|
||||||
|
mov r6, [r2+gprsize*cntr_reg-gprsize]
|
||||||
|
%if %2 == 16
|
||||||
|
mova m4, [r6+r5*4]
|
||||||
|
mova m6, [r6+r5*4+mmsize]
|
||||||
|
%else ; %2 == 8/9/10
|
||||||
|
mova m4, [r6+r5*2]
|
||||||
|
%endif ; %2 == 8/9/10/16
|
||||||
|
|
||||||
|
; coefficients
|
||||||
|
movd m0, [r0+2*cntr_reg-4]; coeff[0], coeff[1]
|
||||||
|
%if %2 == 16
|
||||||
|
pshuflw m7, m0, 0 ; coeff[0]
|
||||||
|
pshuflw m0, m0, 0x55 ; coeff[1]
|
||||||
|
pmovsxwd m7, m7 ; word -> dword
|
||||||
|
pmovsxwd m0, m0 ; word -> dword
|
||||||
|
|
||||||
|
pmulld m3, m7
|
||||||
|
pmulld m5, m7
|
||||||
|
pmulld m4, m0
|
||||||
|
pmulld m6, m0
|
||||||
|
|
||||||
|
paddd m2, m3
|
||||||
|
paddd m1, m5
|
||||||
|
paddd m2, m4
|
||||||
|
paddd m1, m6
|
||||||
|
%else ; %2 == 10/9/8
|
||||||
|
punpcklwd m5, m3, m4
|
||||||
|
punpckhwd m3, m4
|
||||||
|
SPLATD m0, m0
|
||||||
|
|
||||||
|
pmaddwd m5, m0
|
||||||
|
pmaddwd m3, m0
|
||||||
|
|
||||||
|
paddd m2, m5
|
||||||
|
paddd m1, m3
|
||||||
|
%endif ; %2 == 8/9/10/16
|
||||||
|
|
||||||
|
sub cntr_reg, 2
|
||||||
|
jg .filterloop_ %+ %%i
|
||||||
|
|
||||||
|
%if %2 == 16
|
||||||
|
psrad m2, 31 - %2
|
||||||
|
psrad m1, 31 - %2
|
||||||
|
%else ; %2 == 10/9/8
|
||||||
|
psrad m2, 27 - %2
|
||||||
|
psrad m1, 27 - %2
|
||||||
|
%endif ; %2 == 8/9/10/16
|
||||||
|
|
||||||
|
%if %2 == 8
|
||||||
|
packssdw m2, m1
|
||||||
|
packuswb m2, m2
|
||||||
|
movh [r3+r5*1], m2
|
||||||
|
%else ; %2 == 9/10/16
|
||||||
|
%if %2 == 16
|
||||||
|
packssdw m2, m1
|
||||||
|
paddw m2, [minshort]
|
||||||
|
%else ; %2 == 9/10
|
||||||
|
%ifidn %1, sse4
|
||||||
|
packusdw m2, m1
|
||||||
|
%elifidn %1, avx
|
||||||
|
packusdw m2, m1
|
||||||
|
%else ; mmx2/sse2
|
||||||
|
packssdw m2, m1
|
||||||
|
pmaxsw m2, m6
|
||||||
|
%endif ; mmx2/sse2/sse4/avx
|
||||||
|
pminsw m2, [yuv2yuvX_%2_upper]
|
||||||
|
%endif ; %2 == 9/10/16
|
||||||
|
mova [r3+r5*2], m2
|
||||||
|
%endif ; %2 == 8/9/10/16
|
||||||
|
|
||||||
|
add r5, mmsize/2
|
||||||
|
sub r4d, mmsize/2
|
||||||
|
%if %2 == 8
|
||||||
|
%assign %%i %%i+2
|
||||||
|
%endrep
|
||||||
|
%endif ; %2 == 8
|
||||||
|
jg .pixelloop
|
||||||
|
|
||||||
|
%if %2 == 8
|
||||||
|
%ifdef ARCH_X86_32
|
||||||
|
ADD rsp, pad
|
||||||
|
RET
|
||||||
|
%else ; x86-64
|
||||||
|
REP_RET
|
||||||
|
%endif ; x86-32/64
|
||||||
|
%else ; %2 == 9/10/16
|
||||||
|
REP_RET
|
||||||
|
%endif ; %2 == 8/9/10/16
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%define PALIGNR PALIGNR_MMX
|
||||||
|
%ifdef ARCH_X86_32
|
||||||
|
INIT_MMX
|
||||||
|
yuv2planeX_fn mmx2, 8, 0, 7
|
||||||
|
yuv2planeX_fn mmx2, 9, 0, 5
|
||||||
|
yuv2planeX_fn mmx2, 10, 0, 5
|
||||||
|
%endif
|
||||||
|
|
||||||
|
INIT_XMM
|
||||||
|
yuv2planeX_fn sse2, 8, 10, 7
|
||||||
|
yuv2planeX_fn sse2, 9, 7, 5
|
||||||
|
yuv2planeX_fn sse2, 10, 7, 5
|
||||||
|
|
||||||
|
%define PALIGNR PALIGNR_SSSE3
|
||||||
|
yuv2planeX_fn sse4, 8, 10, 7
|
||||||
|
yuv2planeX_fn sse4, 9, 7, 5
|
||||||
|
yuv2planeX_fn sse4, 10, 7, 5
|
||||||
|
yuv2planeX_fn sse4, 16, 8, 5
|
||||||
|
|
||||||
|
INIT_AVX
|
||||||
|
yuv2planeX_fn avx, 8, 10, 7
|
||||||
|
yuv2planeX_fn avx, 9, 7, 5
|
||||||
|
yuv2planeX_fn avx, 10, 7, 5
|
||||||
|
|
||||||
|
; %1=outout-bpc, %2=alignment (u/a)
|
||||||
|
%macro yuv2plane1_mainloop 2
|
||||||
|
.loop_%2:
|
||||||
|
%if %1 == 8
|
||||||
|
paddsw m0, m2, [r0+r2*2+mmsize*0]
|
||||||
|
paddsw m1, m3, [r0+r2*2+mmsize*1]
|
||||||
|
psraw m0, 7
|
||||||
|
psraw m1, 7
|
||||||
|
packuswb m0, m1
|
||||||
|
mov%2 [r1+r2], m0
|
||||||
|
%elif %1 == 16
|
||||||
|
paddd m0, m4, [r0+r2*4+mmsize*0]
|
||||||
|
paddd m1, m4, [r0+r2*4+mmsize*1]
|
||||||
|
paddd m2, m4, [r0+r2*4+mmsize*2]
|
||||||
|
paddd m3, m4, [r0+r2*4+mmsize*3]
|
||||||
|
psrad m0, 3
|
||||||
|
psrad m1, 3
|
||||||
|
psrad m2, 3
|
||||||
|
psrad m3, 3
|
||||||
|
%if cpuflag(sse4) ; avx/sse4
|
||||||
|
packusdw m0, m1
|
||||||
|
packusdw m2, m3
|
||||||
|
%else ; mmx/sse2
|
||||||
|
packssdw m0, m1
|
||||||
|
packssdw m2, m3
|
||||||
|
paddw m0, m5
|
||||||
|
paddw m2, m5
|
||||||
|
%endif ; mmx/sse2/sse4/avx
|
||||||
|
mov%2 [r1+r2*2], m0
|
||||||
|
mov%2 [r1+r2*2+mmsize], m2
|
||||||
|
%else
|
||||||
|
paddsw m0, m2, [r0+r2*2+mmsize*0]
|
||||||
|
paddsw m1, m2, [r0+r2*2+mmsize*1]
|
||||||
|
psraw m0, 15 - %1
|
||||||
|
psraw m1, 15 - %1
|
||||||
|
pmaxsw m0, m4
|
||||||
|
pmaxsw m1, m4
|
||||||
|
pminsw m0, m3
|
||||||
|
pminsw m1, m3
|
||||||
|
mov%2 [r1+r2*2], m0
|
||||||
|
mov%2 [r1+r2*2+mmsize], m1
|
||||||
|
%endif
|
||||||
|
add r2, mmsize
|
||||||
|
jl .loop_%2
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro yuv2plane1_fn 3
|
||||||
|
cglobal yuv2plane1_%1, %3, %3, %2
|
||||||
|
add r2, mmsize - 1
|
||||||
|
and r2, ~(mmsize - 1)
|
||||||
|
%if %1 == 8
|
||||||
|
add r1, r2
|
||||||
|
%else ; %1 != 8
|
||||||
|
lea r1, [r1+r2*2]
|
||||||
|
%endif ; %1 == 8
|
||||||
|
%if %1 == 16
|
||||||
|
lea r0, [r0+r2*4]
|
||||||
|
%else ; %1 != 16
|
||||||
|
lea r0, [r0+r2*2]
|
||||||
|
%endif ; %1 == 16
|
||||||
|
neg r2
|
||||||
|
|
||||||
|
%if %1 == 8
|
||||||
|
pxor m4, m4 ; zero
|
||||||
|
|
||||||
|
; create registers holding dither
|
||||||
|
movq m3, [r3] ; dither
|
||||||
|
test r4d, r4d
|
||||||
|
jz .no_rot
|
||||||
|
%if mmsize == 16
|
||||||
|
punpcklqdq m3, m3
|
||||||
|
%endif ; mmsize == 16
|
||||||
|
PALIGNR_MMX m3, m3, 3, m2
|
||||||
|
.no_rot:
|
||||||
|
%if mmsize == 8
|
||||||
|
mova m2, m3
|
||||||
|
punpckhbw m3, m4 ; byte->word
|
||||||
|
punpcklbw m2, m4 ; byte->word
|
||||||
|
%else
|
||||||
|
punpcklbw m3, m4
|
||||||
|
mova m2, m3
|
||||||
|
%endif
|
||||||
|
%elif %1 == 9
|
||||||
|
pxor m4, m4
|
||||||
|
mova m3, [pw_512]
|
||||||
|
mova m2, [pw_32]
|
||||||
|
%elif %1 == 10
|
||||||
|
pxor m4, m4
|
||||||
|
mova m3, [pw_1024]
|
||||||
|
mova m2, [pw_16]
|
||||||
|
%else ; %1 == 16
|
||||||
|
%if cpuflag(sse4) ; sse4/avx
|
||||||
|
mova m4, [pd_4]
|
||||||
|
%else ; mmx/sse2
|
||||||
|
mova m4, [pd_4min0x40000]
|
||||||
|
mova m5, [minshort]
|
||||||
|
%endif ; mmx/sse2/sse4/avx
|
||||||
|
%endif ; %1 == ..
|
||||||
|
|
||||||
|
; actual pixel scaling
|
||||||
|
%if mmsize == 8
|
||||||
|
yuv2plane1_mainloop %1, a
|
||||||
|
%else ; mmsize == 16
|
||||||
|
test r1, 15
|
||||||
|
jnz .unaligned
|
||||||
|
yuv2plane1_mainloop %1, a
|
||||||
|
REP_RET
|
||||||
|
.unaligned:
|
||||||
|
yuv2plane1_mainloop %1, u
|
||||||
|
%endif ; mmsize == 8/16
|
||||||
|
REP_RET
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%ifdef ARCH_X86_32
|
||||||
|
INIT_MMX mmx
|
||||||
|
yuv2plane1_fn 8, 0, 5
|
||||||
|
yuv2plane1_fn 16, 0, 3
|
||||||
|
|
||||||
|
INIT_MMX mmx2
|
||||||
|
yuv2plane1_fn 9, 0, 3
|
||||||
|
yuv2plane1_fn 10, 0, 3
|
||||||
|
%endif
|
||||||
|
|
||||||
|
INIT_XMM sse2
|
||||||
|
yuv2plane1_fn 8, 5, 5
|
||||||
|
yuv2plane1_fn 9, 5, 3
|
||||||
|
yuv2plane1_fn 10, 5, 3
|
||||||
|
yuv2plane1_fn 16, 6, 3
|
||||||
|
|
||||||
|
INIT_XMM sse4
|
||||||
|
yuv2plane1_fn 16, 5, 3
|
||||||
|
|
||||||
|
INIT_XMM avx
|
||||||
|
yuv2plane1_fn 8, 5, 5
|
||||||
|
yuv2plane1_fn 9, 5, 3
|
||||||
|
yuv2plane1_fn 10, 5, 3
|
||||||
|
yuv2plane1_fn 16, 5, 3
|
@ -1,7 +1,6 @@
|
|||||||
;******************************************************************************
|
;******************************************************************************
|
||||||
;* x86-optimized horizontal/vertical line scaling functions
|
;* x86-optimized horizontal line scaling functions
|
||||||
;* Copyright (c) 2011 Ronald S. Bultje <rsbultje@gmail.com>
|
;* Copyright (c) 2011 Ronald S. Bultje <rsbultje@gmail.com>
|
||||||
;* Kieran Kunhya <kieran@kunhya.com>
|
|
||||||
;*
|
;*
|
||||||
;* This file is part of Libav.
|
;* This file is part of Libav.
|
||||||
;*
|
;*
|
||||||
@ -29,17 +28,6 @@ max_19bit_int: times 4 dd 0x7ffff
|
|||||||
max_19bit_flt: times 4 dd 524287.0
|
max_19bit_flt: times 4 dd 524287.0
|
||||||
minshort: times 8 dw 0x8000
|
minshort: times 8 dw 0x8000
|
||||||
unicoeff: times 4 dd 0x20000000
|
unicoeff: times 4 dd 0x20000000
|
||||||
yuv2yuvX_16_start: times 4 dd 0x4000 - 0x40000000
|
|
||||||
yuv2yuvX_10_start: times 4 dd 0x10000
|
|
||||||
yuv2yuvX_9_start: times 4 dd 0x20000
|
|
||||||
yuv2yuvX_10_upper: times 8 dw 0x3ff
|
|
||||||
yuv2yuvX_9_upper: times 8 dw 0x1ff
|
|
||||||
pd_4: times 4 dd 4
|
|
||||||
pd_4min0x40000:times 4 dd 4 - (0x40000)
|
|
||||||
pw_16: times 8 dw 16
|
|
||||||
pw_32: times 8 dw 32
|
|
||||||
pw_512: times 8 dw 512
|
|
||||||
pw_1024: times 8 dw 1024
|
|
||||||
|
|
||||||
SECTION .text
|
SECTION .text
|
||||||
|
|
||||||
@ -441,371 +429,3 @@ INIT_XMM
|
|||||||
SCALE_FUNCS2 sse2, 6, 7, 8
|
SCALE_FUNCS2 sse2, 6, 7, 8
|
||||||
SCALE_FUNCS2 ssse3, 6, 6, 8
|
SCALE_FUNCS2 ssse3, 6, 6, 8
|
||||||
SCALE_FUNCS2 sse4, 6, 6, 8
|
SCALE_FUNCS2 sse4, 6, 6, 8
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
; vertical line scaling
|
|
||||||
;
|
|
||||||
; void yuv2plane1_<output_size>_<opt>(const int16_t *src, uint8_t *dst, int dstW,
|
|
||||||
; const uint8_t *dither, int offset)
|
|
||||||
; and
|
|
||||||
; void yuv2planeX_<output_size>_<opt>(const int16_t *filter, int filterSize,
|
|
||||||
; const int16_t **src, uint8_t *dst, int dstW,
|
|
||||||
; const uint8_t *dither, int offset)
|
|
||||||
;
|
|
||||||
; Scale one or $filterSize lines of source data to generate one line of output
|
|
||||||
; data. The input is 15-bit in int16_t if $output_size is [8,10] and 19-bit in
|
|
||||||
; int32_t if $output_size is 16. $filter is 12-bits. $filterSize is a multiple
|
|
||||||
; of 2. $offset is either 0 or 3. $dither holds 8 values.
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
%macro yuv2planeX_fn 4
|
|
||||||
|
|
||||||
%ifdef ARCH_X86_32
|
|
||||||
%define cntr_reg r1
|
|
||||||
%define movsx mov
|
|
||||||
%else
|
|
||||||
%define cntr_reg r11
|
|
||||||
%define movsx movsxd
|
|
||||||
%endif
|
|
||||||
|
|
||||||
cglobal yuv2planeX_%2_%1, %4, 7, %3
|
|
||||||
%if %2 == 8 || %2 == 9 || %2 == 10
|
|
||||||
pxor m6, m6
|
|
||||||
%endif ; %2 == 8/9/10
|
|
||||||
|
|
||||||
%if %2 == 8
|
|
||||||
%ifdef ARCH_X86_32
|
|
||||||
%assign pad 0x2c - (stack_offset & 15)
|
|
||||||
SUB rsp, pad
|
|
||||||
%define m_dith m7
|
|
||||||
%else ; x86-64
|
|
||||||
%define m_dith m9
|
|
||||||
%endif ; x86-32
|
|
||||||
|
|
||||||
; create registers holding dither
|
|
||||||
movq m_dith, [r5] ; dither
|
|
||||||
test r6d, r6d
|
|
||||||
jz .no_rot
|
|
||||||
%if mmsize == 16
|
|
||||||
punpcklqdq m_dith, m_dith
|
|
||||||
%endif ; mmsize == 16
|
|
||||||
PALIGNR m_dith, m_dith, 3, m0
|
|
||||||
.no_rot:
|
|
||||||
%if mmsize == 16
|
|
||||||
punpcklbw m_dith, m6
|
|
||||||
%ifdef ARCH_X86_64
|
|
||||||
punpcklwd m8, m_dith, m6
|
|
||||||
pslld m8, 12
|
|
||||||
%else ; x86-32
|
|
||||||
punpcklwd m5, m_dith, m6
|
|
||||||
pslld m5, 12
|
|
||||||
%endif ; x86-32/64
|
|
||||||
punpckhwd m_dith, m6
|
|
||||||
pslld m_dith, 12
|
|
||||||
%ifdef ARCH_X86_32
|
|
||||||
mova [rsp+ 0], m5
|
|
||||||
mova [rsp+16], m_dith
|
|
||||||
%endif
|
|
||||||
%else ; mmsize == 8
|
|
||||||
punpcklbw m5, m_dith, m6
|
|
||||||
punpckhbw m_dith, m6
|
|
||||||
punpcklwd m4, m5, m6
|
|
||||||
punpckhwd m5, m6
|
|
||||||
punpcklwd m3, m_dith, m6
|
|
||||||
punpckhwd m_dith, m6
|
|
||||||
pslld m4, 12
|
|
||||||
pslld m5, 12
|
|
||||||
pslld m3, 12
|
|
||||||
pslld m_dith, 12
|
|
||||||
mova [rsp+ 0], m4
|
|
||||||
mova [rsp+ 8], m5
|
|
||||||
mova [rsp+16], m3
|
|
||||||
mova [rsp+24], m_dith
|
|
||||||
%endif ; mmsize == 8/16
|
|
||||||
%endif ; %2 == 8
|
|
||||||
|
|
||||||
xor r5, r5
|
|
||||||
|
|
||||||
.pixelloop:
|
|
||||||
%assign %%i 0
|
|
||||||
; the rep here is for the 8bit output mmx case, where dither covers
|
|
||||||
; 8 pixels but we can only handle 2 pixels per register, and thus 4
|
|
||||||
; pixels per iteration. In order to not have to keep track of where
|
|
||||||
; we are w.r.t. dithering, we unroll the mmx/8bit loop x2.
|
|
||||||
%if %2 == 8
|
|
||||||
%rep 16/mmsize
|
|
||||||
%endif ; %2 == 8
|
|
||||||
|
|
||||||
%if %2 == 8
|
|
||||||
%ifdef ARCH_X86_32
|
|
||||||
mova m2, [rsp+mmsize*(0+%%i)]
|
|
||||||
mova m1, [rsp+mmsize*(1+%%i)]
|
|
||||||
%else ; x86-64
|
|
||||||
mova m2, m8
|
|
||||||
mova m1, m_dith
|
|
||||||
%endif ; x86-32/64
|
|
||||||
%else ; %2 == 9/10/16
|
|
||||||
mova m1, [yuv2yuvX_%2_start]
|
|
||||||
mova m2, m1
|
|
||||||
%endif ; %2 == 8/9/10/16
|
|
||||||
movsx cntr_reg, r1m
|
|
||||||
.filterloop_ %+ %%i:
|
|
||||||
; input pixels
|
|
||||||
mov r6, [r2+gprsize*cntr_reg-2*gprsize]
|
|
||||||
%if %2 == 16
|
|
||||||
mova m3, [r6+r5*4]
|
|
||||||
mova m5, [r6+r5*4+mmsize]
|
|
||||||
%else ; %2 == 8/9/10
|
|
||||||
mova m3, [r6+r5*2]
|
|
||||||
%endif ; %2 == 8/9/10/16
|
|
||||||
mov r6, [r2+gprsize*cntr_reg-gprsize]
|
|
||||||
%if %2 == 16
|
|
||||||
mova m4, [r6+r5*4]
|
|
||||||
mova m6, [r6+r5*4+mmsize]
|
|
||||||
%else ; %2 == 8/9/10
|
|
||||||
mova m4, [r6+r5*2]
|
|
||||||
%endif ; %2 == 8/9/10/16
|
|
||||||
|
|
||||||
; coefficients
|
|
||||||
movd m0, [r0+2*cntr_reg-4]; coeff[0], coeff[1]
|
|
||||||
%if %2 == 16
|
|
||||||
pshuflw m7, m0, 0 ; coeff[0]
|
|
||||||
pshuflw m0, m0, 0x55 ; coeff[1]
|
|
||||||
pmovsxwd m7, m7 ; word -> dword
|
|
||||||
pmovsxwd m0, m0 ; word -> dword
|
|
||||||
|
|
||||||
pmulld m3, m7
|
|
||||||
pmulld m5, m7
|
|
||||||
pmulld m4, m0
|
|
||||||
pmulld m6, m0
|
|
||||||
|
|
||||||
paddd m2, m3
|
|
||||||
paddd m1, m5
|
|
||||||
paddd m2, m4
|
|
||||||
paddd m1, m6
|
|
||||||
%else ; %2 == 10/9/8
|
|
||||||
punpcklwd m5, m3, m4
|
|
||||||
punpckhwd m3, m4
|
|
||||||
SPLATD m0, m0
|
|
||||||
|
|
||||||
pmaddwd m5, m0
|
|
||||||
pmaddwd m3, m0
|
|
||||||
|
|
||||||
paddd m2, m5
|
|
||||||
paddd m1, m3
|
|
||||||
%endif ; %2 == 8/9/10/16
|
|
||||||
|
|
||||||
sub cntr_reg, 2
|
|
||||||
jg .filterloop_ %+ %%i
|
|
||||||
|
|
||||||
%if %2 == 16
|
|
||||||
psrad m2, 31 - %2
|
|
||||||
psrad m1, 31 - %2
|
|
||||||
%else ; %2 == 10/9/8
|
|
||||||
psrad m2, 27 - %2
|
|
||||||
psrad m1, 27 - %2
|
|
||||||
%endif ; %2 == 8/9/10/16
|
|
||||||
|
|
||||||
%if %2 == 8
|
|
||||||
packssdw m2, m1
|
|
||||||
packuswb m2, m2
|
|
||||||
movh [r3+r5*1], m2
|
|
||||||
%else ; %2 == 9/10/16
|
|
||||||
%if %2 == 16
|
|
||||||
packssdw m2, m1
|
|
||||||
paddw m2, [minshort]
|
|
||||||
%else ; %2 == 9/10
|
|
||||||
%ifidn %1, sse4
|
|
||||||
packusdw m2, m1
|
|
||||||
%elifidn %1, avx
|
|
||||||
packusdw m2, m1
|
|
||||||
%else ; mmx2/sse2
|
|
||||||
packssdw m2, m1
|
|
||||||
pmaxsw m2, m6
|
|
||||||
%endif ; mmx2/sse2/sse4/avx
|
|
||||||
pminsw m2, [yuv2yuvX_%2_upper]
|
|
||||||
%endif ; %2 == 9/10/16
|
|
||||||
mova [r3+r5*2], m2
|
|
||||||
%endif ; %2 == 8/9/10/16
|
|
||||||
|
|
||||||
add r5, mmsize/2
|
|
||||||
sub r4d, mmsize/2
|
|
||||||
%if %2 == 8
|
|
||||||
%assign %%i %%i+2
|
|
||||||
%endrep
|
|
||||||
%endif ; %2 == 8
|
|
||||||
jg .pixelloop
|
|
||||||
|
|
||||||
%if %2 == 8
|
|
||||||
%ifdef ARCH_X86_32
|
|
||||||
ADD rsp, pad
|
|
||||||
RET
|
|
||||||
%else ; x86-64
|
|
||||||
REP_RET
|
|
||||||
%endif ; x86-32/64
|
|
||||||
%else ; %2 == 9/10/16
|
|
||||||
REP_RET
|
|
||||||
%endif ; %2 == 8/9/10/16
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%define PALIGNR PALIGNR_MMX
|
|
||||||
%ifdef ARCH_X86_32
|
|
||||||
INIT_MMX
|
|
||||||
yuv2planeX_fn mmx2, 8, 0, 7
|
|
||||||
yuv2planeX_fn mmx2, 9, 0, 5
|
|
||||||
yuv2planeX_fn mmx2, 10, 0, 5
|
|
||||||
%endif
|
|
||||||
|
|
||||||
INIT_XMM
|
|
||||||
yuv2planeX_fn sse2, 8, 10, 7
|
|
||||||
yuv2planeX_fn sse2, 9, 7, 5
|
|
||||||
yuv2planeX_fn sse2, 10, 7, 5
|
|
||||||
|
|
||||||
%define PALIGNR PALIGNR_SSSE3
|
|
||||||
yuv2planeX_fn sse4, 8, 10, 7
|
|
||||||
yuv2planeX_fn sse4, 9, 7, 5
|
|
||||||
yuv2planeX_fn sse4, 10, 7, 5
|
|
||||||
yuv2planeX_fn sse4, 16, 8, 5
|
|
||||||
|
|
||||||
INIT_AVX
|
|
||||||
yuv2planeX_fn avx, 8, 10, 7
|
|
||||||
yuv2planeX_fn avx, 9, 7, 5
|
|
||||||
yuv2planeX_fn avx, 10, 7, 5
|
|
||||||
|
|
||||||
; %1=outout-bpc, %2=alignment (u/a)
|
|
||||||
%macro yuv2plane1_mainloop 2
|
|
||||||
.loop_%2:
|
|
||||||
%if %1 == 8
|
|
||||||
paddsw m0, m2, [r0+r2*2+mmsize*0]
|
|
||||||
paddsw m1, m3, [r0+r2*2+mmsize*1]
|
|
||||||
psraw m0, 7
|
|
||||||
psraw m1, 7
|
|
||||||
packuswb m0, m1
|
|
||||||
mov%2 [r1+r2], m0
|
|
||||||
%elif %1 == 16
|
|
||||||
paddd m0, m4, [r0+r2*4+mmsize*0]
|
|
||||||
paddd m1, m4, [r0+r2*4+mmsize*1]
|
|
||||||
paddd m2, m4, [r0+r2*4+mmsize*2]
|
|
||||||
paddd m3, m4, [r0+r2*4+mmsize*3]
|
|
||||||
psrad m0, 3
|
|
||||||
psrad m1, 3
|
|
||||||
psrad m2, 3
|
|
||||||
psrad m3, 3
|
|
||||||
%if cpuflag(sse4) ; avx/sse4
|
|
||||||
packusdw m0, m1
|
|
||||||
packusdw m2, m3
|
|
||||||
%else ; mmx/sse2
|
|
||||||
packssdw m0, m1
|
|
||||||
packssdw m2, m3
|
|
||||||
paddw m0, m5
|
|
||||||
paddw m2, m5
|
|
||||||
%endif ; mmx/sse2/sse4/avx
|
|
||||||
mov%2 [r1+r2*2], m0
|
|
||||||
mov%2 [r1+r2*2+mmsize], m2
|
|
||||||
%else
|
|
||||||
paddsw m0, m2, [r0+r2*2+mmsize*0]
|
|
||||||
paddsw m1, m2, [r0+r2*2+mmsize*1]
|
|
||||||
psraw m0, 15 - %1
|
|
||||||
psraw m1, 15 - %1
|
|
||||||
pmaxsw m0, m4
|
|
||||||
pmaxsw m1, m4
|
|
||||||
pminsw m0, m3
|
|
||||||
pminsw m1, m3
|
|
||||||
mov%2 [r1+r2*2], m0
|
|
||||||
mov%2 [r1+r2*2+mmsize], m1
|
|
||||||
%endif
|
|
||||||
add r2, mmsize
|
|
||||||
jl .loop_%2
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%macro yuv2plane1_fn 3
|
|
||||||
cglobal yuv2plane1_%1, %3, %3, %2
|
|
||||||
add r2, mmsize - 1
|
|
||||||
and r2, ~(mmsize - 1)
|
|
||||||
%if %1 == 8
|
|
||||||
add r1, r2
|
|
||||||
%else ; %1 != 8
|
|
||||||
lea r1, [r1+r2*2]
|
|
||||||
%endif ; %1 == 8
|
|
||||||
%if %1 == 16
|
|
||||||
lea r0, [r0+r2*4]
|
|
||||||
%else ; %1 != 16
|
|
||||||
lea r0, [r0+r2*2]
|
|
||||||
%endif ; %1 == 16
|
|
||||||
neg r2
|
|
||||||
|
|
||||||
%if %1 == 8
|
|
||||||
pxor m4, m4 ; zero
|
|
||||||
|
|
||||||
; create registers holding dither
|
|
||||||
movq m3, [r3] ; dither
|
|
||||||
test r4d, r4d
|
|
||||||
jz .no_rot
|
|
||||||
%if mmsize == 16
|
|
||||||
punpcklqdq m3, m3
|
|
||||||
%endif ; mmsize == 16
|
|
||||||
PALIGNR_MMX m3, m3, 3, m2
|
|
||||||
.no_rot:
|
|
||||||
%if mmsize == 8
|
|
||||||
mova m2, m3
|
|
||||||
punpckhbw m3, m4 ; byte->word
|
|
||||||
punpcklbw m2, m4 ; byte->word
|
|
||||||
%else
|
|
||||||
punpcklbw m3, m4
|
|
||||||
mova m2, m3
|
|
||||||
%endif
|
|
||||||
%elif %1 == 9
|
|
||||||
pxor m4, m4
|
|
||||||
mova m3, [pw_512]
|
|
||||||
mova m2, [pw_32]
|
|
||||||
%elif %1 == 10
|
|
||||||
pxor m4, m4
|
|
||||||
mova m3, [pw_1024]
|
|
||||||
mova m2, [pw_16]
|
|
||||||
%else ; %1 == 16
|
|
||||||
%if cpuflag(sse4) ; sse4/avx
|
|
||||||
mova m4, [pd_4]
|
|
||||||
%else ; mmx/sse2
|
|
||||||
mova m4, [pd_4min0x40000]
|
|
||||||
mova m5, [minshort]
|
|
||||||
%endif ; mmx/sse2/sse4/avx
|
|
||||||
%endif ; %1 == ..
|
|
||||||
|
|
||||||
; actual pixel scaling
|
|
||||||
%if mmsize == 8
|
|
||||||
yuv2plane1_mainloop %1, a
|
|
||||||
%else ; mmsize == 16
|
|
||||||
test r1, 15
|
|
||||||
jnz .unaligned
|
|
||||||
yuv2plane1_mainloop %1, a
|
|
||||||
REP_RET
|
|
||||||
.unaligned:
|
|
||||||
yuv2plane1_mainloop %1, u
|
|
||||||
%endif ; mmsize == 8/16
|
|
||||||
REP_RET
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%ifdef ARCH_X86_32
|
|
||||||
INIT_MMX mmx
|
|
||||||
yuv2plane1_fn 8, 0, 5
|
|
||||||
yuv2plane1_fn 16, 0, 3
|
|
||||||
|
|
||||||
INIT_MMX mmx2
|
|
||||||
yuv2plane1_fn 9, 0, 3
|
|
||||||
yuv2plane1_fn 10, 0, 3
|
|
||||||
%endif
|
|
||||||
|
|
||||||
INIT_XMM sse2
|
|
||||||
yuv2plane1_fn 8, 5, 5
|
|
||||||
yuv2plane1_fn 9, 5, 3
|
|
||||||
yuv2plane1_fn 10, 5, 3
|
|
||||||
yuv2plane1_fn 16, 6, 3
|
|
||||||
|
|
||||||
INIT_XMM sse4
|
|
||||||
yuv2plane1_fn 16, 5, 3
|
|
||||||
|
|
||||||
INIT_XMM avx
|
|
||||||
yuv2plane1_fn 8, 5, 5
|
|
||||||
yuv2plane1_fn 9, 5, 3
|
|
||||||
yuv2plane1_fn 10, 5, 3
|
|
||||||
yuv2plane1_fn 16, 5, 3
|
|
||||||
|
@ -369,6 +369,11 @@ do_audio_encoding g726.wav "-b:a 32k -ac 1 -ar 8000 -acodec g726"
|
|||||||
do_audio_decoding
|
do_audio_decoding
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -n "$do_adpcm_adx" ] ; then
|
||||||
|
do_audio_encoding adpcm_adx.adx "-acodec adpcm_adx"
|
||||||
|
do_audio_decoding
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -n "$do_adpcm_ima_wav" ] ; then
|
if [ -n "$do_adpcm_ima_wav" ] ; then
|
||||||
do_audio_encoding adpcm_ima.wav "-acodec adpcm_ima_wav"
|
do_audio_encoding adpcm_ima.wav "-acodec adpcm_ima_wav"
|
||||||
do_audio_decoding
|
do_audio_decoding
|
||||||
|
4
tests/ref/acodec/adpcm_adx
Normal file
4
tests/ref/acodec/adpcm_adx
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
0a30509d9296b857e134b762b76dbc31 *./tests/data/acodec/adpcm_adx.adx
|
||||||
|
297720 ./tests/data/acodec/adpcm_adx.adx
|
||||||
|
2dbc601ed5259f4d74dc48ccd8da7eaf *./tests/data/adpcm_adx.acodec.out.wav
|
||||||
|
stddev: 6989.46 PSNR: 19.44 MAXDIFF:65398 bytes: 1058432/ 1058400
|
Loading…
Reference in New Issue
Block a user