]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blobdiff - libavcodec/vp3.c
Add a chroma_sample_location field to define positioning of chroma samples
[frescor/ffmpeg.git] / libavcodec / vp3.c
index 558465fc8faeed265273906c16c93e33044458fd..c1ca98f3c4fff238c99ac3681809b101d823302a 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 /**
- * @file vp3.c
+ * @file libavcodec/vp3.c
  * On2 VP3 Video Decoder
  *
  * VP3 Video Decoder by Mike Melanson (mike at multimedia.cx)
@@ -36,7 +36,7 @@
 
 #include "avcodec.h"
 #include "dsputil.h"
-#include "bitstream.h"
+#include "get_bits.h"
 
 #include "vp3data.h"
 #include "xiph.h"
@@ -140,8 +140,6 @@ typedef struct Vp3DecodeContext {
     int last_quality_index;
 
     int superblock_count;
-    int superblock_width;
-    int superblock_height;
     int y_superblock_width;
     int y_superblock_height;
     int c_superblock_width;
@@ -231,7 +229,7 @@ typedef struct Vp3DecodeContext {
     uint16_t huffman_table[80][32][2];
 
     uint8_t filter_limit_values[64];
-    int bounding_values_array[256];
+    DECLARE_ALIGNED_8(int, bounding_values_array[256+2]);
 } Vp3DecodeContext;
 
 /************************************************************************
@@ -256,7 +254,6 @@ static int init_block_mapping(Vp3DecodeContext *s)
     int right_edge = 0;
     int bottom_edge = 0;
     int superblock_row_inc = 0;
-    int *hilbert = NULL;
     int mapping_index = 0;
 
     int current_macroblock;
@@ -368,7 +365,6 @@ static int init_block_mapping(Vp3DecodeContext *s)
     current_height = 0;
     superblock_row_inc = s->macroblock_width -
         (s->y_superblock_width * 2 - s->macroblock_width);
-    hilbert = hilbert_walk_mb;
     mapping_index = 0;
     current_macroblock = -1;
     for (i = 0; i < s->u_superblock_start; i++) {
@@ -535,6 +531,7 @@ static void init_loop_filter(Vp3DecodeContext *s)
         bounding_values[x] = x;
         bounding_values[x + filter_limit] = filter_limit - x;
     }
+    bounding_values[129] = bounding_values[130] = filter_limit * 0x02020202;
 }
 
 /*
@@ -742,6 +739,8 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb)
 
         /* is it a custom coding scheme? */
         if (scheme == 0) {
+            for (i = 0; i < 8; i++)
+                custom_mode_alphabet[i] = MODE_INTER_NO_MV;
             for (i = 0; i < 8; i++)
                 custom_mode_alphabet[get_bits(gb, 3)] = i;
         }
@@ -1283,12 +1282,6 @@ static void reverse_dc_prediction(Vp3DecodeContext *s,
     }
 }
 
