acowley / ffmpeg-light

Minimal Haskell bindings to the FFmpeg library
BSD 3-Clause "New" or "Revised" License
67 stars 29 forks source link

Can't encode to jpeg, mjpeg codec refuses to accept `yuv420p` pixel format #67

Open babababag opened 3 years ago

babababag commented 3 years ago

Jpeg output is broken for me on Debian 11.

Example: take Transcode.hs from the demo folder and replace line 34 with below to specify jpeg output. let ep = FF.EncodingParams (fromIntegral w) (fromIntegral h) 30 (Just FF.avCodecIdMjpeg) Nothing "" (Just "mjpeg")

This is what I get:

$ ./Transcode in.jpg out.jpg
[swscaler @ 0x26777c0] deprecated pixel format used, make sure you did set range correctly
[mjpeg @ 0x26923c0] Specified pixel format yuv420p is invalid or not supported
Transcode: Couldn't open codec
CallStack (from HasCallStack):
  error, called at src/Codec/FFmpeg/Encode.hsc:325:21 in ffmpeg-light-0.14.0-BlGBxINPYl8FPzWDcKbKCe:Codec.FFmpeg.Encode

compared to the what actual ffmpeg says when you specify yuv420p and jpeg:

$ ffmpeg -loglevel debug -i in.jpg -pix_fmt yuv420p out.jpg
[graph 0 input from stream 0:0 @ 0x5626d1d602c0] Setting 'pix_fmt' to value '14'
Incompatible pixel format 'yuv420p' for codec 'mjpeg', auto-selecting format 'yuvj420p'
[format @ 0x5626d1d61080] Setting 'pix_fmts' to value 'yuvj420p'
[swscaler @ 0x5626d1dccc00] deprecated pixel format used, make sure you did set range correctly

FFmpeg auto-selects yuvj420p over yuv420p because apparently yuv420p has the wrong color range for jpeg.

I found these lines in my copy of /usr/include/x86_64-linux-gnu/libavutil/pixfmt.h

AV_PIX_FMT_YUVJ420P,  ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting color_range
AV_PIX_FMT_YUVJ422P,  ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting color_range
AV_PIX_FMT_YUVJ444P,  ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting color_range

but I couldn't find a way to use those colorspaces or set the color range here.