#include <stdint.h>
+#include "libavutil/emms.h"
#include "libavutil/internal.h"
#include "libavutil/intmath.h"
#include "libavutil/mathematics.h"
#include "libavutil/mem_internal.h"
-#include "libavutil/pixdesc.h"
#include "libavutil/opt.h"
#include "libavutil/thread.h"
#include "avcodec.h"
-#include "dct.h"
#include "encode.h"
#include "idctdsp.h"
-#include "mpeg12.h"
+#include "mpeg12codecs.h"
#include "mpeg12data.h"
#include "mpeg12enc.h"
#include "mpegvideo.h"
#define QMAT_SHIFT_MMX 16
#define QMAT_SHIFT 21
-static int encode_picture(MpegEncContext *s, int picture_number);
+static int encode_picture(MpegEncContext *s);
static int dct_quantize_refine(MpegEncContext *s, int16_t *block, int16_t *weight, int16_t *orig, int n, int qscale);
static int sse_mb(MpegEncContext *s);
static void denoise_dct_c(MpegEncContext *s, int16_t *block);
MpegEncContext *s = avctx->priv_data;
AVCPBProperties *cpb_props;
int i, ret;
+ int mb_array_size, mv_table_size;
mpv_encode_defaults(s);
s->time_increment_bits = av_log2(avctx->time_base.den - 1) + 1;
switch (avctx->codec->id) {
- case AV_CODEC_ID_MPEG1VIDEO:
- s->out_format = FMT_MPEG1;
- s->low_delay = !!(avctx->flags & AV_CODEC_FLAG_LOW_DELAY);
- avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1);
- break;
+#if CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER
case AV_CODEC_ID_MPEG2VIDEO:
+ s->rtp_mode = 1;
+ /* fallthrough */
+ case AV_CODEC_ID_MPEG1VIDEO:
s->out_format = FMT_MPEG1;
s->low_delay = !!(avctx->flags & AV_CODEC_FLAG_LOW_DELAY);
avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1);
- s->rtp_mode = 1;
+ ff_mpeg1_encode_init(s);
break;
+#endif
#if CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER
case AV_CODEC_ID_MJPEG:
case AV_CODEC_ID_AMV:
case AV_CODEC_ID_H261:
if (!CONFIG_H261_ENCODER)
return AVERROR_ENCODER_NOT_FOUND;
- if (ff_h261_get_picture_format(s->width, s->height) < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "The specified picture size of %dx%d is not valid for the "
- "H.261 codec.\nValid sizes are 176x144, 352x288\n",
- s->width, s->height);
- return AVERROR(EINVAL);
- }
+ ret = ff_h261_encode_init(s);
+ if (ret < 0)
+ return ret;
s->out_format = FMT_H261;
avctx->delay = 0;
s->low_delay = 1;
AV_CODEC_FLAG_INTERLACED_ME) ||
s->alternate_scan);
+ if (s->lmin > s->lmax) {
+ av_log(avctx, AV_LOG_WARNING, "Clipping lmin value to %d\n", s->lmax);
+ s->lmin = s->lmax;
+ }
+
/* init */
ff_mpv_idct_init(s);
if ((ret = ff_mpv_common_init(s)) < 0)
ff_me_cmp_init(&s->mecc, avctx);
ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
ff_pixblockdsp_init(&s->pdsp, avctx);
- ff_qpeldsp_init(&s->qdsp);
if (!(avctx->stats_out = av_mallocz(256)) ||
!FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix, 32) ||
!FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix16, 32) ||
!FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32) ||
!FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix16, 32) ||
- !FF_ALLOCZ_TYPED_ARRAY(s->input_picture, MAX_PICTURE_COUNT) ||
- !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_PICTURE_COUNT))
+ !FF_ALLOCZ_TYPED_ARRAY(s->input_picture, MAX_B_FRAMES + 1) ||
+ !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_B_FRAMES + 1) ||
+ !(s->new_picture = av_frame_alloc()))
+ return AVERROR(ENOMEM);
+
+ /* Allocate MV tables; the MV and MB tables will be copied
+ * to slice contexts by ff_update_duplicate_context(). */
+ mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
+ if (!FF_ALLOCZ_TYPED_ARRAY(s->p_mv_table_base, mv_table_size) ||
+ !FF_ALLOCZ_TYPED_ARRAY(s->b_forw_mv_table_base, mv_table_size) ||
+ !FF_ALLOCZ_TYPED_ARRAY(s->b_back_mv_table_base, mv_table_size) ||
+ !FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_forw_mv_table_base, mv_table_size) ||
+ !FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_back_mv_table_base, mv_table_size) ||
+ !FF_ALLOCZ_TYPED_ARRAY(s->b_direct_mv_table_base, mv_table_size))
return AVERROR(ENOMEM);
+ s->p_mv_table = s->p_mv_table_base + s->mb_stride + 1;
+ s->b_forw_mv_table = s->b_forw_mv_table_base + s->mb_stride + 1;
+ s->b_back_mv_table = s->b_back_mv_table_base + s->mb_stride + 1;
+ s->b_bidir_forw_mv_table = s->b_bidir_forw_mv_table_base + s->mb_stride + 1;
+ s->b_bidir_back_mv_table = s->b_bidir_back_mv_table_base + s->mb_stride + 1;
+ s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1;
+
+ /* Allocate MB type table */
+ mb_array_size = s->mb_stride * s->mb_height;
+ if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_type, mb_array_size) ||
+ !FF_ALLOCZ_TYPED_ARRAY(s->lambda_table, mb_array_size) ||
+ !FF_ALLOC_TYPED_ARRAY (s->cplx_tab, mb_array_size) ||
+ !FF_ALLOC_TYPED_ARRAY (s->bits_tab, mb_array_size) ||
+ !FF_ALLOCZ_TYPED_ARRAY(s->mc_mb_var, mb_array_size) ||
+ !FF_ALLOCZ_TYPED_ARRAY(s->mb_var, mb_array_size) ||
+ !(s->mb_mean = av_mallocz(mb_array_size)))
+ return AVERROR(ENOMEM);
+
+#define ALLOCZ_ARRAYS(p, mult, numb) ((p) = av_calloc(numb, mult * sizeof(*(p))))
+ if (s->codec_id == AV_CODEC_ID_MPEG4 ||
+ (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
+ int16_t (*tmp1)[2];
+ uint8_t *tmp2;
+ if (!(tmp1 = ALLOCZ_ARRAYS(s->b_field_mv_table_base, 8, mv_table_size)) ||
+ !(tmp2 = ALLOCZ_ARRAYS(s->b_field_select_table[0][0], 2 * 4, mv_table_size)) ||
+ !ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * 2, mv_table_size))
+ return AVERROR(ENOMEM);
+
+ s->p_field_select_table[1] = s->p_field_select_table[0] + 2 * mv_table_size;
+ tmp1 += s->mb_stride + 1;
+
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 2; j++) {
+ for (int k = 0; k < 2; k++) {
+ s->b_field_mv_table[i][j][k] = tmp1;
+ tmp1 += mv_table_size;
+ }
+ s->b_field_select_table[i][j] = tmp2;
+ tmp2 += 2 * mv_table_size;
+ }
+ }
+ }
if (s->noise_reduction) {
if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
ff_dct_encode_init(s);
+ if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+ s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;
+ s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;
+ } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
+ s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
+ s->dct_unquantize_inter = s->dct_unquantize_h263_inter;
+ } else {
+ s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;
+ s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;
+ }
+
if ((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant)
s->chroma_qscale_table = ff_h263_chroma_qscale_table;
s->quant_precision = 5;
- ff_set_cmp(&s->mecc, s->mecc.ildct_cmp, avctx->ildct_cmp);
- ff_set_cmp(&s->mecc, s->mecc.frame_skip_cmp, s->frame_skip_cmp);
+ ret = ff_set_cmp(&s->mecc, s->mecc.ildct_cmp, avctx->ildct_cmp);
+ ret |= ff_set_cmp(&s->mecc, s->mecc.frame_skip_cmp, s->frame_skip_cmp);
+ if (ret < 0)
+ return AVERROR(EINVAL);
- if (CONFIG_H261_ENCODER && s->out_format == FMT_H261) {
- ff_h261_encode_init(s);
- } else if ((CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
- && s->out_format == FMT_MPEG1) {
- ff_mpeg1_encode_init(s);
- } else if (CONFIG_H263_ENCODER && s->out_format == FMT_H263) {
+ if (CONFIG_H263_ENCODER && s->out_format == FMT_H263) {
ff_h263_encode_init(s);
- if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version)
+ if (CONFIG_MSMPEG4ENC && s->msmpeg4_version)
ff_msmpeg4_encode_init(s);
}
}
}
- cpb_props = ff_add_cpb_side_data(avctx);
+ cpb_props = ff_encode_add_cpb_side_data(avctx);
if (!cpb_props)
return AVERROR(ENOMEM);
cpb_props->max_bitrate = avctx->rc_max_rate;
av_freep(&avctx->stats_out);
+ av_freep(&s->p_mv_table_base);
+ av_freep(&s->b_forw_mv_table_base);
+ av_freep(&s->b_back_mv_table_base);
+ av_freep(&s->b_bidir_forw_mv_table_base);
+ av_freep(&s->b_bidir_back_mv_table_base);
+ av_freep(&s->b_direct_mv_table_base);
+ av_freep(&s->b_field_mv_table_base);
+ av_freep(&s->b_field_select_table[0][0]);
+ av_freep(&s->p_field_select_table[0]);
+
+ av_freep(&s->mb_type);
+ av_freep(&s->lambda_table);
+
+ av_freep(&s->cplx_tab);
+ av_freep(&s->bits_tab);
+
if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix);
if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
s->q_chroma_intra_matrix= NULL;
av_freep(&s->input_picture);
av_freep(&s->reordered_input_picture);
av_freep(&s->dct_offset);
+ av_freep(&s->mb_var);
+ av_freep(&s->mc_mb_var);
+ av_freep(&s->mb_mean);
return 0;
}
-static int get_sae(uint8_t *src, int ref, int stride)
+#define IS_ENCODER 1
+#include "mpv_reconstruct_mb_template.c"
+
+static void mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64])
+{
+ if (s->avctx->debug & FF_DEBUG_DCT_COEFF) {
+ /* print DCT coefficients */
+ av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y);
+ for (int i = 0; i < 6; i++) {
+ for (int j = 0; j < 64; j++) {
+ av_log(s->avctx, AV_LOG_DEBUG, "%5d",
+ block[i][s->idsp.idct_permutation[j]]);
+ }
+ av_log(s->avctx, AV_LOG_DEBUG, "\n");
+ }
+ }
+
+ mpv_reconstruct_mb_internal(s, block, 0, MAY_BE_MPEG12);
+}
+
+static int get_sae(const uint8_t *src, int ref, int stride)
{
int x,y;
int acc = 0;
return acc;
}
-static int get_intra_count(MpegEncContext *s, uint8_t *src,
- uint8_t *ref, int stride)
+static int get_intra_count(MpegEncContext *s, const uint8_t *src,
+ const uint8_t *ref, int stride)
{
int x, y, w, h;
int acc = 0;
return acc;
}
-static int alloc_picture(MpegEncContext *s, Picture *pic, int shared)
+static int alloc_picture(MpegEncContext *s, Picture *pic)
{
- return ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, shared, 1,
- s->chroma_x_shift, s->chroma_y_shift, s->out_format,
+ AVCodecContext *avctx = s->avctx;
+ int ret;
+
+ pic->f->width = avctx->width + 2 * EDGE_WIDTH;
+ pic->f->height = avctx->height + 2 * EDGE_WIDTH;
+
+ ret = ff_encode_alloc_frame(avctx, pic->f);
+ if (ret < 0)
+ return ret;
+
+ for (int i = 0; pic->f->data[i]; i++) {
+ int offset = (EDGE_WIDTH >> (i ? s->chroma_y_shift : 0)) *
+ pic->f->linesize[i] +
+ (EDGE_WIDTH >> (i ? s->chroma_x_shift : 0));
+ pic->f->data[i] += offset;
+ }
+ pic->f->width = avctx->width;
+ pic->f->height = avctx->height;
+
+ return ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, 1, s->out_format,
s->mb_stride, s->mb_width, s->mb_height, s->b8_stride,
&s->linesize, &s->uvlinesize);
}
}
}
- if (!pic_arg->buf[0] ||
- pic_arg->linesize[0] != s->linesize ||
+ if (pic_arg->linesize[0] != s->linesize ||
pic_arg->linesize[1] != s->uvlinesize ||
pic_arg->linesize[2] != s->uvlinesize)
direct = 0;
if (direct) {
if ((ret = av_frame_ref(pic->f, pic_arg)) < 0)
return ret;
- }
- ret = alloc_picture(s, pic, direct);
- if (ret < 0)
- return ret;
+ pic->shared = 1;
+ } else {
+ ret = alloc_picture(s, pic);
+ if (ret < 0)
+ return ret;
+ ret = av_frame_copy_props(pic->f, pic_arg);
+ if (ret < 0) {
+ ff_mpeg_unref_picture(pic);
+ return ret;
+ }
- if (!direct) {
- if (pic->f->data[0] + INPLACE_OFFSET == pic_arg->data[0] &&
- pic->f->data[1] + INPLACE_OFFSET == pic_arg->data[1] &&
- pic->f->data[2] + INPLACE_OFFSET == pic_arg->data[2]) {
- // empty
- } else {
- int h_chroma_shift, v_chroma_shift;
- av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
- &h_chroma_shift,
- &v_chroma_shift);
-
- for (i = 0; i < 3; i++) {
- int src_stride = pic_arg->linesize[i];
- int dst_stride = i ? s->uvlinesize : s->linesize;
- int h_shift = i ? h_chroma_shift : 0;
- int v_shift = i ? v_chroma_shift : 0;
- int w = s->width >> h_shift;
- int h = s->height >> v_shift;
- uint8_t *src = pic_arg->data[i];
- uint8_t *dst = pic->f->data[i];
- int vpad = 16;
-
- if ( s->codec_id == AV_CODEC_ID_MPEG2VIDEO
- && !s->progressive_sequence
- && FFALIGN(s->height, 32) - s->height > 16)
- vpad = 32;
-
- if (!s->avctx->rc_buffer_size)
- dst += INPLACE_OFFSET;
-
- if (src_stride == dst_stride)
- memcpy(dst, src, src_stride * h);
- else {
- int h2 = h;
- uint8_t *dst2 = dst;
- while (h2--) {
- memcpy(dst2, src, w);
- dst2 += dst_stride;
- src += src_stride;
- }
- }
- if ((s->width & 15) || (s->height & (vpad-1))) {
- s->mpvencdsp.draw_edges(dst, dst_stride,
- w, h,
- 16 >> h_shift,
- vpad >> v_shift,
- EDGE_BOTTOM);
+ for (int i = 0; i < 3; i++) {
+ int src_stride = pic_arg->linesize[i];
+ int dst_stride = i ? s->uvlinesize : s->linesize;
+ int h_shift = i ? s->chroma_x_shift : 0;
+ int v_shift = i ? s->chroma_y_shift : 0;
+ int w = s->width >> h_shift;
+ int h = s->height >> v_shift;
+ const uint8_t *src = pic_arg->data[i];
+ uint8_t *dst = pic->f->data[i];
+ int vpad = 16;
+
+ if ( s->codec_id == AV_CODEC_ID_MPEG2VIDEO
+ && !s->progressive_sequence
+ && FFALIGN(s->height, 32) - s->height > 16)
+ vpad = 32;
+
+ if (!s->avctx->rc_buffer_size)
+ dst += INPLACE_OFFSET;
+
+ if (src_stride == dst_stride)
+ memcpy(dst, src, src_stride * h);
+ else {
+ int h2 = h;
+ uint8_t *dst2 = dst;
+ while (h2--) {
+ memcpy(dst2, src, w);
+ dst2 += dst_stride;
+ src += src_stride;
}
}
- emms_c();
+ if ((s->width & 15) || (s->height & (vpad-1))) {
+ s->mpvencdsp.draw_edges(dst, dst_stride,
+ w, h,
+ 16 >> h_shift,
+ vpad >> v_shift,
+ EDGE_BOTTOM);
+ }
}
+ emms_c();
}
- ret = av_frame_copy_props(pic->f, pic_arg);
- if (ret < 0)
- return ret;
- pic->f->display_picture_number = display_picture_number;
+ pic->display_picture_number = display_picture_number;
pic->f->pts = pts; // we set this here to avoid modifying pic_arg
} else {
/* Flushing: When we have not received enough input frames,
}
/* shift buffer entries */
- for (i = flush_offset; i < MAX_PICTURE_COUNT /*s->encoding_delay + 1*/; i++)
+ for (int i = flush_offset; i <= MAX_B_FRAMES; i++)
s->input_picture[i - flush_offset] = s->input_picture[i];
- s->input_picture[encoding_delay] = (Picture*) pic;
+ s->input_picture[encoding_delay] = pic;
return 0;
}
-static int skip_check(MpegEncContext *s, Picture *p, Picture *ref)
+static int skip_check(MpegEncContext *s, const Picture *p, const Picture *ref)
{
int x, y, plane;
int score = 0;
for (y = 0; y < s->mb_height * bw; y++) {
for (x = 0; x < s->mb_width * bw; x++) {
int off = p->shared ? 0 : 16;
- uint8_t *dptr = p->f->data[plane] + 8 * (x + y * stride) + off;
- uint8_t *rptr = ref->f->data[plane] + 8 * (x + y * stride);
+ const uint8_t *dptr = p->f->data[plane] + 8 * (x + y * stride) + off;
+ const uint8_t *rptr = ref->f->data[plane] + 8 * (x + y * stride);
int v = s->mecc.frame_skip_cmp[1](s, dptr, rptr, stride, 8);
switch (FFABS(s->frame_skip_exp)) {
return 0;
}
-static int encode_frame(AVCodecContext *c, AVFrame *frame, AVPacket *pkt)
+static int encode_frame(AVCodecContext *c, const AVFrame *frame, AVPacket *pkt)
{
int ret;
int size = 0;
FF_LAMBDA_SHIFT;
for (i = 0; i < s->max_b_frames + 2; i++) {
- Picture pre_input, *pre_input_ptr = i ? s->input_picture[i - 1] :
- s->next_picture_ptr;
- uint8_t *data[4];
+ const Picture *pre_input_ptr = i ? s->input_picture[i - 1] :
+ s->next_picture_ptr;
- if (pre_input_ptr && (!i || s->input_picture[i - 1])) {
- pre_input = *pre_input_ptr;
+ if (pre_input_ptr) {
+ const uint8_t *data[4];
memcpy(data, pre_input_ptr->f->data, sizeof(data));
- if (!pre_input.shared && i) {
+ if (!pre_input_ptr->shared && i) {
data[0] += INPLACE_OFFSET;
data[1] += INPLACE_OFFSET;
data[2] += INPLACE_OFFSET;
s->mpvencdsp.shrink[scale](s->tmp_frames[i]->data[0],
s->tmp_frames[i]->linesize[0],
data[0],
- pre_input.f->linesize[0],
+ pre_input_ptr->f->linesize[0],
width, height);
s->mpvencdsp.shrink[scale](s->tmp_frames[i]->data[1],
s->tmp_frames[i]->linesize[1],
data[1],
- pre_input.f->linesize[1],
+ pre_input_ptr->f->linesize[1],
width >> 1, height >> 1);
s->mpvencdsp.shrink[scale](s->tmp_frames[i]->data[2],
s->tmp_frames[i]->linesize[2],
data[2],
- pre_input.f->linesize[2],
+ pre_input_ptr->f->linesize[2],
width >> 1, height >> 1);
}
}
{
int i, ret;
- for (i = 1; i < MAX_PICTURE_COUNT; i++)
+ for (int i = 1; i <= MAX_B_FRAMES; i++)
s->reordered_input_picture[i - 1] = s->reordered_input_picture[i];
- s->reordered_input_picture[MAX_PICTURE_COUNT - 1] = NULL;
+ s->reordered_input_picture[MAX_B_FRAMES] = NULL;
/* set next picture type & ordering */
if (!s->reordered_input_picture[0] && s->input_picture[0]) {
!s->next_picture_ptr || s->intra_only) {
s->reordered_input_picture[0] = s->input_picture[0];
s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_I;
- s->reordered_input_picture[0]->f->coded_picture_number =
+ s->reordered_input_picture[0]->coded_picture_number =
s->coded_picture_number++;
} else {
int b_frames = 0;
if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
for (i = 0; i < s->max_b_frames + 1; i++) {
- int pict_num = s->input_picture[0]->f->display_picture_number + i;
+ int pict_num = s->input_picture[0]->display_picture_number + i;
if (pict_num >= s->rc_context.num_entries)
break;
}
} else if (s->b_frame_strategy == 2) {
b_frames = estimate_best_b_count(s);
- if (b_frames < 0)
+ if (b_frames < 0) {
+ ff_mpeg_unref_picture(s->input_picture[0]);
return b_frames;
+ }
}
emms_c();
s->reordered_input_picture[0] = s->input_picture[b_frames];
if (s->reordered_input_picture[0]->f->pict_type != AV_PICTURE_TYPE_I)
s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_P;
- s->reordered_input_picture[0]->f->coded_picture_number =
+ s->reordered_input_picture[0]->coded_picture_number =
s->coded_picture_number++;
for (i = 0; i < b_frames; i++) {
s->reordered_input_picture[i + 1] = s->input_picture[i];
s->reordered_input_picture[i + 1]->f->pict_type =
AV_PICTURE_TYPE_B;
- s->reordered_input_picture[i + 1]->f->coded_picture_number =
+ s->reordered_input_picture[i + 1]->coded_picture_number =
s->coded_picture_number++;
}
}
if ((ret = av_frame_ref(s->new_picture,
s->reordered_input_picture[0]->f)))
- return ret;
+ goto fail;
if (s->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) {
// input is a shared pix, so we can't modify it -> allocate a new
pic = &s->picture[i];
pic->reference = s->reordered_input_picture[0]->reference;
- if (alloc_picture(s, pic, 0) < 0) {
- return -1;
- }
+ ret = alloc_picture(s, pic);
+ if (ret < 0)
+ goto fail;
ret = av_frame_copy_props(pic->f, s->reordered_input_picture[0]->f);
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ ff_mpeg_unref_picture(pic);
+ goto fail;
+ }
+ pic->coded_picture_number = s->reordered_input_picture[0]->coded_picture_number;
+ pic->display_picture_number = s->reordered_input_picture[0]->display_picture_number;
/* mark us unused / free shared pic */
av_frame_unref(s->reordered_input_picture[0]->f);
s->new_picture->data[i] += INPLACE_OFFSET;
}
}
- s->picture_number = s->new_picture->display_picture_number;
+ s->picture_number = s->current_picture_ptr->display_picture_number;
+
}
return 0;
+fail:
+ ff_mpeg_unref_picture(s->reordered_input_picture[0]);
+ return ret;
}
static void frame_end(MpegEncContext *s)
if (s->unrestricted_mv &&
s->current_picture.reference &&
!s->intra_only) {
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
- int hshift = desc->log2_chroma_w;
- int vshift = desc->log2_chroma_h;
+ int hshift = s->chroma_x_shift;
+ int vshift = s->chroma_y_shift;
s->mpvencdsp.draw_edges(s->current_picture.f->data[0],
s->current_picture.f->linesize[0],
s->h_edge_pos, s->v_edge_pos,
if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&
s->last_picture_ptr != s->next_picture_ptr &&
s->last_picture_ptr->f->buf[0]) {
- ff_mpeg_unref_picture(s->avctx, s->last_picture_ptr);
+ ff_mpeg_unref_picture(s->last_picture_ptr);
}
s->current_picture_ptr->f->pict_type = s->pict_type;
- s->current_picture_ptr->f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
- ff_mpeg_unref_picture(s->avctx, &s->current_picture);
- if ((ret = ff_mpeg_ref_picture(s->avctx, &s->current_picture,
+ ff_mpeg_unref_picture(&s->current_picture);
+ if ((ret = ff_mpeg_ref_picture(&s->current_picture,
s->current_picture_ptr)) < 0)
return ret;
}
if (s->last_picture_ptr) {
- ff_mpeg_unref_picture(s->avctx, &s->last_picture);
+ ff_mpeg_unref_picture(&s->last_picture);
if (s->last_picture_ptr->f->buf[0] &&
- (ret = ff_mpeg_ref_picture(s->avctx, &s->last_picture,
+ (ret = ff_mpeg_ref_picture(&s->last_picture,
s->last_picture_ptr)) < 0)
return ret;
}
if (s->next_picture_ptr) {
- ff_mpeg_unref_picture(s->avctx, &s->next_picture);
+ ff_mpeg_unref_picture(&s->next_picture);
if (s->next_picture_ptr->f->buf[0] &&
- (ret = ff_mpeg_ref_picture(s->avctx, &s->next_picture,
+ (ret = ff_mpeg_ref_picture(&s->next_picture,
s->next_picture_ptr)) < 0)
return ret;
}
- if (s->picture_structure!= PICT_FRAME) {
- int i;
- for (i = 0; i < 4; i++) {
- if (s->picture_structure == PICT_BOTTOM_FIELD) {
- s->current_picture.f->data[i] +=
- s->current_picture.f->linesize[i];
- }
- s->current_picture.f->linesize[i] *= 2;
- s->last_picture.f->linesize[i] *= 2;
- s->next_picture.f->linesize[i] *= 2;
- }
- }
-
- if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
- s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;
- s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;
- } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
- s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
- s->dct_unquantize_inter = s->dct_unquantize_h263_inter;
- } else {
- s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;
- s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;
- }
-
if (s->dct_error_sum) {
av_assert2(s->noise_reduction && s->encoding);
update_noise_reduction(s);
if (ret < 0)
return ret;
vbv_retry:
- ret = encode_picture(s, s->picture_number);
+ ret = encode_picture(s);
if (growing_buffer) {
av_assert0(s->pb.buf == avctx->internal->byte_buffer);
pkt->data = s->pb.buf;
ff_write_pass1_stats(s);
for (i = 0; i < 4; i++) {
- s->current_picture_ptr->encoding_error[i] = s->current_picture.encoding_error[i];
- avctx->error[i] += s->current_picture_ptr->encoding_error[i];
+ avctx->error[i] += s->encoding_error[i];
}
ff_side_data_set_encoder_stats(pkt, s->current_picture.f->quality,
- s->current_picture_ptr->encoding_error,
+ s->encoding_error,
(avctx->flags&AV_CODEC_FLAG_PSNR) ? MPEGVIDEO_MAX_PLANES : 0,
s->pict_type);
s->total_bits += s->frame_bits;
pkt->pts = s->current_picture.f->pts;
+ pkt->duration = s->current_picture.f->duration;
if (!s->low_delay && s->pict_type != AV_PICTURE_TYPE_B) {
- if (!s->current_picture.f->coded_picture_number)
+ if (!s->current_picture.coded_picture_number)
pkt->dts = pkt->pts - s->dts_delta;
else
pkt->dts = s->reordered_pts;
s->reordered_pts = pkt->pts;
} else
pkt->dts = pkt->pts;
- if (s->current_picture.f->key_frame)
+
+ // the no-delay case is handled in generic code
+ if (avctx->codec->capabilities & AV_CODEC_CAP_DELAY) {
+ ret = ff_encode_reordered_opaque(avctx, pkt, s->current_picture.f);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (s->current_picture.f->flags & AV_FRAME_FLAG_KEY)
pkt->flags |= AV_PKT_FLAG_KEY;
if (s->mb_info)
av_packet_shrink_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, s->mb_info_size);
/* release non-reference frames */
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
if (!s->picture[i].reference)
- ff_mpeg_unref_picture(avctx, &s->picture[i]);
+ ff_mpeg_unref_picture(&s->picture[i]);
}
av_assert1((s->frame_bits & 7) == 0);
overflow, minlevel, maxlevel);
}
-static void get_visual_weight(int16_t *weight, uint8_t *ptr, int stride)
+static void get_visual_weight(int16_t *weight, const uint8_t *ptr, int stride)
{
int x, y;
// FIXME optimize
int skip_dct[12];
int dct_offset = s->linesize * 8; // default for progressive frames
int uv_dct_offset = s->uvlinesize * 8;
- uint8_t *ptr_y, *ptr_cb, *ptr_cr;
+ const uint8_t *ptr_y, *ptr_cb, *ptr_cr;
ptrdiff_t wrap_y, wrap_c;
for (i = 0; i < mb_block_count; i++)
}
}
/* pre quantization */
- if (s->current_picture.mc_mb_var[s->mb_stride * mb_y + mb_x] <
- 2 * s->qscale * s->qscale) {
+ if (s->mc_mb_var[s->mb_stride * mb_y + mb_x] < 2 * s->qscale * s->qscale) {
// FIXME optimize
if (s->mecc.sad[1](NULL, ptr_y, dest_y, wrap_y, 8) < 20 * s->qscale)
skip_dct[0] = 1;
case AV_CODEC_ID_MSMPEG4V2:
case AV_CODEC_ID_MSMPEG4V3:
case AV_CODEC_ID_WMV1:
- if (CONFIG_MSMPEG4_ENCODER)
+ if (CONFIG_MSMPEG4ENC)
ff_msmpeg4_encode_mb(s, s->block, motion_x, motion_y);
break;
case AV_CODEC_ID_WMV2:
}
if(s->avctx->mb_decision == FF_MB_DECISION_RD){
- ff_mpv_reconstruct_mb(s, s->block);
+ mpv_reconstruct_mb(s, s->block);
score *= s->lambda2;
score += sse_mb(s) << FF_LAMBDA_SHIFT;
}
}
-static int sse(MpegEncContext *s, uint8_t *src1, uint8_t *src2, int w, int h, int stride){
+static int sse(MpegEncContext *s, const uint8_t *src1, const uint8_t *src2, int w, int h, int stride){
const uint32_t *sq = ff_square_tab + 256;
int acc=0;
int x,y;
for(mb_x=0; mb_x < s->mb_width; mb_x++) {
int xx = mb_x * 16;
int yy = mb_y * 16;
- uint8_t *pix = s->new_picture->data[0] + (yy * s->linesize) + xx;
+ const uint8_t *pix = s->new_picture->data[0] + (yy * s->linesize) + xx;
int varc;
int sum = s->mpvencdsp.pix_sum(pix, s->linesize);
varc = (s->mpvencdsp.pix_norm1(pix, s->linesize) -
(((unsigned) sum * sum) >> 8) + 500 + 128) >> 8;
- 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 [s->mb_stride * mb_y + mb_x] = varc;
+ s->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
s->me.mb_var_sum_temp += varc;
}
}
/* note: quant matrix value (8) is implied here */
s->last_dc[i] = 128 << s->intra_dc_precision;
- s->current_picture.encoding_error[i] = 0;
+ s->encoding_error[i] = 0;
}
if(s->codec_id==AV_CODEC_ID_AMV){
s->last_dc[0] = 128*8/13;
s->mb_x = mb_x;
s->mb_y = mb_y; // moved into loop, can get changed by H.261
- ff_update_block_index(s);
+ ff_update_block_index(s, 8, 0, s->chroma_x_shift);
if(CONFIG_H261_ENCODER && s->codec_id == AV_CODEC_ID_H261){
ff_h261_reorder_mb_index(s);
}
if(s->avctx->mb_decision == FF_MB_DECISION_BITS)
- ff_mpv_reconstruct_mb(s, s->block);
+ mpv_reconstruct_mb(s, s->block);
} else {
int motion_x = 0, motion_y = 0;
s->mv_type=MV_TYPE_16X16;
s->out_format == FMT_H263 && s->pict_type!=AV_PICTURE_TYPE_B)
ff_h263_update_motion_val(s);
- ff_mpv_reconstruct_mb(s, s->block);
+ mpv_reconstruct_mb(s, s->block);
}
/* clean the MV table in IPS frames for direct mode in B-frames */
if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16;
if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16;
- s->current_picture.encoding_error[0] += sse(
+ s->encoding_error[0] += sse(
s, s->new_picture->data[0] + s->mb_x*16 + s->mb_y*s->linesize*16,
s->dest[0], w, h, s->linesize);
- s->current_picture.encoding_error[1] += sse(
+ s->encoding_error[1] += sse(
s, s->new_picture->data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*chr_h,
s->dest[1], w>>1, h>>s->chroma_y_shift, s->uvlinesize);
- s->current_picture.encoding_error[2] += sse(
+ s->encoding_error[2] += sse(
s, s->new_picture->data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*chr_h,
s->dest[2], w>>1, h>>s->chroma_y_shift, s->uvlinesize);
}
}
//not beautiful here but we must write it before flushing so it has to be here
- if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type == AV_PICTURE_TYPE_I)
+ if (CONFIG_MSMPEG4ENC && s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type == AV_PICTURE_TYPE_I)
ff_msmpeg4_encode_ext_header(s);
write_slice_end(s);
MERGE(i_count);
MERGE(skip_count);
MERGE(misc_bits);
- MERGE(current_picture.encoding_error[0]);
- MERGE(current_picture.encoding_error[1]);
- MERGE(current_picture.encoding_error[2]);
+ MERGE(encoding_error[0]);
+ MERGE(encoding_error[1]);
+ MERGE(encoding_error[2]);
if (dst->noise_reduction){
for(i=0; i<64; i++){
}
}
-static int encode_picture(MpegEncContext *s, int picture_number)
+static int encode_picture(MpegEncContext *s)
{
int i, ret;
int bits;
int context_count = s->slice_context_count;
- s->picture_number = picture_number;
-
/* Reset the average MB variance */
s->me.mb_var_sum_temp =
s->me.mc_mb_var_sum_temp = 0;
for(i=1; i<context_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->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;
+ s->mc_mb_var_sum = s->me.mc_mb_var_sum_temp;
+ s->mb_var_sum = s->me. mb_var_sum_temp;
emms_c();
if (s->me.scene_change_score > s->scenechange_threshold &&
if(s->msmpeg4_version >= 3)
s->no_rounding=1;
ff_dlog(s, "Scene change detected, encoding as I Frame %"PRId64" %"PRId64"\n",
- s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum);
+ s->mb_var_sum, s->mc_mb_var_sum);
}
if(!s->umvplus){
s-> intra_matrix[j] = av_clip_uint8(( luma_matrix[i] * s->qscale) >> 3);
}
s->y_dc_scale_table=
- s->c_dc_scale_table= ff_mpeg2_dc_scale_table[s->intra_dc_precision];
+ s->c_dc_scale_table = ff_mpeg12_dc_scale_table[s->intra_dc_precision];
s->chroma_intra_matrix[0] =
- s->intra_matrix[0] = ff_mpeg2_dc_scale_table[s->intra_dc_precision][8];
+ s->intra_matrix[0] = ff_mpeg12_dc_scale_table[s->intra_dc_precision][8];
ff_convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16,
s->intra_matrix, s->intra_quant_bias, 8, 8, 1);
ff_convert_matrix(s, s->q_chroma_intra_matrix, s->q_chroma_intra_matrix16,
s->chroma_intra_matrix, s->intra_quant_bias, 8, 8, 1);
s->qscale = 8;
}
- } else if (s->out_format == FMT_SPEEDHQ) {
- s->y_dc_scale_table=
- s->c_dc_scale_table= ff_mpeg2_dc_scale_table[3];
}
//FIXME var duplication
- s->current_picture_ptr->f->key_frame =
- s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I; //FIXME pic_ptr
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
+ s->current_picture_ptr->f->flags |= AV_FRAME_FLAG_KEY; //FIXME pic_ptr
+ s->current_picture.f->flags |= AV_FRAME_FLAG_KEY;
+ } else {
+ s->current_picture_ptr->f->flags &= ~AV_FRAME_FLAG_KEY; //FIXME pic_ptr
+ s->current_picture.f->flags &= ~AV_FRAME_FLAG_KEY;
+ }
s->current_picture_ptr->f->pict_type =
s->current_picture.f->pict_type = s->pict_type;
- if (s->current_picture.f->key_frame)
+ if (s->current_picture.f->flags & AV_FRAME_FLAG_KEY)
s->picture_in_gop_number=0;
s->mb_x = s->mb_y = 0;
break;
case FMT_H261:
if (CONFIG_H261_ENCODER)
- ff_h261_encode_picture_header(s, picture_number);
+ ff_h261_encode_picture_header(s);
break;
case FMT_H263:
if (CONFIG_WMV2_ENCODER && s->codec_id == AV_CODEC_ID_WMV2)
- ff_wmv2_encode_picture_header(s, picture_number);
- else if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version)
- ff_msmpeg4_encode_picture_header(s, picture_number);
+ ff_wmv2_encode_picture_header(s);
+ else if (CONFIG_MSMPEG4ENC && s->msmpeg4_version)
+ ff_msmpeg4_encode_picture_header(s);
else if (CONFIG_MPEG4_ENCODER && s->h263_pred) {
- ret = ff_mpeg4_encode_picture_header(s, picture_number);
+ ret = ff_mpeg4_encode_picture_header(s);
if (ret < 0)
return ret;
} else if (CONFIG_RV10_ENCODER && s->codec_id == AV_CODEC_ID_RV10) {
- ret = ff_rv10_encode_picture_header(s, picture_number);
+ ret = ff_rv10_encode_picture_header(s);
if (ret < 0)
return ret;
}
else if (CONFIG_RV20_ENCODER && s->codec_id == AV_CODEC_ID_RV20)
- ff_rv20_encode_picture_header(s, picture_number);
+ ff_rv20_encode_picture_header(s);
else if (CONFIG_FLV_ENCODER && s->codec_id == AV_CODEC_ID_FLV1)
- ff_flv_encode_picture_header(s, picture_number);
+ ff_flv_encode_picture_header(s);
else if (CONFIG_H263_ENCODER)
- ff_h263_encode_picture_header(s, picture_number);
+ ff_h263_encode_picture_header(s);
break;
case FMT_MPEG1:
if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
- ff_mpeg1_encode_picture_header(s, picture_number);
+ ff_mpeg1_encode_picture_header(s);
break;
default:
av_assert0(0);