[FFmpeg-cvslog] r25931 - trunk/libavformat/asfdec.c

Reimar Döffinger Reimar.Doeffinger
Thu Dec 16 08:21:25 CET 2010


On Thu, Dec 16, 2010 at 01:00:29AM +0100, Michael Niedermayer wrote:
> The way the scrambling works IIRC (at least in some audio codecs) is that you
> have several small more or less independantly decodeable subpackets these
> are then scrambled around so that a burst error or loss of several in series
> is spread over time and easier to conceal.
> it really makes no sense to drop the whole packet if some subpackets are lost
> IMHO

To be honest I only considered the case of EOF, do we actually have any
other case where a read does not finish but we can still continue?
I don't think so, and I think we would end up getting out of sync.
Anyway what happens in an error case already with the current code
is that an error will be returned and then it will try to read/fill
the same fragment again I think (not really sure I admit).
As said this might/is likely to mean things get out of sync, but
so might filling with 0, as long as we have no real-world protocol
that we can test this against I'd consider that unimplementable.
Anyway, fixed a bug in the last patch (setting
ret = asf->packet_frag_size for the scrambling case), but that
changes nothing for WMA and I am not at all sure if it makes
things better or worse really.
If get_buffer fills half a fragment should we 0-fill the rest of
the fragment or try to read the rest at a later point (and doing
the "fill-up" only at EOF)?
Index: asfdec.c
===================================================================
--- asfdec.c    (revision 25943)
+++ asfdec.c    (working copy)
@@ -953,12 +953,22 @@
 
         ret = get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset,
                          asf->packet_frag_size);
-        if (ret != asf->packet_frag_size)
-            return ret >= 0 ? AVERROR_EOF : ret;
+        if (ret != asf->packet_frag_size) {
+            if (ret < 0 || asf->packet_frag_offset + ret == 0)
+                return ret < 0 ? ret : AVERROR_EOF;
+            if (asf_st->ds_span > 1) {
+                // scrambling, we can either drop it completely or fill the remainder
+                memset(asf_st->pkt.data + asf->packet_frag_offset + ret, 0,
+                       asf->packet_frag_size - ret);
+                ret = asf->packet_frag_size;
+            } else
+                // no scrambling, so we can return partial packets
+                av_shrink_packet(&asf_st->pkt, asf->packet_frag_offset + ret);
+        }
         if (s->key && s->keylen == 20)
             ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset,
-                            asf->packet_frag_size);
-        asf_st->frag_offset += asf->packet_frag_size;
+                            ret);
+        asf_st->frag_offset += ret;
         /* test if whole packet is read */
         if (asf_st->frag_offset == asf_st->pkt.size) {
             //workaround for macroshit radio DVR-MS files



More information about the ffmpeg-cvslog mailing list