diff mbox series

[FFmpeg-devel,6/6] fftools/ffplay: support applying container level cropping

Message ID 20240529214632.9843-6-jamrial@gmail.com
State New
Headers show
Series [FFmpeg-devel,1/6] avcodec/packet: add a decoded frame cropping side data type | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 fail Make fate failed
andriy/make_x86 success Make finished
andriy/make_fate_x86 fail Make fate failed

Commit Message

James Almer May 29, 2024, 9:46 p.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
 fftools/ffplay.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
diff mbox series

Patch

diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index 1d0511b254..47e2865abb 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -32,6 +32,7 @@ 
 
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/mem.h"
 #include "libavutil/pixdesc.h"
@@ -346,6 +347,7 @@  static const char **vfilters_list = NULL;
 static int nb_vfilters = 0;
 static char *afilters = NULL;
 static int autorotate = 1;
+static int apply_cropping = 1;
 static int find_stream_info = 1;
 static int filter_nbthreads = 0;
 static int enable_vulkan = 0;
@@ -1947,6 +1949,28 @@  static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
     last_filter = filt_ctx;                                                  \
 } while (0)
 
+    if (apply_cropping) {
+        const AVPacketSideData *sd = av_packet_side_data_get(is->video_st->codecpar->coded_side_data,
+                                                             is->video_st->codecpar->nb_coded_side_data,
+                                                             AV_PKT_DATA_FRAME_CROPPING);
+
+        if (sd && sd->size == sizeof(uint32_t) * 4) {
+            char crop_buf[64];
+            int top    = AV_RL32(sd->data +  0);
+            int bottom = AV_RL32(sd->data +  4);
+            int left   = AV_RL32(sd->data +  8);
+            int right  = AV_RL32(sd->data + 12);
+
+            if (top < 0 || bottom < 0 || left < 0 || right < 0)  {
+                ret = AVERROR(EINVAL);
+                goto fail;
+            }
+
+            snprintf(crop_buf, sizeof(crop_buf), "w=iw-%d-%d:h=ih-%d-%d", left, right, top, bottom);
+            INSERT_FILT("crop", crop_buf);
+        }
+    }
+
     if (autorotate) {
         double theta = 0.0;
         int32_t *displaymatrix = NULL;
@@ -3691,6 +3715,7 @@  static const OptionDef options[] = {
     { "scodec",             OPT_TYPE_STRING, OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
     { "vcodec",             OPT_TYPE_STRING, OPT_EXPERT, {    &video_codec_name }, "force video decoder",    "decoder_name" },
     { "autorotate",         OPT_TYPE_BOOL,            0, { &autorotate }, "automatically rotate video", "" },
+    { "apply_cropping",     OPT_TYPE_BOOL,            0, { &apply_cropping }, "apply container level frame cropping", "" },
     { "find_stream_info",   OPT_TYPE_BOOL, OPT_INPUT | OPT_EXPERT, { &find_stream_info },
         "read and decode the streams to fill missing information with heuristics" },
     { "filter_threads",     OPT_TYPE_INT,    OPT_EXPERT, { &filter_nbthreads }, "number of filter threads per graph" },