[FFmpeg-devel] [PATCH] deobfuscate ff_interleave_add_packet

avcoder ffmpeg
Sun Apr 12 13:33:57 CEST 2009


Dear:

On Sun, Apr 12, 2009 at 3:55 PM, Reimar D?ffinger
<Reimar.Doeffinger at gmx.de>wrote:

> Simple, afterwards there is the original pkt and there is
> this_pktl->pkt.
> For both we will call av_free_packet. Since in case 3 they remain
> completely unchanged they are the same (and have a destruct function
> set) and thus destruct will be called twice with exactly the same data
> (the AVPacket pointers are different, but their contents are the same).
> If that function was a simple reimplementation of av_destruct_packet
> you'd have a double free thus (and in addition the first free would
> probably before we are finished using the second packet).
>
>
Thanks for your explain!
I have another (ugly )patch to fix the MinGW shared build issue

My patch just use a flag to do the same thing as function pointer, my patch
does not change any FFmpeg's originial logic(But I think the original logic
on AVPacket memory manangement is ugly)

Please keep your eyes on the "pkt->flags", and ignore my other modification
which is not related on this topic

Thanks

Index: ffmpeg.c
===================================================================
--- ffmpeg.c ??? 18424?
+++ ffmpeg.c ??????
@@ -499,6 +499,8 @@
         if(a>0){
             av_free_packet(pkt);
             new_pkt.destruct= av_destruct_packet;
+            new_pkt.flags |= PKT_FLAG_INNER_FREE;
+            new_pkt.flags &= (~(PKT_FLAG_NO_FREE|PKT_FLAG_OUTER_FREE));
         } else if(a<0){
             fprintf(stderr, "%s failed for stream %d, codec %s",
                     bsfc->filter->name, pkt->stream_index,
@@ -1403,8 +1405,11 @@
                         opkt.flags= pkt->flags;

                         //FIXME remove the following 2 lines they shall be
replaced by the bitstream filters
-                        if(av_parser_change(ist->st->parser,
ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags &
PKT_FLAG_KEY))
+                        if(av_parser_change(ist->st->parser,
ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags &
PKT_FLAG_KEY)) {
                             opkt.destruct= av_destruct_packet;
+                            opkt.flags |= PKT_FLAG_INNER_FREE;
+                            opkt.flags &=
(~(PKT_FLAG_NO_FREE|PKT_FLAG_OUTER_FREE));
+                        }

                         write_frame(os, &opkt, ost->st->codec,
bitstream_filters[ost->file_index][opkt.stream_index]);
                         ost->st->codec->frame_number++;
Index: libavcodec/avcodec.h
===================================================================
--- libavcodec/avcodec.h ??? 18424?
+++ libavcodec/avcodec.h ??????
@@ -901,7 +912,19 @@
      */
     int64_t convergence_duration;
 } AVPacket;
-#define PKT_FLAG_KEY   0x0001
+#define PKT_FLAG_KEY        0x0001
+/**
+ * the normal inner free: av_destruct_packet()
+ */
+#define PKT_FLAG_INNER_FREE 0x10000000
+/**
+ * the outter free: the 3rd counterpart of av_destruct_packet()
+ */
+#define PKT_FLAG_OUTER_FREE 0x20000000
+/**
+ * the normal nofree: av_destruct_packet_nofree()
+ */
+#define PKT_FLAG_NO_FREE    0x40000000

 /* resample.c */

Index: libavcodec/avpacket.c
===================================================================
--- libavcodec/avpacket.c ??? 18424?
+++ libavcodec/avpacket.c ??????
@@ -43,6 +43,7 @@
     pkt->flags = 0;
     pkt->stream_index = 0;
     pkt->destruct= av_destruct_packet_nofree;
+    pkt->flags |= PKT_FLAG_NO_FREE;
 }

 int av_new_packet(AVPacket *pkt, int size)
@@ -59,6 +60,8 @@
     pkt->data = data;
     pkt->size = size;
     pkt->destruct = av_destruct_packet;
+    pkt->flags |= PKT_FLAG_INNER_FREE;
+    pkt->flags &= (~(PKT_FLAG_NO_FREE|PKT_FLAG_OUTER_FREE));
     return 0;
 }

@@ -71,7 +74,9 @@

 int av_dup_packet(AVPacket *pkt)
 {
-    if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct ==
NULL)) && pkt->data) {
+    if(!pkt)
+        return -1;
+    if (((pkt->flags&PKT_FLAG_NO_FREE) || (pkt->destruct == NULL)) &&
pkt->data) {
         uint8_t *data;
         /* We duplicate the packet and don't forget to add the padding
again. */
         if((unsigned)pkt->size > (unsigned)pkt->size +
FF_INPUT_BUFFER_PADDING_SIZE)
@@ -84,6 +89,15 @@
         memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
         pkt->data = data;
         pkt->destruct = av_destruct_packet;
+        pkt->flags |= PKT_FLAG_INNER_FREE;
+        pkt->flags &= (~(PKT_FLAG_NO_FREE|PKT_FLAG_OUTER_FREE));
     }
     return 0;
 }

Index: libavformat/oggdec.c
===================================================================
--- libavformat/oggdec.c ??? 18424?
+++ libavformat/oggdec.c ??????
@@ -518,7 +518,7 @@
         os->lastgp = -1;
     }

-    pkt->flags = os->pflags;
+    pkt->flags |= os->pflags;

     return psize;
 }
Index: libavformat/matroskadec.c
===================================================================
--- libavformat/matroskadec.c ??? 18424?
+++ libavformat/matroskadec.c ??????
@@ -1690,7 +1690,7 @@
                     av_free(pkt_data);

                 if (n == 0)
-                    pkt->flags = is_keyframe;
+                    pkt->flags |= is_keyframe;
                 pkt->stream_index = st->index;

                 pkt->pts = timecode;
===================================================================
--- libavformat/lmlm4.c ??? 18424?
+++ libavformat/lmlm4.c ??????
@@ -104,7 +104,7 @@

     switch (frame_type) {
         case LMLM4_I_FRAME:
-            pkt->flags = PKT_FLAG_KEY;
+            pkt->flags |= PKT_FLAG_KEY;
         case LMLM4_P_FRAME:
         case LMLM4_B_FRAME:
             pkt->stream_index = 0;
Index: libavformat/mov.c
===================================================================
--- libavformat/mov.c ??? 18424?
+++ libavformat/mov.c ??????
@@ -78,7 +78,8 @@
     int (*parse)(MOVContext *ctx, ByteIOContext *pb, MOVAtom atom);
 } MOVParseTableEntry;

-static const MOVParseTableEntry mov_default_parse_table[];
+//hacked for MSVC++:error C2133: 'mov_default_parse_table' : unknown size
+static const MOVParseTableEntry *mov_default_parse_table = NULL;

 static int mov_metadata_trkn(MOVContext *c, ByteIOContext *pb, unsigned
len)
 {
@@ -996,7 +997,7 @@
         } else if(st->codec->codec_type==CODEC_TYPE_SUBTITLE){
             // ttxt stsd contains display flags, justification, background
             // color, fonts, and default styles, so fake an atom to read it
-            MOVAtom fake_atom = { .size = size - (url_ftell(pb) -
start_pos) };
+            MOVAtom fake_atom = {0, 0, size - (url_ftell(pb) - start_pos)
};
             if (format != AV_RL32("mp4s")) // mp4s contains a regular esds
atom
                 mov_read_glbl(c, pb, fake_atom);
             st->codec->codec_id= id;
@@ -1446,9 +1447,11 @@
     switch (st->codec->codec_id) {
 #if CONFIG_H261_DECODER
     case CODEC_ID_H261:
+        break;
 #endif
 #if CONFIG_H263_DECODER
     case CODEC_ID_H263:
+        break;
 #endif
 #if CONFIG_H264_DECODER
     case CODEC_ID_H264:
@@ -1805,7 +1808,7 @@
     return 0;
 }

-static const MOVParseTableEntry mov_default_parse_table[] = {
+static const MOVParseTableEntry mov_default_parse_table_a[] = {
 { MKTAG('a','v','s','s'), mov_read_extradata },
 { MKTAG('c','o','6','4'), mov_read_stco },
 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
@@ -1907,6 +1910,9 @@
     int err;
     MOVAtom atom = { 0, 0, 0 };

+    if(!mov_default_parse_table)
+        mov_default_parse_table = mov_default_parse_table_a;
+
     mov->fc = s;
     /* .mov and .mp4 aren't streamable anyway (only progressive download if
moov is before mdat) */
     if(!url_is_streamed(pb))
@@ -1956,9 +1962,10 @@
         }
     }
     if (!sample) {
+        MOVAtom fake_atom = { 0, 0, INT64_MAX };
         mov->found_mdat = 0;
         if (!url_is_streamed(s->pb) ||
-            mov_read_default(mov, s->pb, (MOVAtom){ 0, 0, INT64_MAX }) < 0
||
+            mov_read_default(mov, s->pb, fake_atom) < 0 ||
             url_feof(s->pb))
             return -1;
         dprintf(s, "read fragments, offset 0x%llx\n", url_ftell(s->pb));
@@ -2004,7 +2011,10 @@
         pkt->duration = next_dts - pkt->dts;
         pkt->pts = pkt->dts;
     }
-    pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? PKT_FLAG_KEY : 0;
+    if(sample->flags & AVINDEX_KEYFRAME)
+        pkt->flags |= PKT_FLAG_KEY;
+    else
+        pkt->flags &= (~PKT_FLAG_KEY);
     pkt->pos = sample->pos;
     dprintf(s, "stream %d, pts %"PRId64", dts %"PRId64", pos 0x%"PRIx64",
duration %d\n",
             pkt->stream_index, pkt->pts, pkt->dts, pkt->pos,
pkt->duration);
@@ -2041,6 +2051,9 @@

 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t
sample_time, int flags)
 {
+    MOVStreamContext *sc = 0;
+    AVIndexEntry *index_sample = 0;
+    int64_t best_dts = INT64_MAX;
     AVStream *st;
     int64_t seek_timestamp, timestamp;
     int sample;
@@ -2067,6 +2080,32 @@
         timestamp = av_rescale_q(seek_timestamp,
s->streams[stream_index]->time_base, st->time_base);
         mov_seek_stream(st, timestamp, flags);
     }
+
+    //try to locate the best sample offset
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+        MOVStreamContext *msc = st->priv_data;
+        if (st->discard != AVDISCARD_ALL && msc->pb && msc->current_sample
< msc->sample_count) {
+            AVIndexEntry *current_sample =
&st->index_entries[msc->current_sample];
+            int64_t dts = av_rescale(current_sample->timestamp *
(int64_t)msc->time_rate,
+                                     AV_TIME_BASE, msc->time_scale);
+            dprintf(s, "stream %d, sample %d, dts %"PRId64"\n", i,
msc->current_sample, dts);
+            if (!index_sample || (url_is_streamed(s->pb) &&
current_sample->pos < index_sample->pos) ||
+                (!url_is_streamed(s->pb) &&
+                 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb
&&
+                 ((FFABS(best_dts - dts) <= AV_TIME_BASE &&
current_sample->pos < index_sample->pos) ||
+                  (FFABS(best_dts - dts) > AV_TIME_BASE && dts <
best_dts)))))) {
+                index_sample = current_sample;
+                best_dts = dts;
+                sc = msc;
+            }
+        }
+    }
+    if(index_sample){
+        s->data_offset = index_sample->pos;
+        url_fseek(sc->pb, index_sample->pos, SEEK_SET);
+    }
+
     return 0;
 }

Index: libavformat/utils.c
===================================================================
--- libavformat/utils.c ??? 18424?
+++ libavformat/utils.c ??????
@@ -27,6 +27,9 @@
 #include <sys/time.h>
 #include <time.h>
 #include <strings.h>
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif

 #undef NDEBUG
 #include <assert.h>
