yading@10: /* yading@10: * H261 encoder yading@10: * Copyright (c) 2002-2004 Michael Niedermayer yading@10: * Copyright (c) 2004 Maarten Daniels yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: /** yading@10: * @file yading@10: * H.261 encoder. yading@10: */ yading@10: yading@10: #include "libavutil/avassert.h" yading@10: #include "avcodec.h" yading@10: #include "mpegvideo.h" yading@10: #include "h263.h" yading@10: #include "h261.h" yading@10: yading@10: int ff_h261_get_picture_format(int width, int height) yading@10: { yading@10: // QCIF yading@10: if (width == 176 && height == 144) yading@10: return 0; yading@10: // CIF yading@10: else if (width == 352 && height == 288) yading@10: return 1; yading@10: // ERROR yading@10: else yading@10: return -1; yading@10: } yading@10: yading@10: void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number) yading@10: { yading@10: H261Context *h = (H261Context *)s; yading@10: int format, temp_ref; yading@10: yading@10: avpriv_align_put_bits(&s->pb); yading@10: yading@10: /* Update the pointer to last GOB */ yading@10: s->ptr_lastgob = put_bits_ptr(&s->pb); yading@10: yading@10: put_bits(&s->pb, 20, 0x10); /* PSC */ yading@10: yading@10: temp_ref = s->picture_number * (int64_t)30000 * s->avctx->time_base.num / yading@10: (1001 * (int64_t)s->avctx->time_base.den); // FIXME maybe this should use a timestamp yading@10: put_sbits(&s->pb, 5, temp_ref); /* TemporalReference */ yading@10: yading@10: put_bits(&s->pb, 1, 0); /* split screen off */ yading@10: put_bits(&s->pb, 1, 0); /* camera off */ yading@10: put_bits(&s->pb, 1, 0); /* freeze picture release off */ yading@10: yading@10: format = ff_h261_get_picture_format(s->width, s->height); yading@10: yading@10: put_bits(&s->pb, 1, format); /* 0 == QCIF, 1 == CIF */ yading@10: yading@10: put_bits(&s->pb, 1, 0); /* still image mode */ yading@10: put_bits(&s->pb, 1, 0); /* reserved */ yading@10: yading@10: put_bits(&s->pb, 1, 0); /* no PEI */ yading@10: if (format == 0) yading@10: h->gob_number = -1; yading@10: else yading@10: h->gob_number = 0; yading@10: h->current_mba = 0; yading@10: } yading@10: yading@10: /** yading@10: * Encode a group of blocks header. yading@10: */ yading@10: static void h261_encode_gob_header(MpegEncContext *s, int mb_line) yading@10: { yading@10: H261Context *h = (H261Context *)s; yading@10: if (ff_h261_get_picture_format(s->width, s->height) == 0) { yading@10: h->gob_number += 2; // QCIF yading@10: } else { yading@10: h->gob_number++; // CIF yading@10: } yading@10: put_bits(&s->pb, 16, 1); /* GBSC */ yading@10: put_bits(&s->pb, 4, h->gob_number); /* GN */ yading@10: put_bits(&s->pb, 5, s->qscale); /* GQUANT */ yading@10: put_bits(&s->pb, 1, 0); /* no GEI */ yading@10: h->current_mba = 0; yading@10: h->previous_mba = 0; yading@10: h->current_mv_x = 0; yading@10: h->current_mv_y = 0; yading@10: } yading@10: yading@10: void ff_h261_reorder_mb_index(MpegEncContext *s) yading@10: { yading@10: int index = s->mb_x + s->mb_y * s->mb_width; yading@10: yading@10: if (index % 33 == 0) yading@10: h261_encode_gob_header(s, 0); yading@10: yading@10: /* for CIF the GOB's are fragmented in the middle of a scanline yading@10: * that's why we need to adjust the x and y index of the macroblocks */ yading@10: if (ff_h261_get_picture_format(s->width, s->height) == 1) { // CIF yading@10: s->mb_x = index % 11; yading@10: index /= 11; yading@10: s->mb_y = index % 3; yading@10: index /= 3; yading@10: s->mb_x += 11 * (index % 2); yading@10: index /= 2; yading@10: s->mb_y += 3 * index; yading@10: yading@10: ff_init_block_index(s); yading@10: ff_update_block_index(s); yading@10: } yading@10: } yading@10: yading@10: static void h261_encode_motion(H261Context *h, int val) yading@10: { yading@10: MpegEncContext *const s = &h->s; yading@10: int sign, code; yading@10: if (val == 0) { yading@10: code = 0; yading@10: put_bits(&s->pb, ff_h261_mv_tab[code][1], ff_h261_mv_tab[code][0]); yading@10: } else { yading@10: if (val > 15) yading@10: val -= 32; yading@10: if (val < -16) yading@10: val += 32; yading@10: sign = val < 0; yading@10: code = sign ? -val : val; yading@10: put_bits(&s->pb, ff_h261_mv_tab[code][1], ff_h261_mv_tab[code][0]); yading@10: put_bits(&s->pb, 1, sign); yading@10: } yading@10: } yading@10: yading@10: static inline int get_cbp(MpegEncContext *s, int16_t block[6][64]) yading@10: { yading@10: int i, cbp; yading@10: cbp = 0; yading@10: for (i = 0; i < 6; i++) yading@10: if (s->block_last_index[i] >= 0) yading@10: cbp |= 1 << (5 - i); yading@10: return cbp; yading@10: } yading@10: yading@10: /** yading@10: * Encode an 8x8 block. yading@10: * @param block the 8x8 block yading@10: * @param n block index (0-3 are luma, 4-5 are chroma) yading@10: */ yading@10: static void h261_encode_block(H261Context *h, int16_t *block, int n) yading@10: { yading@10: MpegEncContext *const s = &h->s; yading@10: int level, run, i, j, last_index, last_non_zero, sign, slevel, code; yading@10: RLTable *rl; yading@10: yading@10: rl = &ff_h261_rl_tcoeff; yading@10: if (s->mb_intra) { yading@10: /* DC coef */ yading@10: level = block[0]; yading@10: /* 255 cannot be represented, so we clamp */ yading@10: if (level > 254) { yading@10: level = 254; yading@10: block[0] = 254; yading@10: } yading@10: /* 0 cannot be represented also */ yading@10: else if (level < 1) { yading@10: level = 1; yading@10: block[0] = 1; yading@10: } yading@10: if (level == 128) yading@10: put_bits(&s->pb, 8, 0xff); yading@10: else yading@10: put_bits(&s->pb, 8, level); yading@10: i = 1; yading@10: } else if ((block[0] == 1 || block[0] == -1) && yading@10: (s->block_last_index[n] > -1)) { yading@10: // special case yading@10: put_bits(&s->pb, 2, block[0] > 0 ? 2 : 3); yading@10: i = 1; yading@10: } else { yading@10: i = 0; yading@10: } yading@10: yading@10: /* AC coefs */ yading@10: last_index = s->block_last_index[n]; yading@10: last_non_zero = i - 1; yading@10: for (; i <= last_index; i++) { yading@10: j = s->intra_scantable.permutated[i]; yading@10: level = block[j]; yading@10: if (level) { yading@10: run = i - last_non_zero - 1; yading@10: sign = 0; yading@10: slevel = level; yading@10: if (level < 0) { yading@10: sign = 1; yading@10: level = -level; yading@10: } yading@10: code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, yading@10: run, level); yading@10: if (run == 0 && level < 16) yading@10: code += 1; yading@10: put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); yading@10: if (code == rl->n) { yading@10: put_bits(&s->pb, 6, run); yading@10: av_assert1(slevel != 0); yading@10: av_assert1(level <= 127); yading@10: put_sbits(&s->pb, 8, slevel); yading@10: } else { yading@10: put_bits(&s->pb, 1, sign); yading@10: } yading@10: last_non_zero = i; yading@10: } yading@10: } yading@10: if (last_index > -1) yading@10: put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]); // EOB yading@10: } yading@10: yading@10: void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], yading@10: int motion_x, int motion_y) yading@10: { yading@10: H261Context *h = (H261Context *)s; yading@10: int mvd, mv_diff_x, mv_diff_y, i, cbp; yading@10: cbp = 63; // avoid warning yading@10: mvd = 0; yading@10: yading@10: h->current_mba++; yading@10: h->mtype = 0; yading@10: yading@10: if (!s->mb_intra) { yading@10: /* compute cbp */ yading@10: cbp = get_cbp(s, block); yading@10: yading@10: /* mvd indicates if this block is motion compensated */ yading@10: mvd = motion_x | motion_y; yading@10: yading@10: if ((cbp | mvd | s->dquant) == 0) { yading@10: /* skip macroblock */ yading@10: s->skip_count++; yading@10: h->current_mv_x = 0; yading@10: h->current_mv_y = 0; yading@10: return; yading@10: } yading@10: } yading@10: yading@10: /* MB is not skipped, encode MBA */ yading@10: put_bits(&s->pb, yading@10: ff_h261_mba_bits[(h->current_mba - h->previous_mba) - 1], yading@10: ff_h261_mba_code[(h->current_mba - h->previous_mba) - 1]); yading@10: yading@10: /* calculate MTYPE */ yading@10: if (!s->mb_intra) { yading@10: h->mtype++; yading@10: yading@10: if (mvd || s->loop_filter) yading@10: h->mtype += 3; yading@10: if (s->loop_filter) yading@10: h->mtype += 3; yading@10: if (cbp || s->dquant) yading@10: h->mtype++; yading@10: av_assert1(h->mtype > 1); yading@10: } yading@10: yading@10: if (s->dquant) yading@10: h->mtype++; yading@10: yading@10: put_bits(&s->pb, yading@10: ff_h261_mtype_bits[h->mtype], yading@10: ff_h261_mtype_code[h->mtype]); yading@10: yading@10: h->mtype = ff_h261_mtype_map[h->mtype]; yading@10: yading@10: if (IS_QUANT(h->mtype)) { yading@10: ff_set_qscale(s, s->qscale + s->dquant); yading@10: put_bits(&s->pb, 5, s->qscale); yading@10: } yading@10: yading@10: if (IS_16X16(h->mtype)) { yading@10: mv_diff_x = (motion_x >> 1) - h->current_mv_x; yading@10: mv_diff_y = (motion_y >> 1) - h->current_mv_y; yading@10: h->current_mv_x = (motion_x >> 1); yading@10: h->current_mv_y = (motion_y >> 1); yading@10: h261_encode_motion(h, mv_diff_x); yading@10: h261_encode_motion(h, mv_diff_y); yading@10: } yading@10: yading@10: h->previous_mba = h->current_mba; yading@10: yading@10: if (HAS_CBP(h->mtype)) { yading@10: av_assert1(cbp > 0); yading@10: put_bits(&s->pb, yading@10: ff_h261_cbp_tab[cbp - 1][1], yading@10: ff_h261_cbp_tab[cbp - 1][0]); yading@10: } yading@10: for (i = 0; i < 6; i++) yading@10: /* encode each block */ yading@10: h261_encode_block(h, block[i], i); yading@10: yading@10: if ((h->current_mba == 11) || (h->current_mba == 22) || yading@10: (h->current_mba == 33) || (!IS_16X16(h->mtype))) { yading@10: h->current_mv_x = 0; yading@10: h->current_mv_y = 0; yading@10: } yading@10: } yading@10: yading@10: void ff_h261_encode_init(MpegEncContext *s) yading@10: { yading@10: ff_h261_common_init(); yading@10: yading@10: s->min_qcoeff = -127; yading@10: s->max_qcoeff = 127; yading@10: s->y_dc_scale_table = yading@10: s->c_dc_scale_table = ff_mpeg1_dc_scale_table; yading@10: } yading@10: yading@10: FF_MPV_GENERIC_CLASS(h261) yading@10: yading@10: AVCodec ff_h261_encoder = { yading@10: .name = "h261", yading@10: .type = AVMEDIA_TYPE_VIDEO, yading@10: .id = AV_CODEC_ID_H261, yading@10: .priv_data_size = sizeof(H261Context), yading@10: .init = ff_MPV_encode_init, yading@10: .encode2 = ff_MPV_encode_picture, yading@10: .close = ff_MPV_encode_end, yading@10: .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, yading@10: AV_PIX_FMT_NONE }, yading@10: .long_name = NULL_IF_CONFIG_SMALL("H.261"), yading@10: .priv_class = &h261_class, yading@10: };