[FFmpeg-devel] JPEG2000 multiple SOC and SIZ

Submitted by Anton Novikov on June 30, 2019, 12:04 p.m.

Details

Message ID CAEufGC1-CcfN5wEECzNvUKz1ngEQnEksHJwDULce47ED-GCfcA@mail.gmail.com
State New
Headers show

Commit Message

Anton Novikov June 30, 2019, 12:04 p.m.
When I truncate the packet at next SOC, I get:
[jpeg2000 @ 0x55ce0298aa40] SIZ
[jpeg2000 @ 0x55ce0298aa40] SIZ width=2056 height=2168 tile_width=2056
tile_height=2168 tile_offset_x=0 tile_offset_y=0 xtiles=1 ytiles=1
[jpeg2000 @ 0x55ce0298aa40] SIZ Rsiz=0x8040 2056 2168
[jpeg2000 @ 0x55ce0298aa40] POC
[jpeg2000 @ 0x55ce0298aa40] unsupported marker 0xFF79 at pos 0x70
[jpeg2000 @ 0x55ce0298aa40] COD
[jpeg2000 @ 0x55ce0298aa40] extra cblk styles E
[jpeg2000 @ 0x55ce0298aa40] QCD
[jpeg2000 @ 0x55ce0298aa40] SOT
    Last message repeated 3 times
[jpeg2000 @ 0x55ce0298aa40] Psot 1451180 too big
[jpeg2000 @ 0x55ce0298aa40] error during processing marker segment ff90

Moreover, in both SIZes, tile offsets are 0, I can't get the idea how the
file should be handled correctly.
file: https://www.file-up.org/niuxrl31dyij
fmpeg commits are attached

вс, 30 июн. 2019 г. в 15:17, Paul B Mahol <onemda@gmail.com>:

> On 6/30/19, Anton Novikov <random.plant@gmail.com> wrote:
> > Hi everyone,
> > I'm reversing the recent version of r3d file format, and have
> encountered a
> > JPEG2000-related thing.
> > I've got a memory dump of something that seems to be JPEG2000, and
> modified
> > ffmpeg to consume it. The log follows:
> > [r3d @ 0x558d304077c0] test
> > [r3d @ 0x558d304077c0] error reading end atom
> > Input #0, r3d, from '/home/anek/src/red/frame2.without0.r3d':
> >   Duration: N/A, bitrate: N/A
> >     Stream #0:0: Video: jpeg2000, bayer_rggb16le, 8192x4320, 24 fps, 24
> > tbr, 134286336 tbn, 134286336 tbc
> >     Metadata:
> >       filename        : ?
> > File 'frame.jpg' already exists. Overwrite ? [y/N] y
> > Stream mapping:
> >   Stream #0:0 -> #0:0 (jpeg2000 (native) -> mjpeg (native))
> > Press [q] to stop, [?] for help
> > Truncating packet of size 9496960 to 7595371
> > /home/anek/src/red/frame2.without0.r3d: corrupt input packet in stream 0
> > /home/anek/src/red/frame2.without0.r3d: Operation not permitted
> > [jpeg2000 @ 0x558d3041c280] SIZ
> > [jpeg2000 @ 0x558d3041c280] SIZ Rsiz=0x8040 2056 2168
> > [jpeg2000 @ 0x558d3041c280] POC
> > [jpeg2000 @ 0x558d3041c280] unsupported marker 0xFF79 at pos 0x70
> > [jpeg2000 @ 0x558d3041c280] COD
> > [jpeg2000 @ 0x558d3041c280] extra cblk styles E
> > [jpeg2000 @ 0x558d3041c280] QCD
> > [jpeg2000 @ 0x558d3041c280] SOT
> >     Last message repeated 3 times
> > [jpeg2000 @ 0x558d3041c280] Duplicate SOC at 3821997=0x3A51AD
> > [jpeg2000 @ 0x558d3041c280] SIZ
> > [jpeg2000 @ 0x558d3041c280] SIZ Rsiz=0x8040 2056 2168
> > [jpeg2000 @ 0x558d3041c280] POC
> > [jpeg2000 @ 0x558d3041c280] unsupported marker 0xFF79 at pos 0x3A5203
> > [jpeg2000 @ 0x558d3041c280] COD
> > [jpeg2000 @ 0x558d3041c280] extra cblk styles E
> > [jpeg2000 @ 0x558d3041c280] QCD
> > [jpeg2000 @ 0x558d3041c280] SOT
> >     Last message repeated 3 times
> > [jpeg2000 @ 0x558d3041c280] Progression order RPCL
> >     Last message repeated 3 times
> > [swscaler @ 0x558d30425900] deprecated pixel format used, make sure you
> did
> > set range correctly
> > [mjpeg @ 0x558d3040e780] removing common factors from framerate
> > Output #0, image2, to 'frame.jpg':
> >   Metadata:
> >     encoder         : Lavf58.27.103
> >     Stream #0:0: Video: mjpeg, yuvj444p(pc), 2056x2168, q=2-31, 200 kb/s,
> > 24 fps, 24 tbn, 24 tbc
> >     Metadata:
> >       filename        : ?
> >       encoder         : Lavc58.52.102 mjpeg
> >     Side data:
> >       cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
> > [image2 @ 0x558d3040abc0] Application provided invalid, non monotonically
> > increasing dts to muxer in stream 0: 101000 >= 0
> > /home/anek/src/red/frame2.without0.r3d: Operation not permitted
> > frame=    1 fps=0.4 q=2.9 Lsize=N/A time=00:00:00.00 bitrate=N/A speed=
> > 0x
> > video:96kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB
> > muxing overhead: unknown
> >
> > picture dimensions are 8192x4320, but in JPEG2000 bytestream there are 2
> > SOC and SIZ markers with SIZ mentioning 2056x2168. The image is decoded,
> > but colors and area are wrong. What can I do?
>
> Make sure it uses tiles (each jpeg2000 is special tile) and that your
> packet is trimmed.
> _______________________________________________
> 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".

