From patchwork Tue Mar 21 07:42:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: wm4 X-Patchwork-Id: 3042 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.50.79 with SMTP id y76csp1746714vsy; Tue, 21 Mar 2017 00:43:07 -0700 (PDT) X-Received: by 10.223.179.216 with SMTP id x24mr29025879wrd.171.1490082187252; Tue, 21 Mar 2017 00:43:07 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id i69si16758112wmc.114.2017.03.21.00.43.06; Tue, 21 Mar 2017 00:43:07 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@googlemail.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=googlemail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 605086882FD; Tue, 21 Mar 2017 09:42:45 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f196.google.com (mail-wr0-f196.google.com [209.85.128.196]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4A57968826F for ; Tue, 21 Mar 2017 09:42:38 +0200 (EET) Received: by mail-wr0-f196.google.com with SMTP id u108so21291733wrb.2 for ; Tue, 21 Mar 2017 00:42:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=DqiVkr03rmWtCjOHUHZjvOiPDgOmE6O/+7y4BupfYfo=; b=u8OGGhRXen1Wbz5sOfXMqSk2eXRFZ9IWmkvmhW2fpqHHZNlpOCzEdFHpxXCsur51Ro W/+W3+qS6bfBysFzhCjWkVEYF3m1vSpO98Y5TpQM4EuiNA6BSR3z/SGERWojJAqXRKYR oY1o9/6V3lHmnmi2wMklRfYD8ZFG8H41Qv/rZPcCEuKePZoL5QJaPSR+roqFmutaAE15 FBnT8ODJy2R5+WqFVhmDeyvAX++8bDs0RF/iM3rC7Bnt8agqHEu0WcMpYcvPiUe/5KgD lyJCgsErDmvVP+InL+ogDsk5gLmDXuRQiQ6quHoNEMHVpiX24OOo8gKGhjySo0T9o882 Lk/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=DqiVkr03rmWtCjOHUHZjvOiPDgOmE6O/+7y4BupfYfo=; b=eVis07CFTYQBW1JMDzeQs5IpqfFC7cXprDNKHjtnb8ihoNKvjfYK9Q8XTetrs7dJz2 49uzhqpCALX5wPqN4JdBlrRsIb4R1dI1EbB1dPLv3wmXuND/DGmHT935z8iJhleFxFJk dckv+cHECOOtCuMoGvmnn4xVP9AesP2w6VPrD2kfwtubPB5kUq/m+KxsZYdFFyPy++1d 5TrWPjGadde3oA7yXFP1MTaPKIL9XBzQ8jI6jveBSgKaehxtYxyjvvrsm+83jUUSKf7J fcZWpuHwIQq8XAcnLRGwAtI9wuqQri5MuFUUdV8SAnmLjpSed9uDLJubB01RM+o2T/ej 1y8A== X-Gm-Message-State: AFeK/H0mYneEjicr+gfscFIMQwIODmaJPOAbAywmYfGxklVKVyu79dKK/2LGoarb0g/BZg== X-Received: by 10.223.133.182 with SMTP id 51mr30551555wrt.39.1490082176573; Tue, 21 Mar 2017 00:42:56 -0700 (PDT) Received: from localhost.localdomain (p4FF00DAC.dip0.t-ipconnect.de. [79.240.13.172]) by smtp.googlemail.com with ESMTPSA id 94sm8410485wrp.34.2017.03.21.00.42.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Mar 2017 00:42:55 -0700 (PDT) From: wm4 To: ffmpeg-devel@ffmpeg.org Date: Tue, 21 Mar 2017 08:42:58 +0100 Message-Id: <20170321074258.7426-1-nfxjfg@googlemail.com> X-Mailer: git-send-email 2.11.0 Subject: [FFmpeg-devel] [PATCH] avformat, ffmpeg: deprecate old rotation API X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: wm4 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" The old "API" that signaled rotation as a metadata value has been replaced by DISPLAYMATRIX side data quite a while ago. There is no reason to make muxers/demuxers/API users support both. In addition, the metadata API is dangerous, as user tags could "leak" into it, creating unintended features or bugs. Unfortunately, hacks have been added, that allow the user to override rotation by setting metadata explicitly, e.g. via -metadata:s:v:0 rotate=0 See references to trac #4560. fate-filter-meta-4560-rotate0 tests this. It's easier to adjust the hack for supporting it than arguing for its removal, so ffmpeg CLI now explicitly catches this case, and essentially replaces the "rotate" value with a display matrix side data. (It would be easier for both user and implementation to create an explicit option for rotation.) When the code under FF_API_OLD_ROTATE_API is disabled, one FATE reference file has to be updated (because "rotate" is not exported anymore). --- cmdutils.c | 4 ++++ ffmpeg.c | 11 ++++++++--- ffmpeg.h | 1 + ffmpeg_opt.c | 12 ++++++++---- libavformat/mov.c | 2 ++ libavformat/movenc.c | 4 ++++ libavformat/version.h | 3 +++ 7 files changed, 30 insertions(+), 7 deletions(-) diff --git a/cmdutils.c b/cmdutils.c index 2373dbf841..594581faa4 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -2097,17 +2097,21 @@ void *grow_array(void *array, int elem_size, int *size, int new_size) double get_rotation(AVStream *st) { +#if FF_API_OLD_ROTATE_API AVDictionaryEntry *rotate_tag = av_dict_get(st->metadata, "rotate", NULL, 0); +#endif uint8_t* displaymatrix = av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, NULL); double theta = 0; +#if FF_API_OLD_ROTATE_API if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) { char *tail; theta = av_strtod(rotate_tag->value, &tail); if (*tail) theta = 0; } +#endif if (displaymatrix && !theta) theta = -av_display_rotation_get((int32_t*) displaymatrix); diff --git a/ffmpeg.c b/ffmpeg.c index dcb7720241..6dc36c9e0a 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -50,6 +50,7 @@ #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/dict.h" +#include "libavutil/display.h" #include "libavutil/mathematics.h" #include "libavutil/pixdesc.h" #include "libavutil/avstring.h" @@ -3051,9 +3052,6 @@ static int init_output_stream_streamcopy(OutputStream *ost) const AVPacketSideData *sd_src = &ist->st->side_data[i]; AVPacketSideData *sd_dst = &ost->st->side_data[ost->st->nb_side_data]; - if (ost->rotate_overridden && sd_src->type == AV_PKT_DATA_DISPLAYMATRIX) - continue; - sd_dst->data = av_malloc(sd_src->size); if (!sd_dst->data) return AVERROR(ENOMEM); @@ -3064,6 +3062,13 @@ static int init_output_stream_streamcopy(OutputStream *ost) } } + if (ost->rotate_overridden) { + uint8_t *sd = av_stream_new_side_data(ost->st, AV_PKT_DATA_DISPLAYMATRIX, + sizeof(int32_t) * 9); + if (sd) + av_display_rotation_set((int32_t *)sd, -ost->rotate_override_value); + } + ost->parser = av_parser_init(par_dst->codec_id); ost->parser_avctx = avcodec_alloc_context3(NULL); if (!ost->parser_avctx) diff --git a/ffmpeg.h b/ffmpeg.h index c3ed6ced78..4d0456c1fb 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -475,6 +475,7 @@ typedef struct OutputStream { int force_fps; int top_field_first; int rotate_overridden; + double rotate_override_value; AVRational frame_aspect_ratio; diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index fc885dfac3..ffe1abdb38 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -2549,8 +2549,6 @@ loop_end: av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE); if (!output_streams[i]->stream_copy) { av_dict_set(&output_streams[i]->st->metadata, "encoder", NULL, 0); - if (ist->autorotate) - av_dict_set(&output_streams[i]->st->metadata, "rotate", NULL, 0); } } @@ -2640,9 +2638,15 @@ loop_end: for (j = 0; j < oc->nb_streams; j++) { ost = output_streams[nb_output_streams - oc->nb_streams + j]; if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) { - av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0); if (!strcmp(o->metadata[i].u.str, "rotate")) { - ost->rotate_overridden = 1; + char *tail; + double theta = av_strtod(val, &tail); + if (!*tail) { + ost->rotate_overridden = 1; + ost->rotate_override_value = theta; + } + } else { + av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0); } } else if (ret < 0) exit_program(1); diff --git a/libavformat/mov.c b/libavformat/mov.c index f7dd2502c5..9581c965a3 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4030,6 +4030,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) for (j = 0; j < 3; j++) sc->display_matrix[i * 3 + j] = res_display_matrix[i][j]; +#if FF_API_OLD_ROTATE_API rotate = av_display_rotation_get(sc->display_matrix); if (!isnan(rotate)) { char rotate_buf[64]; @@ -4039,6 +4040,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate); av_dict_set(&st->metadata, "rotate", rotate_buf, 0); } +#endif } // transform the display width/height according to the matrix diff --git a/libavformat/movenc.c b/libavformat/movenc.c index a28621080d..c049aa972f 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2496,19 +2496,23 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov, avio_wb16(pb, 0); /* reserved */ /* Matrix structure */ +#if FF_API_OLD_ROTATE_API if (st && st->metadata) { AVDictionaryEntry *rot = av_dict_get(st->metadata, "rotate", NULL, 0); rotation = (rot && rot->value) ? atoi(rot->value) : 0; } +#endif if (display_matrix) { for (i = 0; i < 9; i++) avio_wb32(pb, display_matrix[i]); +#if FF_API_OLD_ROTATE_API } else if (rotation == 90) { write_matrix(pb, 0, 1, -1, 0, track->par->height, 0); } else if (rotation == 180) { write_matrix(pb, -1, 0, 0, -1, track->par->width, track->par->height); } else if (rotation == 270) { write_matrix(pb, 0, -1, 1, 0, 0, track->par->width); +#endif } else { write_matrix(pb, 1, 0, 0, 1, 0, 0); } diff --git a/libavformat/version.h b/libavformat/version.h index bfc42e3f15..2ff4e4e9d0 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -94,6 +94,9 @@ #ifndef FF_API_LAVF_KEEPSIDE_FLAG #define FF_API_LAVF_KEEPSIDE_FLAG (LIBAVFORMAT_VERSION_MAJOR < 58) #endif +#ifndef FF_API_OLD_ROTATE_API +#define FF_API_OLD_ROTATE_API (LIBAVFORMAT_VERSION_MAJOR < 58) +#endif #ifndef FF_API_R_FRAME_RATE