Skip to content

Commit

Permalink
update hls patch
Browse files Browse the repository at this point in the history
  • Loading branch information
wang-bin committed Sep 30, 2024
1 parent 0f10e62 commit bb8b840
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 72 deletions.
48 changes: 24 additions & 24 deletions patches/5.1/0032-hls-support-segments-pretend-to-be-gif-png.patch
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
From bbaa08785c93082c71f18cbd4cbd46bab4609e22 Mon Sep 17 00:00:00 2001
From 99a96ed5d19e4d5656941369624c5d97c1061694 Mon Sep 17 00:00:00 2001
From: wang-bin <[email protected]>
Date: Sun, 29 Sep 2024 15:59:13 +0800
Subject: [PATCH 32/32] hls: support segments pretend to be gif & png

---
libavformat/hls.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
libavformat/hls.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index bf7fdc1553..4b9bfa082b 100644
index bf7fdc1553..3be4c267af 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -45,6 +45,7 @@
#include "id3v2.h"

#include "hls_sample_encryption.h"
+#include "libavcodec/gif.h"

#define INITIAL_BUFFER_SIZE 32768

@@ -220,6 +221,7 @@ typedef struct HLSContext {
@@ -220,6 +220,7 @@ typedef struct HLSContext {
AVIOInterruptCB *interrupt_callback;
AVDictionary *avio_opts;
AVDictionary *seg_format_opts;
+ int seg_allow_img;
char *allowed_extensions;
int max_reload;
int http_persistent;
@@ -2101,7 +2103,22 @@ static int hls_read_header(AVFormatContext *s)
@@ -2101,7 +2102,30 @@ static int hls_read_header(AVFormatContext *s)
pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
pls->ctx->interrupt_callback = s->interrupt_callback;
url = av_strdup(pls->segments[0]->url);
- ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0);
+ unsigned skip = 0;
+ if (!c->seg_allow_img) {
+ uint8_t b[10] = { 0 };
+ uint8_t b[10] = { 0 }; // probe at most 10
+ avio_read(&pls->pb.pub, b, sizeof(b));
+ avio_seek(&pls->pb.pub, 0, SEEK_SET);
+ if (AV_RB64(b) == 0x89504e470d0a1a0a) {
+ skip = 3;
+ av_log(s, AV_LOG_INFO, "segments pretend to be png\n");
+ } else if ((memcmp(b, gif87a_sig, 6) == 0 || memcmp(b, gif89a_sig, 6) == 0)
+ && (AV_RL16(&b[6]) && AV_RL16(&b[8]))) {
+ skip = 10;
+ av_log(s, AV_LOG_INFO, "segments pretend to be gif\n");
+ const AVProbeData pd = {
+ .buf = b, // png, gif read_probe only use this field
+ .buf_size = sizeof(b),
+ };
+// optional: ffifmt(av_find_input_format("gif" or "gif_pipe" or "png_pipe"))->read_probe
+ int max_score = AVPROBE_SCORE_MAX - 2; // png_pipe, gif, gif_pipe score >= AVPROBE_SCORE_MAX - 1
+ const AVInputFormat* img_fmt = av_probe_input_format2(&pd, 1, &max_score); //
+ if (img_fmt) {
+ if (av_strstart(img_fmt->name, "png", NULL)) { // "png_pipe"
+ skip = 3; // skip until ts sync byte 'G'(0x47)
+ av_log(s, AV_LOG_INFO, "segments pretend to be png\n");
+ } else if (av_strstart(img_fmt->name, "gif", NULL)) { // "gif", "gif_pipe"
+ skip = 10;
+ av_log(s, AV_LOG_INFO, "segments pretend to be gif\n");
+ }
+ }
+ }
+
+ ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, skip, 0);
if (ret < 0) {
/* Free the ctx - it isn't initialized properly at this point,
* so avformat_close_input shouldn't be called. If
@@ -2549,6 +2566,8 @@ static const AVOption hls_options[] = {
@@ -2549,6 +2573,8 @@ static const AVOption hls_options[] = {
OFFSET(http_seekable), AV_OPT_TYPE_BOOL, { .i64 = -1}, -1, 1, FLAGS},
{"seg_format_options", "Set options for segment demuxer",
OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
+ {"seg_allow_img", "Allow segments detected as images, 0 = disable, 1 = enable",
+ {"seg_allow_img", "Allow segments detected as gif and png images, 0 = disable, 1 = enable",
+ OFFSET(seg_allow_img), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS},
{NULL}
};
Expand Down
65 changes: 65 additions & 0 deletions patches/6.0/0031-hls-support-segments-pretend-to-be-gif-png.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
From fb0d157faac343e02a02689f799bc16523f6ca75 Mon Sep 17 00:00:00 2001
From: wang-bin <[email protected]>
Date: Sun, 29 Sep 2024 15:59:13 +0800
Subject: [PATCH 31/31] hls: support segments pretend to be gif & png

---
libavformat/hls.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index ce791e0123..38b37bf70a 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -220,6 +220,7 @@ typedef struct HLSContext {
AVIOInterruptCB *interrupt_callback;
AVDictionary *avio_opts;
AVDictionary *seg_format_opts;
+ int seg_allow_img;
char *allowed_extensions;
int max_reload;
int http_persistent;
@@ -2112,7 +2113,30 @@ static int hls_read_header(AVFormatContext *s)
pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
pls->ctx->interrupt_callback = s->interrupt_callback;
url = av_strdup(pls->segments[0]->url);
- ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0);
+ unsigned skip = 0;
+ if (!c->seg_allow_img) {
+ uint8_t b[10] = { 0 }; // probe at most 10
+ avio_read(&pls->pb.pub, b, sizeof(b));
+ avio_seek(&pls->pb.pub, 0, SEEK_SET);
+ const AVProbeData pd = {
+ .buf = b, // png, gif read_probe only use this field
+ .buf_size = sizeof(b),
+ };
+// optional: ffifmt(av_find_input_format("gif" or "gif_pipe" or "png_pipe"))->read_probe
+ int max_score = AVPROBE_SCORE_MAX - 2; // png_pipe, gif, gif_pipe score >= AVPROBE_SCORE_MAX - 1
+ const AVInputFormat* img_fmt = av_probe_input_format2(&pd, 1, &max_score); //
+ if (img_fmt) {
+ if (av_strstart(img_fmt->name, "png", NULL)) { // "png_pipe"
+ skip = 3; // skip until ts sync byte 'G'(0x47)
+ av_log(s, AV_LOG_INFO, "segments pretend to be png\n");
+ } else if (av_strstart(img_fmt->name, "gif", NULL)) { // "gif", "gif_pipe"
+ skip = 10;
+ av_log(s, AV_LOG_INFO, "segments pretend to be gif\n");
+ }
+ }
+ }
+
+ ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, skip, 0);
if (ret < 0) {
/* Free the ctx - it isn't initialized properly at this point,
* so avformat_close_input shouldn't be called. If
@@ -2562,6 +2586,8 @@ static const AVOption hls_options[] = {
OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
{"seg_max_retry", "Maximum number of times to reload a segment on error.",
OFFSET(seg_max_retry), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
+ {"seg_allow_img", "Allow segments detected as gif and png images, 0 = disable, 1 = enable",
+ OFFSET(seg_allow_img), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS},
{NULL}
};

--
2.39.5 (Apple Git-154)

48 changes: 24 additions & 24 deletions patches/6.1/0032-hls-support-segments-pretend-to-be-gif-png.patch
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
From 5b5b8a4c8a8af68d20bf3f60a47bfef62c5d5adc Mon Sep 17 00:00:00 2001
From d61748699d0f0fcdb6136d81fc41b026b9bfcf9b Mon Sep 17 00:00:00 2001
From: wang-bin <[email protected]>
Date: Sun, 29 Sep 2024 15:59:13 +0800
Subject: [PATCH 32/32] hls: support segments pretend to be gif & png

---
libavformat/hls.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
libavformat/hls.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index f5f549b24d..c14676f1d5 100644
index f5f549b24d..e9c1698e0d 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -46,6 +46,7 @@
#include "url.h"

#include "hls_sample_encryption.h"
+#include "libavcodec/gif.h"

#define INITIAL_BUFFER_SIZE 32768

@@ -221,6 +222,7 @@ typedef struct HLSContext {
@@ -221,6 +221,7 @@ typedef struct HLSContext {
AVIOInterruptCB *interrupt_callback;
AVDictionary *avio_opts;
AVDictionary *seg_format_opts;
+ int seg_allow_img;
char *allowed_extensions;
int max_reload;
int http_persistent;
@@ -2104,7 +2106,22 @@ static int hls_read_header(AVFormatContext *s)
@@ -2104,7 +2105,30 @@ static int hls_read_header(AVFormatContext *s)
pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
pls->ctx->interrupt_callback = s->interrupt_callback;
url = av_strdup(pls->segments[0]->url);
- ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0);
+ unsigned skip = 0;
+ if (!c->seg_allow_img) {
+ uint8_t b[10] = { 0 };
+ uint8_t b[10] = { 0 }; // probe at most 10
+ avio_read(&pls->pb.pub, b, sizeof(b));
+ avio_seek(&pls->pb.pub, 0, SEEK_SET);
+ if (AV_RB64(b) == 0x89504e470d0a1a0a) {
+ skip = 3;
+ av_log(s, AV_LOG_INFO, "segments pretend to be png\n");
+ } else if ((memcmp(b, gif87a_sig, 6) == 0 || memcmp(b, gif89a_sig, 6) == 0)
+ && (AV_RL16(&b[6]) && AV_RL16(&b[8]))) {
+ skip = 10;
+ av_log(s, AV_LOG_INFO, "segments pretend to be gif\n");
+ const AVProbeData pd = {
+ .buf = b, // png, gif read_probe only use this field
+ .buf_size = sizeof(b),
+ };
+// optional: ffifmt(av_find_input_format("gif" or "gif_pipe" or "png_pipe"))->read_probe
+ int max_score = AVPROBE_SCORE_MAX - 2; // png_pipe, gif, gif_pipe score >= AVPROBE_SCORE_MAX - 1
+ const AVInputFormat* img_fmt = av_probe_input_format2(&pd, 1, &max_score); //
+ if (img_fmt) {
+ if (av_strstart(img_fmt->name, "png", NULL)) { // "png_pipe"
+ skip = 3; // skip until ts sync byte 'G'(0x47)
+ av_log(s, AV_LOG_INFO, "segments pretend to be png\n");
+ } else if (av_strstart(img_fmt->name, "gif", NULL)) { // "gif", "gif_pipe"
+ skip = 10;
+ av_log(s, AV_LOG_INFO, "segments pretend to be gif\n");
+ }
+ }
+ }
+
+ ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, skip, 0);
if (ret < 0) {
/* Free the ctx - it isn't initialized properly at this point,
* so avformat_close_input shouldn't be called. If
@@ -2579,6 +2596,8 @@ static const AVOption hls_options[] = {
@@ -2579,6 +2603,8 @@ static const AVOption hls_options[] = {
OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
{"seg_max_retry", "Maximum number of times to reload a segment on error.",
OFFSET(seg_max_retry), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
+ {"seg_allow_img", "Allow segments detected as images, 0 = disable, 1 = enable",
+ {"seg_allow_img", "Allow segments detected as gif and png images, 0 = disable, 1 = enable",
+ OFFSET(seg_allow_img), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS},
{NULL}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
From ecda273842418e9827cab2a193138060a4224629 Mon Sep 17 00:00:00 2001
From a5c5359023c696e002f9c52721452c3c4d719a1f Mon Sep 17 00:00:00 2001
From: wang-bin <[email protected]>
Date: Sun, 29 Sep 2024 15:59:13 +0800
Subject: [PATCH 30/30] hls: support segments pretend to be gif & png

---
libavformat/hls.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
libavformat/hls.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index 62473a15dd..2fd7f8ca2f 100644
index 62473a15dd..7aa18079d9 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -47,6 +47,7 @@
#include "url.h"

#include "hls_sample_encryption.h"
+#include "libavcodec/gif.h"

#define INITIAL_BUFFER_SIZE 32768

@@ -222,6 +223,7 @@ typedef struct HLSContext {
@@ -222,6 +222,7 @@ typedef struct HLSContext {
AVIOInterruptCB *interrupt_callback;
AVDictionary *avio_opts;
AVDictionary *seg_format_opts;
+ int seg_allow_img;
char *allowed_extensions;
int max_reload;
int http_persistent;
@@ -2113,7 +2115,22 @@ static int hls_read_header(AVFormatContext *s)
@@ -2113,7 +2114,30 @@ static int hls_read_header(AVFormatContext *s)
pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
pls->ctx->interrupt_callback = s->interrupt_callback;
url = av_strdup(pls->segments[0]->url);
- ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0);
+ unsigned skip = 0;
+ if (!c->seg_allow_img) {
+ uint8_t b[10] = { 0 };
+ uint8_t b[10] = { 0 }; // probe at most 10
+ avio_read(&pls->pb.pub, b, sizeof(b));
+ avio_seek(&pls->pb.pub, 0, SEEK_SET);
+ if (AV_RB64(b) == 0x89504e470d0a1a0a) {
+ skip = 3;
+ av_log(s, AV_LOG_INFO, "segments pretend to be png\n");
+ } else if ((memcmp(b, gif87a_sig, 6) == 0 || memcmp(b, gif89a_sig, 6) == 0)
+ && (AV_RL16(&b[6]) && AV_RL16(&b[8]))) {
+ skip = 10;
+ av_log(s, AV_LOG_INFO, "segments pretend to be gif\n");
+ const AVProbeData pd = {
+ .buf = b, // png, gif read_probe only use this field
+ .buf_size = sizeof(b),
+ };
+// optional: ffifmt(av_find_input_format("gif" or "gif_pipe" or "png_pipe"))->read_probe
+ int max_score = AVPROBE_SCORE_MAX - 2; // png_pipe, gif, gif_pipe score >= AVPROBE_SCORE_MAX - 1
+ const AVInputFormat* img_fmt = av_probe_input_format2(&pd, 1, &max_score); //
+ if (img_fmt) {
+ if (av_strstart(img_fmt->name, "png", NULL)) { // "png_pipe"
+ skip = 3; // skip until ts sync byte 'G'(0x47)
+ av_log(s, AV_LOG_INFO, "segments pretend to be png\n");
+ } else if (av_strstart(img_fmt->name, "gif", NULL)) { // "gif", "gif_pipe"
+ skip = 10;
+ av_log(s, AV_LOG_INFO, "segments pretend to be gif\n");
+ }
+ }
+ }
+
+ ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, skip, 0);
if (ret < 0) {
/* Free the ctx - it isn't initialized properly at this point,
* so avformat_close_input shouldn't be called. If
@@ -2590,6 +2607,8 @@ static const AVOption hls_options[] = {
@@ -2590,6 +2614,8 @@ static const AVOption hls_options[] = {
OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
{"seg_max_retry", "Maximum number of times to reload a segment on error.",
OFFSET(seg_max_retry), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
+ {"seg_allow_img", "Allow segments detected as images, 0 = disable, 1 = enable",
+ {"seg_allow_img", "Allow segments detected as gif and png images, 0 = disable, 1 = enable",
+ OFFSET(seg_allow_img), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS},
{NULL}
};
Expand Down

0 comments on commit bb8b840

Please sign in to comment.