Web lists-archives.com

[MPlayer-dev-eng] [PATCH] Integrate x265 into MEncoder




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 <chenm003@xxxxxxxxx>+ *+ * 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 <chenm003@xxxxxxxxx>",+    "(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);

Attachment: mencoder_with_x265.patch
Description: Binary data

_______________________________________________
MPlayer-dev-eng mailing list
MPlayer-dev-eng@xxxxxxxxxxxx
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng