Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2002 The FFmpeg Project
  3.  *
  4.  * This file is part of FFmpeg.
  5.  *
  6.  * FFmpeg is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * FFmpeg is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with FFmpeg; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  */
  20.  
  21. #include "avcodec.h"
  22. #include "h263.h"
  23. #include "mpegvideo.h"
  24. #include "msmpeg4.h"
  25. #include "msmpeg4data.h"
  26. #include "wmv2.h"
  27.  
  28.  
  29. static int encode_ext_header(Wmv2Context *w)
  30. {
  31.     MpegEncContext *const s = &w->s;
  32.     PutBitContext pb;
  33.     int code;
  34.  
  35.     init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size);
  36.  
  37.     put_bits(&pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); // yes 29.97 -> 29
  38.     put_bits(&pb, 11, FFMIN(s->bit_rate / 1024, 2047));
  39.  
  40.     put_bits(&pb, 1, w->mspel_bit        = 1);
  41.     put_bits(&pb, 1, s->loop_filter);
  42.     put_bits(&pb, 1, w->abt_flag         = 1);
  43.     put_bits(&pb, 1, w->j_type_bit       = 1);
  44.     put_bits(&pb, 1, w->top_left_mv_flag = 0);
  45.     put_bits(&pb, 1, w->per_mb_rl_bit    = 1);
  46.     put_bits(&pb, 3, code                = 1);
  47.  
  48.     flush_put_bits(&pb);
  49.  
  50.     s->slice_height = s->mb_height / code;
  51.  
  52.     return 0;
  53. }
  54.  
  55. static av_cold int wmv2_encode_init(AVCodecContext *avctx)
  56. {
  57.     Wmv2Context *const w = avctx->priv_data;
  58.  
  59.     if (ff_mpv_encode_init(avctx) < 0)
  60.         return -1;
  61.  
  62.     ff_wmv2_common_init(w);
  63.  
  64.     avctx->extradata_size = 4;
  65.     avctx->extradata      = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
  66.     if (!avctx->extradata)
  67.         return AVERROR(ENOMEM);
  68.  
  69.     encode_ext_header(w);
  70.  
  71.     return 0;
  72. }
  73.  
  74. int ff_wmv2_encode_picture_header(MpegEncContext *s, int picture_number)
  75. {
  76.     Wmv2Context *const w = (Wmv2Context *) s;
  77.  
  78.     put_bits(&s->pb, 1, s->pict_type - 1);
  79.     if (s->pict_type == AV_PICTURE_TYPE_I)
  80.         put_bits(&s->pb, 7, 0);
  81.     put_bits(&s->pb, 5, s->qscale);
  82.  
  83.     s->dc_table_index  = 1;
  84.     s->mv_table_index  = 1; /* only if P frame */
  85.     s->per_mb_rl_table = 0;
  86.     s->mspel           = 0;
  87.     w->per_mb_abt      = 0;
  88.     w->abt_type        = 0;
  89.     w->j_type          = 0;
  90.  
  91.     av_assert0(s->flipflop_rounding);
  92.  
  93.     if (s->pict_type == AV_PICTURE_TYPE_I) {
  94.         av_assert0(s->no_rounding == 1);
  95.         if (w->j_type_bit)
  96.             put_bits(&s->pb, 1, w->j_type);
  97.  
  98.         if (w->per_mb_rl_bit)
  99.             put_bits(&s->pb, 1, s->per_mb_rl_table);
  100.  
  101.         if (!s->per_mb_rl_table) {
  102.             ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index);
  103.             ff_msmpeg4_code012(&s->pb, s->rl_table_index);
  104.         }
  105.  
  106.         put_bits(&s->pb, 1, s->dc_table_index);
  107.  
  108.         s->inter_intra_pred = 0;
  109.     } else {
  110.         int cbp_index;
  111.  
  112.         put_bits(&s->pb, 2, SKIP_TYPE_NONE);
  113.  
  114.         ff_msmpeg4_code012(&s->pb, cbp_index = 0);
  115.         w->cbp_table_index = wmv2_get_cbp_table_index(s, cbp_index);
  116.  
  117.         if (w->mspel_bit)
  118.             put_bits(&s->pb, 1, s->mspel);
  119.  
  120.         if (w->abt_flag) {
  121.             put_bits(&s->pb, 1, w->per_mb_abt ^ 1);
  122.             if (!w->per_mb_abt)
  123.                 ff_msmpeg4_code012(&s->pb, w->abt_type);
  124.         }
  125.  
  126.         if (w->per_mb_rl_bit)
  127.             put_bits(&s->pb, 1, s->per_mb_rl_table);
  128.  
  129.         if (!s->per_mb_rl_table) {
  130.             ff_msmpeg4_code012(&s->pb, s->rl_table_index);
  131.             s->rl_chroma_table_index = s->rl_table_index;
  132.         }
  133.         put_bits(&s->pb, 1, s->dc_table_index);
  134.         put_bits(&s->pb, 1, s->mv_table_index);
  135.  
  136.         s->inter_intra_pred = 0; // (s->width * s->height < 320 * 240 && s->bit_rate <= II_BITRATE);
  137.     }
  138.     s->esc3_level_length = 0;
  139.     s->esc3_run_length   = 0;
  140.  
  141.     return 0;
  142. }
  143.  
  144. /* Nearly identical to wmv1 but that is just because we do not use the
  145.  * useless M$ crap features. It is duplicated here in case someone wants
  146.  * to add support for these crap features. */
  147. void ff_wmv2_encode_mb(MpegEncContext *s, int16_t block[6][64],
  148.                        int motion_x, int motion_y)
  149. {
  150.     Wmv2Context *const w = (Wmv2Context *) s;
  151.     int cbp, coded_cbp, i;
  152.     int pred_x, pred_y;
  153.     uint8_t *coded_block;
  154.  
  155.     ff_msmpeg4_handle_slices(s);
  156.  
  157.     if (!s->mb_intra) {
  158.         /* compute cbp */
  159.         cbp = 0;
  160.         for (i = 0; i < 6; i++)
  161.             if (s->block_last_index[i] >= 0)
  162.                 cbp |= 1 << (5 - i);
  163.  
  164.         put_bits(&s->pb,
  165.                  ff_wmv2_inter_table[w->cbp_table_index][cbp + 64][1],
  166.                  ff_wmv2_inter_table[w->cbp_table_index][cbp + 64][0]);
  167.  
  168.         s->misc_bits += get_bits_diff(s);
  169.         /* motion vector */
  170.         ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
  171.         ff_msmpeg4_encode_motion(s, motion_x - pred_x,
  172.                                  motion_y - pred_y);
  173.         s->mv_bits += get_bits_diff(s);
  174.     } else {
  175.         /* compute cbp */
  176.         cbp       = 0;
  177.         coded_cbp = 0;
  178.         for (i = 0; i < 6; i++) {
  179.             int val, pred;
  180.             val  = (s->block_last_index[i] >= 1);
  181.             cbp |= val << (5 - i);
  182.             if (i < 4) {
  183.                 /* predict value for close blocks only for luma */
  184.                 pred         = ff_msmpeg4_coded_block_pred(s, i, &coded_block);
  185.                 *coded_block = val;
  186.                 val          = val ^ pred;
  187.             }
  188.             coded_cbp |= val << (5 - i);
  189.         }
  190.  
  191.         if (s->pict_type == AV_PICTURE_TYPE_I)
  192.             put_bits(&s->pb,
  193.                      ff_msmp4_mb_i_table[coded_cbp][1],
  194.                      ff_msmp4_mb_i_table[coded_cbp][0]);
  195.         else
  196.             put_bits(&s->pb,
  197.                      ff_wmv2_inter_table[w->cbp_table_index][cbp][1],
  198.                      ff_wmv2_inter_table[w->cbp_table_index][cbp][0]);
  199.         put_bits(&s->pb, 1, 0);         /* no AC prediction yet */
  200.         if (s->inter_intra_pred) {
  201.             s->h263_aic_dir = 0;
  202.             put_bits(&s->pb,
  203.                      ff_table_inter_intra[s->h263_aic_dir][1],
  204.                      ff_table_inter_intra[s->h263_aic_dir][0]);
  205.         }
  206.         s->misc_bits += get_bits_diff(s);
  207.     }
  208.  
  209.     for (i = 0; i < 6; i++)
  210.         ff_msmpeg4_encode_block(s, block[i], i);
  211.     if (s->mb_intra)
  212.         s->i_tex_bits += get_bits_diff(s);
  213.     else
  214.         s->p_tex_bits += get_bits_diff(s);
  215. }
  216.  
  217. static const AVClass wmv2_class = {
  218.     .class_name = "wmv2 encoder",
  219.     .item_name  = av_default_item_name,
  220.     .option     = ff_mpv_generic_options,
  221.     .version    = LIBAVUTIL_VERSION_INT,
  222. };
  223.  
  224. AVCodec ff_wmv2_encoder = {
  225.     .name           = "wmv2",
  226.     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 8"),
  227.     .type           = AVMEDIA_TYPE_VIDEO,
  228.     .id             = AV_CODEC_ID_WMV2,
  229.     .priv_data_size = sizeof(Wmv2Context),
  230.     .priv_class     = &wmv2_class,
  231.     .init           = wmv2_encode_init,
  232.     .encode2        = ff_mpv_encode_picture,
  233.     .close          = ff_mpv_encode_end,
  234.     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
  235.                                                      AV_PIX_FMT_NONE },
  236. };
  237.