@@ -869,7 +872,7 @@
     if(is_intra_only(st->codec))
         pkt->flags |= PKT_FLAG_KEY;
     else if (pc) {
-        pkt->flags = 0;
+        pkt->flags &= (~PKT_FLAG_KEY);
         /* keyframe computation */
         if (pc->key_frame == 1)
             pkt->flags |= PKT_FLAG_KEY;
@@ -925,6 +928,8 @@
                     pkt->pos = st->parser->pos;
                     pkt->destruct = av_destruct_packet_nofree;
                     compute_pkt_fields(s, st, st->parser, pkt);
+                    pkt->flags |= PKT_FLAG_NO_FREE;
+                    pkt->flags &=
(~(PKT_FLAG_INNER_FREE|PKT_FLAG_OUTER_FREE));

                     if((s->iformat->flags & AVFMT_GENERIC_INDEX) &&
pkt->flags & PKT_FLAG_KEY){
                         ff_reduce_index(s, st->index);
@@ -1254,6 +1259,11 @@

     ts_max=
     ts_min= AV_NOPTS_VALUE;
+#ifdef _MSC_VER
+    //avoid MSVC's runtime checking failure in debug mode
+    pos_min = INT64_MIN;
+    pos_max = INT64_MAX;
+#endif
     pos_limit= -1; //gcc falsely says it may be uninitialized

     st= s->streams[stream_index];
@@ -1951,9 +1961,10 @@
 #define MAX_READ_SIZE        5000000

 #define MAX_STD_TIMEBASES (60*12+5)
+static const int av_std_frame_rate[] = {24,30,60,12,15};
 static int get_std_framerate(int i){
     if(i<60*12) return i*1001;
-    else        return ((const int[]){24,30,60,12,15})[i-60*12]*1000*12;
+    else        return av_std_frame_rate[i-60*12]*1000*12;
 }

 /*
@@ -2349,7 +2360,8 @@
         st->pts_buffer[i]= AV_NOPTS_VALUE;
     st->reference_dts = AV_NOPTS_VALUE;

-    st->sample_aspect_ratio = (AVRational){0,1};
+    st->sample_aspect_ratio.num = 0;
+    st->sample_aspect_ratio.den = 1;

     s->streams[s->nb_streams++] = st;
     return st;
@@ -2613,7 +2625,7 @@

     this_pktl = av_mallocz(sizeof(AVPacketList));
     this_pktl->pkt= *pkt;
-    if(pkt->destruct == av_destruct_packet)
+    if(pkt->flags&PKT_FLAG_INNER_FREE)
         pkt->destruct= NULL; // not shared -> must keep original from being
freed
     else
         av_dup_packet(&this_pktl->pkt);  //shared -> must dup
@@ -2905,6 +2917,13 @@
     return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
 }

+int64_t av_gettime_ms(void)
+{
+    struct timeval tv;
+    gettimeofday(&tv,NULL);
+    return (int64_t)tv.tv_sec * 1000 + (tv.tv_usec+500)/1000;
+}
+
 int64_t parse_date(const char *datestr, int duration)
 {
     const char *p;
Index: libavformat/vc1test.c
===================================================================
--- libavformat/vc1test.c ??? 18424?
+++ libavformat/vc1test.c ??????
@@ -96,7 +96,10 @@
         return AVERROR(EIO);
     if(s->streams[0]->time_base.den == 1000)
         pkt->pts = pts;
-    pkt->flags |= keyframe ? PKT_FLAG_KEY : 0;
+    if(keyframe)
+        pkt->flags |= PKT_FLAG_KEY;
+    else
+        pkt->flags &= (~PKT_FLAG_KEY);
     pkt->pos -= 8;

     return pkt->size;
Index: libavformat/rmdec.c
===================================================================
--- libavformat/rmdec.c ??? 18424?
+++ libavformat/rmdec.c ??????
@@ -66,9 +66,8 @@
 static inline void get_strl(ByteIOContext *pb, char *buf, int buf_size, int
len)
 {
     int i;
-    char *q, r;
+    char *q = buf, r;

-    q = buf;
     for(i=0;i<len;i++) {
         r = get_byte(pb);
         if (i < buf_size - 1)
@@ -109,55 +108,60 @@
                                      AVStream *st, RMStream *ast, int
read_all)
 {
     char buf[256];
-    uint32_t version;
+    uint32_t version,headsize;

-    /* ra type header */
-    version = get_be32(pb); /* version */
-    if (((version >> 16) & 0xff) == 3) {
+    version  = get_be16(pb);
+    headsize = get_be16(pb);
+    if (version == 3) {
         int64_t startpos = url_ftell(pb);
+        int64_t headoffset = startpos + headsize;
+
         url_fskip(pb, 14);
         rm_read_metadata(s, 0);
-        if ((startpos + (version & 0xffff)) >= url_ftell(pb) + 2) {
+        if (headoffset >= url_ftell(pb) + 2) {
             // fourcc (should always be "lpcJ")
             get_byte(pb);
             get_str8(pb, buf, sizeof(buf));
         }
         // Skip extra header crap (this should never happen)
-        if ((startpos + (version & 0xffff)) > url_ftell(pb))
-            url_fskip(pb, (version & 0xffff) + startpos - url_ftell(pb));
+        if (headoffset > url_ftell(pb))
+            url_fskip(pb, headoffset - url_ftell(pb));
         st->codec->sample_rate = 8000;
         st->codec->channels = 1;
         st->codec->codec_type = CODEC_TYPE_AUDIO;
         st->codec->codec_id = CODEC_ID_RA_144;
     } else {
-        int flavor, sub_packet_h, coded_framesize, sub_packet_size;
+        int flavor;
         /* old version (4) */
         get_be32(pb); /* .ra4 */
         get_be32(pb); /* data size */
         get_be16(pb); /* version2 */
         get_be32(pb); /* header size */
         flavor= get_be16(pb); /* add codec info / flavor */
-        ast->coded_framesize = coded_framesize = get_be32(pb); /* coded
frame size */
+        ast->coded_framesize = get_be32(pb); /* coded frame size */
         get_be32(pb); /* ??? */
         get_be32(pb); /* ??? */
         get_be32(pb); /* ??? */
-        ast->sub_packet_h = sub_packet_h = get_be16(pb); /* 1 */
+        ast->sub_packet_h = get_be16(pb); /* 1 */
         st->codec->block_align= get_be16(pb); /* frame size */
-        ast->sub_packet_size = sub_packet_size = get_be16(pb); /* sub
packet size */
+        ast->sub_packet_size = get_be16(pb); /* sub packet size */
         get_be16(pb); /* ??? */
-        if (((version >> 16) & 0xff) == 5) {
-            get_be16(pb); get_be16(pb); get_be16(pb);
+        if (version == 5) {
+            get_be16(pb);
+            get_be16(pb);
+            get_be16(pb);
         }
         st->codec->sample_rate = get_be16(pb);
-        get_be32(pb);
+        get_be16(pb); /* ??? */
+        get_be16(pb); /* sample size */
         st->codec->channels = get_be16(pb);
-        if (((version >> 16) & 0xff) == 5) {
+        if (version == 5) {
             get_be32(pb);
             get_buffer(pb, buf, 4);
             buf[4] = 0;
         } else {
             get_str8(pb, buf, sizeof(buf)); /* desc */
-            get_str8(pb, buf, sizeof(buf)); /* desc */
+            get_str8(pb, buf, sizeof(buf)); /* FOURCC */
         }
         st->codec->codec_type = CODEC_TYPE_AUDIO;
         if (!strcmp(buf, "dnet")) {
@@ -167,18 +171,18 @@
             st->codec->codec_id = CODEC_ID_RA_288;
             st->codec->extradata_size= 0;
             ast->audio_framesize = st->codec->block_align;
-            st->codec->block_align = coded_framesize;
+            st->codec->block_align = ast->coded_framesize;

-            if(ast->audio_framesize >= UINT_MAX / sub_packet_h){
+            if(ast->audio_framesize >= UINT_MAX / ast->sub_packet_h){
                 av_log(s, AV_LOG_ERROR, "ast->audio_framesize *
sub_packet_h too large\n");
                 return -1;
             }

-            av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h);
+            av_new_packet(&ast->pkt, ast->audio_framesize *
ast->sub_packet_h);
         } else if ((!strcmp(buf, "cook")) || (!strcmp(buf, "atrc")) ||
(!strcmp(buf, "sipr"))) {
             int codecdata_length;
             get_be16(pb); get_byte(pb);
-            if (((version >> 16) & 0xff) == 5)
+            if (version == 5)
                 get_byte(pb);
             codecdata_length = get_be32(pb);
             if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <=
(unsigned)codecdata_length){
@@ -199,7 +203,7 @@
                 }
                 st->codec->block_align = sipr_subpk_size[flavor];
             } else {
-                if(sub_packet_size <= 0){
+                if(ast->sub_packet_size <= 0){
                     av_log(s, AV_LOG_ERROR, "sub_packet_size is
invalid\n");
                     return -1;
                 }
@@ -209,16 +213,16 @@
             st->codec->extradata= av_mallocz(st->codec->extradata_size +
FF_INPUT_BUFFER_PADDING_SIZE);
             get_buffer(pb, st->codec->extradata,
st->codec->extradata_size);

-            if(ast->audio_framesize >= UINT_MAX / sub_packet_h){
-                av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h
too large\n");
+            if(ast->audio_framesize >= UINT_MAX / ast->sub_packet_h){
+                av_log(s, AV_LOG_ERROR, "ast->audio_framesize *
sub_packet_h too large\n");
                 return -1;
             }

-            av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h);
+            av_new_packet(&ast->pkt, ast->audio_framesize *
ast->sub_packet_h);
         } else if (!strcmp(buf, "raac") || !strcmp(buf, "racp")) {
             int codecdata_length;
             get_be16(pb); get_byte(pb);
-            if (((version >> 16) & 0xff) == 5)
+            if (version == 5)
                 get_byte(pb);
             st->codec->codec_id = CODEC_ID_AAC;
             codecdata_length = get_be32(pb);
@@ -262,7 +266,7 @@
         if (rm_read_audio_stream_info(s, pb, st, rst, 0))
             return -1;
     } else {
-        int fps, fps2;
+        int bpp,fps;
         if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) {
         fail1:
             av_log(st->codec, AV_LOG_ERROR, "Unsupported video codec\n");
@@ -279,10 +283,10 @@
         st->codec->width = get_be16(pb);
         st->codec->height = get_be16(pb);
         st->codec->time_base.num= 1;
-        fps= get_be16(pb);
+        bpp= get_be16(pb);
         st->codec->codec_type = CODEC_TYPE_VIDEO;
         get_be32(pb);
-        fps2= get_be16(pb);
+        fps= get_be16(pb);
         get_be16(pb);

         st->codec->extradata_size= codec_data_size - (url_ftell(pb) -
codec_pos);
@@ -359,7 +363,7 @@

     return 0;
 }
-
+/* audio data is CBR */
 static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap)
 {
     RMDemuxContext *rm = s->priv_data;
@@ -378,9 +382,8 @@
     RMDemuxContext *rm = s->priv_data;
     AVStream *st;
     ByteIOContext *pb = s->pb;
-    unsigned int tag;
+    unsigned int tag, head_size;
     int tag_size;
-    unsigned int start_time, duration;
     unsigned int data_off = 0, indx_off = 0;
     char buf[128];
     int flags = 0;
@@ -393,9 +396,13 @@
         return AVERROR(EIO);
     }

-    get_be32(pb); /* header size */
-    get_be16(pb);
-    get_be32(pb);
+    head_size = get_be32(pb); /* including 8-bytes preamble */
+    get_be16(pb); /* chunk version */
+    /* file version */
+    if(0x12 == head_size)
+        get_be32(pb);
+    else
+        get_be16(pb);
     get_be32(pb); /* number of headers */

     for(;;) {
@@ -403,7 +410,7 @@
             return -1;
         tag = get_le32(pb);
         tag_size = get_be32(pb);
-        get_be16(pb);
+        get_be16(pb); /* version */
 #if 0
         printf("tag=%c%c%c%c (%08x) size=%d\n",
                (tag) & 0xff,
@@ -423,10 +430,10 @@
             get_be32(pb); /* max packet size */
             get_be32(pb); /* avg packet size */
             get_be32(pb); /* nb packets */
-            get_be32(pb); /* duration */
-            get_be32(pb); /* preroll */
-            indx_off = get_be32(pb); /* index offset */
-            data_off = get_be32(pb); /* data offset */
+            get_be32(pb); /* duration in ms */
+            get_be32(pb); /* preroll in ms */
+            indx_off = get_be32(pb); /* the first index offset */
+            data_off = get_be32(pb); /* the first data offset */
             get_be16(pb); /* nb streams */
             flags = get_be16(pb); /* flags */
             break;
@@ -439,14 +446,12 @@
                 return AVERROR(ENOMEM);
             st->id = get_be16(pb);
             get_be32(pb); /* max bit rate */
-            st->codec->bit_rate = get_be32(pb); /* bit rate */
+            st->codec->bit_rate = get_be32(pb); /* avg bit rate */
             get_be32(pb); /* max packet size */
             get_be32(pb); /* avg packet size */
-            start_time = get_be32(pb); /* start time */
-            get_be32(pb); /* preroll */
-            duration = get_be32(pb); /* duration */
-            st->start_time = start_time;
-            st->duration = duration;
+            st->start_time = get_be32(pb); /* start time in ms */
+            get_be32(pb); /* preroll in ms */
+            st->duration = get_be32(pb); /* duration in ms */
             get_str8(pb, buf, sizeof(buf)); /* desc */
             get_str8(pb, buf, sizeof(buf)); /* mimetype */
             st->codec->codec_type = CODEC_TYPE_DATA;
@@ -796,9 +801,9 @@
     rm->audio_pkt_cnt--;
     if ((pkt->pts = ast->audiotimestamp) != AV_NOPTS_VALUE) {
         ast->audiotimestamp = AV_NOPTS_VALUE;
-        pkt->flags = PKT_FLAG_KEY;
+        pkt->flags |= PKT_FLAG_KEY;
     } else
-        pkt->flags = 0;
+        pkt->flags &= (~PKT_FLAG_KEY);
     pkt->stream_index = st->index;

     return rm->audio_pkt_cnt;
Index: libavformat/flv.h
===================================================================
--- libavformat/flv.h ??? 18424?
+++ libavformat/flv.h ??????
@@ -42,6 +42,8 @@

 #define AMF_END_OF_OBJECT         0x09

+#define NUM_OF_ENTRIES 20
+
 enum {
     FLV_HEADER_FLAG_HASVIDEO = 1,
     FLV_HEADER_FLAG_HASAUDIO = 4,
@@ -108,6 +110,9 @@
     AMF_DATA_TYPE_ARRAY       = 0x0a,
     AMF_DATA_TYPE_DATE        = 0x0b,
     AMF_DATA_TYPE_UNSUPPORTED = 0x0d,
+    AMF_CHILDNODE             = 0x03,
+    AMF_CHILDNODEVALUE        = 0x0a,
+    AMF_PARENTNODE            = 0x09,
 } AMFDataType;

 #endif /* AVFORMAT_FLV_H */
Index: libavformat/nsvdec.c
===================================================================
--- libavformat/nsvdec.c ??? 18424?
+++ libavformat/nsvdec.c ??????
@@ -597,7 +597,10 @@
         av_get_packet(pb, pkt, vsize);
         pkt->stream_index = st[NSV_ST_VIDEO]->index;//NSV_ST_VIDEO;
         pkt->dts = nst->frame_offset;
-        pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? PKT_FLAG_KEY : 0;
/* keyframe only likely on a sync frame */
+        if(nsv->state == NSV_HAS_READ_NSVS)
+            pkt->flags |= PKT_FLAG_KEY;/* keyframe only likely on a sync
frame */
+        else
+            pkt->flags &= (~PKT_FLAG_KEY);
 /*
         for (i = 0; i < MIN(8, vsize); i++)
             PRINT(("NSV video: [%d] = %02x\n", i, pkt->data[i]));
@@ -637,7 +640,10 @@
         }
         av_get_packet(pb, pkt, asize);
         pkt->stream_index = st[NSV_ST_AUDIO]->index;//NSV_ST_AUDIO;
-        pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? PKT_FLAG_KEY : 0;
/* keyframe only likely on a sync frame */
+        if(nsv->state == NSV_HAS_READ_NSVS)
+            pkt->flags |= PKT_FLAG_KEY; /* keyframe only likely on a sync
frame */
+        else
+            pkt->flags &= (~PKT_FLAG_KEY);
         if( nsv->state == NSV_HAS_READ_NSVS && st[NSV_ST_VIDEO] ) {
             /* on a nsvs frame we have new information on a/v sync */
             pkt->dts =
(((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset-1);
Index: libavdevice/v4l2.c
===================================================================
--- libavdevice/v4l2.c ??? 18424?
+++ libavdevice/v4l2.c ??????
@@ -379,6 +379,8 @@
     pkt->size = buf.bytesused;
     pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) +
buf.timestamp.tv_usec;
     pkt->destruct = mmap_release_buffer;
+    pkt->flags |= PKT_FLAG_OUTER_FREE;
+    pkt->flags &= (~(PKT_FLAG_INNER_FREE|PKT_FLAG_NO_FREE));
     buf_descriptor = av_malloc(sizeof(struct buff_data));
     if (buf_descriptor == NULL) {
         /* Something went wrong... Since av_malloc() failed, we cannot even

-- 
----------------------------------------------
Inspired by http://ppnext.com
Your potential. Our passion.



More information about the ffmpeg-devel mailing list