diff mbox

[FFmpeg-devel] patch for a new H.264 codec with Matrox m264 card.

Message ID 5f3676de-821c-06de-248f-a56d3d15b596@matrox.com
State New
Headers show

Commit Message

Yufei He March 27, 2019, 3:30 p.m. UTC
Hi

Here is the fixed patch for a new H.264 codec with Matrox M264 card.

It calls the default library from the card's driver installation.
Please review.

Thanks.

Yufei.

Comments

Nicolas George March 27, 2019, 3:35 p.m. UTC | #1
Yufei He (12019-03-27):
> Here is the fixed patch for a new H.264 codec with Matrox M264 card.
> 
> It calls the default library from the card's driver installation.
> Please review.

You are still using programmatic dynamic linking instead of normal
dynamic linking, and you have not given a good reason for that. Please
fix.

Regards,
Carl Eugen Hoyos March 27, 2019, 3:49 p.m. UTC | #2
2019-03-27 16:30 GMT+01:00, Yufei He <yhe@matrox.com>:

> Here is the fixed patch for a new H.264 codec with Matrox
> M264 card.

Please do not send another version of this patch that doesn't
add the non-free requirement in configure (or open-source
your library).

Carl Eugen
Yufei He March 28, 2019, 12:40 p.m. UTC | #3
On 03/27/2019 11:35 AM, Nicolas George wrote:

Yufei He (12019-03-27):


Here is the fixed patch for a new H.264 codec with Matrox M264 card.

It calls the default library from the card's driver installation.
Please review.



You are still using programmatic dynamic linking instead of normal
dynamic linking, and you have not given a good reason for that. Please
fix.

Regards,


Hi Nicolas

In windows, we need provide the interface library mvM264.lib to our customers so that they can build. But driver installation of the card does not have the interface library. It just install mvM264.dll.

We call dlopen to load mvM264.dll on runtime.  It's simpler. That's the way we are doing now in other projects..

Thanks.

Yufei.






_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org<mailto:ffmpeg-devel@ffmpeg.org>
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org<mailto:ffmpeg-devel-request@ffmpeg.org> with subject "unsubscribe".
Jean-Baptiste Kempf March 28, 2019, 2 p.m. UTC | #4
On Thu, 28 Mar 2019, at 13:41, Yufei He wrote:
> In windows, we need provide the interface library mvM264.lib to our 
> customers so that they can build. But driver installation of the card 
> does not have the interface library. It just install mvM264.dll.

Why does mvM264.dll return 0 Google Search result?
Carl Eugen Hoyos March 28, 2019, 2:01 p.m. UTC | #5
2019-03-28 13:40 GMT+01:00, Yufei He <yhe@matrox.com>:

> In windows, we need provide the interface library mvM264.lib

And you should.

Carl Eugen
Yufei He March 28, 2019, 5:13 p.m. UTC | #6
On 03/28/2019 10:00 AM, Jean-Baptiste Kempf wrote:
>

> On Thu, 28 Mar 2019, at 13:41, Yufei He wrote:

>> In windows, we need provide the interface library mvM264.lib to our

>> customers so that they can build. But driver installation of the card

>> does not have the interface library. It just install mvM264.dll.

> Why does mvM264.dll return 0 Google Search result?

>

>

>

Hi Jean-Baptiste

I just did the same Google search, yes, it seems most of the .dlls made 
in last 2 or 3 years can not be found.
I can find some old .dll files, e.g. mvcDCT.dll.

Yufei.
Nicolas George March 28, 2019, 7:40 p.m. UTC | #7
No need to Cc me, I am subscribed to the list.

Yufei He (12019-03-28):
> In windows, we need provide the interface library mvM264.lib to our
> customers so that they can build. But driver installation of the card
> does not have the interface library. It just install mvM264.dll.
> 
> We call dlopen to load mvM264.dll on runtime.  It's simpler. That's
> the way we are doing now in other projects..

It may be simpler for your infrastructure, but it is not simpler for
FFmpeg users, and it actually feels like a deliberate attempt at
circumventing the license.

Regards,
Thomas Volkert March 28, 2019, 8:11 p.m. UTC | #8
On 28.03.2019 13:40, Yufei He wrote:
> On 03/27/2019 11:35 AM, Nicolas George wrote:
>
> Yufei He (12019-03-27):
>
>
> Here is the fixed patch for a new H.264 codec with Matrox M264 card.
>
> It calls the default library from the card's driver installation.
> Please review.
>
>
>
> You are still using programmatic dynamic linking instead of normal
> dynamic linking, and you have not given a good reason for that. Please
> fix.
>
> Regards,
>
>
> Hi Nicolas
>
> In windows, we need provide the interface library mvM264.lib to our customers so that they can build. But driver installation of the card does not have the interface library. It just install mvM264.dll.
>
> We call dlopen to load mvM264.dll on runtime.  It's simpler. That's the way we are doing now in other projects..

I personally prefer this way of dynamic linking for such cases. Intel
does it in a similar way via their mfx_dispatcher. They use it as dll
loader for ondemand access to the Intel QuickSync specific dlls during
the runtime of the corresponding application.
But they published the source of this special dll loader as open source
release.

Best regards,
Thomas.
Dennis Mungai March 28, 2019, 8:18 p.m. UTC | #9
On Thu, 28 Mar 2019 at 22:40, Nicolas George <george@nsup.org> wrote:

> No need to Cc me, I am subscribed to the list.
>
> Yufei He (12019-03-28):
> > In windows, we need provide the interface library mvM264.lib to our
> > customers so that they can build. But driver installation of the card
> > does not have the interface library. It just install mvM264.dll.
> >
> > We call dlopen to load mvM264.dll on runtime.  It's simpler. That's
> > the way we are doing now in other projects..
>
> It may be simpler for your infrastructure, but it is not simpler for
> FFmpeg users, and it actually feels like a deliberate attempt at
> circumventing the license.
>
> Regards,
>
> --
>   Nicolas George
>
>
It's actually a deliberate attempt at circumventing the license.
Clearly that dynamic library *can* be built from source, as its' separable
from the device driver.
What's preventing Matrox from releasing this library such that users can
build it themselves?
And why should FFmpeg  inherit the maintenance burden of dealing with an
opaque ABI whose breakage is guaranteed with version bumps?
Yufei He March 28, 2019, 9:16 p.m. UTC | #10
On 03/28/2019 04:18 PM, Dennis Mungai wrote:
> On Thu, 28 Mar 2019 at 22:40, Nicolas George <george@nsup.org> wrote:

>

>> No need to Cc me, I am subscribed to the list.

>>

>> Yufei He (12019-03-28):

>>> In windows, we need provide the interface library mvM264.lib to our

>>> customers so that they can build. But driver installation of the card

>>> does not have the interface library. It just install mvM264.dll.

>>>

>>> We call dlopen to load mvM264.dll on runtime.  It's simpler. That's

>>> the way we are doing now in other projects..

>> It may be simpler for your infrastructure, but it is not simpler for

>> FFmpeg users, and it actually feels like a deliberate attempt at

>> circumventing the license.

>>

>> Regards,

>>

>> --

>>    Nicolas George

>>

>>

> It's actually a deliberate attempt at circumventing the license.

> Clearly that dynamic library *can* be built from source, as its' separable

> from the device driver.

> What's preventing Matrox from releasing this library such that users can

> build it themselves?

> And why should FFmpeg  inherit the maintenance burden of dealing with an

> opaque ABI whose breakage is guaranteed with version bumps?

> _______________________________________________

> ffmpeg-devel mailing list

> ffmpeg-devel@ffmpeg.org

> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

>

> To unsubscribe, visit link above, or email

> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

Actually, I'm just a software engineer, and very new to FFmpeg.
I know little about license. It's impossible to figure out some ideas to 
circumvent the license.

For me, the most important thing is to get it work. Most of my time is 
on studying code of FFmpeg and figure out how to support M264.

The way I'm doing now is all from study of current code in FFmpeg.
I'm still studying the way how companies like blackmagic support FFmpeg.

Regards.

Yufei.
Dennis Mungai March 28, 2019, 10:15 p.m. UTC | #11
On Fri, Mar 29, 2019, 00:16 Yufei He <yhe@matrox.com> wrote:

> On 03/28/2019 04:18 PM, Dennis Mungai wrote:
> > On Thu, 28 Mar 2019 at 22:40, Nicolas George <george@nsup.org> wrote:
> >
> >> No need to Cc me, I am subscribed to the list.
> >>
> >> Yufei He (12019-03-28):
> >>> In windows, we need provide the interface library mvM264.lib to our
> >>> customers so that they can build. But driver installation of the card
> >>> does not have the interface library. It just install mvM264.dll.
> >>>
> >>> We call dlopen to load mvM264.dll on runtime.  It's simpler. That's
> >>> the way we are doing now in other projects..
> >> It may be simpler for your infrastructure, but it is not simpler for
> >> FFmpeg users, and it actually feels like a deliberate attempt at
> >> circumventing the license.
> >>
> >> Regards,
> >>
> >> --
> >>    Nicolas George
> >>
> >>
> > It's actually a deliberate attempt at circumventing the license.
> > Clearly that dynamic library *can* be built from source, as its'
> separable
> > from the device driver.
> > What's preventing Matrox from releasing this library such that users can
> > build it themselves?
> > And why should FFmpeg  inherit the maintenance burden of dealing with an
> > opaque ABI whose breakage is guaranteed with version bumps?
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> Actually, I'm just a software engineer, and very new to FFmpeg.
> I know little about license. It's impossible to figure out some ideas to
> circumvent the license.
>
> For me, the most important thing is to get it work. Most of my time is
> on studying code of FFmpeg and figure out how to support M264.
>
> The way I'm doing now is all from study of current code in FFmpeg.
> I'm still studying the way how companies like blackmagic support FFmpeg.
>
> Regards.
>
> Yufei.
>
>
>
>


Then understand *how* the development process works. If you're told to
> withdraw a patch for some reason (see what Carlos cited earlier), comply.
> And only resubmit it when

it meets the requirements.


Your role, be it an employee of Matrox or an independent contributor, means
little as far as compliance to the development process is concerned.

The same rules and development guidelines apply to *all* contributors here,
irrespective of the nature of ties they hold to the products and companies
whose support exists in FFmpeg.

The examples you're going through (Decklink, ffnvcodec, etc) are a good
starting point.

We don't enforce these guidelines to discourage contributions to FFmpeg,
but rather, to ensure that such contributions are maintainable, and in a
way that respects the license under which they fall under.
diff mbox

Patch

