* 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
Unified · Split
| @@ -145,7 +145,7 @@ easier to use. The changes are: · 144 unmodified lines | ||
| 145 | 145 | - pan audio filter |
| 146 | 146 | - IFF Amiga Continuous Bitmap (ACBM) decoder |
| 147 | 147 | - ass filter |
| 148 | −- CRI ADX audio format demuxer | |
| 148 | +- CRI ADX audio format muxer and demuxer | |
| 149 | 149 | - Playstation Portable PMP format demuxer |
| 150 | 150 | - Microsoft Windows ICO demuxer |
| 151 | 151 | - life source |
| @@ -88,6 +88,11 @@ · 87 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | #include "libavutil/avassert.h" |
| 90 | 90 | |
| 91 | +#define VSYNC_AUTO -1 | |
| 92 | +#define VSYNC_PASSTHROUGH 0 | |
| 93 | +#define VSYNC_CFR 1 | |
| 94 | +#define VSYNC_VFR 2 | |
| 95 | + | |
| 91 | 96 | const char program_name[] = "avconv"; |
| 92 | 97 | const int program_birth_year = 2000; |
| 93 | 98 | |
| @@ -127,7 +132,7 @@ static int do_hex_dump = 0; · 33 unmodified lines | ||
| 127 | 132 | static int do_pkt_dump = 0; |
| 128 | 133 | static int do_pass = 0; |
| 129 | 134 | static const char *pass_logfilename_prefix; |
| 130 | −static int video_sync_method = -1; | |
| 135 | +static int video_sync_method = VSYNC_AUTO; | |
| 131 | 136 | static int audio_sync_method = 0; |
| 132 | 137 | static float audio_drift_threshold = 0.1; |
| 133 | 138 | static int copy_ts = 0; |
| @@ -1390,16 +1395,16 @@ static void do_video_out(AVFormatContext *s, · 1256 unmodified lines | ||
| 1390 | 1395 | *frame_size = 0; |
| 1391 | 1396 | |
| 1392 | 1397 | format_video_sync = video_sync_method; |
| 1393 | − if (format_video_sync < 0) | |
| 1394 | − format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? 0 : | |
| 1395 | − (s->oformat->flags & AVFMT_VARIABLE_FPS) ? 2 : 1; | |
| 1398 | + if (format_video_sync == VSYNC_AUTO) | |
| 1399 | + format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : | |
| 1400 | + (s->oformat->flags & AVFMT_VARIABLE_FPS) ? VSYNC_VFR : VSYNC_CFR; | |
| 1396 | 1401 | |
| 1397 | − if (format_video_sync) { | |
| 1402 | + if (format_video_sync != VSYNC_PASSTHROUGH) { | |
| 1398 | 1403 | double vdelta = sync_ipts - ost->sync_opts; |
| 1399 | 1404 | // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c |
| 1400 | 1405 | if (vdelta < -1.1) |
| 1401 | 1406 | nb_frames = 0; |
| 1402 | − else if (format_video_sync == 2) { | |
| 1407 | + else if (format_video_sync == VSYNC_VFR) { | |
| 1403 | 1408 | if (vdelta <= -0.6) { |
| 1404 | 1409 | nb_frames = 0; |
| 1405 | 1410 | } else if (vdelta > 0.6) |
| @@ -4426,6 +4431,17 @@ static int opt_video_filters(OptionsContext *o, const char *opt, const char *arg · 3020 unmodified lines | ||
| 4426 | 4431 | return parse_option(o, "filter:v", arg, options); |
| 4427 | 4432 | } |
| 4428 | 4433 | |
| 4434 | +static int opt_vsync(const char *opt, const char *arg) | |
| 4435 | +{ | |
| 4436 | + if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR; | |
| 4437 | + else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR; | |
| 4438 | + else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH; | |
| 4439 | + | |
| 4440 | + if (video_sync_method == VSYNC_AUTO) | |
| 4441 | + video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR); | |
| 4442 | + return 0; | |
| 4443 | +} | |
| 4444 | + | |
| 4429 | 4445 | #define OFFSET(x) offsetof(OptionsContext, x) |
| 4430 | 4446 | static const OptionDef options[] = { |
| 4431 | 4447 | /* main options */ |
| @@ -4457,7 +4473,7 @@ static const OptionDef options[] = { · 25 unmodified lines | ||
| 4457 | 4473 | "when dumping packets, also dump the payload" }, |
| 4458 | 4474 | { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(rate_emu)}, "read input at native frame rate", "" }, |
| 4459 | 4475 | { "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" }, |
| 4460 | − { "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" }, | |
| 4476 | + { "vsync", HAS_ARG | OPT_EXPERT, {(void*)opt_vsync}, "video sync method", "" }, | |
| 4461 | 4477 | { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" }, |
| 4462 | 4478 | { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" }, |
| 4463 | 4479 | { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" }, |
| @@ -1226,6 +1226,7 @@ HAVE_LIST=" · 1225 unmodified lines | ||
| 1226 | 1226 | struct_sockaddr_in6 |
| 1227 | 1227 | struct_sockaddr_sa_len |
| 1228 | 1228 | struct_sockaddr_storage |
| 1229 | + struct_v4l2_frmivalenum_discrete | |
| 1229 | 1230 | symver |
| 1230 | 1231 | symver_asm_label |
| 1231 | 1232 | symver_gnu_asm |
| @@ -3174,6 +3175,8 @@ makeinfo --version > /dev/null 2>&1 && enable makeinfo || disable makeinfo · 1942 unmodified lines | ||
| 3174 | 3175 | check_header linux/fb.h |
| 3175 | 3176 | check_header linux/videodev.h |
| 3176 | 3177 | check_header linux/videodev2.h |
| 3178 | +check_struct linux/videodev2.h "struct v4l2_frmivalenum" discrete | |
| 3179 | + | |
| 3177 | 3180 | check_header sys/videoio.h |
| 3178 | 3181 | |
| 3179 | 3182 | check_func_headers "windows.h vfw.h" capCreateCaptureWindow "$vfwcap_indev_extralibs" |
| @@ -174,6 +174,10 @@ API changes, most recent first: · 173 unmodified lines | ||
| 174 | 174 | 2011-08-14 - 323b930 - lavu 51.12.0 |
| 175 | 175 | Add av_fifo_peek2(), deprecate av_fifo_peek(). |
| 176 | 176 | |
| 177 | +2011-08-26 - lavu 51.9.0 | |
| 178 | + - add41de..abc78a5 Do not include intfloat_readwrite.h, | |
| 179 | + mathematics.h, rational.h, pixfmt.h, or log.h from avutil.h. | |
| 180 | + | |
| 177 | 181 | 2011-08-16 - 48f9e45 - lavf 53.8.0 |
| 178 | 182 | Add avformat_query_codec(). |
| 179 | 183 | |
| @@ -749,15 +749,15 @@ Thread count. · 748 unmodified lines | ||
| 749 | 749 | Video sync method. |
| 750 | 750 | |
| 751 | 751 | @table @option |
| 752 | −@item 0 | |
| 752 | +@item passthrough | |
| 753 | 753 | Each frame is passed with its timestamp from the demuxer to the muxer. |
| 754 | −@item 1 | |
| 754 | +@item cfr | |
| 755 | 755 | Frames will be duplicated and dropped to achieve exactly the requested |
| 756 | 756 | constant framerate. |
| 757 | −@item 2 | |
| 757 | +@item vfr | |
| 758 | 758 | Frames are passed through with their timestamp or dropped so as to |
| 759 | 759 | prevent 2 frames from having the same timestamp. |
| 760 | −@item -1 | |
| 760 | +@item auto | |
| 761 | 761 | Chooses between 1 and 2 depending on muxer capabilities. This is the |
| 762 | 762 | default method. |
| 763 | 763 | @end table |
| @@ -134,7 +134,7 @@ library: · 133 unmodified lines | ||
| 134 | 134 | @item Brute Force & Ignorance @tab @tab X |
| 135 | 135 | @tab Used in the game Flash Traffic: City of Angels. |
| 136 | 136 | @item BWF @tab X @tab X |
| 137 | −@item CRI ADX @tab @tab X | |
| 137 | +@item CRI ADX @tab X @tab X | |
| 138 | 138 | @tab Audio-only format used in console video games. |
| 139 | 139 | @item Discworld II BMV @tab @tab X |
| 140 | 140 | @item Interplay C93 @tab @tab X |
| @@ -515,9 +515,9 @@ kind @file{/dev/video@var{N}}, where @var{N} is a number associated to · 514 unmodified lines | ||
| 515 | 515 | the device. |
| 516 | 516 | |
| 517 | 517 | Video4Linux and Video4Linux2 devices only support a limited set of |
| 518 | −@var{width}x@var{height} sizes and frame rates. You can check which are | |
| 518 | +@var{width}x@var{height} sizes and framerates. You can check which are | |
| 519 | 519 | supported for example with the command @command{dov4l} for Video4Linux |
| 520 | −devices and the command @command{v4l-info} for Video4Linux2 devices. | |
| 520 | +devices and using @command{-list_formats all} for Video4Linux2 devices. | |
| 521 | 521 | |
| 522 | 522 | If the size for the device is set to 0x0, the input device will |
| 523 | 523 | try to auto-detect the size to use. |
| @@ -93,6 +93,11 @@ · 92 unmodified lines | ||
| 93 | 93 | |
| 94 | 94 | #include "libavutil/avassert.h" |
| 95 | 95 | |
| 96 | +#define VSYNC_AUTO -1 | |
| 97 | +#define VSYNC_PASSTHROUGH 0 | |
| 98 | +#define VSYNC_CFR 1 | |
| 99 | +#define VSYNC_VFR 2 | |
| 100 | + | |
| 96 | 101 | const char program_name[] = "ffmpeg"; |
| 97 | 102 | const int program_birth_year = 2000; |
| 98 | 103 | |
| @@ -144,7 +149,7 @@ static int do_pkt_dump = 0; · 45 unmodified lines | ||
| 144 | 149 | static int do_psnr = 0; |
| 145 | 150 | static int do_pass = 0; |
| 146 | 151 | static const char *pass_logfilename_prefix; |
| 147 | −static int video_sync_method = -1; | |
| 152 | +static int video_sync_method = VSYNC_AUTO; | |
| 148 | 153 | static int audio_sync_method = 0; |
| 149 | 154 | static float audio_drift_threshold = 0.1; |
| 150 | 155 | static int copy_ts = 0; |
| @@ -1433,15 +1438,15 @@ static void do_video_out(AVFormatContext *s, · 1282 unmodified lines | ||
| 1433 | 1438 | *frame_size = 0; |
| 1434 | 1439 | |
| 1435 | 1440 | format_video_sync = video_sync_method; |
| 1436 | − if (format_video_sync < 0) | |
| 1437 | − format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? 0 : 2) : 1; | |
| 1441 | + if (format_video_sync == VSYNC_AUTO) | |
| 1442 | + format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : 1; | |
| 1438 | 1443 | |
| 1439 | − if (format_video_sync) { | |
| 1444 | + if (format_video_sync != VSYNC_PASSTHROUGH) { | |
| 1440 | 1445 | double vdelta = sync_ipts - ost->sync_opts + duration; |
| 1441 | 1446 | // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c |
| 1442 | 1447 | if (vdelta < -1.1) |
| 1443 | 1448 | nb_frames = 0; |
| 1444 | − else if (format_video_sync == 2) { | |
| 1449 | + else if (format_video_sync == VSYNC_VFR) { | |
| 1445 | 1450 | if (vdelta <= -0.6) { |
| 1446 | 1451 | nb_frames = 0; |
| 1447 | 1452 | } else if (vdelta > 0.6) |
| @@ -4873,6 +4878,17 @@ static int opt_video_filters(OptionsContext *o, const char *opt, const char *arg · 3425 unmodified lines | ||
| 4873 | 4878 | return parse_option(o, "filter:v", arg, options); |
| 4874 | 4879 | } |
| 4875 | 4880 | |
| 4881 | +static int opt_vsync(const char *opt, const char *arg) | |
| 4882 | +{ | |
| 4883 | + if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR; | |
| 4884 | + else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR; | |
| 4885 | + else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH; | |
| 4886 | + | |
| 4887 | + if (video_sync_method == VSYNC_AUTO) | |
| 4888 | + video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR); | |
| 4889 | + return 0; | |
| 4890 | +} | |
| 4891 | + | |
| 4876 | 4892 | #define OFFSET(x) offsetof(OptionsContext, x) |
| 4877 | 4893 | static const OptionDef options[] = { |
| 4878 | 4894 | /* main options */ |
| @@ -4908,7 +4924,7 @@ static const OptionDef options[] = { · 29 unmodified lines | ||
| 4908 | 4924 | { "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "deprecated, use -loop" }, |
| 4909 | 4925 | { "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "deprecated, use -loop", "" }, |
| 4910 | 4926 | { "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" }, |
| 4911 | − { "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" }, | |
| 4927 | + { "vsync", HAS_ARG | OPT_EXPERT, {(void*)opt_vsync}, "video sync method", "" }, | |
| 4912 | 4928 | { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" }, |
| 4913 | 4929 | { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" }, |
| 4914 | 4930 | { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" }, |
| @@ -165,6 +165,13 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, · 164 unmodified lines | ||
| 165 | 165 | return buf - avpkt->data; |
| 166 | 166 | } |
| 167 | 167 | |
| 168 | +static void adx_decode_flush(AVCodecContext *avctx) | |
| 169 | +{ | |
| 170 | + ADXContext *c = avctx->priv_data; | |
| 171 | + memset(c->prev, 0, sizeof(c->prev)); | |
| 172 | + c->eof = 0; | |
| 173 | +} | |
| 174 | + | |
| 168 | 175 | AVCodec ff_adpcm_adx_decoder = { |
| 169 | 176 | .name = "adpcm_adx", |
| 170 | 177 | .type = AVMEDIA_TYPE_AUDIO, |
| @@ -172,6 +179,7 @@ AVCodec ff_adpcm_adx_decoder = { · 1 unmodified line | ||
| 172 | 179 | .priv_data_size = sizeof(ADXContext), |
| 173 | 180 | .init = adx_decode_init, |
| 174 | 181 | .decode = adx_decode_frame, |
| 182 | + .flush = adx_decode_flush, | |
| 175 | 183 | .capabilities = CODEC_CAP_DR1, |
| 176 | 184 | .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), |
| 177 | 185 | }; |
| @@ -19,9 +19,9 @@ · 18 unmodified lines | ||
| 19 | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | 20 | */ |
| 21 | 21 | |
| 22 | −#include "libavutil/intreadwrite.h" | |
| 23 | 22 | #include "avcodec.h" |
| 24 | 23 | #include "adx.h" |
| 24 | +#include "bytestream.h" | |
| 25 | 25 | #include "put_bits.h" |
| 26 | 26 | |
| 27 | 27 | /** |
| @@ -33,167 +33,135 @@ · 5 unmodified lines | ||
| 33 | 33 | * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ |
| 34 | 34 | */ |
| 35 | 35 | |
| 36 | −/* 18 bytes <-> 32 samples */ | |
| 37 | − | |
| 38 | −static void adx_encode(ADXContext *c, unsigned char *adx, const short *wav, | |
| 39 | − ADXChannelState *prev) | |
| 36 | +static void adx_encode(ADXContext *c, uint8_t *adx, const int16_t *wav, | |
| 37 | + ADXChannelState *prev, int channels) | |
| 40 | 38 | { |
| 41 | 39 | PutBitContext pb; |
| 42 | 40 | int scale; |
| 43 | − int i; | |
| 44 | − int s0,s1,s2,d; | |
| 45 | − int max=0; | |
| 46 | − int min=0; | |
| 47 | − int data[32]; | |
| 41 | + int i, j; | |
| 42 | + int s0, s1, s2, d; | |
| 43 | + int max = 0; | |
| 44 | + int min = 0; | |
| 45 | + int data[BLOCK_SAMPLES]; | |
| 48 | 46 | |
| 49 | 47 | s1 = prev->s1; |
| 50 | 48 | s2 = prev->s2; |
| 51 | − for(i=0;i<32;i++) { | |
| 49 | + for (i = 0, j = 0; j < 32; i += channels, j++) { | |
| 52 | 50 | s0 = wav[i]; |
| 53 | 51 | d = ((s0 << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS; |
| 54 | − data[i]=d; | |
| 55 | − if (max<d) max=d; | |
| 56 | − if (min>d) min=d; | |
| 52 | + data[j] = d; | |
| 53 | + if (max < d) | |
| 54 | + max = d; | |
| 55 | + if (min > d) | |
| 56 | + min = d; | |
| 57 | 57 | s2 = s1; |
| 58 | 58 | s1 = s0; |
| 59 | 59 | } |
| 60 | 60 | prev->s1 = s1; |
| 61 | 61 | prev->s2 = s2; |
| 62 | 62 | |
| 63 | − /* -8..+7 */ | |
| 64 | − | |
| 65 | − if (max==0 && min==0) { | |
| 66 | − memset(adx,0,18); | |
| 63 | + if (max == 0 && min == 0) { | |
| 64 | + memset(adx, 0, BLOCK_SIZE); | |
| 67 | 65 | return; |
| 68 | 66 | } |
| 69 | 67 | |
| 70 | − if (max/7>-min/8) scale = max/7; | |
| 71 | − else scale = -min/8; | |
| 68 | + if (max / 7 > -min / 8) | |
| 69 | + scale = max / 7; | |
| 70 | + else | |
| 71 | + scale = -min / 8; | |
| 72 | 72 | |
| 73 | − if (scale==0) scale=1; | |
| 73 | + if (scale == 0) | |
| 74 | + scale = 1; | |
| 74 | 75 | |
| 75 | 76 | AV_WB16(adx, scale); |
| 76 | 77 | |
| 77 | 78 | init_put_bits(&pb, adx + 2, 16); |
| 78 | − for (i = 0; i < 32; i++) | |
| 79 | − put_sbits(&pb, 4, av_clip(data[i]/scale, -8, 7)); | |
| 79 | + for (i = 0; i < BLOCK_SAMPLES; i++) | |
| 80 | + put_sbits(&pb, 4, av_clip(data[i] / scale, -8, 7)); | |
| 80 | 81 | flush_put_bits(&pb); |
| 81 | 82 | } |
| 82 | 83 | |
| 83 | −static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize) | |
| 84 | +#define HEADER_SIZE 36 | |
| 85 | + | |
| 86 | +static int adx_encode_header(AVCodecContext *avctx, uint8_t *buf, int bufsize) | |
| 84 | 87 | { |
| 85 | −#if 0 | |
| 86 | − struct { | |
| 87 | − uint32_t offset; /* 0x80000000 + sample start - 4 */ | |
| 88 | − unsigned char unknown1[3]; /* 03 12 04 */ | |
| 89 | − unsigned char channel; /* 1 or 2 */ | |
| 90 | − uint32_t freq; | |
| 91 | − uint32_t size; | |
| 92 | − uint32_t unknown2; /* 01 f4 03 00 */ | |
| 93 | − uint32_t unknown3; /* 00 00 00 00 */ | |
| 94 | − uint32_t unknown4; /* 00 00 00 00 */ | |
| 95 | − | |
| 96 | − /* if loop | |
| 97 | − unknown3 00 15 00 01 | |
| 98 | − unknown4 00 00 00 01 | |
| 99 | − long loop_start_sample; | |
| 100 | − long loop_start_byte; | |
| 101 | − long loop_end_sample; | |
| 102 | − long loop_end_byte; | |
| 103 | − long | |
| 104 | − */ | |
| 105 | − } adxhdr; /* big endian */ | |
| 106 | − /* offset-6 "(c)CRI" */ | |
| 107 | −#endif | |
| 108 | 88 | ADXContext *c = avctx->priv_data; |
| 109 | 89 | |
| 110 | − AV_WB32(buf+0x00,0x80000000|0x20); | |
| 111 | − AV_WB32(buf+0x04,0x03120400|avctx->channels); | |
| 112 | − AV_WB32(buf+0x08,avctx->sample_rate); | |
| 113 | − AV_WB32(buf+0x0c,0); /* FIXME: set after */ | |
| 114 | − AV_WB16(buf + 0x10, c->cutoff); | |
| 115 | − AV_WB32(buf + 0x12, 0x03000000); | |
| 116 | − AV_WB32(buf + 0x16, 0x00000000); | |
| 117 | − AV_WB32(buf + 0x1a, 0x00000000); | |
| 118 | − memcpy (buf + 0x1e, "(c)CRI", 6); | |
| 119 | − return 0x20+4; | |
| 90 | + if (bufsize < HEADER_SIZE) | |
| 91 | + return AVERROR(EINVAL); | |
| 92 | + | |
| 93 | + bytestream_put_be16(&buf, 0x8000); /* header signature */ | |
| 94 | + bytestream_put_be16(&buf, HEADER_SIZE - 4); /* copyright offset */ | |
| 95 | + bytestream_put_byte(&buf, 3); /* encoding */ | |
| 96 | + bytestream_put_byte(&buf, BLOCK_SIZE); /* block size */ | |
| 97 | + bytestream_put_byte(&buf, 4); /* sample size */ | |
| 98 | + bytestream_put_byte(&buf, avctx->channels); /* channels */ | |
| 99 | + bytestream_put_be32(&buf, avctx->sample_rate); /* sample rate */ | |
| 100 | + bytestream_put_be32(&buf, 0); /* total sample count */ | |
| 101 | + bytestream_put_be16(&buf, c->cutoff); /* cutoff frequency */ | |
| 102 | + bytestream_put_byte(&buf, 3); /* version */ | |
| 103 | + bytestream_put_byte(&buf, 0); /* flags */ | |
| 104 | + bytestream_put_be32(&buf, 0); /* unknown */ | |
| 105 | + bytestream_put_be32(&buf, 0); /* loop enabled */ | |
| 106 | + bytestream_put_be16(&buf, 0); /* padding */ | |
| 107 | + bytestream_put_buffer(&buf, "(c)CRI", 6); /* copyright signature */ | |
| 108 | + | |
| 109 | + return HEADER_SIZE; | |
| 120 | 110 | } |
| 121 | 111 | |
| 122 | 112 | static av_cold int adx_encode_init(AVCodecContext *avctx) |
| 123 | 113 | { |
| 124 | 114 | ADXContext *c = avctx->priv_data; |
| 125 | 115 | |
| 126 | − if (avctx->channels > 2) | |
| 127 | − return -1; /* only stereo or mono =) */ | |
| 128 | − avctx->frame_size = 32; | |
| 129 | − | |
| 130 | − avctx->coded_frame= avcodec_alloc_frame(); | |
| 131 | − avctx->coded_frame->key_frame= 1; | |
| 116 | + if (avctx->channels > 2) { | |
| 117 | + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); | |
| 118 | + return AVERROR(EINVAL); | |
| 119 | + } | |
| 120 | + avctx->frame_size = BLOCK_SAMPLES; | |
| 132 | 121 | |
| 133 | −// avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; | |
| 122 | + avctx->coded_frame = avcodec_alloc_frame(); | |
| 134 | 123 | |
| 135 | 124 | /* the cutoff can be adjusted, but this seems to work pretty well */ |
| 136 | 125 | c->cutoff = 500; |
| 137 | 126 | ff_adx_calculate_coeffs(c->cutoff, avctx->sample_rate, COEFF_BITS, c->coeff); |
| 138 | 127 | |
| 139 | − av_log(avctx, AV_LOG_DEBUG, "adx encode init\n"); | |
| 140 | − | |
| 141 | 128 | return 0; |
| 142 | 129 | } |
| 143 | 130 | |
| 144 | 131 | static av_cold int adx_encode_close(AVCodecContext *avctx) |
| 145 | 132 | { |
| 146 | 133 | av_freep(&avctx->coded_frame); |
| 147 | − | |
| 148 | 134 | return 0; |
| 149 | 135 | } |
| 150 | 136 | |
| 151 | −static int adx_encode_frame(AVCodecContext *avctx, | |
| 152 | − uint8_t *frame, int buf_size, void *data) | |
| 137 | +static int adx_encode_frame(AVCodecContext *avctx, uint8_t *frame, | |
| 138 | + int buf_size, void *data) | |
| 153 | 139 | { |
| 154 | − ADXContext *c = avctx->priv_data; | |
| 155 | − const short *samples = data; | |
| 156 | − unsigned char *dst = frame; | |
| 157 | − int rest = avctx->frame_size; | |
| 158 | − | |
| 159 | −/* | |
| 160 | − input data size = | |
| 161 | − ffmpeg.c: do_audio_out() | |
| 162 | − frame_bytes = enc->frame_size * 2 * enc->channels; | |
| 163 | −*/ | |
| 140 | + ADXContext *c = avctx->priv_data; | |
| 141 | + const int16_t *samples = data; | |
| 142 | + uint8_t *dst = frame; | |
| 143 | + int ch; | |
| 164 | 144 | |
| 165 | −// printf("sz=%d ",buf_size); fflush(stdout); | |
| 166 | 145 | if (!c->header_parsed) { |
| 167 | − int hdrsize = adx_encode_header(avctx,dst,buf_size); | |
| 168 | − dst+=hdrsize; | |
| 146 | + int hdrsize; | |
| 147 | + if ((hdrsize = adx_encode_header(avctx, dst, buf_size)) < 0) { | |
| 148 | + av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n"); | |
| 149 | + return AVERROR(EINVAL); | |
| 150 | + } | |
| 151 | + dst += hdrsize; | |
| 152 | + buf_size -= hdrsize; | |
| 169 | 153 | c->header_parsed = 1; |
| 170 | 154 | } |
| 155 | + if (buf_size < BLOCK_SIZE * avctx->channels) { | |
| 156 | + av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n"); | |
| 157 | + return AVERROR(EINVAL); | |
| 158 | + } | |
| 171 | 159 | |
| 172 | − if (avctx->channels==1) { | |
| 173 | − while(rest>=32) { | |
| 174 | − adx_encode(c, dst, samples, c->prev); | |
| 175 | − dst+=18; | |
| 176 | − samples+=32; | |
| 177 | − rest-=32; | |
| 178 | − } | |
| 179 | − } else { | |
| 180 | − while(rest>=32*2) { | |
| 181 | − short tmpbuf[32*2]; | |
| 182 | − int i; | |
| 183 | − | |
| 184 | − for(i=0;i<32;i++) { | |
| 185 | − tmpbuf[i] = samples[i*2]; | |
| 186 | − tmpbuf[i+32] = samples[i*2+1]; | |
| 187 | − } | |
| 188 | − | |
| 189 | − adx_encode(c, dst, tmpbuf, c->prev); | |
| 190 | − adx_encode(c, dst + 18, tmpbuf + 32, c->prev + 1); | |
| 191 | − dst+=18*2; | |
| 192 | − samples+=32*2; | |
| 193 | − rest-=32*2; | |
| 194 | − } | |
| 160 | + for (ch = 0; ch < avctx->channels; ch++) { | |
| 161 | + adx_encode(c, dst, samples + ch, &c->prev[ch], avctx->channels); | |
| 162 | + dst += BLOCK_SIZE; | |
| 195 | 163 | } |
| 196 | − return dst-frame; | |
| 164 | + return dst - frame; | |
| 197 | 165 | } |
| 198 | 166 | |
| 199 | 167 | AVCodec ff_adpcm_adx_encoder = { |
| @@ -204,6 +172,7 @@ AVCodec ff_adpcm_adx_encoder = { · 4 unmodified lines | ||
| 204 | 172 | .init = adx_encode_init, |
| 205 | 173 | .encode = adx_encode_frame, |
| 206 | 174 | .close = adx_encode_close, |
| 207 | − .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, | |
| 208 | − .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), | |
| 175 | + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, | |
| 176 | + AV_SAMPLE_FMT_NONE }, | |
| 177 | + .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), | |
| 209 | 178 | }; |
| @@ -25,12 +25,9 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | void ff_rv34_inv_transform_neon(DCTELEM *block); |
| 27 | 27 | void ff_rv34_inv_transform_noround_neon(DCTELEM *block); |
| 28 | −void ff_rv34_dequant4x4_neon(DCTELEM *block, int Qdc, int Q); | |
| 29 | 28 | |
| 30 | 29 | void ff_rv34dsp_init_neon(RV34DSPContext *c, DSPContext* dsp) |
| 31 | 30 | { |
| 32 | 31 | c->rv34_inv_transform_tab[0] = ff_rv34_inv_transform_neon; |
| 33 | 32 | c->rv34_inv_transform_tab[1] = ff_rv34_inv_transform_noround_neon; |
| 34 | − | |
| 35 | − c->rv34_dequant4x4 = ff_rv34_dequant4x4_neon; | |
| 36 | 33 | } |
| @@ -107,27 +107,3 @@ function ff_rv34_inv_transform_noround_neon, export=1 · 106 unmodified lines | ||
| 107 | 107 | vst4.16 {d0[3], d1[3], d2[3], d3[3]}, [r2,:64], r1 |
| 108 | 108 | bx lr |
| 109 | 109 | endfunc |
| 110 | − | |
| 111 | −function ff_rv34_dequant4x4_neon, export=1 | |
| 112 | − mov r3, r0 | |
| 113 | − mov r12, #16 | |
| 114 | − vdup.16 q0, r2 | |
| 115 | − vmov.16 d0[0], r1 | |
| 116 | − vld1.16 {d2}, [r0,:64], r12 | |
| 117 | − vld1.16 {d4}, [r0,:64], r12 | |
| 118 | − vld1.16 {d6}, [r0,:64], r12 | |
| 119 | − vld1.16 {d16}, [r0,:64], r12 | |
| 120 | − vmull.s16 q1, d2, d0 | |
| 121 | − vmull.s16 q2, d4, d1 | |
| 122 | − vmull.s16 q3, d6, d1 | |
| 123 | − vmull.s16 q8, d16, d1 | |
| 124 | − vqrshrn.s32 d2, q1, #4 | |
| 125 | − vqrshrn.s32 d4, q2, #4 | |
| 126 | − vqrshrn.s32 d6, q3, #4 | |
| 127 | − vqrshrn.s32 d16, q8, #4 | |
| 128 | − vst1.16 {d2}, [r3,:64], r12 | |
| 129 | − vst1.16 {d4}, [r3,:64], r12 | |
| 130 | − vst1.16 {d6}, [r3,:64], r12 | |
| 131 | − vst1.16 {d16}, [r3,:64], r12 | |
| 132 | − bx lr | |
| 133 | −endfunc | |
| @@ -39,11 +39,15 @@ static av_always_inline void bytestream_put_ ##name(uint8_t **b, const type valu · 38 unmodified lines | ||
| 39 | 39 | write(*b, value);\ |
| 40 | 40 | (*b) += bytes;\ |
| 41 | 41 | }\ |
| 42 | +static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g)\ | |
| 43 | +{\ | |
| 44 | + return bytestream_get_ ## name(&g->buffer);\ | |
| 45 | +}\ | |
| 42 | 46 | static av_always_inline type bytestream2_get_ ## name(GetByteContext *g)\ |
| 43 | 47 | {\ |
| 44 | 48 | if (g->buffer_end - g->buffer < bytes)\ |
| 45 | 49 | return 0;\ |
| 46 | − return bytestream_get_ ## name(&g->buffer);\ | |
| 50 | + return bytestream2_get_ ## name ## u(g);\ | |
| 47 | 51 | }\ |
| 48 | 52 | static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g)\ |
| 49 | 53 | {\ |
| @@ -109,10 +109,6 @@ void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){ · 108 unmodified lines | ||
| 109 | 109 | c->low= 0; |
| 110 | 110 | c->range= 0x1FE; |
| 111 | 111 | c->outstanding_count= 0; |
| 112 | −#ifdef STRICT_LIMITS | |
| 113 | − c->sym_count =0; | |
| 114 | −#endif | |
| 115 | − | |
| 116 | 112 | c->pb.bit_left++; //avoids firstBitFlag |
| 117 | 113 | } |
| 118 | 114 | |
| @@ -183,10 +179,6 @@ static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ · 64 unmodified lines | ||
| 183 | 179 | } |
| 184 | 180 | |
| 185 | 181 | renorm_cabac_encoder(c); |
| 186 | − | |
| 187 | −#ifdef STRICT_LIMITS | |
| 188 | − c->symCount++; | |
| 189 | −#endif | |
| 190 | 182 | } |
| 191 | 183 | |
| 192 | 184 | /** |
| @@ -208,10 +200,6 @@ static void put_cabac_bypass(CABACContext *c, int bit){ · 15 unmodified lines | ||
| 208 | 200 | put_cabac_bit(c, 1); |
| 209 | 201 | c->low -= 0x400; |
| 210 | 202 | } |
| 211 | − | |
| 212 | −#ifdef STRICT_LIMITS | |
| 213 | − c->symCount++; | |
| 214 | −#endif | |
| 215 | 203 | } |
| 216 | 204 | |
| 217 | 205 | /** |
| @@ -236,10 +224,6 @@ static int put_cabac_terminate(CABACContext *c, int bit){ · 18 unmodified lines | ||
| 236 | 224 | flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong |
| 237 | 225 | } |
| 238 | 226 | |
| 239 | −#ifdef STRICT_LIMITS | |
| 240 | − c->symCount++; | |
| 241 | −#endif | |
| 242 | − | |
| 243 | 227 | return (put_bits_count(&c->pb)+7)>>3; |
| 244 | 228 | } |
| 245 | 229 | |
| @@ -365,21 +349,6 @@ START_TIMER · 119 unmodified lines | ||
| 365 | 349 | av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i); |
| 366 | 350 | STOP_TIMER("get_cabac") |
| 367 | 351 | } |
| 368 | −#if 0 | |
| 369 | − for(i=0; i<SIZE; i++){ | |
| 370 | −START_TIMER | |
| 371 | − if( r[i] != get_cabac_u(&c, state, (i&1) ? 6 : 7, 3, i&1) ) | |
| 372 | − av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i); | |
| 373 | −STOP_TIMER("get_cabac_u") | |
| 374 | − } | |
| 375 | − | |
| 376 | − for(i=0; i<SIZE; i++){ | |
| 377 | −START_TIMER | |
| 378 | − if( r[i] != get_cabac_ueg(&c, state, 3, 0, 1, 2)) | |
| 379 | − av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i); | |
| 380 | −STOP_TIMER("get_cabac_ueg") | |
| 381 | − } | |
| 382 | −#endif | |
| 383 | 352 | if(!get_cabac_terminate(&c)) |
| 384 | 353 | av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n"); |
| 385 | 354 | |
| @@ -41,9 +41,6 @@ typedef struct CABACContext{ · 40 unmodified lines | ||
| 41 | 41 | int low; |
| 42 | 42 | int range; |
| 43 | 43 | int outstanding_count; |
| 44 | −#ifdef STRICT_LIMITS | |
| 45 | − int symCount; | |
| 46 | −#endif | |
| 47 | 44 | const uint8_t *bytestream_start; |
| 48 | 45 | const uint8_t *bytestream; |
| 49 | 46 | const uint8_t *bytestream_end; |
| @@ -216,62 +213,4 @@ static int av_unused get_cabac_terminate(CABACContext *c){ · 166 unmodified lines | ||
| 216 | 213 | } |
| 217 | 214 | } |
| 218 | 215 | |
| 219 | −#if 0 | |
| 220 | −/** | |
| 221 | − * Get (truncated) unary binarization. | |
| 222 | − */ | |
| 223 | −static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){ | |
| 224 | − int i; | |
| 225 | − | |
| 226 | − for(i=0; i<max; i++){ | |
| 227 | − if(get_cabac(c, state)==0) | |
| 228 | − return i; | |
| 229 | − | |
| 230 | − if(i< max_index) state++; | |
| 231 | − } | |
| 232 | − | |
| 233 | − return truncated ? max : -1; | |
| 234 | −} | |
| 235 | − | |
| 236 | −/** | |
| 237 | − * get unary exp golomb k-th order binarization. | |
| 238 | − */ | |
| 239 | −static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){ | |
| 240 | − int i, v; | |
| 241 | − int m= 1<<k; | |
| 242 | − | |
| 243 | − if(get_cabac(c, state)==0) | |
| 244 | − return 0; | |
| 245 | − | |
| 246 | − if(0 < max_index) state++; | |
| 247 | − | |
| 248 | − for(i=1; i<max; i++){ | |
| 249 | − if(get_cabac(c, state)==0){ | |
| 250 | − if(is_signed && get_cabac_bypass(c)){ | |
| 251 | − return -i; | |
| 252 | − }else | |
| 253 | − return i; | |
| 254 | − } | |
| 255 | − | |
| 256 | − if(i < max_index) state++; | |
| 257 | − } | |
| 258 | − | |
| 259 | − while(get_cabac_bypass(c)){ | |
| 260 | − i+= m; | |
| 261 | − m+= m; | |
| 262 | − } | |
| 263 | − | |
| 264 | − v=0; | |
| 265 | − while(m>>=1){ | |
| 266 | − v+= v + get_cabac_bypass(c); | |
| 267 | − } | |
| 268 | − i += v; | |
| 269 | − | |
| 270 | − if(is_signed && get_cabac_bypass(c)){ | |
| 271 | − return -i; | |
| 272 | − }else | |
| 273 | − return i; | |
| 274 | −} | |
| 275 | −#endif /* 0 */ | |
| 276 | − | |
| 277 | 216 | #endif /* AVCODEC_CABAC_H */ |
| @@ -578,9 +578,8 @@ static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, int jobnr, int · 577 unmodified lines | ||
| 578 | 578 | |
| 579 | 579 | for (i = 0; i < 8; i++) { |
| 580 | 580 | DCTELEM *block = ctx->blocks[i]; |
| 581 | − int last_index, overflow; | |
| 582 | − int n = dnxhd_switch_matrix(ctx, i); | |
| 583 | − last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow); | |
| 581 | + int overflow, n = dnxhd_switch_matrix(ctx, i); | |
| 582 | + int last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow); | |
| 584 | 583 | //START_TIMER; |
| 585 | 584 | dnxhd_encode_block(ctx, block, last_index, n); |
| 586 | 585 | //STOP_TIMER("encode_block"); |
| @@ -4051,7 +4051,7 @@ static int decode_frame(AVCodecContext *avctx, · 4050 unmodified lines | ||
| 4051 | 4051 | H264Context *h = avctx->priv_data; |
| 4052 | 4052 | MpegEncContext *s = &h->s; |
| 4053 | 4053 | AVFrame *pict = data; |
| 4054 | − int buf_index; | |
| 4054 | + int buf_index = 0; | |
| 4055 | 4055 | Picture *out; |
| 4056 | 4056 | int i, out_idx; |
| 4057 | 4057 | |
| @@ -4081,7 +4081,7 @@ static int decode_frame(AVCodecContext *avctx, · 23 unmodified lines | ||
| 4081 | 4081 | *pict= *(AVFrame*)out; |
| 4082 | 4082 | } |
| 4083 | 4083 | |
| 4084 | − return buf_size; | |
| 4084 | + return buf_index; | |
| 4085 | 4085 | } |
| 4086 | 4086 | if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){ |
| 4087 | 4087 | int cnt= buf[5]&0x1f; |
| @@ -4112,7 +4112,6 @@ not_extra: · 24 unmodified lines | ||
| 4112 | 4112 | |
| 4113 | 4113 | if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) { |
| 4114 | 4114 | av_assert0(buf_index <= buf_size); |
| 4115 | − buf_size = buf_index; | |
| 4116 | 4115 | goto out; |
| 4117 | 4116 | } |
| 4118 | 4117 | |
| @@ -4193,9 +4192,7 @@ int main(void){ · 74 unmodified lines | ||
| 4193 | 4192 | |
| 4194 | 4193 | init_get_bits(&gb, temp, 8*SIZE); |
| 4195 | 4194 | for(i=0; i<COUNT; i++){ |
| 4196 | − int j, s; | |
| 4197 | − | |
| 4198 | − s= show_bits(&gb, 24); | |
| 4195 | + int j, s = show_bits(&gb, 24); | |
| 4199 | 4196 | |
| 4200 | 4197 | {START_TIMER |
| 4201 | 4198 | j= get_ue_golomb(&gb); |
| @@ -4218,9 +4215,7 @@ int main(void){ · 16 unmodified lines | ||
| 4218 | 4215 | |
| 4219 | 4216 | init_get_bits(&gb, temp, 8*SIZE); |
| 4220 | 4217 | for(i=0; i<COUNT; i++){ |
| 4221 | − int j, s; | |
| 4222 | − | |
| 4223 | − s= show_bits(&gb, 24); | |
| 4218 | + int j, s = show_bits(&gb, 24); | |
| 4224 | 4219 | |
| 4225 | 4220 | {START_TIMER |
| 4226 | 4221 | j= get_se_golomb(&gb); |
| @@ -760,7 +760,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, · 759 unmodified lines | ||
| 760 | 760 | |
| 761 | 761 | switch_buffers(ctx); |
| 762 | 762 | |
| 763 | − //START_TIMER; | |
| 763 | + //{ START_TIMER; | |
| 764 | 764 | |
| 765 | 765 | if (ctx->frame_type != FRAMETYPE_NULL) { |
| 766 | 766 | for (p = 0; p < 3; p++) { |
| @@ -775,7 +775,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, · 8 unmodified lines | ||
| 775 | 775 | } |
| 776 | 776 | } |
| 777 | 777 | |
| 778 | − //STOP_TIMER("decode_planes"); | |
| 778 | + //STOP_TIMER("decode_planes"); } | |
| 779 | 779 | |
| 780 | 780 | if (ctx->frame.data[0]) |
| 781 | 781 | avctx->release_buffer(avctx, &ctx->frame); |
| @@ -83,7 +83,8 @@ typedef struct { · 82 unmodified lines | ||
| 83 | 83 | int abr; ///< flag to enable ABR |
| 84 | 84 | int pkt_frame_count; ///< frame count for the current packet |
| 85 | 85 | int lookahead; ///< encoder delay |
| 86 | − int sample_count; ///< total sample count (used for pts) | |
| 86 | + int64_t next_pts; ///< next pts, in sample_rate time base | |
| 87 | + int pkt_sample_count; ///< sample count in the current packet | |
| 87 | 88 | } LibSpeexEncContext; |
| 88 | 89 | |
| 89 | 90 | static av_cold void print_enc_params(AVCodecContext *avctx, |
| @@ -201,7 +202,7 @@ static av_cold int encode_init(AVCodecContext *avctx) · 111 unmodified lines | ||
| 201 | 202 | |
| 202 | 203 | /* set encoding delay */ |
| 203 | 204 | speex_encoder_ctl(s->enc_state, SPEEX_GET_LOOKAHEAD, &s->lookahead); |
| 204 | − s->sample_count = -s->lookahead; | |
| 205 | + s->next_pts = -s->lookahead; | |
| 205 | 206 | |
| 206 | 207 | /* create header packet bytes from header struct */ |
| 207 | 208 | /* 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, · 27 unmodified lines | ||
| 235 | 236 | { |
| 236 | 237 | LibSpeexEncContext *s = avctx->priv_data; |
| 237 | 238 | int16_t *samples = data; |
| 238 | − int sample_count = s->sample_count; | |
| 239 | 239 | |
| 240 | 240 | if (data) { |
| 241 | 241 | /* encode Speex frame */ |
| @@ -243,7 +243,7 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, · 1 unmodified line | ||
| 243 | 243 | speex_encode_stereo_int(samples, s->header.frame_size, &s->bits); |
| 244 | 244 | speex_encode_int(s->enc_state, samples, &s->bits); |
| 245 | 245 | s->pkt_frame_count++; |
| 246 | − s->sample_count += avctx->frame_size; | |
| 246 | + s->pkt_sample_count += avctx->frame_size; | |
| 247 | 247 | } else { |
| 248 | 248 | /* handle end-of-stream */ |
| 249 | 249 | if (!s->pkt_frame_count) |
| @@ -259,8 +259,10 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, · 9 unmodified lines | ||
| 259 | 259 | if (s->pkt_frame_count == s->frames_per_packet) { |
| 260 | 260 | s->pkt_frame_count = 0; |
| 261 | 261 | avctx->coded_frame->pts = |
| 262 | − av_rescale_q(sample_count, (AVRational){ 1, avctx->sample_rate }, | |
| 262 | + av_rescale_q(s->next_pts, (AVRational){ 1, avctx->sample_rate }, | |
| 263 | 263 | avctx->time_base); |
| 264 | + s->next_pts += s->pkt_sample_count; | |
| 265 | + s->pkt_sample_count = 0; | |
| 264 | 266 | if (buf_size > speex_bits_nbytes(&s->bits)) { |
| 265 | 267 | int ret = speex_bits_write(&s->bits, frame, buf_size); |
| 266 | 268 | speex_bits_reset(&s->bits); |
| @@ -212,7 +212,7 @@ static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table) · 211 unmodified lines | ||
| 212 | 212 | /** |
| 213 | 213 | * Get one coefficient value from the bistream and store it. |
| 214 | 214 | */ |
| 215 | −static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc) | |
| 215 | +static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q) | |
| 216 | 216 | { |
| 217 | 217 | if(coef){ |
| 218 | 218 | if(coef == esc){ |
| @@ -225,14 +225,14 @@ static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext * · 6 unmodified lines | ||
| 225 | 225 | } |
| 226 | 226 | if(get_bits1(gb)) |
| 227 | 227 | coef = -coef; |
| 228 | − *dst = coef; | |
| 228 | + *dst = (coef*q + 8) >> 4; | |
| 229 | 229 | } |
| 230 | 230 | } |
| 231 | 231 | |
| 232 | 232 | /** |
| 233 | 233 | * Decode 2x2 subblock of coefficients. |
| 234 | 234 | */ |
| 235 | −static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc) | |
| 235 | +static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q) | |
| 236 | 236 | { |
| 237 | 237 | int coeffs[4]; |
| 238 | 238 | |
| @@ -240,15 +240,35 @@ static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, · 1 unmodified line | ||
| 240 | 240 | coeffs[1] = modulo_three_table[code][1]; |
| 241 | 241 | coeffs[2] = modulo_three_table[code][2]; |
| 242 | 242 | coeffs[3] = modulo_three_table[code][3]; |
| 243 | − decode_coeff(dst , coeffs[0], 3, gb, vlc); | |
| 243 | + decode_coeff(dst , coeffs[0], 3, gb, vlc, q); | |
| 244 | 244 | if(is_block2){ |
| 245 | − decode_coeff(dst+8, coeffs[1], 2, gb, vlc); | |
| 246 | − decode_coeff(dst+1, coeffs[2], 2, gb, vlc); | |
| 245 | + decode_coeff(dst+8, coeffs[1], 2, gb, vlc, q); | |
| 246 | + decode_coeff(dst+1, coeffs[2], 2, gb, vlc, q); | |
| 247 | 247 | }else{ |
| 248 | − decode_coeff(dst+1, coeffs[1], 2, gb, vlc); | |
| 249 | − decode_coeff(dst+8, coeffs[2], 2, gb, vlc); | |
| 248 | + decode_coeff(dst+1, coeffs[1], 2, gb, vlc, q); | |
| 249 | + decode_coeff(dst+8, coeffs[2], 2, gb, vlc, q); | |
| 250 | 250 | } |
| 251 | − decode_coeff(dst+9, coeffs[3], 2, gb, vlc); | |
| 251 | + decode_coeff(dst+9, coeffs[3], 2, gb, vlc, q); | |
| 252 | +} | |
| 253 | + | |
| 254 | +static inline void decode_subblock3(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, | |
| 255 | + int q_dc, int q_ac1, int q_ac2) | |
| 256 | +{ | |
| 257 | + int coeffs[4]; | |
| 258 | + | |
| 259 | + coeffs[0] = modulo_three_table[code][0]; | |
| 260 | + coeffs[1] = modulo_three_table[code][1]; | |
| 261 | + coeffs[2] = modulo_three_table[code][2]; | |
| 262 | + coeffs[3] = modulo_three_table[code][3]; | |
| 263 | + decode_coeff(dst , coeffs[0], 3, gb, vlc, q_dc); | |
| 264 | + if(is_block2){ | |
| 265 | + decode_coeff(dst+8, coeffs[1], 2, gb, vlc, q_ac1); | |
| 266 | + decode_coeff(dst+1, coeffs[2], 2, gb, vlc, q_ac1); | |
| 267 | + }else{ | |
| 268 | + decode_coeff(dst+1, coeffs[1], 2, gb, vlc, q_ac1); | |
| 269 | + decode_coeff(dst+8, coeffs[2], 2, gb, vlc, q_ac1); | |
| 270 | + } | |
| 271 | + decode_coeff(dst+9, coeffs[3], 2, gb, vlc, q_ac2); | |
| 252 | 272 | } |
| 253 | 273 | |
| 254 | 274 | /** |
| @@ -262,7 +282,7 @@ static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, · 7 unmodified lines | ||
| 262 | 282 | * o--o |
| 263 | 283 | */ |
| 264 | 284 | |
| 265 | −static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc) | |
| 285 | +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) | |
| 266 | 286 | { |
| 267 | 287 | int code, pattern; |
| 268 | 288 | |
| @@ -271,39 +291,23 @@ static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *r · 2 unmodified lines | ||
| 271 | 291 | pattern = code & 0x7; |
| 272 | 292 | |
| 273 | 293 | code >>= 3; |
| 274 | − decode_subblock(dst, code, 0, gb, &rvlc->coefficient); | |
| 294 | + decode_subblock3(dst, code, 0, gb, &rvlc->coefficient, q_dc, q_ac1, q_ac2); | |
| 275 | 295 | |
| 276 | 296 | if(pattern & 4){ |
| 277 | 297 | code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2); |
| 278 | − decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient); | |
| 298 | + decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient, q_ac2); | |
| 279 | 299 | } |
| 280 | 300 | if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block |
| 281 | 301 | code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2); |
| 282 | − decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient); | |
| 302 | + decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient, q_ac2); | |
| 283 | 303 | } |
| 284 | 304 | if(pattern & 1){ |
| 285 | 305 | code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2); |
| 286 | − decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient); | |
| 306 | + decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient, q_ac2); | |
| 287 | 307 | } |
| 288 | 308 | |
| 289 | 309 | } |
| 290 | 310 | |
| 291 | −/** | |
| 292 | − * Dequantize 4x4 block of DC values for 16x16 macroblock. | |
| 293 | − * @todo optimize | |
| 294 | − */ | |
| 295 | −static inline void rv34_dequant4x4_16x16(DCTELEM *block, int Qdc, int Q) | |
| 296 | −{ | |
| 297 | − int i; | |
| 298 | − | |
| 299 | − for(i = 0; i < 3; i++) | |
| 300 | − block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Qdc + 8) >> 4; | |
| 301 | − for(; i < 16; i++) | |
| 302 | − block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Q + 8) >> 4; | |
| 303 | −} | |
| 304 | −/** @} */ //block functions | |
| 305 | − | |
| 306 | − | |
| 307 | 311 | /** |
| 308 | 312 | * @name RV30/40 bitstream parsing |
| 309 | 313 | * @{ |
| @@ -676,8 +680,9 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type, · 366 unmodified lines | ||
| 676 | 680 | srcY += src_y * s->linesize + src_x; |
| 677 | 681 | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 678 | 682 | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 679 | − if( (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 | |
| 680 | − || (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4){ | |
| 683 | + if(s->h_edge_pos - (width << 3) < 6 || s->v_edge_pos - (height << 3) < 6 || | |
| 684 | + (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 || | |
| 685 | + (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4) { | |
| 681 | 686 | uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize; |
| 682 | 687 | |
| 683 | 688 | srcY -= 2 + 2*s->linesize; |
| @@ -1097,6 +1102,7 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types) · 413 unmodified lines | ||
| 1097 | 1102 | MpegEncContext *s = &r->s; |
| 1098 | 1103 | GetBitContext *gb = &s->gb; |
| 1099 | 1104 | int cbp, cbp2; |
| 1105 | + int q_dc, q_ac; | |
| 1100 | 1106 | int i, blknum, blkoff; |
| 1101 | 1107 | LOCAL_ALIGNED_16(DCTELEM, block16, [64]); |
| 1102 | 1108 | int luma_dc_quant; |
| @@ -1133,31 +1139,34 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types) · 30 unmodified lines | ||
| 1133 | 1139 | |
| 1134 | 1140 | luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16 ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale]; |
| 1135 | 1141 | if(r->is16){ |
| 1142 | + q_dc = rv34_qscale_tab[luma_dc_quant]; | |
| 1143 | + q_ac = rv34_qscale_tab[s->qscale]; | |
| 1136 | 1144 | memset(block16, 0, 64 * sizeof(*block16)); |
| 1137 | − rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0); | |
| 1138 | − rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]); | |
| 1145 | + rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac); | |
| 1139 | 1146 | r->rdsp.rv34_inv_transform_tab[1](block16); |
| 1140 | 1147 | } |
| 1141 | 1148 | |
| 1149 | + q_ac = rv34_qscale_tab[s->qscale]; | |
| 1142 | 1150 | for(i = 0; i < 16; i++, cbp >>= 1){ |
| 1143 | 1151 | if(!r->is16 && !(cbp & 1)) continue; |
| 1144 | 1152 | blknum = ((i & 2) >> 1) + ((i & 8) >> 2); |
| 1145 | 1153 | blkoff = ((i & 1) << 2) + ((i & 4) << 3); |
| 1146 | 1154 | if(cbp & 1) |
| 1147 | − rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0); | |
| 1148 | − r->rdsp.rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]); | |
| 1155 | + rv34_decode_block(s->block[blknum] + blkoff, gb, | |
| 1156 | + r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac); | |
| 1149 | 1157 | if(r->is16) //FIXME: optimize |
| 1150 | 1158 | s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)]; |
| 1151 | 1159 | r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff); |
| 1152 | 1160 | } |
| 1153 | 1161 | if(r->block_type == RV34_MB_P_MIX16x16) |
| 1154 | 1162 | r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); |
| 1163 | + q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]]; | |
| 1164 | + q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]; | |
| 1155 | 1165 | for(; i < 24; i++, cbp >>= 1){ |
| 1156 | 1166 | if(!(cbp & 1)) continue; |
| 1157 | 1167 | blknum = ((i & 4) >> 2) + 4; |
| 1158 | 1168 | blkoff = ((i & 1) << 2) + ((i & 2) << 4); |
| 1159 | − rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1); | |
| 1160 | − 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]]); | |
| 1169 | + rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1, q_dc, q_ac, q_ac); | |
| 1161 | 1170 | r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff); |
| 1162 | 1171 | } |
| 1163 | 1172 | if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])) |
| @@ -100,16 +100,6 @@ static const uint16_t rv34_qscale_tab[32] = { · 99 unmodified lines | ||
| 100 | 100 | 963, 1074, 1212, 1392, 1566, 1708, 1978, 2211 |
| 101 | 101 | }; |
| 102 | 102 | |
| 103 | −/** | |
| 104 | − * 4x4 dezigzag pattern | |
| 105 | − */ | |
| 106 | −static const uint8_t rv34_dezigzag[16] = { | |
| 107 | − 0, 1, 8, 16, | |
| 108 | − 9, 2, 3, 10, | |
| 109 | − 17, 24, 25, 18, | |
| 110 | − 11, 19, 26, 27 | |
| 111 | −}; | |
| 112 | − | |
| 113 | 103 | /** |
| 114 | 104 | * tables used to translate a quantizer value into a VLC set for decoding |
| 115 | 105 | * The first table is used for intraframes. |
| @@ -100,26 +100,10 @@ static void rv34_inv_transform_noround_c(DCTELEM *block){ · 99 unmodified lines | ||
| 100 | 100 | /** @} */ // transform |
| 101 | 101 | |
| 102 | 102 | |
| 103 | −/** | |
| 104 | − * Dequantize ordinary 4x4 block. | |
| 105 | − */ | |
| 106 | −void ff_rv34_dequant4x4_neon(DCTELEM *block, int Qdc, int Q); | |
| 107 | −static void rv34_dequant4x4_c(DCTELEM *block, int Qdc, int Q) | |
| 108 | −{ | |
| 109 | − int i, j; | |
| 110 | − | |
| 111 | − block[0] = (block[0] * Qdc + 8) >> 4; | |
| 112 | − for (i = 0; i < 4; i++) | |
| 113 | − for (j = !i; j < 4; j++) | |
| 114 | − block[j + i*8] = (block[j + i*8] * Q + 8) >> 4; | |
| 115 | −} | |
| 116 | − | |
| 117 | 103 | av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) { |
| 118 | 104 | c->rv34_inv_transform_tab[0] = rv34_inv_transform_c; |
| 119 | 105 | c->rv34_inv_transform_tab[1] = rv34_inv_transform_noround_c; |
| 120 | 106 | |
| 121 | − c->rv34_dequant4x4 = rv34_dequant4x4_c; | |
| 122 | − | |
| 123 | 107 | if (HAVE_NEON) |
| 124 | 108 | ff_rv34dsp_init_neon(c, dsp); |
| 125 | 109 | } |
| @@ -56,7 +56,6 @@ typedef struct RV34DSPContext { · 55 unmodified lines | ||
| 56 | 56 | h264_chroma_mc_func avg_chroma_pixels_tab[3]; |
| 57 | 57 | rv40_weight_func rv40_weight_pixels_tab[2]; |
| 58 | 58 | rv34_inv_transform_func rv34_inv_transform_tab[2]; |
| 59 | − void (*rv34_dequant4x4)(DCTELEM *block, int Qdc, int Q); | |
| 60 | 59 | rv40_weak_loop_filter_func rv40_weak_loop_filter[2]; |
| 61 | 60 | rv40_strong_loop_filter_func rv40_strong_loop_filter[2]; |
| 62 | 61 | rv40_loop_filter_strength_func rv40_loop_filter_strength[2]; |
| @@ -38,16 +38,9 @@ typedef struct UltimotionDecodeContext { · 37 unmodified lines | ||
| 38 | 38 | int width, height, blocks; |
| 39 | 39 | AVFrame frame; |
| 40 | 40 | const uint8_t *ulti_codebook; |
| 41 | + GetByteContext gb; | |
| 41 | 42 | } UltimotionDecodeContext; |
| 42 | 43 | |
| 43 | −#define CHECK_OVERREAD_SIZE(size) \ | |
| 44 | − do { \ | |
| 45 | − if (buf_end - buf < (size)) { \ | |
| 46 | − av_log(avctx, AV_LOG_ERROR, "Insufficient data\n"); \ | |
| 47 | − return AVERROR_INVALIDDATA; \ | |
| 48 | − } \ | |
| 49 | − } while(0) | |
| 50 | − | |
| 51 | 44 | static av_cold int ulti_decode_init(AVCodecContext *avctx) |
| 52 | 45 | { |
| 53 | 46 | UltimotionDecodeContext *s = avctx->priv_data; |
| @@ -232,7 +225,6 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 178 unmodified lines | ||
| 232 | 225 | int i; |
| 233 | 226 | int skip; |
| 234 | 227 | int tmp; |
| 235 | − const uint8_t *buf_end = buf + buf_size; | |
| 236 | 228 | |
| 237 | 229 | s->frame.reference = 3; |
| 238 | 230 | 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, · 2 unmodified lines | ||
| 241 | 233 | return -1; |
| 242 | 234 | } |
| 243 | 235 | |
| 236 | + bytestream2_init(&s->gb, buf, buf_size); | |
| 237 | + | |
| 244 | 238 | while(!done) { |
| 245 | 239 | int idx; |
| 246 | 240 | if(blocks >= s->blocks || y >= s->height) |
| 247 | 241 | break;//all blocks decoded |
| 248 | 242 | |
| 249 | − CHECK_OVERREAD_SIZE(1); | |
| 250 | − idx = *buf++; | |
| 243 | + if (bytestream2_get_bytes_left(&s->gb) < 1) | |
| 244 | + goto err; | |
| 245 | + idx = bytestream2_get_byteu(&s->gb); | |
| 251 | 246 | if((idx & 0xF8) == 0x70) { |
| 252 | 247 | switch(idx) { |
| 253 | 248 | case 0x70: //change modifier |
| 254 | − CHECK_OVERREAD_SIZE(1); | |
| 255 | − modifier = *buf++; | |
| 249 | + modifier = bytestream2_get_byte(&s->gb); | |
| 256 | 250 | if(modifier>1) |
| 257 | 251 | av_log(avctx, AV_LOG_INFO, "warning: modifier must be 0 or 1, got %i\n", modifier); |
| 258 | 252 | break; |
| @@ -266,8 +260,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 7 unmodified lines | ||
| 266 | 260 | done = 1; |
| 267 | 261 | break; |
| 268 | 262 | case 0x74: //skip some blocks |
| 269 | − CHECK_OVERREAD_SIZE(1); | |
| 270 | − skip = *buf++; | |
| 263 | + skip = bytestream2_get_byte(&s->gb); | |
| 271 | 264 | if ((blocks + skip) >= s->blocks) |
| 272 | 265 | break; |
| 273 | 266 | blocks += skip; |
| @@ -294,8 +287,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 20 unmodified lines | ||
| 294 | 287 | } else { |
| 295 | 288 | cf = 0; |
| 296 | 289 | if (idx) { |
| 297 | − CHECK_OVERREAD_SIZE(1); | |
| 298 | − chroma = *buf++; | |
| 290 | + chroma = bytestream2_get_byte(&s->gb); | |
| 299 | 291 | } |
| 300 | 292 | } |
| 301 | 293 | for (i = 0; i < 4; i++) { // for every subblock |
| @@ -303,15 +295,13 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 1 unmodified line | ||
| 303 | 295 | if(!code) //skip subblock |
| 304 | 296 | continue; |
| 305 | 297 | if(cf) { |
| 306 | − CHECK_OVERREAD_SIZE(1); | |
| 307 | − chroma = *buf++; | |
| 298 | + chroma = bytestream2_get_byte(&s->gb); | |
| 308 | 299 | } |
| 309 | 300 | tx = x + block_coords[i * 2]; |
| 310 | 301 | ty = y + block_coords[(i * 2) + 1]; |
| 311 | 302 | switch(code) { |
| 312 | 303 | case 1: |
| 313 | − CHECK_OVERREAD_SIZE(1); | |
| 314 | − tmp = *buf++; | |
| 304 | + tmp = bytestream2_get_byte(&s->gb); | |
| 315 | 305 | |
| 316 | 306 | angle = angle_by_index[(tmp >> 6) & 0x3]; |
| 317 | 307 | |
| @@ -331,8 +321,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 13 unmodified lines | ||
| 331 | 321 | |
| 332 | 322 | case 2: |
| 333 | 323 | if (modifier) { // unpack four luma samples |
| 334 | − CHECK_OVERREAD_SIZE(3); | |
| 335 | − tmp = bytestream_get_be24(&buf); | |
| 324 | + tmp = bytestream2_get_be24(&s->gb); | |
| 336 | 325 | |
| 337 | 326 | Y[0] = (tmp >> 18) & 0x3F; |
| 338 | 327 | Y[1] = (tmp >> 12) & 0x3F; |
| @@ -340,8 +329,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 1 unmodified line | ||
| 340 | 329 | Y[3] = tmp & 0x3F; |
| 341 | 330 | angle = 16; |
| 342 | 331 | } else { // retrieve luma samples from codebook |
| 343 | − CHECK_OVERREAD_SIZE(2); | |
| 344 | − tmp = bytestream_get_be16(&buf); | |
| 332 | + tmp = bytestream2_get_be16(&s->gb); | |
| 345 | 333 | |
| 346 | 334 | angle = (tmp >> 12) & 0xF; |
| 347 | 335 | tmp &= 0xFFF; |
| @@ -357,27 +345,27 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 9 unmodified lines | ||
| 357 | 345 | if (modifier) { // all 16 luma samples |
| 358 | 346 | uint8_t Luma[16]; |
| 359 | 347 | |
| 360 | − CHECK_OVERREAD_SIZE(12); | |
| 361 | − | |
| 362 | − tmp = bytestream_get_be24(&buf); | |
| 348 | + if (bytestream2_get_bytes_left(&s->gb) < 12) | |
| 349 | + goto err; | |
| 350 | + tmp = bytestream2_get_be24u(&s->gb); | |
| 363 | 351 | Luma[0] = (tmp >> 18) & 0x3F; |
| 364 | 352 | Luma[1] = (tmp >> 12) & 0x3F; |
| 365 | 353 | Luma[2] = (tmp >> 6) & 0x3F; |
| 366 | 354 | Luma[3] = tmp & 0x3F; |
| 367 | 355 | |
| 368 | − tmp = bytestream_get_be24(&buf); | |
| 356 | + tmp = bytestream2_get_be24u(&s->gb); | |
| 369 | 357 | Luma[4] = (tmp >> 18) & 0x3F; |
| 370 | 358 | Luma[5] = (tmp >> 12) & 0x3F; |
| 371 | 359 | Luma[6] = (tmp >> 6) & 0x3F; |
| 372 | 360 | Luma[7] = tmp & 0x3F; |
| 373 | 361 | |
| 374 | − tmp = bytestream_get_be24(&buf); | |
| 362 | + tmp = bytestream2_get_be24u(&s->gb); | |
| 375 | 363 | Luma[8] = (tmp >> 18) & 0x3F; |
| 376 | 364 | Luma[9] = (tmp >> 12) & 0x3F; |
| 377 | 365 | Luma[10] = (tmp >> 6) & 0x3F; |
| 378 | 366 | Luma[11] = tmp & 0x3F; |
| 379 | 367 | |
| 380 | − tmp = bytestream_get_be24(&buf); | |
| 368 | + tmp = bytestream2_get_be24u(&s->gb); | |
| 381 | 369 | Luma[12] = (tmp >> 18) & 0x3F; |
| 382 | 370 | Luma[13] = (tmp >> 12) & 0x3F; |
| 383 | 371 | Luma[14] = (tmp >> 6) & 0x3F; |
| @@ -385,22 +373,23 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 1 unmodified line | ||
| 385 | 373 | |
| 386 | 374 | ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma); |
| 387 | 375 | } else { |
| 388 | − CHECK_OVERREAD_SIZE(4); | |
| 389 | − tmp = *buf++; | |
| 376 | + if (bytestream2_get_bytes_left(&s->gb) < 4) | |
| 377 | + goto err; | |
| 378 | + tmp = bytestream2_get_byteu(&s->gb); | |
| 390 | 379 | if(tmp & 0x80) { |
| 391 | 380 | angle = (tmp >> 4) & 0x7; |
| 392 | − tmp = (tmp << 8) + *buf++; | |
| 381 | + tmp = (tmp << 8) + bytestream2_get_byteu(&s->gb); | |
| 393 | 382 | Y[0] = (tmp >> 6) & 0x3F; |
| 394 | 383 | Y[1] = tmp & 0x3F; |
| 395 | − Y[2] = (*buf++) & 0x3F; | |
| 396 | − Y[3] = (*buf++) & 0x3F; | |
| 384 | + Y[2] = bytestream2_get_byteu(&s->gb) & 0x3F; | |
| 385 | + Y[3] = bytestream2_get_byteu(&s->gb) & 0x3F; | |
| 397 | 386 | ulti_grad(&s->frame, tx, ty, Y, chroma, angle); //draw block |
| 398 | 387 | } else { // some patterns |
| 399 | 388 | int f0, f1; |
| 400 | − f0 = *buf++; | |
| 389 | + f0 = bytestream2_get_byteu(&s->gb); | |
| 401 | 390 | f1 = tmp; |
| 402 | − Y[0] = (*buf++) & 0x3F; | |
| 403 | − Y[1] = (*buf++) & 0x3F; | |
| 391 | + Y[0] = bytestream2_get_byteu(&s->gb) & 0x3F; | |
| 392 | + Y[1] = bytestream2_get_byteu(&s->gb) & 0x3F; | |
| 404 | 393 | ulti_pattern(&s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma); |
| 405 | 394 | } |
| 406 | 395 | } |
| @@ -422,6 +411,11 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 15 unmodified lines | ||
| 422 | 411 | *(AVFrame*)data= s->frame; |
| 423 | 412 | |
| 424 | 413 | return buf_size; |
| 414 | + | |
| 415 | +err: | |
| 416 | + av_log(avctx, AV_LOG_ERROR, | |
| 417 | + "Insufficient data\n"); | |
| 418 | + return AVERROR_INVALIDDATA; | |
| 425 | 419 | } |
| 426 | 420 | |
| 427 | 421 | AVCodec ff_ulti_decoder = { |
| @@ -568,6 +568,7 @@ static void vc1_mc_1mv(VC1Context *v, int dir) · 567 unmodified lines | ||
| 568 | 568 | } |
| 569 | 569 | |
| 570 | 570 | if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) |
| 571 | + || s->h_edge_pos < 22 || v_edge_pos < 22 | |
| 571 | 572 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3 |
| 572 | 573 | || (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel * 3) { |
| 573 | 574 | 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) · 225 unmodified lines | ||
| 799 | 800 | if (fieldmv && (src_y & 1) && src_y < 4) |
| 800 | 801 | src_y--; |
| 801 | 802 | if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) |
| 803 | + || s->h_edge_pos < 13 || v_edge_pos < 23 | |
| 802 | 804 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2 |
| 803 | 805 | || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) { |
| 804 | 806 | srcY -= s->mspel * (1 + (s->linesize << fieldmv)); |
| @@ -998,6 +1000,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) · 193 unmodified lines | ||
| 998 | 1000 | } |
| 999 | 1001 | |
| 1000 | 1002 | if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) |
| 1003 | + || s->h_edge_pos < 18 || v_edge_pos < 18 | |
| 1001 | 1004 | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9 |
| 1002 | 1005 | || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) { |
| 1003 | 1006 | s->dsp.emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize, |
| @@ -1102,6 +1105,7 @@ static void vc1_mc_4mv_chroma4(VC1Context *v) · 98 unmodified lines | ||
| 1102 | 1105 | if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2) |
| 1103 | 1106 | uvsrc_y--; |
| 1104 | 1107 | if ((v->mv_mode == MV_PMODE_INTENSITY_COMP) |
| 1108 | + || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv) | |
| 1105 | 1109 | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5 |
| 1106 | 1110 | || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) { |
| 1107 | 1111 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize, |
| @@ -2006,7 +2010,7 @@ static void vc1_interp_mc(VC1Context *v) · 898 unmodified lines | ||
| 2006 | 2010 | srcV = s->edge_emu_buffer + 18 * s->linesize; |
| 2007 | 2011 | } |
| 2008 | 2012 | |
| 2009 | − if (v->rangeredfrm | |
| 2013 | + if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 | |
| 2010 | 2014 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 16 - s->mspel * 3 |
| 2011 | 2015 | || (unsigned)(src_y - s->mspel) > v_edge_pos - (my & 3) - 16 - s->mspel * 3) { |
| 2012 | 2016 | uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize; |
| @@ -69,19 +69,17 @@ · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | static const int desired_video_buffers = 256; |
| 71 | 71 | |
| 72 | −enum io_method { | |
| 73 | − io_read, | |
| 74 | − io_mmap, | |
| 75 | − io_userptr | |
| 76 | −}; | |
| 72 | +#define V4L_ALLFORMATS 3 | |
| 73 | +#define V4L_RAWFORMATS 1 | |
| 74 | +#define V4L_COMPFORMATS 2 | |
| 77 | 75 | |
| 78 | 76 | struct video_data { |
| 79 | 77 | AVClass *class; |
| 80 | 78 | int fd; |
| 81 | 79 | int frame_format; /* V4L2_PIX_FMT_* */ |
| 82 | − enum io_method io_method; | |
| 83 | 80 | int width, height; |
| 84 | 81 | int frame_size; |
| 82 | + int interlaced; | |
| 85 | 83 | int top_field_first; |
| 86 | 84 | |
| 87 | 85 | int buffers; |
| @@ -89,8 +87,10 @@ struct video_data { · 1 unmodified line | ||
| 89 | 87 | unsigned int *buf_len; |
| 90 | 88 | char *standard; |
| 91 | 89 | int channel; |
| 92 | − char *video_size; /**< String describing video size, set by a private option. */ | |
| 90 | + char *video_size; /**< String describing video size, | |
| 91 | + set by a private option. */ | |
| 93 | 92 | char *pixel_format; /**< Set by a private option. */ |
| 93 | + int list_format; /**< Set by a private option. */ | |
| 94 | 94 | char *framerate; /**< Set by a private option. */ |
| 95 | 95 | }; |
| 96 | 96 | |
| @@ -124,7 +124,7 @@ static struct fmt_map fmt_conversion_table[] = { · 27 unmodified lines | ||
| 124 | 124 | { PIX_FMT_NONE, CODEC_ID_MJPEG, V4L2_PIX_FMT_JPEG }, |
| 125 | 125 | }; |
| 126 | 126 | |
| 127 | −static int device_open(AVFormatContext *ctx, uint32_t *capabilities) | |
| 127 | +static int device_open(AVFormatContext *ctx) | |
| 128 | 128 | { |
| 129 | 129 | struct v4l2_capability cap; |
| 130 | 130 | int fd; |
| @@ -137,11 +137,15 @@ static int device_open(AVFormatContext *ctx, uint32_t *capabilities) · 6 unmodified lines | ||
| 137 | 137 | if (ctx->flags & AVFMT_FLAG_NONBLOCK) { |
| 138 | 138 | flags |= O_NONBLOCK; |
| 139 | 139 | } |
| 140 | + | |
| 140 | 141 | fd = v4l2_open(ctx->filename, flags, 0); |
| 141 | 142 | if (fd < 0) { |
| 143 | + err = errno; | |
| 144 | + | |
| 142 | 145 | av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n", |
| 143 | − ctx->filename, strerror(errno)); | |
| 144 | − return AVERROR(errno); | |
| 146 | + ctx->filename, strerror(err)); | |
| 147 | + | |
| 148 | + return AVERROR(err); | |
| 145 | 149 | } |
| 146 | 150 | #if CONFIG_LIBV4L2 |
| 147 | 151 | fd_libv4l = v4l2_fd_open(fd, 0); |
| @@ -155,53 +159,80 @@ static int device_open(AVFormatContext *ctx, uint32_t *capabilities) · 7 unmodified lines | ||
| 155 | 159 | #endif |
| 156 | 160 | |
| 157 | 161 | res = v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap); |
| 158 | − // ENOIOCTLCMD definition only availble on __KERNEL__ | |
| 159 | − if (res < 0 && ((err = errno) == 515)) { | |
| 160 | − av_log(ctx, AV_LOG_ERROR, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n"); | |
| 161 | − v4l2_close(fd); | |
| 162 | − | |
| 163 | − return AVERROR(515); | |
| 164 | − } | |
| 165 | 162 | if (res < 0) { |
| 163 | + err = errno; | |
| 166 | 164 | av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n", |
| 167 | − strerror(errno)); | |
| 168 | − v4l2_close(fd); | |
| 169 | − return AVERROR(err); | |
| 165 | + strerror(err)); | |
| 166 | + | |
| 167 | + goto fail; | |
| 168 | + } | |
| 169 | + | |
| 170 | + av_log(ctx, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n", | |
| 171 | + fd, cap.capabilities); | |
| 172 | + | |
| 173 | + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { | |
| 174 | + av_log(ctx, AV_LOG_ERROR, "Not a video capture device.\n"); | |
| 175 | + err = ENODEV; | |
| 176 | + | |
| 177 | + goto fail; | |
| 170 | 178 | } |
| 171 | − if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) { | |
| 172 | − av_log(ctx, AV_LOG_ERROR, "Not a video capture device\n"); | |
| 173 | − v4l2_close(fd); | |
| 174 | − return AVERROR(ENODEV); | |
| 179 | + | |
| 180 | + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { | |
| 181 | + av_log(ctx, AV_LOG_ERROR, | |
| 182 | + "The device does not support the streaming I/O method.\n"); | |
| 183 | + err = ENOSYS; | |
| 184 | + | |
| 185 | + goto fail; | |
| 175 | 186 | } |
| 176 | − *capabilities = cap.capabilities; | |
| 177 | 187 | |
| 178 | 188 | return fd; |
| 189 | + | |
| 190 | +fail: | |
| 191 | + v4l2_close(fd); | |
| 192 | + return AVERROR(err); | |
| 179 | 193 | } |
| 180 | 194 | |
| 181 | −static int device_init(AVFormatContext *ctx, int *width, int *height, uint32_t pix_fmt) | |
| 195 | +static int device_init(AVFormatContext *ctx, int *width, int *height, | |
| 196 | + uint32_t pix_fmt) | |
| 182 | 197 | { |
| 183 | 198 | struct video_data *s = ctx->priv_data; |
| 184 | 199 | int fd = s->fd; |
| 185 | − struct v4l2_format fmt = {0}; | |
| 200 | + struct v4l2_format fmt; | |
| 201 | + struct v4l2_pix_format *pix = &fmt.fmt.pix; | |
| 202 | + | |
| 186 | 203 | int res; |
| 187 | 204 | |
| 205 | + memset(&fmt, 0, sizeof(struct v4l2_format)); | |
| 206 | + | |
| 188 | 207 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 189 | − fmt.fmt.pix.width = *width; | |
| 190 | − fmt.fmt.pix.height = *height; | |
| 191 | − fmt.fmt.pix.pixelformat = pix_fmt; | |
| 192 | − fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; | |
| 208 | + pix->width = *width; | |
| 209 | + pix->height = *height; | |
| 210 | + pix->pixelformat = pix_fmt; | |
| 211 | + pix->field = V4L2_FIELD_ANY; | |
| 212 | + | |
| 193 | 213 | res = v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt); |
| 214 | + | |
| 194 | 215 | if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) { |
| 195 | − 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); | |
| 216 | + av_log(ctx, AV_LOG_INFO, | |
| 217 | + "The V4L2 driver changed the video from %dx%d to %dx%d\n", | |
| 218 | + *width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height); | |
| 196 | 219 | *width = fmt.fmt.pix.width; |
| 197 | 220 | *height = fmt.fmt.pix.height; |
| 198 | 221 | } |
| 199 | 222 | |
| 200 | 223 | if (pix_fmt != fmt.fmt.pix.pixelformat) { |
| 201 | − 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); | |
| 224 | + av_log(ctx, AV_LOG_DEBUG, | |
| 225 | + "The V4L2 driver changed the pixel format " | |
| 226 | + "from 0x%08X to 0x%08X\n", | |
| 227 | + pix_fmt, fmt.fmt.pix.pixelformat); | |
| 202 | 228 | res = -1; |
| 203 | 229 | } |
| 204 | 230 | |
| 231 | + if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) { | |
| 232 | + av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver using the interlaced mode"); | |
| 233 | + s->interlaced = 1; | |
| 234 | + } | |
| 235 | + | |
| 205 | 236 | return res; |
| 206 | 237 | } |
| 207 | 238 | |
| @@ -264,6 +295,71 @@ static enum CodecID fmt_v4l2codec(uint32_t v4l2_fmt) · 56 unmodified lines | ||
| 264 | 295 | return CODEC_ID_NONE; |
| 265 | 296 | } |
| 266 | 297 | |
| 298 | +#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE | |
| 299 | +static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t pixelformat) | |
| 300 | +{ | |
| 301 | + struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat }; | |
| 302 | + | |
| 303 | + while(!ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) { | |
| 304 | + switch (vfse.type) { | |
| 305 | + case V4L2_FRMSIZE_TYPE_DISCRETE: | |
| 306 | + av_log(ctx, AV_LOG_INFO, " %ux%u", | |
| 307 | + vfse.discrete.width, vfse.discrete.height); | |
| 308 | + break; | |
| 309 | + case V4L2_FRMSIZE_TYPE_CONTINUOUS: | |
| 310 | + case V4L2_FRMSIZE_TYPE_STEPWISE: | |
| 311 | + av_log(ctx, AV_LOG_INFO, " {%u-%u, %u}x{%u-%u, %u}", | |
| 312 | + vfse.stepwise.min_width, | |
| 313 | + vfse.stepwise.max_width, | |
| 314 | + vfse.stepwise.step_width, | |
| 315 | + vfse.stepwise.min_height, | |
| 316 | + vfse.stepwise.max_height, | |
| 317 | + vfse.stepwise.step_height); | |
| 318 | + } | |
| 319 | + vfse.index++; | |
| 320 | + } | |
| 321 | +} | |
| 322 | +#endif | |
| 323 | + | |
| 324 | +static void list_formats(AVFormatContext *ctx, int fd, int type) | |
| 325 | +{ | |
| 326 | + struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; | |
| 327 | + | |
| 328 | + while(!ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) { | |
| 329 | + enum CodecID codec_id = fmt_v4l2codec(vfd.pixelformat); | |
| 330 | + enum PixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id); | |
| 331 | + | |
| 332 | + vfd.index++; | |
| 333 | + | |
| 334 | + if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) && | |
| 335 | + type & V4L_RAWFORMATS) { | |
| 336 | + const char *fmt_name = av_get_pix_fmt_name(pix_fmt); | |
| 337 | + av_log(ctx, AV_LOG_INFO, "R : %9s : %20s :", | |
| 338 | + fmt_name ? fmt_name : "Unsupported", | |
| 339 | + vfd.description); | |
| 340 | + } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED && | |
| 341 | + type & V4L_COMPFORMATS) { | |
| 342 | + AVCodec *codec = avcodec_find_encoder(codec_id); | |
| 343 | + av_log(ctx, AV_LOG_INFO, "C : %9s : %20s :", | |
| 344 | + codec ? codec->name : "Unsupported", | |
| 345 | + vfd.description); | |
| 346 | + } else { | |
| 347 | + continue; | |
| 348 | + } | |
| 349 | + | |
| 350 | +#ifdef V4L2_FMT_FLAG_EMULATED | |
| 351 | + if (vfd.flags & V4L2_FMT_FLAG_EMULATED) { | |
| 352 | + av_log(ctx, AV_LOG_WARNING, "%s", "Emulated"); | |
| 353 | + continue; | |
| 354 | + } | |
| 355 | +#endif | |
| 356 | +#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE | |
| 357 | + list_framesizes(ctx, fd, vfd.pixelformat); | |
| 358 | +#endif | |
| 359 | + av_log(ctx, AV_LOG_INFO, "\n"); | |
| 360 | + } | |
| 361 | +} | |
| 362 | + | |
| 267 | 363 | static int mmap_init(AVFormatContext *ctx) |
| 268 | 364 | { |
| 269 | 365 | struct video_data *s = ctx->priv_data; |
| @@ -314,12 +410,16 @@ static int mmap_init(AVFormatContext *ctx) · 44 unmodified lines | ||
| 314 | 410 | |
| 315 | 411 | s->buf_len[i] = buf.length; |
| 316 | 412 | if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) { |
| 317 | − av_log(ctx, AV_LOG_ERROR, "Buffer len [%d] = %d != %d\n", i, s->buf_len[i], s->frame_size); | |
| 413 | + av_log(ctx, AV_LOG_ERROR, | |
| 414 | + "Buffer len [%d] = %d != %d\n", | |
| 415 | + i, s->buf_len[i], s->frame_size); | |
| 318 | 416 | |
| 319 | 417 | return -1; |
| 320 | 418 | } |
| 321 | 419 | s->buf_start[i] = v4l2_mmap(NULL, buf.length, |
| 322 | − PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset); | |
| 420 | + PROT_READ | PROT_WRITE, MAP_SHARED, | |
| 421 | + s->fd, buf.m.offset); | |
| 422 | + | |
| 323 | 423 | if (s->buf_start[i] == MAP_FAILED) { |
| 324 | 424 | av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno)); |
| 325 | 425 | return AVERROR(errno); |
| @@ -329,20 +429,14 @@ static int mmap_init(AVFormatContext *ctx) · 3 unmodified lines | ||
| 329 | 429 | return 0; |
| 330 | 430 | } |
| 331 | 431 | |
| 332 | −static int read_init(AVFormatContext *ctx) | |
| 333 | −{ | |
| 334 | − return -1; | |
| 335 | −} | |
| 336 | − | |
| 337 | 432 | static void mmap_release_buffer(AVPacket *pkt) |
| 338 | 433 | { |
| 339 | 434 | struct v4l2_buffer buf = {0}; |
| 340 | 435 | int res, fd; |
| 341 | 436 | struct buff_data *buf_descriptor = pkt->priv; |
| 342 | 437 | |
| 343 | − if (pkt->data == NULL) { | |
| 344 | − return; | |
| 345 | − } | |
| 438 | + if (pkt->data == NULL) | |
| 439 | + return; | |
| 346 | 440 | |
| 347 | 441 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 348 | 442 | buf.memory = V4L2_MEMORY_MMAP; |
| @@ -351,9 +445,10 @@ static void mmap_release_buffer(AVPacket *pkt) · 2 unmodified lines | ||
| 351 | 445 | av_free(buf_descriptor); |
| 352 | 446 | |
| 353 | 447 | res = v4l2_ioctl(fd, VIDIOC_QBUF, &buf); |
| 354 | − if (res < 0) { | |
| 355 | − av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno)); | |
| 356 | − } | |
| 448 | + if (res < 0) | |
| 449 | + av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", | |
| 450 | + strerror(errno)); | |
| 451 | + | |
| 357 | 452 | pkt->data = NULL; |
| 358 | 453 | pkt->size = 0; |
| 359 | 454 | } |
| @@ -375,13 +470,17 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) · 15 unmodified lines | ||
| 375 | 470 | pkt->size = 0; |
| 376 | 471 | return AVERROR(EAGAIN); |
| 377 | 472 | } |
| 378 | − av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno)); | |
| 473 | + av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", | |
| 474 | + strerror(errno)); | |
| 379 | 475 | |
| 380 | 476 | return AVERROR(errno); |
| 381 | 477 | } |
| 382 | 478 | assert(buf.index < s->buffers); |
| 383 | 479 | if (s->frame_size > 0 && buf.bytesused != s->frame_size) { |
| 384 | − av_log(ctx, AV_LOG_ERROR, "The v4l2 frame is %d bytes, but %d bytes are expected\n", buf.bytesused, s->frame_size); | |
| 480 | + av_log(ctx, AV_LOG_ERROR, | |
| 481 | + "The v4l2 frame is %d bytes, but %d bytes are expected\n", | |
| 482 | + buf.bytesused, s->frame_size); | |
| 483 | + | |
| 385 | 484 | return AVERROR_INVALIDDATA; |
| 386 | 485 | } |
| 387 | 486 | |
| @@ -407,11 +506,6 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) · 19 unmodified lines | ||
| 407 | 506 | return s->buf_len[buf.index]; |
| 408 | 507 | } |
| 409 | 508 | |
| 410 | −static int read_frame(AVFormatContext *ctx, AVPacket *pkt) | |
| 411 | −{ | |
| 412 | − return -1; | |
| 413 | −} | |
| 414 | − | |
| 415 | 509 | static int mmap_start(AVFormatContext *ctx) |
| 416 | 510 | { |
| 417 | 511 | struct video_data *s = ctx->priv_data; |
| @@ -427,7 +521,9 @@ static int mmap_start(AVFormatContext *ctx) · 9 unmodified lines | ||
| 427 | 521 | |
| 428 | 522 | res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf); |
| 429 | 523 | if (res < 0) { |
| 430 | − av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno)); | |
| 524 | + av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", | |
| 525 | + strerror(errno)); | |
| 526 | + | |
| 431 | 527 | return AVERROR(errno); |
| 432 | 528 | } |
| 433 | 529 | } |
| @@ -435,7 +531,9 @@ static int mmap_start(AVFormatContext *ctx) · 1 unmodified line | ||
| 435 | 531 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 436 | 532 | res = v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type); |
| 437 | 533 | if (res < 0) { |
| 438 | − av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", strerror(errno)); | |
| 534 | + av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", | |
| 535 | + strerror(errno)); | |
| 536 | + | |
| 439 | 537 | return AVERROR(errno); |
| 440 | 538 | } |
| 441 | 539 | |
| @@ -471,8 +569,10 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap) · 29 unmodified lines | ||
| 471 | 569 | |
| 472 | 570 | streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 473 | 571 | |
| 474 | − if (s->framerate && (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) { | |
| 475 | − av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", s->framerate); | |
| 572 | + if (s->framerate && | |
| 573 | + (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) { | |
| 574 | + av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", | |
| 575 | + s->framerate); | |
| 476 | 576 | return ret; |
| 477 | 577 | } |
| 478 | 578 | |
| @@ -486,7 +586,8 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap) · 7 unmodified lines | ||
| 486 | 586 | av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n", |
| 487 | 587 | s->channel, input.name); |
| 488 | 588 | if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) { |
| 489 | − av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set input(%d) failed\n", | |
| 589 | + av_log(s1, AV_LOG_ERROR, | |
| 590 | + "The V4L2 driver ioctl set input(%d) failed\n", | |
| 490 | 591 | s->channel); |
| 491 | 592 | return AVERROR(EIO); |
| 492 | 593 | } |
| @@ -506,10 +607,12 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap) · 13 unmodified lines | ||
| 506 | 607 | return ret; |
| 507 | 608 | } |
| 508 | 609 | |
| 509 | − av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s, id: %"PRIu64"\n", | |
| 610 | + av_log(s1, AV_LOG_DEBUG, | |
| 611 | + "The V4L2 driver set standard: %s, id: %"PRIu64"\n", | |
| 510 | 612 | s->standard, (uint64_t)standard.id); |
| 511 | 613 | if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) { |
| 512 | − av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n", | |
| 614 | + av_log(s1, AV_LOG_ERROR, | |
| 615 | + "The V4L2 driver ioctl set standard(%s) failed\n", | |
| 513 | 616 | s->standard); |
| 514 | 617 | return AVERROR(EIO); |
| 515 | 618 | } |
| @@ -520,6 +623,7 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap) · 4 unmodified lines | ||
| 520 | 623 | framerate_q.den, framerate_q.num); |
| 521 | 624 | tpf->numerator = framerate_q.den; |
| 522 | 625 | tpf->denominator = framerate_q.num; |
| 626 | + | |
| 523 | 627 | if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) { |
| 524 | 628 | av_log(s1, AV_LOG_ERROR, |
| 525 | 629 | "ioctl set time per frame(%d/%d) failed\n", |
| @@ -530,14 +634,15 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap) · 4 unmodified lines | ||
| 530 | 634 | if (framerate_q.num != tpf->denominator || |
| 531 | 635 | framerate_q.den != tpf->numerator) { |
| 532 | 636 | av_log(s1, AV_LOG_INFO, |
| 533 | − "The driver changed the time per frame from %d/%d to %d/%d\n", | |
| 637 | + "The driver changed the time per frame from " | |
| 638 | + "%d/%d to %d/%d\n", | |
| 534 | 639 | framerate_q.den, framerate_q.num, |
| 535 | 640 | tpf->numerator, tpf->denominator); |
| 536 | 641 | } |
| 537 | 642 | } else { |
| 538 | − /* if timebase value is not set, read the timebase value from the driver */ | |
| 539 | 643 | if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) { |
| 540 | − av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n", strerror(errno)); | |
| 644 | + av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n", | |
| 645 | + strerror(errno)); | |
| 541 | 646 | return AVERROR(errno); |
| 542 | 647 | } |
| 543 | 648 | } |
| @@ -571,6 +676,7 @@ static uint32_t device_try_init(AVFormatContext *s1, · 27 unmodified lines | ||
| 571 | 676 | } |
| 572 | 677 | } |
| 573 | 678 | } |
| 679 | + | |
| 574 | 680 | if (desired_format != 0) { |
| 575 | 681 | *codec_id = fmt_v4l2codec(desired_format); |
| 576 | 682 | assert(*codec_id != CODEC_ID_NONE); |
| @@ -584,7 +690,7 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) · 7 unmodified lines | ||
| 584 | 690 | struct video_data *s = s1->priv_data; |
| 585 | 691 | AVStream *st; |
| 586 | 692 | int res = 0; |
| 587 | − uint32_t desired_format, capabilities; | |
| 693 | + uint32_t desired_format; | |
| 588 | 694 | enum CodecID codec_id; |
| 589 | 695 | enum PixelFormat pix_fmt = PIX_FMT_NONE; |
| 590 | 696 | |
| @@ -593,42 +699,62 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) · 2 unmodified lines | ||
| 593 | 699 | res = AVERROR(ENOMEM); |
| 594 | 700 | goto out; |
| 595 | 701 | } |
| 596 | − avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ | |
| 597 | 702 | |
| 598 | − if (s->video_size && (res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) { | |
| 599 | − av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n", s->video_size); | |
| 703 | + s->fd = device_open(s1); | |
| 704 | + if (s->fd < 0) { | |
| 705 | + res = s->fd; | |
| 600 | 706 | goto out; |
| 601 | 707 | } |
| 602 | − if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) { | |
| 603 | − av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format); | |
| 604 | − res = AVERROR(EINVAL); | |
| 708 | + | |
| 709 | + if (s->list_format) { | |
| 710 | + list_formats(s1, s->fd, s->list_format); | |
| 711 | + res = AVERROR_EXIT; | |
| 605 | 712 | goto out; |
| 606 | 713 | } |
| 607 | 714 | |
| 608 | − capabilities = 0; | |
| 609 | − s->fd = device_open(s1, &capabilities); | |
| 610 | − if (s->fd < 0) { | |
| 611 | − res = AVERROR(EIO); | |
| 715 | + avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ | |
| 716 | + | |
| 717 | + if (s->video_size && | |
| 718 | + (res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) { | |
| 719 | + av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n", | |
| 720 | + s->video_size); | |
| 612 | 721 | goto out; |
| 613 | 722 | } |
| 614 | − av_log(s1, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n", s->fd, capabilities); | |
| 723 | + | |
| 724 | + if (s->pixel_format) { | |
| 725 | + | |
| 726 | + pix_fmt = av_get_pix_fmt(s->pixel_format); | |
| 727 | + | |
| 728 | + if (pix_fmt == PIX_FMT_NONE) { | |
| 729 | + av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", | |
| 730 | + s->pixel_format); | |
| 731 | + | |
| 732 | + res = AVERROR(EINVAL); | |
| 733 | + goto out; | |
| 734 | + } | |
| 735 | + } | |
| 615 | 736 | |
| 616 | 737 | if (!s->width && !s->height) { |
| 617 | 738 | struct v4l2_format fmt; |
| 618 | 739 | |
| 619 | − av_log(s1, AV_LOG_VERBOSE, "Querying the device for the current frame size\n"); | |
| 740 | + av_log(s1, AV_LOG_VERBOSE, | |
| 741 | + "Querying the device for the current frame size\n"); | |
| 620 | 742 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 621 | 743 | if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) { |
| 622 | − av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", strerror(errno)); | |
| 744 | + av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", | |
| 745 | + strerror(errno)); | |
| 623 | 746 | res = AVERROR(errno); |
| 624 | 747 | goto out; |
| 625 | 748 | } |
| 749 | + | |
| 626 | 750 | s->width = fmt.fmt.pix.width; |
| 627 | 751 | s->height = fmt.fmt.pix.height; |
| 628 | − av_log(s1, AV_LOG_VERBOSE, "Setting frame size to %dx%d\n", s->width, s->height); | |
| 752 | + av_log(s1, AV_LOG_VERBOSE, | |
| 753 | + "Setting frame size to %dx%d\n", s->width, s->height); | |
| 629 | 754 | } |
| 630 | 755 | |
| 631 | − desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height, &codec_id); | |
| 756 | + desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height, | |
| 757 | + &codec_id); | |
| 632 | 758 | if (desired_format == 0) { |
| 633 | 759 | av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for " |
| 634 | 760 | "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) · 4 unmodified lines | ||
| 639 | 765 | } |
| 640 | 766 | if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0) |
| 641 | 767 | goto out; |
| 768 | + | |
| 642 | 769 | s->frame_format = desired_format; |
| 643 | 770 | |
| 644 | 771 | if ((res = v4l2_set_parameters(s1, ap)) < 0) |
| 645 | 772 | goto out; |
| 646 | 773 | |
| 647 | 774 | st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id); |
| 648 | − s->frame_size = avpicture_get_size(st->codec->pix_fmt, s->width, s->height); | |
| 649 | − if (capabilities & V4L2_CAP_STREAMING) { | |
| 650 | − s->io_method = io_mmap; | |
| 651 | − res = mmap_init(s1); | |
| 652 | − if (res == 0) { | |
| 653 | − res = mmap_start(s1); | |
| 654 | − } | |
| 655 | − } else { | |
| 656 | − s->io_method = io_read; | |
| 657 | − res = read_init(s1); | |
| 658 | − } | |
| 659 | − if (res < 0) { | |
| 775 | + s->frame_size = | |
| 776 | + avpicture_get_size(st->codec->pix_fmt, s->width, s->height); | |
| 777 | + | |
| 778 | + if ((res = mmap_init(s1)) || | |
| 779 | + (res = mmap_start(s1)) < 0) { | |
| 660 | 780 | v4l2_close(s->fd); |
| 661 | − res = AVERROR(EIO); | |
| 662 | 781 | goto out; |
| 663 | 782 | } |
| 783 | + | |
| 664 | 784 | s->top_field_first = first_field(s->fd); |
| 665 | 785 | |
| 666 | 786 | st->codec->codec_type = AVMEDIA_TYPE_VIDEO; |
| 667 | 787 | st->codec->codec_id = codec_id; |
| 788 | + if (codec_id == CODEC_ID_RAWVIDEO) | |
| 789 | + st->codec->codec_tag = | |
| 790 | + avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt); | |
| 668 | 791 | st->codec->width = s->width; |
| 669 | 792 | st->codec->height = s->height; |
| 670 | 793 | st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8; |
| @@ -676,26 +799,17 @@ out: · 5 unmodified lines | ||
| 676 | 799 | static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt) |
| 677 | 800 | { |
| 678 | 801 | struct video_data *s = s1->priv_data; |
| 802 | + AVFrame *frame = s1->streams[0]->codec->coded_frame; | |
| 679 | 803 | int res; |
| 680 | 804 | |
| 681 | − if (s->io_method == io_mmap) { | |
| 682 | − av_init_packet(pkt); | |
| 683 | − res = mmap_read_frame(s1, pkt); | |
| 684 | − } else if (s->io_method == io_read) { | |
| 685 | − if (av_new_packet(pkt, s->frame_size) < 0) | |
| 686 | − return AVERROR(EIO); | |
| 687 | − | |
| 688 | − res = read_frame(s1, pkt); | |
| 689 | − } else { | |
| 690 | − return AVERROR(EIO); | |
| 691 | − } | |
| 692 | − if (res < 0) { | |
| 805 | + av_init_packet(pkt); | |
| 806 | + if ((res = mmap_read_frame(s1, pkt)) < 0) { | |
| 693 | 807 | return res; |
| 694 | 808 | } |
| 695 | 809 | |
| 696 | − if (s1->streams[0]->codec->coded_frame) { | |
| 697 | − s1->streams[0]->codec->coded_frame->interlaced_frame = 1; | |
| 698 | − s1->streams[0]->codec->coded_frame->top_field_first = s->top_field_first; | |
| 810 | + if (frame && s->interlaced) { | |
| 811 | + frame->interlaced_frame = 1; | |
| 812 | + frame->top_field_first = s->top_field_first; | |
| 699 | 813 | } |
| 700 | 814 | |
| 701 | 815 | return pkt->size; |
| @@ -705,9 +819,7 @@ static int v4l2_read_close(AVFormatContext *s1) · 3 unmodified lines | ||
| 705 | 819 | { |
| 706 | 820 | struct video_data *s = s1->priv_data; |
| 707 | 821 | |
| 708 | − if (s->io_method == io_mmap) { | |
| 709 | − mmap_close(s); | |
| 710 | − } | |
| 822 | + mmap_close(s); | |
| 711 | 823 | |
| 712 | 824 | v4l2_close(s->fd); |
| 713 | 825 | return 0; |
| @@ -717,11 +829,15 @@ static int v4l2_read_close(AVFormatContext *s1) · 3 unmodified lines | ||
| 717 | 829 | #define DEC AV_OPT_FLAG_DECODING_PARAM |
| 718 | 830 | |
| 719 | 831 | static const AVOption options[] = { |
| 720 | − { "standard", "", OFFSET(standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM }, | |
| 721 | − { "channel", "", OFFSET(channel), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, | |
| 722 | − { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, | |
| 723 | − { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, | |
| 724 | − { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, | |
| 832 | + { "standard", "TV standard, used only by analog frame grabber", OFFSET(standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC }, | |
| 833 | + { "channel", "TV channel, used only by frame grabber", OFFSET(channel), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, DEC }, | |
| 834 | + { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, | |
| 835 | + { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, | |
| 836 | + { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, | |
| 837 | + { "list_formats", "List available formats and exit", OFFSET(list_format), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, DEC, "list_formats" }, | |
| 838 | + { "all", "Show all available formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_ALLFORMATS }, 0, INT_MAX, DEC, "list_formats" }, | |
| 839 | + { "raw", "Show only non-compressed formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_RAWFORMATS }, 0, INT_MAX, DEC, "list_formats" }, | |
| 840 | + { "compressed", "Show only compressed formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_COMPFORMATS }, 0, INT_MAX, DEC, "list_formats" }, | |
| 725 | 841 | { NULL }, |
| 726 | 842 | }; |
| 727 | 843 | |
| @@ -26,6 +26,7 @@ OBJS-$(CONFIG_AC3_MUXER) += rawenc.o · 25 unmodified lines | ||
| 26 | 26 | OBJS-$(CONFIG_ACT_DEMUXER) += act.o |
| 27 | 27 | OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o |
| 28 | 28 | OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o |
| 29 | +OBJS-$(CONFIG_ADX_MUXER) += rawenc.o | |
| 29 | 30 | OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o |
| 30 | 31 | OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o |
| 31 | 32 | OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o isom.o |
| @@ -109,4 +109,5 @@ AVInputFormat ff_adx_demuxer = { · 108 unmodified lines | ||
| 109 | 109 | .read_packet = adx_read_packet, |
| 110 | 110 | .extensions = "adx", |
| 111 | 111 | .value = CODEC_ID_ADPCM_ADX, |
| 112 | + .flags = AVFMT_GENERIC_INDEX, | |
| 112 | 113 | }; |
| @@ -54,7 +54,7 @@ void av_register_all(void) · 53 unmodified lines | ||
| 54 | 54 | REGISTER_DEMUXER (ACT, act); |
| 55 | 55 | REGISTER_DEMUXER (ADF, adf); |
| 56 | 56 | REGISTER_MUXER (ADTS, adts); |
| 57 | − REGISTER_DEMUXER (ADX, adx); | |
| 57 | + REGISTER_MUXDEMUX (ADX, adx); | |
| 58 | 58 | REGISTER_DEMUXER (AEA, aea); |
| 59 | 59 | REGISTER_MUXDEMUX (AIFF, aiff); |
| 60 | 60 | REGISTER_MUXDEMUX (AMR, amr); |
| @@ -574,6 +574,10 @@ static void fill_buffer(AVIOContext *s) · 573 unmodified lines | ||
| 574 | 574 | int len= s->buffer_size - (dst - s->buffer); |
| 575 | 575 | int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE; |
| 576 | 576 | |
| 577 | + /* can't fill the buffer without read_packet, just set EOF if appropiate */ | |
| 578 | + if (!s->read_packet && s->buf_ptr >= s->buf_end) | |
| 579 | + s->eof_reached = 1; | |
| 580 | + | |
| 577 | 581 | /* no need to do anything if EOF already reached */ |
| 578 | 582 | if (s->eof_reached) |
| 579 | 583 | return; |
| @@ -112,10 +112,12 @@ static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap) · 111 unmodified lines | ||
| 112 | 112 | |
| 113 | 113 | avio_skip(pb, 4); |
| 114 | 114 | audio_subsegments = avio_rl16(pb); |
| 115 | − if(!audio_subsegments){ | |
| 116 | − av_log(s, AV_LOG_ERROR, "audio_subsegments is 0\n"); | |
| 117 | − return AVERROR(EINVAL); | |
| 115 | + | |
| 116 | + if (audio_subsegments == 0) { | |
| 117 | + av_log_ask_for_sample(s, "MTV files without audio are not supported\n"); | |
| 118 | + return AVERROR_INVALIDDATA; | |
| 118 | 119 | } |
| 120 | + | |
| 119 | 121 | mtv->full_segment_size = |
| 120 | 122 | audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) + |
| 121 | 123 | mtv->img_segment_size; |
| @@ -45,6 +45,18 @@ AVOutputFormat ff_ac3_muxer = { · 44 unmodified lines | ||
| 45 | 45 | }; |
| 46 | 46 | #endif |
| 47 | 47 | |
| 48 | +#if CONFIG_ADX_MUXER | |
| 49 | +AVOutputFormat ff_adx_muxer = { | |
| 50 | + .name = "adx", | |
| 51 | + .long_name = NULL_IF_CONFIG_SMALL("CRI ADX"), | |
| 52 | + .extensions = "adx", | |
| 53 | + .audio_codec = CODEC_ID_ADPCM_ADX, | |
| 54 | + .video_codec = CODEC_ID_NONE, | |
| 55 | + .write_packet = ff_raw_write_packet, | |
| 56 | + .flags = AVFMT_NOTIMESTAMPS, | |
| 57 | +}; | |
| 58 | +#endif | |
| 59 | + | |
| 48 | 60 | #if CONFIG_DIRAC_MUXER |
| 49 | 61 | AVOutputFormat ff_dirac_muxer = { |
| 50 | 62 | .name = "dirac", |
| @@ -2470,7 +2470,7 @@ static av_always_inline void RENAME(do_a_deblock)(uint8_t *src, int step, int st · 2469 unmodified lines | ||
| 2470 | 2470 | int64_t dc_mask, eq_mask, both_masks; |
| 2471 | 2471 | int64_t sums[10*8*2]; |
| 2472 | 2472 | src+= step*3; // src points to begin of the 8x8 Block |
| 2473 | −//START_TIMER | |
| 2473 | + //{ START_TIMER | |
| 2474 | 2474 | __asm__ volatile( |
| 2475 | 2475 | "movq %0, %%mm7 \n\t" |
| 2476 | 2476 | "movq %1, %%mm6 \n\t" |
| @@ -2995,7 +2995,8 @@ static av_always_inline void RENAME(do_a_deblock)(uint8_t *src, int step, int st · 518 unmodified lines | ||
| 2995 | 2995 | STOP_TIMER("step16") |
| 2996 | 2996 | }else{ |
| 2997 | 2997 | STOP_TIMER("stepX") |
| 2998 | −}*/ | |
| 2998 | +} | |
| 2999 | + } */ | |
| 2999 | 3000 | } |
| 3000 | 3001 | #endif //HAVE_MMX |
| 3001 | 3002 | |
| @@ -19,7 +19,8 @@ OBJS-$(HAVE_MMX) += x86/rgb2rgb.o \ · 18 unmodified lines | ||
| 19 | 19 | x86/swscale_mmx.o \ |
| 20 | 20 | x86/yuv2rgb_mmx.o |
| 21 | 21 | OBJS-$(HAVE_VIS) += sparc/yuv2rgb_vis.o |
| 22 | −OBJS-$(HAVE_YASM) += x86/scale.o | |
| 22 | +MMX-OBJS-$(HAVE_YASM) += x86/output.o \ | |
| 23 | + x86/scale.o | |
| 23 | 24 | |
| 24 | 25 | $(SUBDIR)x86/swscale_mmx.o: CFLAGS += $(NOREDZONE_FLAGS) |
| 25 | 26 | |
| @@ -21,8 +21,8 @@ · 20 unmodified lines | ||
| 21 | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 22 | 22 | */ |
| 23 | 23 | |
| 24 | −#ifndef PPC_YUV2RGB_ALTIVEC_H | |
| 25 | −#define PPC_YUV2RGB_ALTIVEC_H 1 | |
| 24 | +#ifndef SWSCALE_PPC_YUV2RGB_ALTIVEC_H | |
| 25 | +#define SWSCALE_PPC_YUV2RGB_ALTIVEC_H | |
| 26 | 26 | |
| 27 | 27 | #define YUV2PACKEDX_HEADER(suffix) \ |
| 28 | 28 | void ff_yuv2 ## suffix ## _X_altivec(SwsContext *c, const int16_t *lumFilter, \ |
| @@ -39,4 +39,4 @@ YUV2PACKEDX_HEADER(rgba); · 10 unmodified lines | ||
| 39 | 39 | YUV2PACKEDX_HEADER(rgb24); |
| 40 | 40 | YUV2PACKEDX_HEADER(bgr24); |
| 41 | 41 | |
| 42 | −#endif /* PPC_YUV2RGB_ALTIVEC_H */ | |
| 42 | +#endif /* SWSCALE_PPC_YUV2RGB_ALTIVEC_H */ | |
| @@ -18,39 +18,6 @@ · 17 unmodified lines | ||
| 18 | 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | −/* | |
| 22 | − supported Input formats: YV12, I420/IYUV, YUY2, UYVY, BGR32, BGR32_1, BGR24, BGR16, BGR15, RGB32, RGB32_1, RGB24, Y8/Y800, YVU9/IF09, PAL8 | |
| 23 | − supported output formats: YV12, I420/IYUV, YUY2, UYVY, {BGR,RGB}{1,4,8,15,16,24,32}, Y8/Y800, YVU9/IF09 | |
| 24 | − {BGR,RGB}{1,4,8,15,16} support dithering | |
| 25 | − | |
| 26 | − unscaled special converters (YV12=I420=IYUV, Y800=Y8) | |
| 27 | − YV12 -> {BGR,RGB}{1,4,8,12,15,16,24,32} | |
| 28 | − x -> x | |
| 29 | − YUV9 -> YV12 | |
| 30 | − YUV9/YV12 -> Y800 | |
| 31 | − Y800 -> YUV9/YV12 | |
| 32 | − BGR24 -> BGR32 & RGB24 -> RGB32 | |
| 33 | − BGR32 -> BGR24 & RGB32 -> RGB24 | |
| 34 | − BGR15 -> BGR16 | |
| 35 | −*/ | |
| 36 | − | |
| 37 | −/* | |
| 38 | −tested special converters (most are tested actually, but I did not write it down ...) | |
| 39 | − YV12 -> BGR12/BGR16 | |
| 40 | − YV12 -> YV12 | |
| 41 | − BGR15 -> BGR16 | |
| 42 | − BGR16 -> BGR16 | |
| 43 | − YVU9 -> YV12 | |
| 44 | − | |
| 45 | −untested special converters | |
| 46 | − YV12/I420 -> BGR15/BGR24/BGR32 (it is the yuv2rgb stuff, so it should be OK) | |
| 47 | − YV12/I420 -> YV12/I420 | |
| 48 | − YUY2/BGR15/BGR24/BGR32/RGB24/RGB32 -> same format | |
| 49 | − BGR24 -> BGR32 & RGB24 -> RGB32 | |
| 50 | − BGR32 -> BGR24 & RGB32 -> RGB24 | |
| 51 | − BGR24 -> YV12 | |
| 52 | −*/ | |
| 53 | − | |
| 54 | 21 | #include <inttypes.h> |
| 55 | 22 | #include <string.h> |
| 56 | 23 | #include <math.h> |
| @@ -2371,36 +2338,6 @@ find_c_packed_planar_out_funcs(SwsContext *c, · 2314 unmodified lines | ||
| 2371 | 2338 | } else { |
| 2372 | 2339 | YUV_PACKED: |
| 2373 | 2340 | switch (dstFormat) { |
| 2374 | − case PIX_FMT_GRAY16BE: | |
| 2375 | − *yuv2packed1 = yuv2gray16BE_1_c; | |
| 2376 | − *yuv2packed2 = yuv2gray16BE_2_c; | |
| 2377 | − *yuv2packedX = yuv2gray16BE_X_c; | |
| 2378 | − break; | |
| 2379 | − case PIX_FMT_GRAY16LE: | |
| 2380 | − *yuv2packed1 = yuv2gray16LE_1_c; | |
| 2381 | − *yuv2packed2 = yuv2gray16LE_2_c; | |
| 2382 | − *yuv2packedX = yuv2gray16LE_X_c; | |
| 2383 | − break; | |
| 2384 | − case PIX_FMT_MONOWHITE: | |
| 2385 | − *yuv2packed1 = yuv2monowhite_1_c; | |
| 2386 | − *yuv2packed2 = yuv2monowhite_2_c; | |
| 2387 | − *yuv2packedX = yuv2monowhite_X_c; | |
| 2388 | − break; | |
| 2389 | − case PIX_FMT_MONOBLACK: | |
| 2390 | − *yuv2packed1 = yuv2monoblack_1_c; | |
| 2391 | − *yuv2packed2 = yuv2monoblack_2_c; | |
| 2392 | − *yuv2packedX = yuv2monoblack_X_c; | |
| 2393 | − break; | |
| 2394 | − case PIX_FMT_YUYV422: | |
| 2395 | − *yuv2packed1 = yuv2yuyv422_1_c; | |
| 2396 | − *yuv2packed2 = yuv2yuyv422_2_c; | |
| 2397 | − *yuv2packedX = yuv2yuyv422_X_c; | |
| 2398 | − break; | |
| 2399 | − case PIX_FMT_UYVY422: | |
| 2400 | − *yuv2packed1 = yuv2uyvy422_1_c; | |
| 2401 | − *yuv2packed2 = yuv2uyvy422_2_c; | |
| 2402 | − *yuv2packedX = yuv2uyvy422_X_c; | |
| 2403 | − break; | |
| 2404 | 2341 | case PIX_FMT_RGB48LE: |
| 2405 | 2342 | *yuv2packed1 = yuv2rgb48le_1_c; |
| 2406 | 2343 | *yuv2packed2 = yuv2rgb48le_2_c; |
| @@ -2517,6 +2454,38 @@ find_c_packed_planar_out_funcs(SwsContext *c, · 110 unmodified lines | ||
| 2517 | 2454 | break; |
| 2518 | 2455 | } |
| 2519 | 2456 | } |
| 2457 | + switch (dstFormat) { | |
| 2458 | + case PIX_FMT_GRAY16BE: | |
| 2459 | + *yuv2packed1 = yuv2gray16BE_1_c; | |
| 2460 | + *yuv2packed2 = yuv2gray16BE_2_c; | |
| 2461 | + *yuv2packedX = yuv2gray16BE_X_c; | |
| 2462 | + break; | |
| 2463 | + case PIX_FMT_GRAY16LE: | |
| 2464 | + *yuv2packed1 = yuv2gray16LE_1_c; | |
| 2465 | + *yuv2packed2 = yuv2gray16LE_2_c; | |
| 2466 | + *yuv2packedX = yuv2gray16LE_X_c; | |
| 2467 | + break; | |
| 2468 | + case PIX_FMT_MONOWHITE: | |
| 2469 | + *yuv2packed1 = yuv2monowhite_1_c; | |
| 2470 | + *yuv2packed2 = yuv2monowhite_2_c; | |
| 2471 | + *yuv2packedX = yuv2monowhite_X_c; | |
| 2472 | + break; | |
| 2473 | + case PIX_FMT_MONOBLACK: | |
| 2474 | + *yuv2packed1 = yuv2monoblack_1_c; | |
| 2475 | + *yuv2packed2 = yuv2monoblack_2_c; | |
| 2476 | + *yuv2packedX = yuv2monoblack_X_c; | |
| 2477 | + break; | |
| 2478 | + case PIX_FMT_YUYV422: | |
| 2479 | + *yuv2packed1 = yuv2yuyv422_1_c; | |
| 2480 | + *yuv2packed2 = yuv2yuyv422_2_c; | |
| 2481 | + *yuv2packedX = yuv2yuyv422_X_c; | |
| 2482 | + break; | |
| 2483 | + case PIX_FMT_UYVY422: | |
| 2484 | + *yuv2packed1 = yuv2uyvy422_1_c; | |
| 2485 | + *yuv2packed2 = yuv2uyvy422_2_c; | |
| 2486 | + *yuv2packedX = yuv2uyvy422_X_c; | |
| 2487 | + break; | |
| 2488 | + } | |
| 2520 | 2489 | } |
| 2521 | 2490 | |
| 2522 | 2491 | #define DEBUG_SWSCALE_BUFFERS 0 |
| @@ -0,0 +1,409 @@ | ||
| 1 | +;****************************************************************************** | |
| 2 | +;* x86-optimized vertical line scaling functions | |
| 3 | +;* Copyright (c) 2011 Ronald S. Bultje <rsbultje@gmail.com> | |
| 4 | +;* Kieran Kunhya <kieran@kunhya.com> | |
| 5 | +;* | |
| 6 | +;* This file is part of Libav. | |
| 7 | +;* | |
| 8 | +;* Libav is free software; you can redistribute it and/or | |
| 9 | +;* modify it under the terms of the GNU Lesser General Public | |
| 10 | +;* License as published by the Free Software Foundation; either | |
| 11 | +;* version 2.1 of the License, or (at your option) any later version. | |
| 12 | +;* | |
| 13 | +;* Libav is distributed in the hope that it will be useful, | |
| 14 | +;* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 16 | +;* Lesser General Public License for more details. | |
| 17 | +;* | |
| 18 | +;* You should have received a copy of the GNU Lesser General Public | |
| 19 | +;* License along with Libav; if not, write to the Free Software | |
| 20 | +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 21 | +;****************************************************************************** | |
| 22 | + | |
| 23 | +%include "x86inc.asm" | |
| 24 | +%include "x86util.asm" | |
| 25 | + | |
| 26 | +SECTION_RODATA | |
| 27 | + | |
| 28 | +minshort: times 8 dw 0x8000 | |
| 29 | +yuv2yuvX_16_start: times 4 dd 0x4000 - 0x40000000 | |
| 30 | +yuv2yuvX_10_start: times 4 dd 0x10000 | |
| 31 | +yuv2yuvX_9_start: times 4 dd 0x20000 | |
| 32 | +yuv2yuvX_10_upper: times 8 dw 0x3ff | |
| 33 | +yuv2yuvX_9_upper: times 8 dw 0x1ff | |
| 34 | +pd_4: times 4 dd 4 | |
| 35 | +pd_4min0x40000:times 4 dd 4 - (0x40000) | |
| 36 | +pw_16: times 8 dw 16 | |
| 37 | +pw_32: times 8 dw 32 | |
| 38 | +pw_512: times 8 dw 512 | |
| 39 | +pw_1024: times 8 dw 1024 | |
| 40 | + | |
| 41 | +SECTION .text | |
| 42 | + | |
| 43 | +;----------------------------------------------------------------------------- | |
| 44 | +; vertical line scaling | |
| 45 | +; | |
| 46 | +; void yuv2plane1_<output_size>_<opt>(const int16_t *src, uint8_t *dst, int dstW, | |
| 47 | +; const uint8_t *dither, int offset) | |
| 48 | +; and | |
| 49 | +; void yuv2planeX_<output_size>_<opt>(const int16_t *filter, int filterSize, | |
| 50 | +; const int16_t **src, uint8_t *dst, int dstW, | |
| 51 | +; const uint8_t *dither, int offset) | |
| 52 | +; | |
| 53 | +; Scale one or $filterSize lines of source data to generate one line of output | |
| 54 | +; data. The input is 15-bit in int16_t if $output_size is [8,10] and 19-bit in | |
| 55 | +; int32_t if $output_size is 16. $filter is 12-bits. $filterSize is a multiple | |
| 56 | +; of 2. $offset is either 0 or 3. $dither holds 8 values. | |
| 57 | +;----------------------------------------------------------------------------- | |
| 58 | + | |
| 59 | +%macro yuv2planeX_fn 4 | |
| 60 | + | |
| 61 | +%ifdef ARCH_X86_32 | |
| 62 | +%define cntr_reg r1 | |
| 63 | +%define movsx mov | |
| 64 | +%else | |
| 65 | +%define cntr_reg r11 | |
| 66 | +%define movsx movsxd | |
| 67 | +%endif | |
| 68 | + | |
| 69 | +cglobal yuv2planeX_%2_%1, %4, 7, %3 | |
| 70 | +%if %2 == 8 || %2 == 9 || %2 == 10 | |
| 71 | + pxor m6, m6 | |
| 72 | +%endif ; %2 == 8/9/10 | |
| 73 | + | |
| 74 | +%if %2 == 8 | |
| 75 | +%ifdef ARCH_X86_32 | |
| 76 | +%assign pad 0x2c - (stack_offset & 15) | |
| 77 | + SUB rsp, pad | |
| 78 | +%define m_dith m7 | |
| 79 | +%else ; x86-64 | |
| 80 | +%define m_dith m9 | |
| 81 | +%endif ; x86-32 | |
| 82 | + | |
| 83 | + ; create registers holding dither | |
| 84 | + movq m_dith, [r5] ; dither | |
| 85 | + test r6d, r6d | |
| 86 | + jz .no_rot | |
| 87 | +%if mmsize == 16 | |
| 88 | + punpcklqdq m_dith, m_dith | |
| 89 | +%endif ; mmsize == 16 | |
| 90 | + PALIGNR m_dith, m_dith, 3, m0 | |
| 91 | +.no_rot: | |
| 92 | +%if mmsize == 16 | |
| 93 | + punpcklbw m_dith, m6 | |
| 94 | +%ifdef ARCH_X86_64 | |
| 95 | + punpcklwd m8, m_dith, m6 | |
| 96 | + pslld m8, 12 | |
| 97 | +%else ; x86-32 | |
| 98 | + punpcklwd m5, m_dith, m6 | |
| 99 | + pslld m5, 12 | |
| 100 | +%endif ; x86-32/64 | |
| 101 | + punpckhwd m_dith, m6 | |
| 102 | + pslld m_dith, 12 | |
| 103 | +%ifdef ARCH_X86_32 | |
| 104 | + mova [rsp+ 0], m5 | |
| 105 | + mova [rsp+16], m_dith | |
| 106 | +%endif | |
| 107 | +%else ; mmsize == 8 | |
| 108 | + punpcklbw m5, m_dith, m6 | |
| 109 | + punpckhbw m_dith, m6 | |
| 110 | + punpcklwd m4, m5, m6 | |
| 111 | + punpckhwd m5, m6 | |
| 112 | + punpcklwd m3, m_dith, m6 | |
| 113 | + punpckhwd m_dith, m6 | |
| 114 | + pslld m4, 12 | |
| 115 | + pslld m5, 12 | |
| 116 | + pslld m3, 12 | |
| 117 | + pslld m_dith, 12 | |
| 118 | + mova [rsp+ 0], m4 | |
| 119 | + mova [rsp+ 8], m5 | |
| 120 | + mova [rsp+16], m3 | |
| 121 | + mova [rsp+24], m_dith | |
| 122 | +%endif ; mmsize == 8/16 | |
| 123 | +%endif ; %2 == 8 | |
| 124 | + | |
| 125 | + xor r5, r5 | |
| 126 | + | |
| 127 | +.pixelloop: | |
| 128 | +%assign %%i 0 | |
| 129 | + ; the rep here is for the 8bit output mmx case, where dither covers | |
| 130 | + ; 8 pixels but we can only handle 2 pixels per register, and thus 4 | |
| 131 | + ; pixels per iteration. In order to not have to keep track of where | |
| 132 | + ; we are w.r.t. dithering, we unroll the mmx/8bit loop x2. | |
| 133 | +%if %2 == 8 | |
| 134 | +%rep 16/mmsize | |
| 135 | +%endif ; %2 == 8 | |
| 136 | + | |
| 137 | +%if %2 == 8 | |
| 138 | +%ifdef ARCH_X86_32 | |
| 139 | + mova m2, [rsp+mmsize*(0+%%i)] | |
| 140 | + mova m1, [rsp+mmsize*(1+%%i)] | |
| 141 | +%else ; x86-64 | |
| 142 | + mova m2, m8 | |
| 143 | + mova m1, m_dith | |
| 144 | +%endif ; x86-32/64 | |
| 145 | +%else ; %2 == 9/10/16 | |
| 146 | + mova m1, [yuv2yuvX_%2_start] | |
| 147 | + mova m2, m1 | |
| 148 | +%endif ; %2 == 8/9/10/16 | |
| 149 | + movsx cntr_reg, r1m | |
| 150 | +.filterloop_ %+ %%i: | |
| 151 | + ; input pixels | |
| 152 | + mov r6, [r2+gprsize*cntr_reg-2*gprsize] | |
| 153 | +%if %2 == 16 | |
| 154 | + mova m3, [r6+r5*4] | |
| 155 | + mova m5, [r6+r5*4+mmsize] | |
| 156 | +%else ; %2 == 8/9/10 | |
| 157 | + mova m3, [r6+r5*2] | |
| 158 | +%endif ; %2 == 8/9/10/16 | |
| 159 | + mov r6, [r2+gprsize*cntr_reg-gprsize] | |
| 160 | +%if %2 == 16 | |
| 161 | + mova m4, [r6+r5*4] | |
| 162 | + mova m6, [r6+r5*4+mmsize] | |
| 163 | +%else ; %2 == 8/9/10 | |
| 164 | + mova m4, [r6+r5*2] | |
| 165 | +%endif ; %2 == 8/9/10/16 | |
| 166 | + | |
| 167 | + ; coefficients | |
| 168 | + movd m0, [r0+2*cntr_reg-4]; coeff[0], coeff[1] | |
| 169 | +%if %2 == 16 | |
| 170 | + pshuflw m7, m0, 0 ; coeff[0] | |
| 171 | + pshuflw m0, m0, 0x55 ; coeff[1] | |
| 172 | + pmovsxwd m7, m7 ; word -> dword | |
| 173 | + pmovsxwd m0, m0 ; word -> dword | |
| 174 | + | |
| 175 | + pmulld m3, m7 | |
| 176 | + pmulld m5, m7 | |
| 177 | + pmulld m4, m0 | |
| 178 | + pmulld m6, m0 | |
| 179 | + | |
| 180 | + paddd m2, m3 | |
| 181 | + paddd m1, m5 | |
| 182 | + paddd m2, m4 | |
| 183 | + paddd m1, m6 | |
| 184 | +%else ; %2 == 10/9/8 | |
| 185 | + punpcklwd m5, m3, m4 | |
| 186 | + punpckhwd m3, m4 | |
| 187 | + SPLATD m0, m0 | |
| 188 | + | |
| 189 | + pmaddwd m5, m0 | |
| 190 | + pmaddwd m3, m0 | |
| 191 | + | |
| 192 | + paddd m2, m5 | |
| 193 | + paddd m1, m3 | |
| 194 | +%endif ; %2 == 8/9/10/16 | |
| 195 | + | |
| 196 | + sub cntr_reg, 2 | |
| 197 | + jg .filterloop_ %+ %%i | |
| 198 | + | |
| 199 | +%if %2 == 16 | |
| 200 | + psrad m2, 31 - %2 | |
| 201 | + psrad m1, 31 - %2 | |
| 202 | +%else ; %2 == 10/9/8 | |
| 203 | + psrad m2, 27 - %2 | |
| 204 | + psrad m1, 27 - %2 | |
| 205 | +%endif ; %2 == 8/9/10/16 | |
| 206 | + | |
| 207 | +%if %2 == 8 | |
| 208 | + packssdw m2, m1 | |
| 209 | + packuswb m2, m2 | |
| 210 | + movh [r3+r5*1], m2 | |
| 211 | +%else ; %2 == 9/10/16 | |
| 212 | +%if %2 == 16 | |
| 213 | + packssdw m2, m1 | |
| 214 | + paddw m2, [minshort] | |
| 215 | +%else ; %2 == 9/10 | |
| 216 | +%ifidn %1, sse4 | |
| 217 | + packusdw m2, m1 | |
| 218 | +%elifidn %1, avx | |
| 219 | + packusdw m2, m1 | |
| 220 | +%else ; mmx2/sse2 | |
| 221 | + packssdw m2, m1 | |
| 222 | + pmaxsw m2, m6 | |
| 223 | +%endif ; mmx2/sse2/sse4/avx | |
| 224 | + pminsw m2, [yuv2yuvX_%2_upper] | |
| 225 | +%endif ; %2 == 9/10/16 | |
| 226 | + mova [r3+r5*2], m2 | |
| 227 | +%endif ; %2 == 8/9/10/16 | |
| 228 | + | |
| 229 | + add r5, mmsize/2 | |
| 230 | + sub r4d, mmsize/2 | |
| 231 | +%if %2 == 8 | |
| 232 | +%assign %%i %%i+2 | |
| 233 | +%endrep | |
| 234 | +%endif ; %2 == 8 | |
| 235 | + jg .pixelloop | |
| 236 | + | |
| 237 | +%if %2 == 8 | |
| 238 | +%ifdef ARCH_X86_32 | |
| 239 | + ADD rsp, pad | |
| 240 | + RET | |
| 241 | +%else ; x86-64 | |
| 242 | + REP_RET | |
| 243 | +%endif ; x86-32/64 | |
| 244 | +%else ; %2 == 9/10/16 | |
| 245 | + REP_RET | |
| 246 | +%endif ; %2 == 8/9/10/16 | |
| 247 | +%endmacro | |
| 248 | + | |
| 249 | +%define PALIGNR PALIGNR_MMX | |
| 250 | +%ifdef ARCH_X86_32 | |
| 251 | +INIT_MMX | |
| 252 | +yuv2planeX_fn mmx2, 8, 0, 7 | |
| 253 | +yuv2planeX_fn mmx2, 9, 0, 5 | |
| 254 | +yuv2planeX_fn mmx2, 10, 0, 5 | |
| 255 | +%endif | |
| 256 | + | |
| 257 | +INIT_XMM | |
| 258 | +yuv2planeX_fn sse2, 8, 10, 7 | |
| 259 | +yuv2planeX_fn sse2, 9, 7, 5 | |
| 260 | +yuv2planeX_fn sse2, 10, 7, 5 | |
| 261 | + | |
| 262 | +%define PALIGNR PALIGNR_SSSE3 | |
| 263 | +yuv2planeX_fn sse4, 8, 10, 7 | |
| 264 | +yuv2planeX_fn sse4, 9, 7, 5 | |
| 265 | +yuv2planeX_fn sse4, 10, 7, 5 | |
| 266 | +yuv2planeX_fn sse4, 16, 8, 5 | |
| 267 | + | |
| 268 | +INIT_AVX | |
| 269 | +yuv2planeX_fn avx, 8, 10, 7 | |
| 270 | +yuv2planeX_fn avx, 9, 7, 5 | |
| 271 | +yuv2planeX_fn avx, 10, 7, 5 | |
| 272 | + | |
| 273 | +; %1=outout-bpc, %2=alignment (u/a) | |
| 274 | +%macro yuv2plane1_mainloop 2 | |
| 275 | +.loop_%2: | |
| 276 | +%if %1 == 8 | |
| 277 | + paddsw m0, m2, [r0+r2*2+mmsize*0] | |
| 278 | + paddsw m1, m3, [r0+r2*2+mmsize*1] | |
| 279 | + psraw m0, 7 | |
| 280 | + psraw m1, 7 | |
| 281 | + packuswb m0, m1 | |
| 282 | + mov%2 [r1+r2], m0 | |
| 283 | +%elif %1 == 16 | |
| 284 | + paddd m0, m4, [r0+r2*4+mmsize*0] | |
| 285 | + paddd m1, m4, [r0+r2*4+mmsize*1] | |
| 286 | + paddd m2, m4, [r0+r2*4+mmsize*2] | |
| 287 | + paddd m3, m4, [r0+r2*4+mmsize*3] | |
| 288 | + psrad m0, 3 | |
| 289 | + psrad m1, 3 | |
| 290 | + psrad m2, 3 | |
| 291 | + psrad m3, 3 | |
| 292 | +%if cpuflag(sse4) ; avx/sse4 | |
| 293 | + packusdw m0, m1 | |
| 294 | + packusdw m2, m3 | |
| 295 | +%else ; mmx/sse2 | |
| 296 | + packssdw m0, m1 | |
| 297 | + packssdw m2, m3 | |
| 298 | + paddw m0, m5 | |
| 299 | + paddw m2, m5 | |
| 300 | +%endif ; mmx/sse2/sse4/avx | |
| 301 | + mov%2 [r1+r2*2], m0 | |
| 302 | + mov%2 [r1+r2*2+mmsize], m2 | |
| 303 | +%else | |
| 304 | + paddsw m0, m2, [r0+r2*2+mmsize*0] | |
| 305 | + paddsw m1, m2, [r0+r2*2+mmsize*1] | |
| 306 | + psraw m0, 15 - %1 | |
| 307 | + psraw m1, 15 - %1 | |
| 308 | + pmaxsw m0, m4 | |
| 309 | + pmaxsw m1, m4 | |
| 310 | + pminsw m0, m3 | |
| 311 | + pminsw m1, m3 | |
| 312 | + mov%2 [r1+r2*2], m0 | |
| 313 | + mov%2 [r1+r2*2+mmsize], m1 | |
| 314 | +%endif | |
| 315 | + add r2, mmsize | |
| 316 | + jl .loop_%2 | |
| 317 | +%endmacro | |
| 318 | + | |
| 319 | +%macro yuv2plane1_fn 3 | |
| 320 | +cglobal yuv2plane1_%1, %3, %3, %2 | |
| 321 | + add r2, mmsize - 1 | |
| 322 | + and r2, ~(mmsize - 1) | |
| 323 | +%if %1 == 8 | |
| 324 | + add r1, r2 | |
| 325 | +%else ; %1 != 8 | |
| 326 | + lea r1, [r1+r2*2] | |
| 327 | +%endif ; %1 == 8 | |
| 328 | +%if %1 == 16 | |
| 329 | + lea r0, [r0+r2*4] | |
| 330 | +%else ; %1 != 16 | |
| 331 | + lea r0, [r0+r2*2] | |
| 332 | +%endif ; %1 == 16 | |
| 333 | + neg r2 | |
| 334 | + | |
| 335 | +%if %1 == 8 | |
| 336 | + pxor m4, m4 ; zero | |
| 337 | + | |
| 338 | + ; create registers holding dither | |
| 339 | + movq m3, [r3] ; dither | |
| 340 | + test r4d, r4d | |
| 341 | + jz .no_rot | |
| 342 | +%if mmsize == 16 | |
| 343 | + punpcklqdq m3, m3 | |
| 344 | +%endif ; mmsize == 16 | |
| 345 | + PALIGNR_MMX m3, m3, 3, m2 | |
| 346 | +.no_rot: | |
| 347 | +%if mmsize == 8 | |
| 348 | + mova m2, m3 | |
| 349 | + punpckhbw m3, m4 ; byte->word | |
| 350 | + punpcklbw m2, m4 ; byte->word | |
| 351 | +%else | |
| 352 | + punpcklbw m3, m4 | |
| 353 | + mova m2, m3 | |
| 354 | +%endif | |
| 355 | +%elif %1 == 9 | |
| 356 | + pxor m4, m4 | |
| 357 | + mova m3, [pw_512] | |
| 358 | + mova m2, [pw_32] | |
| 359 | +%elif %1 == 10 | |
| 360 | + pxor m4, m4 | |
| 361 | + mova m3, [pw_1024] | |
| 362 | + mova m2, [pw_16] | |
| 363 | +%else ; %1 == 16 | |
| 364 | +%if cpuflag(sse4) ; sse4/avx | |
| 365 | + mova m4, [pd_4] | |
| 366 | +%else ; mmx/sse2 | |
| 367 | + mova m4, [pd_4min0x40000] | |
| 368 | + mova m5, [minshort] | |
| 369 | +%endif ; mmx/sse2/sse4/avx | |
| 370 | +%endif ; %1 == .. | |
| 371 | + | |
| 372 | + ; actual pixel scaling | |
| 373 | +%if mmsize == 8 | |
| 374 | + yuv2plane1_mainloop %1, a | |
| 375 | +%else ; mmsize == 16 | |
| 376 | + test r1, 15 | |
| 377 | + jnz .unaligned | |
| 378 | + yuv2plane1_mainloop %1, a | |
| 379 | + REP_RET | |
| 380 | +.unaligned: | |
| 381 | + yuv2plane1_mainloop %1, u | |
| 382 | +%endif ; mmsize == 8/16 | |
| 383 | + REP_RET | |
| 384 | +%endmacro | |
| 385 | + | |
| 386 | +%ifdef ARCH_X86_32 | |
| 387 | +INIT_MMX mmx | |
| 388 | +yuv2plane1_fn 8, 0, 5 | |
| 389 | +yuv2plane1_fn 16, 0, 3 | |
| 390 | + | |
| 391 | +INIT_MMX mmx2 | |
| 392 | +yuv2plane1_fn 9, 0, 3 | |
| 393 | +yuv2plane1_fn 10, 0, 3 | |
| 394 | +%endif | |
| 395 | + | |
| 396 | +INIT_XMM sse2 | |
| 397 | +yuv2plane1_fn 8, 5, 5 | |
| 398 | +yuv2plane1_fn 9, 5, 3 | |
| 399 | +yuv2plane1_fn 10, 5, 3 | |
| 400 | +yuv2plane1_fn 16, 6, 3 | |
| 401 | + | |
| 402 | +INIT_XMM sse4 | |
| 403 | +yuv2plane1_fn 16, 5, 3 | |
| 404 | + | |
| 405 | +INIT_XMM avx | |
| 406 | +yuv2plane1_fn 8, 5, 5 | |
| 407 | +yuv2plane1_fn 9, 5, 3 | |
| 408 | +yuv2plane1_fn 10, 5, 3 | |
| 409 | +yuv2plane1_fn 16, 5, 3 | |
| @@ -1,7 +1,6 @@ | ||
| 1 | 1 | ;****************************************************************************** |
| 2 | −;* x86-optimized horizontal/vertical line scaling functions | |
| 2 | +;* x86-optimized horizontal line scaling functions | |
| 3 | 3 | ;* Copyright (c) 2011 Ronald S. Bultje <rsbultje@gmail.com> |
| 4 | −;* Kieran Kunhya <kieran@kunhya.com> | |
| 5 | 4 | ;* |
| 6 | 5 | ;* This file is part of Libav. |
| 7 | 6 | ;* |
| @@ -29,17 +28,6 @@ max_19bit_int: times 4 dd 0x7ffff · 21 unmodified lines | ||
| 29 | 28 | max_19bit_flt: times 4 dd 524287.0 |
| 30 | 29 | minshort: times 8 dw 0x8000 |
| 31 | 30 | unicoeff: times 4 dd 0x20000000 |
| 32 | −yuv2yuvX_16_start: times 4 dd 0x4000 - 0x40000000 | |
| 33 | −yuv2yuvX_10_start: times 4 dd 0x10000 | |
| 34 | −yuv2yuvX_9_start: times 4 dd 0x20000 | |
| 35 | −yuv2yuvX_10_upper: times 8 dw 0x3ff | |
| 36 | −yuv2yuvX_9_upper: times 8 dw 0x1ff | |
| 37 | −pd_4: times 4 dd 4 | |
| 38 | −pd_4min0x40000:times 4 dd 4 - (0x40000) | |
| 39 | −pw_16: times 8 dw 16 | |
| 40 | −pw_32: times 8 dw 32 | |
| 41 | −pw_512: times 8 dw 512 | |
| 42 | −pw_1024: times 8 dw 1024 | |
| 43 | 31 | |
| 44 | 32 | SECTION .text |
| 45 | 33 | |
| @@ -441,371 +429,3 @@ INIT_XMM · 395 unmodified lines | ||
| 441 | 429 | SCALE_FUNCS2 sse2, 6, 7, 8 |
| 442 | 430 | SCALE_FUNCS2 ssse3, 6, 6, 8 |
| 443 | 431 | SCALE_FUNCS2 sse4, 6, 6, 8 |
| 444 | − | |
| 445 | −;----------------------------------------------------------------------------- | |
| 446 | −; vertical line scaling | |
| 447 | −; | |
| 448 | −; void yuv2plane1_<output_size>_<opt>(const int16_t *src, uint8_t *dst, int dstW, | |
| 449 | −; const uint8_t *dither, int offset) | |
| 450 | −; and | |
| 451 | −; void yuv2planeX_<output_size>_<opt>(const int16_t *filter, int filterSize, | |
| 452 | −; const int16_t **src, uint8_t *dst, int dstW, | |
| 453 | −; const uint8_t *dither, int offset) | |
| 454 | −; | |
| 455 | −; Scale one or $filterSize lines of source data to generate one line of output | |
| 456 | −; data. The input is 15-bit in int16_t if $output_size is [8,10] and 19-bit in | |
| 457 | −; int32_t if $output_size is 16. $filter is 12-bits. $filterSize is a multiple | |
| 458 | −; of 2. $offset is either 0 or 3. $dither holds 8 values. | |
| 459 | −;----------------------------------------------------------------------------- | |
| 460 | − | |
| 461 | −%macro yuv2planeX_fn 4 | |
| 462 | − | |
| 463 | −%ifdef ARCH_X86_32 | |
| 464 | −%define cntr_reg r1 | |
| 465 | −%define movsx mov | |
| 466 | −%else | |
| 467 | −%define cntr_reg r11 | |
| 468 | −%define movsx movsxd | |
| 469 | −%endif | |
| 470 | − | |
| 471 | −cglobal yuv2planeX_%2_%1, %4, 7, %3 | |
| 472 | −%if %2 == 8 || %2 == 9 || %2 == 10 | |
| 473 | − pxor m6, m6 | |
| 474 | −%endif ; %2 == 8/9/10 | |
| 475 | − | |
| 476 | −%if %2 == 8 | |
| 477 | −%ifdef ARCH_X86_32 | |
| 478 | −%assign pad 0x2c - (stack_offset & 15) | |
| 479 | − SUB rsp, pad | |
| 480 | −%define m_dith m7 | |
| 481 | −%else ; x86-64 | |
| 482 | −%define m_dith m9 | |
| 483 | −%endif ; x86-32 | |
| 484 | − | |
| 485 | − ; create registers holding dither | |
| 486 | − movq m_dith, [r5] ; dither | |
| 487 | − test r6d, r6d | |
| 488 | − jz .no_rot | |
| 489 | −%if mmsize == 16 | |
| 490 | − punpcklqdq m_dith, m_dith | |
| 491 | −%endif ; mmsize == 16 | |
| 492 | − PALIGNR m_dith, m_dith, 3, m0 | |
| 493 | −.no_rot: | |
| 494 | −%if mmsize == 16 | |
| 495 | − punpcklbw m_dith, m6 | |
| 496 | −%ifdef ARCH_X86_64 | |
| 497 | − punpcklwd m8, m_dith, m6 | |
| 498 | − pslld m8, 12 | |
| 499 | −%else ; x86-32 | |
| 500 | − punpcklwd m5, m_dith, m6 | |
| 501 | − pslld m5, 12 | |
| 502 | −%endif ; x86-32/64 | |
| 503 | − punpckhwd m_dith, m6 | |
| 504 | − pslld m_dith, 12 | |
| 505 | −%ifdef ARCH_X86_32 | |
| 506 | − mova [rsp+ 0], m5 | |
| 507 | − mova [rsp+16], m_dith | |
| 508 | −%endif | |
| 509 | −%else ; mmsize == 8 | |
| 510 | − punpcklbw m5, m_dith, m6 | |
| 511 | − punpckhbw m_dith, m6 | |
| 512 | − punpcklwd m4, m5, m6 | |
| 513 | − punpckhwd m5, m6 | |
| 514 | − punpcklwd m3, m_dith, m6 | |
| 515 | − punpckhwd m_dith, m6 | |
| 516 | − pslld m4, 12 | |
| 517 | − pslld m5, 12 | |
| 518 | − pslld m3, 12 | |
| 519 | − pslld m_dith, 12 | |
| 520 | − mova [rsp+ 0], m4 | |
| 521 | − mova [rsp+ 8], m5 | |
| 522 | − mova [rsp+16], m3 | |
| 523 | − mova [rsp+24], m_dith | |
| 524 | −%endif ; mmsize == 8/16 | |
| 525 | −%endif ; %2 == 8 | |
| 526 | − | |
| 527 | − xor r5, r5 | |
| 528 | − | |
| 529 | −.pixelloop: | |
| 530 | −%assign %%i 0 | |
| 531 | − ; the rep here is for the 8bit output mmx case, where dither covers | |
| 532 | − ; 8 pixels but we can only handle 2 pixels per register, and thus 4 | |
| 533 | − ; pixels per iteration. In order to not have to keep track of where | |
| 534 | − ; we are w.r.t. dithering, we unroll the mmx/8bit loop x2. | |
| 535 | −%if %2 == 8 | |
| 536 | −%rep 16/mmsize | |
| 537 | −%endif ; %2 == 8 | |
| 538 | − | |
| 539 | −%if %2 == 8 | |
| 540 | −%ifdef ARCH_X86_32 | |
| 541 | − mova m2, [rsp+mmsize*(0+%%i)] | |
| 542 | − mova m1, [rsp+mmsize*(1+%%i)] | |
| 543 | −%else ; x86-64 | |
| 544 | − mova m2, m8 | |
| 545 | − mova m1, m_dith | |
| 546 | −%endif ; x86-32/64 | |
| 547 | −%else ; %2 == 9/10/16 | |
| 548 | − mova m1, [yuv2yuvX_%2_start] | |
| 549 | − mova m2, m1 | |
| 550 | −%endif ; %2 == 8/9/10/16 | |
| 551 | − movsx cntr_reg, r1m | |
| 552 | −.filterloop_ %+ %%i: | |
| 553 | − ; input pixels | |
| 554 | − mov r6, [r2+gprsize*cntr_reg-2*gprsize] | |
| 555 | −%if %2 == 16 | |
| 556 | − mova m3, [r6+r5*4] | |
| 557 | − mova m5, [r6+r5*4+mmsize] | |
| 558 | −%else ; %2 == 8/9/10 | |
| 559 | − mova m3, [r6+r5*2] | |
| 560 | −%endif ; %2 == 8/9/10/16 | |
| 561 | − mov r6, [r2+gprsize*cntr_reg-gprsize] | |
| 562 | −%if %2 == 16 | |
| 563 | − mova m4, [r6+r5*4] | |
| 564 | − mova m6, [r6+r5*4+mmsize] | |
| 565 | −%else ; %2 == 8/9/10 | |
| 566 | − mova m4, [r6+r5*2] | |
| 567 | −%endif ; %2 == 8/9/10/16 | |
| 568 | − | |
| 569 | − ; coefficients | |
| 570 | − movd m0, [r0+2*cntr_reg-4]; coeff[0], coeff[1] | |
| 571 | −%if %2 == 16 | |
| 572 | − pshuflw m7, m0, 0 ; coeff[0] | |
| 573 | − pshuflw m0, m0, 0x55 ; coeff[1] | |
| 574 | − pmovsxwd m7, m7 ; word -> dword | |
| 575 | − pmovsxwd m0, m0 ; word -> dword | |
| 576 | − | |
| 577 | − pmulld m3, m7 | |
| 578 | − pmulld m5, m7 | |
| 579 | − pmulld m4, m0 | |
| 580 | − pmulld m6, m0 | |
| 581 | − | |
| 582 | − paddd m2, m3 | |
| 583 | − paddd m1, m5 | |
| 584 | − paddd m2, m4 | |
| 585 | − paddd m1, m6 | |
| 586 | −%else ; %2 == 10/9/8 | |
| 587 | − punpcklwd m5, m3, m4 | |
| 588 | − punpckhwd m3, m4 | |
| 589 | − SPLATD m0, m0 | |
| 590 | − | |
| 591 | − pmaddwd m5, m0 | |
| 592 | − pmaddwd m3, m0 | |
| 593 | − | |
| 594 | − paddd m2, m5 | |
| 595 | − paddd m1, m3 | |
| 596 | −%endif ; %2 == 8/9/10/16 | |
| 597 | − | |
| 598 | − sub cntr_reg, 2 | |
| 599 | − jg .filterloop_ %+ %%i | |
| 600 | − | |
| 601 | −%if %2 == 16 | |
| 602 | − psrad m2, 31 - %2 | |
| 603 | − psrad m1, 31 - %2 | |
| 604 | −%else ; %2 == 10/9/8 | |
| 605 | − psrad m2, 27 - %2 | |
| 606 | − psrad m1, 27 - %2 | |
| 607 | −%endif ; %2 == 8/9/10/16 | |
| 608 | − | |
| 609 | −%if %2 == 8 | |
| 610 | − packssdw m2, m1 | |
| 611 | − packuswb m2, m2 | |
| 612 | − movh [r3+r5*1], m2 | |
| 613 | −%else ; %2 == 9/10/16 | |
| 614 | −%if %2 == 16 | |
| 615 | − packssdw m2, m1 | |
| 616 | − paddw m2, [minshort] | |
| 617 | −%else ; %2 == 9/10 | |
| 618 | −%ifidn %1, sse4 | |
| 619 | − packusdw m2, m1 | |
| 620 | −%elifidn %1, avx | |
| 621 | − packusdw m2, m1 | |
| 622 | −%else ; mmx2/sse2 | |
| 623 | − packssdw m2, m1 | |
| 624 | − pmaxsw m2, m6 | |
| 625 | −%endif ; mmx2/sse2/sse4/avx | |
| 626 | − pminsw m2, [yuv2yuvX_%2_upper] | |
| 627 | −%endif ; %2 == 9/10/16 | |
| 628 | − mova [r3+r5*2], m2 | |
| 629 | −%endif ; %2 == 8/9/10/16 | |
| 630 | − | |
| 631 | − add r5, mmsize/2 | |
| 632 | − sub r4d, mmsize/2 | |
| 633 | −%if %2 == 8 | |
| 634 | −%assign %%i %%i+2 | |
| 635 | −%endrep | |
| 636 | −%endif ; %2 == 8 | |
| 637 | − jg .pixelloop | |
| 638 | − | |
| 639 | −%if %2 == 8 | |
| 640 | −%ifdef ARCH_X86_32 | |
| 641 | − ADD rsp, pad | |
| 642 | − RET | |
| 643 | −%else ; x86-64 | |
| 644 | − REP_RET | |
| 645 | −%endif ; x86-32/64 | |
| 646 | −%else ; %2 == 9/10/16 | |
| 647 | − REP_RET | |
| 648 | −%endif ; %2 == 8/9/10/16 | |
| 649 | −%endmacro | |
| 650 | − | |
| 651 | −%define PALIGNR PALIGNR_MMX | |
| 652 | −%ifdef ARCH_X86_32 | |
| 653 | −INIT_MMX | |
| 654 | −yuv2planeX_fn mmx2, 8, 0, 7 | |
| 655 | −yuv2planeX_fn mmx2, 9, 0, 5 | |
| 656 | −yuv2planeX_fn mmx2, 10, 0, 5 | |
| 657 | −%endif | |
| 658 | − | |
| 659 | −INIT_XMM | |
| 660 | −yuv2planeX_fn sse2, 8, 10, 7 | |
| 661 | −yuv2planeX_fn sse2, 9, 7, 5 | |
| 662 | −yuv2planeX_fn sse2, 10, 7, 5 | |
| 663 | − | |
| 664 | −%define PALIGNR PALIGNR_SSSE3 | |
| 665 | −yuv2planeX_fn sse4, 8, 10, 7 | |
| 666 | −yuv2planeX_fn sse4, 9, 7, 5 | |
| 667 | −yuv2planeX_fn sse4, 10, 7, 5 | |
| 668 | −yuv2planeX_fn sse4, 16, 8, 5 | |
| 669 | − | |
| 670 | −INIT_AVX | |
| 671 | −yuv2planeX_fn avx, 8, 10, 7 | |
| 672 | −yuv2planeX_fn avx, 9, 7, 5 | |
| 673 | −yuv2planeX_fn avx, 10, 7, 5 | |
| 674 | − | |
| 675 | −; %1=outout-bpc, %2=alignment (u/a) | |
| 676 | −%macro yuv2plane1_mainloop 2 | |
| 677 | −.loop_%2: | |
| 678 | −%if %1 == 8 | |
| 679 | − paddsw m0, m2, [r0+r2*2+mmsize*0] | |
| 680 | − paddsw m1, m3, [r0+r2*2+mmsize*1] | |
| 681 | − psraw m0, 7 | |
| 682 | − psraw m1, 7 | |
| 683 | − packuswb m0, m1 | |
| 684 | − mov%2 [r1+r2], m0 | |
| 685 | −%elif %1 == 16 | |
| 686 | − paddd m0, m4, [r0+r2*4+mmsize*0] | |
| 687 | − paddd m1, m4, [r0+r2*4+mmsize*1] | |
| 688 | − paddd m2, m4, [r0+r2*4+mmsize*2] | |
| 689 | − paddd m3, m4, [r0+r2*4+mmsize*3] | |
| 690 | − psrad m0, 3 | |
| 691 | − psrad m1, 3 | |
| 692 | − psrad m2, 3 | |
| 693 | − psrad m3, 3 | |
| 694 | −%if cpuflag(sse4) ; avx/sse4 | |
| 695 | − packusdw m0, m1 | |
| 696 | − packusdw m2, m3 | |
| 697 | −%else ; mmx/sse2 | |
| 698 | − packssdw m0, m1 | |
| 699 | − packssdw m2, m3 | |
| 700 | − paddw m0, m5 | |
| 701 | − paddw m2, m5 | |
| 702 | −%endif ; mmx/sse2/sse4/avx | |
| 703 | − mov%2 [r1+r2*2], m0 | |
| 704 | − mov%2 [r1+r2*2+mmsize], m2 | |
| 705 | −%else | |
| 706 | − paddsw m0, m2, [r0+r2*2+mmsize*0] | |
| 707 | − paddsw m1, m2, [r0+r2*2+mmsize*1] | |
| 708 | − psraw m0, 15 - %1 | |
| 709 | − psraw m1, 15 - %1 | |
| 710 | − pmaxsw m0, m4 | |
| 711 | − pmaxsw m1, m4 | |
| 712 | − pminsw m0, m3 | |
| 713 | − pminsw m1, m3 | |
| 714 | − mov%2 [r1+r2*2], m0 | |
| 715 | − mov%2 [r1+r2*2+mmsize], m1 | |
| 716 | −%endif | |
| 717 | − add r2, mmsize | |
| 718 | − jl .loop_%2 | |
| 719 | −%endmacro | |
| 720 | − | |
| 721 | −%macro yuv2plane1_fn 3 | |
| 722 | −cglobal yuv2plane1_%1, %3, %3, %2 | |
| 723 | − add r2, mmsize - 1 | |
| 724 | − and r2, ~(mmsize - 1) | |
| 725 | −%if %1 == 8 | |
| 726 | − add r1, r2 | |
| 727 | −%else ; %1 != 8 | |
| 728 | − lea r1, [r1+r2*2] | |
| 729 | −%endif ; %1 == 8 | |
| 730 | −%if %1 == 16 | |
| 731 | − lea r0, [r0+r2*4] | |
| 732 | −%else ; %1 != 16 | |
| 733 | − lea r0, [r0+r2*2] | |
| 734 | −%endif ; %1 == 16 | |
| 735 | − neg r2 | |
| 736 | − | |
| 737 | −%if %1 == 8 | |
| 738 | − pxor m4, m4 ; zero | |
| 739 | − | |
| 740 | − ; create registers holding dither | |
| 741 | − movq m3, [r3] ; dither | |
| 742 | − test r4d, r4d | |
| 743 | − jz .no_rot | |
| 744 | −%if mmsize == 16 | |
| 745 | − punpcklqdq m3, m3 | |
| 746 | −%endif ; mmsize == 16 | |
| 747 | − PALIGNR_MMX m3, m3, 3, m2 | |
| 748 | −.no_rot: | |
| 749 | −%if mmsize == 8 | |
| 750 | − mova m2, m3 | |
| 751 | − punpckhbw m3, m4 ; byte->word | |
| 752 | − punpcklbw m2, m4 ; byte->word | |
| 753 | −%else | |
| 754 | − punpcklbw m3, m4 | |
| 755 | − mova m2, m3 | |
| 756 | −%endif | |
| 757 | −%elif %1 == 9 | |
| 758 | − pxor m4, m4 | |
| 759 | − mova m3, [pw_512] | |
| 760 | − mova m2, [pw_32] | |
| 761 | −%elif %1 == 10 | |
| 762 | − pxor m4, m4 | |
| 763 | − mova m3, [pw_1024] | |
| 764 | − mova m2, [pw_16] | |
| 765 | −%else ; %1 == 16 | |
| 766 | −%if cpuflag(sse4) ; sse4/avx | |
| 767 | − mova m4, [pd_4] | |
| 768 | −%else ; mmx/sse2 | |
| 769 | − mova m4, [pd_4min0x40000] | |
| 770 | − mova m5, [minshort] | |
| 771 | −%endif ; mmx/sse2/sse4/avx | |
| 772 | −%endif ; %1 == .. | |
| 773 | − | |
| 774 | − ; actual pixel scaling | |
| 775 | −%if mmsize == 8 | |
| 776 | − yuv2plane1_mainloop %1, a | |
| 777 | −%else ; mmsize == 16 | |
| 778 | − test r1, 15 | |
| 779 | − jnz .unaligned | |
| 780 | − yuv2plane1_mainloop %1, a | |
| 781 | − REP_RET | |
| 782 | −.unaligned: | |
| 783 | − yuv2plane1_mainloop %1, u | |
| 784 | −%endif ; mmsize == 8/16 | |
| 785 | − REP_RET | |
| 786 | −%endmacro | |
| 787 | − | |
| 788 | −%ifdef ARCH_X86_32 | |
| 789 | −INIT_MMX mmx | |
| 790 | −yuv2plane1_fn 8, 0, 5 | |
| 791 | −yuv2plane1_fn 16, 0, 3 | |
| 792 | − | |
| 793 | −INIT_MMX mmx2 | |
| 794 | −yuv2plane1_fn 9, 0, 3 | |
| 795 | −yuv2plane1_fn 10, 0, 3 | |
| 796 | −%endif | |
| 797 | − | |
| 798 | −INIT_XMM sse2 | |
| 799 | −yuv2plane1_fn 8, 5, 5 | |
| 800 | −yuv2plane1_fn 9, 5, 3 | |
| 801 | −yuv2plane1_fn 10, 5, 3 | |
| 802 | −yuv2plane1_fn 16, 6, 3 | |
| 803 | − | |
| 804 | −INIT_XMM sse4 | |
| 805 | −yuv2plane1_fn 16, 5, 3 | |
| 806 | − | |
| 807 | −INIT_XMM avx | |
| 808 | −yuv2plane1_fn 8, 5, 5 | |
| 809 | −yuv2plane1_fn 9, 5, 3 | |
| 810 | −yuv2plane1_fn 10, 5, 3 | |
| 811 | −yuv2plane1_fn 16, 5, 3 | |
| @@ -369,6 +369,11 @@ do_audio_encoding g726.wav "-b:a 32k -ac 1 -ar 8000 -acodec g726" · 368 unmodified lines | ||
| 369 | 369 | do_audio_decoding |
| 370 | 370 | fi |
| 371 | 371 | |
| 372 | +if [ -n "$do_adpcm_adx" ] ; then | |
| 373 | +do_audio_encoding adpcm_adx.adx "-acodec adpcm_adx" | |
| 374 | +do_audio_decoding | |
| 375 | +fi | |
| 376 | + | |
| 372 | 377 | if [ -n "$do_adpcm_ima_wav" ] ; then |
| 373 | 378 | do_audio_encoding adpcm_ima.wav "-acodec adpcm_ima_wav" |
| 374 | 379 | do_audio_decoding |
| @@ -0,0 +1,4 @@ | ||
| 1 | +0a30509d9296b857e134b762b76dbc31 *./tests/data/acodec/adpcm_adx.adx | |
| 2 | +297720 ./tests/data/acodec/adpcm_adx.adx | |
| 3 | +2dbc601ed5259f4d74dc48ccd8da7eaf *./tests/data/adpcm_adx.acodec.out.wav | |
| 4 | +stddev: 6989.46 PSNR: 19.44 MAXDIFF:65398 bytes: 1058432/ 1058400 | |