Merge commit '16302246b1fcb7ad4e6f7bd31c49956a455336d2'

* commit '16302246b1fcb7ad4e6f7bd31c49956a455336d2':
  avconv: Add an option for automatically rotating video according to display matrix

Conflicts:
	Changelog
	ffmpeg_opt.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2015-05-02 22:39:00 +02:00
commit f5b26fbc2f
6 changed files with 58 additions and 0 deletions

View File

@ -18,6 +18,7 @@ version <next>:
- nvenc level and tier options - nvenc level and tier options
- chorus filter - chorus filter
- Canopus HQ/HQA decoder - Canopus HQ/HQA decoder
- Automatically rotate videos based on metadata in ffmpeg
version 2.6: version 2.6:

View File

@ -462,6 +462,9 @@ Technical note -- attachments are implemented as codec extradata, so this
option can actually be used to extract extradata from any stream, not just option can actually be used to extract extradata from any stream, not just
attachments. attachments.
@item -noautorotate
Disable automatically rotating video based on file metadata.
@end table @end table
@section Video Options @section Video Options

View File

@ -3647,6 +3647,8 @@ static int process_input(int file_index)
if (av_packet_get_side_data(&pkt, src_sd->type, NULL)) if (av_packet_get_side_data(&pkt, src_sd->type, NULL))
continue; continue;
if (ist->autorotate && src_sd->type == AV_PKT_DATA_DISPLAYMATRIX)
continue;
dst_data = av_packet_new_side_data(&pkt, src_sd->type, src_sd->size); dst_data = av_packet_new_side_data(&pkt, src_sd->type, src_sd->size);
if (!dst_data) if (!dst_data)

View File

@ -122,6 +122,8 @@ typedef struct OptionsContext {
int nb_hwaccels; int nb_hwaccels;
SpecifierOpt *hwaccel_devices; SpecifierOpt *hwaccel_devices;
int nb_hwaccel_devices; int nb_hwaccel_devices;
SpecifierOpt *autorotate;
int nb_autorotate;
/* output options */ /* output options */
StreamMap *stream_maps; StreamMap *stream_maps;
@ -276,6 +278,7 @@ typedef struct InputStream {
int top_field_first; int top_field_first;
int guess_layout_max; int guess_layout_max;
int autorotate;
int resample_height; int resample_height;
int resample_width; int resample_width;
int resample_pix_fmt; int resample_pix_fmt;

View File

@ -31,6 +31,7 @@
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
#include "libavutil/channel_layout.h" #include "libavutil/channel_layout.h"
#include "libavutil/display.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/pixdesc.h" #include "libavutil/pixdesc.h"
#include "libavutil/pixfmt.h" #include "libavutil/pixfmt.h"
@ -339,6 +340,28 @@ static int insert_trim(int64_t start_time, int64_t duration,
return 0; 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) static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
{ {
char *pix_fmts; char *pix_fmts;
@ -676,6 +699,26 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
return ret; return ret;
last_filter = ifilter->filter; 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) { if (ist->framerate.num) {
AVFilterContext *setpts; AVFilterContext *setpts;

View File

@ -602,6 +602,9 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
ist->ts_scale = 1.0; ist->ts_scale = 1.0;
MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st); MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
ist->autorotate = 1;
MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st); MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
if (codec_tag) { if (codec_tag) {
uint32_t tag = strtol(codec_tag, &next, 0); uint32_t tag = strtol(codec_tag, &next, 0);
@ -3069,6 +3072,9 @@ const OptionDef options[] = {
#if HAVE_VDPAU_X11 #if HAVE_VDPAU_X11
{ "vdpau_api_ver", HAS_ARG | OPT_INT | OPT_EXPERT, { &vdpau_api_ver }, "" }, { "vdpau_api_ver", HAS_ARG | OPT_INT | OPT_EXPERT, { &vdpau_api_ver }, "" },
#endif #endif
{ "autorotate", HAS_ARG | OPT_BOOL | OPT_SPEC |
OPT_EXPERT | OPT_INPUT, { .off = OFFSET(autorotate) },
"automatically insert correct rotate filters" },
/* audio options */ /* audio options */
{ "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames }, { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },