Hi,

----- Mail original -----
> Hi,
> 
> ----- Mail original -----
> 
> [...]
> 
> > > > >  avienc.c |    7 +++++++
> > > > >  1 file changed, 7 insertions(+)
> > > > > 8ae96276e07eb00474ab2115f9ff9c3d0f690723  avienc.diff
> > > > > diff --git a/libavformat/avienc.c b/libavformat/avienc.c
> > > > > index c9d8b7f..2855293 100644
> > > > > --- a/libavformat/avienc.c
> > > > > +++ b/libavformat/avienc.c
> > > > > @@ -299,6 +299,13 @@ static int
> > > > > avi_write_header(AVFormatContext
> > > > > *s)
> > > > >          avio_wl32(pb, au_ssize); /* sample size */
> > > > >          avio_wl32(pb, 0);
> > > > >          avio_wl16(pb, enc->width);
> > > > > +        if (   enc->extradata_size >= 9
> > > > > +            && !memcmp(enc->extradata + enc->extradata_size
> > > > > -
> > > > > 9,
> > > > > "BottomUp", 9)) {
> > > > > +            enc->height = -enc->height;
> > > > 
> > > > i think its safer not to change AVCodecContext.height and just
> > > > change
> > > > the in the bitstream stored value instead
> > > > 
> > > 
> > > The issue when doing this is that the BITMAPINFOHEADER is wrong.
> > > So the image is still flipped.
> > 
> > Well then you need a local variable/array or value in the avi muxer
> > context. values in AVCodecContext shouldnt really be randomly
> > be overwritten by the muxer
> > 
> 
> The only thing that is needed is to extend ff_put_bmp_header, so that
> it can be asked to negate height in the BITMAPINFOHEADER header.
> Would that be OK?
> 

Here is a patch to illustrate this...
From 27491a189f2e9d0964b4a896fa515185f0e0ac36 Mon Sep 17 00:00:00 2001
From: Benoit Fouet <benoit.fo...@free.fr>
Date: Tue, 23 Sep 2014 10:07:10 +0200
Subject: [PATCH] avformat/riffenc: extend ff_put_bmp_header to be able to
 force height to not be changed.

When stream copying, height shouldn't be changed when writing the
BITMAPINFOHEADER header if the BottomUp information is present in the
extardata.
---
 libavformat/asfenc.c      |  2 +-
 libavformat/avienc.c      | 12 ++++++++++--
 libavformat/matroskaenc.c |  2 +-
 libavformat/riff.h        |  2 +-
 libavformat/riffenc.c     |  4 ++--
 libavformat/wtvenc.c      |  2 +-
 6 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c
index fbf6158..dd48e85 100644
--- a/libavformat/asfenc.c
+++ b/libavformat/asfenc.c
@@ -556,7 +556,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size,
             avio_wl16(pb, 40 + enc->extradata_size); /* size */
 
             /* BITMAPINFOHEADER header */
-            ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 1, 0);
+            ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 1, 0, 0);
         }
         end_header(pb, hpos);
     }
diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index c9d8b7f..e73b6b2 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -313,14 +313,21 @@ static int avi_write_header(AVFormatContext *s)
                  * are not (yet) supported. */
                 if (enc->codec_id != AV_CODEC_ID_XSUB)
                     break;
-            case AVMEDIA_TYPE_VIDEO:
+            case AVMEDIA_TYPE_VIDEO: {
+                int keep_height = enc->extradata_size >= 9
+                               && !memcmp(enc->extradata + enc->extradata_size - 9, "BottomUp", 9);
                 /* WMP expects RGB 5:5:5 rawvideo in avi to have bpp set to 16. */
                 if (  !enc->codec_tag
                     && enc->codec_id == AV_CODEC_ID_RAWVIDEO
                     && enc->pix_fmt == AV_PIX_FMT_RGB555LE
                     && enc->bits_per_coded_sample == 15)
                     enc->bits_per_coded_sample = 16;
-                ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 0, 0);
+                if (keep_height) {
+                    enc->extradata_size -= 9;
+                    if (!enc->extradata_size)
+                        av_freep(&enc->extradata);
+                }
+                ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 0, 0, keep_height);
                 pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi,
                                               enc->bits_per_coded_sample);
                 if (   !enc->codec_tag
@@ -330,6 +337,7 @@ static int avi_write_header(AVFormatContext *s)
                     av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to avi, output file will be unreadable\n",
                           av_get_pix_fmt_name(enc->pix_fmt));
                 break;
+            }
             case AVMEDIA_TYPE_AUDIO:
                 if ((ret = ff_put_wav_header(pb, enc, 0)) < 0)
                     return ret;
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 3fa4bab..ab3cc8d 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -670,7 +670,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
                 ret = AVERROR(EINVAL);
             }
 
-            ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0, 0);
+            ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0, 0, 0);
         }
     } else if (codec->codec_type == AVMEDIA_TYPE_AUDIO) {
         unsigned int tag;
diff --git a/libavformat/riff.h b/libavformat/riff.h
index 88a77b0..7f6adca 100644
--- a/libavformat/riff.h
+++ b/libavformat/riff.h
@@ -45,7 +45,7 @@ void ff_end_tag(AVIOContext *pb, int64_t start);
  */
 int ff_get_bmp_header(AVIOContext *pb, AVStream *st, unsigned *esize);
 
-void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf, int ignore_extradata);
+void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf, int ignore_extradata, int keep_height);
 
 /**
  * Tell ff_put_wav_header() to use WAVEFORMATEX even for PCM codecs.
diff --git a/libavformat/riffenc.c b/libavformat/riffenc.c
index ef4d399..02edb79 100644
--- a/libavformat/riffenc.c
+++ b/libavformat/riffenc.c
@@ -207,13 +207,13 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags)
 
 /* BITMAPINFOHEADER header */
 void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
-                       const AVCodecTag *tags, int for_asf, int ignore_extradata)
+                       const AVCodecTag *tags, int for_asf, int ignore_extradata, int keep_height)
 {
     /* size */
     avio_wl32(pb, 40 + (ignore_extradata ? 0 : enc->extradata_size));
     avio_wl32(pb, enc->width);
     //We always store RGB TopDown
-    avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
+    avio_wl32(pb, enc->codec_tag || keep_height ? enc->height : -enc->height);
     /* planes */
     avio_wl16(pb, 1);
     /* depth */
diff --git a/libavformat/wtvenc.c b/libavformat/wtvenc.c
index 634545d..6381d92 100644
--- a/libavformat/wtvenc.c
+++ b/libavformat/wtvenc.c
@@ -241,7 +241,7 @@ static void put_videoinfoheader2(AVIOContext *pb, AVStream *st)
     avio_wl32(pb, 0);
     avio_wl32(pb, 0);
 
-    ff_put_bmp_header(pb, st->codec, ff_codec_bmp_tags, 0, 1);
+    ff_put_bmp_header(pb, st->codec, ff_codec_bmp_tags, 0, 1, 0);
 
     if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
         int padding = (st->codec->extradata_size & 3) ? 4 - (st->codec->extradata_size & 3) : 0;
-- 
2.1.0.127.g0c72b98

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to