All of these should be valid for RMVB (file format version 1).

I have no .rm files to test these changes, only .rmhd ones. AAC muxing yet not 
included, requires file format version 2. However, if all muxer changes are 
applied, all existing FATE tests involving .rm muxing/demuxing pass for me.

-Thilo
From c6acdc9eb68b384822345aae7e12e84c05720180 Mon Sep 17 00:00:00 2001
From: Thilo Borgmann <thilo.borgm...@mail.de>
Date: Fri, 2 Feb 2018 02:48:34 +0100
Subject: [PATCH 1/4] lavformat/rm: Add decoding of MLTI chunks, prefer audio
 dts for multiple streams, several muxer fixes depending on codec id

---
 libavformat/rmdec.c | 35 +++++++++++++++++++++++++++++++----
 libavformat/rmenc.c | 30 +++++++++++++++++++++++++-----
 2 files changed, 56 insertions(+), 9 deletions(-)

diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index fea71a2..cf3d545 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -330,7 +330,20 @@ int ff_rm_read_mdpr_codecdata(AVFormatContext *s, 
AVIOContext *pb,
     codec_pos = avio_tell(pb);
     v = avio_rb32(pb);
 
-    if (v == MKTAG(0xfd, 'a', 'r', '.')) {
+    if (v == MKBETAG('M', 'L', 'T', 'I')) {
+        int number_of_streams = avio_rb16(pb);
+        int number_of_mdpr;
+        int i;
+        for (i = 0; i < number_of_streams; i++) {
+            avio_rb16(pb);
+        }
+        number_of_mdpr = avio_rb16(pb);
+        if (number_of_mdpr != 1) {
+            avpriv_request_sample(s, "MLTI with multiple MDPR");
+        }
+        avio_rb32(pb);
+        v = avio_rb32(pb);
+    } else if (v == MKTAG(0xfd, 'a', 'r', '.')) {
         /* ra type header */
         if (rm_read_audio_stream_info(s, pb, st, rst, 0))
             return -1;
@@ -1089,7 +1102,9 @@ static int64_t rm_read_dts(AVFormatContext *s, int 
stream_index,
 {
     RMDemuxContext *rm = s->priv_data;
     int64_t pos, dts;
+    int64_t pos_audio, dts_audio;
     int stream_index2, flags, len, h;
+    int audio_override = 0;
 
     pos = *ppos;
 
@@ -1114,20 +1129,32 @@ static int64_t rm_read_dts(AVFormatContext *s, int 
stream_index,
             if(!(h & 0x40)){
                 seq = avio_r8(s->pb); len--;
             }
+            if (!(flags & 2)       ||
+                (seq & 0x7F)  != 1 ||
+                stream_index2 != stream_index) {
+                audio_override = 0;
+            }
         }
 
         if((flags&2) && (seq&0x7F) == 1){
             av_log(s, AV_LOG_TRACE, "%d %d-%d %"PRId64" %d\n",
                     flags, stream_index2, stream_index, dts, seq);
             av_add_index_entry(st, pos, dts, 0, 0, AVINDEX_KEYFRAME);
-            if(stream_index2 == stream_index)
+            if(stream_index2 == stream_index) {
+                if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+                    dts_audio      = dts;
+                    pos_audio      = pos;
+                    audio_override = 1;
+                }
+
                 break;
+            }
         }
 
         avio_skip(s->pb, len);
     }
-    *ppos = pos;
-    return dts;
+    *ppos = (audio_override ? pos_audio : pos);
+    return (audio_override ? dts_audio : dts);
 }
 
 static int rm_read_seek(AVFormatContext *s, int stream_index,
diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c
index 3bff4da..83b0f3c 100644
--- a/libavformat/rmenc.c
+++ b/libavformat/rmenc.c
@@ -152,7 +152,13 @@ static int rv10_write_header(AVFormatContext *ctx,
         } else {
             desc = "The Video Stream";
             mimetype = "video/x-pn-realvideo";
-            codec_data_size = 34;
+            if(stream->par->codec_id == AV_CODEC_ID_RV10 ||
+               stream->par->codec_id == AV_CODEC_ID_RV20 ||
+               stream->par->codec_id == AV_CODEC_ID_RV40) {
+                codec_data_size = 34;
+            } else {
+                codec_data_size = 26 + stream->par->extradata_size;
+            }
         }
 
         ffio_wfourcc(s,"MDPR");
@@ -245,10 +251,21 @@ static int rv10_write_header(AVFormatContext *ctx,
             /* video codec info */
             avio_wb32(s,34); /* size */
             ffio_wfourcc(s, "VIDO");
-            if(stream->par->codec_id == AV_CODEC_ID_RV10)
+            switch (stream->par->codec_id) {
+            case AV_CODEC_ID_RV10:
                 ffio_wfourcc(s,"RV10");
-            else
+                break;
+            case AV_CODEC_ID_RV20:
                 ffio_wfourcc(s,"RV20");
+                break;
+            case AV_CODEC_ID_RV30:
+                ffio_wfourcc(s,"RV30");
+                break;
+            case AV_CODEC_ID_RV40:
+                ffio_wfourcc(s,"RV40");
+                break;
+            }
+
             avio_wb16(s, stream->par->width);
             avio_wb16(s, stream->par->height);
 
@@ -346,8 +363,11 @@ static int rm_write_header(AVFormatContext *s)
             break;
         case AVMEDIA_TYPE_VIDEO:
             rm->video_stream = stream;
-            // TODO: should be avg_frame_rate
-            stream->frame_rate = av_inv_q(st->time_base);
+            if (st->codecpar->codec_id == AV_CODEC_ID_RV40) {
+                stream->frame_rate = st->avg_frame_rate;
+            } else {
+                stream->frame_rate = av_inv_q(st->time_base);
+            }
             /* XXX: dummy values */
             stream->packet_max_size = 4096;
             stream->nb_packets = 0;
-- 
2.9.3

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to