From: Marton Balint <cus@passwd.hu>
To: ffmpeg-devel@ffmpeg.org
Cc: Marton Balint <cus@passwd.hu>
Subject: [FFmpeg-devel] [PATCH 3/3] avformat/electronicarts: add option to return alpha channel in the main video stream in VP6A codec
Date: Sun, 13 Nov 2022 19:44:41 +0100
Message-ID: <20221113184441.1741-3-cus@passwd.hu> (raw)
In-Reply-To: <20221113184441.1741-1-cus@passwd.hu>
Signed-off-by: Marton Balint <cus@passwd.hu>
---
doc/demuxers.texi | 18 ++++++++++++++++
libavformat/electronicarts.c | 42 +++++++++++++++++++++++++++++++-----
libavformat/version.h | 2 +-
3 files changed, 56 insertions(+), 6 deletions(-)
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 2b6dd86c2a..f07f3f5318 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -285,6 +285,24 @@ This demuxer accepts the following option:
@end table
+@section ea
+
+Electronic Arts Multimedia format demuxer.
+
+This format is used by various Electronic Arts games.
+
+@subsection Options
+
+@table @option
+
+@item merge_alpha @var{bool}
+
+Normally the VP6 alpha channel (if exists) is returned as a secondary video
+stream, by setting this option you can make the demuxer return a single video
+stream which contains the alpha channel in addition to the ordinary video.
+
+@end table
+
@section imf
Interoperable Master Format demuxer.
diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index 0532264f38..e7f574aede 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -28,6 +28,7 @@
#include <inttypes.h>
#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "internal.h"
@@ -75,6 +76,8 @@ typedef struct VideoProperties {
} VideoProperties;
typedef struct EaDemuxContext {
+ const AVClass *class;
+
int big_endian;
VideoProperties video, alpha;
@@ -88,6 +91,7 @@ typedef struct EaDemuxContext {
int num_samples;
int platform;
+ int merge_alpha;
} EaDemuxContext;
static uint32_t read_arbitrary(AVIOContext *pb)
@@ -442,6 +446,10 @@ static int process_ea_header(AVFormatContext *s)
case AVhd_TAG:
err = process_video_header_vp6(s, &ea->alpha);
+ if (err >= 0 && ea->video.codec == AV_CODEC_ID_VP6 && ea->merge_alpha) {
+ ea->alpha.codec = 0;
+ ea->video.codec = AV_CODEC_ID_VP6A;
+ }
break;
}
@@ -578,7 +586,7 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
int partial_packet = 0;
int hit_end = 0;
unsigned int chunk_type, chunk_size;
- int ret = 0, packet_read = 0, key = 0;
+ int ret = 0, packet_read = 0, key = 0, vp6a;
int av_uninit(num_samples);
while ((!packet_read && !hit_end) || partial_packet) {
@@ -721,19 +729,28 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
get_video_packet:
if (!chunk_size)
continue;
+ if (chunk_size > INT_MAX - 3)
+ return AVERROR_INVALIDDATA;
+
+ vp6a = (ea->video.codec == AV_CODEC_ID_VP6A && (chunk_type == MV0F_TAG || chunk_type == MV0K_TAG));
if (partial_packet) {
ret = av_append_packet(pb, pkt, chunk_size);
- } else
- ret = av_get_packet(pb, pkt, chunk_size);
+ } else {
+ if (vp6a)
+ avio_seek(pb, -3, SEEK_CUR);
+ ret = av_get_packet(pb, pkt, chunk_size + (vp6a ? 3 : 0));
+ if (ret >= 0 && vp6a)
+ AV_WB24(pkt->data, chunk_size);
+ }
packet_read = 1;
if (ret < 0) {
partial_packet = 0;
break;
}
- partial_packet = chunk_type == MVIh_TAG;
- if (chunk_type == AV0K_TAG || chunk_type == AV0F_TAG)
+ partial_packet = vp6a || chunk_type == MVIh_TAG;
+ if (ea->alpha.codec && (chunk_type == AV0K_TAG || chunk_type == AV0F_TAG))
pkt->stream_index = ea->alpha.stream_index;
else
pkt->stream_index = ea->video.stream_index;
@@ -752,6 +769,20 @@ get_video_packet:
return ret;
}
+#define OFFSET(x) offsetof(EaDemuxContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ {"merge_alpha", "return VP6 alpha in the main video stream", OFFSET(merge_alpha), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS },
+ {NULL}
+};
+
+static const AVClass ea_class = {
+ .class_name = "ea demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
const AVInputFormat ff_ea_demuxer = {
.name = "ea",
.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia"),
@@ -759,4 +790,5 @@ const AVInputFormat ff_ea_demuxer = {
.read_probe = ea_probe,
.read_header = ea_read_header,
.read_packet = ea_read_packet,
+ .priv_class = &ea_class,
};
diff --git a/libavformat/version.h b/libavformat/version.h
index 7c9d50b7b3..a7e5a9ac66 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -32,7 +32,7 @@
#include "version_major.h"
#define LIBAVFORMAT_VERSION_MINOR 34
-#define LIBAVFORMAT_VERSION_MICRO 101
+#define LIBAVFORMAT_VERSION_MICRO 102
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
--
2.35.3
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2022-11-13 18:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-13 18:44 [FFmpeg-devel] [PATCH 1/3] avformat/electronicarts: fix EOF check Marton Balint
2022-11-13 18:44 ` [FFmpeg-devel] [PATCH 2/3] avformat/electronicarts: set packet_read in one place Marton Balint
2022-11-17 7:30 ` Peter Ross
2022-11-13 18:44 ` Marton Balint [this message]
2022-11-14 16:34 ` [FFmpeg-devel] [PATCH 3/3] avformat/electronicarts: add option to return alpha channel in the main video stream in VP6A codec Anton Khirnov
2022-11-14 22:05 ` Marton Balint
2022-11-17 7:32 ` Peter Ross
2022-11-22 22:31 ` Marton Balint
2022-11-17 7:29 ` [FFmpeg-devel] [PATCH 1/3] avformat/electronicarts: fix EOF check Peter Ross
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221113184441.1741-3-cus@passwd.hu \
--to=cus@passwd.hu \
--cc=ffmpeg-devel@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git