summaryrefslogtreecommitdiff
path: root/avconv_filter.c
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2015-04-29 17:59:01 +0300
committerMartin Storsjö <martin@martin.st>2015-05-02 22:09:06 +0300
commit16302246b1fcb7ad4e6f7bd31c49956a455336d2 (patch)
treec5c5a29b3f25d02b7e56cf0aa2bc679a07ac5d2d /avconv_filter.c
parente2d50fc2f5f3600e13055acf1a10fec35e941f37 (diff)
avconv: Add an option for automatically rotating video according to display matrix
The option is enabled by default, but can be disabled. If this is enabled, such side data isn't copied into the output stream (except when doing stream copy). Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'avconv_filter.c')
-rw-r--r--avconv_filter.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/avconv_filter.c b/avconv_filter.c
index e54da56c7a..c3360f1741 100644
--- a/avconv_filter.c
+++ b/avconv_filter.c
@@ -29,6 +29,7 @@
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/channel_layout.h"
+#include "libavutil/display.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/pixfmt.h"
@@ -226,6 +227,28 @@ static int insert_trim(int64_t start_time, int64_t duration,
return 0;
}
+static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
+ const char *filter_name, const char *args)
+{
+ AVFilterGraph *graph = (*last_filter)->graph;
+ AVFilterContext *ctx;
+ int ret;
+
+ ret = avfilter_graph_create_filter(&ctx,
+ avfilter_get_by_name(filter_name),
+ filter_name, args, NULL, graph);
+ if (ret < 0)
+ return ret;
+
+ ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
+ if (ret < 0)
+ return ret;
+
+ *last_filter = ctx;
+ *pad_idx = 0;
+ return 0;
+}
+
static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
{
char *pix_fmts;
@@ -446,6 +469,26 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
return ret;
last_filter = ifilter->filter;
+ if (ist->autorotate) {
+ uint8_t* displaymatrix = av_stream_get_side_data(ist->st,
+ AV_PKT_DATA_DISPLAYMATRIX, NULL);
+ if (displaymatrix) {
+ double rot = av_display_rotation_get((int32_t*) displaymatrix);
+ if (rot < -135 || rot > 135) {
+ ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
+ if (ret < 0)
+ return ret;
+ ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
+ } else if (rot < -45) {
+ ret = insert_filter(&last_filter, &pad_idx, "transpose", "dir=clock");
+ } else if (rot > 45) {
+ ret = insert_filter(&last_filter, &pad_idx, "transpose", "dir=cclock");
+ }
+ if (ret < 0)
+ return ret;
+ }
+ }
+
if (ist->framerate.num) {
AVFilterContext *setpts;