Comments

Michael Niedermayer July 1, 2019, 2:16 p.m.
On Sun, Jun 30, 2019 at 05:04:38PM +0500, Anton Novikov wrote:
> When I truncate the packet at next SOC, I get:
> [jpeg2000 @ 0x55ce0298aa40] SIZ
> [jpeg2000 @ 0x55ce0298aa40] SIZ width=2056 height=2168 tile_width=2056
> tile_height=2168 tile_offset_x=0 tile_offset_y=0 xtiles=1 ytiles=1
> [jpeg2000 @ 0x55ce0298aa40] SIZ Rsiz=0x8040 2056 2168
> [jpeg2000 @ 0x55ce0298aa40] POC
> [jpeg2000 @ 0x55ce0298aa40] unsupported marker 0xFF79 at pos 0x70
> [jpeg2000 @ 0x55ce0298aa40] COD
> [jpeg2000 @ 0x55ce0298aa40] extra cblk styles E
> [jpeg2000 @ 0x55ce0298aa40] QCD
> [jpeg2000 @ 0x55ce0298aa40] SOT
>     Last message repeated 3 times
> [jpeg2000 @ 0x55ce0298aa40] Psot 1451180 too big
> [jpeg2000 @ 0x55ce0298aa40] error during processing marker segment ff90
> 
> Moreover, in both SIZes, tile offsets are 0, I can't get the idea how the
> file should be handled correctly.
> file: https://www.file-up.org/niuxrl31dyij
> fmpeg commits are attached
> 
> вс, 30 июн. 2019 г. в 15:17, Paul B Mahol <onemda@gmail.com>:
> 
> > On 6/30/19, Anton Novikov <random.plant@gmail.com> wrote:
> > > Hi everyone,
> > > I'm reversing the recent version of r3d file format, and have
> > encountered a
> > > JPEG2000-related thing.
> > > I've got a memory dump of something that seems to be JPEG2000, and
> > modified
> > > ffmpeg to consume it. The log follows:
> > > [r3d @ 0x558d304077c0] test
> > > [r3d @ 0x558d304077c0] error reading end atom
> > > Input #0, r3d, from '/home/anek/src/red/frame2.without0.r3d':
> > >   Duration: N/A, bitrate: N/A
> > >     Stream #0:0: Video: jpeg2000, bayer_rggb16le, 8192x4320, 24 fps, 24
> > > tbr, 134286336 tbn, 134286336 tbc
> > >     Metadata:
> > >       filename        : ?
> > > File 'frame.jpg' already exists. Overwrite ? [y/N] y
> > > Stream mapping:
> > >   Stream #0:0 -> #0:0 (jpeg2000 (native) -> mjpeg (native))
> > > Press [q] to stop, [?] for help
> > > Truncating packet of size 9496960 to 7595371
> > > /home/anek/src/red/frame2.without0.r3d: corrupt input packet in stream 0
> > > /home/anek/src/red/frame2.without0.r3d: Operation not permitted
> > > [jpeg2000 @ 0x558d3041c280] SIZ
> > > [jpeg2000 @ 0x558d3041c280] SIZ Rsiz=0x8040 2056 2168
> > > [jpeg2000 @ 0x558d3041c280] POC
> > > [jpeg2000 @ 0x558d3041c280] unsupported marker 0xFF79 at pos 0x70
> > > [jpeg2000 @ 0x558d3041c280] COD
> > > [jpeg2000 @ 0x558d3041c280] extra cblk styles E
> > > [jpeg2000 @ 0x558d3041c280] QCD
> > > [jpeg2000 @ 0x558d3041c280] SOT
> > >     Last message repeated 3 times
> > > [jpeg2000 @ 0x558d3041c280] Duplicate SOC at 3821997=0x3A51AD
> > > [jpeg2000 @ 0x558d3041c280] SIZ
> > > [jpeg2000 @ 0x558d3041c280] SIZ Rsiz=0x8040 2056 2168
> > > [jpeg2000 @ 0x558d3041c280] POC
> > > [jpeg2000 @ 0x558d3041c280] unsupported marker 0xFF79 at pos 0x3A5203
> > > [jpeg2000 @ 0x558d3041c280] COD
> > > [jpeg2000 @ 0x558d3041c280] extra cblk styles E
> > > [jpeg2000 @ 0x558d3041c280] QCD
> > > [jpeg2000 @ 0x558d3041c280] SOT
> > >     Last message repeated 3 times
> > > [jpeg2000 @ 0x558d3041c280] Progression order RPCL
> > >     Last message repeated 3 times
> > > [swscaler @ 0x558d30425900] deprecated pixel format used, make sure you
> > did
> > > set range correctly
> > > [mjpeg @ 0x558d3040e780] removing common factors from framerate
> > > Output #0, image2, to 'frame.jpg':
> > >   Metadata:
> > >     encoder         : Lavf58.27.103
> > >     Stream #0:0: Video: mjpeg, yuvj444p(pc), 2056x2168, q=2-31, 200 kb/s,
> > > 24 fps, 24 tbn, 24 tbc
> > >     Metadata:
> > >       filename        : ?
> > >       encoder         : Lavc58.52.102 mjpeg
> > >     Side data:
> > >       cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
> > > [image2 @ 0x558d3040abc0] Application provided invalid, non monotonically
> > > increasing dts to muxer in stream 0: 101000 >= 0
> > > /home/anek/src/red/frame2.without0.r3d: Operation not permitted
> > > frame=    1 fps=0.4 q=2.9 Lsize=N/A time=00:00:00.00 bitrate=N/A speed=
> > > 0x
> > > video:96kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB
> > > muxing overhead: unknown
> > >
> > > picture dimensions are 8192x4320, but in JPEG2000 bytestream there are 2
> > > SOC and SIZ markers with SIZ mentioning 2056x2168. The image is decoded,
> > > but colors and area are wrong. What can I do?
> >
> > Make sure it uses tiles (each jpeg2000 is special tile) and that your
> > packet is trimmed.
> > _______________________________________________
> > 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".

>  jpeg2000dec.c |   43 ++++++++++++++++++++++++++++++++++---------
>  1 file changed, 34 insertions(+), 9 deletions(-)
> d9726772b07866243dd21c966649459bb8cbcfed  0002-jpeg2000-decoding-dbginfo.patch
> From ce21789b0da6e7f16c21ea33dcf67586b32630bd Mon Sep 17 00:00:00 2001

> From: Anek <anek@archlinuxi>

Make sure the author is containing your full name unless you want to
use a pseudonym. (It cannot be changed once anything of this is pushed)
and some (samm and trivial) parts of the patches could be split out and pushed

Thanks

[...]

Patch hide | download patch | download mbox

From 5acc9762c553dd3302dc9da537bab817f98ba2a0 Mon Sep 17 00:00:00 2001
From: Anek <anek@archlinuxi>
Date: Sat, 29 Jun 2019 19:20:22 +0500
Subject: [PATCH 1/2] some_picture

---
 fftools/ffmpeg.c         |   5 +-
 libavcodec/jpeg2000.h    |   1 +
 libavcodec/jpeg2000dec.c |  16 +++++-
 libavformat/r3d.c        | 116 +++++++++++++++++++++++++++++++++++++--
 4 files changed, 129 insertions(+), 9 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f04103cf..9e6dac6439 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -3874,10 +3874,13 @@  static OutputStream *choose_output(void)
         int64_t opts = ost->st->cur_dts == AV_NOPTS_VALUE ? INT64_MIN :
                        av_rescale_q(ost->st->cur_dts, ost->st->time_base,
                                     AV_TIME_BASE_Q);
-        if (ost->st->cur_dts == AV_NOPTS_VALUE)
+        if (ost->st->cur_dts == AV_NOPTS_VALUE) {
+		static int nondts = 100000;
+		ost->st->cur_dts = nondts += 1000;
             av_log(NULL, AV_LOG_DEBUG,
                 "cur_dts is invalid st:%d (%d) [init:%d i_done:%d finish:%d] (this is harmless if it occurs once at the start per stream)\n",
                 ost->st->index, ost->st->id, ost->initialized, ost->inputs_done, ost->finished);
+	}
 
         if (!ost->initialized && !ost->inputs_done)
             return ost;
diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h
index c429ca5996..0e8608f4d7 100644
--- a/libavcodec/jpeg2000.h
+++ b/libavcodec/jpeg2000.h
@@ -51,6 +51,7 @@  enum Jpeg2000Markers {
     JPEG2000_PPT,          // packed packet headers, main header
     JPEG2000_CRG = 0xff63, // component registration
     JPEG2000_COM,          // comment
+    JPEG2000_ATK = 0xff79, // arbitrary transformation kernel
     JPEG2000_SOT = 0xff90, // start of tile-part
     JPEG2000_SOP,          // start of packet
     JPEG2000_EPH,          // end of packet header
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index 019dc81f56..a40726f4b8 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -1903,10 +1903,13 @@  static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
             break;
         }
 
+next_marker:
         marker = bytestream2_get_be16u(&s->g);
         oldpos = bytestream2_tell(&s->g);
 
