153 changes: 74 additions & 79 deletions libavcodec/mpegvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,13 +366,6 @@ static int init_duplicate_context(MpegEncContext *s)
if (s->mb_height & 1)
yc_size += 2*s->b8_stride + 2*s->mb_stride;

s->sc.edge_emu_buffer =
s->me.scratchpad =
s->me.temp =
s->sc.rd_scratchpad =
s->sc.b_scratchpad =
s->sc.obmc_scratchpad = NULL;

if (s->encoding) {
if (!FF_ALLOCZ_TYPED_ARRAY(s->me.map, ME_MAP_SIZE) ||
!FF_ALLOCZ_TYPED_ARRAY(s->me.score_map, ME_MAP_SIZE))
Expand Down Expand Up @@ -413,6 +406,35 @@ static int init_duplicate_context(MpegEncContext *s)
return 0;
}

/**
* Initialize an MpegEncContext's thread contexts. Presumes that
* slice_context_count is already set and that all the fields
* that are freed/reset in free_duplicate_context() are NULL.
*/
static int init_duplicate_contexts(MpegEncContext *s)
{
int nb_slices = s->slice_context_count, ret;

/* We initialize the copies before the original so that
* fields allocated in init_duplicate_context are NULL after
* copying. This prevents double-frees upon allocation error. */
for (int i = 1; i < nb_slices; i++) {
s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));
if (!s->thread_context[i])
return AVERROR(ENOMEM);
if ((ret = init_duplicate_context(s->thread_context[i])) < 0)
return ret;
s->thread_context[i]->start_mb_y =
(s->mb_height * (i ) + nb_slices / 2) / nb_slices;
s->thread_context[i]->end_mb_y =
(s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
}
s->start_mb_y = 0;
s->end_mb_y = nb_slices > 1 ? (s->mb_height + nb_slices / 2) / nb_slices
: s->mb_height;
return init_duplicate_context(s);
}

static void free_duplicate_context(MpegEncContext *s)
{
if (!s)
Expand All @@ -435,6 +457,15 @@ static void free_duplicate_context(MpegEncContext *s)
s->block = NULL;
}

static void free_duplicate_contexts(MpegEncContext *s)
{
for (int i = 1; i < s->slice_context_count; i++) {
free_duplicate_context(s->thread_context[i]);
av_freep(&s->thread_context[i]);
}
free_duplicate_context(s);
}

static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
{
#define COPY(a) bak->a = src->a
Expand Down Expand Up @@ -524,7 +555,6 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
}

if (s->height != s1->height || s->width != s1->width || s->context_reinit) {
s->context_reinit = 0;
s->height = s1->height;
s->width = s1->width;
if ((ret = ff_mpv_common_frame_size_change(s)) < 0)
Expand Down Expand Up @@ -932,60 +962,51 @@ av_cold int ff_mpv_common_init(MpegEncContext *s)
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
s->picture[i].f = av_frame_alloc();
if (!s->picture[i].f)
return AVERROR(ENOMEM);
goto fail_nomem;
}

if (!(s->next_picture.f = av_frame_alloc()) ||
!(s->last_picture.f = av_frame_alloc()) ||
!(s->current_picture.f = av_frame_alloc()) ||
!(s->new_picture.f = av_frame_alloc()))
return AVERROR(ENOMEM);
goto fail_nomem;

if ((ret = init_context_frame(s)))
return AVERROR(ENOMEM);
goto fail;

s->parse_context.state = -1;

s->context_initialized = 1;
memset(s->thread_context, 0, sizeof(s->thread_context));
s->thread_context[0] = s;
s->slice_context_count = nb_slices;

// if (s->width && s->height) {
if (nb_slices > 1) {
for (i = 0; i < nb_slices; i++) {
if (i) {
s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));
if (!s->thread_context[i])
return AVERROR(ENOMEM);
}
if ((ret = init_duplicate_context(s->thread_context[i])) < 0)
return ret;
s->thread_context[i]->start_mb_y =
(s->mb_height * (i) + nb_slices / 2) / nb_slices;
s->thread_context[i]->end_mb_y =
(s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
}
} else {
if ((ret = init_duplicate_context(s)) < 0)
return ret;
s->start_mb_y = 0;
s->end_mb_y = s->mb_height;
}
s->slice_context_count = nb_slices;
ret = init_duplicate_contexts(s);
if (ret < 0)
goto fail;
// }

return 0;
fail_nomem:
ret = AVERROR(ENOMEM);
fail:
ff_mpv_common_end(s);
return ret;
}

/**
* Frees and resets MpegEncContext fields depending on the resolution.
* Frees and resets MpegEncContext fields depending on the resolution
* as well as the slice thread contexts.
* Is used during resolution changes to avoid a full reinitialization of the
* codec.
*/
static void free_context_frame(MpegEncContext *s)
{
int i, j, k;

free_duplicate_contexts(s);

av_freep(&s->mb_type);
av_freep(&s->p_mv_table_base);
av_freep(&s->b_forw_mv_table_base);
Expand Down Expand Up @@ -1038,16 +1059,6 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)
if (!s->context_initialized)
return AVERROR(EINVAL);

if (s->slice_context_count > 1) {
for (i = 0; i < s->slice_context_count; i++) {
free_duplicate_context(s->thread_context[i]);
}
for (i = 1; i < s->slice_context_count; i++) {
av_freep(&s->thread_context[i]);
}
} else
free_duplicate_context(s);

free_context_frame(s);

if (s->picture)
Expand All @@ -1067,42 +1078,33 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)

if ((s->width || s->height) &&
(err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0)
return err;
goto fail;

/* set chroma shifts */
err = av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
&s->chroma_x_shift,
&s->chroma_y_shift);
if (err < 0)
goto fail;

if ((err = init_context_frame(s)))
return err;
goto fail;

memset(s->thread_context, 0, sizeof(s->thread_context));
s->thread_context[0] = s;

if (s->width && s->height) {
int nb_slices = s->slice_context_count;
if (nb_slices > 1) {
for (i = 0; i < nb_slices; i++) {
if (i) {
s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));
if (!s->thread_context[i]) {
return AVERROR(ENOMEM);
}
}
if ((err = init_duplicate_context(s->thread_context[i])) < 0)
return err;
s->thread_context[i]->start_mb_y =
(s->mb_height * (i) + nb_slices / 2) / nb_slices;
s->thread_context[i]->end_mb_y =
(s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
}
} else {
err = init_duplicate_context(s);
if (err < 0)
return err;
s->start_mb_y = 0;
s->end_mb_y = s->mb_height;
}
s->slice_context_count = nb_slices;
err = init_duplicate_contexts(s);
if (err < 0)
goto fail;
}
s->context_reinit = 0;

return 0;
fail:
free_context_frame(s);
s->context_reinit = 1;
return err;
}

/* init common structure for both encoder and decoder */
Expand All @@ -1113,15 +1115,9 @@ void ff_mpv_common_end(MpegEncContext *s)
if (!s)
return;

if (s->slice_context_count > 1) {
for (i = 0; i < s->slice_context_count; i++) {
free_duplicate_context(s->thread_context[i]);
}
for (i = 1; i < s->slice_context_count; i++) {
av_freep(&s->thread_context[i]);
}
free_context_frame(s);
if (s->slice_context_count > 1)
s->slice_context_count = 1;
} else free_duplicate_context(s);

av_freep(&s->parse_context.buffer);
s->parse_context.buffer_size = 0;
Expand Down Expand Up @@ -1153,9 +1149,8 @@ void ff_mpv_common_end(MpegEncContext *s)
ff_mpeg_unref_picture(s->avctx, &s->new_picture);
av_frame_free(&s->new_picture.f);

free_context_frame(s);

s->context_initialized = 0;
s->context_reinit = 0;
s->last_picture_ptr =
s->next_picture_ptr =
s->current_picture_ptr = NULL;
Expand Down
24 changes: 18 additions & 6 deletions libavcodec/mpegvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -662,24 +662,36 @@ FF_MPV_OPT_CMP_FUNC, \
{ "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \
{ "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \
{ "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \
{ "force_duplicated_matrix", "Always write luma and chroma matrix for mjpeg, useful for rtp streaming.", FF_MPV_OFFSET(force_duplicated_matrix), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS }, \
{"b_strategy", "Strategy to choose between I/P/B-frames", FF_MPV_OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, FF_MPV_OPT_FLAGS }, \
{"b_sensitivity", "Adjust sensitivity of b_frame_strategy 1", FF_MPV_OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"brd_scale", "Downscale frames for dynamic B-frame decision", FF_MPV_OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 3, FF_MPV_OPT_FLAGS }, \
{"skip_threshold", "Frame skip threshold", FF_MPV_OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"skip_factor", "Frame skip factor", FF_MPV_OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"skip_exp", "Frame skip exponent", FF_MPV_OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"skip_cmp", "Frame skip compare function", FF_MPV_OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{"sc_threshold", "Scene change threshold", FF_MPV_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"noise_reduction", "Noise reduction", FF_MPV_OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"mpeg_quant", "Use MPEG quantizers instead of H.263", FF_MPV_OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS }, \
{"ps", "RTP payload size in bytes", FF_MPV_OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"mepc", "Motion estimation bitrate penalty compensation (1.0 = 256)", FF_MPV_OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"mepre", "pre motion estimation", FF_MPV_OFFSET(me_pre), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"intra_penalty", "Penalty for intra blocks in block decision", FF_MPV_OFFSET(intra_penalty), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX/2, FF_MPV_OPT_FLAGS }, \
{"a53cc", "Use A53 Closed Captions (if available)", FF_MPV_OFFSET(a53_cc), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FF_MPV_OPT_FLAGS }, \
FF_MPV_RC_STRATEGY_OPTS

#define FF_MPV_COMMON_BFRAME_OPTS \
{"b_strategy", "Strategy to choose between I/P/B-frames", FF_MPV_OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, FF_MPV_OPT_FLAGS }, \
{"b_sensitivity", "Adjust sensitivity of b_frame_strategy 1", FF_MPV_OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"brd_scale", "Downscale frames for dynamic B-frame decision", FF_MPV_OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 3, FF_MPV_OPT_FLAGS },

#if FF_API_MPEGVIDEO_OPTS
#define FF_MPV_DEPRECATED_MPEG_QUANT_OPT \
{ "mpeg_quant", "Deprecated, does nothing", FF_MPV_OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 0, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED },
#define FF_MPV_DEPRECATED_A53_CC_OPT \
{ "a53cc", "Deprecated, does nothing", FF_MPV_OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED },
#define FF_MPV_DEPRECATED_MATRIX_OPT \
{ "force_duplicated_matrix", "Deprecated, does nothing", FF_MPV_OFFSET(force_duplicated_matrix), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED },
#define FF_MPV_DEPRECATED_BFRAME_OPTS \
{ "b_strategy", "Deprecated, does nothing", FF_MPV_OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED }, \
{ "b_sensitivity", "Deprecated, does nothing", FF_MPV_OFFSET(b_sensitivity), AV_OPT_TYPE_INT, { .i64 = 40 }, 1, INT_MAX, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED }, \
{ "brd_scale", "Deprecated, does nothing", FF_MPV_OFFSET(brd_scale), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 3, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED },
#endif

extern const AVOption ff_mpv_generic_options[];

/**
Expand Down
156 changes: 52 additions & 104 deletions libavcodec/mpegvideo_enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ static uint8_t default_fcode_tab[MAX_MV * 2 + 1];

const AVOption ff_mpv_generic_options[] = {
FF_MPV_COMMON_OPTS
#if FF_API_MPEGVIDEO_OPTS
FF_MPV_DEPRECATED_MPEG_QUANT_OPT
FF_MPV_DEPRECATED_A53_CC_OPT
FF_MPV_DEPRECATED_MATRIX_OPT
FF_MPV_DEPRECATED_BFRAME_OPTS
#endif
{ NULL },
};

Expand Down Expand Up @@ -297,59 +303,10 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
AVCPBProperties *cpb_props;
int i, ret, format_supported;
int i, ret;

mpv_encode_defaults(s);

switch (avctx->codec_id) {
case AV_CODEC_ID_MPEG2VIDEO:
if (avctx->pix_fmt != AV_PIX_FMT_YUV420P &&
avctx->pix_fmt != AV_PIX_FMT_YUV422P) {
av_log(avctx, AV_LOG_ERROR,
"only YUV420 and YUV422 are supported\n");
return AVERROR(EINVAL);
}
break;
case AV_CODEC_ID_MJPEG:
case AV_CODEC_ID_AMV:
format_supported = 0;
/* JPEG color space */
if (avctx->pix_fmt == AV_PIX_FMT_YUVJ420P ||
avctx->pix_fmt == AV_PIX_FMT_YUVJ422P ||
avctx->pix_fmt == AV_PIX_FMT_YUVJ444P ||
(avctx->color_range == AVCOL_RANGE_JPEG &&
(avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
avctx->pix_fmt == AV_PIX_FMT_YUV444P)))
format_supported = 1;
/* MPEG color space */
else if (avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL &&
(avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
avctx->pix_fmt == AV_PIX_FMT_YUV444P))
format_supported = 1;

if (!format_supported) {
av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n");
return AVERROR(EINVAL);
}
break;
case AV_CODEC_ID_SPEEDHQ:
if (avctx->pix_fmt != AV_PIX_FMT_YUV420P &&
avctx->pix_fmt != AV_PIX_FMT_YUV422P &&
avctx->pix_fmt != AV_PIX_FMT_YUV444P) {
av_log(avctx, AV_LOG_ERROR,
"only YUV420/YUV422/YUV444 are supported (no alpha support yet)\n");
return AVERROR(EINVAL);
}
break;
default:
if (avctx->pix_fmt != AV_PIX_FMT_YUV420P) {
av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n");
return AVERROR(EINVAL);
}
}

switch (avctx->pix_fmt) {
case AV_PIX_FMT_YUVJ444P:
case AV_PIX_FMT_YUV444P:
Expand Down Expand Up @@ -576,24 +533,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
return AVERROR(EINVAL);
}
if ((s->codec_id == AV_CODEC_ID_H263 ||
s->codec_id == AV_CODEC_ID_H263P) &&
s->codec_id == AV_CODEC_ID_H263P ||
s->codec_id == AV_CODEC_ID_RV20) &&
((avctx->width &3) ||
(avctx->height&3) )) {
av_log(avctx, AV_LOG_ERROR, "w/h must be a multiple of 4\n");
return AVERROR(EINVAL);
}

