[MPlayer-dev-eng] [PATCH] Integrate x265 into MEncoder
chen
chenm003 at 163.com
Wed Jul 20 18:21:38 EEST 2016
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 at gmail.com>+ *+ * 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(¶ms);+ 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(©, ":"))) {+ 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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, "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(¶ms);+ 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(¶ms, &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 at gmail.com>",+ "(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);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mencoder_with_x265.patch
Type: application/octet-stream
Size: 17029 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20160720/596ab139/attachment-0001.obj>
More information about the MPlayer-dev-eng
mailing list