-
-static void horizontal_filter(unsigned char *first_pixel, int stride,
-    int *bounding_values);
-static void vertical_filter(unsigned char *first_pixel, int stride,
-    int *bounding_values);
-
 /*
  * Perform the final rendering for a particular slice of data.
  * The slice number ranges from 0..(macroblock_height - 1).
@@ -1409,14 +1402,14 @@ static void render_slice(Vp3DecodeContext *s, int slice)
                     /* dequantize the DCT coefficients */
                     if(s->avctx->idct_algo==FF_IDCT_VP3){
                         Coeff *coeff= s->coeffs + i;
-                        memset(block, 0, sizeof(block));
+                        s->dsp.clear_block(block);
                         while(coeff->next){
                             block[coeff->index]= coeff->coeff * dequantizer[coeff->index];
                             coeff= coeff->next;
                         }
                     }else{
                         Coeff *coeff= s->coeffs + i;
-                        memset(block, 0, sizeof(block));
+                        s->dsp.clear_block(block);
                         while(coeff->next){
                             block[coeff->index]= (coeff->coeff * dequantizer[coeff->index] + 2)>>2;
                             coeff= coeff->next;
@@ -1495,39 +1488,6 @@ static void render_slice(Vp3DecodeContext *s, int slice)
     emms_c();
 }
 
-static void horizontal_filter(unsigned char *first_pixel, int stride,
-    int *bounding_values)
-{
-    unsigned char *end;
-    int filter_value;
-
-    for (end= first_pixel + 8*stride; first_pixel != end; first_pixel += stride) {
-        filter_value =
-            (first_pixel[-2] - first_pixel[ 1])
-         +3*(first_pixel[ 0] - first_pixel[-1]);
-        filter_value = bounding_values[(filter_value + 4) >> 3];
-        first_pixel[-1] = av_clip_uint8(first_pixel[-1] + filter_value);
-        first_pixel[ 0] = av_clip_uint8(first_pixel[ 0] - filter_value);
-    }
-}
-
-static void vertical_filter(unsigned char *first_pixel, int stride,
-    int *bounding_values)
-{
-    unsigned char *end;
-    int filter_value;
-    const int nstride= -stride;
-
-    for (end= first_pixel + 8; first_pixel < end; first_pixel++) {
-        filter_value =
-            (first_pixel[2 * nstride] - first_pixel[ stride])
-         +3*(first_pixel[0          ] - first_pixel[nstride]);
-        filter_value = bounding_values[(filter_value + 4) >> 3];
-        first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value);
-        first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value);
-    }
-}
-
 static void apply_loop_filter(Vp3DecodeContext *s)
 {
     int plane;
@@ -1569,7 +1529,7 @@ static void apply_loop_filter(Vp3DecodeContext *s)
                 /* do not perform left edge filter for left columns frags */
                 if ((x > 0) &&
                     (s->all_fragments[fragment].coding_method != MODE_COPY)) {
-                    horizontal_filter(
+                    s->dsp.vp3_h_loop_filter(
                         plane_data + s->all_fragments[fragment].first_pixel,
                         stride, bounding_values);
                 }
@@ -1577,7 +1537,7 @@ static void apply_loop_filter(Vp3DecodeContext *s)
                 /* do not perform top edge filter for top row fragments */
                 if ((y > 0) &&
                     (s->all_fragments[fragment].coding_method != MODE_COPY)) {
-                    vertical_filter(
+                    s->dsp.vp3_v_loop_filter(
                         plane_data + s->all_fragments[fragment].first_pixel,
                         stride, bounding_values);
                 }
@@ -1588,7 +1548,7 @@ static void apply_loop_filter(Vp3DecodeContext *s)
                 if ((x < width - 1) &&
                     (s->all_fragments[fragment].coding_method != MODE_COPY) &&
                     (s->all_fragments[fragment + 1].coding_method == MODE_COPY)) {
-                    horizontal_filter(
+                    s->dsp.vp3_h_loop_filter(
                         plane_data + s->all_fragments[fragment + 1].first_pixel,
                         stride, bounding_values);
                 }
@@ -1599,7 +1559,7 @@ static void apply_loop_filter(Vp3DecodeContext *s)
                 if ((y < height - 1) &&
                     (s->all_fragments[fragment].coding_method != MODE_COPY) &&
                     (s->all_fragments[fragment + width].coding_method == MODE_COPY)) {
-                    vertical_filter(
+                    s->dsp.vp3_v_loop_filter(
                         plane_data + s->all_fragments[fragment + width].first_pixel,
                         stride, bounding_values);
                 }
@@ -1679,6 +1639,7 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
     s->width = (avctx->width + 15) & 0xFFFFFFF0;
     s->height = (avctx->height + 15) & 0xFFFFFFF0;
     avctx->pix_fmt = PIX_FMT_YUV420P;
+    avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
     if(avctx->idct_algo==FF_IDCT_AUTO)
         avctx->idct_algo=FF_IDCT_VP3;
     dsputil_init(&s->dsp, avctx);
@@ -1838,8 +1799,10 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
  */
 static int vp3_decode_frame(AVCodecContext *avctx,
                             void *data, int *data_size,
-                            const uint8_t *buf, int buf_size)
+                            AVPacket *avpkt)
 {
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
     Vp3DecodeContext *s = avctx->priv_data;
     GetBitContext gb;
     static int counter = 0;
@@ -2052,16 +2015,18 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb)
         }
         s->huff_code_size++;
         s->hbits <<= 1;
-        read_huffman_tree(avctx, gb);
+        if (read_huffman_tree(avctx, gb))
+            return -1;
         s->hbits |= 1;
-        read_huffman_tree(avctx, gb);
+        if (read_huffman_tree(avctx, gb))
+            return -1;
         s->hbits >>= 1;
         s->huff_code_size--;
     }
     return 0;
 }
 
-#ifdef CONFIG_THEORA_DECODER
+#if CONFIG_THEORA_DECODER
 static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
 {
     Vp3DecodeContext *s = avctx->priv_data;
@@ -2230,9 +2195,11 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb)
         s->huff_code_size = 1;
         if (!get_bits1(gb)) {
             s->hbits = 0;
-            read_huffman_tree(avctx, gb);
+            if(read_huffman_tree(avctx, gb))
+                return -1;
             s->hbits = 1;
-            read_huffman_tree(avctx, gb);
+            if(read_huffman_tree(avctx, gb))
+                return -1;
         }
     }
 
@@ -2241,7 +2208,7 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb)
     return 0;
 }
 
-static int theora_decode_init(AVCodecContext *avctx)
+static av_cold int theora_decode_init(AVCodecContext *avctx)
 {
     Vp3DecodeContext *s = avctx->priv_data;
     GetBitContext gb;
@@ -2288,7 +2255,8 @@ static int theora_decode_init(AVCodecContext *avctx)
 //            theora_decode_comments(avctx, gb);
             break;
         case 0x82:
-            theora_decode_tables(avctx, &gb);
+            if (theora_decode_tables(avctx, &gb))
+                return -1;
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Unknown Theora config packet: %d\n", ptype&~0x80);