if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO &&
(avctx->width > 4095 ||
avctx->height > 4095 )) {
av_log(avctx, AV_LOG_ERROR, "MPEG-1 does not support resolutions above 4095x4095\n");
return AVERROR(EINVAL);
}

if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
(avctx->width > 16383 ||
avctx->height > 16383 )) {
av_log(avctx, AV_LOG_ERROR, "MPEG-2 does not support resolutions above 16383x16383\n");
av_log(avctx, AV_LOG_ERROR, "width and height must be a multiple of 4\n");
return AVERROR(EINVAL);
}

Expand All @@ -604,13 +548,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
return AVERROR(EINVAL);
}

if (s->codec_id == AV_CODEC_ID_RV20 &&
(avctx->width &3 ||
avctx->height&3 )) {
av_log(avctx, AV_LOG_ERROR, "width and height must be a multiple of 4\n");
return AVERROR(EINVAL);
}

if ((s->codec_id == AV_CODEC_ID_WMV1 ||
s->codec_id == AV_CODEC_ID_WMV2) &&
avctx->width & 1) {
Expand All @@ -627,17 +564,16 @@ FF_ENABLE_DEPRECATION_WARNINGS
#if FF_API_PRIVATE_OPT
FF_DISABLE_DEPRECATION_WARNINGS
if (avctx->mpeg_quant)
s->mpeg_quant = avctx->mpeg_quant;
s->mpeg_quant = 1;
FF_ENABLE_DEPRECATION_WARNINGS
#endif

// FIXME mpeg2 uses that too
if (s->mpeg_quant && ( s->codec_id != AV_CODEC_ID_MPEG4
&& s->codec_id != AV_CODEC_ID_MPEG2VIDEO)) {
av_log(avctx, AV_LOG_ERROR,
"mpeg2 style quantization not supported by codec\n");
return AVERROR(EINVAL);
}
#endif

if ((s->mpv_flags & FF_MPV_FLAG_CBP_RD) && !avctx->trellis) {
av_log(avctx, AV_LOG_ERROR, "CBP RD needs trellis quant\n");
Expand Down Expand Up @@ -721,11 +657,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
return AVERROR_PATCHWELCOME;
}

if (!avctx->time_base.den || !avctx->time_base.num) {
av_log(avctx, AV_LOG_ERROR, "framerate not set\n");
return AVERROR(EINVAL);
}

#if FF_API_PRIVATE_OPT
FF_DISABLE_DEPRECATION_WARNINGS
if (avctx->b_frame_strategy)
Expand Down Expand Up @@ -789,17 +720,17 @@ FF_ENABLE_DEPRECATION_WARNINGS
avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1);
s->rtp_mode = 1;
break;
#if CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER
case AV_CODEC_ID_MJPEG:
case AV_CODEC_ID_AMV:
s->out_format = FMT_MJPEG;
s->intra_only = 1; /* force intra only for jpeg */
if (!CONFIG_MJPEG_ENCODER)
return AVERROR_ENCODER_NOT_FOUND;
if ((ret = ff_mjpeg_encode_init(s)) < 0)
return ret;
avctx->delay = 0;
s->low_delay = 1;
break;
#endif
case AV_CODEC_ID_SPEEDHQ:
s->out_format = FMT_SPEEDHQ;
s->intra_only = 1; /* force intra only for SHQ */
Expand Down Expand Up @@ -1008,8 +939,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (CONFIG_H263_ENCODER && s->out_format == FMT_H263)
ff_h263_encode_init(s);
if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version)
if ((ret = ff_msmpeg4_encode_init(s)) < 0)
return ret;
ff_msmpeg4_encode_init(s);
if ((CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
&& s->out_format == FMT_MPEG1)
ff_mpeg1_encode_init(s);
Expand Down Expand Up @@ -1098,7 +1028,7 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
ff_rate_control_uninit(s);

ff_mpv_common_end(s);
if (CONFIG_MJPEG_ENCODER &&
if ((CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER) &&
s->out_format == FMT_MJPEG)
ff_mjpeg_encode_close(s);

Expand Down Expand Up @@ -1696,7 +1626,8 @@ static int select_input_picture(MpegEncContext *s)
// input is not a shared pix -> reuse buffer for current_pix
s->current_picture_ptr = s->reordered_input_picture[0];
for (i = 0; i < 4; i++) {
s->new_picture.f->data[i] += INPLACE_OFFSET;
if (s->new_picture.f->data[i])
s->new_picture.f->data[i] += INPLACE_OFFSET;
}
}
ff_mpeg_unref_picture(s->avctx, &s->current_picture);
Expand Down Expand Up @@ -1926,7 +1857,7 @@ FF_ENABLE_DEPRECATION_WARNINGS

frame_end(s);

if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG)
if ((CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER) && s->out_format == FMT_MJPEG)
ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits);

