Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 19 Feb 2012 00:36:23 +0000 (01:36 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 19 Feb 2012 00:47:10 +0000 (01:47 +0100)
* qatar/master:
  mov: Use defines for sample flags in fragments
  mov: Use defines for trun flags
  mov: Use defines for tfhd flags
  proresenc: force bitrate not to exceed given limit
  vc1parse: call vc1_init_common().
  wma: don't return 0 on invalid packets.
  asf: prevent packet_size_left from going negative if hdrlen > pktlen.
  mjpegb: don't return 0 at the end of frame decoding.
  rtpdec: Identify incorrectly signalled H263
  vp8dsp: split long line.
  aiff: don't skip block_align==0 check on COMM-after-SSND files.
  dpcm: ignore extra unpaired bytes in stereo streams.
  mp3on4: require a minimum framesize.
  mpc7: assign an error level + context to av_log() msg.
  huffyuv: error out on bit overrun.
  dct-test: Add the missing ff_ prefix to the altivec functions
  dct-test: Remove a stray declaration of a nonexistent function
  movenc: Write the unknown duration as 64 bit fields in ismv
  movenc: Write track durations with all bits set if duration is unknown

Conflicts:
libavcodec/dct-test.c
libavcodec/wmadec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
21 files changed:
libavcodec/dct-test.c
libavcodec/dpcm.c
libavcodec/huffyuv.c
libavcodec/mjpegbdec.c
libavcodec/mpc7.c
libavcodec/mpegaudiodec.c
libavcodec/proresenc_kostya.c
libavcodec/vc1.h
libavcodec/vc1_parser.c
libavcodec/vc1dec.c
libavcodec/vp8dsp.h
libavcodec/wmadec.c
libavformat/aiffdec.c
libavformat/asfdec.c
libavformat/isom.h
libavformat/mov.c
libavformat/movenc.c
libavformat/rtpdec_formats.h
libavformat/rtpdec_h263.c
libavformat/rtpdec_h263_rfc2190.c
tests/ref/lavf/ismv

index 5a27b75..3a6ab96 100644 (file)
@@ -54,7 +54,7 @@ void ff_bfin_fdct(DCTELEM *block);
 
 // ALTIVEC
 void ff_fdct_altivec(DCTELEM *block);
-//void idct_altivec(DCTELEM *block);?? no routine
+//void ff_idct_altivec(DCTELEM *block);?? no routine
 
 // ARM
 void ff_j_rev_dct_arm(DCTELEM *data);
index 8240221..4915223 100644 (file)
@@ -183,6 +183,11 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
     int stereo = s->channels - 1;
     int16_t *output_samples;
 
+    if (stereo && (buf_size & 1)) {
+        buf_size--;
+        buf_end--;
+    }
+
     /* calculate output size */
     switch(avctx->codec->id) {
     case CODEC_ID_ROQ_DPCM:
@@ -320,7 +325,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
     *got_frame_ptr   = 1;
     *(AVFrame *)data = s->frame;
 
-    return buf_size;
+    return avpkt->size;
 }
 
 #define DPCM_DECODER(id_, name_, long_name_)                \
index c46e93f..625d8fb 100644 (file)
@@ -212,7 +212,7 @@ static int read_len_table(uint8_t *dst, GetBitContext *gb){
         if(repeat==0)
             repeat= get_bits(gb, 8);
 //printf("%d %d\n", val, repeat);
-        if(i+repeat > 256) {
+        if(i+repeat > 256 || get_bits_left(gb) < 0) {
             av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n");
             return -1;
         }
index fc77b14..b70311b 100644 (file)
@@ -69,7 +69,7 @@ read_header:
     if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g'))
     {
         av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n");
-        return 0;
+        return AVERROR_INVALIDDATA;
     }
 
     field_size = get_bits_long(&hgb, 32); /* field size */
@@ -149,7 +149,7 @@ read_header:
         picture->quality*= FF_QP2LAMBDA;
     }
 
-    return buf_ptr - buf;
+    return buf_size;
 }
 
 AVCodec ff_mjpegb_decoder = {
index e90c934..6e4b850 100644 (file)
@@ -298,7 +298,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
     bits_used = get_bits_count(&gb);
     bits_avail = buf_size * 8;
     if (!last_frame && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))) {
-        av_log(NULL,0, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail);
+        av_log(avctx, AV_LOG_ERROR, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail);
         return -1;
     }
     if(c->frames_to_skip){
index 2ca30f2..f474161 100644 (file)
@@ -1914,6 +1914,10 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
         m     = s->mp3decctx[fr];
         assert(m != NULL);
 
+        if (fsize < HEADER_SIZE) {
+            av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");
+            return AVERROR_INVALIDDATA;
+        }
         header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
 
         if (ff_mpa_check_header(header) < 0) // Bad header, discard block
index 242537b..8259b2a 100644 (file)
@@ -139,11 +139,14 @@ struct TrellisNode {
     int score;
 };
 
+#define MAX_STORED_Q 16
+
 typedef struct ProresContext {
     AVClass *class;
     DECLARE_ALIGNED(16, DCTELEM, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
     DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
-    int16_t quants[16][64];
+    int16_t quants[MAX_STORED_Q][64];
+    int16_t custom_q[64];
 
     ProresDSPContext dsp;
     ScanTable  scantable;
@@ -156,6 +159,8 @@ typedef struct ProresContext {
     int num_planes;
     int bits_per_mb;
 
+    int frame_size;
+
     int profile;
     const struct prores_profile *profile_info;
 
@@ -348,6 +353,15 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
     int slice_width_factor = av_log2(mbs_per_slice);
     int num_cblocks, pwidth;
     int plane_factor, is_chroma;
+    uint16_t *qmat;
+
+    if (quant < MAX_STORED_Q) {
+        qmat = ctx->quants[quant];
+    } else {
+        qmat = ctx->custom_q;
+        for (i = 0; i < 64; i++)
+            qmat[i] = ctx->profile_info->quant[i] * quant;
+    }
 
     for (i = 0; i < ctx->num_planes; i++) {
         is_chroma    = (i == 1 || i == 2);
@@ -373,7 +387,7 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
         sizes[i] = encode_slice_plane(ctx, pb, src, pic->linesize[i],
                                       mbs_per_slice, ctx->blocks[0],
                                       num_cblocks, plane_factor,
-                                      ctx->quants[quant]);
+                                      qmat);
         total_size += sizes[i];
     }
     return total_size;
@@ -500,6 +514,8 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
     int error, bits, bits_limit;
     int mbs, prev, cur, new_score;
     int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
+    int overquant;
+    uint16_t *qmat;
 
     mbs = x + mbs_per_slice;
 
@@ -526,7 +542,7 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
                        mbs_per_slice, num_cblocks[i]);
     }
 
-    for (q = min_quant; q <= max_quant; q++) {
+    for (q = min_quant; q < max_quant + 2; q++) {
         ctx->nodes[trellis_node + q].prev_node = -1;
         ctx->nodes[trellis_node + q].quant     = q;
     }
@@ -549,12 +565,43 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
         slice_bits[q]  = bits;
         slice_score[q] = error;
     }
+    if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
+        slice_bits[max_quant + 1]  = slice_bits[max_quant];
+        slice_score[max_quant + 1] = slice_score[max_quant] + 1;
+        overquant = max_quant;
+    } else {
+        for (q = max_quant + 1; q < 128; q++) {
+            bits  = 0;
+            error = 0;
+            if (q < MAX_STORED_Q) {
+                qmat = ctx->quants[q];
+            } else {
+                qmat = ctx->custom_q;
+                for (i = 0; i < 64; i++)
+                    qmat[i] = ctx->profile_info->quant[i] * q;
+            }
+            for (i = 0; i < ctx->num_planes; i++) {
+                bits += estimate_slice_plane(ctx, &error, i,
+                                             src, pic->linesize[i],
+                                             mbs_per_slice,
+                                             num_cblocks[i], plane_factor[i],
+                                             qmat);
+            }
+            if (bits <= ctx->bits_per_mb * mbs_per_slice)
+                break;
+        }
+
+        slice_bits[max_quant + 1]  = bits;
+        slice_score[max_quant + 1] = error;
+        overquant = q;
+    }
+    ctx->nodes[trellis_node + max_quant + 1].quant = overquant;
 
     bits_limit = mbs * ctx->bits_per_mb;
