avcodec/dvenc: Support adjusting the quantizer deadzone
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
		
							parent
							
								
									a5380f9c1c
								
							
						
					
					
						commit
						fea7bc9e7b
					
				| @ -38,6 +38,7 @@ typedef struct DVwork_chunk { | |||||||
| } DVwork_chunk; | } DVwork_chunk; | ||||||
| 
 | 
 | ||||||
| typedef struct DVVideoContext { | typedef struct DVVideoContext { | ||||||
|  |     AVClass *avclass; | ||||||
|     const AVDVProfile *sys; |     const AVDVProfile *sys; | ||||||
|     const AVFrame   *frame; |     const AVFrame   *frame; | ||||||
|     AVCodecContext  *avctx; |     AVCodecContext  *avctx; | ||||||
| @ -51,6 +52,8 @@ typedef struct DVVideoContext { | |||||||
|     me_cmp_func ildct_cmp; |     me_cmp_func ildct_cmp; | ||||||
|     DVwork_chunk work_chunks[4 * 12 * 27]; |     DVwork_chunk work_chunks[4 * 12 * 27]; | ||||||
|     uint32_t idct_factor[2 * 4 * 16 * 64]; |     uint32_t idct_factor[2 * 4 * 16 * 64]; | ||||||
|  | 
 | ||||||
|  |     int quant_deadzone; | ||||||
| } DVVideoContext; | } DVVideoContext; | ||||||
| 
 | 
 | ||||||
| enum dv_section_type { | enum dv_section_type { | ||||||
|  | |||||||
| @ -17,6 +17,8 @@ | |||||||
|  * You should have received a copy of the GNU Lesser General Public |  * You should have received a copy of the GNU Lesser General Public | ||||||
|  * License along with FFmpeg; if not, write to the Free Software |  * License along with FFmpeg; if not, write to the Free Software | ||||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||||
|  |  * | ||||||
|  |  * quant_deadzone code and fixes sponsored by NOA GmbH | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -28,6 +30,7 @@ | |||||||
| 
 | 
 | ||||||
| #include "libavutil/attributes.h" | #include "libavutil/attributes.h" | ||||||
| #include "libavutil/internal.h" | #include "libavutil/internal.h" | ||||||
|  | #include "libavutil/opt.h" | ||||||
| #include "libavutil/pixdesc.h" | #include "libavutil/pixdesc.h" | ||||||
| 
 | 
 | ||||||
| #include "avcodec.h" | #include "avcodec.h" | ||||||
| @ -265,6 +268,8 @@ static av_always_inline int dv_init_enc_block(EncBlockInfo *bi, uint8_t *data, | |||||||
| #endif | #endif | ||||||
|     int max  = classes[0]; |     int max  = classes[0]; | ||||||
|     int prev = 0; |     int prev = 0; | ||||||
|  |     const unsigned deadzone = s->quant_deadzone; | ||||||
|  |     const unsigned threshold = 2 * deadzone; | ||||||
| 
 | 
 | ||||||
|     av_assert2((((int) blk) & 15) == 0); |     av_assert2((((int) blk) & 15) == 0); | ||||||
| 
 | 
 | ||||||
| @ -297,13 +302,15 @@ static av_always_inline int dv_init_enc_block(EncBlockInfo *bi, uint8_t *data, | |||||||
|         for (i = mb_area_start[area]; i < mb_area_start[area + 1]; i++) { |         for (i = mb_area_start[area]; i < mb_area_start[area + 1]; i++) { | ||||||
|             int level = blk[zigzag_scan[i]]; |             int level = blk[zigzag_scan[i]]; | ||||||
| 
 | 
 | ||||||
|             if (level + 15 > 30U) { |             if (level + deadzone > threshold) { | ||||||
|                 bi->sign[i] = (level >> 31) & 1; |                 bi->sign[i] = (level >> 31) & 1; | ||||||
|                 /* Weight it and shift down into range, adding for rounding.
 |                 /* Weight it and shift down into range, adding for rounding.
 | ||||||
|                  * The extra division by a factor of 2^4 reverses the 8x |                  * The extra division by a factor of 2^4 reverses the 8x | ||||||
|                  * expansion of the DCT AND the 2x doubling of the weights. */ |                  * expansion of the DCT AND the 2x doubling of the weights. */ | ||||||
|                 level     = (FFABS(level) * weight[i] + (1 << (dv_weight_bits + 3))) >> |                 level     = (FFABS(level) * weight[i] + (1 << (dv_weight_bits + 3))) >> | ||||||
|                             (dv_weight_bits + 4); |                             (dv_weight_bits + 4); | ||||||
|  |                 if (!level) | ||||||
|  |                     continue; | ||||||
|                 bi->mb[i] = level; |                 bi->mb[i] = level; | ||||||
|                 if (level > max) |                 if (level > max) | ||||||
|                     max = level; |                     max = level; | ||||||
| @ -746,6 +753,20 @@ FF_ENABLE_DEPRECATION_WARNINGS | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM | ||||||
|  | #define OFFSET(x) offsetof(DVVideoContext, x) | ||||||
|  | static const AVOption dv_options[] = { | ||||||
|  |     { "quant_deadzone",        "Quantizer dead zone",    OFFSET(quant_deadzone),       AV_OPT_TYPE_INT, { .i64 = 15 }, 0, 1024, VE }, | ||||||
|  |     { NULL }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const AVClass dvvideo_encode_class = { | ||||||
|  |     .class_name = "dvvideo encoder", | ||||||
|  |     .item_name  = av_default_item_name, | ||||||
|  |     .option     = dv_options, | ||||||
|  |     .version    = LIBAVUTIL_VERSION_INT, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| AVCodec ff_dvvideo_encoder = { | AVCodec ff_dvvideo_encoder = { | ||||||
|     .name           = "dvvideo", |     .name           = "dvvideo", | ||||||
|     .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), |     .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), | ||||||
| @ -759,4 +780,5 @@ AVCodec ff_dvvideo_encoder = { | |||||||
|         AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P, |         AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P, | ||||||
|         AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE |         AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE | ||||||
|     }, |     }, | ||||||
|  |     .priv_class     = &dvvideo_encode_class, | ||||||
| }; | }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user