if (avctx->rc_buffer_size) {
Expand Down Expand Up @@ -1993,8 +1924,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
stuffing_count = ff_vbv_update(s, s->frame_bits);
s->stuffing_bits = 8*stuffing_count;
if (stuffing_count) {
if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) <
stuffing_count + 50) {
if (put_bytes_left(&s->pb, 0) < stuffing_count + 50) {
av_log(avctx, AV_LOG_ERROR, "stuffing too large\n");
return -1;
}
Expand Down Expand Up @@ -2597,11 +2527,12 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
if (CONFIG_H263_ENCODER)
ff_h263_encode_mb(s, s->block, motion_x, motion_y);
break;
#if CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER
case AV_CODEC_ID_MJPEG:
case AV_CODEC_ID_AMV:
if (CONFIG_MJPEG_ENCODER)
ff_mjpeg_encode_mb(s, s->block);
ff_mjpeg_encode_mb(s, s->block);
break;
#endif
case AV_CODEC_ID_SPEEDHQ:
if (CONFIG_SPEEDHQ_ENCODER)
ff_speedhq_encode_mb(s, s->block);
Expand Down Expand Up @@ -2854,7 +2785,8 @@ static void write_slice_end(MpegEncContext *s){
}

ff_mpeg4_stuffing(&s->pb);
}else if(CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG){
} else if ((CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER) &&
s->out_format == FMT_MJPEG) {
ff_mjpeg_encode_stuffing(s);
} else if (CONFIG_SPEEDHQ_ENCODER && s->out_format == FMT_SPEEDHQ) {
ff_speedhq_end_slice(s);
Expand Down Expand Up @@ -2890,28 +2822,28 @@ static void update_mb_info(MpegEncContext *s, int startcode)
{
if (!s->mb_info)
return;
if (put_bits_count(&s->pb) - s->prev_mb_info*8 >= s->mb_info*8) {
if (put_bytes_count(&s->pb, 0) - s->prev_mb_info >= s->mb_info) {
s->mb_info_size += 12;
s->prev_mb_info = s->last_mb_info;
}
if (startcode) {
s->prev_mb_info = put_bits_count(&s->pb)/8;
s->prev_mb_info = put_bytes_count(&s->pb, 0);
/* This might have incremented mb_info_size above, and we return without
* actually writing any info into that slot yet. But in that case,
* this will be called again at the start of the after writing the
* start code, actually writing the mb info. */
return;
}

s->last_mb_info = put_bits_count(&s->pb)/8;
s->last_mb_info = put_bytes_count(&s->pb, 0);
if (!s->mb_info_size)
s->mb_info_size += 12;
write_mb_info(s);
}

int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t size_increase)
{
if ( s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < threshold
if (put_bytes_left(&s->pb, 0) < threshold
&& s->slice_context_count == 1
&& s->pb.buf == s->avctx->internal->byte_buffer) {
int lastgob_pos = s->ptr_lastgob - s->pb.buf;
Expand Down Expand Up @@ -2940,7 +2872,7 @@ int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t s
s->ptr_lastgob = s->pb.buf + lastgob_pos;
s->vbv_delay_ptr = s->pb.buf + vbv_pos;
}
if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < threshold)
if (put_bytes_left(&s->pb, 0) < threshold)
return AVERROR(EINVAL);
return 0;
}
Expand Down Expand Up @@ -3032,13 +2964,13 @@ static int encode_thread(AVCodecContext *c, void *arg){
+ s->mb_width*MAX_MB_BYTES;

ff_mpv_reallocate_putbitbuffer(s, MAX_MB_BYTES, size_increase);
if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){
if (put_bytes_left(&s->pb, 0) < MAX_MB_BYTES){
av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
return -1;
}
if(s->data_partitioning){
if( s->pb2 .buf_end - s->pb2 .buf - (put_bits_count(&s-> pb2)>>3) < MAX_MB_BYTES
|| s->tex_pb.buf_end - s->tex_pb.buf - (put_bits_count(&s->tex_pb )>>3) < MAX_MB_BYTES){
if (put_bytes_left(&s->pb2, 0) < MAX_MB_BYTES ||
put_bytes_left(&s->tex_pb, 0) < MAX_MB_BYTES) {
av_log(s->avctx, AV_LOG_ERROR, "encoded partitioned frame too large\n");
return -1;
}
Expand All @@ -3058,7 +2990,8 @@ static int encode_thread(AVCodecContext *c, void *arg){
if(s->rtp_mode){
int current_packet_size, is_gob_start;

current_packet_size= ((put_bits_count(&s->pb)+7)>>3) - (s->ptr_lastgob - s->pb.buf);
current_packet_size = put_bytes_count(&s->pb, 1)
- (s->ptr_lastgob - s->pb.buf);

is_gob_start = s->rtp_payload_size &&
current_packet_size >= s->rtp_payload_size &&
Expand Down Expand Up @@ -3095,7 +3028,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
current_packet_size= put_bits_ptr(&s->pb) - s->ptr_lastgob;

if (s->error_rate && s->resync_mb_x + s->resync_mb_y > 0) {
int r= put_bits_count(&s->pb)/8 + s->picture_number + 16 + s->mb_x + s->mb_y;
int r = put_bytes_count(&s->pb, 0) + s->picture_number + 16 + s->mb_x + s->mb_y;
int d = 100 / s->error_rate;
if(r % d == 0){
current_packet_size=0;
Expand Down Expand Up @@ -3921,11 +3854,14 @@ static int encode_picture(MpegEncContext *s, int picture_number)
s->mb_x = s->mb_y = 0;
s->last_bits= put_bits_count(&s->pb);
switch(s->out_format) {
#if CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER
case FMT_MJPEG:
if (CONFIG_MJPEG_ENCODER && s->huffman != HUFFMAN_TABLE_OPTIMAL)
/* s->huffman == HUFFMAN_TABLE_OPTIMAL can only be true for MJPEG. */
if (!CONFIG_MJPEG_ENCODER || s->huffman != HUFFMAN_TABLE_OPTIMAL)
ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable,
s->pred, s->intra_matrix, s->chroma_intra_matrix);
break;
#endif
case FMT_SPEEDHQ:
if (CONFIG_SPEEDHQ_ENCODER)
ff_speedhq_encode_picture_header(s);
Expand Down Expand Up @@ -4777,6 +4713,12 @@ static const AVOption h263_options[] = {
{ "obmc", "use overlapped block motion compensation.", OFFSET(obmc), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "mb_info", "emit macroblock info for RFC 2190 packetization, the parameter value is the maximum payload size", OFFSET(mb_info), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
FF_MPV_COMMON_OPTS
#if FF_API_MPEGVIDEO_OPTS
FF_MPV_DEPRECATED_MPEG_QUANT_OPT
FF_MPV_DEPRECATED_A53_CC_OPT
FF_MPV_DEPRECATED_MATRIX_OPT
FF_MPV_DEPRECATED_BFRAME_OPTS
#endif
{ NULL },
};

Expand Down Expand Up @@ -4807,6 +4749,12 @@ static const AVOption h263p_options[] = {
{ "obmc", "use overlapped block motion compensation.", OFFSET(obmc), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "structured_slices", "Write slice start position at every GOB header instead of just GOB number.", OFFSET(h263_slice_structured), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
FF_MPV_COMMON_OPTS
#if FF_API_MPEGVIDEO_OPTS
FF_MPV_DEPRECATED_MPEG_QUANT_OPT
FF_MPV_DEPRECATED_A53_CC_OPT
FF_MPV_DEPRECATED_MATRIX_OPT
FF_MPV_DEPRECATED_BFRAME_OPTS
#endif
{ NULL },
};
static const AVClass h263p_class = {
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/msmpeg4.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my);
int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n,
uint8_t **coded_block_ptr);

int ff_msmpeg4_encode_init(MpegEncContext *s);
void ff_msmpeg4_encode_init(MpegEncContext *s);
void ff_msmpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
void ff_msmpeg4_encode_ext_header(MpegEncContext *s);
void ff_msmpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
Expand Down
30 changes: 14 additions & 16 deletions libavcodec/msmpeg4dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,18 +356,16 @@ av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx)
&ff_v2_mb_type[0][1], 2, 1,
&ff_v2_mb_type[0][0], 2, 1, 128);

INIT_VLC_STATIC(&ff_mb_non_intra_vlc[0], MB_NON_INTRA_VLC_BITS, 128,
&ff_wmv2_inter_table[0][0][1], 8, 4,
&ff_wmv2_inter_table[0][0][0], 8, 4, 1636);
INIT_VLC_STATIC(&ff_mb_non_intra_vlc[1], MB_NON_INTRA_VLC_BITS, 128,
&ff_wmv2_inter_table[1][0][1], 8, 4,
&ff_wmv2_inter_table[1][0][0], 8, 4, 2648);
INIT_VLC_STATIC(&ff_mb_non_intra_vlc[2], MB_NON_INTRA_VLC_BITS, 128,
&ff_wmv2_inter_table[2][0][1], 8, 4,
&ff_wmv2_inter_table[2][0][0], 8, 4, 1532);
INIT_VLC_STATIC(&ff_mb_non_intra_vlc[3], MB_NON_INTRA_VLC_BITS, 128,
&ff_wmv2_inter_table[3][0][1], 8, 4,
&ff_wmv2_inter_table[3][0][0], 8, 4, 2488);
for (unsigned i = 0, offset = 0; i < 4; i++) {
static VLC_TYPE vlc_buf[1636 + 2648 + 1532 + 2488][2];
ff_mb_non_intra_vlc[i].table = &vlc_buf[offset];
ff_mb_non_intra_vlc[i].table_allocated = FF_ARRAY_ELEMS(vlc_buf) - offset;
init_vlc(&ff_mb_non_intra_vlc[i], MB_NON_INTRA_VLC_BITS, 128,
&ff_wmv2_inter_table[i][0][1], 8, 4,
&ff_wmv2_inter_table[i][0][0], 8, 4,
INIT_VLC_STATIC_OVERLONG);
offset += ff_mb_non_intra_vlc[i].table_size;
}

INIT_VLC_STATIC(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64,
&ff_msmp4_mb_i_table[0][1], 4, 2,
Expand Down Expand Up @@ -870,7 +868,7 @@ AVCodec ff_msmpeg4v1_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
Expand All @@ -888,7 +886,7 @@ AVCodec ff_msmpeg4v2_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
Expand All @@ -906,7 +904,7 @@ AVCodec ff_msmpeg4v3_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
Expand All @@ -924,7 +922,7 @@ AVCodec ff_wmv1_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
Expand Down
46 changes: 12 additions & 34 deletions libavcodec/msmpeg4enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

#include "libavutil/attributes.h"
#include "libavutil/avutil.h"
#include "libavutil/mem.h"
#include "mpegvideo.h"
#include "h263.h"
#include "internal.h"
Expand All @@ -46,13 +45,11 @@
static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];

/* build the table which associate a (x,y) motion vector to a vlc */
static av_cold int init_mv_table(MVTable *tab)
static av_cold void init_mv_table(MVTable *tab, uint16_t table_mv_index[4096])
{
int i, x, y;

tab->table_mv_index = av_malloc(sizeof(uint16_t) * 4096);
if (!tab->table_mv_index)
return AVERROR(ENOMEM);
tab->table_mv_index = table_mv_index;

/* mark all entries as not used */
for(i=0;i<4096;i++)
Expand All @@ -63,8 +60,6 @@ static av_cold int init_mv_table(MVTable *tab)
y = tab->table_mvy[i];
tab->table_mv_index[(x << 6) | y] = i;
}

return 0;
}

void ff_msmpeg4_code012(PutBitContext *pb, int n)
Expand Down Expand Up @@ -118,10 +113,10 @@ static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run,
return size;
}

av_cold int ff_msmpeg4_encode_init(MpegEncContext *s)
av_cold void ff_msmpeg4_encode_init(MpegEncContext *s)
{
static int init_done=0;
int i, ret;
int i;

ff_msmpeg4_common_init(s);
if(s->msmpeg4_version>=4){
Expand All @@ -130,12 +125,12 @@ av_cold int ff_msmpeg4_encode_init(MpegEncContext *s)
}

if (!init_done) {
static uint16_t mv_index_tables[2][4096];
/* init various encoding tables */
init_done = 1;
if ((ret = init_mv_table(&ff_mv_tables[0])) < 0)
return ret;
if ((ret = init_mv_table(&ff_mv_tables[1])) < 0)
return ret;
init_mv_table(&ff_mv_tables[0], mv_index_tables[0]);
init_mv_table(&ff_mv_tables[1], mv_index_tables[1]);

for(i=0;i<NB_RL_TABLES;i++)
ff_rl_init(&ff_rl_table[i], ff_static_rl_table_store[i]);

Expand All @@ -152,8 +147,6 @@ av_cold int ff_msmpeg4_encode_init(MpegEncContext *s)
}
}
}

return 0;
}

static void find_best_tables(MpegEncContext * s)
Expand Down Expand Up @@ -499,8 +492,7 @@ void ff_msmpeg4_encode_mb(MpegEncContext * s,
static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr)
{
int sign, code;
int pred, av_uninit(extquant);
int extrabits = 0;
int pred;

int16_t *dc_val;
pred = ff_msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
Expand Down Expand Up @@ -534,15 +526,6 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr
code = level;
if (code > DC_MAX)
code = DC_MAX;
else if( s->msmpeg4_version>=6 ) {
if( s->qscale == 1 ) {
extquant = (level + 3) & 0x3;
code = ((level+3)>>2);
} else if( s->qscale == 2 ) {
extquant = (level + 1) & 0x1;
code = ((level+1)>>1);
}
}

if (s->dc_table_index == 0) {
if (n < 4) {
Expand All @@ -558,13 +541,8 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr
}
}

if(s->msmpeg4_version>=6 && s->qscale<=2)
extrabits = 3 - s->qscale;

if (code == DC_MAX)
put_bits(&s->pb, 8 + extrabits, level);
else if(extrabits > 0)//== VC1 && s->qscale<=2
put_bits(&s->pb, extrabits, extquant);
put_bits(&s->pb, 8, level);

if (level != 0) {
put_bits(&s->pb, 1, sign);
Expand Down Expand Up @@ -603,7 +581,7 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
}

/* recalculate block_last_index for M$ wmv1 */
if(s->msmpeg4_version>=4 && s->msmpeg4_version<6 && s->block_last_index[n]>0){
if (s->msmpeg4_version >= 4 && s->block_last_index[n] > 0) {
for(last_index=63; last_index>=0; last_index--){
if(block[scantable[last_index]]) break;
}
Expand Down Expand Up @@ -663,7 +641,7 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
s->esc3_run_length= 6;
//ESCLVLSZ + ESCRUNSZ
if(s->qscale<8)
put_bits(&s->pb, 6 + (s->msmpeg4_version>=6), 3);
put_bits(&s->pb, 6, 3);
else
put_bits(&s->pb, 8, 3);
}
Expand Down
1 change: 1 addition & 0 deletions libavcodec/msp2dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static int msp2_decode_frame(AVCodecContext *avctx,
while (bytestream2_get_bytes_left(&gb) && x < width) {
int size = bytestream2_get_byte(&gb);
if (size) {
size = FFMIN(size, bytestream2_get_bytes_left(&gb));
memcpy(p->data[0] + y * p->linesize[0] + x, gb.buffer, FFMIN(size, width - x));
bytestream2_skip(&gb, size);
} else {
Expand Down
17 changes: 10 additions & 7 deletions libavcodec/mss12.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,14 +291,15 @@ static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx,
return decode_pixel(acoder, pctx, ref_pix, nlen, 1);
}

static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic,
static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_dst,
int x, int y, int width, int height, ptrdiff_t stride,
ptrdiff_t rgb_stride, PixContext *pctx,
const uint32_t *pal)
{
int i, j, p;
uint8_t *rgb_dst = rgb_pic + x * 3 + y * rgb_stride;

rgb_stride = rgb_dst ? rgb_stride : 0;
rgb_dst = rgb_dst ? rgb_dst + x * 3 + y * rgb_stride : NULL;
dst += x + y * stride;

for (j = 0; j < height; j++) {
Expand All @@ -312,11 +313,11 @@ static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic,
return p;
dst[i] = p;

if (rgb_pic)
if (rgb_dst)
AV_WB24(rgb_dst + i * 3, pal[p]);
}
dst += stride;
rgb_dst += rgb_stride;
rgb_dst = FF_PTR_ADD(rgb_dst, rgb_stride);
}

return 0;
Expand Down Expand Up @@ -476,17 +477,19 @@ static int decode_region_intra(SliceContext *sc, ArithCoder *acoder,
ptrdiff_t stride = c->pal_stride;
ptrdiff_t rgb_stride = c->rgb_stride;
uint8_t *dst = c->pal_pic + x + y * stride;
uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * rgb_stride;
uint8_t *rgb_dst = c->rgb_pic ? c->rgb_pic + x * 3 + y * rgb_stride : NULL;

pix = decode_pixel(acoder, &sc->intra_pix_ctx, NULL, 0, 0);
if (pix < 0)
return pix;
rgb_pix = c->pal[pix];
for (i = 0; i < height; i++, dst += stride, rgb_dst += rgb_stride) {
for (i = 0; i < height; i++, dst += stride) {
memset(dst, pix, width);
if (c->rgb_pic)
if (rgb_dst) {
for (j = 0; j < width * 3; j += 3)
AV_WB24(rgb_dst + j, rgb_pix);
rgb_dst += rgb_stride;
}
}
} else {
return decode_region(acoder, c->pal_pic, c->rgb_pic,
Expand Down
4 changes: 1 addition & 3 deletions libavcodec/mss2.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,9 +751,7 @@ static av_cold int wmv9_init(AVCodecContext *avctx)

v->s.avctx = avctx;

if ((ret = ff_vc1_init_common(v)) < 0)
return ret;
ff_vc1dsp_init(&v->vc1dsp);
ff_vc1_init_common(v);

v->profile = PROFILE_MAIN;

Expand Down
30 changes: 20 additions & 10 deletions libavcodec/nvenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ const enum AVPixelFormat ff_nvenc_pix_fmts[] = {
AV_PIX_FMT_YUV444P16, // Truncated to 10bits
AV_PIX_FMT_0RGB32,
AV_PIX_FMT_0BGR32,
AV_PIX_FMT_GBRP,
AV_PIX_FMT_GBRP16, // Truncated to 10bits
AV_PIX_FMT_CUDA,
#if CONFIG_D3D11VA
AV_PIX_FMT_D3D11,
Expand All @@ -69,12 +71,18 @@ const AVCodecHWConfigInternal *const ff_nvenc_hw_configs[] = {
NULL,
};

#define IS_10BIT(pix_fmt) (pix_fmt == AV_PIX_FMT_P010 || \
pix_fmt == AV_PIX_FMT_P016 || \
pix_fmt == AV_PIX_FMT_YUV444P16)
#define IS_10BIT(pix_fmt) (pix_fmt == AV_PIX_FMT_P010 || \
pix_fmt == AV_PIX_FMT_P016 || \
pix_fmt == AV_PIX_FMT_YUV444P16 || \
pix_fmt == AV_PIX_FMT_GBRP16)

#define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P || \
pix_fmt == AV_PIX_FMT_YUV444P16)
#define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P || \
pix_fmt == AV_PIX_FMT_YUV444P16 || \
pix_fmt == AV_PIX_FMT_GBRP || \
pix_fmt == AV_PIX_FMT_GBRP16)

#define IS_GBRP(pix_fmt) (pix_fmt == AV_PIX_FMT_GBRP || \
pix_fmt == AV_PIX_FMT_GBRP16)

static const struct {
NVENCSTATUS nverr;
Expand Down Expand Up @@ -1028,14 +1036,14 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
NV_ENC_CONFIG_H264 *h264 = &cc->encodeCodecConfig.h264Config;
NV_ENC_CONFIG_H264_VUI_PARAMETERS *vui = &h264->h264VUIParameters;

vui->colourMatrix = avctx->colorspace;
vui->colourMatrix = IS_GBRP(ctx->data_pix_fmt) ? AVCOL_SPC_RGB : avctx->colorspace;
vui->colourPrimaries = avctx->color_primaries;
vui->transferCharacteristics = avctx->color_trc;
vui->videoFullRangeFlag = (avctx->color_range == AVCOL_RANGE_JPEG
|| ctx->data_pix_fmt == AV_PIX_FMT_YUVJ420P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ422P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ444P);

vui->colourDescriptionPresentFlag =
(avctx->colorspace != 2 || avctx->color_primaries != 2 || avctx->color_trc != 2);
(vui->colourMatrix != 2 || vui->colourPrimaries != 2 || vui->transferCharacteristics != 2);

vui->videoSignalTypePresentFlag =
(vui->colourDescriptionPresentFlag
Expand Down Expand Up @@ -1094,7 +1102,7 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
}

// force setting profile as high444p if input is AV_PIX_FMT_YUV444P
if (ctx->data_pix_fmt == AV_PIX_FMT_YUV444P) {
if (IS_YUV444(ctx->data_pix_fmt)) {
cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
avctx->profile = FF_PROFILE_H264_HIGH_444_PREDICTIVE;
}
Expand Down Expand Up @@ -1125,14 +1133,14 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
NV_ENC_CONFIG_HEVC *hevc = &cc->encodeCodecConfig.hevcConfig;
NV_ENC_CONFIG_HEVC_VUI_PARAMETERS *vui = &hevc->hevcVUIParameters;

vui->colourMatrix = avctx->colorspace;
vui->colourMatrix = IS_GBRP(ctx->data_pix_fmt) ? AVCOL_SPC_RGB : avctx->colorspace;
vui->colourPrimaries = avctx->color_primaries;
vui->transferCharacteristics = avctx->color_trc;
vui->videoFullRangeFlag = (avctx->color_range == AVCOL_RANGE_JPEG
|| ctx->data_pix_fmt == AV_PIX_FMT_YUVJ420P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ422P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ444P);

vui->colourDescriptionPresentFlag =
(avctx->colorspace != 2 || avctx->color_primaries != 2 || avctx->color_trc != 2);
(vui->colourMatrix != 2 || vui->colourPrimaries != 2 || vui->transferCharacteristics != 2);

vui->videoSignalTypePresentFlag =
(vui->colourDescriptionPresentFlag
Expand Down Expand Up @@ -1406,8 +1414,10 @@ static NV_ENC_BUFFER_FORMAT nvenc_map_buffer_format(enum AVPixelFormat pix_fmt)
case AV_PIX_FMT_P010:
case AV_PIX_FMT_P016:
return NV_ENC_BUFFER_FORMAT_YUV420_10BIT;
case AV_PIX_FMT_GBRP:
case AV_PIX_FMT_YUV444P:
return NV_ENC_BUFFER_FORMAT_YUV444_PL;
case AV_PIX_FMT_GBRP16:
case AV_PIX_FMT_YUV444P16:
return NV_ENC_BUFFER_FORMAT_YUV444_10BIT;
case AV_PIX_FMT_0RGB32:
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
static const char* context_to_name(void* ptr) {
AVCodecContext *avc= ptr;

if(avc && avc->codec && avc->codec->name)
if (avc && avc->codec)
return avc->codec->name;
else
return "NULL";
Expand Down
409 changes: 235 additions & 174 deletions libavcodec/pngdec.c

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion libavcodec/pnm_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ static int pnm_parse(AVCodecParserContext *s, AVCodecContext *avctx,
} else {
int ret = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
next = pnmctx.bytestream - pnmctx.bytestream_start + skip;
if (ret >= 0)
if (ret >= 0 && next + (uint64_t)ret <= INT_MAX)
next += ret;
}
if (next != END_NOT_FOUND && pnmctx.bytestream_start != buf + skip)
Expand Down
14 changes: 8 additions & 6 deletions libavcodec/proresdec2.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,8 +623,8 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
AVFrame *pic = ctx->frame;
int i, hdr_size, qscale, log2_chroma_blocks_per_mb;
int luma_stride, chroma_stride;
int y_data_size, u_data_size, v_data_size, a_data_size;
uint8_t *dest_y, *dest_u, *dest_v, *dest_a;
int y_data_size, u_data_size, v_data_size, a_data_size, offset;
uint8_t *dest_y, *dest_u, *dest_v;
LOCAL_ALIGNED_16(int16_t, qmat_luma_scaled, [64]);
LOCAL_ALIGNED_16(int16_t, qmat_chroma_scaled,[64]);
int mb_x_shift;
Expand Down Expand Up @@ -676,16 +676,16 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
log2_chroma_blocks_per_mb = 1;
}

dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
offset = (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
dest_y = pic->data[0] + offset;
dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
dest_a = pic->data[3] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);

if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) {
dest_y += pic->linesize[0];
dest_u += pic->linesize[1];
dest_v += pic->linesize[2];
dest_a += pic->linesize[3];
offset += pic->linesize[3];
}

ret = decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride,
Expand Down Expand Up @@ -722,10 +722,12 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
}

/* decode alpha plane if available */
if (ctx->alpha_info && pic->data[3] && a_data_size)
if (ctx->alpha_info && pic->data[3] && a_data_size) {
uint8_t *dest_a = pic->data[3] + offset;
decode_slice_alpha(ctx, (uint16_t*)dest_a, luma_stride,
buf + y_data_size + u_data_size + v_data_size,
a_data_size, slice->mb_count);
}

slice->ret = 0;
return 0;
Expand Down
4 changes: 3 additions & 1 deletion libavcodec/proresenc_anatoliy.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ static av_always_inline int encode_alpha_slice_data(AVCodecContext *avctx, int8_
if (run)
put_alpha_run(&pb, run);
flush_put_bits(&pb);
*a_data_size = put_bits_count(&pb) >> 3;
*a_data_size = put_bytes_output(&pb);

if (put_bits_left(&pb) < 0) {
av_log(avctx, AV_LOG_ERROR,
Expand Down Expand Up @@ -957,6 +957,7 @@ AVCodec ff_prores_aw_encoder = {
.capabilities = AV_CODEC_CAP_FRAME_THREADS,
.priv_class = &proresaw_enc_class,
.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};

AVCodec ff_prores_encoder = {
Expand All @@ -972,4 +973,5 @@ AVCodec ff_prores_encoder = {
.capabilities = AV_CODEC_CAP_FRAME_THREADS,
.priv_class = &prores_enc_class,
.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
41 changes: 13 additions & 28 deletions libavcodec/proresenc_kostya.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,23 +464,17 @@ static void encode_acs(PutBitContext *pb, int16_t *blocks,
}
}

static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
static void encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
const uint16_t *src, ptrdiff_t linesize,
int mbs_per_slice, int16_t *blocks,
int blocks_per_mb, int plane_size_factor,
const int16_t *qmat)
{
int blocks_per_slice, saved_pos;

saved_pos = put_bits_count(pb);
blocks_per_slice = mbs_per_slice * blocks_per_mb;
int blocks_per_slice = mbs_per_slice * blocks_per_mb;

encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
ctx->scantable, qmat);
flush_put_bits(pb);

return (put_bits_count(pb) - saved_pos) >> 3;
}

static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
Expand Down Expand Up @@ -516,14 +510,13 @@ static void put_alpha_run(PutBitContext *pb, int run)
}

// todo alpha quantisation for high quants
static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
static void encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
int mbs_per_slice, uint16_t *blocks,
int quant)
{
const int abits = ctx->alpha_bits;
const int mask = (1 << abits) - 1;
const int num_coeffs = mbs_per_slice * 256;
int saved_pos = put_bits_count(pb);
int prev = mask, cur;
int idx = 0;
int run = 0;
Expand All @@ -544,8 +537,6 @@ static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
} while (idx < num_coeffs);
if (run)
put_alpha_run(pb, run);
flush_put_bits(pb);
return (put_bits_count(pb) - saved_pos) >> 3;
}

static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
Expand Down Expand Up @@ -611,29 +602,23 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
ctx->blocks[0], ctx->emu_buf,
mbs_per_slice, num_cblocks, is_chroma);
if (!is_chroma) {/* luma quant */
sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
mbs_per_slice, ctx->blocks[0],
num_cblocks, plane_factor,
qmat);
encode_slice_plane(ctx, pb, src, linesize,
mbs_per_slice, ctx->blocks[0],
num_cblocks, plane_factor, qmat);
} else { /* chroma plane */
sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
mbs_per_slice, ctx->blocks[0],
num_cblocks, plane_factor,
qmat_chroma);
encode_slice_plane(ctx, pb, src, linesize,
mbs_per_slice, ctx->blocks[0],
num_cblocks, plane_factor, qmat_chroma);
}
} else {
get_alpha_data(ctx, src, linesize, xp, yp,
pwidth, avctx->height / ctx->pictures_per_frame,
ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
sizes[i] = encode_alpha_plane(ctx, pb, mbs_per_slice,
ctx->blocks[0], quant);
}
total_size += sizes[i];
if (put_bits_left(pb) < 0) {
av_log(avctx, AV_LOG_ERROR,
"Underestimated required buffer size.\n");
return AVERROR_BUG;
encode_alpha_plane(ctx, pb, mbs_per_slice, ctx->blocks[0], quant);
}
flush_put_bits(pb);
sizes[i] = put_bytes_output(pb) - total_size;
total_size = put_bytes_output(pb);
}
return total_size;
}
Expand Down
35 changes: 32 additions & 3 deletions libavcodec/put_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ typedef struct PutBitContext {
BitBuf bit_buf;
int bit_left;
uint8_t *buf, *buf_ptr, *buf_end;
#if LIBAVCODEC_VERSION_MAJOR < 59
int size_in_bits;
#endif
} PutBitContext;