-    for (pq = min_quant; pq <= max_quant; pq++) {
+    for (pq = min_quant; pq < max_quant + 2; pq++) {
         prev = trellis_node - TRELLIS_WIDTH + pq;
 
-        for (q = min_quant; q <= max_quant; q++) {
+        for (q = min_quant; q < max_quant + 2; q++) {
             cur = trellis_node + q;
 
             bits  = ctx->nodes[prev].bits + slice_bits[q];
@@ -578,7 +625,7 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
 
     error = ctx->nodes[trellis_node + min_quant].score;
     pq    = trellis_node + min_quant;
-    for (q = min_quant + 1; q <= max_quant; q++) {
+    for (q = min_quant + 1; q < max_quant + 2; q++) {
         if (ctx->nodes[trellis_node + q].score <= error) {
             error = ctx->nodes[trellis_node + q].score;
             pq    = trellis_node + q;
@@ -606,8 +653,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
     avctx->coded_frame->key_frame = 1;
 
-    pkt_size = ctx->mb_width * ctx->mb_height * 64 * 3 * 12
-               + ctx->num_slices * 2 + 200 + FF_MIN_BUFFER_SIZE;
+    pkt_size = ctx->frame_size + FF_MIN_BUFFER_SIZE;
 
     if ((ret = ff_alloc_packet(pkt, pkt_size)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
@@ -762,9 +808,13 @@ static av_cold int encode_init(AVCodecContext *avctx)
             break;
     ctx->bits_per_mb   = ctx->profile_info->br_tab[i];
 
+    ctx->frame_size = ctx->num_slices * (2 + 2 * ctx->num_planes
+                                         + (2 * mps * ctx->bits_per_mb) / 8)
+                      + 200;
+
     min_quant = ctx->profile_info->min_quant;
     max_quant = ctx->profile_info->max_quant;
-    for (i = min_quant; i <= max_quant; i++) {
+    for (i = min_quant; i < MAX_STORED_Q; i++) {
         for (j = 0; j < 64; j++)
             ctx->quants[i][j] = ctx->profile_info->quant[j] * i;
     }
@@ -773,6 +823,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     av_log(avctx, AV_LOG_DEBUG, "profile %d, %d slices, %d bits per MB\n",
            ctx->profile, ctx->num_slices, ctx->bits_per_mb);
+    av_log(avctx, AV_LOG_DEBUG, "estimated frame size %d\n",
+           ctx->frame_size);
 
     ctx->nodes = av_malloc((ctx->slices_width + 1) * TRELLIS_WIDTH
                            * sizeof(*ctx->nodes));
@@ -780,7 +832,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         encode_close(avctx);
         return AVERROR(ENOMEM);
     }
-    for (i = min_quant; i <= max_quant; i++) {
+    for (i = min_quant; i < max_quant + 2; i++) {
         ctx->nodes[i].prev_node = -1;
         ctx->nodes[i].bits      = 0;
         ctx->nodes[i].score     = 0;
index 61b3427..0f18530 100644 (file)
@@ -447,5 +447,6 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex
 
 int ff_vc1_parse_frame_header    (VC1Context *v, GetBitContext *gb);
 int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb);
+int ff_vc1_init_common(VC1Context *v);
 
 #endif /* AVCODEC_VC1_H */
index f133e3a..a2a0d4a 100644 (file)
@@ -188,7 +188,7 @@ static int vc1_parse_init(AVCodecParserContext *s)
 {
     VC1ParseContext *vpc = s->priv_data;
     vpc->v.s.slice_context_count = 1;
-    return 0;
+    return ff_vc1_init_common(&vpc->v);
 }
 
 AVCodecParser ff_vc1_parser = {
index a10ec85..bffd7b8 100644 (file)
@@ -67,7 +67,7 @@ static const int offset_table2[9] = {  0,  1,  3,  7, 15, 31, 63, 127, 255 };
  * @param v The VC1Context to initialize
  * @return Status
  */
-static int vc1_init_common(VC1Context *v)
+int ff_vc1_init_common(VC1Context *v)
 {
     static int done = 0;
     int i = 0;
@@ -5274,7 +5274,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
         avctx->idct_algo = FF_IDCT_WMV2;
     }
 
-    if (vc1_init_common(v) < 0)
+    if (ff_vc1_init_common(v) < 0)
         return -1;
     ff_vc1dsp_init(&v->vc1dsp);
 
index 987fa59..951a556 100644 (file)
@@ -29,7 +29,9 @@
 
 #include "dsputil.h"
 
-typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, int dstStride, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
+typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, int dstStride,
+                            uint8_t *src/*align 1*/, int srcStride,
+                            int h, int x, int y);
 
 typedef struct VP8DSPContext {
     void (*vp8_luma_dc_wht)(DCTELEM block[4][4][16], DCTELEM dc[16]);
index 7d7cc7f..c90e22c 100644 (file)
@@ -834,8 +834,12 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data,
         s->last_superframe_len = 0;
         return 0;
     }
-    if (buf_size < s->block_align)
-        return AVERROR(EINVAL);
+    if (buf_size < s->block_align) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Input packet size too small (%d < %d)\n",
+               buf_size, s->block_align);
+        return AVERROR_INVALIDDATA;
+    }
     if(s->block_align)
         buf_size = s->block_align;
 
index fbbf6a4..239fca3 100644 (file)
@@ -270,12 +270,12 @@ static int aiff_read_header(AVFormatContext *s)
         }
     }
 
+got_sound:
     if (!st->codec->block_align) {
-        av_log(s, AV_LOG_ERROR, "could not find COMM tag\n");
+        av_log(s, AV_LOG_ERROR, "could not find COMM tag or invalid block_align value\n");
         return -1;
     }
 
-got_sound:
     /* Now positioned, get the sound data start and end */
     avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
     st->start_time = 0;
index e2f46dc..b37cbb0 100644 (file)
@@ -797,6 +797,13 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
         asf->packet_segments = 1;
         asf->packet_segsizetype = 0x80;
     }
+    if (rsize > packet_length - padsize) {
+        asf->packet_size_left = 0;
+        av_log(s, AV_LOG_ERROR,
+               "invalid packet header length %d for pktlen %d-%d at %"PRId64"\n",
+               rsize, packet_length, padsize, avio_tell(pb));
+        return -1;
+    }
     asf->packet_size_left = packet_length - padsize - rsize;
     if (packet_length < asf->hdr.min_pktsize)
         padsize += asf->hdr.min_pktsize - packet_length;
index 776b265..32c81b7 100644 (file)
@@ -162,6 +162,30 @@ void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id);
 #define MP4DecSpecificDescrTag          0x05
 #define MP4SLDescrTag                   0x06
 
+#define MOV_TFHD_BASE_DATA_OFFSET       0x01
+#define MOV_TFHD_STSD_ID                0x02
+#define MOV_TFHD_DEFAULT_DURATION       0x08
+#define MOV_TFHD_DEFAULT_SIZE           0x10
+#define MOV_TFHD_DEFAULT_FLAGS          0x20
+#define MOV_TFHD_DURATION_IS_EMPTY  0x010000
+
+#define MOV_TRUN_DATA_OFFSET            0x01
+#define MOV_TRUN_FIRST_SAMPLE_FLAGS     0x04
+#define MOV_TRUN_SAMPLE_DURATION       0x100
+#define MOV_TRUN_SAMPLE_SIZE           0x200
+#define MOV_TRUN_SAMPLE_FLAGS          0x400
+#define MOV_TRUN_SAMPLE_CTS            0x800
+
+#define MOV_FRAG_SAMPLE_FLAG_DEGRADATION_PRIORITY_MASK 0x0000ffff
+#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC               0x00010000
+#define MOV_FRAG_SAMPLE_FLAG_PADDING_MASK              0x000e0000
+#define MOV_FRAG_SAMPLE_FLAG_REDUNDANCY_MASK           0x00300000
+#define MOV_FRAG_SAMPLE_FLAG_DEPENDED_MASK             0x00c00000
+#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_MASK              0x03000000
+
+#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO                0x02000000
+#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES               0x01000000
+
 int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom);
 enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags);
 
index 71b96c1..c668027 100644 (file)
@@ -2257,14 +2257,16 @@ static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         return AVERROR_INVALIDDATA;
     }
 
-    if (flags & 0x01) frag->base_data_offset = avio_rb64(pb);
-    else              frag->base_data_offset = frag->moof_offset;
-    if (flags & 0x02) frag->stsd_id          = avio_rb32(pb);
-    else              frag->stsd_id          = trex->stsd_id;
-
-    frag->duration = flags & 0x08 ? avio_rb32(pb) : trex->duration;
-    frag->size     = flags & 0x10 ? avio_rb32(pb) : trex->size;
-    frag->flags    = flags & 0x20 ? avio_rb32(pb) : trex->flags;
+    frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
+                             avio_rb64(pb) : frag->moof_offset;
+    frag->stsd_id  = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
+
+    frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
+                     avio_rb32(pb) : trex->duration;
+    frag->size     = flags & MOV_TFHD_DEFAULT_SIZE ?
+                     avio_rb32(pb) : trex->size;
+    frag->flags    = flags & MOV_TFHD_DEFAULT_FLAGS ?
+                     avio_rb32(pb) : trex->flags;
     av_dlog(c->fc, "frag flags 0x%x\n", frag->flags);
     return 0;
 }
