return 0;
}
+int opt_report(const char *opt)
+{
+ char filename[64];
+ time_t now;
+ struct tm *tm;
+
+ if (report_file) /* already opened */
+ return 0;
+ time(&now);
+ tm = localtime(&now);
+ snprintf(filename, sizeof(filename), "%s-%04d%02d%02d-%02d%02d%02d.log",
+ program_name,
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ report_file = fopen(filename, "w");
+ if (!report_file) {
+ av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
+ filename, strerror(errno));
+ return AVERROR(errno);
+ }
+ av_log_set_callback(log_callback_report);
+ av_log(NULL, AV_LOG_INFO,
+ "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
+ "Report written to \"%s\"\n",
+ program_name,
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ filename);
+ av_log_set_level(FFMAX(av_log_get_level(), AV_LOG_VERBOSE));
+ return 0;
+}
+
+int opt_max_alloc(const char *opt, const char *arg)
+{
+ char *tail;
+ size_t max;
+
+ max = strtol(arg, &tail, 10);
+ if (*tail) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
+ exit_program(1);
+ }
+ av_max_alloc(max);
+ return 0;
+}
+
+int opt_cpuflags(const char *opt, const char *arg)
+{
+ static const AVOption cpuflags_opts[] = {
+ { "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { 0 }, INT64_MIN, INT64_MAX, .unit = "flags" },
+ { "altivec" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ALTIVEC }, .unit = "flags" },
+ { "mmx" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_MMX }, .unit = "flags" },
+ { "mmx2" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_MMX2 }, .unit = "flags" },
+ { "sse" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE }, .unit = "flags" },
+ { "sse2" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE2 }, .unit = "flags" },
+ { "sse2slow", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE2SLOW }, .unit = "flags" },
+ { "sse3" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE3 }, .unit = "flags" },
+ { "sse3slow", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE3SLOW }, .unit = "flags" },
+ { "ssse3" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSSE3 }, .unit = "flags" },
+ { "atom" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ATOM }, .unit = "flags" },
+ { "sse4.1" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE4 }, .unit = "flags" },
+ { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE42 }, .unit = "flags" },
+ { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_AVX }, .unit = "flags" },
+ { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_XOP }, .unit = "flags" },
+ { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_FMA4 }, .unit = "flags" },
+ { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_3DNOW }, .unit = "flags" },
+ { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_3DNOWEXT }, .unit = "flags" },
++
++ { "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV5TE }, .unit = "flags" },
++ { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV6 }, .unit = "flags" },
++ { "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" },
++ { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_VFP }, .unit = "flags" },
++ { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_VFPV3 }, .unit = "flags" },
++ { "neon", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_NEON }, .unit = "flags" },
++
+ { NULL },
+ };
+ static const AVClass class = {
+ .class_name = "cpuflags",
+ .item_name = av_default_item_name,
+ .option = cpuflags_opts,
+ .version = LIBAVUTIL_VERSION_INT,
+ };
+ int flags = av_get_cpu_flags();
+ int ret;
+ const AVClass *pclass = &class;
+
+ if ((ret = av_opt_eval_flags(&pclass, &cpuflags_opts[0], arg, &flags)) < 0)
+ return ret;
+
+ av_force_cpu_flags(flags);
+ return 0;
+}
+
+int opt_codec_debug(const char *opt, const char *arg)
+{
+ av_log_set_level(AV_LOG_DEBUG);
+ return opt_default(opt, arg);
+}
+
int opt_timelimit(const char *opt, const char *arg)
{
#if HAVE_SETRLIMIT
/* SDL allocates a buffer smaller than requested if the video
* overlay hardware is unable to support the requested size. */
fprintf(stderr, "Error: the video system does not support an image\n"
- "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
+ "size of %dx%d pixels. Try using -vf \"scale=w:h\"\n"
"to reduce the image size.\n", vp->width, vp->height );
- do_exit();
+ do_exit(is);
}
SDL_LockMutex(is->pictq_mutex);
*/
#include <stdint.h>
+
+ #include "libavutil/arm/cpu.h"
#include "libavcodec/vp8dsp.h"
-void ff_vp8_luma_dc_wht_neon(DCTELEM block[4][4][16], DCTELEM dc[16]);
-void ff_vp8_luma_dc_wht_dc_neon(DCTELEM block[4][4][16], DCTELEM dc[16]);
+void ff_vp8_luma_dc_wht_dc_armv6(DCTELEM block[4][4][16], DCTELEM dc[16]);
-void ff_vp8_idct_add_neon(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add_neon(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add4y_neon(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add4uv_neon(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride);
+#define idct_funcs(opt) \
+void ff_vp8_luma_dc_wht_ ## opt(DCTELEM block[4][4][16], DCTELEM dc[16]); \
+void ff_vp8_idct_add_ ## opt(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride); \
+void ff_vp8_idct_dc_add_ ## opt(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride); \
+void ff_vp8_idct_dc_add4y_ ## opt(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride); \
+void ff_vp8_idct_dc_add4uv_ ## opt(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride)
+
+idct_funcs(neon);
+idct_funcs(armv6);
void ff_vp8_v_loop_filter16_neon(uint8_t *dst, ptrdiff_t stride,
int flim_E, int flim_I, int hev_thresh);
VP8_MC(bilin4_v);
VP8_MC(bilin4_hv);
+#define VP8_V6_MC(n) \
+void ff_put_vp8_##n##_armv6(uint8_t *dst, int dststride, uint8_t *src, \
+ int srcstride, int w, int h, int mxy)
+
+VP8_V6_MC(epel_v6);
+VP8_V6_MC(epel_h6);
+VP8_V6_MC(epel_v4);
+VP8_V6_MC(epel_h4);
+VP8_V6_MC(bilin_v);
+VP8_V6_MC(bilin_h);
+
+#define VP8_EPEL_HV(SIZE, TAPNUMX, TAPNUMY, NAME, HNAME, VNAME, MAXHEIGHT) \
+static void ff_put_vp8_##NAME##SIZE##_##HNAME##VNAME##_armv6( \
+ uint8_t *dst, int dststride, uint8_t *src, \
+ int srcstride, int h, int mx, int my) \
+{ \
+ DECLARE_ALIGNED(4, uint8_t, tmp)[SIZE * (MAXHEIGHT + TAPNUMY - 1)]; \
+ uint8_t *tmpptr = tmp + SIZE * (TAPNUMY / 2 - 1); \
+ src -= srcstride * (TAPNUMY / 2 - 1); \
+ ff_put_vp8_ ## NAME ## _ ## HNAME ## _armv6(tmp, SIZE, src, srcstride, \
+ SIZE, h + TAPNUMY - 1, mx); \
+ ff_put_vp8_ ## NAME ## _ ## VNAME ## _armv6(dst, dststride, tmpptr, SIZE, \
+ SIZE, h, my); \
+}
+
+VP8_EPEL_HV(16, 6, 6, epel, h6, v6, 16);
+VP8_EPEL_HV(16, 2, 2, bilin, h, v, 16);
+VP8_EPEL_HV(8, 6, 6, epel, h6, v6, 16);
+VP8_EPEL_HV(8, 4, 6, epel, h4, v6, 16);
+VP8_EPEL_HV(8, 6, 4, epel, h6, v4, 16);
+VP8_EPEL_HV(8, 4, 4, epel, h4, v4, 16);
+VP8_EPEL_HV(8, 2, 2, bilin, h, v, 16);
+VP8_EPEL_HV(4, 6, 6, epel, h6, v6, 8);
+VP8_EPEL_HV(4, 4, 6, epel, h4, v6, 8);
+VP8_EPEL_HV(4, 6, 4, epel, h6, v4, 8);
+VP8_EPEL_HV(4, 4, 4, epel, h4, v4, 8);
+VP8_EPEL_HV(4, 2, 2, bilin, h, v, 8);
+
+extern void put_vp8_epel4_v6_c(uint8_t *dst, int d, uint8_t *src, int s, int h, int mx, int my);
+#undef printf
+#define VP8_EPEL_H_OR_V(SIZE, NAME, HV) \
+static void ff_put_vp8_##NAME##SIZE##_##HV##_armv6( \
+ uint8_t *dst, int dststride, uint8_t *src, \
+ int srcstride, int h, int mx, int my) \
+{ \
+ ff_put_vp8_## NAME ## _ ## HV ## _armv6(dst, dststride, src, srcstride, \
+ SIZE, h, mx | my); \
+}
+
+VP8_EPEL_H_OR_V(4, epel, h6);
+VP8_EPEL_H_OR_V(4, epel, h4);
+VP8_EPEL_H_OR_V(4, epel, v6);
+VP8_EPEL_H_OR_V(4, epel, v4);
+VP8_EPEL_H_OR_V(4, bilin, v);
+VP8_EPEL_H_OR_V(4, bilin, h);
+VP8_EPEL_H_OR_V(8, epel, h6);
+VP8_EPEL_H_OR_V(8, epel, h4);
+VP8_EPEL_H_OR_V(8, epel, v6);
+VP8_EPEL_H_OR_V(8, epel, v4);
+VP8_EPEL_H_OR_V(8, bilin, v);
+VP8_EPEL_H_OR_V(8, bilin, h);
+VP8_EPEL_H_OR_V(16, epel, h6);
+VP8_EPEL_H_OR_V(16, epel, v6);
+VP8_EPEL_H_OR_V(16, bilin, v);
+VP8_EPEL_H_OR_V(16, bilin, h);
+
av_cold void ff_vp8dsp_init_arm(VP8DSPContext *dsp)
{
- if (HAVE_NEON) {
+#define set_func_ptrs(opt) \
+ dsp->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_##opt; \
+ dsp->vp8_luma_dc_wht_dc = ff_vp8_luma_dc_wht_dc_armv6; \
+ \
+ dsp->vp8_idct_add = ff_vp8_idct_add_##opt; \
+ dsp->vp8_idct_dc_add = ff_vp8_idct_dc_add_##opt; \
+ dsp->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_##opt; \
+ dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_##opt; \
+ \
+ dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_##opt; \
+ dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_##opt; \
+ dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_##opt; \
+ dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_##opt; \
+ \
+ dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_##opt; \
+ dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_##opt; \
+ dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_##opt; \
+ dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_##opt; \
+ \
+ dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter16_simple_##opt; \
+ dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter16_simple_##opt; \
+ \
+ dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_##opt; \
+ dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_##opt; \
+ dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_##opt; \
+ dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_##opt; \
+ \
+ dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_##opt; \
+ dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_##opt; \
+ dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_##opt; \
+ dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_##opt; \
+ dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_##opt; \
+ dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_##opt; \
+ dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_##opt; \
+ dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_##opt; \
+ dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_##opt; \
+ \
+ dsp->put_vp8_epel_pixels_tab[2][0][0] = ff_put_vp8_pixels4_armv6; \
+ dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_##opt; \
+ dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_##opt; \
+ dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_##opt; \
+ dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_##opt; \
+ dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_##opt; \
+ dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_##opt; \
+ dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_##opt; \
+ dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_##opt; \
+ \
+ dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilin16_h_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilin16_v_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilin16_hv_##opt; \
+ \
+ dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilin8_h_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilin8_h_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilin8_v_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilin8_hv_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilin8_hv_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilin8_v_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilin8_hv_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilin8_hv_##opt; \
+ \
+ dsp->put_vp8_bilinear_pixels_tab[2][0][0] = ff_put_vp8_pixels4_armv6; \
+ dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilin4_h_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilin4_h_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilin4_v_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilin4_hv_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilin4_hv_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilin4_v_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilin4_hv_##opt; \
+ dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilin4_hv_##opt
- dsp->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_neon;
- dsp->vp8_luma_dc_wht_dc = ff_vp8_luma_dc_wht_dc_neon;
-
- dsp->vp8_idct_add = ff_vp8_idct_add_neon;
- dsp->vp8_idct_dc_add = ff_vp8_idct_dc_add_neon;
- dsp->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_neon;
- dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_neon;
-
- dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_neon;
- dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_neon;
- dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_neon;
- dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_neon;
-
- dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_neon;
- dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_neon;
- dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_neon;
- dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_neon;
-
- dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter16_simple_neon;
- dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter16_simple_neon;
-
- dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_neon;
- dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_neon;
- dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_neon;
- dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_neon;
-
- dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_neon;
- dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_neon;
- dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_neon;
- dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_neon;
- dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_neon;
- dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_neon;
- dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_neon;
- dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_neon;
- dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_neon;
-
- dsp->put_vp8_epel_pixels_tab[2][0][0] = ff_put_vp8_pixels4_neon;
- dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_neon;
- dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_neon;
- dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_neon;
- dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_neon;
- dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_neon;
- dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_neon;
- dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_neon;
- dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_neon;
-
- dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_neon;
- dsp->put_vp8_bilinear_pixels_tab[0][0][1] = ff_put_vp8_bilin16_h_neon;
- dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilin16_h_neon;
- dsp->put_vp8_bilinear_pixels_tab[0][1][0] = ff_put_vp8_bilin16_v_neon;
- dsp->put_vp8_bilinear_pixels_tab[0][1][1] = ff_put_vp8_bilin16_hv_neon;
- dsp->put_vp8_bilinear_pixels_tab[0][1][2] = ff_put_vp8_bilin16_hv_neon;
- dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilin16_v_neon;
- dsp->put_vp8_bilinear_pixels_tab[0][2][1] = ff_put_vp8_bilin16_hv_neon;
- dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilin16_hv_neon;
-
- dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_neon;
- dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilin8_h_neon;
- dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilin8_h_neon;
- dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilin8_v_neon;
- dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilin8_hv_neon;
- dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilin8_hv_neon;
- dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilin8_v_neon;
- dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilin8_hv_neon;
- dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilin8_hv_neon;
-
- dsp->put_vp8_bilinear_pixels_tab[2][0][0] = ff_put_vp8_pixels4_neon;
- dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilin4_h_neon;
- dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilin4_h_neon;
- dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilin4_v_neon;
- dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilin4_hv_neon;
- dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilin4_hv_neon;
- dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilin4_v_neon;
- dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilin4_hv_neon;
- dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilin4_hv_neon;
+ int cpu_flags = av_get_cpu_flags();
+
+ if (have_neon(cpu_flags)) {
+ set_func_ptrs(neon);
+ } else if (HAVE_ARMV6) {
+ set_func_ptrs(armv6);
}
}
--- /dev/null
- ctx->dec_params.cp_reduce = avctx->lowres;
+/*
+ * JPEG 2000 decoding support via OpenJPEG
+ * Copyright (c) 2009 Jaikrishnan Menon <realityman@gmx.net>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+* @file
+* JPEG 2000 decoder using libopenjpeg
+*/
+
+#include "libavutil/imgutils.h"
+#include "libavutil/pixfmt.h"
+#include "avcodec.h"
+#include "libavutil/intreadwrite.h"
+#include "thread.h"
+#define OPJ_STATIC
+#include <openjpeg.h>
+
+#define JP2_SIG_TYPE 0x6A502020
+#define JP2_SIG_VALUE 0x0D0A870A
+
+typedef struct {
+ opj_dparameters_t dec_params;
+ AVFrame image;
+} LibOpenJPEGContext;
+
+static enum PixelFormat check_image_attributes(AVCodecContext *avctx, opj_image_t *image)
+{
+ opj_image_comp_t c0 = image->comps[0];
+ opj_image_comp_t c1 = image->comps[1];
+ opj_image_comp_t c2 = image->comps[2];
+ int compRatio = 0;
+ compRatio |= c0.dx << 15 | c0.dy << 12;
+ compRatio |= c1.dx << 9 | c1.dy << 6;
+ compRatio |= c2.dx << 3 | c2.dy;
+
+ if (image->numcomps == 4) {
+ if (c0.prec == 8) {
+ if (compRatio == 0112222 &&
+ image->comps[3].dx == 1 && image->comps[3].dy == 1) {
+ return PIX_FMT_YUVA420P;
+ } else {
+ return PIX_FMT_RGBA;
+ }
+ } else {
+ return PIX_FMT_RGBA64;
+ }
+ }
+
+ switch (compRatio) {
+ case 0111111: goto libopenjpeg_yuv444_rgb;
+ case 0111212: return PIX_FMT_YUV440P;
+ case 0112121: goto libopenjpeg_yuv422;
+ case 0112222: goto libopenjpeg_yuv420;
+ default: goto libopenjpeg_rgb;
+ }
+
+libopenjpeg_yuv420:
+ switch (c0.prec) {
+ case 8: return PIX_FMT_YUV420P;
+ case 9: return PIX_FMT_YUV420P9;
+ case 10: return PIX_FMT_YUV420P10;
+ case 16: return PIX_FMT_YUV420P16;
+ }
+
+libopenjpeg_yuv422:
+ switch (c0.prec) {
+ case 8: return PIX_FMT_YUV422P;
+ case 9: return PIX_FMT_YUV422P9;
+ case 10: return PIX_FMT_YUV422P10;
+ case 16: return PIX_FMT_YUV422P16;
+ }
+
+libopenjpeg_yuv444_rgb:
+ switch (c0.prec) {
+ case 8: return PIX_FMT_RGB24;
+ case 9: return PIX_FMT_YUV444P9;
+ case 10: return PIX_FMT_YUV444P10;
+ case 16: return PIX_FMT_YUV444P16;
+ }
+
+libopenjpeg_rgb:
+ switch (c0.prec) {
+ case 8: return PIX_FMT_RGB24;
+ default: return PIX_FMT_RGB48;
+ }
+
+ return PIX_FMT_RGB24;
+}
+
+static inline int libopenjpeg_ispacked(enum PixelFormat pix_fmt) {
+ int i, component_plane;
+
+ if (pix_fmt == PIX_FMT_GRAY16)
+ return 0;
+
+ component_plane = av_pix_fmt_descriptors[pix_fmt].comp[0].plane;
+ for(i = 1; i < av_pix_fmt_descriptors[pix_fmt].nb_components; i++) {
+ if (component_plane != av_pix_fmt_descriptors[pix_fmt].comp[i].plane)
+ return 0;
+ }
+ return 1;
+}
+
+static inline void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *image) {
+ uint8_t *img_ptr;
+ int index, x, y, c;
+ for(y = 0; y < picture->height; y++) {
+ index = y*picture->width;
+ img_ptr = picture->data[0] + y*picture->linesize[0];
+ for(x = 0; x < picture->width; x++, index++) {
+ for(c = 0; c < image->numcomps; c++) {
+ *img_ptr++ = image->comps[c].data[index];
+ }
+ }
+ }
+}
+
+static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image) {
+ uint16_t *img_ptr;
+ int index, x, y, c;
+ int adjust[4];
+ for (x = 0; x < image->numcomps; x++) {
+ adjust[x] = FFMAX(FFMIN(16 - image->comps[x].prec, 8), 0);
+ }
+ for (y = 0; y < picture->height; y++) {
+ index = y*picture->width;
+ img_ptr = (uint16_t*) (picture->data[0] + y*picture->linesize[0]);
+ for (x = 0; x < picture->width; x++, index++) {
+ for (c = 0; c < image->numcomps; c++) {
+ *img_ptr++ = image->comps[c].data[index] << adjust[c];
+ }
+ }
+ }
+}
+
+static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) {
+ int *comp_data;
+ uint8_t *img_ptr;
+ int index, x, y;
+
+ for(index = 0; index < image->numcomps; index++) {
+ comp_data = image->comps[index].data;
+ for(y = 0; y < image->comps[index].h; y++) {
+ img_ptr = picture->data[index] + y * picture->linesize[index];
+ for(x = 0; x < image->comps[index].w; x++) {
+ *img_ptr = (uint8_t) *comp_data;
+ img_ptr++;
+ comp_data++;
+ }
+ }
+ }
+}
+
+static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) {
+ int *comp_data;
+ uint16_t *img_ptr;
+ int index, x, y;
+ for(index = 0; index < image->numcomps; index++) {
+ comp_data = image->comps[index].data;
+ for(y = 0; y < image->comps[index].h; y++) {
+ img_ptr = (uint16_t*) (picture->data[index] + y * picture->linesize[index]);
+ for(x = 0; x < image->comps[index].w; x++) {
+ *img_ptr = *comp_data;
+ img_ptr++;
+ comp_data++;
+ }
+ }
+ }
+}
+
+static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx)
+{
+ LibOpenJPEGContext *ctx = avctx->priv_data;
+
+ opj_set_default_decoder_parameters(&ctx->dec_params);
+ avcodec_get_frame_defaults(&ctx->image);
+ avctx->coded_frame = &ctx->image;
+ return 0;
+}
+
+static av_cold int libopenjpeg_decode_init_thread_copy(AVCodecContext *avctx)
+{
+ LibOpenJPEGContext *ctx = avctx->priv_data;
+
+ avctx->coded_frame = &ctx->image;
+ return 0;
+}
+
+static int libopenjpeg_decode_frame(AVCodecContext *avctx,
+ void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ LibOpenJPEGContext *ctx = avctx->priv_data;
+ AVFrame *picture = &ctx->image, *output = data;
+ opj_dinfo_t *dec;
+ opj_cio_t *stream;
+ opj_image_t *image;
+ int width, height, ret = -1;
+ int pixel_size = 0;
+ int ispacked = 0;
+
+ *data_size = 0;
+
+ // Check if input is a raw jpeg2k codestream or in jp2 wrapping
+ if((AV_RB32(buf) == 12) &&
+ (AV_RB32(buf + 4) == JP2_SIG_TYPE) &&
+ (AV_RB32(buf + 8) == JP2_SIG_VALUE)) {
+ dec = opj_create_decompress(CODEC_JP2);
+ } else {
+ // If the AVPacket contains a jp2c box, then skip to
+ // the starting byte of the codestream.
+ if (AV_RB32(buf + 4) == AV_RB32("jp2c"))
+ buf += 8;
+ dec = opj_create_decompress(CODEC_J2K);
+ }
+
+ if(!dec) {
+ av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n");
+ return -1;
+ }
+ opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
+
+ ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
+ // Tie decoder with decoding parameters
+ opj_setup_decoder(dec, &ctx->dec_params);
+ stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
+ if(!stream) {
+ av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
+ opj_destroy_decompress(dec);
+ return -1;
+ }
+
+ // Decode the header only
+ image = opj_decode_with_info(dec, stream, NULL);
+ opj_cio_close(stream);
+ if(!image) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
+ opj_destroy_decompress(dec);
+ return -1;
+ }
+ width = image->x1 - image->x0;
+ height = image->y1 - image->y0;
+ if(av_image_check_size(width, height, 0, avctx) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height);
+ goto done;
+ }
+ avcodec_set_dimensions(avctx, width, height);
+
+ switch (image->numcomps) {
+ case 1: avctx->pix_fmt = (image->comps[0].prec == 8) ? PIX_FMT_GRAY8 : PIX_FMT_GRAY16;
+ break;
+ case 2: avctx->pix_fmt = PIX_FMT_GRAY8A;
+ break;
+ case 3:
+ case 4: avctx->pix_fmt = check_image_attributes(avctx, image);
+ break;
+ default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps);
+ goto done;
+ }
+
+ if(picture->data[0])
+ ff_thread_release_buffer(avctx, picture);
+
+ if(ff_thread_get_buffer(avctx, picture) < 0){
+ av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n");
+ goto done;
+ }
+
+ ctx->dec_params.cp_limit_decoding = NO_LIMITATION;
- .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
+ // Tie decoder with decoding parameters
+ opj_setup_decoder(dec, &ctx->dec_params);
+ stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
+ if(!stream) {
+ av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
+ goto done;
+ }
+
+ opj_image_destroy(image);
+ // Decode the codestream
+ image = opj_decode_with_info(dec, stream, NULL);
+ opj_cio_close(stream);
+ if(!image) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
+ goto done;
+ }
+
+ pixel_size = av_pix_fmt_descriptors[avctx->pix_fmt].comp[0].step_minus1 + 1;
+ ispacked = libopenjpeg_ispacked(avctx->pix_fmt);
+
+ switch (pixel_size) {
+ case 1:
+ if (ispacked) {
+ libopenjpeg_copy_to_packed8(picture, image);
+ } else {
+ libopenjpeg_copyto8(picture, image);
+ }
+ break;
+ case 2:
+ if (ispacked) {
+ libopenjpeg_copy_to_packed8(picture, image);
+ } else {
+ libopenjpeg_copyto16(picture, image);
+ }
+ break;
+ case 3:
+ case 4:
+ if (ispacked) {
+ libopenjpeg_copy_to_packed8(picture, image);
+ }
+ break;
+ case 6:
+ case 8:
+ if (ispacked) {
+ libopenjpeg_copy_to_packed16(picture, image);
+ }
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "unsupported pixel size %d\n", pixel_size);
+ goto done;
+ }
+
+ *output = ctx->image;
+ *data_size = sizeof(AVPicture);
+ ret = buf_size;
+
+done:
+ opj_image_destroy(image);
+ opj_destroy_decompress(dec);
+ return ret;
+}
+
+static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx)
+{
+ LibOpenJPEGContext *ctx = avctx->priv_data;
+
+ if(ctx->image.data[0])
+ ff_thread_release_buffer(avctx, &ctx->image);
+ return 0 ;
+}
+
+
+AVCodec ff_libopenjpeg_decoder = {
+ .name = "libopenjpeg",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_JPEG2000,
+ .priv_data_size = sizeof(LibOpenJPEGContext),
+ .init = libopenjpeg_decode_init,
+ .close = libopenjpeg_decode_close,
+ .decode = libopenjpeg_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+ .max_lowres = 5,
++ .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy),
+};
break;
}
+ if(s->codec_id == CODEC_ID_IFF_ILBM || s->codec_id == CODEC_ID_IFF_BYTERUN1){
+ w_align= FFMAX(w_align, 8);
+ }
+
*width = FFALIGN(*width , w_align);
*height= FFALIGN(*height, h_align);
- if(s->codec_id == CODEC_ID_H264 || s->lowres)
+ if (s->codec_id == CODEC_ID_H264)
*height+=2; // some of the optimized chroma MC reads one line too much
- // which is also done in mpeg decoders with lowres > 0
for (i = 0; i < 4; i++)
linesize_align[i] = STRIDE_ALIGN;
if (!HAVE_THREADS && !(codec->capabilities & CODEC_CAP_AUTO_THREADS))
avctx->thread_count = 1;
+ if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) {
+ av_log(avctx, AV_LOG_ERROR, "The maximum value for lowres supported by the decoder is %d\n",
+ avctx->codec->max_lowres);
+ ret = AVERROR(EINVAL);
+ goto free_and_end;
+ }
++
if (av_codec_is_encoder(avctx->codec)) {
int i;
if (avctx->codec->sample_fmts) {
unsigned int stts_sample = 0;
unsigned int sample_size;
unsigned int distance = 0;
- int key_off = sc->keyframe_count && sc->keyframes[0] == 1;
- int key_off = (sc->keyframes && sc->keyframes[0] > 0) || (sc->stps_data && sc->stps_data[0] > 0);
++ int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_data && sc->stps_data[0] > 0);
current_dts -= sc->dts_shift;
*
* @warning this function is not thread safe.
*/
-void av_set_cpu_flags_mask(int mask);
+attribute_deprecated void av_set_cpu_flags_mask(int mask);
/* The following CPU-specific functions shall not be called directly. */
+ int ff_get_cpu_flags_arm(void);
int ff_get_cpu_flags_ppc(void);
int ff_get_cpu_flags_x86(void);