Re: [FFmpeg-devel] [PATCH v6] lavf/flv: Add XV (Xunlei Video) Support. Fixes ticket #3720

2019-04-12 Thread Michael Niedermayer
On Fri, Apr 12, 2019 at 07:15:49AM +0530, Shivam wrote:
> On 4/10/19 10:05 PM, Michael Niedermayer wrote:
> >On Tue, Apr 09, 2019 at 11:50:16PM +0530, Shivam Goyal wrote:
> >>lavf/flv: Add XV (Xunlei Video) Support.
> >>
> >>Fixes ticket #3720.
> >>
> >>
> >>
> >>  Changelog|1
> >>  libavformat/Makefile |1
> >>  libavformat/allformats.c |1
> >>  libavformat/flvdec.c |   86 
> >> +++
> >>  libavformat/version.h|2 -
> >>  5 files changed, 90 insertions(+), 1 deletion(-)
> >>c221c019d4dcd7063828c54567b8fc7c905b211b  added_xv_support_v6.patch
> >> From 605dc262abf948813c26d58f51d5e2d7f498d9cd Mon Sep 17 00:00:00 2001
> >>From: Shivam Goyal
> >>Date: Tue, 9 Apr 2019 23:36:27 +0530
> >>Subject: [PATCH] lavf/flv: Add XV (Xunlei Video) Support. Fixes ticket 
> >>#3720.
> >>
> >>---
> >>  Changelog|  1 +
> >>  libavformat/Makefile |  1 +
> >>  libavformat/allformats.c |  1 +
> >>  libavformat/flvdec.c | 86 
> >>  libavformat/version.h|  2 +-
> >>  5 files changed, 90 insertions(+), 1 deletion(-)
> >>
> >>diff --git a/Changelog b/Changelog
> >>index 8c866cd0c2..8caaab53c2 100644
> >>--- a/Changelog
> >>+++ b/Changelog
> >>@@ -22,6 +22,7 @@ version :
> >>  - removed libndi-newtek
> >>  - agm decoder
> >>  - KUX demuxer
> >>+- XV (Xunlei Video) demuxer
> >>  version 4.1:
> >>diff --git a/libavformat/Makefile b/libavformat/Makefile
> >>index 99be60d184..e090c051f1 100644
> >>--- a/libavformat/Makefile
> >>+++ b/libavformat/Makefile
> >>@@ -561,6 +561,7 @@ OBJS-$(CONFIG_WV_MUXER)  += wvenc.o 
> >>wv.o apetag.o img2.o
> >>  OBJS-$(CONFIG_XA_DEMUXER)+= xa.o
> >>  OBJS-$(CONFIG_XBIN_DEMUXER)  += bintext.o sauce.o
> >>  OBJS-$(CONFIG_XMV_DEMUXER)   += xmv.o
> >>+OBJS-$(CONFIG_XV_DEMUXER)+= flvdec.o
> >>  OBJS-$(CONFIG_XVAG_DEMUXER)  += xvag.o
> >>  OBJS-$(CONFIG_XWMA_DEMUXER)  += xwma.o
> >>  OBJS-$(CONFIG_YOP_DEMUXER)   += yop.o
> >>diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> >>index d316a0529a..b499186071 100644
> >>--- a/libavformat/allformats.c
> >>+++ b/libavformat/allformats.c
> >>@@ -456,6 +456,7 @@ extern AVOutputFormat ff_wv_muxer;
> >>  extern AVInputFormat  ff_xa_demuxer;
> >>  extern AVInputFormat  ff_xbin_demuxer;
> >>  extern AVInputFormat  ff_xmv_demuxer;
> >>+extern AVInputFormat  ff_xv_demuxer;
> >>  extern AVInputFormat  ff_xvag_demuxer;
> >>  extern AVInputFormat  ff_xwma_demuxer;
> >>  extern AVInputFormat  ff_yop_demuxer;
> >>diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
> >>index b531a39adc..a56f5b448a 100644
> >>--- a/libavformat/flvdec.c
> >>+++ b/libavformat/flvdec.c
> >>@@ -127,6 +127,19 @@ static int kux_probe(const AVProbeData *p)
> >>  return 0;
> >>  }
> >>+static int xv_probe(const AVProbeData *p)
> >>+{
> >>+const uint8_t *d = p->buf;
> >>+
> >>+if (d[0] == 'X' &&
> >>+d[1] == 'L' &&
> >>+d[2] == 'V' &&
> >>+d[3] == 'F') {
> >>+return AVPROBE_SCORE_EXTENSION + 1;
> >>+}
> >>+return 0;
> >>+}
> >>+
> >>  static void add_keyframes_index(AVFormatContext *s)
> >>  {
> >>  FLVContext *flv   = s->priv_data;
> >>@@ -459,6 +472,12 @@ static int parse_keyframes_index(AVFormatContext *s, 
> >>AVIOContext *ioc, int64_t m
> >>  }
> >>  }
> >>+if (!strcmp(s->iformat->name , "xv")) {
> >>+for (i = 0; i < FFMIN(2,fileposlen); i++) {
> >>+filepositions[i] += 0x20;
> >>+}
> >>+}
> >>+
> >>  if (timeslen == fileposlen && fileposlen>1 && max_pos <= 
> >> filepositions[0]) {
> >>  for (i = 0; i < FFMIN(2,fileposlen); i++) {
> >>  flv->validate_index[i].pos = filepositions[i];
> >>@@ -783,6 +802,52 @@ static int flv_read_header(AVFormatContext *s)
> >>  return 0;
> >>  }
> >>+static int xv_read_header(AVFormatContext *s)
> >>+{
> >>+int flags;
> >>+FLVContext *xv = s->priv_data;
> >>+AVIOContext *ic = s->pb;
> >>+int offset;
> >>+int rot;
> >>+int i;
> >>+int64_t pos;
> >>+
> >>+//Find the rot value for rotating the bytes
> >>+avio_skip(ic, 0x20);
> >>+rot = 0x46 - avio_r8(ic);
> >>+
> >>+avio_skip(ic, 3);
> >>+
> >>+flags = (avio_r8(ic) + rot) & 0xff;
> >>+
> >>+xv->missing_streams = flags & (FLV_HEADER_FLAG_HASVIDEO | 
> >>FLV_HEADER_FLAG_HASAUDIO);
> >>+
> >>+s->ctx_flags |= AVFMTCTX_NOHEADER;
> >>+
> >>+offset = ((avio_r8(ic) + rot & 0xff) << 24 |
> >>+  (avio_r8(ic) + rot & 0xff) << 16 |
> >>+  (avio_r8(ic) + rot & 0xff) << 8 |
> >>+  (avio_r8(ic) + rot & 0xff)) + 0x20;
> >>+
> >>+avio_seek(ic, offset + 4, SEEK_SET);
> >>+
> >>+
> >>+// Will modify the current buffer, as only
> >>+// the bytes from 0x20 to 0x200400 are needed to decode
> >>+pos = ic->pos + 

Re: [FFmpeg-devel] [PATCH v6] lavf/flv: Add XV (Xunlei Video) Support. Fixes ticket #3720

2019-04-11 Thread Shivam

On 4/10/19 10:05 PM, Michael Niedermayer wrote:

On Tue, Apr 09, 2019 at 11:50:16PM +0530, Shivam Goyal wrote:

lavf/flv: Add XV (Xunlei Video) Support.

Fixes ticket #3720.



  Changelog|1
  libavformat/Makefile |1
  libavformat/allformats.c |1
  libavformat/flvdec.c |   86 
+++
  libavformat/version.h|2 -
  5 files changed, 90 insertions(+), 1 deletion(-)
c221c019d4dcd7063828c54567b8fc7c905b211b  added_xv_support_v6.patch
 From 605dc262abf948813c26d58f51d5e2d7f498d9cd Mon Sep 17 00:00:00 2001
From: Shivam Goyal
Date: Tue, 9 Apr 2019 23:36:27 +0530
Subject: [PATCH] lavf/flv: Add XV (Xunlei Video) Support. Fixes ticket #3720.

---
  Changelog|  1 +
  libavformat/Makefile |  1 +
  libavformat/allformats.c |  1 +
  libavformat/flvdec.c | 86 
  libavformat/version.h|  2 +-
  5 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/Changelog b/Changelog
index 8c866cd0c2..8caaab53c2 100644
--- a/Changelog
+++ b/Changelog
@@ -22,6 +22,7 @@ version :
  - removed libndi-newtek
  - agm decoder
  - KUX demuxer
+- XV (Xunlei Video) demuxer
  
  
  version 4.1:

diff --git a/libavformat/Makefile b/libavformat/Makefile
index 99be60d184..e090c051f1 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -561,6 +561,7 @@ OBJS-$(CONFIG_WV_MUXER)  += wvenc.o wv.o 
apetag.o img2.o
  OBJS-$(CONFIG_XA_DEMUXER)+= xa.o
  OBJS-$(CONFIG_XBIN_DEMUXER)  += bintext.o sauce.o
  OBJS-$(CONFIG_XMV_DEMUXER)   += xmv.o
+OBJS-$(CONFIG_XV_DEMUXER)+= flvdec.o
  OBJS-$(CONFIG_XVAG_DEMUXER)  += xvag.o
  OBJS-$(CONFIG_XWMA_DEMUXER)  += xwma.o
  OBJS-$(CONFIG_YOP_DEMUXER)   += yop.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index d316a0529a..b499186071 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -456,6 +456,7 @@ extern AVOutputFormat ff_wv_muxer;
  extern AVInputFormat  ff_xa_demuxer;
  extern AVInputFormat  ff_xbin_demuxer;
  extern AVInputFormat  ff_xmv_demuxer;
+extern AVInputFormat  ff_xv_demuxer;
  extern AVInputFormat  ff_xvag_demuxer;
  extern AVInputFormat  ff_xwma_demuxer;
  extern AVInputFormat  ff_yop_demuxer;
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index b531a39adc..a56f5b448a 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -127,6 +127,19 @@ static int kux_probe(const AVProbeData *p)
  return 0;
  }
  
+static int xv_probe(const AVProbeData *p)

+{
+const uint8_t *d = p->buf;
+
+if (d[0] == 'X' &&
+d[1] == 'L' &&
+d[2] == 'V' &&
+d[3] == 'F') {
+return AVPROBE_SCORE_EXTENSION + 1;
+}
+return 0;
+}
+
  static void add_keyframes_index(AVFormatContext *s)
  {
  FLVContext *flv   = s->priv_data;
@@ -459,6 +472,12 @@ static int parse_keyframes_index(AVFormatContext *s, 
AVIOContext *ioc, int64_t m
  }
  }
  
+if (!strcmp(s->iformat->name , "xv")) {

+for (i = 0; i < FFMIN(2,fileposlen); i++) {
+filepositions[i] += 0x20;
+}
+}
+
  if (timeslen == fileposlen && fileposlen>1 && max_pos <= 
filepositions[0]) {
  for (i = 0; i < FFMIN(2,fileposlen); i++) {
  flv->validate_index[i].pos = filepositions[i];
@@ -783,6 +802,52 @@ static int flv_read_header(AVFormatContext *s)
  return 0;
  }
  
+static int xv_read_header(AVFormatContext *s)

+{
+int flags;
+FLVContext *xv = s->priv_data;
+AVIOContext *ic = s->pb;
+int offset;
+int rot;
+int i;
+int64_t pos;
+
+//Find the rot value for rotating the bytes
+avio_skip(ic, 0x20);
+rot = 0x46 - avio_r8(ic);
+
+avio_skip(ic, 3);
+
+flags = (avio_r8(ic) + rot) & 0xff;
+
+xv->missing_streams = flags & (FLV_HEADER_FLAG_HASVIDEO | 
FLV_HEADER_FLAG_HASAUDIO);
+
+s->ctx_flags |= AVFMTCTX_NOHEADER;
+
+offset = ((avio_r8(ic) + rot & 0xff) << 24 |
+  (avio_r8(ic) + rot & 0xff) << 16 |
+  (avio_r8(ic) + rot & 0xff) << 8 |
+  (avio_r8(ic) + rot & 0xff)) + 0x20;
+
+avio_seek(ic, offset + 4, SEEK_SET);
+
+
+// Will modify the current buffer, as only
+// the bytes from 0x20 to 0x200400 are needed to decode
+pos = ic->pos + ic->buf_ptr - ic->buf_end;
+for (i = 0; i < 0x400; i++) {
+if (pos >= 0x200400) break;
+ic->buf_ptr[i] = (ic->buf_ptr[i] + rot) & 0xff;
+pos++;
+}

the demuxer should not manipulate the protocols /avio internal buffer.
This would make the demuxer depend on how this buffer is implemented.
Also the data that needs changes may not be in the buffer but be read
later i think-
It would be quite annoying for maintaince if changing the internal
AVIO code would require updating the implementations of demuxers

[...]



Yeah, I realise that this would be hard to 

Re: [FFmpeg-devel] [PATCH v6] lavf/flv: Add XV (Xunlei Video) Support. Fixes ticket #3720

2019-04-10 Thread Michael Niedermayer
On Tue, Apr 09, 2019 at 11:50:16PM +0530, Shivam Goyal wrote:
> lavf/flv: Add XV (Xunlei Video) Support.
> 
> Fixes ticket #3720.
> 
> 
> 

>  Changelog|1 
>  libavformat/Makefile |1 
>  libavformat/allformats.c |1 
>  libavformat/flvdec.c |   86 
> +++
>  libavformat/version.h|2 -
>  5 files changed, 90 insertions(+), 1 deletion(-)
> c221c019d4dcd7063828c54567b8fc7c905b211b  added_xv_support_v6.patch
> From 605dc262abf948813c26d58f51d5e2d7f498d9cd Mon Sep 17 00:00:00 2001
> From: Shivam Goyal 
> Date: Tue, 9 Apr 2019 23:36:27 +0530
> Subject: [PATCH] lavf/flv: Add XV (Xunlei Video) Support. Fixes ticket #3720.
> 
> ---
>  Changelog|  1 +
>  libavformat/Makefile |  1 +
>  libavformat/allformats.c |  1 +
>  libavformat/flvdec.c | 86 
>  libavformat/version.h|  2 +-
>  5 files changed, 90 insertions(+), 1 deletion(-)
> 
> diff --git a/Changelog b/Changelog
> index 8c866cd0c2..8caaab53c2 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -22,6 +22,7 @@ version :
>  - removed libndi-newtek
>  - agm decoder
>  - KUX demuxer
> +- XV (Xunlei Video) demuxer
>  
>  
>  version 4.1:
> diff --git a/libavformat/Makefile b/libavformat/Makefile
> index 99be60d184..e090c051f1 100644
> --- a/libavformat/Makefile
> +++ b/libavformat/Makefile
> @@ -561,6 +561,7 @@ OBJS-$(CONFIG_WV_MUXER)  += wvenc.o wv.o 
> apetag.o img2.o
>  OBJS-$(CONFIG_XA_DEMUXER)+= xa.o
>  OBJS-$(CONFIG_XBIN_DEMUXER)  += bintext.o sauce.o
>  OBJS-$(CONFIG_XMV_DEMUXER)   += xmv.o
> +OBJS-$(CONFIG_XV_DEMUXER)+= flvdec.o
>  OBJS-$(CONFIG_XVAG_DEMUXER)  += xvag.o
>  OBJS-$(CONFIG_XWMA_DEMUXER)  += xwma.o
>  OBJS-$(CONFIG_YOP_DEMUXER)   += yop.o
> diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> index d316a0529a..b499186071 100644
> --- a/libavformat/allformats.c
> +++ b/libavformat/allformats.c
> @@ -456,6 +456,7 @@ extern AVOutputFormat ff_wv_muxer;
>  extern AVInputFormat  ff_xa_demuxer;
>  extern AVInputFormat  ff_xbin_demuxer;
>  extern AVInputFormat  ff_xmv_demuxer;
> +extern AVInputFormat  ff_xv_demuxer;
>  extern AVInputFormat  ff_xvag_demuxer;
>  extern AVInputFormat  ff_xwma_demuxer;
>  extern AVInputFormat  ff_yop_demuxer;
> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
> index b531a39adc..a56f5b448a 100644
> --- a/libavformat/flvdec.c
> +++ b/libavformat/flvdec.c
> @@ -127,6 +127,19 @@ static int kux_probe(const AVProbeData *p)
>  return 0;
>  }
>  
> +static int xv_probe(const AVProbeData *p)
> +{
> +const uint8_t *d = p->buf;
> +
> +if (d[0] == 'X' &&
> +d[1] == 'L' &&
> +d[2] == 'V' &&
> +d[3] == 'F') {
> +return AVPROBE_SCORE_EXTENSION + 1;
> +}
> +return 0;
> +}
> +
>  static void add_keyframes_index(AVFormatContext *s)
>  {
>  FLVContext *flv   = s->priv_data;
> @@ -459,6 +472,12 @@ static int parse_keyframes_index(AVFormatContext *s, 
> AVIOContext *ioc, int64_t m
>  }
>  }
>  
> +if (!strcmp(s->iformat->name , "xv")) {
> +for (i = 0; i < FFMIN(2,fileposlen); i++) {
> +filepositions[i] += 0x20;
> +}
> +}
> +
>  if (timeslen == fileposlen && fileposlen>1 && max_pos <= 
> filepositions[0]) {
>  for (i = 0; i < FFMIN(2,fileposlen); i++) {
>  flv->validate_index[i].pos = filepositions[i];
> @@ -783,6 +802,52 @@ static int flv_read_header(AVFormatContext *s)
>  return 0;
>  }
>  
> +static int xv_read_header(AVFormatContext *s)
> +{
> +int flags;
> +FLVContext *xv = s->priv_data;
> +AVIOContext *ic = s->pb;
> +int offset;
> +int rot;
> +int i;
> +int64_t pos;
> +
> +//Find the rot value for rotating the bytes
> +avio_skip(ic, 0x20);
> +rot = 0x46 - avio_r8(ic);
> +
> +avio_skip(ic, 3);
> +
> +flags = (avio_r8(ic) + rot) & 0xff;
> +
> +xv->missing_streams = flags & (FLV_HEADER_FLAG_HASVIDEO | 
> FLV_HEADER_FLAG_HASAUDIO);
> +
> +s->ctx_flags |= AVFMTCTX_NOHEADER;
> +
> +offset = ((avio_r8(ic) + rot & 0xff) << 24 |
> +  (avio_r8(ic) + rot & 0xff) << 16 |
> +  (avio_r8(ic) + rot & 0xff) << 8 |
> +  (avio_r8(ic) + rot & 0xff)) + 0x20;
> +
> +avio_seek(ic, offset + 4, SEEK_SET);
> +
> +
> +// Will modify the current buffer, as only
> +// the bytes from 0x20 to 0x200400 are needed to decode
> +pos = ic->pos + ic->buf_ptr - ic->buf_end;
> +for (i = 0; i < 0x400; i++) {
> +if (pos >= 0x200400) break;
> +ic->buf_ptr[i] = (ic->buf_ptr[i] + rot) & 0xff;
> +pos++;
> +}

the demuxer should not manipulate the protocols /avio internal buffer.
This would make the demuxer depend on how this buffer is implemented.
Also the data that needs changes may not be in the buffer but be read
later 

[FFmpeg-devel] [PATCH v6] lavf/flv: Add XV (Xunlei Video) Support. Fixes ticket #3720

2019-04-09 Thread Shivam Goyal

lavf/flv: Add XV (Xunlei Video) Support.

Fixes ticket #3720.



>From 605dc262abf948813c26d58f51d5e2d7f498d9cd Mon Sep 17 00:00:00 2001
From: Shivam Goyal 
Date: Tue, 9 Apr 2019 23:36:27 +0530
Subject: [PATCH] lavf/flv: Add XV (Xunlei Video) Support. Fixes ticket #3720.

---
 Changelog|  1 +
 libavformat/Makefile |  1 +
 libavformat/allformats.c |  1 +
 libavformat/flvdec.c | 86 
 libavformat/version.h|  2 +-
 5 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/Changelog b/Changelog
index 8c866cd0c2..8caaab53c2 100644
--- a/Changelog
+++ b/Changelog
@@ -22,6 +22,7 @@ version :
 - removed libndi-newtek
 - agm decoder
 - KUX demuxer
+- XV (Xunlei Video) demuxer
 
 
 version 4.1:
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 99be60d184..e090c051f1 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -561,6 +561,7 @@ OBJS-$(CONFIG_WV_MUXER)  += wvenc.o wv.o apetag.o img2.o
 OBJS-$(CONFIG_XA_DEMUXER)+= xa.o
 OBJS-$(CONFIG_XBIN_DEMUXER)  += bintext.o sauce.o
 OBJS-$(CONFIG_XMV_DEMUXER)   += xmv.o
+OBJS-$(CONFIG_XV_DEMUXER)+= flvdec.o
 OBJS-$(CONFIG_XVAG_DEMUXER)  += xvag.o
 OBJS-$(CONFIG_XWMA_DEMUXER)  += xwma.o
 OBJS-$(CONFIG_YOP_DEMUXER)   += yop.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index d316a0529a..b499186071 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -456,6 +456,7 @@ extern AVOutputFormat ff_wv_muxer;
 extern AVInputFormat  ff_xa_demuxer;
 extern AVInputFormat  ff_xbin_demuxer;
 extern AVInputFormat  ff_xmv_demuxer;
+extern AVInputFormat  ff_xv_demuxer;
 extern AVInputFormat  ff_xvag_demuxer;
 extern AVInputFormat  ff_xwma_demuxer;
 extern AVInputFormat  ff_yop_demuxer;
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index b531a39adc..a56f5b448a 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -127,6 +127,19 @@ static int kux_probe(const AVProbeData *p)
 return 0;
 }
 
+static int xv_probe(const AVProbeData *p)
+{
+const uint8_t *d = p->buf;
+
+if (d[0] == 'X' &&
+d[1] == 'L' &&
+d[2] == 'V' &&
+d[3] == 'F') {
+return AVPROBE_SCORE_EXTENSION + 1;
+}
+return 0;
+}
+
 static void add_keyframes_index(AVFormatContext *s)
 {
 FLVContext *flv   = s->priv_data;
@@ -459,6 +472,12 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t m
 }
 }
 
+if (!strcmp(s->iformat->name , "xv")) {
+for (i = 0; i < FFMIN(2,fileposlen); i++) {
+filepositions[i] += 0x20;
+}
+}
+
 if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) {
 for (i = 0; i < FFMIN(2,fileposlen); i++) {
 flv->validate_index[i].pos = filepositions[i];
@@ -783,6 +802,52 @@ static int flv_read_header(AVFormatContext *s)
 return 0;
 }
 
+static int xv_read_header(AVFormatContext *s)
+{
+int flags;
+FLVContext *xv = s->priv_data;
+AVIOContext *ic = s->pb;
+int offset;
+int rot;
+int i;
+int64_t pos;
+
+//Find the rot value for rotating the bytes
+avio_skip(ic, 0x20);
+rot = 0x46 - avio_r8(ic);
+
+avio_skip(ic, 3);
+
+flags = (avio_r8(ic) + rot) & 0xff;
+
+xv->missing_streams = flags & (FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO);
+
+s->ctx_flags |= AVFMTCTX_NOHEADER;
+
+offset = ((avio_r8(ic) + rot & 0xff) << 24 |
+  (avio_r8(ic) + rot & 0xff) << 16 |
+  (avio_r8(ic) + rot & 0xff) << 8 |
+  (avio_r8(ic) + rot & 0xff)) + 0x20;
+
+avio_seek(ic, offset + 4, SEEK_SET);
+
+
+// Will modify the current buffer, as only
+// the bytes from 0x20 to 0x200400 are needed to decode
+pos = ic->pos + ic->buf_ptr - ic->buf_end;
+for (i = 0; i < 0x400; i++) {
+if (pos >= 0x200400) break;
+ic->buf_ptr[i] = (ic->buf_ptr[i] + rot) & 0xff;
+pos++;
+}
+
+s->start_time = 0;
+xv->sum_flv_tag_size = 0;
+xv->last_keyframe_stream_index = -1;
+
+return 0;
+}
+
 static int flv_read_close(AVFormatContext *s)
 {
 int i;
@@ -1424,3 +1489,24 @@ AVInputFormat ff_kux_demuxer = {
 .extensions = "kux",
 .priv_class = _class,
 };
+
+static const AVClass xv_class = {
+.class_name = "xvdec",
+.item_name  = av_default_item_name,
+.option = options,
+.version= LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_xv_demuxer = {
+.name   = "xv",
+.long_name  = NULL_IF_CONFIG_SMALL("Xunlei(Thunder) Video File"),
+.priv_data_size = sizeof(FLVContext),
+.read_probe = xv_probe,
+.read_header= xv_read_header,
+.read_packet= flv_read_packet,
+.read_seek  = flv_read_seek,
+.read_close = flv_read_close,
+.extensions = "xv",
+.priv_class =