* Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
* Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de>
*
- * This file is part of FFmpeg.
+ * This file is part of Libav.
*
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
- * @file libavcodec/cavsdec.c
+ * @file
* Chinese AVS video (AVS1-P2, JiZhun profile) decoder
* @author Stefan Gehrer <stefan.gehrer@gmx.de>
*/
#include "avcodec.h"
-#include "bitstream.h"
+#include "get_bits.h"
#include "golomb.h"
#include "cavs.h"
r++;
mask = -(level_code & 1);
level = (level^mask) - mask;
- } else {
+ } else if (level_code >= 0) {
level = r->rltab[level_code][0];
if(!level) //end of block signal
break;
run = r->rltab[level_code][1];
r += r->rltab[level_code][2];
+ } else {
+ break;
}
level_buf[i] = level;
run_buf[i] = run;
if(dequant(h,level_buf, run_buf, block, ff_cavs_dequant_mul[qp],
ff_cavs_dequant_shift[qp], i))
return -1;
- h->s.dsp.cavs_idct8_add(dst,block,stride);
+ h->cdsp.cavs_idct8_add(dst,block,stride);
h->s.dsp.clear_block(block);
return 0;
}
static int decode_mb_i(AVSContext *h, int cbp_code) {
GetBitContext *gb = &h->s.gb;
- int block, pred_mode_uv;
+ unsigned pred_mode_uv;
+ int block;
uint8_t top[18];
uint8_t *left = NULL;
uint8_t *d;
ff_cavs_modify_mb_i(h, &pred_mode_uv);
/* get coded block pattern */
- if(h->pic_type == FF_I_TYPE)
+ if(h->pic_type == AV_PICTURE_TYPE_I)
cbp_code = get_ue_golomb(gb);
if(cbp_code > 63){
av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n");
h->qp = get_bits(gb,6);
}
/* inter frame or second slice can have weighting params */
- if((h->pic_type != FF_I_TYPE) || (!h->pic_structure && h->mby >= h->mb_width/2))
+ if((h->pic_type != AV_PICTURE_TYPE_I) || (!h->pic_structure && h->mby >= h->mb_width/2))
if(get_bits1(gb)) { //slice_weighting_flag
av_log(h->s.avctx, AV_LOG_ERROR,
"weighted prediction not yet supported\n");
align = (-get_bits_count(gb)) & 7;
/* check for stuffing byte */
if(!align && (show_bits(gb,8) == 0x80))
- get_bits(gb,8);
+ align = 8;
if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) {
skip_bits_long(gb,24+align);
h->stc = get_bits(gb,8);
+ if (h->stc >= h->mb_height)
+ return 0;
decode_slice_header(h,gb);
return 1;
}
}
skip_bits(&s->gb,16);//bbv_dwlay
if(h->stc == PIC_PB_START_CODE) {
- h->pic_type = get_bits(&s->gb,2) + FF_I_TYPE;
- if(h->pic_type > FF_B_TYPE) {
+ h->pic_type = get_bits(&s->gb,2) + AV_PICTURE_TYPE_I;
+ if(h->pic_type > AV_PICTURE_TYPE_B) {
av_log(s->avctx, AV_LOG_ERROR, "illegal picture type\n");
return -1;
}
/* make sure we have the reference frames we need */
- if(!h->DPB[0].data[0] ||
- (!h->DPB[1].data[0] && h->pic_type == FF_B_TYPE))
+ if(!h->DPB[0].f.data[0] ||
+ (!h->DPB[1].f.data[0] && h->pic_type == AV_PICTURE_TYPE_B))
return -1;
} else {
- h->pic_type = FF_I_TYPE;
+ h->pic_type = AV_PICTURE_TYPE_I;
if(get_bits1(&s->gb))
skip_bits(&s->gb,24);//time_code
+ /* old sample clips were all progressive and no low_delay,
+ bump stream revision if detected otherwise */
+ if (s->low_delay || !(show_bits(&s->gb,9) & 1))
+ h->stream_revision = 1;
+ /* similarly test top_field_first and repeat_first_field */
+ else if(show_bits(&s->gb,11) & 3)
+ h->stream_revision = 1;
+ if(h->stream_revision > 0)
+ skip_bits(&s->gb,1); //marker_bit
}
/* release last B frame */
- if(h->picture.data[0])
+ if(h->picture.f.data[0])
s->avctx->release_buffer(s->avctx, (AVFrame *)&h->picture);
s->avctx->get_buffer(s->avctx, (AVFrame *)&h->picture);
h->picture.poc = get_bits(&s->gb,8)*2;
/* get temporal distances and MV scaling factors */
- if(h->pic_type != FF_B_TYPE) {
+ if(h->pic_type != AV_PICTURE_TYPE_B) {
h->dist[0] = (h->picture.poc - h->DPB[0].poc + 512) % 512;
} else {
h->dist[0] = (h->DPB[0].poc - h->picture.poc + 512) % 512;
h->dist[1] = (h->picture.poc - h->DPB[1].poc + 512) % 512;
h->scale_den[0] = h->dist[0] ? 512/h->dist[0] : 0;
h->scale_den[1] = h->dist[1] ? 512/h->dist[1] : 0;
- if(h->pic_type == FF_B_TYPE) {
+ if(h->pic_type == AV_PICTURE_TYPE_B) {
h->sym_factor = h->dist[0]*h->scale_den[1];
} else {
h->direct_den[0] = h->dist[0] ? 16384/h->dist[0] : 0;
skip_bits1(&s->gb); //repeat_first_field
h->qp_fixed = get_bits1(&s->gb);
h->qp = get_bits(&s->gb,6);
- if(h->pic_type == FF_I_TYPE) {
+ if(h->pic_type == AV_PICTURE_TYPE_I) {
if(!h->progressive && !h->pic_structure)
skip_bits1(&s->gb);//what is this?
skip_bits(&s->gb,4); //reserved bits
} else {
- if(!(h->pic_type == FF_B_TYPE && h->pic_structure == 1))
+ if(!(h->pic_type == AV_PICTURE_TYPE_B && h->pic_structure == 1))
h->ref_flag = get_bits1(&s->gb);
skip_bits(&s->gb,4); //reserved bits
h->skip_mode_flag = get_bits1(&s->gb);
} else {
h->alpha_offset = h->beta_offset = 0;
}
- if(h->pic_type == FF_I_TYPE) {
+ if(h->pic_type == AV_PICTURE_TYPE_I) {
do {
check_for_slice(h);
decode_mb_i(h, 0);
} while(ff_cavs_next_mb(h));
- } else if(h->pic_type == FF_P_TYPE) {
+ } else if(h->pic_type == AV_PICTURE_TYPE_P) {
do {
if(check_for_slice(h))
skip_count = -1;
decode_mb_p(h,mb_type);
}
} while(ff_cavs_next_mb(h));
- } else { /* FF_B_TYPE */
+ } else { /* AV_PICTURE_TYPE_B */
do {
if(check_for_slice(h))
skip_count = -1;
}
} while(ff_cavs_next_mb(h));
}
- if(h->pic_type != FF_B_TYPE) {
- if(h->DPB[1].data[0])
+ if(h->pic_type != AV_PICTURE_TYPE_B) {
+ if(h->DPB[1].f.data[0])
s->avctx->release_buffer(s->avctx, (AVFrame *)&h->DPB[1]);
h->DPB[1] = h->DPB[0];
h->DPB[0] = h->picture;
s->low_delay = get_bits1(&s->gb);
h->mb_width = (s->width + 15) >> 4;
h->mb_height = (s->height + 15) >> 4;
- h->s.avctx->time_base.den = ff_frame_rate_tab[frame_rate_code].num;
- h->s.avctx->time_base.num = ff_frame_rate_tab[frame_rate_code].den;
+ h->s.avctx->time_base.den = avpriv_frame_rate_tab[frame_rate_code].num;
+ h->s.avctx->time_base.num = avpriv_frame_rate_tab[frame_rate_code].den;
h->s.avctx->width = s->width;
h->s.avctx->height = s->height;
if(!h->top_qp)
s->avctx = avctx;
if (buf_size == 0) {
- if(!s->low_delay && h->DPB[0].data[0]) {
+ if (!s->low_delay && h->DPB[0].f.data[0]) {
*data_size = sizeof(AVPicture);
*picture = *(AVFrame *) &h->DPB[0];
}
buf_ptr = buf;
buf_end = buf + buf_size;
for(;;) {
- buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc);
- if(stc & 0xFFFFFE00)
+ buf_ptr = avpriv_mpv_find_start_code(buf_ptr,buf_end, &stc);
+ if((stc & 0xFFFFFE00) || buf_ptr == buf_end)
return FFMAX(0, buf_ptr - buf - s->parse_context.last_index);
input_size = (buf_end - buf_ptr)*8;
switch(stc) {
break;
case PIC_I_START_CODE:
if(!h->got_keyframe) {
- if(h->DPB[0].data[0])
+ if(h->DPB[0].f.data[0])
avctx->release_buffer(avctx, (AVFrame *)&h->DPB[0]);
- if(h->DPB[1].data[0])
+ if(h->DPB[1].f.data[0])
avctx->release_buffer(avctx, (AVFrame *)&h->DPB[1]);
h->got_keyframe = 1;
}
if(decode_pic(h))
break;
*data_size = sizeof(AVPicture);
- if(h->pic_type != FF_B_TYPE) {
- if(h->DPB[1].data[0]) {
+ if(h->pic_type != AV_PICTURE_TYPE_B) {
+ if(h->DPB[1].f.data[0]) {
*picture = *(AVFrame *) &h->DPB[1];
} else {
*data_size = 0;
}
}
-AVCodec cavs_decoder = {
- "cavs",
- CODEC_TYPE_VIDEO,
- CODEC_ID_CAVS,
- sizeof(AVSContext),
- ff_cavs_init,
- NULL,
- ff_cavs_end,
- cavs_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+AVCodec ff_cavs_decoder = {
+ .name = "cavs",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_CAVS,
+ .priv_data_size = sizeof(AVSContext),
+ .init = ff_cavs_init,
+ .close = ff_cavs_end,
+ .decode = cavs_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
.flush= cavs_flush,
.long_name= NULL_IF_CONFIG_SMALL("Chinese AVS video (AVS1-P2, JiZhun profile)"),
};