diff options
Diffstat (limited to 'libavcodec/h261enc.c')
-rw-r--r-- | libavcodec/h261enc.c | 126 |
1 files changed, 90 insertions, 36 deletions
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c index 3cac88253f..315762c10c 100644 --- a/libavcodec/h261enc.c +++ b/libavcodec/h261enc.c @@ -3,20 +3,20 @@ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2004 Maarten Daniels * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg 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. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -26,6 +26,7 @@ */ #include "libavutil/attributes.h" +#include "libavutil/avassert.h" #include "avcodec.h" #include "mpegutils.h" #include "mpegvideo.h" @@ -33,6 +34,9 @@ #include "h261.h" #include "mpegvideodata.h" +static uint8_t uni_h261_rl_len [64*64*2*2]; +#define UNI_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level)) + int ff_h261_get_picture_format(int width, int height) { // QCIF @@ -43,7 +47,7 @@ int ff_h261_get_picture_format(int width, int height) return 1; // ERROR else - return -1; + return AVERROR(EINVAL); } void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number) @@ -58,8 +62,8 @@ void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number) put_bits(&s->pb, 20, 0x10); /* PSC */ - temp_ref = s->picture_number * (int64_t)30000 * s->avctx->time_base.num / - (1001 * (int64_t)s->avctx->time_base.den); // FIXME maybe this should use a timestamp + temp_ref = s->picture_number * 30000LL * s->avctx->time_base.num / + (1001LL * s->avctx->time_base.den); // FIXME maybe this should use a timestamp put_sbits(&s->pb, 5, temp_ref); /* TemporalReference */ put_bits(&s->pb, 1, 0); /* split screen off */ @@ -78,7 +82,7 @@ void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number) h->gob_number = -1; else h->gob_number = 0; - h->current_mba = 0; + s->mb_skip_run = 0; } /** @@ -96,18 +100,21 @@ static void h261_encode_gob_header(MpegEncContext *s, int mb_line) put_bits(&s->pb, 4, h->gob_number); /* GN */ put_bits(&s->pb, 5, s->qscale); /* GQUANT */ put_bits(&s->pb, 1, 0); /* no GEI */ - h->current_mba = 0; - h->previous_mba = 0; - h->current_mv_x = 0; - h->current_mv_y = 0; + s->mb_skip_run = 0; + s->last_mv[0][0][0] = 0; + s->last_mv[0][0][1] = 0; } void ff_h261_reorder_mb_index(MpegEncContext *s) { int index = s->mb_x + s->mb_y * s->mb_width; - if (index % 33 == 0) - h261_encode_gob_header(s, 0); + if (index % 11 == 0) { + if (index % 33 == 0) + h261_encode_gob_header(s, 0); + s->last_mv[0][0][0] = 0; + s->last_mv[0][0][1] = 0; + } /* for CIF the GOB's are fragmented in the middle of a scanline * that's why we need to adjust the x and y index of the macroblocks */ @@ -214,8 +221,8 @@ static void h261_encode_block(H261Context *h, int16_t *block, int n) put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); if (code == rl->n) { put_bits(&s->pb, 6, run); - assert(slevel != 0); - assert(level <= 127); + av_assert1(slevel != 0); + av_assert1(level <= 127); put_sbits(&s->pb, 8, slevel); } else { put_bits(&s->pb, 1, sign); @@ -235,7 +242,6 @@ void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], cbp = 63; // avoid warning mvd = 0; - h->current_mba++; h->mtype = 0; if (!s->mb_intra) { @@ -245,19 +251,22 @@ void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], /* mvd indicates if this block is motion compensated */ mvd = motion_x | motion_y; - if ((cbp | mvd | s->dquant) == 0) { + if ((cbp | mvd) == 0) { /* skip macroblock */ s->skip_count++; - h->current_mv_x = 0; - h->current_mv_y = 0; + s->mb_skip_run++; + s->last_mv[0][0][0] = 0; + s->last_mv[0][0][1] = 0; + s->qscale -= s->dquant; return; } } /* MB is not skipped, encode MBA */ put_bits(&s->pb, - ff_h261_mba_bits[(h->current_mba - h->previous_mba) - 1], - ff_h261_mba_code[(h->current_mba - h->previous_mba) - 1]); + ff_h261_mba_bits[s->mb_skip_run], + ff_h261_mba_code[s->mb_skip_run]); + s->mb_skip_run = 0; /* calculate MTYPE */ if (!s->mb_intra) { @@ -267,13 +276,15 @@ void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], h->mtype += 3; if (s->loop_filter) h->mtype += 3; - if (cbp || s->dquant) + if (cbp) h->mtype++; - assert(h->mtype > 1); + av_assert1(h->mtype > 1); } - if (s->dquant) + if (s->dquant && cbp) { h->mtype++; + } else + s->qscale -= s->dquant; put_bits(&s->pb, ff_h261_mtype_bits[h->mtype], @@ -287,18 +298,16 @@ void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], } if (IS_16X16(h->mtype)) { - mv_diff_x = (motion_x >> 1) - h->current_mv_x; - mv_diff_y = (motion_y >> 1) - h->current_mv_y; - h->current_mv_x = (motion_x >> 1); - h->current_mv_y = (motion_y >> 1); + mv_diff_x = (motion_x >> 1) - s->last_mv[0][0][0]; + mv_diff_y = (motion_y >> 1) - s->last_mv[0][0][1]; + s->last_mv[0][0][0] = (motion_x >> 1); + s->last_mv[0][0][1] = (motion_y >> 1); h261_encode_motion(h, mv_diff_x); h261_encode_motion(h, mv_diff_y); } - h->previous_mba = h->current_mba; - if (HAS_CBP(h->mtype)) { - assert(cbp > 0); + av_assert1(cbp > 0); put_bits(&s->pb, ff_h261_cbp_tab[cbp - 1][1], ff_h261_cbp_tab[cbp - 1][0]); @@ -307,10 +316,49 @@ void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], /* encode each block */ h261_encode_block(h, block[i], i); - if ((h->current_mba == 11) || (h->current_mba == 22) || - (h->current_mba == 33) || (!IS_16X16(h->mtype))) { - h->current_mv_x = 0; - h->current_mv_y = 0; + if (!IS_16X16(h->mtype)) { + s->last_mv[0][0][0] = 0; + s->last_mv[0][0][1] = 0; + } +} + +static av_cold void init_uni_h261_rl_tab(RLTable *rl, uint32_t *bits_tab, + uint8_t *len_tab) +{ + int slevel, run, last; + + av_assert0(MAX_LEVEL >= 64); + av_assert0(MAX_RUN >= 63); + + for(slevel=-64; slevel<64; slevel++){ + if(slevel==0) continue; + for(run=0; run<64; run++){ + for(last=0; last<=1; last++){ + const int index= UNI_ENC_INDEX(last, run, slevel+64); + int level= slevel < 0 ? -slevel : slevel; + int len, code; + + len_tab[index]= 100; + + /* ESC0 */ + code= get_rl_index(rl, 0, run, level); + len= rl->table_vlc[code][1] + 1; + if(last) + len += 2; + + if(code!=rl->n && len < len_tab[index]){ + len_tab [index]= len; + } + /* ESC */ + len = rl->table_vlc[rl->n][1]; + if(last) + len += 2; + + if(len < len_tab[index]){ + len_tab [index]= len; + } + } + } } } @@ -322,6 +370,12 @@ av_cold void ff_h261_encode_init(MpegEncContext *s) s->max_qcoeff = 127; s->y_dc_scale_table = s->c_dc_scale_table = ff_mpeg1_dc_scale_table; + s->ac_esc_length = 6+6+8; + + init_uni_h261_rl_tab(&ff_h261_rl_tcoeff, NULL, uni_h261_rl_len); + + s->intra_ac_vlc_length = s->inter_ac_vlc_length = uni_h261_rl_len; + s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len + 128*64; } static const AVClass h261_class = { |