[PATCH] Integrate x265 into MEncoder

chen <[email protected]>
Newsgroups gmane.comp.video.mplayer.devel
Message-ID <[email protected]>
Index: Makefile===================================================================--- Makefile	(revision 37877)+++ Makefile	(working copy)@@ -628,6 +628,7 @@ SRCS_MENCODER-$(TWOLAME)          += libmpcodecs/ae_twolame.c SRCS_MENCODER-$(WIN32DLL)         += libmpcodecs/ve_vfw.c SRCS_MENCODER-$(X264)             += libmpcodecs/ve_x264.c+SRCS_MENCODER-$(X265)             += libmpcodecs/ve_x265.c SRCS_MENCODER-$(XVID4)            += libmpcodecs/ve_xvid4.c  SRCS_MENCODER = mencoder.c                      \Index: cfg-mencoder.h===================================================================--- cfg-mencoder.h	(revision 37877)+++ cfg-mencoder.h	(working copy)@@ -29,6 +29,7 @@ #include "libmpcodecs/ae_twolame.h" #include "libmpcodecs/ve.h" #include "libmpcodecs/ve_x264.h"+#include "libmpcodecs/ve_x265.h" #include "libmpdemux/muxer.h" #include "libmpdemux/muxer_avi.h" #include "cfg-common.h"@@ -44,6 +45,9 @@     {"qtvideo", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_QTVIDEO, NULL},     {"nuv", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_NUV, NULL},     {"x264", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_X264, NULL},+#ifdef CONFIG_X265+    {"x265", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_X265, NULL},+#endif     {"help", "\nAvailable codecs:\n"     "   copy     - frame copy, without re-encoding. Doesn't work with filters.\n"     "   frameno  - special audio-only file for 3-pass encoding, see DOCS.\n"@@ -67,6 +71,9 @@ #ifdef CONFIG_X264     "   x264     - H.264 encoding\n" #endif+#ifdef CONFIG_X265+    "   x265     - H.265/HEVC encoding\n"+#endif     "\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},     {NULL, NULL, 0, 0, 0, 0, NULL} };@@ -254,6 +261,9 @@ #if defined(CONFIG_X264)     {"x264encopts", &x264enc_set_param, CONF_TYPE_FUNC_PARAM, CONF_GLOBAL, 0, 0, NULL}, #endif+#if defined(CONFIG_X265)+    {"x265encopts", &x265enc_set_param, CONF_TYPE_FUNC_PARAM, CONF_GLOBAL, 0, 0, NULL},+#endif  #ifdef CONFIG_LIBLZO     {"nuvopts",  nuvopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},Index: configure===================================================================--- configure	(revision 37877)+++ configure	(working copy)@@ -404,6 +404,7 @@   --disable-xvid-lavc       disable Xvid in libavcodec [autodetect]   --disable-x264            disable x264 [autodetect]   --disable-x264-lavc       disable x264 in libavcodec [autodetect]+  --disable-x265            disable x265 [autodetect]   --disable-libdirac-lavc   disable Dirac in libavcodec [autodetect]   --disable-libschroedinger-lavc   disable Dirac in libavcodec (Schroedinger                                    decoder) [autodetect]@@ -799,6 +800,7 @@ _xvid_lavc=auto _x264=auto _x264_lavc=auto+_x265=auto _libdirac_lavc=auto _libschroedinger_lavc=auto _libvpx_lavc=auto@@ -1254,6 +1256,8 @@   --disable-x264)       _x264=no        ;;   --enable-x264-lavc)   _x264_lavc=yes  ;;   --disable-x264-lavc)  _x264_lavc=no   ;;+  --enable-x265)        _x265=yes       ;;+  --disable-x265)       _x265=no        ;;   --enable-libdirac-lavc)   _libdirac_lavc=yes  ;;   --disable-libdirac-lavc)  _libdirac_lavc=no   ;;   --enable-libschroedinger-lavc)   _libschroedinger_lavc=yes  ;;@@ -7380,6 +7384,31 @@ echores "$_x264"  +echocheck "x265"+if test "$_x265" = auto && test "$_mencoder" = yes ; then+  cat > $TMPC << EOF+#include <inttypes.h>+#include <x265.h>+#if !(X265_BUILD >= 78)+#error We do not support old versions of x265. Get the latest from git.+#endif+int main(void) { x265_encoder_open((void*)0); return 0; }+EOF+  _x265=no+  for ld_x265 in "-lx265 -lstdc++ $ld_pthread" "-lx265 -lstdc++ $ld_pthread" ; do+    cc_check $ld_x265 && libs_mencoder="$libs_mencoder $ld_x265" && _x265=yes && break+  done+fi++if test "$_x265" = yes ; then+  def_x264='#define CONFIG_X265 1'+  codecmodules="x265 $codecmodules"+else+  def_x265='#undef CONFIG_X265'+  nocodecmodules="x265 $nocodecmodules"+fi+echores "$_x265"+ echocheck "libdirac" if test "$_libdirac_lavc" = auto; then   _libdirac_lavc=no@@ -8608,6 +8637,7 @@ WINVIDIX = $winvidix X11 = $_x11 X264 = $_x264+X265 = $_x265 XANIM_CODECS = $_xanim XMGA = $_xmga XMMS_PLUGINS = $_xmmsIndex: libmpcodecs/ve.c===================================================================--- libmpcodecs/ve.c	(revision 37877)+++ libmpcodecs/ve.c	(working copy)@@ -36,6 +36,7 @@ extern const vf_info_t ve_info_qtvideo; extern const vf_info_t ve_info_nuv; extern const vf_info_t ve_info_x264;+extern const vf_info_t ve_info_x265;  /* Please do not add any new encoders here. If you want to implement a new  * encoder, add it to libavcodec, except for wrappers around external@@ -64,6 +65,9 @@ #ifdef CONFIG_X264     &ve_info_x264, #endif+#ifdef CONFIG_X265+    &ve_info_x265,+#endif     /* Please do not add any new encoders here. If you want to implement a new      * encoder, add it to libavcodec, except for wrappers around external      * libraries and encoders requiring binary support. */Index: libmpcodecs/ve_x265.c===================================================================--- libmpcodecs/ve_x265.c	(revision 0)+++ libmpcodecs/ve_x265.c	(working copy)@@ -0,0 +1,319 @@+/*****************************************************************************+ *+ * - H.265/HEVC encoder for mencoder using x265 -+ *+ * Copyright (C) 2016 Min Chen+ *+ * Written by Min Chen <[email protected]>+ *+ * This file is part of MPlayer.+ *+ * MPlayer is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * MPlayer 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 General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License along+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.+ *+ *****************************************************************************/++#define _BSD_SOURCE++#include <stdio.h>+#include <stdlib.h>+#include <string.h>+#include <strings.h>+#include <errno.h>++#include "config.h"+#include "mp_msg.h"+#include "mencoder.h"+#include "m_option.h"+#include "codec-cfg.h"+#include "stream/stream.h"+#include "libmpdemux/demuxer.h"+#include "libmpdemux/stheader.h"+#include "osdep/strsep.h"+#include "stream/stream.h"+#include "libmpdemux/muxer.h"++#include "img_format.h"+#include "mp_image.h"+#include "vf.h"+#include "ve.h"+#include "ve_x265.h"++#include <x265.h>++typedef struct h265_module_t {+    muxer_stream_t *mux;++    const x265_api *api;+    x265_encoder *encoder;+    x265_picture pic;+} h265_module_t;++static x265_param params;+static int parse_error = 0;++static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts);+static int encode_frame(struct vf_instance *vf, struct x265_picture *pic_in);++void x265enc_set_param(const m_option_t* opt, char* arg)+{+    static int initialized = 0;+    char *preset = NULL, *tune = NULL, *profile = NULL;+    char *p, *copy, *name;++    if (!initialized) {+        x265_param_default(&params);+        initialized = 1;+    }++    if (!arg) {+        mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x265encopts: no options provided\n");+        parse_error = 1;+        return;+    } else if (!*arg)+        /* Empty arguments, just doing initialization of default parameters. */+        return;++    /* Step 1: look for initial preset/tune. */+    copy = p = strdup(arg);+    while ((name = strsep(&copy, ":"))) {+        char *value = strpbrk(name, "=:");+        if (!value)+            continue;+        *value++ = 0;+        if (!strcasecmp(name, "preset"))+            preset = value;+        else if (!strcasecmp(name, "tune"))+            tune = value;+    }+    if (x265_param_default_preset(&params, preset, tune) < 0) {+        mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x265encopts: Invalid preset or tune.\n");+        parse_error = 1;+    }+    free(p);++    /* Step 2: explicit user overrides */+    while ((name = strsep(&arg, ":")) && *name) {+        int ret = 0;+        char *value = strpbrk(name, "=:");++        if (value)+            *value++ = 0;+        if (!strcasecmp(name, "profile"))+            profile = value;+        else if (strcasecmp(name, "preset") && strcasecmp(name, "tune")) {+            ret = x265_param_parse(&params, name, value);+            if (ret == X265_PARAM_BAD_NAME)+                mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x265encopts: Unknown suboption %s\n", name);+            if (ret == X265_PARAM_BAD_VALUE)+                mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x265encopts: Bad argument %s=%s\n",+                       name, value ? value : "(null)");++        }+        /* mark this option as done, so it's not reparsed if there's another -x265encopts */+        *name = 0;++        parse_error |= ret;+    }++    /* Step 3: enforce profile */+    if (profile && x265_param_apply_profile(&params, profile) < 0)+        parse_error = 1;+}++static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) {+    h265_module_t *mod=(h265_module_t*)vf->priv;++    if(parse_error)+        return 0;++    if (!mod->api)+        return 0;++    mod->mux->bih->biWidth = width;+    mod->mux->bih->biHeight = height;+    mod->mux->bih->biSizeImage = width * height * 3;+    mod->mux->aspect = (float)d_width/d_height;++    // make sure param is initialized+    x265enc_set_param(NULL, "");+    params.sourceWidth = width;+    params.sourceHeight = height;+    params.fpsNum = mod->mux->h.dwRate;+    params.fpsDenom = mod->mux->h.dwScale;+    params.vui.sarWidth = d_width*height;+    params.vui.sarHeight = d_height*width;++    x265_param_parse(&params, "stats", passtmpfile);++    switch(outfmt) {+    case IMGFMT_Y8:+        params.internalCsp = X265_CSP_I400;+        break;+    case IMGFMT_I420:+        params.internalCsp = X265_CSP_I420;+        break;+    case IMGFMT_422P:+        params.internalCsp = X265_CSP_I422;+        break;+    case IMGFMT_444P:+        params.internalCsp = X265_CSP_I444;+        break;+    default:+        mp_msg(MSGT_MENCODER, MSGL_ERR, "Wrong colorspace.\n");+        return 0;+    }++    mod->encoder = mod->api->encoder_open(&params);+    if(!mod->encoder) {+        mp_msg(MSGT_MENCODER, MSGL_ERR, "x265_encoder_open failed.\n");+        return 0;+    }++    if(!params.bRepeatHeaders){+        x265_nal *nal;+        int extradata_size, nnal;++        extradata_size = mod->api->encoder_headers(mod->encoder, &nal, &nnal);++        mod->mux->bih= realloc(mod->mux->bih, sizeof(*mod->mux->bih) + extradata_size);+        memcpy(mod->mux->bih + 1, nal->payload, extradata_size);+        mod->mux->bih->biSize= sizeof(*mod->mux->bih) + extradata_size;+    }++    if (params.bframes > 1 && params.bBPyramid)+        mod->mux->decoder_delay = 2;+    else+        mod->mux->decoder_delay = params.bframes ? 1 : 0;++    return 1;+}++static int control(struct vf_instance *vf, int request, void *data)+{+    h265_module_t *mod=(h265_module_t*)vf->priv;+    switch(request){+        case VFCTRL_FLUSH_FRAMES:+            while (encode_frame(vf, NULL) > 0)+                ;+            return CONTROL_TRUE;+        default:+            return CONTROL_UNKNOWN;+    }+}++static int query_format(struct vf_instance *vf, unsigned int fmt)+{+    switch(fmt) {+    case IMGFMT_Y8:+    case IMGFMT_I420:+    case IMGFMT_422P:+    case IMGFMT_444P:+        return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;+    default:+        return 0; /* VFCAP_CSP_SUPPORTED */+    }+    return 0;+}++static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)+{+    h265_module_t *mod=(h265_module_t*)vf->priv;+    int i;++    mod->api->picture_init(&params, &mod->pic);+    mod->pic.colorSpace = params.internalCsp;+    for(i = 0; i < 3; i++) {+        mod->pic.planes[i] = mpi->planes[i];+        mod->pic.stride[i] = mpi->stride[i];+    }++    mod->pic.sliceType = X265_TYPE_AUTO;+    if (is_forced_key_frame(pts))+        mod->pic.sliceType = X265_TYPE_IDR;++    return encode_frame(vf, &mod->pic) >= 0;+}+++static int encode_frame(struct vf_instance *vf, struct x265_picture *pic_in)+{+    h265_module_t *mod=(h265_module_t*)vf->priv;+    x265_picture pic_out;+    x265_nal *nal;+    int i_nal;+    int i_encoded;+    int i;++    i_encoded = mod->api->encoder_encode(mod->encoder, &nal, &i_nal, pic_in, &pic_out);++    if(i_encoded < 0) {+        mp_msg(MSGT_MENCODER, MSGL_ERR, "x265_encoder_encode failed\n");+        return -1;+    }+    if(i_nal > 0) {+        for(i = 0; i < i_nal; i++) {+            int keyframe = (pic_out.sliceType == X265_TYPE_IDR);+            int i_nal_size = (int)nal[i].sizeBytes;+            memcpy(mod->mux->buffer, nal[i].payload, i_nal_size);+            muxer_write_chunk(mod->mux, i_nal_size, (keyframe ? AVIIF_KEYFRAME : 0), MP_NOPTS_VALUE, MP_NOPTS_VALUE);+        }+    }+    else+        ++mod->mux->encoder_delay;++    return i_nal;+}++static void uninit(struct vf_instance *vf)+{+    h265_module_t *mod=(h265_module_t*)vf->priv;+    if (mod->api) {+        if (mod->encoder) {+            mod->api->encoder_close(mod->encoder);+            mod->encoder = NULL;+        }+    }+}++static int vf_open(vf_instance_t *vf, char *args) {+    h265_module_t *mod;++    vf->config = config;+    vf->default_caps = VFCAP_CONSTANT;+    vf->control = control;+    vf->query_format = query_format;+    vf->put_image = put_image;+    vf->uninit = uninit;+    vf->priv = malloc(sizeof(h265_module_t));++    mod=(h265_module_t*)vf->priv;+    mod->mux = (muxer_stream_t*)args;+    mod->mux->bih = calloc(1, sizeof(*mod->mux->bih));+    mod->mux->bih->biSize = sizeof(*mod->mux->bih);+    mod->mux->bih->biPlanes = 1;+    mod->mux->bih->biBitCount = 24;+    mod->mux->bih->biCompression = mmioFOURCC('H', 'E', 'V', 'C');+    mod->api = x265_api_get(0); /* 0=auto_bit_depth, may set to 12/10/8 in future */++    return 1;+}++const vf_info_t ve_info_x265 = {+    "H.265/HEVC encoder",+    "x265",+    "Min Chen <[email protected]>",+    "(C) 2016 Min Chen",+    vf_open+};Index: libmpcodecs/ve_x265.h===================================================================--- libmpcodecs/ve_x265.h	(revision 0)+++ libmpcodecs/ve_x265.h	(working copy)@@ -0,0 +1,26 @@+/*+ * This file is part of MPlayer.+ *+ * MPlayer is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * MPlayer 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 General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License along+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.+ */++#ifndef MPLAYER_X265_H+#define MPLAYER_X265_H++#include "m_option.h"++void x265enc_set_param(const m_option_t* opt, char* arg);++#endif /* MPLAYER_X265_H */Index: mencoder.c===================================================================--- mencoder.c	(revision 37877)+++ mencoder.c	(working copy)@@ -27,6 +27,7 @@ #define VCODEC_NUV 11 #define VCODEC_RAW 12 #define VCODEC_X264 13+#define VCODEC_X265 14  #define ACODEC_COPY 0 #define ACODEC_PCM 1@@ -961,6 +962,10 @@         sh_video->vfilter=vf_open_encoder(NULL,"nuv",(char *)mux_v); break;     case VCODEC_X264:         sh_video->vfilter=vf_open_encoder(NULL,"x264",(char *)mux_v); break;+#ifdef CONFIG_X265+    case VCODEC_X265:+        sh_video->vfilter=vf_open_encoder(NULL,"x265",(char *)mux_v); break;+#endif     }     if(!mux_v->bih || !sh_video->vfilter){         mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_EncoderOpenFailed);

