]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
Don't print header bits by default
[ffmpeg] / ffmpeg.c
index 6d22e43b16d3750fe6778d2b3386f631c57e647e..752125ca2a7acb7e9ff26b269e4c70c226b16166 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
 #define HAVE_AV_CONFIG_H
 #include <limits.h>
 #include "avformat.h"
+#include "swscale.h"
 #include "framehook.h"
 #include "dsputil.h"
 #include "opt.h"
 
-#ifndef CONFIG_WIN32
+#ifndef __MINGW32__
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -40,6 +41,7 @@
 #undef time //needed because HAVE_AV_CONFIG_H is defined on top
 #include <time.h>
 
+#include "version.h"
 #include "cmdutils.h"
 
 #undef NDEBUG
@@ -158,9 +160,8 @@ static int me_penalty_compensation= 256;
 static int frame_skip_threshold= 0;
 static int frame_skip_factor= 0;
 static int frame_skip_exp= 0;
-extern int loop_input; /* currently a hack */
+static int loop_input = 0;
 static int loop_output = AVFMT_NOOUTPUTLOOP;
-static int genpts = 0;
 static int qp_hist = 0;
 
 static int gop_size = 12;
@@ -192,6 +193,7 @@ static char *str_title = NULL;
 static char *str_author = NULL;
 static char *str_copyright = NULL;
 static char *str_comment = NULL;
+static char *str_album = NULL;
 static int do_benchmark = 0;
 static int do_hex_dump = 0;
 static int do_pkt_dump = 0;
@@ -211,12 +213,12 @@ static int video_global_header = 0;
 static int rate_emu = 0;
 
 #ifdef CONFIG_BKTR
-static char *video_grab_format = "bktr";
+static const char *video_grab_format = "bktr";
 #else
 #ifdef CONFIG_VIDEO4LINUX2
-static char *video_grab_format = "video4linux2";
+static const char *video_grab_format = "video4linux2";
 #else
-static char *video_grab_format = "video4linux";
+static const char *video_grab_format = "video4linux";
 #endif
 #endif
 static char *video_device = NULL;
@@ -224,7 +226,7 @@ static char *grab_device = NULL;
 static int  video_channel = 0;
 static char *video_standard = "ntsc";
 
-static char *audio_grab_format = "audio_device";
+static const char *audio_grab_format = "audio_device";
 static char *audio_device = NULL;
 static int audio_volume = 256;
 
@@ -243,11 +245,18 @@ static int input_sync;
 static int limit_filesize = 0; //
 
 static int pgmyuv_compatibility_hack=0;
+static int dts_delta_threshold = 10;
+
+static int sws_flags = SWS_BICUBIC;
 
 const char **opt_names=NULL;
 int opt_name_count=0;
 AVCodecContext *avctx_opts;
+AVFormatContext *avformat_opts;
 
+static AVBitStreamFilterContext *video_bitstream_filters=NULL;
+static AVBitStreamFilterContext *audio_bitstream_filters=NULL;
+static AVBitStreamFilterContext *bitstream_filters[MAX_FILES][MAX_STREAMS];
 
 #define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
 
@@ -266,15 +275,16 @@ typedef struct AVOutputStream {
     struct AVInputStream *sync_ist; /* input stream to sync against */
     int64_t sync_opts;       /* output frame counter, could be changed to some true timestamp */ //FIXME look at frame_number
     /* video only */
-    int video_resample;      /* video_resample and video_crop are mutually exclusive */
+    int video_resample;
     AVFrame pict_tmp;      /* temporary image for resampling */
-    ImgReSampleContext *img_resample_ctx; /* for image resampling */
+    struct SwsContext *img_resample_ctx; /* for image resampling */
+    int resample_height;
 
-    int video_crop;          /* video_resample and video_crop are mutually exclusive */
+    int video_crop;
     int topBand;             /* cropping area sizes */
     int leftBand;
 
-    int video_pad;           /* video_resample and video_pad are mutually exclusive */
+    int video_pad;
     int padtop;              /* padding area sizes */
     int padbottom;
     int padleft;
@@ -312,7 +322,7 @@ typedef struct AVInputFile {
     int nb_streams;       /* nb streams we are aware of */
 } AVInputFile;
 
-#ifndef CONFIG_WIN32
+#ifndef __MINGW32__
 
 /* init terminal so that we can grab keys */
 static struct termios oldtty;
@@ -443,6 +453,25 @@ get_sync_ipts(const AVOutputStream *ost)
     return (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/AV_TIME_BASE;
 }
 
+static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx, AVBitStreamFilterContext *bsfc){
+    while(bsfc){
+        AVPacket new_pkt= *pkt;
+        int a= av_bitstream_filter_filter(bsfc, avctx, NULL,
+                                          &new_pkt.data, &new_pkt.size,
+                                          pkt->data, pkt->size,
+                                          pkt->flags & PKT_FLAG_KEY);
+        if(a){
+            av_free_packet(pkt);
+            new_pkt.destruct= av_destruct_packet;
+        }
+        *pkt= new_pkt;
+
+        bsfc= bsfc->next;
+    }
+
+    av_interleaved_write_frame(s, pkt);
+}
+
 #define MAX_AUDIO_PACKET_SIZE (128 * 1024)
 
 static void do_audio_out(AVFormatContext *s,
@@ -546,7 +575,7 @@ static void do_audio_out(AVFormatContext *s,
             if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
                 pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
             pkt.flags |= PKT_FLAG_KEY;
-            av_interleaved_write_frame(s, &pkt);
+            write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);
 
             ost->sync_opts += enc->frame_size;
         }
