]> git.sesse.net Git - ffmpeg/blobdiff - avconv_filter.c
hevc_parser: fix standalone build with the hevc decoder disabled
[ffmpeg] / avconv_filter.c
index 348196f5fa1b2feb1b14b8d4c7bfe5ed2bed0a98..c3360f1741aaf9a48d68c4eaebed56b99b5d81c0 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "avconv.h"
 
 #include "libavfilter/avfilter.h"
@@ -27,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"
@@ -37,8 +40,8 @@
 #define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name)           \
 static char *choose_ ## var ## s(OutputStream *ost)                            \
 {                                                                              \
-    if (ost->st->codec->var != none) {                                         \
-        get_name(ost->st->codec->var);                                         \
+    if (ost->enc_ctx->var != none) {                                           \
+        get_name(ost->enc_ctx->var);                                           \
         return av_strdup(name);                                                \
     } else if (ost->enc && ost->enc->supported_list) {                         \
         const type *p;                                                         \
@@ -147,12 +150,12 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
         /* find the first unused stream of corresponding type */
         for (i = 0; i < nb_input_streams; i++) {
             ist = input_streams[i];
-            if (ist->st->codec->codec_type == type && ist->discard)
+            if (ist->dec_ctx->codec_type == type && ist->discard)
                 break;
         }
         if (i == nb_input_streams) {
             av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for "
-                   "unlabeled input pad %d on filter %s", in->pad_idx,
+                   "unlabeled input pad %d on filter %s\n", in->pad_idx,
                    in->filter_ctx->name);
             exit(1);
         }
@@ -224,12 +227,34 @@ 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;
     OutputStream *ost = ofilter->ost;
     OutputFile    *of = output_files[ost->file_index];
-    AVCodecContext *codec = ost->st->codec;
+    AVCodecContext *codec = ost->enc_ctx;
     AVFilterContext *last_filter = out->filter_ctx;
     int pad_idx = out->pad_idx;
     int ret;
@@ -266,17 +291,17 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
         AVFilterContext *filter;
         snprintf(name, sizeof(name), "pixel format for output stream %d:%d",
                  ost->file_index, ost->index);
-        if ((ret = avfilter_graph_create_filter(&filter,
-                                                avfilter_get_by_name("format"),
-                                                "format", pix_fmts, NULL,
-                                                fg->graph)) < 0)
+        ret = avfilter_graph_create_filter(&filter,
+                                           avfilter_get_by_name("format"),
+                                           "format", pix_fmts, NULL, fg->graph);
+        av_freep(&pix_fmts);
+        if (ret < 0)
             return ret;
         if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
             return ret;
 
         last_filter = filter;
         pad_idx     = 0;
-        av_freep(&pix_fmts);
     }
 
     if (ost->frame_rate.num) {
@@ -317,7 +342,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
 {
     OutputStream *ost = ofilter->ost;
     OutputFile    *of = output_files[ost->file_index];
-    AVCodecContext *codec  = ost->st->codec;
+    AVCodecContext *codec  = ost->enc_ctx;
     AVFilterContext *last_filter = out->filter_ctx;
     int pad_idx = out->pad_idx;
     char *sample_fmts, *sample_rates, *channel_layouts;
@@ -431,9 +456,10 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
 
     sar = ist->st->sample_aspect_ratio.num ?
           ist->st->sample_aspect_ratio :
-          ist->st->codec->sample_aspect_ratio;
-    snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width,
-             ist->st->codec->height, ist->st->codec->pix_fmt,
+          ist->dec_ctx->sample_aspect_ratio;
+    snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", ist->dec_ctx->width,
+             ist->dec_ctx->height,
+             ist->hwaccel_retrieve_data ? ist->hwaccel_retrieved_pix_fmt : ist->dec_ctx->pix_fmt,
              tb.num, tb.den, sar.num, sar.den);
     snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
              ist->file_index, ist->st->index);
@@ -443,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;
 
@@ -484,10 +530,10 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
 
     snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s"
              ":channel_layout=0x%"PRIx64,
-             1, ist->st->codec->sample_rate,
-             ist->st->codec->sample_rate,
-             av_get_sample_fmt_name(ist->st->codec->sample_fmt),
-             ist->st->codec->channel_layout);
+             1, ist->dec_ctx->sample_rate,
+             ist->dec_ctx->sample_rate,
+             av_get_sample_fmt_name(ist->dec_ctx->sample_fmt),
+             ist->dec_ctx->channel_layout);
     snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
              ist->file_index, ist->st->index);