[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