]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/mjpegenc: Include all supported pix_fmts in mpegenc pix_fmts
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>
Tue, 6 Apr 2021 01:01:14 +0000 (03:01 +0200)
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>
Sat, 10 Apr 2021 01:48:41 +0000 (03:48 +0200)
Currently said list contains only the pixel formats that are always
supported irrespective of the range and the value of
strict_std_compliance. This makes the MJPEG encoder an outlier as all
other codecs put all potentially supported pixel formats into said list
and error out if the chosen pixel format is unsupported. This commit
brings it therefore in line with the other encoders.

The behaviour of fftools/ffmpeg_filter.c has been preserved. A more
informed decision would be possible if colour range were available
at this point, but it isn't.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
fftools/ffmpeg_filter.c
libavcodec/encode.c
libavcodec/ljpegenc.c
libavcodec/mjpegenc.c
libavcodec/mjpegenc_common.c
libavcodec/mjpegenc_common.h
libavcodec/mpegvideo_enc.c

index 4ab769c07b9a4c36cf50238b366ff062d844d868..5c44b75eff07591b1d1bd676f3d6318157dd6e54 100644 (file)
 #include "libavutil/imgutils.h"
 #include "libavutil/samplefmt.h"
 
-static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum AVCodecID codec_id, const enum AVPixelFormat default_formats[])
+// FIXME: YUV420P etc. are actually supported with full color range,
+// yet the latter information isn't available here.
+static const enum AVPixelFormat *get_compliance_normal_pix_fmts(enum AVCodecID codec_id, const enum AVPixelFormat default_formats[])
 {
     static const enum AVPixelFormat mjpeg_formats[] =
         { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
-          AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,
           AV_PIX_FMT_NONE };
-    static const enum AVPixelFormat ljpeg_formats[] =
-        { AV_PIX_FMT_BGR24   , AV_PIX_FMT_BGRA    , AV_PIX_FMT_BGR0,
-          AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
-          AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P,
-          AV_PIX_FMT_NONE};
 
     if (codec_id == AV_CODEC_ID_MJPEG) {
         return mjpeg_formats;
-    } else if (codec_id == AV_CODEC_ID_LJPEG) {
-        return ljpeg_formats;
     } else {
         return default_formats;
     }
@@ -70,8 +64,8 @@ static enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx
         int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
         enum AVPixelFormat best= AV_PIX_FMT_NONE;
 
-        if (enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
-            p = get_compliance_unofficial_pix_fmts(enc_ctx->codec_id, p);
+        if (enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
+            p = get_compliance_normal_pix_fmts(enc_ctx->codec_id, p);
         }
         for (; *p != AV_PIX_FMT_NONE; p++) {
             best = av_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
@@ -118,8 +112,8 @@ static char *choose_pix_fmts(OutputFilter *ofilter)
             exit_program(1);
 
         p = ost->enc->pix_fmts;
-        if (ost->enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
-            p = get_compliance_unofficial_pix_fmts(ost->enc_ctx->codec_id, p);
+        if (ost->enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
+            p = get_compliance_normal_pix_fmts(ost->enc_ctx->codec_id, p);
         }
 
         for (; *p != AV_PIX_FMT_NONE; p++) {
index 89df5235dafdd56a5f5154cbebc50a2f65dfeeb6..9a4140f91aca6859f642b87875c9eb3abea1430d 100644 (file)
@@ -564,9 +564,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
         for (i = 0; avctx->codec->pix_fmts[i] != AV_PIX_FMT_NONE; i++)
             if (avctx->pix_fmt == avctx->codec->pix_fmts[i])
                 break;
-        if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE
-            && !(avctx->codec_id == AV_CODEC_ID_MJPEG
-                 && avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL)) {
+        if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE) {
             char buf[128];
             snprintf(buf, sizeof(buf), "%d", avctx->pix_fmt);
             av_log(avctx, AV_LOG_ERROR, "Specified pixel format %s is invalid or not supported\n",
index dd91c729d4313bcc83389a9be383cb53fca19651..74a2cdcc462571859a4d9a5bfc5d6f89f4e8a41f 100644 (file)
@@ -289,19 +289,11 @@ static av_cold int ljpeg_encode_close(AVCodecContext *avctx)
 
 static av_cold int ljpeg_encode_init(AVCodecContext *avctx)
 {
+    int ret = ff_mjpeg_encode_check_pix_fmt(avctx);
     LJpegEncContext *s = avctx->priv_data;
 
-    if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
-         avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
-         avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
-         avctx->color_range == AVCOL_RANGE_MPEG) &&
-        avctx->color_range != AVCOL_RANGE_JPEG   &&
-        avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Non full-range YUV is non-standard, set strict_std_compliance "
-               "to at most unofficial to use it.\n");
-        return AVERROR(EINVAL);
-    }
+    if (ret < 0)
+        return ret;
 
 #if FF_API_CODED_FRAME
 FF_DISABLE_DEPRECATION_WARNINGS
index e5d2e24d66c256ea4caac574d939f48077123962..3cff50abdbcd894f6d21c228845091c1ce20627f 100644 (file)
@@ -261,9 +261,16 @@ static int alloc_huffman(MpegEncContext *s)
 av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
 {
     MJpegContext *m;
+    int ret;
 
     av_assert0(s->slice_context_count == 1);
 
+    /* The following check is automatically true for AMV,
+     * but it doesn't hurt either. */
+    ret = ff_mjpeg_encode_check_pix_fmt(s->avctx);
+    if (ret < 0)
+        return ret;
+
     if (s->width > 65500 || s->height > 65500) {
         av_log(s, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n");
         return AVERROR(EINVAL);
@@ -609,7 +616,9 @@ AVCodec ff_mjpeg_encoder = {
     .capabilities   = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .pix_fmts       = (const enum AVPixelFormat[]) {
-        AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE
+        AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
+        AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_NONE
     },
     .priv_class     = &mjpeg_class,
     .profiles       = NULL_IF_CONFIG_SMALL(ff_mjpeg_profiles),
index 3eae9b7d0f0c895578b6d696147c7563f52accd2..c1b842d547fa250e04da74f02e0d82f9555a69fb 100644 (file)
@@ -436,3 +436,19 @@ void ff_mjpeg_encode_dc(PutBitContext *pb, int val,
         put_sbits(pb, nbits, mant);
     }
 }
+
+int ff_mjpeg_encode_check_pix_fmt(AVCodecContext *avctx)
+{
+    if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL &&
+        avctx->color_range != AVCOL_RANGE_JPEG &&
+        (avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
+         avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
+         avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
+         avctx->color_range == AVCOL_RANGE_MPEG)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Non full-range YUV is non-standard, set strict_std_compliance "
+               "to at most unofficial to use it.\n");
+        return AVERROR(EINVAL);
+    }
+    return 0;
+}
index b4f8a08e118d74423e5679b7e4617e7faa84ad03..76c236d835750c998427620a38a59b626f0af13a 100644 (file)
@@ -41,4 +41,6 @@ void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[4], int vsample[4
 void ff_mjpeg_encode_dc(PutBitContext *pb, int val,
                         uint8_t *huff_size, uint16_t *huff_code);
 
+int ff_mjpeg_encode_check_pix_fmt(AVCodecContext *avctx);
+
 #endif /* AVCODEC_MJPEGENC_COMMON_H */
index 862e3450171ba1088de3df0ca68f0e7d0fd64f97..1f8fc8d8b8b7f3c6a962e621c89bb0d7d980f22e 100644 (file)
@@ -297,36 +297,10 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
     AVCPBProperties *cpb_props;
-    int i, ret, format_supported;
+    int i, ret;
 
     mpv_encode_defaults(s);
 
-    switch (avctx->codec_id) {
-    case AV_CODEC_ID_MJPEG:
-        format_supported = 0;
-        /* JPEG color space */
-        if (avctx->pix_fmt == AV_PIX_FMT_YUVJ420P ||
-            avctx->pix_fmt == AV_PIX_FMT_YUVJ422P ||
-            avctx->pix_fmt == AV_PIX_FMT_YUVJ444P ||
-            (avctx->color_range == AVCOL_RANGE_JPEG &&
-             (avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
-              avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
-              avctx->pix_fmt == AV_PIX_FMT_YUV444P)))
-            format_supported = 1;
-        /* MPEG color space */
-        else if (avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL &&
-                 (avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
-                  avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
-                  avctx->pix_fmt == AV_PIX_FMT_YUV444P))
-            format_supported = 1;
-
-        if (!format_supported) {
-            av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n");
-            return AVERROR(EINVAL);
-        }
-        break;
-    }
-
     switch (avctx->pix_fmt) {
     case AV_PIX_FMT_YUVJ444P:
     case AV_PIX_FMT_YUV444P: