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

