]> git.sesse.net Git - ffmpeg/blobdiff - avconv.c
h264: Workaround invalid flag combinations of 8x8 inference.
[ffmpeg] / avconv.c
index 58204f8318f4b7c3d74279cd4879545083a914d7..6425c0f4562457fd3ce29d92bb27ab35af0c6c05 100644 (file)
--- a/avconv.c
+++ b/avconv.c
@@ -149,11 +149,13 @@ static int input_sync;
 
 static float dts_delta_threshold = 10;
 
+static int print_stats = 1;
+
 static uint8_t *audio_buf;
 static uint8_t *audio_out;
 static unsigned int allocated_audio_out_size, allocated_audio_buf_size;
 
-static short *samples;
+static void *samples;
 
 #define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass"
 
@@ -238,7 +240,7 @@ typedef struct OutputStream {
     AVFilterGraph *graph;
 #endif
 
-   int sws_flags;
+   int64_t sws_flags;
    AVDictionary *opts;
    int is_past_recording_time;
 } OutputStream;
@@ -448,7 +450,7 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost)
         snprintf(args, 255, "%d:%d:flags=0x%X",
                  codec->width,
                  codec->height,
-                 ost->sws_flags);
+                 (unsigned)ost->sws_flags);
         if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
                                                 NULL, args, NULL, ost->graph)) < 0)
             return ret;
@@ -457,7 +459,7 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost)
         last_filter = filter;
     }
 
