* The simplest mpeg encoder (well, it was the simplest!).
*/
-#include <limits.h>
-#include <math.h> //for PI
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
#include "faandct.h"
+#include <limits.h>
#ifdef USE_FASTMEMCPY
#include "fastmemcpy.h"
DCTELEM *block, int n, int qscale);
static void dct_unquantize_h263_inter_c(MpegEncContext *s,
DCTELEM *block, int n, int qscale);
+static void dct_unquantize_h261_intra_c(MpegEncContext *s,
+ DCTELEM *block, int n, int qscale);
+static void dct_unquantize_h261_inter_c(MpegEncContext *s,
+ DCTELEM *block, int n, int qscale);
static void draw_edges_c(uint8_t *buf, int wrap, int width, int height, int w);
#ifdef CONFIG_ENCODERS
static int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
{
s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;
s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c;
+ s->dct_unquantize_h261_intra = dct_unquantize_h261_intra_c;
+ s->dct_unquantize_h261_inter = dct_unquantize_h261_inter_c;
s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c;
s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c;
s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c;
*/
#ifdef CONFIG_ENCODERS
-void MPV_encode_defaults(MpegEncContext *s){
+static void MPV_encode_defaults(MpegEncContext *s){
static int done=0;
MPV_common_defaults(s);
{
int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y;
+ if(s->avctx->thread_count > MAX_THREADS || (16*s->avctx->thread_count > s->height && s->height)){
+ av_log(s->avctx, AV_LOG_ERROR, "too many threads\n");
+ return -1;
+ }
+
dsputil_init(&s->dsp, s->avctx);
DCT_common_init(s);
}
}
av_freep(&s->picture);
- avcodec_default_free_buffers(s->avctx);
s->context_initialized = 0;
s->last_picture_ptr=
s->next_picture_ptr=
s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0;
s->mpeg_quant= avctx->mpeg_quant;
s->rtp_mode= !!avctx->rtp_payload_size;
+ s->intra_dc_precision= avctx->intra_dc_precision;
if (s->gop_size <= 1) {
s->intra_only = 1;
return -1;
}
- if(s->avctx->thread_count > MAX_THREADS || 16*s->avctx->thread_count > s->height){
- av_log(avctx, AV_LOG_ERROR, "too many threads\n");
- return -1;
- }
-
if(s->avctx->thread_count > 1)
s->rtp_mode= 1;
default:
return -1;
}
+
+ avctx->has_b_frames= !s->low_delay;
s->encoding = 1;
}else if(s->out_format == FMT_H263){
s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
s->dct_unquantize_inter = s->dct_unquantize_h263_inter;
+ }else if(s->out_format == FMT_H261){
+ s->dct_unquantize_intra = s->dct_unquantize_h261_intra;
+ s->dct_unquantize_inter = s->dct_unquantize_h261_inter;
}else{
s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;
s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;
if((s->avctx->debug_mv) && pict->motion_val){
int type;
for(type=0; type<3; type++){
- int direction;
+ int direction = 0;
switch (type) {
case 0: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_P_FOR)) || (pict->pict_type!=FF_P_TYPE))
continue;
uvsrc_x = src_x>>1;
uvsrc_y = src_y>>1;
}
+ }else if(s->out_format == FMT_H261){//even chroma mv's are full pel in H261
+ mx = motion_x / 4;
+ my = motion_y / 4;
+ uvdxy = 0;
+ uvsrc_x = s->mb_x*8 + mx;
+ uvsrc_y = s->mb_y*8 + my;
} else {
mx = motion_x / 2;
my = motion_y / 2;
}
}
ff_set_qscale(s, last_qp + s->dquant);
- }
+ }else if(s->flags&CODEC_FLAG_QP_RD)
+ ff_set_qscale(s, s->qscale + s->dquant);
wrap_y = s->linesize;
wrap_c = s->uvlinesize;
s->current_picture.mb_var [s->mb_stride * mb_y + mb_x] = varc;
s->current_picture.mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
- s->mb_var_sum_temp += varc;
+ s->me.mb_var_sum_temp += varc;
}
}
return 0;
for(i=0; i<3; i++){
/* init last dc values */
/* note: quant matrix value (8) is implied here */
- s->last_dc[i] = 128;
+ s->last_dc[i] = 128 << s->intra_dc_precision;
s->current_picture_ptr->error[i] = 0;
}
}
if (s->avctx->rtp_callback)
- s->avctx->rtp_callback(s->ptr_lastgob, current_packet_size, 0);
+ s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, current_packet_size, 0);
switch(s->codec_id){
case CODEC_ID_MPEG4:
pdif = pbBufPtr(&s->pb) - s->ptr_lastgob;
/* Call the RTP callback to send the last GOB */
emms_c();
- s->avctx->rtp_callback(s->ptr_lastgob, pdif, 0);
+ s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, pdif, 0);
}
return 0;
#define MERGE(field) dst->field += src->field; src->field=0
static void merge_context_after_me(MpegEncContext *dst, MpegEncContext *src){
- MERGE(scene_change_score);
- MERGE(mc_mb_var_sum_temp);
- MERGE(mb_var_sum_temp);
+ MERGE(me.scene_change_score);
+ MERGE(me.mc_mb_var_sum_temp);
+ MERGE(me.mb_var_sum_temp);
}
static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src){
static void encode_picture(MpegEncContext *s, int picture_number)
{
- int i, j;
+ int i;
int bits;
s->picture_number = picture_number;
/* Reset the average MB variance */
- s->mb_var_sum_temp =
- s->mc_mb_var_sum_temp = 0;
+ s->me.mb_var_sum_temp =
+ s->me.mc_mb_var_sum_temp = 0;
#ifdef CONFIG_RISKY
/* we need to initialize some time vars before we can encode b-frames */
ff_set_mpeg4_time(s, s->picture_number); //FIXME rename and use has_b_frames or similar
#endif
- s->scene_change_score=0;
+ s->me.scene_change_score=0;
- s->lambda= s->current_picture_ptr->quality; //FIXME qscale / ... stuff for ME ratedistoration
+// s->lambda= s->current_picture_ptr->quality; //FIXME qscale / ... stuff for ME ratedistoration
if(s->pict_type==I_TYPE){
if(s->msmpeg4_version >= 3) s->no_rounding=1;
for(i=1; i<s->avctx->thread_count; i++){
merge_context_after_me(s, s->thread_context[i]);
}
- s->current_picture.mc_mb_var_sum= s->current_picture_ptr->mc_mb_var_sum= s->mc_mb_var_sum_temp;
- s->current_picture. mb_var_sum= s->current_picture_ptr-> mb_var_sum= s-> mb_var_sum_temp;
+ s->current_picture.mc_mb_var_sum= s->current_picture_ptr->mc_mb_var_sum= s->me.mc_mb_var_sum_temp;
+ s->current_picture. mb_var_sum= s->current_picture_ptr-> mb_var_sum= s->me. mb_var_sum_temp;
emms_c();
- if(s->scene_change_score > s->avctx->scenechange_threshold && s->pict_type == P_TYPE){
+ if(s->me.scene_change_score > s->avctx->scenechange_threshold && s->pict_type == P_TYPE){
s->pict_type= I_TYPE;
for(i=0; i<s->mb_stride*s->mb_height; i++)
s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
ff_fix_long_p_mvs(s);
ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, 0);
if(s->flags & CODEC_FLAG_INTERLACED_ME){
+ int j;
for(i=0; i<2; i++){
for(j=0; j<2; j++)
ff_fix_long_mvs(s, s->p_field_select_table[i], j,
ff_fix_long_mvs(s, NULL, 0, s->b_bidir_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_BIDIR, 1);
ff_fix_long_mvs(s, NULL, 0, s->b_bidir_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BIDIR, 1);
if(s->flags & CODEC_FLAG_INTERLACED_ME){
- int dir;
+ int dir, j;
for(dir=0; dir<2; dir++){
for(i=0; i<2; i++){
for(j=0; j<2; j++){
int best_score=s->dsp.try_8x8basis(rem, weight, basis[0], 0);
int best_coeff=0;
int best_change=0;
- int run2, best_unquant_change, analyze_gradient;
+ int run2, best_unquant_change=0, analyze_gradient;
#ifdef REFINE_STATS
{START_TIMER
#endif
}
}
+static void dct_unquantize_h261_intra_c(MpegEncContext *s,
+ DCTELEM *block, int n, int qscale)
+{
+ int i, level, even;
+ int nCoeffs;
+
+ assert(s->block_last_index[n]>=0);
+
+ if (n < 4)
+ block[0] = block[0] * s->y_dc_scale;
+ else
+ block[0] = block[0] * s->c_dc_scale;
+ even = (qscale & 1)^1;
+ nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
+
+ for(i=1; i<=nCoeffs; i++){
+ level = block[i];
+ if (level){
+ if (level < 0){
+ level = qscale * ((level << 1) - 1) + even;
+ }else{
+ level = qscale * ((level << 1) + 1) - even;
+ }
+ }
+ block[i] = level;
+ }
+}
+
+static void dct_unquantize_h261_inter_c(MpegEncContext *s,
+ DCTELEM *block, int n, int qscale)
+{
+ int i, level, even;
+ int nCoeffs;
+
+ assert(s->block_last_index[n]>=0);
+
+ even = (qscale & 1)^1;
+
+ nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
+
+ for(i=0; i<=nCoeffs; i++){
+ level = block[i];
+ if (level){
+ if (level < 0){
+ level = qscale * ((level << 1) - 1) + even;
+ }else{
+ level = qscale * ((level << 1) + 1) - even;
+ }
+ }
+ block[i] = level;
+ }
+}
+
static const AVOption mpeg4_options[] =
{
AVOPTION_CODEC_INT("bitrate", "desired video bitrate", bit_rate, 4, 240000000, 800000),