/**
Expand All @@ -69,7 +71,6 @@ static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
buffer = NULL;
}

s->size_in_bits = 8 * buffer_size;
s->buf = buffer;
s->buf_end = s->buf + buffer_size;
s->buf_ptr = s->buf;
Expand All @@ -85,6 +86,26 @@ static inline int put_bits_count(PutBitContext *s)
return (s->buf_ptr - s->buf) * 8 + BUF_BITS - s->bit_left;
}

/**
* @return the number of bytes output so far; may only be called
* when the PutBitContext is freshly initialized or flushed.
*/
static inline int put_bytes_output(const PutBitContext *s)
{
av_assert2(s->bit_left == BUF_BITS);
return s->buf_ptr - s->buf;
}

/**
* @param round_up When set, the number of bits written so far will be
* rounded up to the next byte.
* @return the number of bytes output so far.
*/
static inline int put_bytes_count(const PutBitContext *s, int round_up)
{
return s->buf_ptr - s->buf + ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3);
}

/**
* Rebase the bit writer onto a reallocated buffer.
*
Expand All @@ -100,7 +121,6 @@ static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
s->buf_end = buffer + buffer_size;
s->buf_ptr = buffer + (s->buf_ptr - s->buf);
s->buf = buffer;
s->size_in_bits = 8 * buffer_size;
}

/**
Expand All @@ -111,6 +131,16 @@ static inline int put_bits_left(PutBitContext* s)
return (s->buf_end - s->buf_ptr) * 8 - BUF_BITS + s->bit_left;
}

/**
* @param round_up When set, the number of bits written will be
* rounded up to the next byte.
* @return the number of bytes left.
*/
static inline int put_bytes_left(const PutBitContext *s, int round_up)
{
return s->buf_end - s->buf_ptr - ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3);
}

