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 "dsputil.h" 23#include "mpegvideo.h" 24#include "msmpeg4.h" 25#include "msmpeg4data.h" 26#include "h263.h" 27#include "wmv2.h" 28 29 30static int encode_ext_header(Wmv2Context *w){ 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 55static av_cold int wmv2_encode_init(AVCodecContext *avctx){ 56 Wmv2Context * const w= avctx->priv_data; 57 58 if(MPV_encode_init(avctx) < 0) 59 return -1; 60 61 ff_wmv2_common_init(w); 62 63 avctx->extradata_size= 4; 64 avctx->extradata= av_mallocz(avctx->extradata_size + 10); 65 encode_ext_header(w); 66 67 return 0; 68} 69 70int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number) 71{ 72 Wmv2Context * const w= (Wmv2Context*)s; 73 74 put_bits(&s->pb, 1, s->pict_type - 1); 75 if(s->pict_type == FF_I_TYPE){ 76 put_bits(&s->pb, 7, 0); 77 } 78 put_bits(&s->pb, 5, s->qscale); 79 80 s->dc_table_index = 1; 81 s->mv_table_index = 1; /* only if P frame */ 82 s->per_mb_rl_table = 0; 83 s->mspel= 0; 84 w->per_mb_abt=0; 85 w->abt_type=0; 86 w->j_type=0; 87 88 assert(s->flipflop_rounding); 89 90 if (s->pict_type == FF_I_TYPE) { 91 assert(s->no_rounding==1); 92 if(w->j_type_bit) put_bits(&s->pb, 1, w->j_type); 93 94 if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); 95 96 if(!s->per_mb_rl_table){ 97 ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index); 98 ff_msmpeg4_code012(&s->pb, s->rl_table_index); 99 } 100 101 put_bits(&s->pb, 1, s->dc_table_index); 102 103 s->inter_intra_pred= 0; 104 }else{ 105 int cbp_index; 106 107 put_bits(&s->pb, 2, SKIP_TYPE_NONE); 108 109 ff_msmpeg4_code012(&s->pb, cbp_index=0); 110 if(s->qscale <= 10){ 111 int map[3]= {0,2,1}; 112 w->cbp_table_index= map[cbp_index]; 113 }else if(s->qscale <= 20){ 114 int map[3]= {1,0,2}; 115 w->cbp_table_index= map[cbp_index]; 116 }else{ 117 int map[3]= {2,1,0}; 118 w->cbp_table_index= map[cbp_index]; 119 } 120 121 if(w->mspel_bit) put_bits(&s->pb, 1, s->mspel); 122 123 if(w->abt_flag){ 124 put_bits(&s->pb, 1, w->per_mb_abt^1); 125 if(!w->per_mb_abt){ 126 ff_msmpeg4_code012(&s->pb, w->abt_type); 127 } 128 } 129 130 if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); 131 132 if(!s->per_mb_rl_table){ 133 ff_msmpeg4_code012(&s->pb, s->rl_table_index); 134 s->rl_chroma_table_index = s->rl_table_index; 135 } 136 put_bits(&s->pb, 1, s->dc_table_index); 137 put_bits(&s->pb, 1, s->mv_table_index); 138 139 s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); 140 } 141 s->esc3_level_length= 0; 142 s->esc3_run_length= 0; 143 144 return 0; 145} 146 147/* Nearly identical to wmv1 but that is just because we do not use the 148 * useless M$ crap features. It is duplicated here in case someone wants 149 * to add support for these crap features. */ 150void ff_wmv2_encode_mb(MpegEncContext * s, 151 DCTELEM block[6][64], 152 int motion_x, int motion_y) 153{ 154 Wmv2Context * const w= (Wmv2Context*)s; 155 int cbp, coded_cbp, i; 156 int pred_x, pred_y; 157 uint8_t *coded_block; 158 159 ff_msmpeg4_handle_slices(s); 160 161 if (!s->mb_intra) { 162 /* compute cbp */ 163 cbp = 0; 164 for (i = 0; i < 6; i++) { 165 if (s->block_last_index[i] >= 0) 166 cbp |= 1 << (5 - i); 167 } 168 169 put_bits(&s->pb, 170 wmv2_inter_table[w->cbp_table_index][cbp + 64][1], 171 wmv2_inter_table[w->cbp_table_index][cbp + 64][0]); 172 173 /* motion vector */ 174 h263_pred_motion(s, 0, 0, &pred_x, &pred_y); 175 ff_msmpeg4_encode_motion(s, motion_x - pred_x, 176 motion_y - pred_y); 177 } else { 178 /* compute cbp */ 179 cbp = 0; 180 coded_cbp = 0; 181 for (i = 0; i < 6; i++) { 182 int val, pred; 183 val = (s->block_last_index[i] >= 1); 184 cbp |= val << (5 - i); 185 if (i < 4) { 186 /* predict value for close blocks only for luma */ 187 pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block); 188 *coded_block = val; 189 val = val ^ pred; 190 } 191 coded_cbp |= val << (5 - i); 192 } 193 194 if (s->pict_type == FF_I_TYPE) { 195 put_bits(&s->pb, 196 ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); 197 } else { 198 put_bits(&s->pb, 199 wmv2_inter_table[w->cbp_table_index][cbp][1], 200 wmv2_inter_table[w->cbp_table_index][cbp][0]); 201 } 202 put_bits(&s->pb, 1, 0); /* no AC prediction yet */ 203 if(s->inter_intra_pred){ 204 s->h263_aic_dir=0; 205 put_bits(&s->pb, table_inter_intra[s->h263_aic_dir][1], table_inter_intra[s->h263_aic_dir][0]); 206 } 207 } 208 209 for (i = 0; i < 6; i++) { 210 ff_msmpeg4_encode_block(s, block[i], i); 211 } 212} 213 214AVCodec wmv2_encoder = { 215 "wmv2", 216 AVMEDIA_TYPE_VIDEO, 217 CODEC_ID_WMV2, 218 sizeof(Wmv2Context), 219 wmv2_encode_init, 220 MPV_encode_picture, 221 MPV_encode_end, 222 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, 223 .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 8"), 224}; 225