@@ -590,7 +619,7 @@ static void do_audio_out(AVFormatContext *s,
         if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
             pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
         pkt.flags |= PKT_FLAG_KEY;
-        av_interleaved_write_frame(s, &pkt);
+        write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);
     }
 }
 
@@ -625,13 +654,7 @@ static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void
                 picture2 = picture;
             }
         } else {
-            if (img_convert(picture2, dec->pix_fmt, picture,
-                            dec->pix_fmt, dec->width, dec->height) < 0) {
-                /* if error, do not copy */
-                av_free(buf);
-                buf = NULL;
-                picture2 = picture;
-            }
+            img_copy(picture2, picture, dec->pix_fmt, dec->width, dec->height);
         }
     } else {
         picture2 = picture;
@@ -647,39 +670,6 @@ static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void
 /* we begin to correct av delay at this threshold */
 #define AV_DELAY_MAX 0.100
 
-
-/* Expects img to be yuv420 */
-static void fill_pad_region(AVPicture* img, int height, int width,
-        int padtop, int padbottom, int padleft, int padright, int *color) {
-
-    int i, y, shift;
-    uint8_t *optr;
-
-    for (i = 0; i < 3; i++) {
-        shift = (i == 0) ? 0 : 1;
-
-        if (padtop || padleft) {
-            memset(img->data[i], color[i], (((img->linesize[i] * padtop) +
-                            padleft) >> shift));
-        }
-
-        if (padleft || padright) {
-            optr = img->data[i] + (img->linesize[i] * (padtop >> shift)) +
-                (img->linesize[i] - (padright >> shift));
-
-            for (y = 0; y < ((height - (padtop + padbottom) - 1) >> shift); y++) {
-                memset(optr, color[i], (padleft + padright) >> shift);
-                optr += img->linesize[i];
-            }
-        }
-
-        if (padbottom || padright) {
-            optr = img->data[i] + (((img->linesize[i] * (height - padbottom)) - padright) >> shift);
-            memset(optr, color[i], (((img->linesize[i] * padbottom) + padright) >> shift));
-        }
-    }
-}
-
 static void do_subtitle_out(AVFormatContext *s,
                             AVOutputStream *ost,
                             AVInputStream *ist,
@@ -728,7 +718,7 @@ static void do_subtitle_out(AVFormatContext *s,
             else
                 pkt.pts += 90 * sub->end_display_time;
         }
-        av_interleaved_write_frame(s, &pkt);
+        write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);
     }
 }
 