/**
* Pad the end of the output stream with zeros.
*/
Expand Down Expand Up @@ -384,7 +414,6 @@ static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
{
av_assert0(size <= INT_MAX/8 - BUF_BITS);
s->buf_end = s->buf + size;
s->size_in_bits = 8*size;
}

/**
Expand Down
22 changes: 13 additions & 9 deletions libavcodec/qtrleenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,14 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui
int sec_lowest_bulk_cost;
int sec_lowest_bulk_cost_index;

uint8_t *this_line = p-> data[0] + line*p-> linesize[0] +
(width - 1)*s->pixel_size;
uint8_t *prev_line = s->previous_frame->data[0] + line * s->previous_frame->linesize[0] +
(width - 1)*s->pixel_size;
const uint8_t *this_line = p->data[0] + line * p->linesize[0] + width * s->pixel_size;
/* There might be no earlier frame if the current frame is a keyframe.
* So just use a pointer to the current frame to avoid a check
* to avoid NULL - s->pixel_size (which is undefined behaviour). */
const uint8_t *prev_line = s->key_frame ? this_line
: s->previous_frame->data[0]
+ line * s->previous_frame->linesize[0]
+ width * s->pixel_size;

s->length_table[width] = 0;
skipcount = 0;
Expand All @@ -175,6 +179,9 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui

int prev_bulk_cost;

this_line -= s->pixel_size;
prev_line -= s->pixel_size;

/* If our lowest bulk cost index is too far away, replace it
* with the next lowest bulk cost */
if (FFMIN(width, i + MAX_RLE_BULK) < lowest_bulk_cost_index) {
Expand Down Expand Up @@ -259,10 +266,6 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui
/* These bulk costs increase every iteration */
lowest_bulk_cost += s->pixel_size;
sec_lowest_bulk_cost += s->pixel_size;
if (this_line >= p->data[0] + s->pixel_size)
this_line -= s->pixel_size;
if (prev_line >= s->previous_frame->data[0] + s->pixel_size)
prev_line -= s->pixel_size;
}

/* Good! Now we have the best sequence for this line, let's output it. */
Expand Down Expand Up @@ -369,7 +372,8 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size, 0)) < 0)
return ret;