@@ -2353,8 +2355,8 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         return AVERROR(ENOMEM);
     sc->ctts_data = ctts_data;
 
-    if (flags & 0x001) data_offset        = avio_rb32(pb);
-    if (flags & 0x004) first_sample_flags = avio_rb32(pb);
+    if (flags & MOV_TRUN_DATA_OFFSET)        data_offset        = avio_rb32(pb);
+    if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
     dts    = sc->track_end - sc->time_offset;
     offset = frag->base_data_offset + data_offset;
     distance = 0;
@@ -2365,14 +2367,15 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         unsigned sample_duration = frag->duration;
         int keyframe;
 
-        if (flags & 0x100) sample_duration = avio_rb32(pb);
-        if (flags & 0x200) sample_size     = avio_rb32(pb);
-        if (flags & 0x400) sample_flags    = avio_rb32(pb);
+        if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
+        if (flags & MOV_TRUN_SAMPLE_SIZE)     sample_size     = avio_rb32(pb);
+        if (flags & MOV_TRUN_SAMPLE_FLAGS)    sample_flags    = avio_rb32(pb);
         sc->ctts_data[sc->ctts_count].count = 1;
-        sc->ctts_data[sc->ctts_count].duration = (flags & 0x800) ? avio_rb32(pb) : 0;
+        sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ?
+                                                  avio_rb32(pb) : 0;
         sc->ctts_count++;
         if ((keyframe = st->codec->codec_type == AVMEDIA_TYPE_AUDIO ||
-             (flags & 0x004 && !i && !(sample_flags & 0xffff0000)) || sample_flags & 0x2000000))
+             (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS && !i && !(sample_flags & ~MOV_FRAG_SAMPLE_FLAG_DEGRADATION_PRIORITY_MASK)) || sample_flags & MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO))
             distance = 0;
         av_add_index_entry(st, offset, dts, sample_size, distance,
                            keyframe ? AVINDEX_KEYFRAME : 0);