-    snprintf(args, sizeof(args), "flags=0x%X", ost->sws_flags);
+    snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
     ost->graph->scale_sws_opts = av_strdup(args);
 
     if (ost->avfilter) {
@@ -1374,6 +1376,9 @@ static void print_report(OutputFile *output_files,
     static int qp_histogram[52];
     int hours, mins, secs, us;
 
+    if (!print_stats && !is_last_report)
+        return;
+
     if (!is_last_report) {
         int64_t cur_time;
         /* display the report every 0.5 seconds */
@@ -1470,7 +1475,7 @@ static void print_report(OutputFile *output_files,
         snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",
                 nb_frames_dup, nb_frames_drop);
 
-    av_log(NULL, is_last_report ? AV_LOG_WARNING : AV_LOG_INFO, "%s    \r", buf);
+    av_log(NULL, AV_LOG_INFO, "%s    \r", buf);
 
     fflush(stderr);
 
@@ -1586,9 +1591,8 @@ static int output_packet(InputStream *ist, int ist_index,
 {
     AVFormatContext *os;
     OutputStream *ost;
-    int ret, i;
+    int ret = 0, i;
     int got_output;
-    AVFrame picture;
     void *buffer_to_free = NULL;
     static unsigned int samples_size= 0;
     AVSubtitle subtitle, *subtitle_to_free;
@@ -1623,6 +1627,7 @@ static int output_packet(InputStream *ist, int ist_index,
     while (avpkt.size > 0 || (!pkt && got_output)) {
         uint8_t *data_buf, *decoded_data_buf;
         int data_size, decoded_data_size;
+        AVFrame *decoded_frame, *filtered_frame;
     handle_eof:
         ist->pts= ist->next_pts;
 
@@ -1632,6 +1637,7 @@ static int output_packet(InputStream *ist, int ist_index,
             ist->showed_multi_packet_warning=1;
 
         /* decode the packet if needed */
+        decoded_frame    = filtered_frame = NULL;
         decoded_data_buf = NULL; /* fail safe */
         decoded_data_size= 0;
         data_buf  = avpkt.data;
@@ -1640,8 +1646,8 @@ static int output_packet(InputStream *ist, int ist_index,
         if (ist->decoding_needed) {
             switch(ist->st->codec->codec_type) {
             case AVMEDIA_TYPE_AUDIO:{
-                if(pkt && samples_size < FFMAX(pkt->size*sizeof(*samples), AVCODEC_MAX_AUDIO_FRAME_SIZE)) {
-                    samples_size = FFMAX(pkt->size*sizeof(*samples), AVCODEC_MAX_AUDIO_FRAME_SIZE);
+                if(pkt && samples_size < FFMAX(pkt->size * bps, AVCODEC_MAX_AUDIO_FRAME_SIZE)) {
+                    samples_size = FFMAX(pkt->size * bps, AVCODEC_MAX_AUDIO_FRAME_SIZE);
                     av_free(samples);
                     samples= av_malloc(samples_size);
                 }
@@ -1667,23 +1673,23 @@ static int output_packet(InputStream *ist, int ist_index,
                     (ist->st->codec->sample_rate * ist->st->codec->channels);
                 break;}
             case AVMEDIA_TYPE_VIDEO:
-                    decoded_data_size = (ist->st->codec->width * ist->st->codec->height * 3) / 2;
-                    /* XXX: allocate picture correctly */
-                    avcodec_get_frame_defaults(&picture);
+                    if (!(decoded_frame = avcodec_alloc_frame()))
+                        return AVERROR(ENOMEM);
                     avpkt.pts = pkt_pts;
                     avpkt.dts = ist->pts;
                     pkt_pts = AV_NOPTS_VALUE;
 
                     ret = avcodec_decode_video2(ist->st->codec,
-                                                &picture, &got_output, &avpkt);
-                    quality = same_quant ? picture.quality : 0;
+                                                decoded_frame, &got_output, &avpkt);
+                    quality = same_quant ? decoded_frame->quality : 0;
                     if (ret < 0)
-                        return ret;
+                        goto fail;
                     if (!got_output) {
                         /* no picture yet */
+                        av_freep(&decoded_frame);
                         goto discard_packet;
                     }
-                    ist->next_pts = ist->pts = picture.best_effort_timestamp;
+                    ist->next_pts = ist->pts = decoded_frame->best_effort_timestamp;
                     if (ist->st->codec->time_base.num != 0) {
                         int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame;
                         ist->next_pts += ((int64_t)AV_TIME_BASE *
@@ -1692,7 +1698,7 @@ static int output_packet(InputStream *ist, int ist_index,
                     }
                     avpkt.size = 0;
                     buffer_to_free = NULL;
-                    pre_process_video_frame(ist, (AVPicture *)&picture, &buffer_to_free);
+                    pre_process_video_frame(ist, (AVPicture *)decoded_frame, &buffer_to_free);
                     break;
             case AVMEDIA_TYPE_SUBTITLE:
                 ret = avcodec_decode_subtitle2(ist->st->codec,
@@ -1729,11 +1735,57 @@ static int output_packet(InputStream *ist, int ist_index,
         // preprocess audio (volume)
         if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
             if (audio_volume != 256) {
-                short *volp;
-                volp = samples;
-                for(i=0;i<(decoded_data_size / sizeof(short));i++) {
-                    int v = ((*volp) * audio_volume + 128) >> 8;
-                    *volp++ = av_clip_int16(v);
+                switch (ist->st->codec->sample_fmt) {
+                case AV_SAMPLE_FMT_U8:
+                {
+                    uint8_t *volp = samples;
+                    for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
+                        int v = (((*volp - 128) * audio_volume + 128) >> 8) + 128;
+                        *volp++ = av_clip_uint8(v);
+                    }
+                    break;
+                }
+                case AV_SAMPLE_FMT_S16:
+                {
+                    int16_t *volp = samples;
+                    for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
+                        int v = ((*volp) * audio_volume + 128) >> 8;
+                        *volp++ = av_clip_int16(v);
+                    }
+                    break;
+                }
+                case AV_SAMPLE_FMT_S32:
+                {
+                    int32_t *volp = samples;
+                    for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
+                        int64_t v = (((int64_t)*volp * audio_volume + 128) >> 8);
+                        *volp++ = av_clipl_int32(v);
+                    }
+                    break;
+                }
+                case AV_SAMPLE_FMT_FLT:
+                {
+                    float *volp = samples;
+                    float scale = audio_volume / 256.f;
+                    for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
+                        *volp++ *= scale;
+                    }
+                    break;
+                }
+                case AV_SAMPLE_FMT_DBL:
+                {
+                    double *volp = samples;
+                    double scale = audio_volume / 256.;
+                    for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
+                        *volp++ *= scale;
+                    }
+                    break;
+                }
+                default:
+                    av_log(NULL, AV_LOG_FATAL,
+                           "Audio volume adjustment on sample format %s is not supported.\n",
+                           av_get_sample_fmt_name(ist->st->codec->sample_fmt));
+                    exit_program(1);
                 }
             }
         }
@@ -1768,11 +1820,15 @@ static int output_packet(InputStream *ist, int ist_index,
 #if CONFIG_AVFILTER
             if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
                 ost->input_video_filter) {
-                if (!picture.sample_aspect_ratio.num)
-                    picture.sample_aspect_ratio = ist->st->sample_aspect_ratio;
-                picture.pts = ist->pts;
+                if (!decoded_frame->sample_aspect_ratio.num)
+                    decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio;
+                decoded_frame->pts = ist->pts;
 
-                av_vsrc_buffer_add_frame(ost->input_video_filter, &picture, AV_VSRC_BUF_FLAG_OVERWRITE);
+                av_vsrc_buffer_add_frame(ost->input_video_filter, decoded_frame, AV_VSRC_BUF_FLAG_OVERWRITE);
+                if (!(filtered_frame = avcodec_alloc_frame())) {
+                    ret = AVERROR(ENOMEM);
+                    goto fail;
+                }
             }
             frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
                 !ost->output_video_filter || avfilter_poll_frame(ost->output_video_filter->inputs[0]);
@@ -1782,10 +1838,12 @@ static int output_packet(InputStream *ist, int ist_index,
                     if (av_buffersink_get_buffer_ref(ost->output_video_filter, &ost->picref, 0) < 0)
                         goto cont;
                     if (ost->picref) {
-                        avfilter_fill_frame_from_video_buffer_ref(&picture, ost->picref);
+                        avfilter_fill_frame_from_video_buffer_ref(filtered_frame, ost->picref);
                         ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
                     }
                 }
+#else
+                filtered_frame = decoded_frame;
 #endif
                 os = output_files[ost->file_index].ctx;
 
@@ -1803,8 +1861,8 @@ static int output_packet(InputStream *ist, int ist_index,
                         if (ost->picref->video && !ost->frame_aspect_ratio)
                             ost->st->codec->sample_aspect_ratio = ost->picref->video->sample_aspect_ratio;
 #endif
-                        do_video_out(os, ost, ist, &picture, &frame_size,
-                                        same_quant ? quality : ost->st->codec->global_quality);
+                        do_video_out(os, ost, ist, filtered_frame, &frame_size,
+                                     same_quant ? quality : ost->st->codec->global_quality);
                         if (vstats_filename && frame_size)
                             do_video_stats(os, ost, frame_size);
                         break;
@@ -1884,15 +1942,20 @@ static int output_packet(InputStream *ist, int ist_index,
                 if (ost->picref)
                     avfilter_unref_buffer(ost->picref);
             }
+            av_freep(&filtered_frame);
 #endif
             }
 
+fail:
         av_free(buffer_to_free);
         /* XXX: allocate the subtitles in the codec ? */
         if (subtitle_to_free) {
             avsubtitle_free(subtitle_to_free);
             subtitle_to_free = NULL;
         }
+        av_freep(&decoded_frame);
+        if (ret < 0)
+            return ret;
     }
  discard_packet:
 
@@ -2068,6 +2131,7 @@ static int transcode_init(OutputFile *output_files,
                 codec->height = icodec->height;
                 break;
             case AVMEDIA_TYPE_DATA:
+            case AVMEDIA_TYPE_ATTACHMENT:
                 break;
             default:
                 abort();
@@ -2075,6 +2139,8 @@ static int transcode_init(OutputFile *output_files,
         } else {
             if (!ost->enc)
                 ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
+            ist->decoding_needed = 1;
+            ost->encoding_needed = 1;
             switch(codec->codec_type) {
             case AVMEDIA_TYPE_AUDIO:
                 ost->fifo= av_fifo_alloc(1024);
@@ -2098,8 +2164,6 @@ static int transcode_init(OutputFile *output_files,
                     codec->channel_layout = 0;
                 ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;
                 icodec->request_channels = codec->channels;
-                ist->decoding_needed = 1;
-                ost->encoding_needed = 1;
                 ost->resample_sample_fmt  = icodec->sample_fmt;
                 ost->resample_sample_rate = icodec->sample_rate;
                 ost->resample_channels    = icodec->channels;
@@ -2129,8 +2193,6 @@ static int transcode_init(OutputFile *output_files,
                 ost->resample_height = icodec->height;
                 ost->resample_width  = icodec->width;
                 ost->resample_pix_fmt= icodec->pix_fmt;
-                ost->encoding_needed = 1;
-                ist->decoding_needed = 1;
 
                 if (!ost->frame_rate.num)
                     ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25,1};
@@ -2153,15 +2215,13 @@ static int transcode_init(OutputFile *output_files,
 #endif
                 break;
             case AVMEDIA_TYPE_SUBTITLE:
-                ost->encoding_needed = 1;
-                ist->decoding_needed = 1;
                 break;
             default:
                 abort();
                 break;
             }
             /* two pass mode */
-            if (ost->encoding_needed && codec->codec_id != CODEC_ID_H264 &&
+            if (codec->codec_id != CODEC_ID_H264 &&
                 (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
                 char logfilename[1024];
                 FILE *f;
@@ -2605,12 +2665,6 @@ static int transcode(OutputFile *output_files,
     return ret;
 }
 
-static int opt_verbose(const char *opt, const char *arg)
-{
-    av_log(NULL, AV_LOG_WARNING, "-%s is deprecated, use -loglevel\n", opt);
-    return 0;
-}
-
 static double parse_frame_aspect_ratio(const char *arg)
 {
     int x = 0, y = 0;
@@ -3097,7 +3151,10 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
         st->codec->global_quality = FF_QP2LAMBDA * qscale;
     }
 
-    ost->sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
+    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
+        st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+    av_opt_get_int(sws_opts, "sws_flags", 0, &ost->sws_flags);
     return ost;
 }
 
@@ -3128,10 +3185,6 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
     st  = ost->st;
     video_enc = st->codec;
 
-    if(oc->oformat->flags & AVFMT_GLOBALHEADER) {
-        video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
-    }
-
     if (!st->stream_copy) {
         const char *p = NULL;
         char *forced_key_frames = NULL, *frame_rate = NULL, *frame_size = NULL;
@@ -3249,9 +3302,6 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
     audio_enc = st->codec;
     audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
 
-    if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
-        audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
-    }
     if (!st->stream_copy) {
         char *sample_fmt = NULL;
 
@@ -3274,20 +3324,21 @@ static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
 {
     AVStream *st;
     OutputStream *ost;
-    AVCodecContext *data_enc;
 
     ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA);
     st  = ost->st;
-    data_enc = st->codec;
     if (!st->stream_copy) {
         av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
         exit_program(1);
     }
 
-    if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
-        data_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
-    }
+    return ost;
+}
 
+static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc)
+{
+    OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT);
+    ost->st->stream_copy = 1;
     return ost;
 }
 
@@ -3303,10 +3354,6 @@ static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc)
 
     subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
 
-    if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
-        subtitle_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
-    }
-
     return ost;
 }
 
@@ -3495,6 +3542,7 @@ static void opt_output_file(void *optctx, const char *filename)
             case AVMEDIA_TYPE_AUDIO:    ost = new_audio_stream(o, oc);    break;
             case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break;
             case AVMEDIA_TYPE_DATA:     ost = new_data_stream(o, oc);     break;
+            case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break;
             default:
                 av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d.%d - unsupported type.\n",
                        map->file_index, map->stream_index);
@@ -3733,11 +3781,7 @@ static void show_usage(void)
 
 static int opt_help(const char *opt, const char *arg)
 {
-    AVCodec *c;
-    AVOutputFormat *oformat = NULL;
-    AVInputFormat  *iformat = NULL;
-    const AVClass *class;
-
+    int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
     av_log_set_callback(log_callback_help);
     show_usage();
     show_help_options(options, "Main options:\n",
@@ -3764,41 +3808,10 @@ static int opt_help(const char *opt, const char *arg)
                       OPT_GRAB,
                       OPT_GRAB);
     printf("\n");
-    class = avcodec_get_class();
-    av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
-    printf("\n");
-
-    /* individual codec options */
-    c = NULL;
-    while ((c = av_codec_next(c))) {
-        if (c->priv_class) {
-            av_opt_show2(&c->priv_class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
-            printf("\n");
-        }
-    }
-
-    class = avformat_get_class();
-    av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
-    printf("\n");
-
-    /* individual muxer options */
-    while ((oformat = av_oformat_next(oformat))) {
-        if (oformat->priv_class) {
-            av_opt_show2(&oformat->priv_class, NULL, AV_OPT_FLAG_ENCODING_PARAM, 0);
-            printf("\n");
-        }
-    }
-
-    /* individual demuxer options */
-    while ((iformat = av_iformat_next(iformat))) {
-        if (iformat->priv_class) {
-            av_opt_show2(&iformat->priv_class, NULL, AV_OPT_FLAG_DECODING_PARAM, 0);
-            printf("\n");
-        }
-    }
+    show_help_children(avcodec_get_class(), flags);
+    show_help_children(avformat_get_class(), flags);
+    show_help_children(sws_get_class(), flags);
 
-    class = sws_get_class();
-    av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
     return 0;
 }
 
@@ -4033,7 +4046,6 @@ static const OptionDef options[] = {
     { "hex", OPT_BOOL | OPT_EXPERT, {(void*)&do_hex_dump},
       "when dumping packets, also dump the payload" },
     { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(rate_emu)}, "read input at native frame rate", "" },
-    { "v", HAS_ARG, {(void*)opt_verbose}, "deprecated, use -loglevel instead", "number" },
     { "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
     { "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
     { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
@@ -4051,6 +4063,7 @@ static const OptionDef options[] = {
 #if CONFIG_AVFILTER
     { "filter", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(filters)}, "set stream filterchain", "filter_list" },
 #endif
+    { "stats", OPT_BOOL, {&print_stats}, "print progress report during encoding", },
 
     /* video options */
     { "vframes", HAS_ARG | OPT_VIDEO | OPT_FUNC2, {(void*)opt_video_frames}, "set the number of video frames to record", "number" },