_______________________________________________
MPlayer-dev-eng mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng
mencoder_with_x265.patch (application/octet-stream, 16.6 KB)
Index: Makefile
===================================================================
--- Makefile	(revision 37877)
+++ Makefile	(working copy)
@@ -628,6 +628,7 @@
 SRCS_MENCODER-$(TWOLAME)          += libmpcodecs/ae_twolame.c
 SRCS_MENCODER-$(WIN32DLL)         += libmpcodecs/ve_vfw.c
 SRCS_MENCODER-$(X264)             += libmpcodecs/ve_x264.c
+SRCS_MENCODER-$(X265)             += libmpcodecs/ve_x265.c
 SRCS_MENCODER-$(XVID4)            += libmpcodecs/ve_xvid4.c
 
 SRCS_MENCODER = mencoder.c                      \
Index: cfg-mencoder.h
===================================================================
--- cfg-mencoder.h	(revision 37877)
+++ cfg-mencoder.h	(working copy)
@@ -29,6 +29,7 @@
 #include "libmpcodecs/ae_twolame.h"
 #include "libmpcodecs/ve.h"
 #include "libmpcodecs/ve_x264.h"
+#include "libmpcodecs/ve_x265.h"
 #include "libmpdemux/muxer.h"
 #include "libmpdemux/muxer_avi.h"
 #include "cfg-common.h"
