[FFmpeg-devel] [RFC] RM muxer fix

Kostya kostya.shishkov
Tue Oct 23 13:06:31 CEST 2007


As spotted by Benoit, current regression tests fail
in part of RM testing.

That happens because lavf RM muxer generates very
incorrect data (length and position values).

Here is my code to output correct RMs either single-frame
based or new frame format toggled by #ifdef and regressions
difference.

I hope it will be useful to fix muxer.
-------------- next part --------------
Index: libavformat/rmenc.c
===================================================================
--- libavformat/rmenc.c	(revision 10844)
+++ libavformat/rmenc.c	(working copy)
@@ -337,6 +337,15 @@
     return 0;
 }
 
+static inline void put_num(ByteIOContext *pb, int num)
+{
+    if(num > 0x3FFF){
+        put_be16(pb, 0x4000 | (num >> 16));
+        put_be16(pb, num);
+    }else
+        put_be16(pb, 0x4000 | num);
+}
+
 static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int flags)
 {
     RMContext *rm = s->priv_data;
@@ -344,34 +353,43 @@
     StreamInfo *stream = rm->video_stream;
     int key_frame = !!(flags & PKT_FLAG_KEY);
 
-    /* XXX: this is incorrect: should be a parameter */
+#ifdef OUTPUT_SLICES
+    int slices, i, offset, ssize, pos, last, hsize;
 
-    /* Well, I spent some time finding the meaning of these bits. I am
-       not sure I understood everything, but it works !! */
-#if 1
-    write_packet_header(s, stream, size + 7, key_frame);
-    /* bit 7: '1' if final packet of a frame converted in several packets */
-    put_byte(pb, 0x81);
-    /* bit 7: '1' if I frame. bits 6..0 : sequence number in current
-       frame starting from 1 */
-    if (key_frame) {
-        put_byte(pb, 0x81);
-    } else {
-        put_byte(pb, 0x01);
+    slices = buf[0] + 1;
+    for(i=0;i<slices;i++) {
+        last = (i+1) < slices;
+        offset = AV_RL32(buf + 5 + i*8);
+        ssize = (last ? AV_RL32(buf + 5 + i*8) : size) - offset;
+        pos = last ? ssize : offset;
+        
+        hsize = 7 + (size > 0x3FFF ? 2 : 0) + (pos > 0x3FFF ? 2 : 0);
+        write_packet_header(s, stream, ssize + hsize, key_frame);
+        //put slice type and number of slices
+        if(!last)
+            put_byte(pb, slices>>1);
+        else
+            put_byte(pb, 0x80 + (slices>>1));
+        //slice number
+        put_byte(pb, i+1);
+        //put total frame size and offset of current slice in it
+        put_num(pb, size);
+        put_num(pb, pos);
+        //picture num
+        put_byte(pb, stream->nb_frames & 0xff);
+        //actual data
+        put_buffer(pb, buf, size);
+        put_flush_packet(pb);
     }
-    put_be16(pb, 0x4000 + (size)); /* total frame size */
-    put_be16(pb, 0x4000 + (size));              /* offset from the start or the end */
 #else
     /* full frame */
-    write_packet_header(s, size + 6);
-    put_byte(pb, 0xc0);
-    put_be16(pb, 0x4000 + size); /* total frame size */
-    put_be16(pb, 0x4000 + packet_number * 126); /* position in stream */
-#endif
+    write_packet_header(s, stream, size + 2, key_frame);
+    put_byte(pb, 0x41);
     put_byte(pb, stream->nb_frames & 0xff);
 
     put_buffer(pb, buf, size);
     put_flush_packet(pb);
+#endif
 
     stream->nb_frames++;
     return 0;
-------------- next part --------------
--- tests/data/ffmpeg.regression	2007-10-23 13:36:55.000000000 +0300
+++ tests/ffmpeg.regression.ref	2007-10-18 14:57:36.000000000 +0300
@@ -117,12 +117,12 @@
 9086676 ./tests/data/a-jpegls.avi
 0f8637e9b861230aff9894825af83720 *./tests/data/out.yuv
 stddev:  2.84 PSNR:39.04 bytes:7602176
-e1bdb8be4e086810ed8bfee1bdd559e1 *./tests/data/a-rv10.rm
-667665 ./tests/data/a-rv10.rm
+7eee6367442884321e27d15a26bc032a *./tests/data/a-rv10.rm
+667915 ./tests/data/a-rv10.rm
 d507be4253a9c8211a3738c58ba28118 *./tests/data/out.yuv
 stddev:  8.06 PSNR:29.99 bytes:7602176
-279b0d6e4d6ff8e33fb35f2c800832a4 *./tests/data/a-rv20.rm
-640606 ./tests/data/a-rv20.rm
+55c73229105f35cbb06ee0dda215df2f *./tests/data/a-rv20.rm
+640856 ./tests/data/a-rv20.rm
 297dc46da1a256c0a97158c036c30c7f *./tests/data/out.yuv
 stddev:  8.26 PSNR:29.77 bytes:7602176
 d13292f4583618d1b7b525a9ee010dff *./tests/data/a-asv1.avi



More information about the ffmpeg-devel mailing list