[FFmpeg-cvslog] avfilter/vf_framepack: add >8 format support

Paul B Mahol git at videolan.org
Tue Feb 9 13:29:29 EET 2021


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Tue Feb  9 12:25:48 2021 +0100| [cfcc36240f5019c7645134c7da6503430db9268d] | committer: Paul B Mahol

avfilter/vf_framepack: add >8 format support

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=cfcc36240f5019c7645134c7da6503430db9268d
---

 libavfilter/vf_framepack.c | 70 ++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 64 insertions(+), 6 deletions(-)

diff --git a/libavfilter/vf_framepack.c b/libavfilter/vf_framepack.c
index b5d877ca99..3da80cfeef 100644
--- a/libavfilter/vf_framepack.c
+++ b/libavfilter/vf_framepack.c
@@ -44,6 +44,7 @@
 typedef struct FramepackContext {
     const AVClass *class;
 
+    int depth;
     const AVPixFmtDescriptor *pix_desc; ///< agreed pixel format
 
     enum AVStereo3DType format;         ///< frame pack type output
@@ -52,9 +53,29 @@ typedef struct FramepackContext {
 } FramepackContext;
 
 static const enum AVPixelFormat formats_supported[] = {
-    AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,
-    AV_PIX_FMT_YUV410P,  AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVJ420P,
-    AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P,
+    AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9,
+    AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14,
+    AV_PIX_FMT_GRAY16,
+    AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,
+    AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P,
+    AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P,
+    AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P,
+    AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ444P,
+    AV_PIX_FMT_YUVJ411P,
+    AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
+    AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
+    AV_PIX_FMT_YUV440P10,
+    AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12,
+    AV_PIX_FMT_YUV440P12,
+    AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14,
+    AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
+    AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
+    AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
+    AV_PIX_FMT_YUVA420P,  AV_PIX_FMT_YUVA422P,   AV_PIX_FMT_YUVA444P,
+    AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16,
+    AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16,
+    AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16,
+    AV_PIX_FMT_GBRAP,     AV_PIX_FMT_GBRAP10,    AV_PIX_FMT_GBRAP12,    AV_PIX_FMT_GBRAP16,
     AV_PIX_FMT_NONE
 };
 
@@ -113,6 +134,7 @@ static int config_output(AVFilterLink *outlink)
     s->pix_desc = av_pix_fmt_desc_get(outlink->format);
     if (!s->pix_desc)
         return AVERROR_BUG;
+    s->depth = s->pix_desc->comp[0].depth;
 
     // modify output properties as needed
     switch (s->format) {
@@ -149,7 +171,7 @@ static void horizontal_frame_pack(AVFilterLink *outlink,
     FramepackContext *s = ctx->priv;
     int i, plane;
 
-    if (interleaved) {
+    if (interleaved && s->depth <= 8) {
         const uint8_t *leftp  = s->input_views[LEFT]->data[0];
         const uint8_t *rightp = s->input_views[RIGHT]->data[0];
         uint8_t *dstp         = out->data[0];
@@ -184,17 +206,53 @@ static void horizontal_frame_pack(AVFilterLink *outlink,
                 }
             }
         }
+    } else if (interleaved && s->depth > 8) {
+        const uint16_t *leftp  = (const uint16_t *)s->input_views[LEFT]->data[0];
+        const uint16_t *rightp = (const uint16_t *)s->input_views[RIGHT]->data[0];
+        uint16_t *dstp         = (uint16_t *)out->data[0];
+        int length = out->width / 2;
+        int lines  = out->height;
+
+        for (plane = 0; plane < s->pix_desc->nb_components; plane++) {
+            if (plane == 1 || plane == 2) {
+                length = AV_CEIL_RSHIFT(out->width / 2, s->pix_desc->log2_chroma_w);
+                lines  = AV_CEIL_RSHIFT(out->height,    s->pix_desc->log2_chroma_h);
+            }
+            for (i = 0; i < lines; i++) {
+                int j;
+                leftp  = (const uint16_t *)s->input_views[LEFT]->data[plane] +
+                         s->input_views[LEFT]->linesize[plane] * i / 2;
+                rightp = (const uint16_t *)s->input_views[RIGHT]->data[plane] +
+                         s->input_views[RIGHT]->linesize[plane] * i / 2;
+                dstp   = (uint16_t *)out->data[plane] + out->linesize[plane] * i / 2;
+                for (j = 0; j < length; j++) {
+                    // interpolate chroma as necessary
+                    if ((s->pix_desc->log2_chroma_w ||
+                         s->pix_desc->log2_chroma_h) &&
+                        (plane == 1 || plane == 2)) {
+                        *dstp++ = (*leftp + *rightp) / 2;
+                        *dstp++ = (*leftp + *rightp) / 2;
+                    } else {
+                        *dstp++ = *leftp;
+                        *dstp++ = *rightp;
+                    }
+                    leftp += 1;
+                    rightp += 1;
+                }
+            }
+        }
     } else {
         for (i = 0; i < 2; i++) {
+            const int psize = 1 + (s->depth > 8);
             const uint8_t *src[4];
             uint8_t *dst[4];
-            int sub_w = s->input_views[i]->width >> s->pix_desc->log2_chroma_w;
+            int sub_w = psize * s->input_views[i]->width >> s->pix_desc->log2_chroma_w;
 
             src[0] = s->input_views[i]->data[0];
             src[1] = s->input_views[i]->data[1];
             src[2] = s->input_views[i]->data[2];
 
-            dst[0] = out->data[0] + i * s->input_views[i]->width;
+            dst[0] = out->data[0] + i * s->input_views[i]->width * psize;
             dst[1] = out->data[1] + i * sub_w;
             dst[2] = out->data[2] + i * sub_w;
 



More information about the ffmpeg-cvslog mailing list