@@ -44,6 +45,9 @@
     {"qtvideo", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_QTVIDEO, NULL},
     {"nuv", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_NUV, NULL},
     {"x264", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_X264, NULL},
+#ifdef CONFIG_X265
+    {"x265", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_X265, NULL},
+#endif
     {"help", "\nAvailable codecs:\n"
     "   copy     - frame copy, without re-encoding. Doesn't work with filters.\n"
     "   frameno  - special audio-only file for 3-pass encoding, see DOCS.\n"
@@ -67,6 +71,9 @@
 #ifdef CONFIG_X264
     "   x264     - H.264 encoding\n"
 #endif
+#ifdef CONFIG_X265
+    "   x265     - H.265/HEVC encoding\n"
+#endif
     "\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
     {NULL, NULL, 0, 0, 0, 0, NULL}
 };
@@ -254,6 +261,9 @@
 #if defined(CONFIG_X264)
     {"x264encopts", &x264enc_set_param, CONF_TYPE_FUNC_PARAM, CONF_GLOBAL, 0, 0, NULL},
 #endif
+#if defined(CONFIG_X265)
+    {"x265encopts", &x265enc_set_param, CONF_TYPE_FUNC_PARAM, CONF_GLOBAL, 0, 0, NULL},
+#endif
 
 #ifdef CONFIG_LIBLZO
     {"nuvopts",  nuvopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
Index: configure
===================================================================
--- configure	(revision 37877)
+++ configure	(working copy)
@@ -404,6 +404,7 @@
   --disable-xvid-lavc       disable Xvid in libavcodec [autodetect]
   --disable-x264            disable x264 [autodetect]
   --disable-x264-lavc       disable x264 in libavcodec [autodetect]
+  --disable-x265            disable x265 [autodetect]
   --disable-libdirac-lavc   disable Dirac in libavcodec [autodetect]
   --disable-libschroedinger-lavc   disable Dirac in libavcodec (Schroedinger
                                    decoder) [autodetect]
@@ -799,6 +800,7 @@
 _xvid_lavc=auto
 _x264=auto
 _x264_lavc=auto
+_x265=auto
 _libdirac_lavc=auto
 _libschroedinger_lavc=auto
 _libvpx_lavc=auto
@@ -1254,6 +1256,8 @@
   --disable-x264)       _x264=no        ;;
   --enable-x264-lavc)   _x264_lavc=yes  ;;
   --disable-x264-lavc)  _x264_lavc=no   ;;
+  --enable-x265)        _x265=yes       ;;
+  --disable-x265)       _x265=no        ;;
   --enable-libdirac-lavc)   _libdirac_lavc=yes  ;;
   --disable-libdirac-lavc)  _libdirac_lavc=no   ;;
   --enable-libschroedinger-lavc)   _libschroedinger_lavc=yes  ;;
@@ -7380,6 +7384,31 @@
 echores "$_x264"
 
 
+echocheck "x265"
+if test "$_x265" = auto && test "$_mencoder" = yes ; then
+  cat > $TMPC << EOF
+#include <inttypes.h>
+#include <x265.h>
+#if !(X265_BUILD >= 78)
+#error We do not support old versions of x265. Get the latest from git.
+#endif
+int main(void) { x265_encoder_open((void*)0); return 0; }
+EOF
+  _x265=no
+  for ld_x265 in "-lx265 -lstdc++ $ld_pthread" "-lx265 -lstdc++ $ld_pthread" ; do
+    cc_check $ld_x265 && libs_mencoder="$libs_mencoder $ld_x265" && _x265=yes && break
+  done
+fi
+
+if test "$_x265" = yes ; then
+  def_x264='#define CONFIG_X265 1'
+  codecmodules="x265 $codecmodules"
+else
+  def_x265='#undef CONFIG_X265'
+  nocodecmodules="x265 $nocodecmodules"
+fi
+echores "$_x265"
+
 echocheck "libdirac"
 if test "$_libdirac_lavc" = auto; then
   _libdirac_lavc=no
