mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-27 13:30:45 +00:00
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:
commit
f5b26fbc2f
@ -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:
|
||||||
|
@ -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
|
||||||
|
2
ffmpeg.c
2
ffmpeg.c
@ -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)
|
||||||
|
3
ffmpeg.h
3
ffmpeg.h
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 },
|
||||||
|
Loading…
Reference in New Issue
Block a user