* 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 | - pan audio filter | 145 | - pan audio filter |
| 146 | - IFF Amiga Continuous Bitmap (ACBM) decoder | 146 | - IFF Amiga Continuous Bitmap (ACBM) decoder |
| 147 | - ass filter | 147 | - ass filter |
| 148 | - CRI ADX audio format demuxer | 148 | - CRI ADX audio format muxer and demuxer |
| 149 | - Playstation Portable PMP format demuxer | 149 | - Playstation Portable PMP format demuxer |
| 150 | - Microsoft Windows ICO demuxer | 150 | - Microsoft Windows ICO demuxer |
| 151 | - life source | 151 | - life source |
| @@ -88,6 +88,11 @@ · 87 unmodified lines | |||
| 88 | 88 | ||
| 89 | #include "libavutil/avassert.h" | 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 | const char program_name[] = "avconv"; | 96 | const char program_name[] = "avconv"; |
| 92 | const int program_birth_year = 2000; | 97 | const int program_birth_year = 2000; |
| 93 | 98 | ||
| @@ -127,7 +132,7 @@ static int do_hex_dump = 0; · 33 unmodified lines | |||
| 127 | static int do_pkt_dump = 0; | 132 | static int do_pkt_dump = 0; |
| 128 | static int do_pass = 0; | 133 | static int do_pass = 0; |
| 129 | static const char *pass_logfilename_prefix; | 134 | static const char *pass_logfilename_prefix; |
| 130 | static int video_sync_method = -1; | 135 | static int video_sync_method = VSYNC_AUTO; |
| 131 | static int audio_sync_method = 0; | 136 | static int audio_sync_method = 0; |
| 132 | static float audio_drift_threshold = 0.1; | 137 | static float audio_drift_threshold = 0.1; |
| 133 | static int copy_ts = 0; | 138 | static int copy_ts = 0; |
| @@ -1390,16 +1395,16 @@ static void do_video_out(AVFormatContext *s, · 1256 unmodified lines | |||
| 1390 | *frame_size = 0; | 1395 | *frame_size = 0; |
| 1391 | 1396 | ||
| 1392 | format_video_sync = video_sync_method; | 1397 | format_video_sync = video_sync_method; |
| 1393 | if (format_video_sync < 0) | 1398 | if (format_video_sync == VSYNC_AUTO) |
| 1394 | format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? 0 : | 1399 | format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : |
| 1395 | (s->oformat->flags & AVFMT_VARIABLE_FPS) ? 2 : 1; | 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 | double vdelta = sync_ipts - ost->sync_opts; | 1403 | double vdelta = sync_ipts - ost->sync_opts; |
| 1399 | // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c | 1404 | // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c |
| 1400 | if (vdelta < -1.1) | 1405 | if (vdelta < -1.1) |
| 1401 | nb_frames = 0; | 1406 | nb_frames = 0; |
| 1402 | else if (format_video_sync == 2) { | 1407 | else if (format_video_sync == VSYNC_VFR) { |
| 1403 | if (vdelta <= -0.6) { | 1408 | if (vdelta <= -0.6) { |
| 1404 | nb_frames = 0; | 1409 | nb_frames = 0; |
| 1405 | } else if (vdelta > 0.6) | 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 | return parse_option(o, "filter:v", arg, options); | 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 | #define OFFSET(x) offsetof(OptionsContext, x) | 4445 | #define OFFSET(x) offsetof(OptionsContext, x) |
| 4430 | static const OptionDef options[] = { | 4446 | static const OptionDef options[] = { |
| 4431 | /* main options */ | 4447 | /* main options */ |
| @@ -4457,7 +4473,7 @@ static const OptionDef options[] = { · 25 unmodified lines | |||
| 4457 | "when dumping packets, also dump the payload" }, | 4473 | "when dumping packets, also dump the payload" }, |
| 4458 | { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(rate_emu)}, "read input at native frame rate", "" }, | 4474 | { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(rate_emu)}, "read input at native frame rate", "" }, |
| 4459 | { "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" }, | 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 | { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" }, | 4477 | { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" }, |
| 4462 | { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" }, | 4478 | { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" }, |
| 4463 | { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" }, | 4479 | { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" }, |
| @@ -1226,6 +1226,7 @@ HAVE_LIST=" · 1225 unmodified lines | |||
| 1226 | struct_sockaddr_in6 | 1226 | struct_sockaddr_in6 |
| 1227 | struct_sockaddr_sa_len | 1227 | struct_sockaddr_sa_len |
| 1228 | struct_sockaddr_storage | 1228 | struct_sockaddr_storage |
| 1229 | struct_v4l2_frmivalenum_discrete | ||
| 1229 | symver | 1230 | symver |
| 1230 | symver_asm_label | 1231 | symver_asm_label |
| 1231 | symver_gnu_asm | 1232 | symver_gnu_asm |
| @@ -3174,6 +3175,8 @@ makeinfo --version > /dev/null 2>&1 && enable makeinfo || disable makeinfo · 1942 unmodified lines | |||
| 3174 | check_header linux/fb.h | 3175 | check_header linux/fb.h |
| 3175 | check_header linux/videodev.h | 3176 | check_header linux/videodev.h |
| 3176 | check_header linux/videodev2.h | 3177 | check_header linux/videodev2.h |
| 3178 | check_struct linux/videodev2.h "struct v4l2_frmivalenum" discrete | ||
| 3179 | |||
| 3177 | check_header sys/videoio.h | 3180 | check_header sys/videoio.h |
| 3178 | 3181 | ||
| 3179 | check_func_headers "windows.h vfw.h" capCreateCaptureWindow "$vfwcap_indev_extralibs" | 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 | 2011-08-14 - 323b930 - lavu 51.12.0 | 174 | 2011-08-14 - 323b930 - lavu 51.12.0 |
| 175 | Add av_fifo_peek2(), deprecate av_fifo_peek(). | 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 | 2011-08-16 - 48f9e45 - lavf 53.8.0 | 181 | 2011-08-16 - 48f9e45 - lavf 53.8.0 |
| 178 | Add avformat_query_codec(). | 182 | Add avformat_query_codec(). |
| 179 | 183 | ||
| @@ -749,15 +749,15 @@ Thread count. · 748 unmodified lines | |||
| 749 | Video sync method. | 749 | Video sync method. |
| 750 | 750 | ||
| 751 | @table @option | 751 | @table @option |
| 752 | @item 0 | 752 | @item passthrough |
| 753 | Each frame is passed with its timestamp from the demuxer to the muxer. | 753 | Each frame is passed with its timestamp from the demuxer to the muxer. |
| 754 | @item 1 | 754 | @item cfr |
| 755 | Frames will be duplicated and dropped to achieve exactly the requested | 755 | Frames will be duplicated and dropped to achieve exactly the requested |
| 756 | constant framerate. | 756 | constant framerate. |
| 757 | @item 2 | 757 | @item vfr |
| 758 | Frames are passed through with their timestamp or dropped so as to | 758 | Frames are passed through with their timestamp or dropped so as to |
| 759 | prevent 2 frames from having the same timestamp. | 759 | prevent 2 frames from having the same timestamp. |
| 760 | @item -1 | 760 | @item auto |
| 761 | Chooses between 1 and 2 depending on muxer capabilities. This is the | 761 | Chooses between 1 and 2 depending on muxer capabilities. This is the |
| 762 | default method. | 762 | default method. |
| 763 | @end table | 763 | @end table |
| @@ -134,7 +134,7 @@ library: · 133 unmodified lines | |||
| 134 | @item Brute Force & Ignorance @tab @tab X | 134 | @item Brute Force & Ignorance @tab @tab X |
| 135 | @tab Used in the game Flash Traffic: City of Angels. | 135 | @tab Used in the game Flash Traffic: City of Angels. |
| 136 | @item BWF @tab X @tab X | 136 | @item BWF @tab X @tab X |
| 137 | @item CRI ADX @tab @tab X | 137 | @item CRI ADX @tab X @tab X |
| 138 | @tab Audio-only format used in console video games. | 138 | @tab Audio-only format used in console video games. |
| 139 | @item Discworld II BMV @tab @tab X | 139 | @item Discworld II BMV @tab @tab X |
| 140 | @item Interplay C93 @tab @tab X | 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 | the device. | 515 | the device. |
| 516 | 516 | ||
| 517 | Video4Linux and Video4Linux2 devices only support a limited set of | 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 | supported for example with the command @command{dov4l} for Video4Linux | 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 | If the size for the device is set to 0x0, the input device will | 522 | If the size for the device is set to 0x0, the input device will |
| 523 | try to auto-detect the size to use. | 523 | try to auto-detect the size to use. |
| @@ -93,6 +93,11 @@ · 92 unmodified lines | |||
| 93 | 93 | ||
| 94 | #include "libavutil/avassert.h" | 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 | const char program_name[] = "ffmpeg"; | 101 | const char program_name[] = "ffmpeg"; |
| 97 | const int program_birth_year = 2000; | 102 | const int program_birth_year = 2000; |
| 98 | 103 | ||
| @@ -144,7 +149,7 @@ static int do_pkt_dump = 0; · 45 unmodified lines | |||
| 144 | static int do_psnr = 0; | 149 | static int do_psnr = 0; |
| 145 | static int do_pass = 0; | 150 | static int do_pass = 0; |
| 146 | static const char *pass_logfilename_prefix; | 151 | static const char *pass_logfilename_prefix; |
| 147 | static int video_sync_method = -1; | 152 | static int video_sync_method = VSYNC_AUTO; |
| 148 | static int audio_sync_method = 0; | 153 | static int audio_sync_method = 0; |
| 149 | static float audio_drift_threshold = 0.1; | 154 | static float audio_drift_threshold = 0.1; |
| 150 | static int copy_ts = 0; | 155 | static int copy_ts = 0; |
| @@ -1433,15 +1438,15 @@ static void do_video_out(AVFormatContext *s, · 1282 unmodified lines | |||
| 1433 | *frame_size = 0; | 1438 | *frame_size = 0; |
| 1434 | 1439 | ||
| 1435 | format_video_sync = video_sync_method; | 1440 | format_video_sync = video_sync_method; |
| 1436 | if (format_video_sync < 0) | 1441 | if (format_video_sync == VSYNC_AUTO) |
| 1437 | format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? 0 : 2) : 1; | 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 | double vdelta = sync_ipts - ost->sync_opts + duration; | 1445 | double vdelta = sync_ipts - ost->sync_opts + duration; |
| 1441 | // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c | 1446 | // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c |
| 1442 | if (vdelta < -1.1) | 1447 | if (vdelta < -1.1) |
| 1443 | nb_frames = 0; | 1448 | nb_frames = 0; |
| 1444 | else if (format_video_sync == 2) { | 1449 | else if (format_video_sync == VSYNC_VFR) { |
| 1445 | if (vdelta <= -0.6) { | 1450 | if (vdelta <= -0.6) { |
| 1446 | nb_frames = 0; | 1451 | nb_frames = 0; |
| 1447 | } else if (vdelta > 0.6) | 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 | return parse_option(o, "filter:v", arg, options); | 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 | #define OFFSET(x) offsetof(OptionsContext, x) | 4892 | #define OFFSET(x) offsetof(OptionsContext, x) |
| 4877 | static const OptionDef options[] = { | 4893 | static const OptionDef options[] = { |
| 4878 | /* main options */ | 4894 | /* main options */ |
| @@ -4908,7 +4924,7 @@ static const OptionDef options[] = { · 29 unmodified lines | |||
| 4908 | { "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "deprecated, use -loop" }, | 4924 | { "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "deprecated, use -loop" }, |
| 4909 | { "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "deprecated, use -loop", "" }, | 4925 | { "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "deprecated, use -loop", "" }, |
| 4910 | { "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" }, | 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 | { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" }, | 4928 | { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" }, |
| 4913 | { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" }, | 4929 | { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" }, |
| 4914 | { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" }, | 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 | return buf - avpkt->data; | 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 | AVCodec ff_adpcm_adx_decoder = { | 175 | AVCodec ff_adpcm_adx_decoder = { |
| 169 | .name = "adpcm_adx", | 176 | .name = "adpcm_adx", |
| 170 | .type = AVMEDIA_TYPE_AUDIO, | 177 | .type = AVMEDIA_TYPE_AUDIO, |
| @@ -172,6 +179,7 @@ AVCodec ff_adpcm_adx_decoder = { · 1 unmodified line | |||
| 172 | .priv_data_size = sizeof(ADXContext), | 179 | .priv_data_size = sizeof(ADXContext), |
| 173 | .init = adx_decode_init, | 180 | .init = adx_decode_init, |
| 174 | .decode = adx_decode_frame, | 181 | .decode = adx_decode_frame, |
| 182 | .flush = adx_decode_flush, | ||
| 175 | .capabilities = CODEC_CAP_DR1, | 183 | .capabilities = CODEC_CAP_DR1, |
| 176 | .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), | 184 | .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), |
| 177 | }; | 185 | }; |
| @@ -19,9 +19,9 @@ · 18 unmodified lines | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "libavutil/intreadwrite.h" | ||
| 23 | #include "avcodec.h" | 22 | #include "avcodec.h" |
| 24 | #include "adx.h" | 23 | #include "adx.h" |
| 24 | #include "bytestream.h" | ||
| 25 | #include "put_bits.h" | 25 | #include "put_bits.h" |
| 26 | 26 | ||
| 27 | /** | 27 | /** |
| @@ -33,167 +33,135 @@ · 5 unmodified lines | |||
| 33 | * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ | 33 | * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | /* 18 bytes <-> 32 samples */ | 36 | static void adx_encode(ADXContext *c, uint8_t *adx, const int16_t *wav, |
| 37 | 37 | ADXChannelState *prev, int channels) | |
| 38 | static void adx_encode(ADXContext *c, unsigned char *adx, const short *wav, | ||
| 39 | ADXChannelState *prev) | ||
| 40 | { | 38 | { |
| 41 | PutBitContext pb; | 39 | PutBitContext pb; |
| 42 | int scale; | 40 | int scale; |
| 43 | int i; | 41 | int i, j; |
| 44 | int s0,s1,s2,d; | 42 | int s0, s1, s2, d; |
| 45 | int max=0; | 43 | int max = 0; |
| 46 | int min=0; | 44 | int min = 0; |
| 47 | int data[32]; | 45 | int data[BLOCK_SAMPLES]; |
| 48 | 46 | ||
| 49 | s1 = prev->s1; | 47 | s1 = prev->s1; |
| 50 | s2 = prev->s2; | 48 | s2 = prev->s2; |
| 51 | for(i=0;i<32;i++) { | 49 | for (i = 0, j = 0; j < 32; i += channels, j++) { |
| 52 | s0 = wav[i]; | 50 | s0 = wav[i]; |
| 53 | d = ((s0 << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS; | 51 | d = ((s0 << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS; |
| 54 | data[i]=d; | 52 | data[j] = d; |
| 55 | if (max<d) max=d; | 53 | if (max < d) |
| 56 | if (min>d) min=d; | 54 | max = d; |
| 55 | if (min > d) | ||
| 56 | min = d; | ||
| 57 | s2 = s1; | 57 | s2 = s1; |
| 58 | s1 = s0; | 58 | s1 = s0; |
| 59 | } | 59 | } |
| 60 | prev->s1 = s1; | 60 | prev->s1 = s1; |
| 61 | prev->s2 = s2; | 61 | prev->s2 = s2; |
| 62 | 62 | ||
| 63 | /* -8..+7 */ | 63 | if (max == 0 && min == 0) { |
| 64 | 64 | memset(adx, 0, BLOCK_SIZE); | |
| 65 | if (max==0 && min==0) { | ||
| 66 | memset(adx,0,18); | ||
| 67 | return; | 65 | return; |
| 68 | } | 66 | } |
| 69 | 67 | ||
| 70 | if (max/7>-min/8) scale = max/7; | 68 | if (max / 7 > -min / 8) |
| 71 | else scale = -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 | AV_WB16(adx, scale); | 76 | AV_WB16(adx, scale); |
| 76 | 77 | ||
| 77 | init_put_bits(&pb, adx + 2, 16); | 78 | init_put_bits(&pb, adx + 2, 16); |
| 78 | for (i = 0; i < 32; i++) | 79 | for (i = 0; i < BLOCK_SAMPLES; i++) |
| 79 | put_sbits(&pb, 4, av_clip(data[i]/scale, -8, 7)); | 80 | put_sbits(&pb, 4, av_clip(data[i] / scale, -8, 7)); |
| 80 | flush_put_bits(&pb); | 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 | ADXContext *c = avctx->priv_data; | 88 | ADXContext *c = avctx->priv_data; |
| 109 | 89 | ||
| 110 | AV_WB32(buf+0x00,0x80000000|0x20); | 90 | if (bufsize < HEADER_SIZE) |
| 111 | AV_WB32(buf+0x04,0x03120400|avctx->channels); | 91 | return AVERROR(EINVAL); |
| 112 | AV_WB32(buf+0x08,avctx->sample_rate); | 92 | |
| 113 | AV_WB32(buf+0x0c,0); /* FIXME: set after */ | 93 | bytestream_put_be16(&buf, 0x8000); /* header signature */ |
| 114 | AV_WB16(buf + 0x10, c->cutoff); | 94 | bytestream_put_be16(&buf, HEADER_SIZE - 4); /* copyright offset */ |
| 115 | AV_WB32(buf + 0x12, 0x03000000); | 95 | bytestream_put_byte(&buf, 3); /* encoding */ |
| 116 | AV_WB32(buf + 0x16, 0x00000000); | 96 | bytestream_put_byte(&buf, BLOCK_SIZE); /* block size */ |
| 117 | AV_WB32(buf + 0x1a, 0x00000000); | 97 | bytestream_put_byte(&buf, 4); /* sample size */ |
| 118 | memcpy (buf + 0x1e, "(c)CRI", 6); | 98 | bytestream_put_byte(&buf, avctx->channels); /* channels */ |
| 119 | return 0x20+4; | 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 | static av_cold int adx_encode_init(AVCodecContext *avctx) | 112 | static av_cold int adx_encode_init(AVCodecContext *avctx) |
| 123 | { | 113 | { |
| 124 | ADXContext *c = avctx->priv_data; | 114 | ADXContext *c = avctx->priv_data; |
| 125 | 115 | ||
| 126 | if (avctx->channels > 2) | 116 | if (avctx->channels > 2) { |
| 127 | return -1; /* only stereo or mono =) */ | 117 | av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); |
| 128 | avctx->frame_size = 32; | 118 | return AVERROR(EINVAL); |
| 129 | 119 | } | |
| 130 | avctx->coded_frame= avcodec_alloc_frame(); | 120 | avctx->frame_size = BLOCK_SAMPLES; |
| 131 | avctx->coded_frame->key_frame= 1; | ||
| 132 | 121 | ||
| 133 | // avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; | 122 | avctx->coded_frame = avcodec_alloc_frame(); |
| 134 | 123 | ||
| 135 | /* the cutoff can be adjusted, but this seems to work pretty well */ | 124 | /* the cutoff can be adjusted, but this seems to work pretty well */ |
| 136 | c->cutoff = 500; | 125 | c->cutoff = 500; |
| 137 | ff_adx_calculate_coeffs(c->cutoff, avctx->sample_rate, COEFF_BITS, c->coeff); | 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 | return 0; | 128 | return 0; |
| 142 | } | 129 | } |
| 143 | 130 | ||
| 144 | static av_cold int adx_encode_close(AVCodecContext *avctx) | 131 | static av_cold int adx_encode_close(AVCodecContext *avctx) |
| 145 | { | 132 | { |
| 146 | av_freep(&avctx->coded_frame); | 133 | av_freep(&avctx->coded_frame); |
| 147 | |||
| 148 | return 0; | 134 | return 0; |
| 149 | } | 135 | } |
| 150 | 136 | ||
| 151 | static int adx_encode_frame(AVCodecContext *avctx, | 137 | static int adx_encode_frame(AVCodecContext *avctx, uint8_t *frame, |
| 152 | uint8_t *frame, int buf_size, void *data) | 138 | int buf_size, void *data) |
| 153 | { | 139 | { |
| 154 | ADXContext *c = avctx->priv_data; | 140 | ADXContext *c = avctx->priv_data; |
| 155 | const short *samples = data; | 141 | const int16_t *samples = data; |
| 156 | unsigned char *dst = frame; | 142 | uint8_t *dst = frame; |
| 157 | int rest = avctx->frame_size; | 143 | int ch; |
| 158 | |||
| 159 | /* | ||
| 160 | input data size = | ||
| 161 | ffmpeg.c: do_audio_out() | ||
| 162 | frame_bytes = enc->frame_size * 2 * enc->channels; | ||
| 163 | */ | ||
| 164 | 144 | ||
| 165 | // printf("sz=%d ",buf_size); fflush(stdout); | ||
| 166 | if (!c->header_parsed) { | 145 | if (!c->header_parsed) { |
| 167 | int hdrsize = adx_encode_header(avctx,dst,buf_size); | 146 | int hdrsize; |
| 168 | dst+=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 | c->header_parsed = 1; | 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) { | 160 | for (ch = 0; ch < avctx->channels; ch++) { |
| 173 | while(rest>=32) { | 161 | adx_encode(c, dst, samples + ch, &c->prev[ch], avctx->channels); |
| 174 | adx_encode(c, dst, samples, c->prev); | 162 | dst += BLOCK_SIZE; |
| 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 | } | ||
| 195 | } | 163 | } |
| 196 | return dst-frame; | 164 | return dst - frame; |
| 197 | } | 165 | } |
| 198 | 166 | ||
| 199 | AVCodec ff_adpcm_adx_encoder = { | 167 | AVCodec ff_adpcm_adx_encoder = { |
| @@ -204,6 +172,7 @@ AVCodec ff_adpcm_adx_encoder = { · 4 unmodified lines | |||
| 204 | .init = adx_encode_init, | 172 | .init = adx_encode_init, |
| 205 | .encode = adx_encode_frame, | 173 | .encode = adx_encode_frame, |
| 206 | .close = adx_encode_close, | 174 | .close = adx_encode_close, |
| 207 | .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, | 175 | .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, |
| 208 | .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), | 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 | void ff_rv34_inv_transform_neon(DCTELEM *block); | 26 | void ff_rv34_inv_transform_neon(DCTELEM *block); |
| 27 | void ff_rv34_inv_transform_noround_neon(DCTELEM *block); | 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 | void ff_rv34dsp_init_neon(RV34DSPContext *c, DSPContext* dsp) | 29 | void ff_rv34dsp_init_neon(RV34DSPContext *c, DSPContext* dsp) |
| 31 | { | 30 | { |
| 32 | c->rv34_inv_transform_tab[0] = ff_rv34_inv_transform_neon; | 31 | c->rv34_inv_transform_tab[0] = ff_rv34_inv_transform_neon; |
| 33 | c->rv34_inv_transform_tab[1] = ff_rv34_inv_transform_noround_neon; | 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 | vst4.16 {d0[3], d1[3], d2[3], d3[3]}, [r2,:64], r1 | 107 | vst4.16 {d0[3], d1[3], d2[3], d3[3]}, [r2,:64], r1 |
| 108 | bx lr | 108 | bx lr |
| 109 | endfunc | 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 | write(*b, value);\ | 39 | write(*b, value);\ |
| 40 | (*b) += bytes;\ | 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 | static av_always_inline type bytestream2_get_ ## name(GetByteContext *g)\ | 46 | static av_always_inline type bytestream2_get_ ## name(GetByteContext *g)\ |
| 43 | {\ | 47 | {\ |
| 44 | if (g->buffer_end - g->buffer < bytes)\ | 48 | if (g->buffer_end - g->buffer < bytes)\ |
| 45 | return 0;\ | 49 | return 0;\ |
| 46 | return bytestream_get_ ## name(&g->buffer);\ | 50 | return bytestream2_get_ ## name ## u(g);\ |
| 47 | }\ | 51 | }\ |
| 48 | static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g)\ | 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 | c->low= 0; | 109 | c->low= 0; |
| 110 | c->range= 0x1FE; | 110 | c->range= 0x1FE; |
| 111 | c->outstanding_count= 0; | 111 | c->outstanding_count= 0; |
| 112 | #ifdef STRICT_LIMITS | ||
| 113 | c->sym_count =0; | ||
| 114 | #endif | ||
| 115 | |||
| 116 | c->pb.bit_left++; //avoids firstBitFlag | 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 | renorm_cabac_encoder(c); | 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 | put_cabac_bit(c, 1); | 200 | put_cabac_bit(c, 1); |
| 209 | c->low -= 0x400; | 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 | flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong | 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 | return (put_bits_count(&c->pb)+7)>>3; | 227 | return (put_bits_count(&c->pb)+7)>>3; |
| 244 | } | 228 | } |
| 245 | 229 | ||
| @@ -365,21 +349,6 @@ START_TIMER · 119 unmodified lines | |||
| 365 | av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i); | 349 | av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i); |
| 366 | STOP_TIMER("get_cabac") | 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 | if(!get_cabac_terminate(&c)) | 352 | if(!get_cabac_terminate(&c)) |
| 384 | av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n"); | 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 | int low; | 41 | int low; |
| 42 | int range; | 42 | int range; |
| 43 | int outstanding_count; | 43 | int outstanding_count; |
| 44 | #ifdef STRICT_LIMITS | ||
| 45 | int symCount; | ||
| 46 | #endif | ||
| 47 | const uint8_t *bytestream_start; | 44 | const uint8_t *bytestream_start; |
| 48 | const uint8_t *bytestream; | 45 | const uint8_t *bytestream; |
| 49 | const uint8_t *bytestream_end; | 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 | #endif /* AVCODEC_CABAC_H */ | 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 | for (i = 0; i < 8; i++) { | 579 | for (i = 0; i < 8; i++) { |
| 580 | DCTELEM *block = ctx->blocks[i]; | 580 | DCTELEM *block = ctx->blocks[i]; |
| 581 | int last_index, overflow; | 581 | int overflow, n = dnxhd_switch_matrix(ctx, i); |
| 582 | int n = dnxhd_switch_matrix(ctx, i); | 582 | int last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow); |
| 583 | last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow); | ||
| 584 | //START_TIMER; | 583 | //START_TIMER; |
| 585 | dnxhd_encode_block(ctx, block, last_index, n); | 584 | dnxhd_encode_block(ctx, block, last_index, n); |
| 586 | //STOP_TIMER("encode_block"); | 585 | //STOP_TIMER("encode_block"); |
| @@ -4051,7 +4051,7 @@ static int decode_frame(AVCodecContext *avctx, · 4050 unmodified lines | |||
| 4051 | H264Context *h = avctx->priv_data; | 4051 | H264Context *h = avctx->priv_data; |
| 4052 | MpegEncContext *s = &h->s; | 4052 | MpegEncContext *s = &h->s; |
| 4053 | AVFrame *pict = data; | 4053 | AVFrame *pict = data; |
| 4054 | int buf_index; | 4054 | int buf_index = 0; |
| 4055 | Picture *out; | 4055 | Picture *out; |
| 4056 | int i, out_idx; | 4056 | int i, out_idx; |
| 4057 | 4057 | ||
| @@ -4081,7 +4081,7 @@ static int decode_frame(AVCodecContext *avctx, · 23 unmodified lines | |||
| 4081 | *pict= *(AVFrame*)out; | 4081 | *pict= *(AVFrame*)out; |
| 4082 | } | 4082 | } |
| 4083 | 4083 | ||
| 4084 | return buf_size; | 4084 | return buf_index; |
| 4085 | } | 4085 | } |
| 4086 | if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){ | 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 | int cnt= buf[5]&0x1f; | 4087 | int cnt= buf[5]&0x1f; |
| @@ -4112,7 +4112,6 @@ not_extra: · 24 unmodified lines | |||
| 4112 | 4112 | ||
| 4113 | if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) { | 4113 | if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) { |
| 4114 | av_assert0(buf_index <= buf_size); | 4114 | av_assert0(buf_index <= buf_size); |
| 4115 | buf_size = buf_index; | ||
| 4116 | goto out; | 4115 | goto out; |
| 4117 | } | 4116 | } |
| 4118 | 4117 | ||
| @@ -4193,9 +4192,7 @@ int main(void){ · 74 unmodified lines | |||
| 4193 | 4192 | ||
| 4194 | init_get_bits(&gb, temp, 8*SIZE); | 4193 | init_get_bits(&gb, temp, 8*SIZE); |
| 4195 | for(i=0; i<COUNT; i++){ | 4194 | for(i=0; i<COUNT; i++){ |
| 4196 | int j, s; | 4195 | int j, s = show_bits(&gb, 24); |
| 4197 | |||
| 4198 | s= show_bits(&gb, 24); | ||
| 4199 | 4196 | ||
| 4200 | {START_TIMER | 4197 | {START_TIMER |
| 4201 | j= get_ue_golomb(&gb); | 4198 | j= get_ue_golomb(&gb); |
| @@ -4218,9 +4215,7 @@ int main(void){ · 16 unmodified lines | |||
| 4218 | 4215 | ||
| 4219 | init_get_bits(&gb, temp, 8*SIZE); | 4216 | init_get_bits(&gb, temp, 8*SIZE); |
| 4220 | for(i=0; i<COUNT; i++){ | 4217 | for(i=0; i<COUNT; i++){ |
| 4221 | int j, s; | 4218 | int j, s = show_bits(&gb, 24); |
| 4222 | |||
| 4223 | s= show_bits(&gb, 24); | ||
| 4224 | 4219 | ||
| 4225 | {START_TIMER | 4220 | {START_TIMER |
| 4226 | j= get_se_golomb(&gb); | 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 | switch_buffers(ctx); | 761 | switch_buffers(ctx); |
| 762 | 762 | ||
| 763 | //START_TIMER; | 763 | //{ START_TIMER; |
| 764 | 764 | ||
| 765 | if (ctx->frame_type != FRAMETYPE_NULL) { | 765 | if (ctx->frame_type != FRAMETYPE_NULL) { |
| 766 | for (p = 0; p < 3; p++) { | 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 | if (ctx->frame.data[0]) | 780 | if (ctx->frame.data[0]) |
| 781 | avctx->release_buffer(avctx, &ctx->frame); | 781 | avctx->release_buffer(avctx, &ctx->frame); |
| @@ -83,7 +83,8 @@ typedef struct { · 82 unmodified lines | |||
| 83 | int abr; ///< flag to enable ABR | 83 | int abr; ///< flag to enable ABR |
| 84 | int pkt_frame_count; ///< frame count for the current packet | 84 | int pkt_frame_count; ///< frame count for the current packet |
| 85 | int lookahead; ///< encoder delay | 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 | } LibSpeexEncContext; | 88 | } LibSpeexEncContext; |
| 88 | 89 | ||
| 89 | static av_cold void print_enc_params(AVCodecContext *avctx, | 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 | /* set encoding delay */ | 203 | /* set encoding delay */ |
| 203 | speex_encoder_ctl(s->enc_state, SPEEX_GET_LOOKAHEAD, &s->lookahead); | 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 | /* create header packet bytes from header struct */ | 207 | /* create header packet bytes from header struct */ |
| 207 | /* note: libspeex allocates the memory for header_data, which is freed | 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 | LibSpeexEncContext *s = avctx->priv_data; | 237 | LibSpeexEncContext *s = avctx->priv_data; |
| 237 | int16_t *samples = data; | 238 | int16_t *samples = data; |
| 238 | int sample_count = s->sample_count; | ||
| 239 | 239 | ||
| 240 | if (data) { | 240 | if (data) { |
| 241 | /* encode Speex frame */ | 241 | /* encode Speex frame */ |
| @@ -243,7 +243,7 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, · 1 unmodified line | |||
| 243 | speex_encode_stereo_int(samples, s->header.frame_size, &s->bits); | 243 | speex_encode_stereo_int(samples, s->header.frame_size, &s->bits); |
| 244 | speex_encode_int(s->enc_state, samples, &s->bits); | 244 | speex_encode_int(s->enc_state, samples, &s->bits); |
| 245 | s->pkt_frame_count++; | 245 | s->pkt_frame_count++; |
| 246 | s->sample_count += avctx->frame_size; | 246 | s->pkt_sample_count += avctx->frame_size; |
| 247 | } else { | 247 | } else { |
| 248 | /* handle end-of-stream */ | 248 | /* handle end-of-stream */ |
| 249 | if (!s->pkt_frame_count) | 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 | if (s->pkt_frame_count == s->frames_per_packet) { | 259 | if (s->pkt_frame_count == s->frames_per_packet) { |
| 260 | s->pkt_frame_count = 0; | 260 | s->pkt_frame_count = 0; |
| 261 | avctx->coded_frame->pts = | 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 | avctx->time_base); | 263 | avctx->time_base); |
| 264 | s->next_pts += s->pkt_sample_count; | ||
| 265 | s->pkt_sample_count = 0; | ||
| 264 | if (buf_size > speex_bits_nbytes(&s->bits)) { | 266 | if (buf_size > speex_bits_nbytes(&s->bits)) { |
| 265 | int ret = speex_bits_write(&s->bits, frame, buf_size); | 267 | int ret = speex_bits_write(&s->bits, frame, buf_size); |
| 266 | speex_bits_reset(&s->bits); | 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 | * Get one coefficient value from the bistream and store it. | 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 | if(coef){ | 217 | if(coef){ |
| 218 | if(coef == esc){ | 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 | if(get_bits1(gb)) | 226 | if(get_bits1(gb)) |
| 227 | coef = -coef; | 227 | coef = -coef; |
| 228 | *dst = coef; | 228 | *dst = (coef*q + 8) >> 4; |
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | /** | 232 | /** |
| 233 | * Decode 2x2 subblock of coefficients. | 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 | int coeffs[4]; | 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 | coeffs[1] = modulo_three_table[code][1]; | 240 | coeffs[1] = modulo_three_table[code][1]; |
| 241 | coeffs[2] = modulo_three_table[code][2]; | 241 | coeffs[2] = modulo_three_table[code][2]; |
| 242 | coeffs[3] = modulo_three_table[code][3]; | 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 | if(is_block2){ | 244 | if(is_block2){ |
| 245 | decode_coeff(dst+8, coeffs[1], 2, gb, vlc); | 245 | decode_coeff(dst+8, coeffs[1], 2, gb, vlc, q); |
| 246 | decode_coeff(dst+1, coeffs[2], 2, gb, vlc); | 246 | decode_coeff(dst+1, coeffs[2], 2, gb, vlc, q); |
| 247 | }else{ | 247 | }else{ |
| 248 | decode_coeff(dst+1, coeffs[1], 2, gb, vlc); | 248 | decode_coeff(dst+1, coeffs[1], 2, gb, vlc, q); |
| 249 | decode_coeff(dst+8, coeffs[2], 2, gb, vlc); | 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 | * o--o | 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 | int code, pattern; | 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 | pattern = code & 0x7; | 291 | pattern = code & 0x7; |
| 272 | 292 | ||
| 273 | code >>= 3; | 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 | if(pattern & 4){ | 296 | if(pattern & 4){ |
| 277 | code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2); | 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 | if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block | 300 | if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block |
| 281 | code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2); | 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 | if(pattern & 1){ | 304 | if(pattern & 1){ |
| 285 | code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2); | 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 | * @name RV30/40 bitstream parsing | 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 | srcY += src_y * s->linesize + src_x; | 680 | srcY += src_y * s->linesize + src_x; |
| 677 | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; | 681 | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 678 | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; | 682 | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 679 | if( (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 | 683 | if(s->h_edge_pos - (width << 3) < 6 || s->v_edge_pos - (height << 3) < 6 || |
| 680 | || (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4){ | 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 | uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize; | 686 | uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize; |
| 682 | 687 | ||
| 683 | srcY -= 2 + 2*s->linesize; | 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 | MpegEncContext *s = &r->s; | 1102 | MpegEncContext *s = &r->s; |
| 1098 | GetBitContext *gb = &s->gb; | 1103 | GetBitContext *gb = &s->gb; |
| 1099 | int cbp, cbp2; | 1104 | int cbp, cbp2; |
| 1105 | int q_dc, q_ac; | ||
| 1100 | int i, blknum, blkoff; | 1106 | int i, blknum, blkoff; |
| 1101 | LOCAL_ALIGNED_16(DCTELEM, block16, [64]); | 1107 | LOCAL_ALIGNED_16(DCTELEM, block16, [64]); |
| 1102 | int luma_dc_quant; | 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 | luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16 ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale]; | 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 | if(r->is16){ | 1141 | if(r->is16){ |
| 1142 | q_dc = rv34_qscale_tab[luma_dc_quant]; | ||
| 1143 | q_ac = rv34_qscale_tab[s->qscale]; | ||
| 1136 | memset(block16, 0, 64 * sizeof(*block16)); | 1144 | memset(block16, 0, 64 * sizeof(*block16)); |
| 1137 | rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0); | 1145 | rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac); |
| 1138 | rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]); | ||
| 1139 | r->rdsp.rv34_inv_transform_tab[1](block16); | 1146 | r->rdsp.rv34_inv_transform_tab[1](block16); |
| 1140 | } | 1147 | } |
| 1141 | 1148 | ||
| 1149 | q_ac = rv34_qscale_tab[s->qscale]; | ||
| 1142 | for(i = 0; i < 16; i++, cbp >>= 1){ | 1150 | for(i = 0; i < 16; i++, cbp >>= 1){ |
| 1143 | if(!r->is16 && !(cbp & 1)) continue; | 1151 | if(!r->is16 && !(cbp & 1)) continue; |
| 1144 | blknum = ((i & 2) >> 1) + ((i & 8) >> 2); | 1152 | blknum = ((i & 2) >> 1) + ((i & 8) >> 2); |
| 1145 | blkoff = ((i & 1) << 2) + ((i & 4) << 3); | 1153 | blkoff = ((i & 1) << 2) + ((i & 4) << 3); |
| 1146 | if(cbp & 1) | 1154 | if(cbp & 1) |
| 1147 | rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0); | 1155 | rv34_decode_block(s->block[blknum] + blkoff, gb, |
| 1148 | r->rdsp.rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]); | 1156 | r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac); |
| 1149 | if(r->is16) //FIXME: optimize | 1157 | if(r->is16) //FIXME: optimize |
| 1150 | s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)]; | 1158 | s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)]; |
| 1151 | r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff); | 1159 | r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff); |
| 1152 | } | 1160 | } |
| 1153 | if(r->block_type == RV34_MB_P_MIX16x16) | 1161 | if(r->block_type == RV34_MB_P_MIX16x16) |
| 1154 | r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); | 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 | for(; i < 24; i++, cbp >>= 1){ | 1165 | for(; i < 24; i++, cbp >>= 1){ |
| 1156 | if(!(cbp & 1)) continue; | 1166 | if(!(cbp & 1)) continue; |
| 1157 | blknum = ((i & 4) >> 2) + 4; | 1167 | blknum = ((i & 4) >> 2) + 4; |
| 1158 | blkoff = ((i & 1) << 2) + ((i & 2) << 4); | 1168 | blkoff = ((i & 1) << 2) + ((i & 2) << 4); |
| 1159 | rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1); | 1169 | rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1, q_dc, q_ac, q_ac); |
| 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]]); | ||
| 1161 | r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff); | 1170 | r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff); |
| 1162 | } | 1171 | } |
| 1163 | if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])) | 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 | 963, 1074, 1212, 1392, 1566, 1708, 1978, 2211 | 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 | * tables used to translate a quantizer value into a VLC set for decoding | 104 | * tables used to translate a quantizer value into a VLC set for decoding |
| 115 | * The first table is used for intraframes. | 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 | /** @} */ // transform | 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 | av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) { | 103 | av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) { |
| 118 | c->rv34_inv_transform_tab[0] = rv34_inv_transform_c; | 104 | c->rv34_inv_transform_tab[0] = rv34_inv_transform_c; |
| 119 | c->rv34_inv_transform_tab[1] = rv34_inv_transform_noround_c; | 105 | c->rv34_inv_transform_tab[1] = rv34_inv_transform_noround_c; |
| 120 | 106 | ||
| 121 | c->rv34_dequant4x4 = rv34_dequant4x4_c; | ||
| 122 | |||
| 123 | if (HAVE_NEON) | 107 | if (HAVE_NEON) |
| 124 | ff_rv34dsp_init_neon(c, dsp); | 108 | ff_rv34dsp_init_neon(c, dsp); |
| 125 | } | 109 | } |
| @@ -56,7 +56,6 @@ typedef struct RV34DSPContext { · 55 unmodified lines | |||
| 56 | h264_chroma_mc_func avg_chroma_pixels_tab[3]; | 56 | h264_chroma_mc_func avg_chroma_pixels_tab[3]; |
| 57 | rv40_weight_func rv40_weight_pixels_tab[2]; | 57 | rv40_weight_func rv40_weight_pixels_tab[2]; |
| 58 | rv34_inv_transform_func rv34_inv_transform_tab[2]; | 58 | rv34_inv_transform_func rv34_inv_transform_tab[2]; |
| 59 | void (*rv34_dequant4x4)(DCTELEM *block, int Qdc, int Q); | ||
| 60 | rv40_weak_loop_filter_func rv40_weak_loop_filter[2]; | 59 | rv40_weak_loop_filter_func rv40_weak_loop_filter[2]; |
| 61 | rv40_strong_loop_filter_func rv40_strong_loop_filter[2]; | 60 | rv40_strong_loop_filter_func rv40_strong_loop_filter[2]; |
| 62 | rv40_loop_filter_strength_func rv40_loop_filter_strength[2]; | 61 | rv40_loop_filter_strength_func rv40_loop_filter_strength[2]; |
| @@ -38,16 +38,9 @@ typedef struct UltimotionDecodeContext { · 37 unmodified lines | |||
| 38 | int width, height, blocks; | 38 | int width, height, blocks; |
| 39 | AVFrame frame; | 39 | AVFrame frame; |
| 40 | const uint8_t *ulti_codebook; | 40 | const uint8_t *ulti_codebook; |
| 41 | GetByteContext gb; | ||
| 41 | } UltimotionDecodeContext; | 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 | static av_cold int ulti_decode_init(AVCodecContext *avctx) | 44 | static av_cold int ulti_decode_init(AVCodecContext *avctx) |
| 52 | { | 45 | { |
| 53 | UltimotionDecodeContext *s = avctx->priv_data; | 46 | UltimotionDecodeContext *s = avctx->priv_data; |
| @@ -232,7 +225,6 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 178 unmodified lines | |||
| 232 | int i; | 225 | int i; |
| 233 | int skip; | 226 | int skip; |
| 234 | int tmp; | 227 | int tmp; |
| 235 | const uint8_t *buf_end = buf + buf_size; | ||
| 236 | 228 | ||
| 237 | s->frame.reference = 3; | 229 | s->frame.reference = 3; |
| 238 | s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; | 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 | return -1; | 233 | return -1; |
| 242 | } | 234 | } |
| 243 | 235 | ||
| 236 | bytestream2_init(&s->gb, buf, buf_size); | ||
| 237 | |||
| 244 | while(!done) { | 238 | while(!done) { |
| 245 | int idx; | 239 | int idx; |
| 246 | if(blocks >= s->blocks || y >= s->height) | 240 | if(blocks >= s->blocks || y >= s->height) |
| 247 | break;//all blocks decoded | 241 | break;//all blocks decoded |
| 248 | 242 | ||
| 249 | CHECK_OVERREAD_SIZE(1); | 243 | if (bytestream2_get_bytes_left(&s->gb) < 1) |
| 250 | idx = *buf++; | 244 | goto err; |
| 245 | idx = bytestream2_get_byteu(&s->gb); | ||
| 251 | if((idx & 0xF8) == 0x70) { | 246 | if((idx & 0xF8) == 0x70) { |
| 252 | switch(idx) { | 247 | switch(idx) { |
| 253 | case 0x70: //change modifier | 248 | case 0x70: //change modifier |
| 254 | CHECK_OVERREAD_SIZE(1); | 249 | modifier = bytestream2_get_byte(&s->gb); |
| 255 | modifier = *buf++; | ||
| 256 | if(modifier>1) | 250 | if(modifier>1) |
| 257 | av_log(avctx, AV_LOG_INFO, "warning: modifier must be 0 or 1, got %i\n", modifier); | 251 | av_log(avctx, AV_LOG_INFO, "warning: modifier must be 0 or 1, got %i\n", modifier); |
| 258 | break; | 252 | break; |
| @@ -266,8 +260,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 7 unmodified lines | |||
| 266 | done = 1; | 260 | done = 1; |
| 267 | break; | 261 | break; |
| 268 | case 0x74: //skip some blocks | 262 | case 0x74: //skip some blocks |
| 269 | CHECK_OVERREAD_SIZE(1); | 263 | skip = bytestream2_get_byte(&s->gb); |
| 270 | skip = *buf++; | ||
| 271 | if ((blocks + skip) >= s->blocks) | 264 | if ((blocks + skip) >= s->blocks) |
| 272 | break; | 265 | break; |
| 273 | blocks += skip; | 266 | blocks += skip; |
| @@ -294,8 +287,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 20 unmodified lines | |||
| 294 | } else { | 287 | } else { |
| 295 | cf = 0; | 288 | cf = 0; |
| 296 | if (idx) { | 289 | if (idx) { |
| 297 | CHECK_OVERREAD_SIZE(1); | 290 | chroma = bytestream2_get_byte(&s->gb); |
| 298 | chroma = *buf++; | ||
| 299 | } | 291 | } |
| 300 | } | 292 | } |
| 301 | for (i = 0; i < 4; i++) { // for every subblock | 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 | if(!code) //skip subblock | 295 | if(!code) //skip subblock |
| 304 | continue; | 296 | continue; |
| 305 | if(cf) { | 297 | if(cf) { |
| 306 | CHECK_OVERREAD_SIZE(1); | 298 | chroma = bytestream2_get_byte(&s->gb); |
| 307 | chroma = *buf++; | ||
| 308 | } | 299 | } |
| 309 | tx = x + block_coords[i * 2]; | 300 | tx = x + block_coords[i * 2]; |
| 310 | ty = y + block_coords[(i * 2) + 1]; | 301 | ty = y + block_coords[(i * 2) + 1]; |
| 311 | switch(code) { | 302 | switch(code) { |
| 312 | case 1: | 303 | case 1: |
| 313 | CHECK_OVERREAD_SIZE(1); | 304 | tmp = bytestream2_get_byte(&s->gb); |
| 314 | tmp = *buf++; | ||
| 315 | 305 | ||
| 316 | angle = angle_by_index[(tmp >> 6) & 0x3]; | 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 | case 2: | 322 | case 2: |
| 333 | if (modifier) { // unpack four luma samples | 323 | if (modifier) { // unpack four luma samples |
| 334 | CHECK_OVERREAD_SIZE(3); | 324 | tmp = bytestream2_get_be24(&s->gb); |
| 335 | tmp = bytestream_get_be24(&buf); | ||
| 336 | 325 | ||
| 337 | Y[0] = (tmp >> 18) & 0x3F; | 326 | Y[0] = (tmp >> 18) & 0x3F; |
| 338 | Y[1] = (tmp >> 12) & 0x3F; | 327 | Y[1] = (tmp >> 12) & 0x3F; |
| @@ -340,8 +329,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 1 unmodified line | |||
| 340 | Y[3] = tmp & 0x3F; | 329 | Y[3] = tmp & 0x3F; |
| 341 | angle = 16; | 330 | angle = 16; |
| 342 | } else { // retrieve luma samples from codebook | 331 | } else { // retrieve luma samples from codebook |
| 343 | CHECK_OVERREAD_SIZE(2); | 332 | tmp = bytestream2_get_be16(&s->gb); |
| 344 | tmp = bytestream_get_be16(&buf); | ||
| 345 | 333 | ||
| 346 | angle = (tmp >> 12) & 0xF; | 334 | angle = (tmp >> 12) & 0xF; |
| 347 | tmp &= 0xFFF; | 335 | tmp &= 0xFFF; |
| @@ -357,27 +345,27 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 9 unmodified lines | |||
| 357 | if (modifier) { // all 16 luma samples | 345 | if (modifier) { // all 16 luma samples |
| 358 | uint8_t Luma[16]; | 346 | uint8_t Luma[16]; |
| 359 | 347 | ||
| 360 | CHECK_OVERREAD_SIZE(12); | 348 | if (bytestream2_get_bytes_left(&s->gb) < 12) |
| 361 | 349 | goto err; | |
| 362 | tmp = bytestream_get_be24(&buf); | 350 | tmp = bytestream2_get_be24u(&s->gb); |
| 363 | Luma[0] = (tmp >> 18) & 0x3F; | 351 | Luma[0] = (tmp >> 18) & 0x3F; |
| 364 | Luma[1] = (tmp >> 12) & 0x3F; | 352 | Luma[1] = (tmp >> 12) & 0x3F; |
| 365 | Luma[2] = (tmp >> 6) & 0x3F; | 353 | Luma[2] = (tmp >> 6) & 0x3F; |
| 366 | Luma[3] = tmp & 0x3F; | 354 | Luma[3] = tmp & 0x3F; |
| 367 | 355 | ||
| 368 | tmp = bytestream_get_be24(&buf); | 356 | tmp = bytestream2_get_be24u(&s->gb); |
| 369 | Luma[4] = (tmp >> 18) & 0x3F; | 357 | Luma[4] = (tmp >> 18) & 0x3F; |
| 370 | Luma[5] = (tmp >> 12) & 0x3F; | 358 | Luma[5] = (tmp >> 12) & 0x3F; |
| 371 | Luma[6] = (tmp >> 6) & 0x3F; | 359 | Luma[6] = (tmp >> 6) & 0x3F; |
| 372 | Luma[7] = tmp & 0x3F; | 360 | Luma[7] = tmp & 0x3F; |
| 373 | 361 | ||
| 374 | tmp = bytestream_get_be24(&buf); | 362 | tmp = bytestream2_get_be24u(&s->gb); |
| 375 | Luma[8] = (tmp >> 18) & 0x3F; | 363 | Luma[8] = (tmp >> 18) & 0x3F; |
| 376 | Luma[9] = (tmp >> 12) & 0x3F; | 364 | Luma[9] = (tmp >> 12) & 0x3F; |
| 377 | Luma[10] = (tmp >> 6) & 0x3F; | 365 | Luma[10] = (tmp >> 6) & 0x3F; |
| 378 | Luma[11] = tmp & 0x3F; | 366 | Luma[11] = tmp & 0x3F; |
| 379 | 367 | ||
| 380 | tmp = bytestream_get_be24(&buf); | 368 | tmp = bytestream2_get_be24u(&s->gb); |
| 381 | Luma[12] = (tmp >> 18) & 0x3F; | 369 | Luma[12] = (tmp >> 18) & 0x3F; |
| 382 | Luma[13] = (tmp >> 12) & 0x3F; | 370 | Luma[13] = (tmp >> 12) & 0x3F; |
| 383 | Luma[14] = (tmp >> 6) & 0x3F; | 371 | Luma[14] = (tmp >> 6) & 0x3F; |
| @@ -385,22 +373,23 @@ static int ulti_decode_frame(AVCodecContext *avctx, · 1 unmodified line | |||
| 385 | 373 | ||
| 386 | ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma); | 374 | ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma); |
| 387 | } else { | 375 | } else { |
| 388 | CHECK_OVERREAD_SIZE(4); | 376 | if (bytestream2_get_bytes_left(&s->gb) < 4) |
| 389 | tmp = *buf++; | 377 | goto err; |
| 378 | tmp = bytestream2_get_byteu(&s->gb); | ||
| 390 | if(tmp & 0x80) { | 379 | if(tmp & 0x80) { |
| 391 | angle = (tmp >> 4) & 0x7; | 380 | angle = (tmp >> 4) & 0x7; |
| 392 | tmp = (tmp << 8) + *buf++; | 381 | tmp = (tmp << 8) + bytestream2_get_byteu(&s->gb); |
| 393 | Y[0] = (tmp >> 6) & 0x3F; | 382 | Y[0] = (tmp >> 6) & 0x3F; |
| 394 | Y[1] = tmp & 0x3F; | 383 | Y[1] = tmp & 0x3F; |
| 395 | Y[2] = (*buf++) & 0x3F; | 384 | Y[2] = bytestream2_get_byteu(&s->gb) & 0x3F; |
| 396 | Y[3] = (*buf++) & 0x3F; | 385 | Y[3] = bytestream2_get_byteu(&s->gb) & 0x3F; |
| 397 | ulti_grad(&s->frame, tx, ty, Y, chroma, angle); //draw block | 386 | ulti_grad(&s->frame, tx, ty, Y, chroma, angle); //draw block |
| 398 | } else { // some patterns | 387 | } else { // some patterns |
| 399 | int f0, f1; | 388 | int f0, f1; |
| 400 | f0 = *buf++; | 389 | f0 = bytestream2_get_byteu(&s->gb); |
| 401 | f1 = tmp; | 390 | f1 = tmp; |
| 402 | Y[0] = (*buf++) & 0x3F; | 391 | Y[0] = bytestream2_get_byteu(&s->gb) & 0x3F; |
| 403 | Y[1] = (*buf++) & 0x3F; | 392 | Y[1] = bytestream2_get_byteu(&s->gb) & 0x3F; |
| 404 | ulti_pattern(&s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma); | 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 | *(AVFrame*)data= s->frame; | 411 | *(AVFrame*)data= s->frame; |
| 423 | 412 | ||
| 424 | return buf_size; | 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 | AVCodec ff_ulti_decoder = { | 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 | if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) | 570 | if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) |
| 571 | || s->h_edge_pos < 22 || v_edge_pos < 22 | ||
| 571 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3 | 572 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3 |
| 572 | || (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel * 3) { | 573 | || (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel * 3) { |
| 573 | uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize; | 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 | if (fieldmv && (src_y & 1) && src_y < 4) | 800 | if (fieldmv && (src_y & 1) && src_y < 4) |
| 800 | src_y--; | 801 | src_y--; |
| 801 | if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) | 802 | if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) |
| 803 | || s->h_edge_pos < 13 || v_edge_pos < 23 | ||
| 802 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2 | 804 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2 |
| 803 | || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) { | 805 | || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) { |
| 804 | srcY -= s->mspel * (1 + (s->linesize << fieldmv)); | 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 | if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) | 1002 | if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) |
| 1003 | || s->h_edge_pos < 18 || v_edge_pos < 18 | ||
| 1001 | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9 | 1004 | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9 |
| 1002 | || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) { | 1005 | || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) { |
| 1003 | s->dsp.emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize, | 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 | if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2) | 1105 | if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2) |
| 1103 | uvsrc_y--; | 1106 | uvsrc_y--; |
| 1104 | if ((v->mv_mode == MV_PMODE_INTENSITY_COMP) | 1107 | if ((v->mv_mode == MV_PMODE_INTENSITY_COMP) |
| 1108 | || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv) | ||
| 1105 | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5 | 1109 | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5 |
| 1106 | || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) { | 1110 | || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) { |
| 1107 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize, | 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 | srcV = s->edge_emu_buffer + 18 * s->linesize; | 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 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 16 - s->mspel * 3 | 2014 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 16 - s->mspel * 3 |
| 2011 | || (unsigned)(src_y - s->mspel) > v_edge_pos - (my & 3) - 16 - s->mspel * 3) { | 2015 | || (unsigned)(src_y - s->mspel) > v_edge_pos - (my & 3) - 16 - s->mspel * 3) { |
| 2012 | uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize; | 2016 | uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize; |
| @@ -69,19 +69,17 @@ · 68 unmodified lines | |||
| 69 | 69 | ||
| 70 | static const int desired_video_buffers = 256; | 70 | static const int desired_video_buffers = 256; |
| 71 | 71 | ||
| 72 | enum io_method { | 72 | #define V4L_ALLFORMATS 3 |
| 73 | io_read, | 73 | #define V4L_RAWFORMATS 1 |
| 74 | io_mmap, | 74 | #define V4L_COMPFORMATS 2 |
| 75 | io_userptr | ||
| 76 | }; | ||
| 77 | 75 | ||
| 78 | struct video_data { | 76 | struct video_data { |
| 79 | AVClass *class; | 77 | AVClass *class; |
| 80 | int fd; | 78 | int fd; |
| 81 | int frame_format; /* V4L2_PIX_FMT_* */ | 79 | int frame_format; /* V4L2_PIX_FMT_* */ |
| 82 | enum io_method io_method; | ||
| 83 | int width, height; | 80 | int width, height; |
| 84 | int frame_size; | 81 | int frame_size; |
| 82 | int interlaced; | ||
| 85 | int top_field_first; | 83 | int top_field_first; |
| 86 | 84 | ||
| 87 | int buffers; | 85 | int buffers; |
| @@ -89,8 +87,10 @@ struct video_data { · 1 unmodified line | |||
| 89 | unsigned int *buf_len; | 87 | unsigned int *buf_len; |
| 90 | char *standard; | 88 | char *standard; |
| 91 | int channel; | 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 | char *pixel_format; /**< Set by a private option. */ | 92 | char *pixel_format; /**< Set by a private option. */ |
| 93 | int list_format; /**< Set by a private option. */ | ||
| 94 | char *framerate; /**< Set by a private option. */ | 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 | { PIX_FMT_NONE, CODEC_ID_MJPEG, V4L2_PIX_FMT_JPEG }, | 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 | struct v4l2_capability cap; | 129 | struct v4l2_capability cap; |
| 130 | int fd; | 130 | int fd; |
| @@ -137,11 +137,15 @@ static int device_open(AVFormatContext *ctx, uint32_t *capabilities) · 6 unmodified lines | |||
| 137 | if (ctx->flags & AVFMT_FLAG_NONBLOCK) { | 137 | if (ctx->flags & AVFMT_FLAG_NONBLOCK) { |
| 138 | flags |= O_NONBLOCK; | 138 | flags |= O_NONBLOCK; |
| 139 | } | 139 | } |
| 140 | |||
| 140 | fd = v4l2_open(ctx->filename, flags, 0); | 141 | fd = v4l2_open(ctx->filename, flags, 0); |
| 141 | if (fd < 0) { | 142 | if (fd < 0) { |
| 143 | err = errno; | ||
| 144 | |||
| 142 | av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n", | 145 | av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n", |
| 143 | ctx->filename, strerror(errno)); | 146 | ctx->filename, strerror(err)); |
| 144 | return AVERROR(errno); | 147 | |
| 148 | return AVERROR(err); | ||
| 145 | } | 149 | } |
| 146 | #if CONFIG_LIBV4L2 | 150 | #if CONFIG_LIBV4L2 |
| 147 | fd_libv4l = v4l2_fd_open(fd, 0); | 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 | #endif | 159 | #endif |
| 156 | 160 | ||
| 157 | res = v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap); | 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 | if (res < 0) { | 162 | if (res < 0) { |
| 163 | err = errno; | ||
| 166 | av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n", | 164 | av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n", |
| 167 | strerror(errno)); | 165 | strerror(err)); |
| 168 | v4l2_close(fd); | 166 | |
| 169 | return AVERROR(err); | 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) { | 179 | |
| 172 | av_log(ctx, AV_LOG_ERROR, "Not a video capture device\n"); | 180 | if (!(cap.capabilities & V4L2_CAP_STREAMING)) { |
| 173 | v4l2_close(fd); | 181 | av_log(ctx, AV_LOG_ERROR, |
| 174 | return AVERROR(ENODEV); | 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 | return fd; | 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 | struct video_data *s = ctx->priv_data; | 198 | struct video_data *s = ctx->priv_data; |
| 184 | int fd = s->fd; | 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 | int res; | 203 | int res; |
| 187 | 204 | ||
| 205 | memset(&fmt, 0, sizeof(struct v4l2_format)); | ||
| 206 | |||
| 188 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 207 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 189 | fmt.fmt.pix.width = *width; | 208 | pix->width = *width; |
| 190 | fmt.fmt.pix.height = *height; | 209 | pix->height = *height; |
| 191 | fmt.fmt.pix.pixelformat = pix_fmt; | 210 | pix->pixelformat = pix_fmt; |
| 192 | fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; | 211 | pix->field = V4L2_FIELD_ANY; |
| 212 | |||
| 193 | res = v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt); | 213 | res = v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt); |
| 214 | |||
| 194 | if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) { | 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 | *width = fmt.fmt.pix.width; | 219 | *width = fmt.fmt.pix.width; |
| 197 | *height = fmt.fmt.pix.height; | 220 | *height = fmt.fmt.pix.height; |
| 198 | } | 221 | } |
| 199 | 222 | ||
| 200 | if (pix_fmt != fmt.fmt.pix.pixelformat) { | 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 | res = -1; | 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 | return res; | 236 | return res; |
| 206 | } | 237 | } |
| 207 | 238 | ||
| @@ -264,6 +295,71 @@ static enum CodecID fmt_v4l2codec(uint32_t v4l2_fmt) · 56 unmodified lines | |||
| 264 | return CODEC_ID_NONE; | 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 | static int mmap_init(AVFormatContext *ctx) | 363 | static int mmap_init(AVFormatContext *ctx) |
| 268 | { | 364 | { |
| 269 | struct video_data *s = ctx->priv_data; | 365 | struct video_data *s = ctx->priv_data; |
| @@ -314,12 +410,16 @@ static int mmap_init(AVFormatContext *ctx) · 44 unmodified lines | |||
| 314 | 410 | ||
| 315 | s->buf_len[i] = buf.length; | 411 | s->buf_len[i] = buf.length; |
| 316 | if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) { | 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 | return -1; | 417 | return -1; |
| 320 | } | 418 | } |
| 321 | s->buf_start[i] = v4l2_mmap(NULL, buf.length, | 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 | if (s->buf_start[i] == MAP_FAILED) { | 423 | if (s->buf_start[i] == MAP_FAILED) { |
| 324 | av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno)); | 424 | av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno)); |
| 325 | return AVERROR(errno); | 425 | return AVERROR(errno); |
| @@ -329,20 +429,14 @@ static int mmap_init(AVFormatContext *ctx) · 3 unmodified lines | |||
| 329 | return 0; | 429 | return 0; |
| 330 | } | 430 | } |
| 331 | 431 | ||
| 332 | static int read_init(AVFormatContext *ctx) | ||
| 333 | { | ||
| 334 | return -1; | ||
| 335 | } | ||
| 336 | |||
| 337 | static void mmap_release_buffer(AVPacket *pkt) | 432 | static void mmap_release_buffer(AVPacket *pkt) |
| 338 | { | 433 | { |
| 339 | struct v4l2_buffer buf = {0}; | 434 | struct v4l2_buffer buf = {0}; |
| 340 | int res, fd; | 435 | int res, fd; |
| 341 | struct buff_data *buf_descriptor = pkt->priv; | 436 | struct buff_data *buf_descriptor = pkt->priv; |
| 342 | 437 | ||
| 343 | if (pkt->data == NULL) { | 438 | if (pkt->data == NULL) |
| 344 | return; | 439 | return; |
| 345 | } | ||
| 346 | 440 | ||
| 347 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 441 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 348 | buf.memory = V4L2_MEMORY_MMAP; | 442 | buf.memory = V4L2_MEMORY_MMAP; |
| @@ -351,9 +445,10 @@ static void mmap_release_buffer(AVPacket *pkt) · 2 unmodified lines | |||
| 351 | av_free(buf_descriptor); | 445 | av_free(buf_descriptor); |
| 352 | 446 | ||
| 353 | res = v4l2_ioctl(fd, VIDIOC_QBUF, &buf); | 447 | res = v4l2_ioctl(fd, VIDIOC_QBUF, &buf); |
| 354 | if (res < 0) { | 448 | if (res < 0) |
| 355 | av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno)); | 449 | av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", |
| 356 | } | 450 | strerror(errno)); |
| 451 | |||
| 357 | pkt->data = NULL; | 452 | pkt->data = NULL; |
| 358 | pkt->size = 0; | 453 | pkt->size = 0; |
| 359 | } | 454 | } |
| @@ -375,13 +470,17 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) · 15 unmodified lines | |||
| 375 | pkt->size = 0; | 470 | pkt->size = 0; |
| 376 | return AVERROR(EAGAIN); | 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 | return AVERROR(errno); | 476 | return AVERROR(errno); |
| 381 | } | 477 | } |
| 382 | assert(buf.index < s->buffers); | 478 | assert(buf.index < s->buffers); |
| 383 | if (s->frame_size > 0 && buf.bytesused != s->frame_size) { | 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 | return AVERROR_INVALIDDATA; | 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 | return s->buf_len[buf.index]; | 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 | static int mmap_start(AVFormatContext *ctx) | 509 | static int mmap_start(AVFormatContext *ctx) |
| 416 | { | 510 | { |
| 417 | struct video_data *s = ctx->priv_data; | 511 | struct video_data *s = ctx->priv_data; |
| @@ -427,7 +521,9 @@ static int mmap_start(AVFormatContext *ctx) · 9 unmodified lines | |||
| 427 | 521 | ||
| 428 | res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf); | 522 | res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf); |
| 429 | if (res < 0) { | 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 | return AVERROR(errno); | 527 | return AVERROR(errno); |
| 432 | } | 528 | } |
| 433 | } | 529 | } |
| @@ -435,7 +531,9 @@ static int mmap_start(AVFormatContext *ctx) · 1 unmodified line | |||
| 435 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 531 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 436 | res = v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type); | 532 | res = v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type); |
| 437 | if (res < 0) { | 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 | return AVERROR(errno); | 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 | streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 570 | streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 473 | 571 | ||
| 474 | if (s->framerate && (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) { | 572 | if (s->framerate && |
| 475 | av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", 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 | return ret; | 576 | return ret; |
| 477 | } | 577 | } |
| 478 | 578 | ||
| @@ -486,7 +586,8 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap) · 7 unmodified lines | |||
| 486 | av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n", | 586 | av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n", |
| 487 | s->channel, input.name); | 587 | s->channel, input.name); |
| 488 | if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) { | 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 | s->channel); | 591 | s->channel); |
| 491 | return AVERROR(EIO); | 592 | return AVERROR(EIO); |
| 492 | } | 593 | } |
| @@ -506,10 +607,12 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap) · 13 unmodified lines | |||
| 506 | return ret; | 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 | s->standard, (uint64_t)standard.id); | 612 | s->standard, (uint64_t)standard.id); |
| 511 | if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) { | 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 | s->standard); | 616 | s->standard); |
| 514 | return AVERROR(EIO); | 617 | return AVERROR(EIO); |
| 515 | } | 618 | } |
| @@ -520,6 +623,7 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap) · 4 unmodified lines | |||
| 520 | framerate_q.den, framerate_q.num); | 623 | framerate_q.den, framerate_q.num); |
| 521 | tpf->numerator = framerate_q.den; | 624 | tpf->numerator = framerate_q.den; |
| 522 | tpf->denominator = framerate_q.num; | 625 | tpf->denominator = framerate_q.num; |
| 626 | |||
| 523 | if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) { | 627 | if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) { |
| 524 | av_log(s1, AV_LOG_ERROR, | 628 | av_log(s1, AV_LOG_ERROR, |
| 525 | "ioctl set time per frame(%d/%d) failed\n", | 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 | if (framerate_q.num != tpf->denominator || | 634 | if (framerate_q.num != tpf->denominator || |
| 531 | framerate_q.den != tpf->numerator) { | 635 | framerate_q.den != tpf->numerator) { |
| 532 | av_log(s1, AV_LOG_INFO, | 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 | framerate_q.den, framerate_q.num, | 639 | framerate_q.den, framerate_q.num, |
| 535 | tpf->numerator, tpf->denominator); | 640 | tpf->numerator, tpf->denominator); |
| 536 | } | 641 | } |
| 537 | } else { | 642 | } else { |
| 538 | /* if timebase value is not set, read the timebase value from the driver */ | ||
| 539 | if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) { | 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 | return AVERROR(errno); | 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 | if (desired_format != 0) { | 680 | if (desired_format != 0) { |
| 575 | *codec_id = fmt_v4l2codec(desired_format); | 681 | *codec_id = fmt_v4l2codec(desired_format); |
| 576 | assert(*codec_id != CODEC_ID_NONE); | 682 | assert(*codec_id != CODEC_ID_NONE); |
| @@ -584,7 +690,7 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) · 7 unmodified lines | |||
| 584 | struct video_data *s = s1->priv_data; | 690 | struct video_data *s = s1->priv_data; |
| 585 | AVStream *st; | 691 | AVStream *st; |
| 586 | int res = 0; | 692 | int res = 0; |
| 587 | uint32_t desired_format, capabilities; | 693 | uint32_t desired_format; |
| 588 | enum CodecID codec_id; | 694 | enum CodecID codec_id; |
| 589 | enum PixelFormat pix_fmt = PIX_FMT_NONE; | 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 | res = AVERROR(ENOMEM); | 699 | res = AVERROR(ENOMEM); |
| 594 | goto out; | 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) { | 703 | s->fd = device_open(s1); |
| 599 | av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n", s->video_size); | 704 | if (s->fd < 0) { |
| 705 | res = s->fd; | ||
| 600 | goto out; | 706 | goto out; |
| 601 | } | 707 | } |
| 602 | if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) { | 708 | |
| 603 | av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format); | 709 | if (s->list_format) { |
| 604 | res = AVERROR(EINVAL); | 710 | list_formats(s1, s->fd, s->list_format); |
| 711 | res = AVERROR_EXIT; | ||
| 605 | goto out; | 712 | goto out; |
| 606 | } | 713 | } |
| 607 | 714 | ||
| 608 | capabilities = 0; | 715 | avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ |
| 609 | s->fd = device_open(s1, &capabilities); | 716 | |
| 610 | if (s->fd < 0) { | 717 | if (s->video_size && |
| 611 | res = AVERROR(EIO); | 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 | goto out; | 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 | if (!s->width && !s->height) { | 737 | if (!s->width && !s->height) { |
| 617 | struct v4l2_format fmt; | 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 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 742 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 621 | if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) { | 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 | res = AVERROR(errno); | 746 | res = AVERROR(errno); |
| 624 | goto out; | 747 | goto out; |
| 625 | } | 748 | } |
| 749 | |||
| 626 | s->width = fmt.fmt.pix.width; | 750 | s->width = fmt.fmt.pix.width; |
| 627 | s->height = fmt.fmt.pix.height; | 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 | if (desired_format == 0) { | 758 | if (desired_format == 0) { |
| 633 | av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for " | 759 | av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for " |
| 634 | "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt); | 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 | if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0) | 766 | if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0) |
| 641 | goto out; | 767 | goto out; |
| 768 | |||
| 642 | s->frame_format = desired_format; | 769 | s->frame_format = desired_format; |
| 643 | 770 | ||
| 644 | if ((res = v4l2_set_parameters(s1, ap)) < 0) | 771 | if ((res = v4l2_set_parameters(s1, ap)) < 0) |
| 645 | goto out; | 772 | goto out; |
| 646 | 773 | ||
| 647 | st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id); | 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); | 775 | s->frame_size = |
| 649 | if (capabilities & V4L2_CAP_STREAMING) { | 776 | avpicture_get_size(st->codec->pix_fmt, s->width, s->height); |
| 650 | s->io_method = io_mmap; | 777 | |
| 651 | res = mmap_init(s1); | 778 | if ((res = mmap_init(s1)) || |
| 652 | if (res == 0) { | 779 | (res = mmap_start(s1)) < 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) { | ||
| 660 | v4l2_close(s->fd); | 780 | v4l2_close(s->fd); |
| 661 | res = AVERROR(EIO); | ||
| 662 | goto out; | 781 | goto out; |
| 663 | } | 782 | } |
| 783 | |||
| 664 | s->top_field_first = first_field(s->fd); | 784 | s->top_field_first = first_field(s->fd); |
| 665 | 785 | ||
| 666 | st->codec->codec_type = AVMEDIA_TYPE_VIDEO; | 786 | st->codec->codec_type = AVMEDIA_TYPE_VIDEO; |
| 667 | st->codec->codec_id = codec_id; | 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 | st->codec->width = s->width; | 791 | st->codec->width = s->width; |
| 669 | st->codec->height = s->height; | 792 | st->codec->height = s->height; |
| 670 | st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8; | 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 | static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt) | 799 | static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt) |
| 677 | { | 800 | { |
| 678 | struct video_data *s = s1->priv_data; | 801 | struct video_data *s = s1->priv_data; |
| 802 | AVFrame *frame = s1->streams[0]->codec->coded_frame; | ||
| 679 | int res; | 803 | int res; |
| 680 | 804 | ||
| 681 | if (s->io_method == io_mmap) { | 805 | av_init_packet(pkt); |
| 682 | av_init_packet(pkt); | 806 | if ((res = mmap_read_frame(s1, pkt)) < 0) { |
| 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) { | ||
| 693 | return res; | 807 | return res; |
| 694 | } | 808 | } |
| 695 | 809 | ||
| 696 | if (s1->streams[0]->codec->coded_frame) { | 810 | if (frame && s->interlaced) { |
| 697 | s1->streams[0]->codec->coded_frame->interlaced_frame = 1; | 811 | frame->interlaced_frame = 1; |
| 698 | s1->streams[0]->codec->coded_frame->top_field_first = s->top_field_first; | 812 | frame->top_field_first = s->top_field_first; |
| 699 | } | 813 | } |
| 700 | 814 | ||
| 701 | return pkt->size; | 815 | return pkt->size; |
| @@ -705,9 +819,7 @@ static int v4l2_read_close(AVFormatContext *s1) · 3 unmodified lines | |||
| 705 | { | 819 | { |
| 706 | struct video_data *s = s1->priv_data; | 820 | struct video_data *s = s1->priv_data; |
| 707 | 821 | ||
| 708 | if (s->io_method == io_mmap) { | 822 | mmap_close(s); |
| 709 | mmap_close(s); | ||
| 710 | } | ||
| 711 | 823 | ||
| 712 | v4l2_close(s->fd); | 824 | v4l2_close(s->fd); |
| 713 | return 0; | 825 | return 0; |
| @@ -717,11 +829,15 @@ static int v4l2_read_close(AVFormatContext *s1) · 3 unmodified lines | |||
| 717 | #define DEC AV_OPT_FLAG_DECODING_PARAM | 829 | #define DEC AV_OPT_FLAG_DECODING_PARAM |
| 718 | 830 | ||
| 719 | static const AVOption options[] = { | 831 | static const AVOption options[] = { |
| 720 | { "standard", "", OFFSET(standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM }, | 832 | { "standard", "TV standard, used only by analog frame grabber", OFFSET(standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC }, |
| 721 | { "channel", "", OFFSET(channel), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, | 833 | { "channel", "TV channel, used only by frame grabber", OFFSET(channel), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, DEC }, |
| 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 }, | 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 }, |
| 723 | { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, | 835 | { "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 }, | 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 | { NULL }, | 841 | { NULL }, |
| 726 | }; | 842 | }; |
| 727 | 843 | ||
| @@ -26,6 +26,7 @@ OBJS-$(CONFIG_AC3_MUXER) += rawenc.o · 25 unmodified lines | |||
| 26 | OBJS-$(CONFIG_ACT_DEMUXER) += act.o | 26 | OBJS-$(CONFIG_ACT_DEMUXER) += act.o |
| 27 | OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o | 27 | OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o |
| 28 | OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o | 28 | OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o |
| 29 | OBJS-$(CONFIG_ADX_MUXER) += rawenc.o | ||
| 29 | OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o | 30 | OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o |
| 30 | OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o | 31 | OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o |
| 31 | OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o isom.o | 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 | .read_packet = adx_read_packet, | 109 | .read_packet = adx_read_packet, |
| 110 | .extensions = "adx", | 110 | .extensions = "adx", |
| 111 | .value = CODEC_ID_ADPCM_ADX, | 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 | REGISTER_DEMUXER (ACT, act); | 54 | REGISTER_DEMUXER (ACT, act); |
| 55 | REGISTER_DEMUXER (ADF, adf); | 55 | REGISTER_DEMUXER (ADF, adf); |
| 56 | REGISTER_MUXER (ADTS, adts); | 56 | REGISTER_MUXER (ADTS, adts); |
| 57 | REGISTER_DEMUXER (ADX, adx); | 57 | REGISTER_MUXDEMUX (ADX, adx); |
| 58 | REGISTER_DEMUXER (AEA, aea); | 58 | REGISTER_DEMUXER (AEA, aea); |
| 59 | REGISTER_MUXDEMUX (AIFF, aiff); | 59 | REGISTER_MUXDEMUX (AIFF, aiff); |
| 60 | REGISTER_MUXDEMUX (AMR, amr); | 60 | REGISTER_MUXDEMUX (AMR, amr); |
| @@ -574,6 +574,10 @@ static void fill_buffer(AVIOContext *s) · 573 unmodified lines | |||
| 574 | int len= s->buffer_size - (dst - s->buffer); | 574 | int len= s->buffer_size - (dst - s->buffer); |
| 575 | int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE; | 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 | /* no need to do anything if EOF already reached */ | 581 | /* no need to do anything if EOF already reached */ |
| 578 | if (s->eof_reached) | 582 | if (s->eof_reached) |
| 579 | return; | 583 | return; |
| @@ -112,10 +112,12 @@ static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap) · 111 unmodified lines | |||
| 112 | 112 | ||
| 113 | avio_skip(pb, 4); | 113 | avio_skip(pb, 4); |
| 114 | audio_subsegments = avio_rl16(pb); | 114 | audio_subsegments = avio_rl16(pb); |
| 115 | if(!audio_subsegments){ | 115 | |
| 116 | av_log(s, AV_LOG_ERROR, "audio_subsegments is 0\n"); | 116 | if (audio_subsegments == 0) { |
| 117 | return AVERROR(EINVAL); | 117 | av_log_ask_for_sample(s, "MTV files without audio are not supported\n"); |
| 118 | return AVERROR_INVALIDDATA; | ||
| 118 | } | 119 | } |
| 120 | |||
| 119 | mtv->full_segment_size = | 121 | mtv->full_segment_size = |
| 120 | audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) + | 122 | audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) + |
| 121 | mtv->img_segment_size; | 123 | mtv->img_segment_size; |
| @@ -45,6 +45,18 @@ AVOutputFormat ff_ac3_muxer = { · 44 unmodified lines | |||
| 45 | }; | 45 | }; |
| 46 | #endif | 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 | #if CONFIG_DIRAC_MUXER | 60 | #if CONFIG_DIRAC_MUXER |
| 49 | AVOutputFormat ff_dirac_muxer = { | 61 | AVOutputFormat ff_dirac_muxer = { |
| 50 | .name = "dirac", | 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 | int64_t dc_mask, eq_mask, both_masks; | 2470 | int64_t dc_mask, eq_mask, both_masks; |
| 2471 | int64_t sums[10*8*2]; | 2471 | int64_t sums[10*8*2]; |
| 2472 | src+= step*3; // src points to begin of the 8x8 Block | 2472 | src+= step*3; // src points to begin of the 8x8 Block |
| 2473 | //START_TIMER | 2473 | //{ START_TIMER |
| 2474 | __asm__ volatile( | 2474 | __asm__ volatile( |
| 2475 | "movq %0, %%mm7 \n\t" | 2475 | "movq %0, %%mm7 \n\t" |
| 2476 | "movq %1, %%mm6 \n\t" | 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 | STOP_TIMER("step16") | 2995 | STOP_TIMER("step16") |
| 2996 | }else{ | 2996 | }else{ |
| 2997 | STOP_TIMER("stepX") | 2997 | STOP_TIMER("stepX") |
| 2998 | }*/ | 2998 | } |
| 2999 | } */ | ||
| 2999 | } | 3000 | } |
| 3000 | #endif //HAVE_MMX | 3001 | #endif //HAVE_MMX |
| 3001 | 3002 | ||
| @@ -19,7 +19,8 @@ OBJS-$(HAVE_MMX) += x86/rgb2rgb.o \ · 18 unmodified lines | |||
| 19 | x86/swscale_mmx.o \ | 19 | x86/swscale_mmx.o \ |
| 20 | x86/yuv2rgb_mmx.o | 20 | x86/yuv2rgb_mmx.o |
| 21 | OBJS-$(HAVE_VIS) += sparc/yuv2rgb_vis.o | 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 | $(SUBDIR)x86/swscale_mmx.o: CFLAGS += $(NOREDZONE_FLAGS) | 25 | $(SUBDIR)x86/swscale_mmx.o: CFLAGS += $(NOREDZONE_FLAGS) |
| 25 | 26 | ||
| @@ -21,8 +21,8 @@ · 20 unmodified lines | |||
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | #ifndef PPC_YUV2RGB_ALTIVEC_H | 24 | #ifndef SWSCALE_PPC_YUV2RGB_ALTIVEC_H |
| 25 | #define PPC_YUV2RGB_ALTIVEC_H 1 | 25 | #define SWSCALE_PPC_YUV2RGB_ALTIVEC_H |
| 26 | 26 | ||
| 27 | #define YUV2PACKEDX_HEADER(suffix) \ | 27 | #define YUV2PACKEDX_HEADER(suffix) \ |
| 28 | void ff_yuv2 ## suffix ## _X_altivec(SwsContext *c, const int16_t *lumFilter, \ | 28 | void ff_yuv2 ## suffix ## _X_altivec(SwsContext *c, const int16_t *lumFilter, \ |
| @@ -39,4 +39,4 @@ YUV2PACKEDX_HEADER(rgba); · 10 unmodified lines | |||
| 39 | YUV2PACKEDX_HEADER(rgb24); | 39 | YUV2PACKEDX_HEADER(rgb24); |
| 40 | YUV2PACKEDX_HEADER(bgr24); | 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 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 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 | #include <inttypes.h> | 21 | #include <inttypes.h> |
| 55 | #include <string.h> | 22 | #include <string.h> |
| 56 | #include <math.h> | 23 | #include <math.h> |
| @@ -2371,36 +2338,6 @@ find_c_packed_planar_out_funcs(SwsContext *c, · 2314 unmodified lines | |||
| 2371 | } else { | 2338 | } else { |
| 2372 | YUV_PACKED: | 2339 | YUV_PACKED: |
| 2373 | switch (dstFormat) { | 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 | case PIX_FMT_RGB48LE: | 2341 | case PIX_FMT_RGB48LE: |
| 2405 | *yuv2packed1 = yuv2rgb48le_1_c; | 2342 | *yuv2packed1 = yuv2rgb48le_1_c; |
| 2406 | *yuv2packed2 = yuv2rgb48le_2_c; | 2343 | *yuv2packed2 = yuv2rgb48le_2_c; |
| @@ -2517,6 +2454,38 @@ find_c_packed_planar_out_funcs(SwsContext *c, · 110 unmodified lines | |||
| 2517 | break; | 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 | #define DEBUG_SWSCALE_BUFFERS 0 | 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 | ;* Copyright (c) 2011 Ronald S. Bultje <rsbultje@gmail.com> | 3 | ;* Copyright (c) 2011 Ronald S. Bultje <rsbultje@gmail.com> |
| 4 | ;* Kieran Kunhya <kieran@kunhya.com> | ||
| 5 | ;* | 4 | ;* |
| 6 | ;* This file is part of Libav. | 5 | ;* This file is part of Libav. |
| 7 | ;* | 6 | ;* |
| @@ -29,17 +28,6 @@ max_19bit_int: times 4 dd 0x7ffff · 21 unmodified lines | |||
| 29 | max_19bit_flt: times 4 dd 524287.0 | 28 | max_19bit_flt: times 4 dd 524287.0 |
| 30 | minshort: times 8 dw 0x8000 | 29 | minshort: times 8 dw 0x8000 |
| 31 | unicoeff: times 4 dd 0x20000000 | 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 | SECTION .text | 32 | SECTION .text |
| 45 | 33 | ||
| @@ -441,371 +429,3 @@ INIT_XMM · 395 unmodified lines | |||
| 441 | SCALE_FUNCS2 sse2, 6, 7, 8 | 429 | SCALE_FUNCS2 sse2, 6, 7, 8 |
| 442 | SCALE_FUNCS2 ssse3, 6, 6, 8 | 430 | SCALE_FUNCS2 ssse3, 6, 6, 8 |
| 443 | SCALE_FUNCS2 sse4, 6, 6, 8 | 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 | do_audio_decoding | 369 | do_audio_decoding |
| 370 | fi | 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 | if [ -n "$do_adpcm_ima_wav" ] ; then | 377 | if [ -n "$do_adpcm_ima_wav" ] ; then |
| 373 | do_audio_encoding adpcm_ima.wav "-acodec adpcm_ima_wav" | 378 | do_audio_encoding adpcm_ima.wav "-acodec adpcm_ima_wav" |
| 374 | do_audio_decoding | 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 | ||