|  | @@ -867,6 +867,12 @@ typedef struct HDCDContext { | 
														
													
														
															
																|  |  | const AVClass *class; |  |  | const AVClass *class; | 
														
													
														
															
																|  |  | hdcd_state_t state[2]; |  |  | hdcd_state_t state[2]; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | /* always extend peaks above -3dBFS even if PE isn't signaled | 
														
													
														
															
																|  |  |  |  |  | * -af hdcd=force_pe=0 for off | 
														
													
														
															
																|  |  |  |  |  | * -af hdcd=force_pe=1 for on | 
														
													
														
															
																|  |  |  |  |  | * default is off */ | 
														
													
														
															
																|  |  |  |  |  | int force_pe; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | AVFilterContext *fctx; /* filter context for logging errors */ |  |  | AVFilterContext *fctx; /* filter context for logging errors */ | 
														
													
														
															
																|  |  | int sample_count;      /* used in error logging */ |  |  | int sample_count;      /* used in error logging */ | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -878,7 +884,10 @@ typedef struct HDCDContext { | 
														
													
														
															
																|  |  | float max_gain_adjustment; /* in dB, expected in the range -6.0 to 0.0 */ |  |  | float max_gain_adjustment; /* in dB, expected in the range -6.0 to 0.0 */ | 
														
													
														
															
																|  |  | } HDCDContext; |  |  | } HDCDContext; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | #define OFFSET(x) offsetof(HDCDContext, x) | 
														
													
														
															
																|  |  | static const AVOption hdcd_options[] = { |  |  | static const AVOption hdcd_options[] = { | 
														
													
														
															
																|  |  |  |  |  | { "force_pe", "Always extend peaks above -3dBFS even when PE is not signaled.", | 
														
													
														
															
																|  |  |  |  |  | OFFSET(force_pe), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, 0 }, | 
														
													
														
															
																|  |  | {NULL} |  |  | {NULL} | 
														
													
														
															
																|  |  | }; |  |  | }; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -1093,14 +1102,21 @@ static int hdcd_envelope(int32_t *samples, int count, int stride, int gain, int | 
														
													
														
															
																|  |  | return gain; |  |  | return gain; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | /* extract fields from control code */ | 
														
													
														
															
																|  |  |  |  |  | static void hdcd_control(HDCDContext *ctx, hdcd_state_t *state, int *peak_extend, int *target_gain) | 
														
													
														
															
																|  |  |  |  |  | { | 
														
													
														
															
																|  |  |  |  |  | *peak_extend = (ctx->force_pe || state->control & 16); | 
														
													
														
															
																|  |  |  |  |  | *target_gain = (state->control & 15) << 7; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | static void hdcd_process(HDCDContext *ctx, hdcd_state_t *state, int32_t *samples, int count, int stride) |  |  | static void hdcd_process(HDCDContext *ctx, hdcd_state_t *state, int32_t *samples, int count, int stride) | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | int32_t *samples_end = samples + count * stride; |  |  | int32_t *samples_end = samples + count * stride; | 
														
													
														
															
																|  |  | int gain = state->running_gain; |  |  | int gain = state->running_gain; | 
														
													
														
															
																|  |  | int peak_extend = (state->control & 16); |  |  |  | 
														
													
														
															
																|  |  | int target_gain = (state->control & 15) << 7; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | int peak_extend, target_gain; | 
														
													
														
															
																|  |  | int lead = 0; |  |  | int lead = 0; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | hdcd_control(ctx, state, &peak_extend, &target_gain); | 
														
													
														
															
																|  |  | while (count > lead) { |  |  | while (count > lead) { | 
														
													
														
															
																|  |  | int envelope_run; |  |  | int envelope_run; | 
														
													
														
															
																|  |  | int run; |  |  | int run; | 
														
													
												
													
														
															
																|  | @@ -1115,8 +1131,7 @@ static void hdcd_process(HDCDContext *ctx, hdcd_state_t *state, int32_t *samples | 
														
													
														
															
																|  |  | samples += envelope_run * stride; |  |  | samples += envelope_run * stride; | 
														
													
														
															
																|  |  | count -= envelope_run; |  |  | count -= envelope_run; | 
														
													
														
															
																|  |  | lead = run - envelope_run; |  |  | lead = run - envelope_run; | 
														
													
														
															
																|  |  | peak_extend = (state->control & 16); |  |  |  | 
														
													
														
															
																|  |  | target_gain = (state->control & 15) << 7; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | hdcd_control(ctx, state, &peak_extend, &target_gain); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | if (lead > 0) { |  |  | if (lead > 0) { | 
														
													
														
															
																|  |  | av_assert0(samples + lead * stride <= samples_end); |  |  | av_assert0(samples + lead * stride <= samples_end); | 
														
													
												
													
														
															
																|  | @@ -1285,6 +1300,9 @@ static av_cold int init(AVFilterContext *ctx) | 
														
													
														
															
																|  |  | hdcd_reset(&s->state[c], 44100); |  |  | hdcd_reset(&s->state[c], 44100); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | av_log(ctx, AV_LOG_VERBOSE, "Force PE: %s\n", | 
														
													
														
															
																|  |  |  |  |  | (s->force_pe) ? "on" : "off"); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | return 0; |  |  | return 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | 
 |