[FFmpeg-devel] patch for a new H.264 codec

Moritz Barsnick barsnick at gmx.net
Mon Feb 25 23:21:32 EET 2019


Hi Yufei,
before providing large patches here, do read this mailing list and the
ffmpeg codebase for a while. It will help you to understand the
process, and to understand how ffmpeg's sources are organized.

I'm sure you missed this:
https://www.ffmpeg.org/developer.html

Read all of it thoroughly.

The content of this section:
https://www.ffmpeg.org/developer.html#Coding-Rules-1
especially comes to mind. Your code uses totally different formatting
than the rest of the ffmpeg codebase. You should take a look around as
see how others do it, and what that style guide says.

Apart from that: Everything that Nicolas wrote.

In addition this:

On Mon, Feb 25, 2019 at 19:49:43 +0000, Yufei He wrote:
> index c90f119..f70368b 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -11,6 +11,7 @@ version <next>:
>  - dhav demuxer
>  - PCM-DVD encoder
>  - GIF parser
> +- M264 encoder

Your patch is against an at least two months old version of ffmpeg git.
Please merge it to latest git HEAD and create a new patch. Your patch
won't apply currently, and therefore noone will bother to test it.

And even if I try to work around that, here's what happens:

LD      ffmpeg_g
/usr/bin/ld: libavcodec/libavcodec.a(m264enc.o): in function `ff_m264_encode_init':
/home/barsnick/Development/ffmpeg-stuff/ffmpeg/libavcodec/m264enc.c:98: undefined reference to `dlopen'
/usr/bin/ld: /home/barsnick/Development/ffmpeg-stuff/ffmpeg/libavcodec/m264enc.c:108: undefined reference to `dlsym'
/usr/bin/ld: /home/barsnick/Development/ffmpeg-stuff/ffmpeg/libavcodec/m264enc.c:109: undefined reference to `dlsym'
/usr/bin/ld: /home/barsnick/Development/ffmpeg-stuff/ffmpeg/libavcodec/m264enc.c:110: undefined reference to `dlsym'
/usr/bin/ld: /home/barsnick/Development/ffmpeg-stuff/ffmpeg/libavcodec/m264enc.c:111: undefined reference to `dlsym'
/usr/bin/ld: /home/barsnick/Development/ffmpeg-stuff/ffmpeg/libavcodec/m264enc.c:112: undefined reference to `dlsym'
/usr/bin/ld: libavcodec/libavcodec.a(m264enc.o):/home/barsnick/Development/ffmpeg-stuff/ffmpeg/libavcodec/m264enc.c:113: more undefined references to `dlsym' follow
/usr/bin/ld: libavcodec/libavcodec.a(m264enc.o): in function `ff_m264_encode_close':
/home/barsnick/Development/ffmpeg-stuff/ffmpeg/libavcodec/m264enc.c:264: undefined reference to `dlclose'
collect2: error: ld returned 1 exit status
make: *** [Makefile:108: ffmpeg_g] Error 1

You need to get your dependencies right.

> +   if(*got_output)        
> +   {
> +      if(decoded_frame->width == 0)
> +      {
> +         av_log(NULL, AV_LOG_DEBUG, "Frame parameters mismatch context %d,%d,%d != %d,%d,%d\n",
> +               decoded_frame->width,
> +               decoded_frame->height,
> +               decoded_frame->format,
> +               ist->dec_ctx->width,
> +               ist->dec_ctx->height,
> +               ist->dec_ctx->pix_fmt);
> +      }
> +   }

This is debug code and does not belong into a released codec.
Furthermore, ffmpeg provides av_log() functions.

> index 0000000..dc1852f
> --- /dev/null
> +++ b/libavcodec/.vscode/settings.json

Don't commit your local development environment's settings, please.

>  OBJS-$(CONFIG_DNXHD_DECODER)           += dnxhddec.o dnxhddata.o
>  OBJS-$(CONFIG_DNXHD_ENCODER)           += dnxhdenc.o dnxhddata.o
> +OBJS-$(CONFIG_M264_ENCODER)            += m264enc.o
> +OBJS-$(CONFIG_M264_DECODER)            += m264dec.o
>  OBJS-$(CONFIG_DOLBY_E_DECODER)         += dolby_e.o kbdwin.o
>  OBJS-$(CONFIG_DPX_DECODER)             += dpx.o

Do you realize that the rest of this list is in alphabetical order?

>  OBJS-$(CONFIG_VP9_SUPERFRAME_SPLIT_BSF)   += vp9_superframe_split_bsf.o
>  
> +
> +
> +
>  # thread libraries

Why do you add useless empty lines, and commit them?

>  extern AVCodec ff_dnxhd_encoder;
>  extern AVCodec ff_dnxhd_decoder;
> +extern AVCodec ff_m264_encoder;
> +extern AVCodec ff_m264_decoder;
>  extern AVCodec ff_dpx_encoder;
>  extern AVCodec ff_dpx_decoder;

Alphabetical order, again.

>      if (c)
> -        *opaque = (void*)(i + 1);
> -
> +      *opaque = (void*)(i + 1);
> +      
>      return c;

Useless change. And please don't ever leave whitespace at your line
endings, it won't be accepted. (Your IDE surely can fix this for you.)

