]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/rv34.c
matroskadec: use new metadata API to export some simple information
[ffmpeg] / libavcodec / rv34.c
index 8a14e08e76597fdb2025e2bf582d296514b2bd98..607a92837cd2e5a017fa3c0671a7fa9c28660bce 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 /**
- * @file rv34.c
+ * @file libavcodec/rv34.c
  * RV30/40 decoder common data
  */
 
@@ -65,6 +65,7 @@ static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
  * Generate VLC from codeword lengths.
  * @param bits   codeword lengths (zeroes are accepted)
  * @param size   length of input data
+ * @param vlc    output VLC
  * @param insyms symbols for input codes (NULL for default ones)
  */
 static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms)
@@ -100,7 +101,7 @@ static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t
 /**
  * Initialize all tables.
  */
-static av_cold void rv34_init_tables()
+static av_cold void rv34_init_tables(void)
 {
     int i, j, k;
 
@@ -222,7 +223,7 @@ static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table)
     int ones;
     static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};
     static const int shifts[4] = { 0, 2, 8, 10 };
-    int *curshift = shifts;
+    const int *curshift = shifts;
     int i, t, mask;
 
     code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);
@@ -618,6 +619,10 @@ static const int chroma_coeffs[3] = { 0, 3, 5 };
  * @param mv_off offset to the motion vector information
  * @param width width of the current partition in 8x8 blocks
  * @param height height of the current partition in 8x8 blocks
+ * @param dir motion compensation direction (i.e. from the last or the next reference frame)
+ * @param thirdpel motion vectors are specified in 1/3 of pixel
+ * @param qpel_mc a set of functions used to perform luma motion compensation
+ * @param chroma_mc a set of functions used to perform chroma motion compensation
  */
 static inline void rv34_mc(RV34DecContext *r, const int block_type,
                           const int xoff, const int yoff, int mv_off,
@@ -878,7 +883,7 @@ static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int
     }
     if(!right && up){
         topleft = dst[-stride + 3] * 0x01010101;
-        prev = &topleft;
+        prev = (uint8_t*)&topleft;
     }
     r->h.pred4x4[itype](dst, prev, stride);
 }
@@ -1391,6 +1396,28 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
     }else
         slice_count = avctx->slice_count;
 
+    //parse first slice header to check whether this frame can be decoded
+    if(get_slice_offset(avctx, slices_hdr, 0) > buf_size){
+        av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n");
+        return -1;
+    }
+    init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), buf_size-get_slice_offset(avctx, slices_hdr, 0));
+    if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){
+        av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");
+        return -1;
+    }
+    if((!s->last_picture_ptr || !s->last_picture_ptr->data[0]) && si.type == FF_B_TYPE)
+        return -1;
+    /* skip b frames if we are in a hurry */
+    if(avctx->hurry_up && si.type==FF_B_TYPE) return buf_size;
+    if(   (avctx->skip_frame >= AVDISCARD_NONREF && si.type==FF_B_TYPE)
+       || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=FF_I_TYPE)
+       ||  avctx->skip_frame >= AVDISCARD_ALL)
+        return buf_size;
+    /* skip everything if we are in a hurry>=5 */
+    if(avctx->hurry_up>=5)
+        return buf_size;
+
     for(i=0; i<slice_count; i++){
         int offset= get_slice_offset(avctx, slices_hdr, i);
         int size;
@@ -1415,8 +1442,6 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
             }else
                 r->si.end = si.start;
         }
-        if(!i && si.type == FF_B_TYPE && (!s->last_picture_ptr || !s->last_picture_ptr->data[0]))
-            return -1;
         last = rv34_decode_slice(r, r->si.end, buf + offset, size);
         s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;
         if(last)