Browse Source

codec: videotoolbox: account fields in pic_pacer

pull/162/head
François Cartegnie 3 years ago
committed by Steve Lhomme
parent
commit
deedd6cee1
  1. 12
      modules/codec/videotoolbox/decoder.c
  2. 55
      modules/codec/videotoolbox/pacer.c
  3. 18
      modules/codec/videotoolbox/pacer.h

12
modules/codec/videotoolbox/decoder.c

@ -2094,7 +2094,7 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_block)
goto skip;
}
pic_pacer_WaitAllocatableSlot(p_sys->pic_pacer);
pic_pacer_WaitAllocatableSlot(p_sys->pic_pacer, p_info->b_field);
VTDecodeInfoFlags flagOut;
VTDecodeFrameFlags decoderFlags = kVTDecodeFrame_EnableAsynchronousDecompression;
@ -2106,7 +2106,7 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_block)
enum vtsession_status vtsession_status;
if (HandleVTStatus(p_dec, status, &vtsession_status) == VLC_SUCCESS)
{
pic_pacer_AccountScheduledDecode(p_sys->pic_pacer);
pic_pacer_AccountScheduledDecode(p_sys->pic_pacer, p_info->b_field);
if(p_sys->decoder_state != STATE_DECODER_STARTED)
{
@ -2216,9 +2216,8 @@ video_context_OnPicReleased(vlc_video_context *vctx, unsigned nb_fields)
{
struct pic_pacer *pic_pacer =
vlc_video_context_GetCVPXPrivate(vctx, CVPX_VIDEO_CONTEXT_VIDEOTOOLBOX);
VLC_UNUSED(nb_fields);
pic_pacer_AccountDeallocation(pic_pacer);
pic_pacer_AccountDeallocation(pic_pacer, nb_fields == 1);
}
static void DecoderCallback(void *decompressionOutputRefCon,
@ -2233,6 +2232,7 @@ static void DecoderCallback(void *decompressionOutputRefCon,
decoder_t *p_dec = (decoder_t *)decompressionOutputRefCon;
decoder_sys_t *p_sys = p_dec->p_sys;
frame_info_t *p_info = (frame_info_t *) sourceFrameRefCon;
const bool b_field = p_info->b_field;
vlc_mutex_lock(&p_sys->lock);
if (p_sys->b_discard_decoder_output)
@ -2305,7 +2305,7 @@ static void DecoderCallback(void *decompressionOutputRefCon,
* allocating way too many frames. This can be problematic for 4K
* 10bits. To fix this issue, we ensure that we don't have too many
* output frames allocated by waiting for the vout to release them. */
pic_pacer_AccountAllocation(p_sys->pic_pacer);
pic_pacer_AccountAllocation(p_sys->pic_pacer, p_info->b_field);
}
}
@ -2322,7 +2322,7 @@ static void DecoderCallback(void *decompressionOutputRefCon,
end:
free(p_info);
vlc_mutex_unlock(&p_sys->lock);
pic_pacer_AccountFinishedDecode(p_sys->pic_pacer);
pic_pacer_AccountFinishedDecode(p_sys->pic_pacer, b_field);
return;
}

55
modules/codec/videotoolbox/pacer.c

@ -41,62 +41,63 @@ void pic_pacer_Init(struct pic_pacer *pic_pacer)
{
vlc_mutex_init(&pic_pacer->lock);
vlc_cond_init(&pic_pacer->wait);
pic_pacer->nb_out = 0;
pic_pacer->allocated_max = 6;
pic_pacer->allocated_next = pic_pacer->allocated_max;
pic_pacer->queued_for_decode = 0;
pic_pacer->nb_fields_out = 0;
pic_pacer->allocated_fields_max = 6 /* pics */ * 2;
pic_pacer->allocated_fields_next = pic_pacer->allocated_fields_max;
pic_pacer->queued_fields_for_decode = 0;
}
void pic_pacer_AccountAllocation(struct pic_pacer *pic_pacer)
void pic_pacer_AccountAllocation(struct pic_pacer *pic_pacer, bool b_field)
{
vlc_mutex_lock(&pic_pacer->lock);
pic_pacer->nb_out += 1;
pic_pacer->nb_fields_out += b_field ? 1 : 2;
vlc_mutex_unlock(&pic_pacer->lock);
}
void pic_pacer_AccountScheduledDecode(struct pic_pacer *pic_pacer)
void pic_pacer_AccountScheduledDecode(struct pic_pacer *pic_pacer, bool b_field)
{
vlc_mutex_lock(&pic_pacer->lock);
pic_pacer->queued_for_decode += 1;
pic_pacer->queued_fields_for_decode += b_field ? 1 : 2;
vlc_mutex_unlock(&pic_pacer->lock);
}
void pic_pacer_AccountFinishedDecode(struct pic_pacer *pic_pacer)
void pic_pacer_AccountFinishedDecode(struct pic_pacer *pic_pacer, bool b_field)
{
vlc_mutex_lock(&pic_pacer->lock);
pic_pacer->queued_for_decode -= 1;
pic_pacer->queued_fields_for_decode -= b_field ? 1 : 2;
vlc_cond_signal(&pic_pacer->wait);
vlc_mutex_unlock(&pic_pacer->lock);
}
void pic_pacer_WaitAllocatableSlot(struct pic_pacer *pic_pacer)
void pic_pacer_WaitAllocatableSlot(struct pic_pacer *pic_pacer, bool b_field)
{
vlc_mutex_lock(&pic_pacer->lock);
uint8_t allocatable_total = pic_pacer->allocated_max + PIC_PACER_DECODE_QUEUE;
uint8_t allocatable_fields_total = pic_pacer->allocated_fields_max + PIC_PACER_DECODE_QUEUE;
while( pic_pacer->queued_for_decode + pic_pacer->nb_out >= allocatable_total )
while( pic_pacer->queued_fields_for_decode +
pic_pacer->nb_fields_out + (1 - !!b_field) >= allocatable_fields_total )
{
#ifdef PIC_PACER_DEBUG
fprintf(stderr, "input pacing %d+%d >= %d\n",
pic_pacer->queued_for_decode, pic_pacer->nb_out, allocatable_total);
pic_pacer->queued_fields_for_decode, pic_pacer->nb_fields_out, allocatable_fields_total);
#endif
vlc_cond_wait(&pic_pacer->wait, &pic_pacer->lock);
/*update*/
allocatable_total = pic_pacer->allocated_max + PIC_PACER_DECODE_QUEUE;
allocatable_fields_total = pic_pacer->allocated_fields_max + PIC_PACER_DECODE_QUEUE;
}
vlc_mutex_unlock(&pic_pacer->lock);
}
void pic_pacer_AccountDeallocation(struct pic_pacer *pic_pacer)
void pic_pacer_AccountDeallocation(struct pic_pacer *pic_pacer, bool b_field)
{
vlc_mutex_lock(&pic_pacer->lock);
assert(pic_pacer->nb_out > 0);
pic_pacer->nb_out -= 1;
assert(pic_pacer->nb_fields_out > 0);
pic_pacer->nb_fields_out -= (b_field ? 1 : 2);
/* our shrink condition */
if(pic_pacer->allocated_next < pic_pacer->allocated_max &&
pic_pacer->nb_out <= pic_pacer->allocated_next)
pic_pacer->allocated_max = pic_pacer->allocated_next;
if(pic_pacer->allocated_fields_next < pic_pacer->allocated_fields_max &&
pic_pacer->nb_fields_out <= pic_pacer->allocated_fields_next)
pic_pacer->allocated_fields_max = pic_pacer->allocated_fields_next;
vlc_cond_signal(&pic_pacer->wait);
@ -107,21 +108,21 @@ void pic_pacer_UpdateMaxBuffering(struct pic_pacer *pic_pacer, uint8_t pic_max)
{
vlc_mutex_lock(&pic_pacer->lock);
pic_max += PIC_PACER_ALLOCATABLE_MAX;
bool b_growing = pic_max > pic_pacer->allocated_max;
const uint8_t fields_max = (pic_max + PIC_PACER_ALLOCATABLE_MAX) * 2;
bool b_growing = fields_max > pic_pacer->allocated_fields_max;
#ifdef PIC_PACER_DEBUG
fprintf(stderr, "updating pacer max %d/%d to %d\n",
pic_pacer->nb_out, pic_pacer->allocated_max, pic_reorder_max);
pic_pacer->nb_fields_out, pic_pacer->allocated_fields_max / 2, pic_max);
#endif
if(b_growing)
{
pic_pacer->allocated_max = pic_max;
pic_pacer->allocated_next = pic_max;
pic_pacer->allocated_fields_max = fields_max;
pic_pacer->allocated_fields_next = fields_max;
vlc_cond_signal(&pic_pacer->wait);
}
else
{
pic_pacer->allocated_next = pic_max;
pic_pacer->allocated_fields_next = fields_max;
}
vlc_mutex_unlock(&pic_pacer->lock);

18
modules/codec/videotoolbox/pacer.h

@ -24,25 +24,25 @@ struct pic_pacer
{
vlc_mutex_t lock;
vlc_cond_t wait;
uint8_t nb_out;
uint8_t allocated_max;
uint8_t allocated_next;
uint8_t queued_for_decode;
uint8_t nb_fields_out;
uint8_t allocated_fields_max;
uint8_t allocated_fields_next;
uint8_t queued_fields_for_decode;
};
void pic_pacer_Clean(struct pic_pacer *);
void pic_pacer_Init(struct pic_pacer *);
void pic_pacer_AccountAllocation(struct pic_pacer *);
void pic_pacer_AccountAllocation(struct pic_pacer *, bool b_field);
void pic_pacer_AccountScheduledDecode(struct pic_pacer *);
void pic_pacer_AccountScheduledDecode(struct pic_pacer *, bool b_field);
void pic_pacer_AccountFinishedDecode(struct pic_pacer *);
void pic_pacer_AccountFinishedDecode(struct pic_pacer *, bool b_field);
void pic_pacer_WaitAllocatableSlot(struct pic_pacer *);
void pic_pacer_WaitAllocatableSlot(struct pic_pacer *, bool b_field);
void pic_pacer_AccountDeallocation(struct pic_pacer *);
void pic_pacer_AccountDeallocation(struct pic_pacer *, bool b_field);
void pic_pacer_UpdateMaxBuffering(struct pic_pacer *, uint8_t);

Loading…
Cancel
Save