From da521d4e1315199a5fb781adf8a56efdc64c2b42 Mon Sep 17 00:00:00 2001
From: yhe <yhe@matrox.com>
Date: Wed, 27 Mar 2019 11:05:41 -0400
Subject: [PATCH] h.264 decoder and encoder support with M264

---
 Changelog              |   1 +
 configure              |   2 +
 libavcodec/Makefile    |   2 +
 libavcodec/allcodecs.c |   2 +
 libavcodec/m264dec.c   | 357 +++++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/m264dec.h   |  40 ++++++
 libavcodec/m264enc.c   | 335 ++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/m264enc.h   |  38 ++++++
 8 files changed, 777 insertions(+)
 create mode 100644 libavcodec/m264dec.c
 create mode 100644 libavcodec/m264dec.h
 create mode 100644 libavcodec/m264enc.c
 create mode 100644 libavcodec/m264enc.h

diff --git a/Changelog b/Changelog
index 4d80e5b..ce0daf8 100644
--- a/Changelog
+++ b/Changelog
@@ -19,6 +19,7 @@  version <next>:
 - ARBC decoder
 - libaribb24 based ARIB STD-B24 caption support (profiles A and C)
 - Support decoding of HEVC 4:4:4 content in nvdec and cuviddec
+- Support h.264 encoding and decoding with Matrox M264 card.
 
 
 version 4.1:
diff --git a/configure b/configure
index dcead3a..3be416e 100755
--- a/configure
+++ b/configure
@@ -2697,6 +2697,8 @@  h263p_decoder_select="h263_decoder"
 h263p_encoder_select="h263_encoder"
 h264_decoder_select="cabac golomb h264chroma h264dsp h264parse h264pred h264qpel videodsp"
 h264_decoder_suggest="error_resilience"
+h264_m264_decoder_deps_any="libdl"
+h264_m264_encoder_deps_any="libdl libswscale"
 hap_decoder_select="snappy texturedsp"
 hap_encoder_deps="libsnappy"
 hap_encoder_select="texturedspenc"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 15c43a8..8e8f9ab 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -348,6 +348,8 @@  OBJS-$(CONFIG_H264_DECODER)            += h264dec.o h264_cabac.o h264_cavlc.o \
                                           h264_slice.o h264data.o
 OBJS-$(CONFIG_H264_AMF_ENCODER)        += amfenc_h264.o
 OBJS-$(CONFIG_H264_CUVID_DECODER)      += cuviddec.o
+OBJS-$(CONFIG_H264_M264_DECODER)       += m264dec.o
+OBJS-$(CONFIG_H264_M264_ENCODER)       += m264enc.o
 OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o
 OBJS-$(CONFIG_H264_MMAL_DECODER)       += mmaldec.o
 OBJS-$(CONFIG_H264_NVENC_ENCODER)      += nvenc_h264.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index b26aeca..c03a5a3 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -737,6 +737,8 @@  extern AVCodec ff_libopenh264_encoder;
 extern AVCodec ff_libopenh264_decoder;
 extern AVCodec ff_h264_amf_encoder;
 extern AVCodec ff_h264_cuvid_decoder;
+extern AVCodec ff_h264_m264_decoder;
+extern AVCodec ff_h264_m264_encoder;
 extern AVCodec ff_h264_nvenc_encoder;
 extern AVCodec ff_h264_omx_encoder;
 extern AVCodec ff_h264_qsv_encoder;