@@ -8608,6 +8637,7 @@
 WINVIDIX = $winvidix
 X11 = $_x11
 X264 = $_x264
+X265 = $_x265
 XANIM_CODECS = $_xanim
 XMGA = $_xmga
 XMMS_PLUGINS = $_xmms
Index: libmpcodecs/ve.c
===================================================================
--- libmpcodecs/ve.c	(revision 37877)
+++ libmpcodecs/ve.c	(working copy)
@@ -36,6 +36,7 @@
 extern const vf_info_t ve_info_qtvideo;
 extern const vf_info_t ve_info_nuv;
 extern const vf_info_t ve_info_x264;
+extern const vf_info_t ve_info_x265;
 
 /* Please do not add any new encoders here. If you want to implement a new
  * encoder, add it to libavcodec, except for wrappers around external
@@ -64,6 +65,9 @@
 #ifdef CONFIG_X264
     &ve_info_x264,
 #endif
+#ifdef CONFIG_X265
+    &ve_info_x265,
+#endif
     /* Please do not add any new encoders here. If you want to implement a new
      * encoder, add it to libavcodec, except for wrappers around external
      * libraries and encoders requiring binary support. */
Index: libmpcodecs/ve_x265.c
===================================================================
--- libmpcodecs/ve_x265.c	(revision 0)
+++ libmpcodecs/ve_x265.c	(working copy)
@@ -0,0 +1,319 @@
+/*****************************************************************************
+ *
+ * - H.265/HEVC encoder for mencoder using x265 -
+ *
+ * Copyright (C) 2016 Min Chen
+ *
+ * Written by Min Chen <[email protected]>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *****************************************************************************/
+
+#define _BSD_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "mencoder.h"
+#include "m_option.h"
+#include "codec-cfg.h"
+#include "stream/stream.h"
+#include "libmpdemux/demuxer.h"
+#include "libmpdemux/stheader.h"
+#include "osdep/strsep.h"
+#include "stream/stream.h"
+#include "libmpdemux/muxer.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "ve.h"
+#include "ve_x265.h"
+
+#include <x265.h>
+
+typedef struct h265_module_t {
+    muxer_stream_t *mux;
+
+    const x265_api *api;
+    x265_encoder *encoder;
+    x265_picture pic;
+} h265_module_t;
+
+static x265_param params;
+static int parse_error = 0;
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts);
+static int encode_frame(struct vf_instance *vf, struct x265_picture *pic_in);
+
+void x265enc_set_param(const m_option_t* opt, char* arg)
+{
+    static int initialized = 0;
+    char *preset = NULL, *tune = NULL, *profile = NULL;
+    char *p, *copy, *name;
+
+    if (!initialized) {
+        x265_param_default(&params);
+        initialized = 1;
+    }
+
+    if (!arg) {
+        mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x265encopts: no options provided\n");
+        parse_error = 1;
+        return;
+    } else if (!*arg)
+        /* Empty arguments, just doing initialization of default parameters. */
+        return;
+
+    /* Step 1: look for initial preset/tune. */
+    copy = p = strdup(arg);
+    while ((name = strsep(&copy, ":"))) {
+        char *value = strpbrk(name, "=:");
+        if (!value)
+            continue;
+        *value++ = 0;
+        if (!strcasecmp(name, "preset"))
+            preset = value;
+        else if (!strcasecmp(name, "tune"))
+            tune = value;
+    }
+    if (x265_param_default_preset(&params, preset, tune) < 0) {
+        mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x265encopts: Invalid preset or tune.\n");
+        parse_error = 1;
+    }
+    free(p);
+
+    /* Step 2: explicit user overrides */
+    while ((name = strsep(&arg, ":")) && *name) {
+        int ret = 0;
+        char *value = strpbrk(name, "=:");
+
+        if (value)
+            *value++ = 0;
+        if (!strcasecmp(name, "profile"))
+            profile = value;
+        else if (strcasecmp(name, "preset") && strcasecmp(name, "tune")) {
+            ret = x265_param_parse(&params, name, value);
+            if (ret == X265_PARAM_BAD_NAME)
+                mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x265encopts: Unknown suboption %s\n", name);
+            if (ret == X265_PARAM_BAD_VALUE)
+                mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x265encopts: Bad argument %s=%s\n",
+                       name, value ? value : "(null)");
+
+        }
+        /* mark this option as done, so it's not reparsed if there's another -x265encopts */
+        *name = 0;
+
+        parse_error |= ret;
+    }
+
+    /* Step 3: enforce profile */
+    if (profile && x265_param_apply_profile(&params, profile) < 0)
+        parse_error = 1;
+}
+
+static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) {
+    h265_module_t *mod=(h265_module_t*)vf->priv;
+
+    if(parse_error)
+        return 0;
+
+    if (!mod->api)
+        return 0;
+
+    mod->mux->bih->biWidth = width;
+    mod->mux->bih->biHeight = height;
+    mod->mux->bih->biSizeImage = width * height * 3;
+    mod->mux->aspect = (float)d_width/d_height;
+
+    // make sure param is initialized
+    x265enc_set_param(NULL, "");
+    params.sourceWidth = width;
+    params.sourceHeight = height;
+    params.fpsNum = mod->mux->h.dwRate;
+    params.fpsDenom = mod->mux->h.dwScale;
+    params.vui.sarWidth = d_width*height;
+    params.vui.sarHeight = d_height*width;
+
+    x265_param_parse(&params, "stats", passtmpfile);
+
+    switch(outfmt) {
+    case IMGFMT_Y8:
+        params.internalCsp = X265_CSP_I400;
+        break;
+    case IMGFMT_I420:
+        params.internalCsp = X265_CSP_I420;
+        break;
+    case IMGFMT_422P:
+        params.internalCsp = X265_CSP_I422;
+        break;
+    case IMGFMT_444P:
+        params.internalCsp = X265_CSP_I444;
+        break;
+    default:
+        mp_msg(MSGT_MENCODER, MSGL_ERR, "Wrong colorspace.\n");
+        return 0;
+    }
+
+    mod->encoder = mod->api->encoder_open(&params);
+    if(!mod->encoder) {
+        mp_msg(MSGT_MENCODER, MSGL_ERR, "x265_encoder_open failed.\n");
+        return 0;
+    }
+
+    if(!params.bRepeatHeaders){
+        x265_nal *nal;
+        int extradata_size, nnal;
+
+        extradata_size = mod->api->encoder_headers(mod->encoder, &nal, &nnal);
+
+        mod->mux->bih= realloc(mod->mux->bih, sizeof(*mod->mux->bih) + extradata_size);
+        memcpy(mod->mux->bih + 1, nal->payload, extradata_size);
+        mod->mux->bih->biSize= sizeof(*mod->mux->bih) + extradata_size;
+    }
+
+    if (params.bframes > 1 && params.bBPyramid)
+        mod->mux->decoder_delay = 2;
+    else
+        mod->mux->decoder_delay = params.bframes ? 1 : 0;
+
+    return 1;
+}
+
+static int control(struct vf_instance *vf, int request, void *data)
+{
+    h265_module_t *mod=(h265_module_t*)vf->priv;
+    switch(request){
+        case VFCTRL_FLUSH_FRAMES:
+            while (encode_frame(vf, NULL) > 0)
+                ;
+            return CONTROL_TRUE;
+        default:
+            return CONTROL_UNKNOWN;
+    }
+}
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+    switch(fmt) {
+    case IMGFMT_Y8:
+    case IMGFMT_I420:
+    case IMGFMT_422P:
+    case IMGFMT_444P:
+        return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;
+    default:
+        return 0; /* VFCAP_CSP_SUPPORTED */
+    }
+    return 0;
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    h265_module_t *mod=(h265_module_t*)vf->priv;
+    int i;
+
+    mod->api->picture_init(&params, &mod->pic);
+    mod->pic.colorSpace = params.internalCsp;
+    for(i = 0; i < 3; i++) {
+        mod->pic.planes[i] = mpi->planes[i];
+        mod->pic.stride[i] = mpi->stride[i];
+    }
+
+    mod->pic.sliceType = X265_TYPE_AUTO;
+    if (is_forced_key_frame(pts))
+        mod->pic.sliceType = X265_TYPE_IDR;
+
+    return encode_frame(vf, &mod->pic) >= 0;
+}
+
+
+static int encode_frame(struct vf_instance *vf, struct x265_picture *pic_in)
+{
+    h265_module_t *mod=(h265_module_t*)vf->priv;
+    x265_picture pic_out;
+    x265_nal *nal;
+    int i_nal;
+    int i_encoded;
+    int i;
+
+    i_encoded = mod->api->encoder_encode(mod->encoder, &nal, &i_nal, pic_in, &pic_out);
+
+    if(i_encoded < 0) {
+        mp_msg(MSGT_MENCODER, MSGL_ERR, "x265_encoder_encode failed\n");
+        return -1;
+    }
+    if(i_nal > 0) {
+        for(i = 0; i < i_nal; i++) {
+            int keyframe = (pic_out.sliceType == X265_TYPE_IDR);
+            int i_nal_size = (int)nal[i].sizeBytes;
+            memcpy(mod->mux->buffer, nal[i].payload, i_nal_size);
+            muxer_write_chunk(mod->mux, i_nal_size, (keyframe ? AVIIF_KEYFRAME : 0), MP_NOPTS_VALUE, MP_NOPTS_VALUE);
+        }
+    }
+    else
+        ++mod->mux->encoder_delay;
+
+    return i_nal;
+}
+
+static void uninit(struct vf_instance *vf)
+{
+    h265_module_t *mod=(h265_module_t*)vf->priv;
+    if (mod->api) {
+        if (mod->encoder) {
+            mod->api->encoder_close(mod->encoder);
+            mod->encoder = NULL;
+        }
+    }
+}
+
+static int vf_open(vf_instance_t *vf, char *args) {
+    h265_module_t *mod;
+
+    vf->config = config;
+    vf->default_caps = VFCAP_CONSTANT;
+    vf->control = control;
+    vf->query_format = query_format;
+    vf->put_image = put_image;
+    vf->uninit = uninit;
+    vf->priv = malloc(sizeof(h265_module_t));
+
+    mod=(h265_module_t*)vf->priv;
+    mod->mux = (muxer_stream_t*)args;
+    mod->mux->bih = calloc(1, sizeof(*mod->mux->bih));
+    mod->mux->bih->biSize = sizeof(*mod->mux->bih);
+    mod->mux->bih->biPlanes = 1;
+    mod->mux->bih->biBitCount = 24;
+    mod->mux->bih->biCompression = mmioFOURCC('H', 'E', 'V', 'C');
+    mod->api = x265_api_get(0); /* 0=auto_bit_depth, may set to 12/10/8 in future */
+
+    return 1;
+}
+
+const vf_info_t ve_info_x265 = {
+    "H.265/HEVC encoder",
+    "x265",
+    "Min Chen <[email protected]>",
+    "(C) 2016 Min Chen",
+    vf_open
+};
Index: libmpcodecs/ve_x265.h
===================================================================
--- libmpcodecs/ve_x265.h	(revision 0)
+++ libmpcodecs/ve_x265.h	(working copy)
@@ -0,0 +1,26 @@
+/*
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPLAYER_X265_H
+#define MPLAYER_X265_H
+
+#include "m_option.h"
+
+void x265enc_set_param(const m_option_t* opt, char* arg);
+
+#endif /* MPLAYER_X265_H */
Index: mencoder.c
===================================================================
--- mencoder.c	(revision 37877)
+++ mencoder.c	(working copy)
@@ -27,6 +27,7 @@
 #define VCODEC_NUV 11
 #define VCODEC_RAW 12
 #define VCODEC_X264 13
+#define VCODEC_X265 14
 
 #define ACODEC_COPY 0
 #define ACODEC_PCM 1
@@ -961,6 +962,10 @@
         sh_video->vfilter=vf_open_encoder(NULL,"nuv",(char *)mux_v); break;
     case VCODEC_X264:
         sh_video->vfilter=vf_open_encoder(NULL,"x264",(char *)mux_v); break;
+#ifdef CONFIG_X265
+    case VCODEC_X265:
+        sh_video->vfilter=vf_open_encoder(NULL,"x265",(char *)mux_v); break;
+#endif
     }
     if(!mux_v->bih || !sh_video->vfilter){
         mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_EncoderOpenFailed);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.