index 72a66db..b5e8770 100644 (file)
@@ -1342,6 +1342,9 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
 {
     int version = track->track_duration < INT32_MAX ? 0 : 1;
 
+    if (track->mode == MODE_ISM)
+        version = 1;
+
     (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
     ffio_wfourcc(pb, "mdhd");
     avio_w8(pb, version);
@@ -1354,7 +1357,10 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
         avio_wb32(pb, track->time); /* modification time */
     }
     avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
-    (version == 1) ? avio_wb64(pb, track->track_duration) : avio_wb32(pb, track->track_duration); /* duration */
+    if (!track->entry)
+        (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
+    else
+        (version == 1) ? avio_wb64(pb, track->track_duration) : avio_wb32(pb, track->track_duration); /* duration */
     avio_wb16(pb, track->language); /* language */
     avio_wb16(pb, 0); /* reserved (quality) */
 
@@ -1385,6 +1391,9 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
                                       track->timescale, AV_ROUND_UP);
     int version = duration < INT32_MAX ? 0 : 1;
 
+    if (track->mode == MODE_ISM)
+        version = 1;
+
     (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
     ffio_wfourcc(pb, "tkhd");
     avio_w8(pb, version);
@@ -1398,7 +1407,10 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
     }
     avio_wb32(pb, track->track_id); /* track-id */
     avio_wb32(pb, 0); /* reserved */
-    (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
+    if (!track->entry)
+        (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
+    else
+        (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
 
     avio_wb32(pb, 0); /* reserved */
     avio_wb32(pb, 0); /* reserved */
@@ -2225,19 +2237,19 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
                               int64_t moof_offset)
 {
     int64_t pos = avio_tell(pb);
-    /* default-sample-size + default-sample-duration + base-data-offset */
-    uint32_t flags = 0x19;
+    uint32_t flags = MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
+                     MOV_TFHD_BASE_DATA_OFFSET;
     if (!track->entry) {
-        flags |= 0x010000; /* duration-is-empty */
+        flags |= MOV_TFHD_DURATION_IS_EMPTY;
     } else {
-        flags |= 0x20; /* default-sample-flags-present */
+        flags |= MOV_TFHD_DEFAULT_FLAGS;
     }
 
     /* Don't set a default sample size, the silverlight player refuses
      * to play files with that set. Don't set a default sample duration,
      * WMP freaks out if it is set. */
     if (track->mode == MODE_ISM)
-        flags &= ~0x18;
+        flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION);
 
     avio_wb32(pb, 0); /* size placeholder */
     ffio_wfourcc(pb, "tfhd");
@@ -2245,22 +2257,23 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
     avio_wb24(pb, flags);
 
     avio_wb32(pb, track->track_id); /* track-id */
-    if (flags & 0x01)
+    if (flags & MOV_TFHD_BASE_DATA_OFFSET)
         avio_wb64(pb, moof_offset);
-    if (flags & 0x08) {
+    if (flags & MOV_TFHD_DEFAULT_DURATION) {
         track->default_duration = track->audio_vbr ? track->enc->frame_size : 1;
         avio_wb32(pb, track->default_duration);
     }
-    if (flags & 0x10) {
+    if (flags & MOV_TFHD_DEFAULT_SIZE) {
         track->default_size = track->entry ? track->cluster[0].size : 1;
         avio_wb32(pb, track->default_size);
     } else
         track->default_size = -1;
 
-    if (flags & 0x20) {
+    if (flags & MOV_TFHD_DEFAULT_FLAGS) {
         track->default_sample_flags =
             track->enc->codec_type == AVMEDIA_TYPE_VIDEO ?
-            0x01010000 : 0x02000000;
+            (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC) :
+            MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO;
         avio_wb32(pb, track->default_sample_flags);
     }
 
@@ -2269,13 +2282,14 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
 
 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
 {
-    return entry->flags & MOV_SYNC_SAMPLE ? 0x02000000 : 0x01010000;
+    return entry->flags & MOV_SYNC_SAMPLE ? MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO :
+           (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC);
 }
 
 static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
-    uint32_t flags = 1; /* data-offset-present */
+    uint32_t flags = MOV_TRUN_DATA_OFFSET;
     int i;
 
     for (i = 0; i < track->entry; i++) {
@@ -2283,16 +2297,16 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
             track->track_duration - track->cluster[i].dts + track->start_dts :
             track->cluster[i + 1].dts - track->cluster[i].dts;
         if (duration != track->default_duration)
-            flags |= 0x100; /* sample-duration-present */
+            flags |= MOV_TRUN_SAMPLE_DURATION;
         if (track->cluster[i].size != track->default_size)
-            flags |= 0x200; /* sample-size-present */
+            flags |= MOV_TRUN_SAMPLE_SIZE;
         if (i > 0 && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
-            flags |= 0x400; /* sample-flags-present */
+            flags |= MOV_TRUN_SAMPLE_FLAGS;
     }
-    if (!(flags & 0x400))
-        flags |= 0x4; /* first-sample-flags-present */
+    if (!(flags & MOV_TRUN_SAMPLE_FLAGS))
+        flags |= MOV_TRUN_FIRST_SAMPLE_FLAGS;
     if (track->flags & MOV_TRACK_CTTS)
-        flags |= 0x800; /* sample-composition-time-offsets-present */
+        flags |= MOV_TRUN_SAMPLE_CTS;
 
     avio_wb32(pb, 0); /* size placeholder */
     ffio_wfourcc(pb, "trun");
@@ -2302,20 +2316,20 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
     avio_wb32(pb, track->entry); /* sample count */
     track->moof_size_offset = avio_tell(pb);
     avio_wb32(pb, 0); /* data offset */
-    if (flags & 0x4) /* first sample flags */
+    if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
         avio_wb32(pb, get_sample_flags(track, &track->cluster[0]));
 
     for (i = 0; i < track->entry; i++) {
         int64_t duration = i + 1 == track->entry ?
             track->track_duration - track->cluster[i].dts + track->start_dts :
             track->cluster[i + 1].dts - track->cluster[i].dts;
-        if (flags & 0x100)
+        if (flags & MOV_TRUN_SAMPLE_DURATION)
             avio_wb32(pb, duration);
-        if (flags & 0x200)
+        if (flags & MOV_TRUN_SAMPLE_SIZE)
             avio_wb32(pb, track->cluster[i].size);
-        if (flags & 0x400)
+        if (flags & MOV_TRUN_SAMPLE_FLAGS)
             avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
-        if (flags & 0x800)
+        if (flags & MOV_TRUN_SAMPLE_CTS)
             avio_wb32(pb, track->cluster[i].cts);
     }
 
index 41d9590..73ffe1f 100644 (file)
  */
 int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p);
 
+int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
+                          AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                          const uint8_t *buf, int len, int flags);
+
 extern RTPDynamicProtocolHandler ff_amr_nb_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_amr_wb_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_g726_16_dynamic_handler;
index 27173f0..6c22a24 100644 (file)
 #include "rtpdec_formats.h"
 #include "libavutil/intreadwrite.h"
 
-static int h263_handle_packet(AVFormatContext *ctx,
-                              PayloadContext *data,
-                              AVStream *st,
-                              AVPacket * pkt,
-                              uint32_t * timestamp,
-                              const uint8_t * buf,
-                              int len, int flags)
+int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
+                          AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                          const uint8_t *buf, int len, int flags)
 {
     uint8_t *ptr;
     uint16_t header;
@@ -96,12 +92,12 @@ RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler = {
     .enc_name         = "H263-1998",
     .codec_type       = AVMEDIA_TYPE_VIDEO,
     .codec_id         = CODEC_ID_H263,
-    .parse_packet     = h263_handle_packet,
+    .parse_packet     = ff_h263_handle_packet,
 };
 
 RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler = {
     .enc_name         = "H263-2000",
     .codec_type       = AVMEDIA_TYPE_VIDEO,
     .codec_id         = CODEC_ID_H263,
-    .parse_packet     = h263_handle_packet,
+    .parse_packet     = ff_h263_handle_packet,
 };
index baec6a4..a3a4825 100644 (file)
@@ -35,6 +35,7 @@ struct PayloadContext {
     uint8_t      endbyte;
     int          endbyte_bits;
     uint32_t     timestamp;
+    int          newformat;
 };
 
 static PayloadContext *h263_new_context(void)
@@ -58,9 +59,14 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                               AVStream *st, AVPacket *pkt, uint32_t *timestamp,
                               const uint8_t *buf, int len, int flags)
 {
-    int f, p, i, sbit, ebit; /* Corresponding to header fields in the RFC */
+    /* Corresponding to header fields in the RFC */
+    int f, p, i, sbit, ebit, src, r;
     int header_size;
 
+    if (data->newformat)
+        return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, len,
+                                     flags);
+
     if (data->buf && data->timestamp != *timestamp) {
         /* Dropping old buffered, unfinished data */
         uint8_t *p;
@@ -80,6 +86,7 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
         /* Mode A */
         header_size = 4;
         i = buf[1] & 0x10;
+        r = ((buf[1] & 0x01) << 3) | ((buf[2] & 0xe0) >> 5);
     } else if (!p) {
         /* Mode B */
         header_size = 8;
@@ -89,6 +96,7 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                    len, header_size);
             return AVERROR_INVALIDDATA;
         }
+        r = buf[3] & 0x03;
         i = buf[4] & 0x80;
     } else {
         /* Mode C */
@@ -99,10 +107,24 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                    len, header_size);
             return AVERROR_INVALIDDATA;
         }
+        r = buf[3] & 0x03;
         i = buf[4] & 0x80;
     }
     sbit = (buf[0] >> 3) & 0x7;
     ebit =  buf[0]       & 0x7;