@@ -742,14 +732,13 @@ static void do_video_out(AVFormatContext *s,
                          int *frame_size)
 {
     int nb_frames, i, ret;
-    AVFrame *final_picture, *formatted_picture;
-    AVFrame picture_format_temp, picture_crop_temp;
+    AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src;
+    AVFrame picture_crop_temp, picture_pad_temp;
     uint8_t *buf = NULL, *buf1 = NULL;
     AVCodecContext *enc, *dec;
-    enum PixelFormat target_pixfmt;
 
-    avcodec_get_frame_defaults(&picture_format_temp);
     avcodec_get_frame_defaults(&picture_crop_temp);
+    avcodec_get_frame_defaults(&picture_pad_temp);
 
     enc = ost->st->codec;
     dec = ist->st->codec;
@@ -784,135 +773,43 @@ static void do_video_out(AVFormatContext *s,
     if (nb_frames <= 0)
         return;
 
-    /* convert pixel format if needed */
-    target_pixfmt = ost->video_resample || ost->video_pad
-        ? PIX_FMT_YUV420P : enc->pix_fmt;
-    if (dec->pix_fmt != target_pixfmt) {
-        int size;
-
-        /* create temporary picture */
-        size = avpicture_get_size(target_pixfmt, dec->width, dec->height);
-        buf = av_malloc(size);
-        if (!buf)
-            return;
-        formatted_picture = &picture_format_temp;
-        avpicture_fill((AVPicture*)formatted_picture, buf, target_pixfmt, dec->width, dec->height);
-
-        if (img_convert((AVPicture*)formatted_picture, target_pixfmt,
-                        (AVPicture *)in_picture, dec->pix_fmt,
-                        dec->width, dec->height) < 0) {
-
-            if (verbose >= 0)
-                fprintf(stderr, "pixel format conversion not handled\n");
-
+    if (ost->video_crop) {
+        if (img_crop((AVPicture *)&picture_crop_temp, (AVPicture *)in_picture, dec->pix_fmt, ost->topBand, ost->leftBand) < 0) {
+            av_log(NULL, AV_LOG_ERROR, "error cropping picture\n");
             goto the_end;
         }
+        formatted_picture = &picture_crop_temp;
     } else {
         formatted_picture = in_picture;
     }
 
-    /* XXX: resampling could be done before raw format conversion in
-       some cases to go faster */
-    /* XXX: only works for YUV420P */
-    if (ost->video_resample) {
+    final_picture = formatted_picture;
+    padding_src = formatted_picture;
+    resampling_dst = &ost->pict_tmp;
+    if (ost->video_pad) {
         final_picture = &ost->pict_tmp;
-        img_resample(ost->img_resample_ctx, (AVPicture*)final_picture, (AVPicture*)formatted_picture);
-
-        if (ost->padtop || ost->padbottom || ost->padleft || ost->padright) {
-            fill_pad_region((AVPicture*)final_picture, enc->height, enc->width,
-                    ost->padtop, ost->padbottom, ost->padleft, ost->padright,
-                    padcolor);
-        }
-
-        if (enc->pix_fmt != PIX_FMT_YUV420P) {
-            int size;
-
-            av_free(buf);
-            /* create temporary picture */
-            size = avpicture_get_size(enc->pix_fmt, enc->width, enc->height);
-            buf = av_malloc(size);
-            if (!buf)
-                return;
-            final_picture = &picture_format_temp;
-            avpicture_fill((AVPicture*)final_picture, buf, enc->pix_fmt, enc->width, enc->height);
-
-            if (img_convert((AVPicture*)final_picture, enc->pix_fmt,
-                            (AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P,
-                            enc->width, enc->height) < 0) {
-
-                if (verbose >= 0)
-                    fprintf(stderr, "pixel format conversion not handled\n");
-
+        if (ost->video_resample) {
+            if (img_crop((AVPicture *)&picture_pad_temp, (AVPicture *)final_picture, enc->pix_fmt, ost->padtop, ost->padleft) < 0) {
+                av_log(NULL, AV_LOG_ERROR, "error padding picture\n");
                 goto the_end;
             }
+            resampling_dst = &picture_pad_temp;
         }
-    } else if (ost->video_crop) {
-        picture_crop_temp.data[0] = formatted_picture->data[0] +
-                (ost->topBand * formatted_picture->linesize[0]) + ost->leftBand;
-
-        picture_crop_temp.data[1] = formatted_picture->data[1] +
-                ((ost->topBand >> 1) * formatted_picture->linesize[1]) +
-                (ost->leftBand >> 1);
-
-        picture_crop_temp.data[2] = formatted_picture->data[2] +
-                ((ost->topBand >> 1) * formatted_picture->linesize[2]) +
-                (ost->leftBand >> 1);
-
-        picture_crop_temp.linesize[0] = formatted_picture->linesize[0];
-        picture_crop_temp.linesize[1] = formatted_picture->linesize[1];
-        picture_crop_temp.linesize[2] = formatted_picture->linesize[2];
-        final_picture = &picture_crop_temp;
-    } else if (ost->video_pad) {
-        final_picture = &ost->pict_tmp;
-
-        for (i = 0; i < 3; i++) {
-            uint8_t *optr, *iptr;
-            int shift = (i == 0) ? 0 : 1;
-            int y, yheight;
-
-            /* set offset to start writing image into */
-            optr = final_picture->data[i] + (((final_picture->linesize[i] *
-                            ost->padtop) + ost->padleft) >> shift);
-            iptr = formatted_picture->data[i];
-
-            yheight = (enc->height - ost->padtop - ost->padbottom) >> shift;
-            for (y = 0; y < yheight; y++) {
-                /* copy unpadded image row into padded image row */
-                memcpy(optr, iptr, formatted_picture->linesize[i]);
-                optr += final_picture->linesize[i];
-                iptr += formatted_picture->linesize[i];
-            }
-        }
-
-        fill_pad_region((AVPicture*)final_picture, enc->height, enc->width,
-                ost->padtop, ost->padbottom, ost->padleft, ost->padright,
-                padcolor);
-
-        if (enc->pix_fmt != PIX_FMT_YUV420P) {
-            int size;
-
-            av_free(buf);
-            /* create temporary picture */
-            size = avpicture_get_size(enc->pix_fmt, enc->width, enc->height);
-            buf = av_malloc(size);
-            if (!buf)
-                return;
-            final_picture = &picture_format_temp;
-            avpicture_fill((AVPicture*)final_picture, buf, enc->pix_fmt, enc->width, enc->height);
-
-            if (img_convert((AVPicture*)final_picture, enc->pix_fmt,
-                        (AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P,
-                        enc->width, enc->height) < 0) {
+    }
 
-                if (verbose >= 0)
-                    fprintf(stderr, "pixel format conversion not handled\n");
+    if (ost->video_resample) {
+        padding_src = NULL;
+        final_picture = &ost->pict_tmp;
+        sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize,
+              0, ost->resample_height, resampling_dst->data, resampling_dst->linesize);
+    }
 
-                goto the_end;
-            }
-        }
-    } else {
-        final_picture = formatted_picture;
+    if (ost->video_pad) {
+        img_pad((AVPicture*)final_picture, (AVPicture *)padding_src,
+                enc->height, enc->width, enc->pix_fmt,
+                ost->padtop, ost->padbottom, ost->padleft, ost->padright, padcolor);
     }
+
     /* duplicates frame if needed */
     for(i=0;i<nb_frames;i++) {
         AVPacket pkt;
@@ -932,7 +829,7 @@ static void do_video_out(AVFormatContext *s,
             if(dec->coded_frame && dec->coded_frame->key_frame)
                 pkt.flags |= PKT_FLAG_KEY;
 
-            av_interleaved_write_frame(s, &pkt);
+            write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);
             enc->coded_frame = old_frame;
         } else {
             AVFrame big_picture;
@@ -975,7 +872,7 @@ static void do_video_out(AVFormatContext *s,
 
                 if(enc->coded_frame && enc->coded_frame->key_frame)
                     pkt.flags |= PKT_FLAG_KEY;
-                av_interleaved_write_frame(s, &pkt);
+                write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);
                 *frame_size = ret;
                 //fprintf(stderr,"\nFrame: %3d %3d size: %5d type: %d",
                 //        enc->frame_number-1, enc->real_pict_num, ret,
@@ -1396,9 +1293,12 @@ static int output_packet(AVInputStream *ist, int ist_index,
                                 opkt.dts= av_rescale_q(dts + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);
                             }
                             opkt.flags= pkt->flags;
+
+                            //FIXME remove the following 2 lines they shall be replaced by the bitstream filters
                             if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY))
                                 opkt.destruct= av_destruct_packet;
-                            av_interleaved_write_frame(os, &opkt);
+
+                            write_frame(os, &opkt, ost->st->codec, bitstream_filters[ost->file_index][pkt->stream_index]);
                             ost->st->codec->frame_number++;
                             ost->frame_number++;
                             av_free_packet(&opkt);
@@ -1437,12 +1337,27 @@ static int output_packet(AVInputStream *ist, int ist_index,
                 if (ost->encoding_needed) {
                     for(;;) {
                         AVPacket pkt;
+                        int fifo_bytes;
                         av_init_packet(&pkt);
                         pkt.stream_index= ost->index;
 
                         switch(ost->st->codec->codec_type) {
                         case CODEC_TYPE_AUDIO:
-                            ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL);
+                            fifo_bytes = fifo_size(&ost->fifo, NULL);
+                            ret = 0;
+                            /* encode any samples remaining in fifo */
+                            if(fifo_bytes > 0 && enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
+                                int fs_tmp = enc->frame_size;
+                                enc->frame_size = fifo_bytes / (2 * enc->channels);
+                                if(fifo_read(&ost->fifo, (uint8_t *)samples, fifo_bytes,
+                                        &ost->fifo.rptr) == 0) {
+                                    ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);
+                                }
+                                enc->frame_size = fs_tmp;
+                            }
+                            if(ret <= 0) {
+                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL);
+                            }
                             audio_size += ret;
                             pkt.flags |= PKT_FLAG_KEY;
                             break;
@@ -1465,7 +1380,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
                         pkt.size= ret;
                         if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
                             pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
-                        av_interleaved_write_frame(os, &pkt);
+                        write_frame(os, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);
                     }
                 }
             }
@@ -1661,6 +1576,7 @@ static int av_encode(AVFormatContext **output_files,
                 codec->block_align= icodec->block_align;
                 break;
             case CODEC_TYPE_VIDEO:
+                codec->pix_fmt = icodec->pix_fmt;
                 codec->width = icodec->width;
                 codec->height = icodec->height;
                 codec->has_b_frames = icodec->has_b_frames;
@@ -1711,65 +1627,50 @@ static int av_encode(AVFormatContext **output_files,
                 ost->encoding_needed = 1;
                 break;
             case CODEC_TYPE_VIDEO:
-                if (codec->width == icodec->width &&
-                    codec->height == icodec->height &&
-                    frame_topBand == 0 &&
-                    frame_bottomBand == 0 &&
-                    frame_leftBand == 0 &&
-                    frame_rightBand == 0 &&
-                    frame_padtop == 0 &&
-                    frame_padbottom == 0 &&
-                    frame_padleft == 0 &&
-                    frame_padright == 0)
-                {
-                    ost->video_resample = 0;
-                    ost->video_crop = 0;
-                    ost->video_pad = 0;
-                } else if ((codec->width == icodec->width -
-                                (frame_leftBand + frame_rightBand)) &&
-                        (codec->height == icodec->height -
-                                (frame_topBand  + frame_bottomBand)))
-                {
-                    ost->video_resample = 0;
-                    ost->video_crop = 1;
+                ost->video_crop = ((frame_leftBand + frame_rightBand + frame_topBand + frame_bottomBand) != 0);
+                ost->video_pad = ((frame_padleft + frame_padright + frame_padtop + frame_padbottom) != 0);
+                ost->video_resample = ((codec->width != icodec->width -
+                                (frame_leftBand + frame_rightBand) +
+                                (frame_padleft + frame_padright)) ||
+                        (codec->height != icodec->height -
+                                (frame_topBand  + frame_bottomBand) +
+                                (frame_padtop + frame_padbottom)) ||
+                        (codec->pix_fmt != icodec->pix_fmt));
+                if (ost->video_crop) {
                     ost->topBand = frame_topBand;
                     ost->leftBand = frame_leftBand;
-                } else if ((codec->width == icodec->width +
-                                (frame_padleft + frame_padright)) &&
-                        (codec->height == icodec->height +
-                                (frame_padtop + frame_padbottom))) {
-                    ost->video_resample = 0;
-                    ost->video_crop = 0;
-                    ost->video_pad = 1;
+                }
+                if (ost->video_pad) {
                     ost->padtop = frame_padtop;
                     ost->padleft = frame_padleft;
                     ost->padbottom = frame_padbottom;
                     ost->padright = frame_padright;
+                    if (!ost->video_resample) {
+                        avcodec_get_frame_defaults(&ost->pict_tmp);
+                        if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, codec->pix_fmt,
+                                         codec->width, codec->height ) )
+                            goto fail;
+                    }
+                }
+                if (ost->video_resample) {
                     avcodec_get_frame_defaults(&ost->pict_tmp);
-                    if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P,
-                                codec->width, codec->height ) )
-                        goto fail;
-                } else {
-                    ost->video_resample = 1;
-                    ost->video_crop = 0; // cropping is handled as part of resample
-                    avcodec_get_frame_defaults(&ost->pict_tmp);
-                    if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P,
+                    if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, codec->pix_fmt,
                                          codec->width, codec->height ) )
                         goto fail;
 
-                    ost->img_resample_ctx = img_resample_full_init(
-                                      codec->width, codec->height,
-                                      icodec->width, icodec->height,
-                                      frame_topBand, frame_bottomBand,
-                            frame_leftBand, frame_rightBand,
-                            frame_padtop, frame_padbottom,
-                            frame_padleft, frame_padright);
-
-                    ost->padtop = frame_padtop;
-                    ost->padleft = frame_padleft;
-                    ost->padbottom = frame_padbottom;
-                    ost->padright = frame_padright;
-
+                    ost->img_resample_ctx = sws_getContext(
+                            icodec->width - (frame_leftBand + frame_rightBand),
+                            icodec->height - (frame_topBand + frame_bottomBand),
+                            icodec->pix_fmt,
+                            codec->width - (frame_padleft + frame_padright),
+                            codec->height - (frame_padtop + frame_padbottom),
+                            codec->pix_fmt,
+                            sws_flags, NULL, NULL, NULL);
+                    if (ost->img_resample_ctx == NULL) {
+                        fprintf(stderr, "Cannot get resampling context\n");
+                        exit(1);
+                    }
+                    ost->resample_height = icodec->height - (frame_topBand + frame_bottomBand);
                 }
                 ost->encoding_needed = 1;
                 ist->decoding_needed = 1;
@@ -1957,7 +1858,7 @@ static int av_encode(AVFormatContext **output_files,
         }
     }
 
-#ifndef CONFIG_WIN32
+#ifndef __MINGW32__
     if ( !using_stdin && verbose >= 0) {
         fprintf(stderr, "Press [q] to stop encoding\n");
         url_set_interrupt_cb(decode_interrupt_cb);
@@ -2055,7 +1956,7 @@ static int av_encode(AVFormatContext **output_files,
 //        fprintf(stderr, "next:%lld dts:%lld off:%lld %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec->codec_type);
         if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE) {
             int64_t delta= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q) - ist->next_pts;
-            if(ABS(delta) > 10LL*AV_TIME_BASE && !copy_ts){
+            if(ABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE && !copy_ts){
                 input_files_ts_offset[ist->file_index]-= delta;
                 if (verbose > 2)
                     fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", delta, input_files_ts_offset[ist->file_index]);
@@ -2147,7 +2048,7 @@ static int av_encode(AVFormatContext **output_files,
                                           initialized but set to zero */
                 av_free(ost->pict_tmp.data[0]);
                 if (ost->video_resample)
-                    img_resample_close(ost->img_resample_ctx);
+                    sws_freeContext(ost->img_resample_ctx);
                 if (ost->audio_resample)
                     audio_resample_close(ost->resample);
                 av_free(ost);
@@ -2504,9 +2405,9 @@ static void opt_pre_me(const char *arg)
 static void opt_qscale(const char *arg)
 {
     video_qscale = atof(arg);
-    if (video_qscale < 0.01 ||
+    if (video_qscale <= 0 ||
         video_qscale > 255) {
-        fprintf(stderr, "qscale must be >= 0.01 and <= 255\n");
+        fprintf(stderr, "qscale must be > 0.0 and <= 255\n");
         exit(1);
     }
 }
@@ -2880,7 +2781,10 @@ static void opt_input_file(const char *filename)
                    !strcmp( filename, "/dev/stdin" );
 
     /* get default parameters from command line */
+    ic = av_alloc_format_context();
+
     memset(ap, 0, sizeof(*ap));
+    ap->prealloced_context = 1;
     ap->sample_rate = audio_sample_rate;
     ap->channels = audio_channels;
     ap->time_base.den = frame_rate;
@@ -2897,6 +2801,12 @@ static void opt_input_file(const char *filename)
     if(pgmyuv_compatibility_hack)
         ap->video_codec_id= CODEC_ID_PGMYUV;
 
+    for(i=0; i<opt_name_count; i++){
+        AVOption *opt;
+        double d= av_get_double(avformat_opts, opt_names[i], &opt);
+        if(d==d && (opt->flags&AV_OPT_FLAG_DECODING_PARAM))
+            av_set_double(ic, opt_names[i], d);
+    }
     /* open the input file with generic libav function */
     err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
     if (err < 0) {
@@ -2904,8 +2814,7 @@ static void opt_input_file(const char *filename)
         exit(1);
     }
 
-    if(genpts)
-        ic->flags|= AVFMT_FLAG_GENPTS;
+    ic->loop_input = loop_input;
 
     /* If not enough info to get the stream parameters, we decode the
        first frames to get it. (used in mpeg case for example) */
@@ -3066,6 +2975,9 @@ static void new_video_stream(AVFormatContext *oc)
         fprintf(stderr, "Could not alloc stream\n");
         exit(1);
     }
+    bitstream_filters[nb_output_files][oc->nb_streams - 1]= video_bitstream_filters;
+    video_bitstream_filters= NULL;
+
 #if defined(HAVE_THREADS)
     if(thread_count>1)
         avcodec_thread_init(st->codec, thread_count);
@@ -3131,7 +3043,7 @@ static void new_video_stream(AVFormatContext *oc)
 
         video_enc->width = frame_width + frame_padright + frame_padleft;
         video_enc->height = frame_height + frame_padtop + frame_padbottom;
-        video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
+        video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*video_enc->height/video_enc->width, 255);
         video_enc->pix_fmt = frame_pix_fmt;
 
         if(codec && codec->pix_fmts){
@@ -3265,6 +3177,10 @@ static void new_audio_stream(AVFormatContext *oc)
         fprintf(stderr, "Could not alloc stream\n");
         exit(1);
     }
+
+    bitstream_filters[nb_output_files][oc->nb_streams - 1]= audio_bitstream_filters;
+    audio_bitstream_filters= NULL;
+
 #if defined(HAVE_THREADS)
     if(thread_count>1)
         avcodec_thread_init(st->codec, thread_count);
@@ -3394,7 +3310,7 @@ static void opt_new_video_stream(void)
 static void opt_output_file(const char *filename)
 {
     AVFormatContext *oc;
-    int use_video, use_audio, input_has_video, input_has_audio;
+    int use_video, use_audio, input_has_video, input_has_audio, i;
     AVFormatParameters params, *ap = &params;
 
     if (!strcmp(filename, "-"))
@@ -3467,13 +3383,15 @@ static void opt_output_file(const char *filename)
             pstrcpy(oc->copyright, sizeof(oc->copyright), str_copyright);
         if (str_comment)
             pstrcpy(oc->comment, sizeof(oc->comment), str_comment);
+        if (str_album)
+            pstrcpy(oc->album, sizeof(oc->album), str_album);
     }
 
     output_files[nb_output_files++] = oc;
 
     /* check filename in case of an image number is expected */
     if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
-        if (filename_number_test(oc->filename) < 0) {
+        if (!av_filename_number_test(oc->filename)) {
             print_error(oc->filename, AVERROR_NUMEXPECTED);
             exit(1);
         }
@@ -3524,6 +3442,13 @@ static void opt_output_file(const char *filename)
     oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE);
     oc->loop_output = loop_output;
 
+    for(i=0; i<opt_name_count; i++){
+        AVOption *opt;
+        double d = av_get_double(avformat_opts, opt_names[i], &opt);
+        if(d==d && (opt->flags&AV_OPT_FLAG_ENCODING_PARAM))
+            av_set_double(oc, opt_names[i], d);
+    }
+
     /* reset some options */
     file_oformat = NULL;
     file_iformat = NULL;
@@ -3565,6 +3490,10 @@ static void prepare_grab(void)
 
                 if (vp->time_base.num*(int64_t)enc->time_base.den > enc->time_base.num*(int64_t)vp->time_base.den){
                     vp->time_base = enc->time_base;
+                    vp->width += frame_leftBand + frame_rightBand;
+                    vp->width -= (frame_padleft + frame_padright);
+                    vp->height += frame_topBand + frame_bottomBand;
+                    vp->height -= (frame_padtop + frame_padbottom);
                 }
                 has_video = 1;
                 break;
@@ -3635,7 +3564,7 @@ static void opt_pass(const char *pass_str)
     do_pass = pass;
 }
 
-#if defined(CONFIG_WIN32) || defined(CONFIG_OS2)
+#if defined(__MINGW32__) || defined(CONFIG_OS2)
 static int64_t getutime(void)
 {
   return av_gettime();
@@ -3650,7 +3579,9 @@ static int64_t getutime(void)
 }
 #endif
 
+#if defined(CONFIG_FFM_DEMUXER) || defined(CONFIG_FFM_MUXER)
 extern int ffm_nopts;
+#endif
 
 static void show_formats(void)
 {
@@ -3949,11 +3880,13 @@ static void opt_target(const char *arg)
         audio_bit_rate = 448000;
         audio_sample_rate = 48000;
 
-    } else if(!strcmp(arg, "dv")) {
+    } else if(!strncmp(arg, "dv", 2)) {
 
         opt_format("dv");
 
         opt_frame_size(norm ? "720x480" : "720x576");
+        opt_frame_pix_fmt(!strncmp(arg, "dv50", 4) ? "yuv422p" :
+                                             (norm ? "yuv411p" : "yuv420p"));
         opt_frame_rate(frame_rates[norm]);
 
         audio_sample_rate = 48000;
@@ -3965,6 +3898,41 @@ static void opt_target(const char *arg)
     }
 }
 
+static void opt_video_bsf(const char *arg)
+{
+    AVBitStreamFilterContext *bsfc= av_bitstream_filter_init(arg); //FIXME split name and args for filter at '='
+    AVBitStreamFilterContext **bsfp;
+
+    if(!bsfc){
+        fprintf(stderr, "Unkown bitstream filter %s\n", arg);
+        exit(1);
+    }
+
+    bsfp= &video_bitstream_filters;
+    while(*bsfp)
+        bsfp= &(*bsfp)->next;
+
+    *bsfp= bsfc;
+}
+
+//FIXME avoid audio - video code duplication
+static void opt_audio_bsf(const char *arg)
+{
+    AVBitStreamFilterContext *bsfc= av_bitstream_filter_init(arg); //FIXME split name and args for filter at '='
+    AVBitStreamFilterContext **bsfp;
+
+    if(!bsfc){
+        fprintf(stderr, "Unkown bitstream filter %s\n", arg);
+        exit(1);
+    }
+
+    bsfp= &audio_bitstream_filters;
+    while(*bsfp)
+        bsfp= &(*bsfp)->next;
+
+    *bsfp= bsfc;
+}
+
 static void show_version(void)
 {
     /* TODO: add function interface to avutil and avformat */
@@ -3978,6 +3946,8 @@ static void show_version(void)
 
 static int opt_default(const char *opt, const char *arg){
     AVOption *o= av_set_string(avctx_opts, opt, arg);
+    if(!o)
+        o = av_set_string(avformat_opts, opt, arg);
     if(!o)
         return -1;
 
@@ -3987,9 +3957,11 @@ static int opt_default(const char *opt, const char *arg){
     opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
     opt_names[opt_name_count++]= o->name;
 
+#if defined(CONFIG_FFM_DEMUXER) || defined(CONFIG_FFM_MUXER)
     /* disable generate of real time pts in ffm (need to be supressed anyway) */
     if(avctx_opts->flags & CODEC_FLAG_BITEXACT)
         ffm_nopts = 1;
+#endif
 
     if(avctx_opts->debug)
         av_log_set_level(AV_LOG_DEBUG);
@@ -4017,6 +3989,7 @@ const OptionDef options[] = {
     { "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" },
     { "copyright", HAS_ARG | OPT_STRING, {(void*)&str_copyright}, "set the copyright", "string" },
     { "comment", HAS_ARG | OPT_STRING, {(void*)&str_comment}, "set the comment", "string" },
+    { "album", HAS_ARG | OPT_STRING, {(void*)&str_album}, "set the album", "string" },
     { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
       "add timings for benchmarking" },
     { "dump", OPT_BOOL | OPT_EXPERT, {(void*)&do_pkt_dump},
@@ -4024,16 +3997,17 @@ const OptionDef options[] = {
     { "hex", OPT_BOOL | OPT_EXPERT, {(void*)&do_hex_dump},
       "when dumping packets, also dump the payload" },
     { "re", OPT_BOOL | OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate", "" },
-    { "loop", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "loop (current only works with images)" },
+    { "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "loop (current only works with images)" },
     { "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "number of times to loop output in formats that support looping (0 loops forever)", "" },
     { "v", HAS_ARG, {(void*)opt_verbose}, "control amount of logging", "verbose" },
-    { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
+    { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
     { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
     { "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", "" },
     { "vglobal", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_global_header}, "video global header storage type", "" },
     { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)&copy_ts}, "copy timestamps" },
     { "shortest", OPT_BOOL | OPT_EXPERT, {(void*)&opt_shortest}, "finish encoding within shortest input" }, //
+    { "dts_delta_threshold", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "" },
 
     /* video options */
     { "b", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
@@ -4113,7 +4087,6 @@ const OptionDef options[] = {
     { "skip_factor", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_factor}, "frame skip factor", "factor" },
     { "skip_exp", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_exp}, "frame skip exponent", "exponent" },
     { "newvideo", OPT_VIDEO, {(void*)opt_new_video_stream}, "add a new video stream to the current output stream" },
-    { "genpts", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&genpts }, "generate pts" },
     { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" },
 
     /* audio options */
@@ -4148,6 +4121,10 @@ const OptionDef options[] = {
     { "packetsize", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&mux_packet_size}, "set packet size", "size" },
     { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT, {(void*)&mux_max_delay}, "set the maximum demux-decode delay", "seconds" },
     { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT, {(void*)&mux_preload}, "set the initial demux-decode delay", "seconds" },
+
+    { "absf", HAS_ARG | OPT_AUDIO | OPT_EXPERT, {(void*)opt_audio_bsf}, "", "bitstream filter" },
+    { "vbsf", HAS_ARG | OPT_VIDEO | OPT_EXPERT, {(void*)opt_video_bsf}, "", "bitstream filter" },
+
     { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
     { NULL, },
 };
@@ -4236,6 +4213,7 @@ static void show_help(void)
                       OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
                       OPT_EXPERT);
     av_opt_show(avctx_opts, NULL);
+    av_opt_show(avformat_opts, NULL);
 
     exit(1);
 }
@@ -4253,6 +4231,7 @@ int main(int argc, char **argv)
     av_register_all();
 
     avctx_opts= avcodec_alloc_context();
+    avformat_opts = av_alloc_format_context();
 
     if (argc <= 1)
         show_help();
@@ -4307,7 +4286,7 @@ int main(int argc, char **argv)
     powerpc_display_perf_report();
 #endif /* POWERPC_PERFORMANCE_REPORT */
 
-#ifndef CONFIG_WIN32
+#ifndef __MINGW32__
     if (received_sigterm) {
         fprintf(stderr,
             "Received signal %d: terminating.\n",