if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) {
if (avctx->gop_size == 0 || !s->previous_frame->data[0] ||
(s->avctx->frame_number % avctx->gop_size) == 0) {
/* I-Frame */
s->key_frame = 1;
} else {
Expand Down
1 change: 1 addition & 0 deletions libavcodec/rawdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ static av_cold int raw_close_decoder(AVCodecContext *avctx)
RawVideoContext *context = avctx->priv_data;

av_buffer_unref(&context->palette);
av_freep(&context->bitstream_buf);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion libavcodec/rpzaenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ static int rpza_encode_frame(AVCodecContext *avctx, AVPacket *pkt,

flush_put_bits(&s->pb);

av_shrink_packet(pkt, put_bits_count(&s->pb) >> 3);
av_shrink_packet(pkt, put_bytes_output(&s->pb));
buf = pkt->data;

// write header opcode
Expand Down
4 changes: 1 addition & 3 deletions libavcodec/rv10.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ static int rv20_decode_picture_header(RVDecContext *rv)
new_w = rv->orig_width;
new_h = rv->orig_height;
}
if (new_w != s->width || new_h != s->height) {
if (new_w != s->width || new_h != s->height || !s->context_initialized) {
AVRational old_aspect = s->avctx->sample_aspect_ratio;
av_log(s->avctx, AV_LOG_DEBUG,
"attempting to change resolution to %dx%d\n", new_w, new_h);
Expand Down Expand Up @@ -687,7 +687,6 @@ AVCodec ff_rv10_decoder = {
.close = rv10_decode_end,
.decode = rv10_decode_frame,
.capabilities = AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
Expand All @@ -705,7 +704,6 @@ AVCodec ff_rv20_decoder = {
.close = rv10_decode_end,
.decode = rv10_decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.flush = ff_mpeg_flush,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
Expand Down
1 change: 1 addition & 0 deletions libavcodec/rv30.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ static av_cold int rv30_decode_init(AVCodecContext *avctx)
r->loop_filter = rv30_loop_filter;
r->luma_dc_quant_i = rv30_luma_dc_quant;
r->luma_dc_quant_p = rv30_luma_dc_quant;
ff_rv30dsp_init(&r->rdsp);
return 0;
}

Expand Down
22 changes: 9 additions & 13 deletions libavcodec/rv34.c
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,7 @@ static int rv34_decoder_alloc(RV34DecContext *r)

if (!(r->cbp_chroma && r->cbp_luma && r->deblock_coefs &&
r->intra_types_hist && r->mb_type)) {
r->s.context_reinit = 1;
rv34_decoder_free(r);
return AVERROR(ENOMEM);
}
Expand Down Expand Up @@ -1502,15 +1503,6 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx)

ff_h264_pred_init(&r->h, AV_CODEC_ID_RV40, 8, 1);

#if CONFIG_RV30_DECODER
if (avctx->codec_id == AV_CODEC_ID_RV30)
ff_rv30dsp_init(&r->rdsp);
#endif
#if CONFIG_RV40_DECODER
if (avctx->codec_id == AV_CODEC_ID_RV40)
ff_rv40dsp_init(&r->rdsp);
#endif

if ((ret = rv34_decoder_alloc(r)) < 0) {
ff_mpv_common_end(&r->s);
return ret;
Expand All @@ -1530,7 +1522,7 @@ int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecConte
if (dst == src || !s1->context_initialized)
return 0;

if (s->height != s1->height || s->width != s1->width) {
if (s->height != s1->height || s->width != s1->width || s->context_reinit) {
s->height = s1->height;
s->width = s1->width;
if ((err = ff_mpv_common_frame_size_change(s)) < 0)
Expand Down Expand Up @@ -1667,11 +1659,12 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
if (s->mb_num_left > 0 && s->current_picture_ptr) {
av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.\n",
s->mb_num_left);
ff_er_frame_end(&s->er);
if (!s->context_reinit)
ff_er_frame_end(&s->er);
ff_mpv_frame_end(s);
}

if (s->width != si.width || s->height != si.height) {
if (s->width != si.width || s->height != si.height || s->context_reinit) {
int err;

av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n",
Expand All @@ -1689,7 +1682,6 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
err = ff_set_dimensions(s->avctx, s->width, s->height);
if (err < 0)
return err;

if ((err = ff_mpv_common_frame_size_change(s)) < 0)
return err;
if ((err = rv34_decoder_realloc(r)) < 0)
Expand Down Expand Up @@ -1744,6 +1736,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
}
s->mb_x = s->mb_y = 0;
ff_thread_finish_setup(s->avctx);
} else if (s->context_reinit) {
av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames to "
"reinitialize (start MB is %d).\n", si.start);
return AVERROR_INVALIDDATA;
} else if (HAVE_THREADS &&
(s->avctx->active_thread_type & FF_THREAD_FRAME)) {
av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames in frame "
Expand Down
1 change: 1 addition & 0 deletions libavcodec/rv40.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ static av_cold int rv40_decode_init(AVCodecContext *avctx)
r->loop_filter = rv40_loop_filter;
r->luma_dc_quant_i = rv40_luma_dc_quant[0];
r->luma_dc_quant_p = rv40_luma_dc_quant[1];
ff_rv40dsp_init(&r->rdsp);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion libavcodec/sbcenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ static size_t sbc_pack_frame(AVPacket *avpkt, struct sbc_frame *frame,

flush_put_bits(&pb);

return (put_bits_count(&pb) + 7) / 8;
return put_bytes_output(&pb);
}

static int sbc_encode_init(AVCodecContext *avctx)
Expand Down
4 changes: 1 addition & 3 deletions libavcodec/sonic.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ static av_cold int sonic_encode_init(AVCodecContext *avctx)
put_bits(&pb, 1, 0); // XXX FIXME: no custom tap quant table

flush_put_bits(&pb);
avctx->extradata_size = put_bits_count(&pb)/8;
avctx->extradata_size = put_bytes_output(&pb);

av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d.%d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n",
s->version, s->minor_version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling);
Expand Down Expand Up @@ -832,8 +832,6 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
return ret;
}

// av_log(avctx, AV_LOG_DEBUG, "used bytes: %d\n", (put_bits_count(&pb)+7)/8);

avpkt->size = ff_rac_terminate(&c, 0);
*got_packet_ptr = 1;
return 0;
Expand Down
5 changes: 2 additions & 3 deletions libavcodec/svq1enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,7 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
int score[4] = { 0, 0, 0, 0 }, best;
uint8_t *temp = s->scratchbuf;

if (s->pb.buf_end - s->pb.buf -
(put_bits_count(&s->pb) >> 3) < 3000) { // FIXME: check size
if (put_bytes_left(&s->pb, 0) < 3000) { // FIXME: check size
av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
return -1;
}
Expand Down Expand Up @@ -653,7 +652,7 @@ FF_ENABLE_DEPRECATION_WARNINGS

flush_put_bits(&s->pb);

pkt->size = put_bits_count(&s->pb) / 8;
pkt->size = put_bytes_output(&s->pb);
if (s->pict_type == AV_PICTURE_TYPE_I)
pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = 1;
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/tests/cabac.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static int put_cabac_terminate(CABACTestContext *c, int bit)
flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
}

return (put_bits_count(&c->pb)+7)>>3;
return put_bytes_count(&c->pb, 1);
}

/**
Expand Down
422 changes: 201 additions & 221 deletions libavcodec/tiff.c

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion libavcodec/ttaenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ static int tta_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
}

flush_put_bits(&pb);
out_bytes = put_bits_count(&pb) >> 3;
out_bytes = put_bytes_output(&pb);
put_bits32(&pb, av_crc(s->crc_table, UINT32_MAX, avpkt->data, out_bytes) ^ UINT32_MAX);
flush_put_bits(&pb);

Expand Down
179 changes: 67 additions & 112 deletions libavcodec/ttmlenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf,
{
TTMLContext *s = avctx->priv_data;
ASSDialog *dialog;
AVBPrint local_bprint = { 0 };
int i;

av_bprint_clear(&s->buffer);
Expand All @@ -102,19 +101,11 @@ static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf,

for (; dialog && num--; dialog++) {
if (dialog->style) {
av_bprint_init(&local_bprint, 0, AV_BPRINT_SIZE_UNLIMITED);

av_bprint_escape(&local_bprint, dialog->style, NULL,
av_bprintf(&s->buffer, "<span region=\"");
av_bprint_escape(&s->buffer, dialog->style, NULL,
AV_ESCAPE_MODE_XML,
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
if (!av_bprint_is_complete(&local_bprint)) {
return AVERROR(ENOMEM);
}

av_bprintf(&s->buffer, "<span region=\"%s\">",
local_bprint.str);

av_bprint_finalize(&local_bprint, NULL);
av_bprintf(&s->buffer, "\">");
}

{
Expand Down Expand Up @@ -144,19 +135,11 @@ static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf,
return AVERROR(ENOMEM);

if (dialog->style) {
av_bprint_init(&local_bprint, 0, AV_BPRINT_SIZE_UNLIMITED);

av_bprint_escape(&local_bprint, dialog->style, NULL,
av_bprintf(&s->buffer, "<span region=\"");
av_bprint_escape(&s->buffer, dialog->style, NULL,
AV_ESCAPE_MODE_XML,
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
if (!av_bprint_is_complete(&local_bprint)) {
return AVERROR(ENOMEM);
}

av_bprintf(&s->buffer, "<span region=\"%s\">",
local_bprint.str);

av_bprint_finalize(&local_bprint, NULL);
av_bprintf(&s->buffer, "\">");
}

{
Expand Down Expand Up @@ -260,7 +243,7 @@ static void ttml_get_origin(ASSScriptInfo script_info, ASSStyle *style,
*origin_left = av_rescale(style->margin_l, 100, script_info.play_res_x);
*origin_top =
av_rescale((style->alignment >= 7) ? style->margin_v : 0,
100, script_info.play_res_x);
100, script_info.play_res_y);
}

static void ttml_get_extent(ASSScriptInfo script_info, ASSStyle *style,
Expand All @@ -274,28 +257,16 @@ static void ttml_get_extent(ASSScriptInfo script_info, ASSStyle *style,
100, script_info.play_res_y);
}

// if we set cell resolution to our script reference resolution,
// then a single line is a single "point" on our canvas. Thus, by setting our
// font size to font size in cells, we should gain a similar enough scale
// without resorting to explicit pixel based font sizing, which is frowned
// upon in the TTML community.
static const char ttml_region_base[] =
" <region xml:id=\"%s\"\n"
" tts:origin=\"%d%% %d%%\"\n"
" tts:extent=\"%d%% %d%%\"\n"
" tts:displayAlign=\"%s\"\n"
" tts:textAlign=\"%s\"\n"
" tts:fontSize=\"%dc\"\n";

static const char ttml_region_font_family[] =
" tts:fontFamily=\"%s\"\n";

static const char ttml_region_footer[] =
" tts:overflow=\"visible\" />\n";

static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf,
ASSScriptInfo script_info, ASSStyle *style)
{
const char *display_alignment = NULL;
const char *text_alignment = NULL;
int origin_left = 0;
int origin_top = 0;
int width = 0;
int height = 0;

if (!style)
return AVERROR_INVALIDDATA;

Expand All @@ -318,71 +289,58 @@ static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf,
return AVERROR_INVALIDDATA;
}

{
const char *display_alignment =
ttml_get_display_alignment(style->alignment);
const char *text_alignment =
ttml_get_text_alignment(style->alignment);
int origin_left = 0;
int origin_top = 0;
int width = 0;
int height = 0;
char *style_name = NULL;
char *font_name = NULL;
AVBPrint local_bprint = { 0 };
int ret = AVERROR_BUG;

if (!display_alignment || !text_alignment) {
av_log(avctx, AV_LOG_ERROR,
"Failed to convert ASS style alignment %d of style %s to "
"TTML display and text alignment!\n",
style->alignment,
style->name);
return AVERROR_INVALIDDATA;
}

ttml_get_origin(script_info, style, &origin_left, &origin_top);
ttml_get_extent(script_info, style, &width, &height);

av_bprint_init(&local_bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
av_bprint_escape(&local_bprint, style->name, NULL,
AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
if (!av_bprint_is_complete(&local_bprint)) {
return AVERROR(ENOMEM);
}

if ((ret = av_bprint_finalize(&local_bprint, &style_name)) < 0)
return ret;

av_bprintf(buf, ttml_region_base, style_name,
origin_left, origin_top, width, height,
display_alignment, text_alignment, style->font_size);

if (style->font_name) {
av_bprint_init(&local_bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
av_bprint_escape(&local_bprint, style->font_name, NULL,
AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
if (!av_bprint_is_complete(&local_bprint)) {
ret = AVERROR(ENOMEM);
goto fail;
}

if ((ret = av_bprint_finalize(&local_bprint, &font_name)) < 0)
goto fail;

av_bprintf(buf, ttml_region_font_family, font_name);
}
display_alignment = ttml_get_display_alignment(style->alignment);
text_alignment = ttml_get_text_alignment(style->alignment);
if (!display_alignment || !text_alignment) {
av_log(avctx, AV_LOG_ERROR,
"Failed to convert ASS style alignment %d of style %s to "
"TTML display and text alignment!\n",
style->alignment,
style->name);
return AVERROR_INVALIDDATA;
}

ttml_get_origin(script_info, style, &origin_left, &origin_top);
ttml_get_extent(script_info, style, &width, &height);

av_bprintf(buf, " <region xml:id=\"");
av_bprint_escape(buf, style->name, NULL, AV_ESCAPE_MODE_XML,
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
av_bprintf(buf, "\"\n");

av_bprintf(buf, " tts:origin=\"%d%% %d%%\"\n",
origin_left, origin_top);
av_bprintf(buf, " tts:extent=\"%d%% %d%%\"\n",
width, height);

av_bprintf(buf, " tts:displayAlign=\"");
av_bprint_escape(buf, display_alignment, NULL, AV_ESCAPE_MODE_XML,
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
av_bprintf(buf, "\"\n");

av_bprintf(buf, " tts:textAlign=\"");
av_bprint_escape(buf, text_alignment, NULL, AV_ESCAPE_MODE_XML,
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
av_bprintf(buf, "\"\n");

// if we set cell resolution to our script reference resolution,
// then a single line is a single "point" on our canvas. Thus, by setting
// our font size to font size in cells, we should gain a similar enough
// scale without resorting to explicit pixel based font sizing, which is
// frowned upon in the TTML community.
av_bprintf(buf, " tts:fontSize=\"%dc\"\n",
style->font_size);

av_bprintf(buf, ttml_region_footer);
if (style->font_name) {
av_bprintf(buf, " tts:fontFamily=\"");
av_bprint_escape(buf, style->font_name, NULL, AV_ESCAPE_MODE_XML,
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
av_bprintf(buf, "\"\n");
}

ret = 0;
av_bprintf(buf, " tts:overflow=\"visible\" />\n");

fail:
av_freep(&style_name);
av_freep(&font_name);
return ret;
}
return 0;
}

static int ttml_write_header_content(AVCodecContext *avctx)
Expand All @@ -393,10 +351,8 @@ static int ttml_write_header_content(AVCodecContext *avctx)
const size_t base_extradata_size = TTMLENC_EXTRADATA_SIGNATURE_SIZE + 1 +
AV_INPUT_BUFFER_PADDING_SIZE;
size_t additional_extradata_size = 0;
ASSStyle *style = ff_ass_style_get(s->ass_ctx, "Default");

if (!script_info.play_res_x || script_info.play_res_x < 0 ||
!script_info.play_res_y || script_info.play_res_y < 0) {
if (script_info.play_res_x <= 0 || script_info.play_res_y <= 0) {
av_log(avctx, AV_LOG_ERROR,
"Invalid subtitle reference resolution %dx%d!\n",
script_info.play_res_x, script_info.play_res_y);
Expand All @@ -418,23 +374,22 @@ static int ttml_write_header_content(AVCodecContext *avctx)
av_bprintf(&s->buffer, " <layout>\n");

for (int i = 0; i < ass->styles_count; i++) {
int ret = AVERROR_BUG;
style = &ass->styles[i];

if ((ret = ttml_write_region(avctx, &s->buffer, script_info, style)) < 0)
ASSStyle *style = &ass->styles[i];
int ret = ttml_write_region(avctx, &s->buffer, script_info, style);
if (ret < 0)
return ret;
}

av_bprintf(&s->buffer, " </layout>\n");
av_bprintf(&s->buffer, " </head>\n");
av_bprint_chars(&s->buffer, '\0', 1);

if (!av_bprint_is_complete(&s->buffer)) {
return AVERROR(ENOMEM);
}

additional_extradata_size = s->buffer.len;

// and now, write the contents of the AVB
if (!(avctx->extradata =
av_mallocz(base_extradata_size + additional_extradata_size))) {
return AVERROR(ENOMEM);
Expand Down
10 changes: 4 additions & 6 deletions libavcodec/utvideoenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,13 +398,11 @@ static int write_huff_codes(uint8_t *src, uint8_t *dst, int dst_size,
if (count)
put_bits(&pb, 32 - count, 0);

/* Get the amount of bits written */
count = put_bits_count(&pb);

/* Flush the rest with zeroes */
flush_put_bits(&pb);

return count;
/* Return the amount of bytes written */
return put_bytes_output(&pb);
}

static int encode_plane(AVCodecContext *avctx, uint8_t *src,
Expand Down Expand Up @@ -512,11 +510,11 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src,

/*
* Write the huffman codes to a buffer,
* get the offset in bits and convert to bytes.
* get the offset in bytes.
*/
offset += write_huff_codes(dst + sstart * width, c->slice_bits,
width * height + 4, width,
send - sstart, he) >> 3;
send - sstart, he);

slice_len = offset - slice_len;

Expand Down
6 changes: 1 addition & 5 deletions libavcodec/vc1.c
Original file line number Diff line number Diff line change
Expand Up @@ -1695,12 +1695,10 @@ static av_cold void vc1_init_static(void)
* @param v The VC1Context to initialize
* @return Status
*/
av_cold int ff_vc1_init_common(VC1Context *v)
av_cold void ff_vc1_init_common(VC1Context *v)
{
static AVOnce init_static_once = AV_ONCE_INIT;

v->hrd_rate = v->hrd_buffer = NULL;

/* defaults */
v->pq = -1;
v->mvrange = 0; /* 7.1.1.18, p80 */
Expand All @@ -1709,6 +1707,4 @@ av_cold int ff_vc1_init_common(VC1Context *v)

/* VLC tables */
ff_thread_once(&init_static_once, vc1_init_static);

return 0;
}
4 changes: 1 addition & 3 deletions libavcodec/vc1.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,6 @@ typedef struct VC1Context{
uint8_t* over_flags_plane; ///< Overflags bitplane
int overflg_is_raw;
uint8_t condover;
uint16_t *hrd_rate, *hrd_buffer;
uint8_t *hrd_fullness;
uint8_t range_mapy_flag;
uint8_t range_mapuv_flag;
uint8_t range_mapy;
Expand Down Expand Up @@ -413,7 +411,7 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex

int ff_vc1_parse_frame_header (VC1Context *v, GetBitContext *gb);
int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb);
int ff_vc1_init_common(VC1Context *v);
void ff_vc1_init_common(VC1Context *v);

int ff_vc1_decode_init_alloc_tables(VC1Context *v);
void ff_vc1_init_transposed_scantables(VC1Context *v);
Expand Down
3 changes: 2 additions & 1 deletion libavcodec/vc1_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,8 @@ static av_cold int vc1_parse_init(AVCodecParserContext *s)
vpc->bytes_to_skip = 0;
vpc->unesc_index = 0;
vpc->search_state = NO_MATCH;
return ff_vc1_init_common(&vpc->v);
ff_vc1_init_common(&vpc->v);
return 0;
}

AVCodecParser ff_vc1_parser = {
Expand Down
7 changes: 2 additions & 5 deletions libavcodec/vc1dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v)
if (s->avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || s->avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
for (i = 0; i < 4; i++)
if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width)))
return AVERROR(ENOMEM);
goto error;
}

