diff mbox

[FFmpeg-devel] Add new MPEG bitstream filter

Message ID 20170801122233.15918-1-david.griffiths@gmail.com
State New
Headers show

Commit Message

David Griffiths Aug. 1, 2017, 12:22 p.m. UTC
Given an MPEG1/2 stream, this bitstream filter can be used to modify
the sequence headers. The most common use would be to change the
aspect ration without the need for re-encoding. Some MOD files have
the aspect ratio incorrectly set to 4:3
(see https://en.wikipedia.org/wiki/MOD_and_TOD).
---
 doc/bitstream_filters.texi           |  21 ++++++++
 libavcodec/Makefile                  |   1 +
 libavcodec/bitstream_filters.c       |   1 +
 libavcodec/mod_mpeg_seq_header_bsf.c | 102 +++++++++++++++++++++++++++++++++++
 4 files changed, 125 insertions(+)
 create mode 100644 libavcodec/mod_mpeg_seq_header_bsf.c

Comments

Jan Ekström Aug. 1, 2017, 6:05 p.m. UTC | #1
Hi,

On Tue, Aug 1, 2017 at 3:22 PM, David Griffiths
<david.griffiths@gmail.com> wrote:
> Given an MPEG1/2 stream, this bitstream filter can be used to modify
> the sequence headers. The most common use would be to change the
> aspect ration without the need for re-encoding. Some MOD files have
> the aspect ratio incorrectly set to 4:3
> (see https://en.wikipedia.org/wiki/MOD_and_TOD).

Thanks for the contribution, but this looks like a limited version of
https://lists.libav.org/pipermail/libav-devel/2017-July/084528.html ,
which seems to contain support for MPEG-2 bit stream filtering as
well.

Please see if you can cherry-pick this patch set and test with it. The
framework posted on libav-devel seems more complete and seems to
support other formats than just MPEG-2 video. If it works for you,
feel free to post the patch set here as well.

Best regards,
Jan
David Griffiths Aug. 1, 2017, 7:24 p.m. UTC | #2
Hi, I was not aware of that. I'm not that familiar with the
differences between ffmpeg and libav. Do you know if the libav "coded
bitstream editing" framework you mention is documented anywhere?

Cheers,

David

On 1 August 2017 at 19:05, Jan Ekstrom <jeebjp@gmail.com> wrote:
> Hi,
>
> On Tue, Aug 1, 2017 at 3:22 PM, David Griffiths
> <david.griffiths@gmail.com> wrote:
>> Given an MPEG1/2 stream, this bitstream filter can be used to modify
>> the sequence headers. The most common use would be to change the
>> aspect ration without the need for re-encoding. Some MOD files have
>> the aspect ratio incorrectly set to 4:3
>> (see https://en.wikipedia.org/wiki/MOD_and_TOD).
>
> Thanks for the contribution, but this looks like a limited version of
> https://lists.libav.org/pipermail/libav-devel/2017-July/084528.html ,
> which seems to contain support for MPEG-2 bit stream filtering as
> well.
>
> Please see if you can cherry-pick this patch set and test with it. The
> framework posted on libav-devel seems more complete and seems to
> support other formats than just MPEG-2 video. If it works for you,
> feel free to post the patch set here as well.
>
> Best regards,
> Jan
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Mark Thompson Aug. 1, 2017, 7:59 p.m. UTC | #3
On 01/08/17 19:05, Jan Ekstrom wrote:
> Hi,
> 
> On Tue, Aug 1, 2017 at 3:22 PM, David Griffiths
> <david.griffiths@gmail.com> wrote:
>> Given an MPEG1/2 stream, this bitstream filter can be used to modify
>> the sequence headers. The most common use would be to change the
>> aspect ration without the need for re-encoding. Some MOD files have
>> the aspect ratio incorrectly set to 4:3
>> (see https://en.wikipedia.org/wiki/MOD_and_TOD).
> 
> Thanks for the contribution, but this looks like a limited version of
> https://lists.libav.org/pipermail/libav-devel/2017-July/084528.html ,
> which seems to contain support for MPEG-2 bit stream filtering as
> well.
I'm intending to bring this across myself soon.  It's slightly awkward because it's all written against Alexandra's bitstream API and would need to be changed to get_bits here.  (I was hoping the API would come at some point, but apparently people here are generally against it.  Oh well.)

Anyway, I finished off a half-written MPEG-2 metadata filter which will do the stuff described here: <https://lists.libav.org/pipermail/libav-devel/2017-August/084563.html>.  I've ignored MPEG-1 so far, but it would probably be easy to add if anyone cares.

- Mark
David Griffiths Aug. 1, 2017, 8:15 p.m. UTC | #4
Hi, that certainly does sound as though it does the same as my patch plus
more. I will download libav and have a play.

Cheers,

David

On Tue, 1 Aug 2017 at 20:59, Mark Thompson <sw@jkqxz.net> wrote:

> On 01/08/17 19:05, Jan Ekstrom wrote:
> > Hi,
> >
> > On Tue, Aug 1, 2017 at 3:22 PM, David Griffiths
> > <david.griffiths@gmail.com> wrote:
> >> Given an MPEG1/2 stream, this bitstream filter can be used to modify
> >> the sequence headers. The most common use would be to change the
> >> aspect ration without the need for re-encoding. Some MOD files have
> >> the aspect ratio incorrectly set to 4:3
> >> (see https://en.wikipedia.org/wiki/MOD_and_TOD).
> >
> > Thanks for the contribution, but this looks like a limited version of
> > https://lists.libav.org/pipermail/libav-devel/2017-July/084528.html ,
> > which seems to contain support for MPEG-2 bit stream filtering as
> > well.
> I'm intending to bring this across myself soon.  It's slightly awkward
> because it's all written against Alexandra's bitstream API and would need
> to be changed to get_bits here.  (I was hoping the API would come at some
> point, but apparently people here are generally against it.  Oh well.)
>
> Anyway, I finished off a half-written MPEG-2 metadata filter which will do
> the stuff described here: <
> https://lists.libav.org/pipermail/libav-devel/2017-August/084563.html>.
> I've ignored MPEG-1 so far, but it would probably be easy to add if anyone
> cares.
>
> - Mark
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
diff mbox

Patch

diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index 2dffe021f9..c9801f966c 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -186,6 +186,27 @@  ffmpeg -i frame_%d.jpg -c:v copy rotated.avi
 Add an MJPEG A header to the bitstream, to enable decoding by
 Quicktime.
 
+@section mod_mpeg_seq_header
+
+Given an MPEG1/2 stream, this bitstream filter can be used to modify
+the sequence headers. The most common use would be to change the
+aspect ration without the need for re-encoding. Some MOD files have
+the aspect ratio incorrectly set to 4:3 (see 
+@url{https://en.wikipedia.org/wiki/MOD_and_TOD}).
+
+To set widescreen format in a mod file do this:
+
+@example
+ffmpeg -i in.mod -bsf:v mod_mpeg_seq_header=aspect_ratio=3 -codec copy out.mpeg
+@end example
+
+@table @option
+@item aspect_ratio
+Common values are 2 for 4:3 format and 3 for 16:9 (widescreen).
+@item frame_rate
+Use 2 for 24 fps and 3 for 25 fps.
+@end table
+
 @anchor{mov2textsub}
 @section mov2textsub
 
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 357fa1a361..e275eb6062 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1002,6 +1002,7 @@  OBJS-$(CONFIG_TEXT2MOVSUB_BSF)            += movsub_bsf.o
 OBJS-$(CONFIG_VP9_RAW_REORDER_BSF)        += vp9_raw_reorder_bsf.o
 OBJS-$(CONFIG_VP9_SUPERFRAME_BSF)         += vp9_superframe_bsf.o
 OBJS-$(CONFIG_VP9_SUPERFRAME_SPLIT_BSF)   += vp9_superframe_split_bsf.o
+OBJS-$(CONFIG_MOD_MPEG_SEQ_HEADER_BSF)    += mod_mpeg_seq_header_bsf.o
 
 # thread libraries
 OBJS-$(HAVE_LIBC_MSVCRT)               += file_open.o
diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
index ce34de640d..dfe46e3e0c 100644
--- a/libavcodec/bitstream_filters.c
+++ b/libavcodec/bitstream_filters.c
@@ -44,6 +44,7 @@  extern const AVBitStreamFilter ff_text2movsub_bsf;
 extern const AVBitStreamFilter ff_vp9_raw_reorder_bsf;
 extern const AVBitStreamFilter ff_vp9_superframe_bsf;
 extern const AVBitStreamFilter ff_vp9_superframe_split_bsf;
+extern const AVBitStreamFilter ff_mod_mpeg_seq_header_bsf;
 
 #include "libavcodec/bsf_list.c"
 
diff --git a/libavcodec/mod_mpeg_seq_header_bsf.c b/libavcodec/mod_mpeg_seq_header_bsf.c
new file mode 100644
index 0000000000..824197746b
--- /dev/null
+++ b/libavcodec/mod_mpeg_seq_header_bsf.c
@@ -0,0 +1,102 @@ 
+/*
+ * Modify MPEG Sequence Headers bitstream filter
+ * Copyright (c) 2017 David Griffiths <david.griffiths@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Modify MPEG Sequence Headers bitstream filter
+ */
+
+#include "avcodec.h"
+#include "bsf.h"
+#include "internal.h"
+
+#include "libavutil/opt.h"
+
+typedef struct ModifySeqHeaderContext {
+    const AVClass *class;
+    int aspect_ratio;
+    int frame_rate;
+    int done_log;
+} ModifySeqHeaderContext;
+
+/**
+ * This filter can be used to modify the sequence headers for aspect ratio
+ * and/or frame rate without the need for transcoding.
+ */
+static int mod_mpeg_seq_header_filter(AVBSFContext *ctx, AVPacket *out)
+{
+    ModifySeqHeaderContext *s = ctx->priv_data;
+    AVPacket *in;
+    int ret;
+
+    ret = ff_bsf_get_packet(ctx, &in);
+    if (ret < 0)
+        return ret;
+
+    if (in->data[0] == 0 && in->data[1] == 0 && in->data[2] == 1 && 
+      in->data[3] == 0xb3) {
+        if (!s->done_log)
+            av_log(ctx, AV_LOG_INFO, "old aspect byte was %x\n", in->data[7]);
+        if (s->aspect_ratio != 0) {
+            in->data[7] = (s->aspect_ratio << 4) | (in->data[7] & 0xf);
+        }
+        if (s->frame_rate != 0) {
+            in->data[7] = s->frame_rate | (in->data[7] & 0xf0);
+        }
+        if (!s->done_log)
+            av_log(ctx, AV_LOG_INFO, "new aspect byte is %x\n", in->data[7]);
+        s->done_log = 1;
+    }
+
+    av_packet_move_ref(out, in);
+    av_packet_free(&in);
+
+    return 0;
+}
+
+static const enum AVCodecID codec_ids[] = {
+    AV_CODEC_ID_MPEG1VIDEO,
+    AV_CODEC_ID_MPEG2VIDEO,
+    AV_CODEC_ID_NONE,
+};
+
+#define OFFSET(x) offsetof(ModifySeqHeaderContext, x)
+static const AVOption options[] = {
+    { "aspect_ratio", NULL, OFFSET(aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 14 },
+    { "frame_rate", NULL, OFFSET(frame_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8 },
+    { NULL },
+};
+
+static const AVClass mod_mpeg_seq_header_class = {
+    .class_name = "mod_mpeg_seq_header",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+
+const AVBitStreamFilter ff_mod_mpeg_seq_header_bsf = {
+    .name   = "mod_mpeg_seq_header",
+    .priv_data_size = sizeof(ModifySeqHeaderContext),
+    .priv_class     = &mod_mpeg_seq_header_class,
+    .filter = mod_mpeg_seq_header_filter,
+    .codec_ids = codec_ids,
+};