+    src  = (buf[1] & 0xe0) >> 5;
+    if (!(buf[0] & 0xf8)) { /* Reserved bits in RFC 2429/4629 are zero */
+        if ((src == 0 || src >= 6) && r) {
+            /* Invalid src for this format, and bits that should be zero
+             * according to RFC 2190 aren't zero. */
+            av_log(ctx, AV_LOG_WARNING,
+                   "Interpreting H263 RTP data as RFC 2429/4629 even though "
+                   "signalled with a static payload type.\n");
+            data->newformat = 1;
+            return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf,
+                                         len, flags);
+        }
+    }
 
     buf += header_size;
     len -= header_size;
index 5922cb6..cf0a583 100644 (file)
@@ -1,9 +1,9 @@
-c4e12d7ed2ab47d43b912eb160a2bea8 *./tests/data/lavf/lavf.ismv
-312247 ./tests/data/lavf/lavf.ismv
+eb116b60befadfd5c9118635d81c5a6e *./tests/data/lavf/lavf.ismv
+312271 ./tests/data/lavf/lavf.ismv
 ./tests/data/lavf/lavf.ismv CRC=0xbcc963fc
-44c724f5dd12436d283aacc95065ad7f *./tests/data/lavf/lavf.ismv
-321521 ./tests/data/lavf/lavf.ismv
+90db70a6f33cf22db9ce242087b5870b *./tests/data/lavf/lavf.ismv
+321545 ./tests/data/lavf/lavf.ismv
 ./tests/data/lavf/lavf.ismv CRC=0x3998478f
-c4e12d7ed2ab47d43b912eb160a2bea8 *./tests/data/lavf/lavf.ismv
-312247 ./tests/data/lavf/lavf.ismv
+eb116b60befadfd5c9118635d81c5a6e *./tests/data/lavf/lavf.ismv
+312271 ./tests/data/lavf/lavf.ismv
 ./tests/data/lavf/lavf.ismv CRC=0xbcc963fc