ret = ff_intrax8_common_init(s->avctx, &v->x8, &s->idsp,
Expand Down Expand Up @@ -434,8 +434,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
return AVERROR_INVALIDDATA;
v->s.avctx = avctx;

if ((ret = ff_vc1_init_common(v)) < 0)
return ret;
ff_vc1_init_common(v);

if (avctx->codec_id == AV_CODEC_ID_WMV3 || avctx->codec_id == AV_CODEC_ID_WMV3IMAGE) {
int count = 0;
Expand Down Expand Up @@ -594,8 +593,6 @@ av_cold int ff_vc1_decode_end(AVCodecContext *avctx)

for (i = 0; i < 4; i++)
av_freep(&v->sr_rows[i >> 1][i & 1]);
av_freep(&v->hrd_rate);
av_freep(&v->hrd_buffer);
ff_mpv_common_end(&v->s);
av_freep(&v->mv_type_mb_plane);
av_freep(&v->direct_mb_plane);
Expand Down
13 changes: 8 additions & 5 deletions libavcodec/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
#include "libavutil/version.h"

#define LIBAVCODEC_VERSION_MAJOR 58
#define LIBAVCODEC_VERSION_MINOR 135
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_MINOR 136
#define LIBAVCODEC_VERSION_MICRO 101

#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
Expand All @@ -51,9 +51,6 @@
* at once through the bump. This improves the git bisect-ability of the change.
*/

#ifndef FF_API_AVCTX_TIMEBASE
#define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_CODED_FRAME
#define FF_API_CODED_FRAME (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
Expand Down Expand Up @@ -168,5 +165,11 @@
#ifndef FF_API_INIT_PACKET
#define FF_API_INIT_PACKET (LIBAVCODEC_VERSION_MAJOR < 60)
#endif
#ifndef FF_API_AVCTX_TIMEBASE
#define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 60)
#endif
#ifndef FF_API_MPEGVIDEO_OPTS
#define FF_API_MPEGVIDEO_OPTS (LIBAVCODEC_VERSION_MAJOR < 60)
#endif

#endif /* AVCODEC_VERSION_H */
19 changes: 12 additions & 7 deletions libavcodec/vmdvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
unsigned char len;
int ofs;

int frame_x, frame_y;
int frame_x, frame_y, prev_linesize;
int frame_width, frame_height;

frame_x = AV_RL16(&s->buf[6]);
Expand Down Expand Up @@ -282,7 +282,13 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
}

dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x];
if (s->prev_frame->data[0]) {
prev_linesize = s->prev_frame->linesize[0];
pp = s->prev_frame->data[0] + frame_y * prev_linesize + frame_x;
} else {
pp = NULL;
prev_linesize = 0;
}
switch (meth) {
case 1:
for (i = 0; i < frame_height; i++) {
Expand All @@ -298,7 +304,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
ofs += len;
} else {
/* interframe pixel copy */
if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
if (ofs + len + 1 > frame_width || !pp)
return AVERROR_INVALIDDATA;
memcpy(&dp[ofs], &pp[ofs], len + 1);
ofs += len + 1;
Expand All @@ -311,15 +317,14 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
return AVERROR_INVALIDDATA;
}
dp += frame->linesize[0];
pp += s->prev_frame->linesize[0];
pp = FF_PTR_ADD(pp, prev_linesize);
}
break;

case 2:
for (i = 0; i < frame_height; i++) {
bytestream2_get_buffer(&gb, dp, frame_width);
dp += frame->linesize[0];
pp += s->prev_frame->linesize[0];
}
break;

Expand Down Expand Up @@ -347,7 +352,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
}
} else {
/* interframe pixel copy */
if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
if (ofs + len + 1 > frame_width || !pp)
return AVERROR_INVALIDDATA;
memcpy(&dp[ofs], &pp[ofs], len + 1);
ofs += len + 1;
Expand All @@ -360,7 +365,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
return AVERROR_INVALIDDATA;
}
dp += frame->linesize[0];
pp += s->prev_frame->linesize[0];
pp = FF_PTR_ADD(pp, prev_linesize);
}
break;
}
Expand Down
17 changes: 6 additions & 11 deletions libavcodec/vorbisenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ static inline int put_codeword(PutBitContext *pb, vorbis_enc_codebook *cb,
av_assert2(entry >= 0);
av_assert2(entry < cb->nentries);
av_assert2(cb->lens[entry]);
if (pb->size_in_bits - put_bits_count(pb) < cb->lens[entry])
if (put_bits_left(pb) < cb->lens[entry])
return AVERROR(EINVAL);
put_bits(pb, cb->lens[entry], cb->codewords[entry]);
return 0;
Expand Down Expand Up @@ -637,7 +637,7 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out)
put_bits(&pb, 1, 1); // framing

flush_put_bits(&pb);
hlens[0] = put_bits_count(&pb) >> 3;
hlens[0] = put_bytes_output(&pb);
buffer_len -= hlens[0];
p += hlens[0];

Expand All @@ -651,7 +651,7 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out)
put_bits(&pb, 1, 1); // framing

flush_put_bits(&pb);
hlens[1] = put_bits_count(&pb) >> 3;
hlens[1] = put_bytes_output(&pb);
buffer_len -= hlens[1];
p += hlens[1];

Expand Down Expand Up @@ -725,7 +725,7 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out)
put_bits(&pb, 1, 1); // framing

flush_put_bits(&pb);
hlens[2] = put_bits_count(&pb) >> 3;
hlens[2] = put_bytes_output(&pb);

len = hlens[0] + hlens[1] + hlens[2];
p = *out = av_mallocz(64 + len + len/255);
Expand Down Expand Up @@ -798,7 +798,7 @@ static int floor_encode(vorbis_enc_context *venc, vorbis_enc_floor *fc,
int coded[MAX_FLOOR_VALUES]; // first 2 values are unused
int i, counter;

if (pb->size_in_bits - put_bits_count(pb) < 1 + 2 * ilog(range - 1))
if (put_bits_left(pb) < 1 + 2 * ilog(range - 1))
return AVERROR(EINVAL);
put_bits(pb, 1, 1); // non zero
put_bits(pb, ilog(range - 1), posts[0]);
Expand Down Expand Up @@ -1135,11 +1135,6 @@ static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,

init_put_bits(&pb, avpkt->data, avpkt->size);

if (pb.size_in_bits - put_bits_count(&pb) < 1 + ilog(venc->nmodes - 1)) {
av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
return AVERROR(EINVAL);
}

put_bits(&pb, 1, 0); // magic bit

put_bits(&pb, ilog(venc->nmodes - 1), 1); // Mode for current frame
Expand Down Expand Up @@ -1185,7 +1180,7 @@ static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
}

flush_put_bits(&pb);
avpkt->size = put_bits_count(&pb) >> 3;
avpkt->size = put_bytes_output(&pb);

ff_af_queue_remove(&venc->afq, frame_size, &avpkt->pts, &avpkt->duration);

