2020-11-09 12:25:02 +01:00
|
|
|
/*
|
|
|
|
|
* SpeedHQ encoder
|
|
|
|
|
* Copyright (c) 2000, 2001 Fabrice Bellard
|
|
|
|
|
* Copyright (c) 2003 Alex Beregszaszi
|
|
|
|
|
* Copyright (c) 2003-2004 Michael Niedermayer
|
|
|
|
|
* Copyright (c) 2020 FFmpeg
|
|
|
|
|
*
|
|
|
|
|
* This file is part of FFmpeg.
|
|
|
|
|
*
|
|
|
|
|
* FFmpeg is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* FFmpeg is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with FFmpeg; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
* SpeedHQ encoder.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "libavutil/thread.h"
|
|
|
|
|
|
|
|
|
|
#include "avcodec.h"
|
2022-03-16 18:18:28 +01:00
|
|
|
#include "codec_internal.h"
|
2021-12-22 04:07:14 +01:00
|
|
|
#include "mpeg12data.h"
|
2022-09-30 01:20:07 +02:00
|
|
|
#include "mpeg12vlc.h"
|
2020-11-09 12:25:02 +01:00
|
|
|
#include "mpegvideo.h"
|
2022-10-02 21:32:19 +02:00
|
|
|
#include "mpegvideodata.h"
|
2022-01-28 01:14:42 +01:00
|
|
|
#include "mpegvideoenc.h"
|
2022-10-22 18:55:04 +02:00
|
|
|
#include "rl.h"
|
2022-10-18 14:29:03 +02:00
|
|
|
#include "speedhq.h"
|
2020-11-09 12:25:02 +01:00
|
|
|
#include "speedhqenc.h"
|
|
|
|
|
|
2022-10-22 18:55:04 +02:00
|
|
|
static uint8_t speedhq_max_level[MAX_LEVEL + 1];
|
|
|
|
|
static uint8_t speedhq_index_run[MAX_RUN + 1];
|
2020-11-09 12:25:02 +01:00
|
|
|
|
2020-12-10 09:19:08 +01:00
|
|
|
/* Exactly the same as MPEG-2, except little-endian. */
|
|
|
|
|
static const uint16_t mpeg12_vlc_dc_lum_code_reversed[12] = {
|
|
|
|
|
0x1, 0x0, 0x2, 0x5, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF
|
|
|
|
|
};
|
|
|
|
|
static const uint16_t mpeg12_vlc_dc_chroma_code_reversed[12] = {
|
|
|
|
|
0x0, 0x2, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF
|
|
|
|
|
};
|
2020-11-09 12:25:02 +01:00
|
|
|
|
|
|
|
|
/* simple include everything table for dc, first byte is bits
|
|
|
|
|
* number next 3 are code */
|
|
|
|
|
static uint32_t speedhq_lum_dc_uni[512];
|
|
|
|
|
static uint32_t speedhq_chr_dc_uni[512];
|
|
|
|
|
|
|
|
|
|
static uint8_t uni_speedhq_ac_vlc_len[64 * 64 * 2];
|
|
|
|
|
|
2022-01-25 17:03:47 +01:00
|
|
|
typedef struct SpeedHQEncContext {
|
2025-02-28 18:56:15 +01:00
|
|
|
MPVMainEncContext m;
|
2022-01-25 17:03:47 +01:00
|
|
|
|
|
|
|
|
int slice_start;
|
|
|
|
|
} SpeedHQEncContext;
|
|
|
|
|
|
2020-11-09 12:25:02 +01:00
|
|
|
static av_cold void speedhq_init_static_data(void)
|
|
|
|
|
{
|
2022-10-22 18:55:04 +02:00
|
|
|
ff_rl_init_level_run(speedhq_max_level, speedhq_index_run,
|
|
|
|
|
ff_speedhq_run, ff_speedhq_level, SPEEDHQ_RL_NB_ELEMS);
|
2020-11-09 12:25:02 +01:00
|
|
|
|
|
|
|
|
/* build unified dc encoding tables */
|
|
|
|
|
for (int i = -255; i < 256; i++) {
|
|
|
|
|
int adiff, index;
|
|
|
|
|
int bits, code;
|
|
|
|
|
int diff = i;
|
|
|
|
|
|
|
|
|
|
adiff = FFABS(diff);
|
|
|
|
|
if (diff < 0)
|
|
|
|
|
diff--;
|
|
|
|
|
index = av_log2(2 * adiff);
|
|
|
|
|
|
|
|
|
|
bits = ff_mpeg12_vlc_dc_lum_bits[index] + index;
|
|
|
|
|
code = mpeg12_vlc_dc_lum_code_reversed[index] +
|
2024-06-11 13:50:07 -03:00
|
|
|
(av_zero_extend(diff, index) << ff_mpeg12_vlc_dc_lum_bits[index]);
|
2020-11-09 12:25:02 +01:00
|
|
|
speedhq_lum_dc_uni[i + 255] = bits + (code << 8);
|
|
|
|
|
|
|
|
|
|
bits = ff_mpeg12_vlc_dc_chroma_bits[index] + index;
|
|
|
|
|
code = mpeg12_vlc_dc_chroma_code_reversed[index] +
|
2024-06-11 13:50:07 -03:00
|
|
|
(av_zero_extend(diff, index) << ff_mpeg12_vlc_dc_chroma_bits[index]);
|
2020-11-09 12:25:02 +01:00
|
|
|
speedhq_chr_dc_uni[i + 255] = bits + (code << 8);
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-22 18:55:04 +02:00
|
|
|
ff_mpeg1_init_uni_ac_vlc(speedhq_max_level, speedhq_index_run,
|
2022-10-22 01:33:11 +02:00
|
|
|
ff_speedhq_vlc_table, uni_speedhq_ac_vlc_len);
|
2020-11-09 12:25:02 +01:00
|
|
|
}
|
|
|
|
|
|
2025-03-03 23:35:01 +01:00
|
|
|
static int speedhq_encode_picture_header(MPVMainEncContext *const m)
|
2020-11-09 12:25:02 +01:00
|
|
|
{
|
2025-03-03 23:35:01 +01:00
|
|
|
SpeedHQEncContext *const ctx = (SpeedHQEncContext*)m;
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
MPVEncContext *const s = &m->s;
|
2022-01-25 17:03:47 +01:00
|
|
|
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
put_bits_le(&s->pb, 8, 100 - s->c.qscale * 2); /* FIXME why doubled */
|
2020-11-09 12:25:02 +01:00
|
|
|
put_bits_le(&s->pb, 24, 4); /* no second field */
|
|
|
|
|
|
2022-01-25 17:03:47 +01:00
|
|
|
ctx->slice_start = 4;
|
2020-11-09 12:25:02 +01:00
|
|
|
/* length of first slice, will be filled out later */
|
|
|
|
|
put_bits_le(&s->pb, 24, 0);
|
2025-03-03 23:35:01 +01:00
|
|
|
|
|
|
|
|
return 0;
|
2020-11-09 12:25:02 +01:00
|
|
|
}
|
|
|
|
|
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
void ff_speedhq_end_slice(MPVEncContext *const s)
|
2020-11-09 12:25:02 +01:00
|
|
|
{
|
2022-01-25 17:03:47 +01:00
|
|
|
SpeedHQEncContext *ctx = (SpeedHQEncContext*)s;
|
2020-11-09 12:25:02 +01:00
|
|
|
int slice_len;
|
|
|
|
|
|
|
|
|
|
flush_put_bits_le(&s->pb);
|
2022-01-25 17:03:47 +01:00
|
|
|
slice_len = put_bytes_output(&s->pb) - ctx->slice_start;
|
|
|
|
|
AV_WL24(s->pb.buf + ctx->slice_start, slice_len);
|
2020-11-09 12:25:02 +01:00
|
|
|
|
|
|
|
|
/* length of next slice, will be filled out later */
|
2022-01-25 17:03:47 +01:00
|
|
|
ctx->slice_start = put_bytes_output(&s->pb);
|
2020-11-09 12:25:02 +01:00
|
|
|
put_bits_le(&s->pb, 24, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void encode_dc(PutBitContext *pb, int diff, int component)
|
|
|
|
|
{
|
|
|
|
|
unsigned int diff_u = diff + 255;
|
|
|
|
|
if (diff_u >= 511) {
|
|
|
|
|
int index;
|
|
|
|
|
|
|
|
|
|
if (diff < 0) {
|
|
|
|
|
index = av_log2_16bit(-2 * diff);
|
|
|
|
|
diff--;
|
|
|
|
|
} else {
|
|
|
|
|
index = av_log2_16bit(2 * diff);
|
|
|
|
|
}
|
|
|
|
|
if (component == 0)
|
|
|
|
|
put_bits_le(pb,
|
|
|
|
|
ff_mpeg12_vlc_dc_lum_bits[index] + index,
|
|
|
|
|
mpeg12_vlc_dc_lum_code_reversed[index] +
|
2024-06-11 13:50:07 -03:00
|
|
|
(av_zero_extend(diff, index) << ff_mpeg12_vlc_dc_lum_bits[index]));
|
2020-11-09 12:25:02 +01:00
|
|
|
else
|
|
|
|
|
put_bits_le(pb,
|
|
|
|
|
ff_mpeg12_vlc_dc_chroma_bits[index] + index,
|
|
|
|
|
mpeg12_vlc_dc_chroma_code_reversed[index] +
|
2024-06-11 13:50:07 -03:00
|
|
|
(av_zero_extend(diff, index) << ff_mpeg12_vlc_dc_chroma_bits[index]));
|
2020-11-09 12:25:02 +01:00
|
|
|
} else {
|
|
|
|
|
if (component == 0)
|
|
|
|
|
put_bits_le(pb,
|
|
|
|
|
speedhq_lum_dc_uni[diff + 255] & 0xFF,
|
|
|
|
|
speedhq_lum_dc_uni[diff + 255] >> 8);
|
|
|
|
|
else
|
|
|
|
|
put_bits_le(pb,
|
|
|
|
|
speedhq_chr_dc_uni[diff + 255] & 0xFF,
|
|
|
|
|
speedhq_chr_dc_uni[diff + 255] >> 8);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
static void encode_block(MPVEncContext *const s, const int16_t block[], int n)
|
2020-11-09 12:25:02 +01:00
|
|
|
{
|
|
|
|
|
int alevel, level, last_non_zero, dc, i, j, run, last_index, sign;
|
|
|
|
|
int code;
|
|
|
|
|
int component, val;
|
|
|
|
|
|
|
|
|
|
/* DC coef */
|
|
|
|
|
component = (n <= 3 ? 0 : (n&1) + 1);
|
|
|
|
|
dc = block[0]; /* overflow is impossible */
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
val = s->c.last_dc[component] - dc; /* opposite of most codecs */
|
2020-11-09 12:25:02 +01:00
|
|
|
encode_dc(&s->pb, val, component);
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
s->c.last_dc[component] = dc;
|
2020-11-09 12:25:02 +01:00
|
|
|
|
|
|
|
|
/* now quantify & encode AC coefs */
|
|
|
|
|
last_non_zero = 0;
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
last_index = s->c.block_last_index[n];
|
2020-11-09 12:25:02 +01:00
|
|
|
|
|
|
|
|
for (i = 1; i <= last_index; i++) {
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
j = s->c.intra_scantable.permutated[i];
|
2020-11-09 12:25:02 +01:00
|
|
|
level = block[j];
|
|
|
|
|
|
|
|
|
|
/* encode using VLC */
|
|
|
|
|
if (level != 0) {
|
|
|
|
|
run = i - last_non_zero - 1;
|
|
|
|
|
|
|
|
|
|
alevel = level;
|
|
|
|
|
MASK_ABS(sign, alevel);
|
|
|
|
|
sign &= 1;
|
|
|
|
|
|
2022-10-22 18:55:04 +02:00
|
|
|
if (alevel <= speedhq_max_level[run]) {
|
|
|
|
|
code = speedhq_index_run[run] + alevel - 1;
|
2020-11-09 12:25:02 +01:00
|
|
|
/* store the VLC & sign at once */
|
2022-10-22 00:39:13 +02:00
|
|
|
put_bits_le(&s->pb, ff_speedhq_vlc_table[code][1] + 1,
|
|
|
|
|
ff_speedhq_vlc_table[code][0] | (sign << ff_speedhq_vlc_table[code][1]));
|
2020-11-09 12:25:02 +01:00
|
|
|
} else {
|
2021-12-22 15:09:55 +01:00
|
|
|
/* escape seems to be pretty rare <5% so I do not optimize it;
|
2025-03-19 12:26:47 +01:00
|
|
|
* The following encodes the escape value 100000b together with
|
|
|
|
|
* run and level. */
|
|
|
|
|
put_bits_le(&s->pb, 6 + 6 + 12, 0x20 | run << 6 |
|
|
|
|
|
(level + 2048) << 12);
|
2020-11-09 12:25:02 +01:00
|
|
|
}
|
|
|
|
|
last_non_zero = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-22 00:39:13 +02:00
|
|
|
/* end of block; the values correspond to ff_speedhq_vlc_table[122] */
|
2021-12-22 15:09:55 +01:00
|
|
|
put_bits_le(&s->pb, 4, 6);
|
2020-11-09 12:25:02 +01:00
|
|
|
}
|
|
|
|
|
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
static void speedhq_encode_mb(MPVEncContext *const s, int16_t block[12][64],
|
2025-03-04 19:09:24 +01:00
|
|
|
int unused_x, int unused_y)
|
2020-11-09 12:25:02 +01:00
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0;i<6;i++) {
|
|
|
|
|
encode_block(s, block[i], i);
|
|
|
|
|
}
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
if (s->c.chroma_format == CHROMA_444) {
|
2020-11-09 12:25:02 +01:00
|
|
|
encode_block(s, block[8], 8);
|
|
|
|
|
encode_block(s, block[9], 9);
|
|
|
|
|
|
|
|
|
|
encode_block(s, block[6], 6);
|
|
|
|
|
encode_block(s, block[7], 7);
|
|
|
|
|
|
|
|
|
|
encode_block(s, block[10], 10);
|
|
|
|
|
encode_block(s, block[11], 11);
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
} else if (s->c.chroma_format == CHROMA_422) {
|
2020-11-09 12:25:02 +01:00
|
|
|
encode_block(s, block[6], 6);
|
|
|
|
|
encode_block(s, block[7], 7);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s->i_tex_bits += get_bits_diff(s);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-03 19:24:25 +01:00
|
|
|
static av_cold int speedhq_encode_init(AVCodecContext *avctx)
|
|
|
|
|
{
|
|
|
|
|
static AVOnce init_static_once = AV_ONCE_INIT;
|
2025-03-03 23:35:01 +01:00
|
|
|
MPVMainEncContext *const m = avctx->priv_data;
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
MPVEncContext *const s = &m->s;
|
2025-03-03 19:24:25 +01:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (avctx->width > 65500 || avctx->height > 65500) {
|
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n");
|
|
|
|
|
return AVERROR(EINVAL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// border is not implemented correctly at the moment, see ticket #10078
|
|
|
|
|
if (avctx->width % 16) {
|
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 16\n");
|
|
|
|
|
return AVERROR_PATCHWELCOME;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (avctx->pix_fmt) {
|
|
|
|
|
case AV_PIX_FMT_YUV420P:
|
|
|
|
|
avctx->codec_tag = MKTAG('S','H','Q','0');
|
|
|
|
|
break;
|
|
|
|
|
case AV_PIX_FMT_YUV422P:
|
|
|
|
|
avctx->codec_tag = MKTAG('S','H','Q','2');
|
|
|
|
|
break;
|
|
|
|
|
case AV_PIX_FMT_YUV444P:
|
|
|
|
|
avctx->codec_tag = MKTAG('S','H','Q','4');
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
av_assert0(0);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-03 23:35:01 +01:00
|
|
|
m->encode_picture_header = speedhq_encode_picture_header;
|
2025-03-04 19:09:24 +01:00
|
|
|
s->encode_mb = speedhq_encode_mb;
|
2025-03-03 23:35:01 +01:00
|
|
|
|
2025-03-03 19:24:25 +01:00
|
|
|
s->min_qcoeff = -2048;
|
|
|
|
|
s->max_qcoeff = 2047;
|
|
|
|
|
|
|
|
|
|
s->intra_ac_vlc_length =
|
|
|
|
|
s->intra_ac_vlc_last_length =
|
|
|
|
|
s->intra_chroma_ac_vlc_length =
|
|
|
|
|
s->intra_chroma_ac_vlc_last_length = uni_speedhq_ac_vlc_len;
|
|
|
|
|
|
avcodec/mpegvideoenc: Add MPVEncContext
Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.
More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.
The MotionEstContext has not been moved yet.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-03-19 08:11:01 +01:00
|
|
|
s->c.y_dc_scale_table =
|
|
|
|
|
s->c.c_dc_scale_table = ff_mpeg12_dc_scale_table[3];
|
2025-03-03 19:24:25 +01:00
|
|
|
|
|
|
|
|
ret = ff_mpv_encode_init(avctx);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
ff_thread_once(&init_static_once, speedhq_init_static_data);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-16 21:09:54 +01:00
|
|
|
const FFCodec ff_speedhq_encoder = {
|
|
|
|
|
.p.name = "speedhq",
|
2022-08-29 13:38:02 +02:00
|
|
|
CODEC_LONG_NAME("NewTek SpeedHQ"),
|
2022-03-16 21:09:54 +01:00
|
|
|
.p.type = AVMEDIA_TYPE_VIDEO,
|
|
|
|
|
.p.id = AV_CODEC_ID_SPEEDHQ,
|
|
|
|
|
.p.priv_class = &ff_mpv_enc_class,
|
2024-06-30 17:44:46 +02:00
|
|
|
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
|
2022-01-25 17:03:47 +01:00
|
|
|
.priv_data_size = sizeof(SpeedHQEncContext),
|
2025-03-01 23:37:50 +01:00
|
|
|
.init = speedhq_encode_init,
|
2022-03-30 23:28:24 +02:00
|
|
|
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
|
2020-11-09 12:25:02 +01:00
|
|
|
.close = ff_mpv_encode_end,
|
2022-07-10 00:05:45 +02:00
|
|
|
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
avcodec/internal: add FFCodec.color_ranges
I went through all codecs and put them into five basic categories:
1. JPEG range only
2. MPEG range only
3. Explicitly tagged
4. Broken (codec supports both but encoder ignores tags)
5. N/A (headerless or pseudo-formats)
Filters in category 5 remain untouched. The rest gain an explicit
assignment of their supported color ranges, with codecs in category
4 being set to MPEG-only for safety.
It might be considered redundant to distinguish between 0 (category 5)
and MPEG+JPEG (category 3), but in doing so we effectively communicate
that we can guarantee that these tags will be encoded, which is distinct
from the situation where there are some codecs that simply don't have
tagging or implied semantics (e.g. rawvideo).
A full list of codecs follows:
JPEG range only:
- amv
- roqvideo
MPEG range only:
- asv1, asv2
- avui
- cfhd
- cljr
- dnxhd
- dvvideo
- ffv1
- flv
- h261, h263, h263p
- {h263,vp8}_v4l2m2m
- huffyuv, ffvhuff
- jpeg2000
- libopenjpeg
- libtheora
- libwebp, libwebp_anim
- libx262
- libxavs, libxavs2
- libxvid
- mpeg1video, mpeg2video
- mpeg2_qsv
- mpeg2_vaapi
- mpeg4, msmpeg4, msmpeg4v2, wmv1, wmv2
- mpeg4_omx
- prores, prores_aw, prores_ks
- rv10, rv20
- snow
- speedhq
- svq1
- tiff
- utvideo
Explicitly tagged (MPEG/JPEG):
- {av1,h264,hevc}_nvenc
- {av1,h264,hevc}_vaapi
- {av1,h264,hevc,vp8,vp9,mpeg4}_mediacodec
- {av1,h264,hevc,vp9}_qsv
- h264_amf
- {h264,hevc,prores}_videotoolbox
- libaom-av1
- libkvazaar
- libopenh264
- librav1e
- libsvtav1
- libvpx, libvpx-vp9
- libx264
- libx265
- ljpeg
- mjpeg
- vc2
Broken (encoder ignores tags):
- {av1,hevc}_amf
- {h264,hevc,mpeg4}_v4l2m2m
- h264_omx
- libxeve
- magicyuv
- {vp8,vp9,mjpeg}_vaapi
N/A:
- ayuv, yuv4, y41p, v308, v210, v410, v408 (headerless)
- pgmyuv (headerless)
- rawvideo, bitpacked (headerless)
- vnull, wrapped_avframe (pseudocodecs)
2023-10-11 16:09:33 +02:00
|
|
|
.color_ranges = AVCOL_RANGE_MPEG,
|
2025-03-07 01:19:27 +01:00
|
|
|
CODEC_PIXFMTS(AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P),
|
2020-11-09 12:25:02 +01:00
|
|
|
};
|