-        if (marker == JPEG2000_SOD) {
+	if (marker == JPEG2000_SOC)
+		goto next_marker;
+	else if (marker == JPEG2000_SOD) {
             Jpeg2000Tile *tile;
             Jpeg2000TilePart *tp;
 
@@ -1935,13 +1938,17 @@  static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
 
         len = bytestream2_get_be16(&s->g);
         if (len < 2 || bytestream2_get_bytes_left(&s->g) < len - 2) {
-            av_log(s->avctx, AV_LOG_ERROR, "Invalid len %d left=%d\n", len, bytestream2_get_bytes_left(&s->g));
+	    if (bytestream2_get_bytes_left(&s->g) == 0)
+		    break;
+            av_log(s->avctx, AV_LOG_ERROR, "Invalid len %d pos=%d left=%d\n", len, bytestream2_tell(&s->g), bytestream2_get_bytes_left(&s->g));
             return AVERROR_INVALIDDATA;
         }
 
         switch (marker) {
+	case JPEG2000_SOC:
+	    return 0xdeadbeef;
         case JPEG2000_SIZ:
-            if (s->ncomponents) {
+            if (0 && s->ncomponents) {
                 av_log(s->avctx, AV_LOG_ERROR, "Duplicate SIZ\n");
                 return AVERROR_INVALIDDATA;
             }
@@ -2217,6 +2224,7 @@  static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
         bytestream2_seek(&s->g, 0, SEEK_SET);
     }
 
+next_codestream:
     while (bytestream2_get_bytes_left(&s->g) >= 3 && bytestream2_peek_be16(&s->g) != JPEG2000_SOC)
         bytestream2_skip(&s->g, 1);
 
@@ -2252,6 +2260,8 @@  static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
     return bytestream2_tell(&s->g);
 
 end:
+    if (ret == 0xdeadbeef)
+	    ret = 0;
     jpeg2000_dec_cleanup(s);
     return ret;
 }
diff --git a/libavformat/r3d.c b/libavformat/r3d.c
index 934cebefa8..862c51f295 100644
--- a/libavformat/r3d.c
+++ b/libavformat/r3d.c
@@ -29,6 +29,7 @@  typedef struct R3DContext {
     unsigned video_offsets_count;
     unsigned *video_offsets;
     unsigned rdvo_offset;
+    unsigned rdvs_offset;
 
     int audio_channels;
 } R3DContext;
@@ -48,6 +49,11 @@  static int read_atom(AVFormatContext *s, Atom *atom)
     if (atom->size < 8)
         return -1;
     atom->tag = avio_rl32(s->pb);
+    if (atom->tag == MKTAG('R','E','D','2'))
+	    format2 = 1;
+    if (format2)
+	    if (atom->size % 0x1000 > 0)
+		    atom->size += 0x1000 - atom->size % 0x1000;
     av_log(s, AV_LOG_TRACE, "atom %u %.4s offset %#"PRIx64"\n",
             atom->size, (char*)&atom->tag, atom->offset);
     return atom->size;
@@ -84,6 +90,7 @@  static int r3d_read_red1(AVFormatContext *s)
 
     st->codecpar->width  = avio_rb32(s->pb);
     st->codecpar->height = avio_rb32(s->pb);
+    st->codecpar->format = AV_PIX_FMT_BAYER_BGGR16LE;
 
     tmp = avio_rb16(s->pb); // unknown
     av_log(s, AV_LOG_TRACE, "unknown2 %d\n", tmp);
@@ -143,14 +150,17 @@  static int r3d_read_red2(AVFormatContext *s)
 
     avio_skip(s->pb, 32); // unknown
 
+    avio_seek(s->pb, 0x4C, SEEK_SET);
     st->codecpar->width  = avio_rb32(s->pb);
     st->codecpar->height = avio_rb32(s->pb);
+    st->codecpar->format = AV_PIX_FMT_BAYER_RGGB16;
 
     tmp = avio_rb16(s->pb); // unknown
     av_log(s, AV_LOG_TRACE, "unknown2 %d\n", tmp);
 
-    framerate.num = avio_rb16(s->pb);
     framerate.den = avio_rb16(s->pb);
+    tmp = avio_rb16(s->pb); // unknown
+    framerate.num = avio_rb16(s->pb);
     if (framerate.num > 0 && framerate.den > 0) {
 #if FF_API_R_FRAME_RATE
         st->r_frame_rate =
@@ -158,6 +168,10 @@  static int r3d_read_red2(AVFormatContext *s)
         st->avg_frame_rate = framerate;
     }
 
+    r3d->video_offsets_count = 1;
+    r3d->video_offsets = av_malloc(4);
+    r3d->video_offsets[0] = 0x12680;
+
     r3d->audio_channels = avio_r8(s->pb); // audio channels
     av_log(s, AV_LOG_TRACE, "audio channels %d\n", tmp);
 
@@ -203,13 +217,43 @@  static int r3d_read_rdvo(AVFormatContext *s, Atom *atom)
     return 0;
 }
 
+static int r3d_read_rdvs(AVFormatContext *s, Atom *atom)
+{
+    R3DContext *r3d = s->priv_data;
+    AVStream *st = s->streams[0];
+    int i;
+
+    r3d->video_offsets_count = (atom->size - 8) / 4;
+    r3d->video_offsets = av_malloc(atom->size);
+    if (!r3d->video_offsets)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < r3d->video_offsets_count; i++) {
+        r3d->video_offsets[i] = avio_rb32(s->pb);
+        if (!r3d->video_offsets[i]) {
+            r3d->video_offsets_count = i;
+            break;
+        }
+        av_log(s, AV_LOG_TRACE, "video offset %d: %#x\n", i, r3d->video_offsets[i]);
+    }
+
+    if (st->avg_frame_rate.num)
+        st->duration = av_rescale_q(r3d->video_offsets_count,
+                                    av_inv_q(st->avg_frame_rate),
+                                    st->time_base);
+    av_log(s, AV_LOG_TRACE, "duration %"PRId64"\n", st->duration);
+    avio_seek(s->pb, s->internal->data_offset, SEEK_SET);
+
+    return 0;
+}
+
 static void r3d_read_reos(AVFormatContext *s)
 {
     R3DContext *r3d = s->priv_data;
     int av_unused tmp;
 
     r3d->rdvo_offset = avio_rb32(s->pb);
-    avio_rb32(s->pb); // rdvs offset
+    r3d->rdvs_offset = avio_rb32(s->pb);
     avio_rb32(s->pb); // rdao offset
     avio_rb32(s->pb); // rdas offset
 
@@ -261,17 +305,25 @@  static int r3d_read_header(AVFormatContext *s)
     if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
         return 0;
     // find REOB/REOF/REOS to load index
-    avio_seek(s->pb, avio_size(s->pb)-48-8, SEEK_SET);
-    if (read_atom(s, &atom) < 0)
+    avio_seek(s->pb, atom.offset + atom.size, SEEK_SET);
+next:
+    av_log(s, AV_LOG_TRACE, "at %x\n", avio_tell(s->pb));
+    if (read_atom(s, &atom) < 0) {
         av_log(s, AV_LOG_ERROR, "error reading end atom\n");
+	goto out;
+    }
+
+    avio_seek(s->pb, atom.offset + atom.size, SEEK_SET);
 
     if (atom.tag != MKTAG('R','E','O','B') &&
         atom.tag != MKTAG('R','E','O','F') &&
         atom.tag != MKTAG('R','E','O','S'))
-        goto out;
+        goto next;
 
+    avio_seek(s->pb, atom.offset + 8, SEEK_SET);
     r3d_read_reos(s);
 
+    avio_seek(s->pb, s->internal->data_offset, SEEK_SET);
     if (r3d->rdvo_offset) {
         avio_seek(s->pb, r3d->rdvo_offset, SEEK_SET);
         if (read_atom(s, &atom) < 0)
@@ -281,9 +333,22 @@  static int r3d_read_header(AVFormatContext *s)
                 av_log(s, AV_LOG_ERROR, "error parsing 'rdvo' atom\n");
         }
     }