Expand Down
4 changes: 2 additions & 2 deletions libavcodec/wavpackenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2777,7 +2777,7 @@ static int wavpack_encode_block(WavPackEncodeContext *s,
}
encode_flush(s);
flush_put_bits(&s->pb);
data_size = put_bits_count(&s->pb) >> 3;
data_size = put_bytes_output(&s->pb);
bytestream2_put_le24(&pb, (data_size + 1) >> 1);
bytestream2_skip_p(&pb, data_size);
if (data_size & 1)
Expand All @@ -2791,7 +2791,7 @@ static int wavpack_encode_block(WavPackEncodeContext *s,
else
pack_int32(s, s->orig_l, s->orig_r, nb_samples);
flush_put_bits(&s->pb);
data_size = put_bits_count(&s->pb) >> 3;
data_size = put_bytes_output(&s->pb);
bytestream2_put_le24(&pb, (data_size + 5) >> 1);
bytestream2_put_le32(&pb, s->crc_x);
bytestream2_skip_p(&pb, data_size);
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/wmaenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt,
return AVERROR(EINVAL);
}
av_assert0((put_bits_count(&s->pb) & 7) == 0);
i= avctx->block_align - (put_bits_count(&s->pb)+7)/8;
i = avctx->block_align - put_bytes_count(&s->pb, 0);
av_assert0(i>=0);
while(i--)
put_bits(&s->pb, 8, 'N');
Expand Down
13 changes: 7 additions & 6 deletions libavcodec/wmavoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ static av_cold void wmavoice_flush(AVCodecContext *ctx)
static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
{
static AVOnce init_static_once = AV_ONCE_INIT;
int n, flags, pitch_range, lsp16_flag;
int n, flags, pitch_range, lsp16_flag, ret;
WMAVoiceContext *s = ctx->priv_data;

ff_thread_once(&init_static_once, wmavoice_init_static_data);
Expand Down Expand Up @@ -395,10 +395,11 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
s->spillover_bitsize = 3 + av_ceil_log2(ctx->block_align);
s->do_apf = flags & 0x1;
if (s->do_apf) {
ff_rdft_init(&s->rdft, 7, DFT_R2C);
ff_rdft_init(&s->irdft, 7, IDFT_C2R);
ff_dct_init(&s->dct, 6, DCT_I);
ff_dct_init(&s->dst, 6, DST_I);
if ((ret = ff_rdft_init(&s->rdft, 7, DFT_R2C)) < 0 ||
(ret = ff_rdft_init(&s->irdft, 7, IDFT_C2R)) < 0 ||
(ret = ff_dct_init (&s->dct, 6, DCT_I)) < 0 ||
(ret = ff_dct_init (&s->dst, 6, DST_I)) < 0)
return ret;

ff_sine_window_init(s->cos, 256);
memcpy(&s->sin[255], s->cos, 256 * sizeof(s->cos[0]));
Expand Down Expand Up @@ -1881,7 +1882,7 @@ static void copy_bits(PutBitContext *pb,
rmn_bits = rmn_bytes = get_bits_left(gb);
if (rmn_bits < nbits)
return;
if (nbits > pb->size_in_bits - put_bits_count(pb))
if (nbits > put_bits_left(pb))
return;
rmn_bits &= 7; rmn_bytes >>= 3;
if ((rmn_bits = FFMIN(rmn_bits, nbits)) > 0)
Expand Down
6 changes: 3 additions & 3 deletions libavcodec/xsubenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static int xsub_encode_rle(PutBitContext *pb, const uint8_t *bitmap,
x0 = 0;
while (x0 < w) {
// Make sure we have enough room for at least one run and padding
if (pb->size_in_bits - put_bits_count(pb) < 7*8)
if (put_bytes_left(pb, 1) < 7)
return AVERROR_BUFFER_TOO_SMALL;

x1 = x0;
Expand Down Expand Up @@ -197,7 +197,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
h->rects[0]->linesize[0] * 2,
h->rects[0]->w, (h->rects[0]->h + 1) >> 1))
return AVERROR_BUFFER_TOO_SMALL;
bytestream_put_le16(&rlelenptr, put_bits_count(&pb) >> 3); // Length of first field
bytestream_put_le16(&rlelenptr, put_bytes_count(&pb, 0)); // Length of first field

if (xsub_encode_rle(&pb, h->rects[0]->data[0] + h->rects[0]->linesize[0],
h->rects[0]->linesize[0] * 2,
Expand All @@ -211,7 +211,7 @@ FF_ENABLE_DEPRECATION_WARNINGS

flush_put_bits(&pb);

return hdr - buf + put_bits_count(&pb)/8;
return hdr - buf + put_bytes_output(&pb);
}

static av_cold int xsub_encoder_init(AVCodecContext *avctx)
Expand Down
8 changes: 4 additions & 4 deletions libavfilter/af_hdcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state *states, int channels, in

for (j = result - 1; j >= 0; j--) {
for (i = 0; i < channels; i++)
bits[i] |= (*(samples++) & 1) << j;
bits[i] |= (*(samples++) & 1U) << j;
samples += stride - channels;
}

Expand Down Expand Up @@ -1210,7 +1210,7 @@ static int hdcd_analyze(int32_t *samples, int count, int stride, int gain, int t
int32_t *samples_end = samples + stride * count;

for (i = 0; i < count; i++) {
samples[i * stride] <<= 15;
samples[i * stride] *= 1 << 15;
if (mode == HDCD_ANA_PE) {
int pel = (samples[i * stride] >> 16) & 1;
int32_t sample = samples[i * stride];
Expand Down Expand Up @@ -1284,13 +1284,13 @@ static int hdcd_envelope(int32_t *samples, int count, int stride, int vbits, int
av_assert0(asample <= max_asample);
sample = sample >= 0 ? peaktab[asample] : -peaktab[asample];
} else
sample <<= shft;
sample *= (1 << shft);

samples[i * stride] = sample;
}
} else {
for (i = 0; i < count; i++)
samples[i * stride] <<= shft;
samples[i * stride] *= (1 << shft);
}

if (gain <= target_gain) {
Expand Down
8 changes: 4 additions & 4 deletions libavfilter/dnn/dnn_backend_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,8 @@ static DNNReturnType execute_model_native(const DNNModel *model, const char *inp
input.data = oprd->data;
input.dt = oprd->data_type;
if (do_ioproc) {
if (native_model->model->pre_proc != NULL) {
native_model->model->pre_proc(in_frame, &input, native_model->model->filter_ctx);
if (native_model->model->frame_pre_proc != NULL) {
native_model->model->frame_pre_proc(in_frame, &input, native_model->model->filter_ctx);
} else {
ff_proc_from_frame_to_dnn(in_frame, &input, native_model->model->func_type, ctx);
}
Expand Down Expand Up @@ -358,8 +358,8 @@ static DNNReturnType execute_model_native(const DNNModel *model, const char *inp
output.dt = oprd->data_type;

if (do_ioproc) {
if (native_model->model->post_proc != NULL) {
native_model->model->post_proc(out_frame, &output, native_model->model->filter_ctx);
if (native_model->model->frame_post_proc != NULL) {
native_model->model->frame_post_proc(out_frame, &output, native_model->model->filter_ctx);
} else {
ff_proc_from_dnn_to_frame(out_frame, &output, ctx);
}
Expand Down
39 changes: 30 additions & 9 deletions libavfilter/dnn/dnn_backend_openvino.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ static DNNReturnType fill_model_input_ov(OVModel *ov_model, RequestItem *request
for (int i = 0; i < request->task_count; ++i) {
task = request->tasks[i];
if (task->do_ioproc) {
if (ov_model->model->pre_proc != NULL) {
ov_model->model->pre_proc(task->in_frame, &input, ov_model->model->filter_ctx);
if (ov_model->model->frame_pre_proc != NULL) {
ov_model->model->frame_pre_proc(task->in_frame, &input, ov_model->model->filter_ctx);
} else {
ff_proc_from_frame_to_dnn(task->in_frame, &input, ov_model->model->func_type, ctx);
}
Expand Down Expand Up @@ -236,16 +236,32 @@ static void infer_completion_callback(void *args)
av_assert0(request->task_count >= 1);
for (int i = 0; i < request->task_count; ++i) {
task = request->tasks[i];
if (task->do_ioproc) {
if (task->ov_model->model->post_proc != NULL) {
task->ov_model->model->post_proc(task->out_frame, &output, task->ov_model->model->filter_ctx);

switch (task->ov_model->model->func_type) {
case DFT_PROCESS_FRAME:
if (task->do_ioproc) {
if (task->ov_model->model->frame_post_proc != NULL) {
task->ov_model->model->frame_post_proc(task->out_frame, &output, task->ov_model->model->filter_ctx);
} else {
ff_proc_from_dnn_to_frame(task->out_frame, &output, ctx);
}
} else {
ff_proc_from_dnn_to_frame(task->out_frame, &output, ctx);
task->out_frame->width = output.width;
task->out_frame->height = output.height;
}
} else {
task->out_frame->width = output.width;
task->out_frame->height = output.height;
break;
case DFT_ANALYTICS_DETECT:
if (!task->ov_model->model->detect_post_proc) {
av_log(ctx, AV_LOG_ERROR, "detect filter needs to provide post proc\n");
return;
}
task->ov_model->model->detect_post_proc(task->out_frame, &output, 1, task->ov_model->model->filter_ctx);
break;
default:
av_assert0(!"should not reach here");
break;
}

task->done = 1;
output.data = (uint8_t *)output.data
+ output.width * output.height * output.channels * get_datatype_size(output.dt);
Expand Down Expand Up @@ -493,6 +509,11 @@ static DNNReturnType get_output_ov(void *model, const char *input_name, int inpu
IEStatusCode status;
input_shapes_t input_shapes;

if (ov_model->model->func_type != DFT_PROCESS_FRAME) {
av_log(ctx, AV_LOG_ERROR, "Get output dim only when processing frame.\n");
return DNN_ERROR;
}

if (ctx->options.input_resizable) {
status = ie_network_get_input_shapes(ov_model->network, &input_shapes);
input_shapes.shapes->shape.dims[2] = input_height;
Expand Down
8 changes: 4 additions & 4 deletions libavfilter/dnn/dnn_backend_tf.c
Original file line number Diff line number Diff line change
Expand Up @@ -756,8 +756,8 @@ static DNNReturnType execute_model_tf(const DNNModel *model, const char *input_n
input.data = (float *)TF_TensorData(input_tensor);

if (do_ioproc) {
if (tf_model->model->pre_proc != NULL) {
tf_model->model->pre_proc(in_frame, &input, tf_model->model->filter_ctx);
if (tf_model->model->frame_pre_proc != NULL) {
tf_model->model->frame_pre_proc(in_frame, &input, tf_model->model->filter_ctx);
} else {
ff_proc_from_frame_to_dnn(in_frame, &input, tf_model->model->func_type, ctx);
}
Expand Down Expand Up @@ -818,8 +818,8 @@ static DNNReturnType execute_model_tf(const DNNModel *model, const char *input_n
output.dt = TF_TensorType(output_tensors[i]);

if (do_ioproc) {
if (tf_model->model->post_proc != NULL) {
tf_model->model->post_proc(out_frame, &output, tf_model->model->filter_ctx);
if (tf_model->model->frame_post_proc != NULL) {
tf_model->model->frame_post_proc(out_frame, &output, tf_model->model->filter_ctx);
} else {
ff_proc_from_dnn_to_frame(out_frame, &output, ctx);
}
Expand Down
13 changes: 13 additions & 0 deletions libavfilter/dnn_filter_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ int ff_dnn_init(DnnContext *ctx, DNNFunctionType func_type, AVFilterContext *fil
return 0;
}

int ff_dnn_set_frame_proc(DnnContext *ctx, FramePrePostProc pre_proc, FramePrePostProc post_proc)
{
ctx->model->frame_pre_proc = pre_proc;
ctx->model->frame_post_proc = post_proc;
return 0;
}

int ff_dnn_set_detect_post_proc(DnnContext *ctx, DetectPostProc post_proc)
{
ctx->model->detect_post_proc = post_proc;
return 0;
}

DNNReturnType ff_dnn_get_input(DnnContext *ctx, DNNData *input)
{
return ctx->model->get_input(ctx->model->model, input, ctx->model_inputname);
Expand Down
2 changes: 2 additions & 0 deletions libavfilter/dnn_filter_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ typedef struct DnnContext {


int ff_dnn_init(DnnContext *ctx, DNNFunctionType func_type, AVFilterContext *filter_ctx);
int ff_dnn_set_frame_proc(DnnContext *ctx, FramePrePostProc pre_proc, FramePrePostProc post_proc);
int ff_dnn_set_detect_post_proc(DnnContext *ctx, DetectPostProc post_proc);
DNNReturnType ff_dnn_get_input(DnnContext *ctx, DNNData *input);
DNNReturnType ff_dnn_get_output(DnnContext *ctx, int input_width, int input_height, int *output_width, int *output_height);
DNNReturnType ff_dnn_execute_model(DnnContext *ctx, AVFrame *in_frame, AVFrame *out_frame);
Expand Down
9 changes: 7 additions & 2 deletions libavfilter/dnn_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ typedef struct DNNData{
DNNColorOrder order;
} DNNData;

typedef int (*FramePrePostProc)(AVFrame *frame, DNNData *model, AVFilterContext *filter_ctx);
typedef int (*DetectPostProc)(AVFrame *frame, DNNData *output, uint32_t nb, AVFilterContext *filter_ctx);

typedef struct DNNModel{
// Stores model that can be different for different backends.
void *model;
Expand All @@ -80,10 +83,12 @@ typedef struct DNNModel{
const char *output_name, int *output_width, int *output_height);
// set the pre process to transfer data from AVFrame to DNNData
// the default implementation within DNN is used if it is not provided by the filter
int (*pre_proc)(AVFrame *frame_in, DNNData *model_input, AVFilterContext *filter_ctx);
FramePrePostProc frame_pre_proc;
// set the post process to transfer data from DNNData to AVFrame
// the default implementation within DNN is used if it is not provided by the filter
int (*post_proc)(AVFrame *frame_out, DNNData *model_output, AVFilterContext *filter_ctx);
FramePrePostProc frame_post_proc;
// set the post process to interpret detect result from DNNData
DetectPostProc detect_post_proc;
} DNNModel;

// Stores pointers to functions for loading, executing, freeing DNN models for one of the backends.
Expand Down
Loading