diff --git a/libavcodec/m264dec.c b/libavcodec/m264dec.c
new file mode 100644
index 0000000..f6cc65f
--- /dev/null
+++ b/libavcodec/m264dec.c
@@ -0,0 +1,357 @@ 
+/*
+ * M264 H.264 video decoder
+ *
+ * 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
+ * Matrox M264 card supports h.264 encoding and decoding.
+ */
+
+#include "decode.h"
+#include "cabac.h"
+#include "error_resilience.h"
+#include "h264_parse.h"
+#include "h264_ps.h"
+#include "h264_sei.h"
+#include "h2645_parse.h"
+#include "h264chroma.h"
+#include "h264dsp.h"
+#include "h264pred.h"
+#include "h264qpel.h"
+#include "internal.h"
+#include "mpegutils.h"
+#include "parser.h"
+#include "qpeldsp.h"
+#include "rectangle.h"
+#include "videodsp.h"
+#include "config.h"
+#include "libswscale/swscale.h"
+#include "libavutil/opt.h"
+#include "m264dec.h"
+#ifdef _WIN32
+#include "compat/w32dlfcn.h"
+#else
+#include <dlfcn.h>
+#endif
+
+typedef struct {
+   uint16_t input_width;
+   uint16_t input_height;
+   uint16_t output_width;
+   uint16_t output_height;
+   uint16_t scale;
+   uint16_t rate;
+   uint16_t gop_size;
+   uint32_t bitrate;
+   uint8_t  field_order;
+} M264DecoderInfo;
+
+typedef struct {
+    AVClass *class;
+    int (*init_m264_decoder)(void *decoder_info, void **m264_decoder_object);
+    int (*exit_m264_decoder)(void *m264_decoder_object);
+    int (*send_packet)(void *m264_decoder_object, void *extradata, unsigned long extradata_size, void *buffer, unsigned long buffer_size, double duration);
+    int (*receive_frame)(void *m264_decoder_object, void **buffer_context, void **buffer, unsigned long *buffer_size);
+    int (*release_frame_buffer)(void *m264_decoder_object, void *buffer_context);
+    void *lib_handle;
+    void *decoder_context;
+    int64_t frames;
+    int eof;
+    char *sps_pps;
+    int length_sps_pps;
+    AVBSFContext *ctx;
+    char *resize_expr;
+    struct {
+        int width;
+        int height;
+    } resize;
+} M264DecoderContext;
+
+int m264_mp4_to_annexb(AVCodecContext *avctx, AVPacket *packet)
+{
+    M264DecoderContext *m264_decoder_context = (M264DecoderContext *)avctx->priv_data;
+    int ret = 0;
+
+    if (m264_decoder_context->ctx) {
+        ret = av_bsf_send_packet(m264_decoder_context->ctx, packet);
+        if (ret < 0)
+            return ret;
+
+        ret = av_bsf_receive_packet(m264_decoder_context->ctx, packet);
+        if (ret < 0)
+            return ret;
+    }
+
+    return ret;
+}
+
+int m264_init_spspps_mp4(AVCodecContext *avctx)
+{
+    M264DecoderContext *m264_decoder_context = (M264DecoderContext *)avctx->priv_data;
+    int ret = 0;
+    const AVBitStreamFilter *filter = av_bsf_get_by_name("h264_mp4toannexb");
+    AVBSFContext *ctx = NULL;
+
+    ret = av_bsf_alloc(filter, &ctx);
+    if (ret < 0)
+        return ret;
+
+    ret = avcodec_parameters_from_context(ctx->par_in, avctx);
+    if (ret < 0)
+        return ret;
+
+    ret = av_bsf_init(ctx);
+    if (ret < 0)
+        return ret;
+
+    m264_decoder_context->ctx = ctx;
+
+    if (ctx->par_out->extradata_size > 0) {
+        m264_decoder_context->sps_pps = av_mallocz(ctx->par_out->extradata_size);
+        memcpy(m264_decoder_context->sps_pps, ctx->par_out->extradata, ctx->par_out->extradata_size);
+        m264_decoder_context->length_sps_pps = ctx->par_out->extradata_size;
+    }
+
+    return ret;
+}
+
+av_cold int ff_m264_decode_init(AVCodecContext *avctx)
+{
+    int ret = 0;
+    void *lib_handle;
+    M264DecoderContext *m264_decoder_context;
+    M264DecoderInfo decoder_info;
+
+    #ifdef _WIN32
+    lib_handle = dlopen("mvM264.dll", RTLD_LAZY);
+    #else
+    lib_handle = dlopen("libmvM264.so", RTLD_LAZY);
+    #endif
+
+    if (!lib_handle) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_DECODER_NOT_FOUND;
+    }
+
+    m264_decoder_context = avctx->priv_data;
+
+    m264_decoder_context->init_m264_decoder = dlsym(lib_handle, "m264_decoder_init");
+    if (!m264_decoder_context->init_m264_decoder) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_DECODER_NOT_FOUND;
+    }
+
+    m264_decoder_context->exit_m264_decoder = dlsym(lib_handle, "m264_decoder_exit");
+    if (!m264_decoder_context->exit_m264_decoder) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_DECODER_NOT_FOUND;
+    }
+
+    m264_decoder_context->send_packet = dlsym(lib_handle, "m264_decoder_send_packet");
+    if (!m264_decoder_context->send_packet) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_DECODER_NOT_FOUND;
+    }
+
+    m264_decoder_context->receive_frame = dlsym(lib_handle, "m264_decoder_receive_frame");
+    if (!m264_decoder_context->receive_frame) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_DECODER_NOT_FOUND;
+    }
+
+    m264_decoder_context->release_frame_buffer = dlsym(lib_handle, "m264_decoder_release_frame_buffer");
+    if (!m264_decoder_context->release_frame_buffer) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_DECODER_NOT_FOUND;
+    }
+
+    m264_decoder_context->lib_handle = lib_handle;
+    m264_decoder_context->eof = 0;
+
+    decoder_info.input_width = avctx->width;
+    decoder_info.input_height = avctx->height;
+
+    if (m264_decoder_context->resize_expr) {
+        if (sscanf(m264_decoder_context->resize_expr, "%dx%d", &m264_decoder_context->resize.width, &m264_decoder_context->resize.height) != 2) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid resize expressions\n");
+            m264_decoder_context->resize.width = avctx->width;
+            m264_decoder_context->resize.height = avctx->height;
+        }
+
+        if (m264_decoder_context->resize.height == -1)
+            m264_decoder_context->resize.height = (float)m264_decoder_context->resize.width * avctx->height / avctx->width;
+
+        avctx->width = m264_decoder_context->resize.width;
+        avctx->height = m264_decoder_context->resize.height;
+    }
+
+    decoder_info.output_width = avctx->width;
+    decoder_info.output_height = avctx->height;
+    decoder_info.scale = avctx->framerate.den;
+    decoder_info.rate = avctx->framerate.num;
+    decoder_info.field_order = (uint8_t)avctx->field_order;
+    av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->field_order is %d \n", avctx->field_order);
+    av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->width = %d, avctx->height = %d, avctx->framerate.num = %d, avctx->framerate.den = %d\n",
+                                 avctx->width, avctx->height, avctx->framerate.num, avctx->framerate.den);
+
+    ret = m264_decoder_context->init_m264_decoder(&decoder_info, &(m264_decoder_context->decoder_context));
+    if (ret < 0)
+        return ret;
+
+    avctx->priv_data = m264_decoder_context;
+    avctx->pix_fmt = AV_PIX_FMT_YUYV422; // m264 card only supports YUYV422 as input. 
+    avctx->bits_per_raw_sample = 8;
+
+    if (avctx->extradata_size > 0 && avctx->extradata)
+        ret = m264_init_spspps_mp4(avctx);
+
+    return ret;
+}
+
+int ff_m264_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+{
+    int ret = 0;
+    AVPacket pkt = {0};
+    void *buffer_context = NULL;
+    void *buffer = NULL;
+    unsigned long buffer_size = 0;
+    unsigned long line_size;
+    int line;
+    int actual_line_size;
+    unsigned char *srcmem,*dstmem;
+    long double duration = 0;
+
+    M264DecoderContext *m264_decoder_context = (M264DecoderContext *)avctx->priv_data;
+    ret = m264_decoder_context->receive_frame(m264_decoder_context->decoder_context, &buffer_context, &buffer, &buffer_size);
+    if (ret == -1) {
+        av_log(avctx, AV_LOG_DEBUG, "ff_m264_receive_frame: m264_decoder_context->receive_packet get eos, return AVERROR_EOF \n");
+        return AVERROR_EOF;
+    }
+
+    if (buffer_size > 0) {
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+            return ret;
+
+        line_size = buffer_size / avctx->height;
+        srcmem = (unsigned char *)buffer;
+        dstmem = (unsigned char *)frame->data[0];
+        actual_line_size = avctx->width * 2;
+
+        for (line = 0; line < avctx->height; line++) {
+            memcpy(dstmem, srcmem, actual_line_size);
+            dstmem += frame->linesize[0];
+            srcmem += line_size;
+        }
+
+        frame->pts = m264_decoder_context->frames * frame->pkt_duration;
+        m264_decoder_context->frames++;
+        av_log(avctx, AV_LOG_DEBUG, "ff_m264_receive_frame: m264_decoder_context->frames = %d\n", (int)m264_decoder_context->frames);
+        ret = m264_decoder_context->release_frame_buffer(m264_decoder_context->decoder_context, buffer_context);
+    } else {
+        if (m264_decoder_context->eof != 1) {
+            ret = ff_decode_get_packet(avctx, &pkt);
+            av_log(avctx, AV_LOG_DEBUG, "decoder: ff_m264_receive_frame: ff_decode_get_packet  pkt.size = %d\n", pkt.size);
+            if (ret < 0 && ret != AVERROR_EOF) 
+                return ret;
+        }
+
+        if (ret == AVERROR_EOF ) {
+            if (m264_decoder_context->eof != 1) {
+                pkt.data = NULL;
+                pkt.size = 0;
+                m264_decoder_context->eof = 1;
+                ret = m264_decoder_context->send_packet(m264_decoder_context->decoder_context, m264_decoder_context->sps_pps, m264_decoder_context->length_sps_pps, pkt.data, pkt.size, 0);
+            }
+        } else {
+            if (m264_decoder_context->eof != 1) {
+                av_log(avctx, AV_LOG_DEBUG, "decoder: ff_m264_receive_frame: pkt.side_data_elems = %d\n", pkt.side_data_elems);
+
+                if (pkt.data != NULL)
+                {
+                    ret = m264_mp4_to_annexb(avctx, &pkt);
+                    if (ret < 0)
+                        return ret;
+                }
+
+                duration = (long double)pkt.duration * avctx->pkt_timebase.num / avctx->pkt_timebase.den;
+
+                if (pkt.flags)
+                    ret = m264_decoder_context->send_packet(m264_decoder_context->decoder_context, m264_decoder_context->sps_pps, m264_decoder_context->length_sps_pps, pkt.data, pkt.size, duration);
+                else
+                    ret = m264_decoder_context->send_packet(m264_decoder_context->decoder_context, NULL , 0, pkt.data, pkt.size, duration);
+            }
+        }
+        av_packet_unref(&pkt);
+        ret = AVERROR(EAGAIN);
+    }
+    return ret;
+}
+
+int av_cold ff_m264_decode_close(AVCodecContext *avctx)
+{
+    M264DecoderContext *m264_decoder_context = (M264DecoderContext *)avctx->priv_data;
+
+    if (m264_decoder_context) {
+
+        if (m264_decoder_context->decoder_context) {
+            m264_decoder_context->exit_m264_decoder(m264_decoder_context->decoder_context);
+        }
+
+        if (m264_decoder_context->lib_handle) {
+            dlclose(m264_decoder_context->lib_handle);
+        }
+
+        if (m264_decoder_context->ctx) {
+            av_bsf_free(&m264_decoder_context->ctx);
+        }
+
+        av_free(m264_decoder_context->sps_pps);
+    }
+
+    return 0;
+}
+
+#define OFFSET(x) offsetof(M264DecoderContext, x)
+#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption h264_m264_decoder_options[] = {
+    { "resize",   "Resize (width)x(height)", OFFSET(resize_expr), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD,"resize" },
+    { NULL }
+};
+
+static const AVClass h264_m264_decoder_class = {
+    .class_name = "h264_m264_decoder",
+    .item_name  = av_default_item_name,
+    .option     = h264_m264_decoder_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_h264_m264_decoder = {
+    .name           = "m264",
+    .long_name      = NULL_IF_CONFIG_SMALL("Matrox M264 Codec"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H264,
+    .init           = ff_m264_decode_init,
+    .receive_frame  = ff_m264_receive_frame,
+    .close          = ff_m264_decode_close,
+    .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
+    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
+    .priv_data_size = sizeof(M264DecoderContext),
+    .priv_class     = &h264_m264_decoder_class,
+    .wrapper_name   = "m264",
+};
diff --git a/libavcodec/m264dec.h b/libavcodec/m264dec.h
new file mode 100644
index 0000000..27ef7a7
--- /dev/null
+++ b/libavcodec/m264dec.h
@@ -0,0 +1,40 @@ 
+/*
+ * M264 H.264 video decoder
+ *
+ * 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
+ * Matrox M264 card supports h.264 encoding and decoding.
+ */
+
+#ifndef AVCODEC_M264DEC_H
+#define AVCODEC_M264DEC_H
+
+#include "libavutil/fifo.h"
+
+#include "avcodec.h"
+
+int ff_m264_decode_init(AVCodecContext *avctx);
+int ff_m264_decode_close(AVCodecContext *avctx);
+int ff_m264_receive_frame(AVCodecContext *avctx, AVFrame *frame);
+int m264_init_spspps_mp4(AVCodecContext *avctx);
+int m264_mp4_to_annexb(AVCodecContext *avctx, AVPacket *packet);
+
+#endif //AVCODEC_M264DEC_H
+
diff --git a/libavcodec/m264enc.c b/libavcodec/m264enc.c
new file mode 100644
index 0000000..ca2c097
--- /dev/null
+++ b/libavcodec/m264enc.c
@@ -0,0 +1,335 @@ 
+/*
+ * M264 H.264 video encoder
+ *
+ * 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
+ * Matrox M264 card supports h.264 encoding and decoding.
+ */
+
+#include "libswscale/swscale.h"
+#include "m264enc.h"
+#include "internal.h"
+#include "profiles.h"
+#include "libavutil/opt.h"
+
+#ifdef _WIN32
+#include "compat/w32dlfcn.h"
+#else
+#include <dlfcn.h>
+#endif
+
+typedef struct {
+    uint16_t width;
+    uint16_t height;
+    uint16_t scale;
+    uint16_t rate;
+    uint16_t profile;
+    uint16_t level;
+    uint16_t gop_size;
+    uint32_t bitrate;
+} M264EncoderInfo;
+
+typedef struct {
+    AVClass *class;
+    int (*init_m264_encoder)(void *encoder_info, void **m264_encoder_object);
+    int (*exit_m264_encoder)(void *m264_encoder_object);
+    int (*get_extradata)(void *m264_encoder_object, void **extradata, unsigned long *extradata_size);
+    int (*get_uncompressed_buffer)(void *m264_encoder_object, void **buffer_context, void **buffer, unsigned long *buffer_size);
+    int (*send_frame)(void *m264_encoder_object, void *buffer_context, int polarity);
+    int (*receive_packet)(void *m264_encoder_object, void *buffer_context, void **buffer, unsigned long *buffer_size, int32_t *pts, int32_t *dts, int8_t *key);
+    int (*release_packet_buffer)(void *m264_encoder_object, void *buffer_context);
+    void *lib_handle;
+    void *encoder_context;
+    struct SwsContext *sw_context;
+    int profile;
+    int level;
+} M264EncoderContext;
+
+av_cold int ff_m264_encode_init(AVCodecContext *avctx)
+{
+    int ret = 0;
+    void *lib_handle;
+    M264EncoderContext *m264_encoder_context;
+    M264EncoderInfo encoder_info;
+    void *extradata = NULL;
+    unsigned long extradata_size = 0;
+
+    #ifdef _WIN32
+    lib_handle = dlopen("mvM264.dll", RTLD_LAZY);
+    #else
+    lib_handle = dlopen("libmvM264.so", RTLD_LAZY);
+    #endif
+
+    if (!lib_handle) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_ENCODER_NOT_FOUND;
+    }
+
+    m264_encoder_context = avctx->priv_data;
+
+    m264_encoder_context->init_m264_encoder = dlsym(lib_handle, "m264_encoder_init");
+    if (!m264_encoder_context->init_m264_encoder) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_ENCODER_NOT_FOUND;
+    }
+
+    m264_encoder_context->exit_m264_encoder = dlsym(lib_handle, "m264_encoder_exit");
+    if (!m264_encoder_context->exit_m264_encoder) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_ENCODER_NOT_FOUND;
+    }
+
+    m264_encoder_context->get_extradata = dlsym(lib_handle, "m264_encoder_get_extradata");
+    if (!m264_encoder_context->get_extradata) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_ENCODER_NOT_FOUND;
+    }
+
+    m264_encoder_context->get_uncompressed_buffer = dlsym(lib_handle, "m264_encoder_get_uncompressed_buffer");
+    if (!m264_encoder_context->get_uncompressed_buffer) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_ENCODER_NOT_FOUND;
+    }
+
+    m264_encoder_context->send_frame = dlsym(lib_handle, "m264_encoder_send_frame");
+    if (!m264_encoder_context->send_frame) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_ENCODER_NOT_FOUND;
+    }
+
+    m264_encoder_context->receive_packet = dlsym(lib_handle, "m264_encoder_receive_packet");
+    if (!m264_encoder_context->receive_packet) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_ENCODER_NOT_FOUND;
+    }
+
+    m264_encoder_context->release_packet_buffer = dlsym(lib_handle, "m264_encoder_release_packet_buffer");
+    if (!m264_encoder_context->release_packet_buffer) {
+        av_log(avctx, AV_LOG_ERROR, "failed to load mvM264\n");
+        return AVERROR_ENCODER_NOT_FOUND;
+    }
+
+    m264_encoder_context->lib_handle = lib_handle;
+
+    encoder_info.width = avctx->width;
+    encoder_info.height = avctx->height;
+    encoder_info.rate = avctx->framerate.num;
+    encoder_info.scale = avctx->framerate.den;
+    encoder_info.profile = m264_encoder_context->profile;
+    encoder_info.level = m264_encoder_context->level;
+    encoder_info.gop_size = avctx->gop_size;
+    encoder_info.bitrate = avctx->bit_rate;
+    av_log(avctx, AV_LOG_DEBUG, "m264_encode_init_h264: avctx->width = %d, avctx->height = %d, avctx->framerate.num = %d, avctx->framerate.den = %d, avctx->gop_size = %d, avctx->bit_rate = %" PRId64 "\n",
+                                 avctx->width, avctx->height, avctx->framerate.num, avctx->framerate.den, avctx->gop_size, avctx->bit_rate);
+
+    ret = m264_encoder_context->init_m264_encoder(&encoder_info, &(m264_encoder_context->encoder_context));
+    if (ret < 0)
+        return ret;
+
+    if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
+        ret = m264_encoder_context->get_extradata(m264_encoder_context->encoder_context, &extradata, &extradata_size);
+        if (ret < 0)
+            return ret;
+
+        if (extradata_size > 0) {
+            avctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
+            if (!avctx->extradata)
+                return AVERROR(ENOMEM);
+            memcpy(avctx->extradata, extradata, extradata_size);
+            avctx->extradata_size = extradata_size;
+        }
+    }
+
+    return ret;
+}
+
+int ff_m264_send_frame(AVCodecContext *avctx, const AVFrame *frame)
+{
+    int ret = 0;
+    enum AVPixelFormat src_pixel_format;
+    enum AVPixelFormat dest_pixel_format;
+    uint8_t *dst[1];
+    int dst_stride[1];
+    void *buffer_context;
+    unsigned long buffer_size;
+    unsigned long line_size;
+    int line;
+    int actual_line_size;
+    unsigned char *srcmem,*dstmem;
+
+    M264EncoderContext *m264_encoder_context = (M264EncoderContext *)avctx->priv_data;
+
+    if (frame) {
+        src_pixel_format = (enum AVPixelFormat)frame->format;
+        dest_pixel_format = AV_PIX_FMT_YUYV422;
+        if (m264_encoder_context->sw_context == NULL) {
+            m264_encoder_context->sw_context = sws_getContext(frame->width, frame->height, src_pixel_format, frame->width, frame->height,
+                                                      dest_pixel_format, SWS_BILINEAR, NULL, NULL, NULL);
+            if (!m264_encoder_context->sw_context) {
+                av_log(avctx, AV_LOG_ERROR, "failed to get sw_context\n");
+                ret = -1;
+                return ret;
+            }
+        }
+        ret = m264_encoder_context->get_uncompressed_buffer(m264_encoder_context->encoder_context, &buffer_context, (void **)&dst[0], &buffer_size);
+        if (ret < 0)
+            return ret;
+
+        dst_stride[0] = buffer_size / avctx->height;
+        if (src_pixel_format != AV_PIX_FMT_YUYV422) {
+            ret = sws_scale(m264_encoder_context->sw_context, (const uint8_t * const*)frame->data, frame->linesize, 0, frame->height, dst, dst_stride);
+            if (ret < 0)
+                return ret;
+        } else {
+            line_size = buffer_size / avctx->height;
+            dstmem = (unsigned char *)dst[0];
+            srcmem = (unsigned char *)frame->data[0];
+            actual_line_size = avctx->width * 2;
+
+            for (line = 0; line < avctx->height; line++) {
+                memcpy(dstmem, srcmem, actual_line_size);
+                srcmem += frame->linesize[0];
+                dstmem += line_size;
+            }
+        }
+        av_log(avctx, AV_LOG_DEBUG, "ff_m264_send_frame: frame->width = %d, frame->height = %d\n", frame->width, frame->height);
+        ret = m264_encoder_context->send_frame(m264_encoder_context->encoder_context, buffer_context, 0);
+        if (ret < 0)
+            return ret;
+    } else {
+        av_log(avctx, AV_LOG_DEBUG, "ff_m264_send_frame: frame is null. eof\n");
+        ret = m264_encoder_context->send_frame(m264_encoder_context->encoder_context, NULL, 0);
+        if (ret < 0)
+            return ret;
+    }
+    return ret;
+}
+
+int ff_m264_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
+{
+    int ret;
+    M264EncoderContext *m264_encoder_context = (M264EncoderContext *)avctx->priv_data;
+    void *buffer_context = NULL;
+    void *buffer = NULL;
+    unsigned long buffer_size = 0;
+    int32_t pts, dts;
+    int8_t key;
+
+    ret = m264_encoder_context->receive_packet(m264_encoder_context->encoder_context, &buffer_context, &buffer, &buffer_size, &pts, &dts, &key);
+    if (ret == -1) {
+        av_log(avctx, AV_LOG_DEBUG, "ff_m264_receive_packet: m264_encoder_context->receive_packet get eos, return AVERROR_EOF\n");
+        return AVERROR_EOF;
+    } else if (buffer_size == 0) {
+        return AVERROR(EAGAIN);
+    }
+
+    av_log(avctx, AV_LOG_DEBUG, "ff_m264_receive_packet  m264_encoder_context->receive_packet buffer_size = %d\n", (int)buffer_size); 
+
+    ret = ff_alloc_packet2(avctx, avpkt, buffer_size, 0);
+    if (ret < 0)
+        return ret;
+
+    memcpy(avpkt->data, buffer, buffer_size);
+
+    avpkt->dts = dts - 2;
+    avpkt->pts = pts;
+    avpkt->flags = key ? AV_PKT_FLAG_KEY : 0;
+    avpkt->duration = 1;
+
+    ret = m264_encoder_context->release_packet_buffer(m264_encoder_context->encoder_context, buffer_context);
+    if (ret < 0)
+        return ret;
+
+    return ret;
+}
+
+int av_cold ff_m264_encode_close(AVCodecContext *avctx)
+{
+    M264EncoderContext *m264_encoder_context = (M264EncoderContext *)avctx->priv_data;
+
+    if (m264_encoder_context) {
+        if (m264_encoder_context->encoder_context) {
+            m264_encoder_context->exit_m264_encoder(m264_encoder_context->encoder_context);
+        }
+
+        if (m264_encoder_context->sw_context) {
+            sws_freeContext(m264_encoder_context->sw_context);
+        }
+
+        if (m264_encoder_context->lib_handle) {
+            dlclose(m264_encoder_context->lib_handle);
+        }
+    }
+
+    return 0;
+}
+
+#define OFFSET(x) offsetof(M264EncoderContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption h264_m264_encoder_options[] = {
+    { "profile",      "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT,{ .i64 = FF_PROFILE_H264_MAIN }, FF_PROFILE_H264_BASELINE, FF_PROFILE_H264_HIGH_444, VE, "profile" },
+    { "baseline",     "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_BASELINE },  0, 0, VE, "profile" },
+    { "main",         "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_MAIN },      0, 0, VE, "profile" },
+    { "high",         "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_HIGH },      0, 0, VE, "profile" },
+    { "high10",       "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_HIGH_10 },   0, 0, VE, "profile" },
+    { "high422",      "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_HIGH_422 },  0, 0, VE, "profile" },
+    { "level",        "Profile Level",            OFFSET(level),                  AV_OPT_TYPE_INT,   { .i64 =  0 }, 0, 62, VE, "level" },
+    { "1.b",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 =  9 }, 0, 0,  VE, "level" },
+    { "1",            "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 10 }, 0, 0,  VE, "level" },
+    { "1.1",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 11 }, 0, 0,  VE, "level" },
+    { "1.2",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 12 }, 0, 0,  VE, "level" },
+    { "1.3",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 13 }, 0, 0,  VE, "level" },
+    { "2.0",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 20 }, 0, 0,  VE, "level" },
+    { "2.1",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 21 }, 0, 0,  VE, "level" },
+    { "2.2",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 22 }, 0, 0,  VE, "level" },
+    { "3.0",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 30 }, 0, 0,  VE, "level" },
+    { "3.1",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 31 }, 0, 0,  VE, "level" },
+    { "3.2",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 32 }, 0, 0,  VE, "level" },
+    { "4.0",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 40 }, 0, 0,  VE, "level" },
+    { "4.1",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 41 }, 0, 0,  VE, "level" },
+    { "4.2",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 42 }, 0, 0,  VE, "level" },
+    { "5.0",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 50 }, 0, 0,  VE, "level" },
+    { "5.1",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 51 }, 0, 0,  VE, "level" },
+    { "5.2",          "",                                   0,                    AV_OPT_TYPE_CONST, { .i64 = 52 }, 0, 0,  VE, "level" },
+    { NULL },
+};
+
+static const AVClass h264_m264_encoder_class = {
+    .class_name = "h264_m264_encoder",
+    .item_name  = av_default_item_name,
+    .option     = h264_m264_encoder_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_h264_m264_encoder = {
+    .name           = "m264",
+    .long_name      = NULL_IF_CONFIG_SMALL("Matrox M264 Codec"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H264,
+    .init           = ff_m264_encode_init,
+    .send_frame     = ff_m264_send_frame,
+    .receive_packet = ff_m264_receive_packet,
+    .close          = ff_m264_encode_close,
+    .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
+    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
+    .priv_data_size = sizeof(M264EncoderContext),
+    .priv_class     = &h264_m264_encoder_class,
+    .wrapper_name   = "m264",
+};
diff --git a/libavcodec/m264enc.h b/libavcodec/m264enc.h
new file mode 100644
index 0000000..0c44b32
--- /dev/null
+++ b/libavcodec/m264enc.h
@@ -0,0 +1,38 @@ 
+/*
+ * M264 H.264 video encoder
+ *
+ * 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
+ * Matrox M264 card supports h.264 encoding and decoding.
+ */
+
+#ifndef AVCODEC_M264ENC_H
+#define AVCODEC_M264ENC_H
+
+#include "libavutil/fifo.h"
+
+#include "avcodec.h"
+
+int ff_m264_encode_init(AVCodecContext *avctx);
+int ff_m264_encode_close(AVCodecContext *avctx);
+int ff_m264_send_frame(AVCodecContext *avctx, const AVFrame *frame);
+int ff_m264_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
+
+#endif //AVCODEC_AMAVCODEC_M264ENC_H
-- 
2.7.4