+    /*
+    if (r3d->rdvs_offset) {
+	av_log(s, AV_LOG_ERROR, "rdvs");
+        avio_seek(s->pb, r3d->rdvs_offset, SEEK_SET);
+        if (read_atom(s, &atom) < 0)
+            av_log(s, AV_LOG_ERROR, "error reading 'rdvs' atom\n");
+        if (atom.tag == MKTAG('R','D','V','S')) {
+            if (r3d_read_rdvs(s, &atom) < 0)
+                av_log(s, AV_LOG_ERROR, "error parsing 'rdvs' atom\n");
+        }
+    }
+    */
 
  out:
     avio_seek(s->pb, s->internal->data_offset, SEEK_SET);
+    //avio_seek(s->pb, 0x12680, SEEK_SET);
     return 0;
 }
 
@@ -342,6 +407,38 @@  static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom)
     return 0;
 }
 
+static int r3d_read_redv2(AVFormatContext *s, AVPacket *pkt, Atom *atom)
+{
+    AVStream *st = s->streams[0];
+    int tmp;
+    int av_unused tmp2;
+    int64_t pos = avio_tell(s->pb);
+    unsigned dts;
+    int ret;
+
+    static nondts = 100000;
+    dts = nondts++;
+
+    tmp = atom->size;
+    tmp = 9496960;
+    if (tmp < 0)
+        return -1;
+    ret = av_get_packet(s->pb, pkt, tmp);
+    if (ret < 0) {
+        av_log(s, AV_LOG_ERROR, "error reading video packet\n");
+        return -1;
+    }
+
+    pkt->stream_index = 0;
+    pkt->dts = dts;
+    if (st->avg_frame_rate.num)
+        pkt->duration = (uint64_t)st->time_base.den*
+            st->avg_frame_rate.den/st->avg_frame_rate.num;
+    av_log(s, AV_LOG_TRACE, "pkt dts %"PRId64" duration %"PRId64"\n", pkt->dts, pkt->duration);
+
+    return 0;
+}
+
 static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom)
 {
     R3DContext *r3d = s->priv_data;
@@ -433,6 +530,13 @@  static int r3d_read_packet(AVFormatContext *s, AVPacket *pkt)
                 return 0;
             break;
         default:
+            avio_seek(s->pb, 0x12680, SEEK_SET);
+	    av_log(s, AV_LOG_TRACE, "packet atom %u", atom.tag);
+            if (s->streams[0]->discard == AVDISCARD_ALL)
+                goto skip;
+            if (!(err = r3d_read_redv2(s, pkt, &atom)))
+                return 0;
+            break;
         skip:
             avio_skip(s->pb, atom.size-8);
         }
@@ -444,6 +548,8 @@  static int r3d_probe(const AVProbeData *p)
 {
     if (AV_RL32(p->buf + 4) == MKTAG('R','E','D','1'))
         return AVPROBE_SCORE_MAX;
+    if (AV_RL32(p->buf + 4) == MKTAG('R','E','D','2'))
+        return AVPROBE_SCORE_MAX;
     return 0;
 }
 
-- 
2.22.0