> +#define FF_PROFILE_M264             0

What is this?

> +        .props     = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER,
> +        .profiles  = NULL_IF_CONFIG_SMALL(ff_h264_profiles),

Does the encoder even honor any of the profiles?

> +   #ifdef _WIN32
> +   av_log(avctx, AV_LOG_DEBUG, "_WIN32\n");
> +   #elif defined _WIN64
> +   av_log(avctx, AV_LOG_DEBUG, "_WIN64\n");
> +   #else
> +   av_log(avctx, AV_LOG_DEBUG, "linux\n");
> +   #endif

What for?

> +#ifdef _WIN32
> +   lib_handle = dlopen("mvM264Ffmpeg.dll", RTLD_LAZY);
> +#else   
> +   lib_handle = dlopen("libmvM264Ffmpeg.so", RTLD_LAZY);
> +#endif

I'm not sure this is acceptable within ffmpeg.

> +   if (!lib_handle)
> +   {
> +      av_log(avctx, AV_LOG_ERROR, "failed to load mvM264ffmpeg\n");
> +   }
> +
> +   m264_decoder =  av_mallocz(sizeof(M264Decoder));
> +
> +   m264_decoder->init_m264_decoder = dlsym(lib_handle, "m264_ffmpeg_decoder_init");
> +   m264_decoder->exit_m264_decoder = dlsym(lib_handle, "m264_ffmpeg_decoder_exit");
> +   m264_decoder->send_packet = dlsym(lib_handle, "m264_ffmpeg_decoder_send_packet");
> +   m264_decoder->receive_frame = dlsym(lib_handle, "m264_ffmpeg_decoder_receive_frame");
> +   m264_decoder->release_frame_buffer = dlsym(lib_handle, "m264_ffmpeg_decoder_release_frame_buffer");
> +   m264_decoder->lib_handle = lib_handle;

If it fails to load, you just continue? Honestly?

> +   switch (avctx->field_order)
> +   {
> +      case AV_FIELD_UNKNOWN: 
> +         av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->field_order is AV_FIELD_UNKNOWN \n");
> +         break;
> +      case AV_FIELD_PROGRESSIVE: 
> +         av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->field_order is AV_FIELD_PROGRESSIVE \n");
> +         break;
> +      case AV_FIELD_TT: 
> +         av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->field_order is AV_FIELD_TT \n");
> +         break;
> +      case AV_FIELD_BB: 
> +         av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->field_order is AV_FIELD_BB \n");
> +         break;
> +      case AV_FIELD_TB: 
> +         av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->field_order is AV_FIELD_TB \n");
> +         break;
> +      case AV_FIELD_BT: 
> +         av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->field_order is AV_FIELD_BT \n");
> +         break;
> +      default:
> +         av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->field_order is default \n");
> +         assert(false);
> +         break;
> +   }

Probably much too noisy. And coded way too complicated.

> +   av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->width = %d\n", avctx->width);
> +   av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->height = %d\n", avctx->height);
> +   av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->framerate.num = %d\n", avctx->framerate.num);
> +   av_log(avctx, AV_LOG_DEBUG, "m264_decode_init_h264: avctx->framerate.den = %d\n", avctx->framerate.den);

Probably much too noisy. And even if, could be in just one line.

> +   avctx->pix_fmt = AV_PIX_FMT_YUYV422;

That's all it supports?

> +   av_log(avctx, AV_LOG_DEBUG, "ff_m264_decode_close: 2 \n");

"2"?

> +++ b/libavcodec/m264enc.c
[...]
> +#include "m264enc.h"
[...]
> +#include "m264enc.h"

Twice? Please, come on. If even such simple things are done
incorrectly, how do you expect anyone to take the time to review the
rest of the code?

> +#ifdef _WIN32
> +   lib_handle = dlopen("mvM264Ffmpeg.dll", RTLD_LAZY);
> +#else   
> +   lib_handle = dlopen("libmvM264Ffmpeg.so", RTLD_LAZY);
> +#endif

I'm not sure this is acceptable within ffmpeg.

> +   printf("m264_encode_init_h264: avctx->width = %d\n", avctx->width);
> +   printf("m264_encode_init_h264: avctx->height = %d\n", avctx->height);
> +   printf("m264_encode_init_h264: avctx->framerate.num = %d\n", avctx->framerate.num);
> +   printf("m264_encode_init_h264: avctx->framerate.den = %d\n", avctx->framerate.den);
> +   printf("m264_encode_init_h264: avctx->gop_size = %d\n", avctx->gop_size);
> +   printf("m264_encode_init_h264: avctx->bit_rate = %" PRId64 "\n", avctx->bit_rate);

This is debug code and does not belong into a released codec.
Furthermore, ffmpeg provides av_log() functions.

> +      {
> +         result = sws_scale(m264_encoder->sw_context, (const uint8_t * const*)frame->data, frame->linesize, 0, frame->height, dst, dst_stride);
> +      }

I'm sure an eventual dependency to sws_scale must be registered in
configure.

> +   av_log(avctx, AV_LOG_DEBUG, "ff_m264_encode_close 1");

"1"?


And apart from this superficial review, there are probably quite a lot
of other quality issues.

Moritz


More information about the ffmpeg-devel mailing list