avcodec/dovi_rpu: store entire config record
And make it public. For encoding, users may also be interested in the configured level and compatibility ID. So generalize the dv_profile field and just expose the whole configuration record. This makes the already rather reductive ff_dovi_update_cfg() function almost wholly redundant, since users can just directly assign DOVIContext.cfg.
This commit is contained in:
		
							parent
							
								
									20206e14d7
								
							
						
					
					
						commit
						d0392619a7
					
				@ -885,10 +885,10 @@ static av_cold int av1_decode_init(AVCodecContext *avctx)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->dovi.logctx = avctx;
 | 
			
		||||
    s->dovi.dv_profile = 10; // default for AV1
 | 
			
		||||
    s->dovi.cfg.dv_profile = 10; // default for AV1
 | 
			
		||||
    sd = ff_get_coded_side_data(avctx, AV_PKT_DATA_DOVI_CONF);
 | 
			
		||||
    if (sd && sd->size > 0)
 | 
			
		||||
        ff_dovi_update_cfg(&s->dovi, (AVDOVIDecoderConfigurationRecord *) sd->data);
 | 
			
		||||
    if (sd && sd->size >= sizeof(s->dovi.cfg))
 | 
			
		||||
        s->dovi.cfg = *(AVDOVIDecoderConfigurationRecord *) sd->data;
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -64,7 +64,7 @@ void ff_dovi_ctx_flush(DOVIContext *s)
 | 
			
		||||
 | 
			
		||||
    *s = (DOVIContext) {
 | 
			
		||||
        .logctx = s->logctx,
 | 
			
		||||
        .dv_profile = s->dv_profile,
 | 
			
		||||
        .cfg = s->cfg,
 | 
			
		||||
        /* preserve temporary buffer */
 | 
			
		||||
        .rpu_buf = s->rpu_buf,
 | 
			
		||||
        .rpu_buf_sz = s->rpu_buf_sz,
 | 
			
		||||
@ -74,22 +74,14 @@ void ff_dovi_ctx_flush(DOVIContext *s)
 | 
			
		||||
void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext *s0)
 | 
			
		||||
{
 | 
			
		||||
    s->logctx = s0->logctx;
 | 
			
		||||
    s->cfg = s0->cfg;
 | 
			
		||||
    s->mapping = s0->mapping;
 | 
			
		||||
    s->color = s0->color;
 | 
			
		||||
    s->dv_profile = s0->dv_profile;
 | 
			
		||||
    for (int i = 0; i <= DOVI_MAX_DM_ID; i++)
 | 
			
		||||
        ff_refstruct_replace(&s->vdr[i], s0->vdr[i]);
 | 
			
		||||
    ff_refstruct_replace(&s->ext_blocks, s0->ext_blocks);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ff_dovi_update_cfg(DOVIContext *s, const AVDOVIDecoderConfigurationRecord *cfg)
 | 
			
		||||
{
 | 
			
		||||
    if (!cfg)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    s->dv_profile = cfg->dv_profile;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
 | 
			
		||||
{
 | 
			
		||||
    AVFrameSideData *sd;
 | 
			
		||||
@ -392,7 +384,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size,
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    /* Container */
 | 
			
		||||
    if (s->dv_profile == 10 /* dav1.10 */) {
 | 
			
		||||
    if (s->cfg.dv_profile == 10 /* dav1.10 */) {
 | 
			
		||||
        /* DV inside AV1 re-uses an EMDF container skeleton, but with fixed
 | 
			
		||||
         * values - so we can effectively treat this as a magic byte sequence.
 | 
			
		||||
         *
 | 
			
		||||
@ -517,7 +509,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size,
 | 
			
		||||
    use_prev_vdr_rpu = get_bits1(gb);
 | 
			
		||||
    use_nlq = (hdr->rpu_format & 0x700) == 0 && !hdr->disable_residual_flag;
 | 
			
		||||
 | 
			
		||||
    profile = s->dv_profile ? s->dv_profile : guess_profile(hdr);
 | 
			
		||||
    profile = s->cfg.dv_profile ? s->cfg.dv_profile : guess_profile(hdr);
 | 
			
		||||
    if (profile == 5 && use_nlq) {
 | 
			
		||||
        av_log(s->logctx, AV_LOG_ERROR, "Profile 5 RPUs should not use NLQ\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,16 @@
 | 
			
		||||
typedef struct DOVIContext {
 | 
			
		||||
    void *logctx;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Currently active dolby vision configuration, or {0} for none.
 | 
			
		||||
     * Set by the user when decoding.
 | 
			
		||||
     *
 | 
			
		||||
     * Note: sizeof(cfg) is not part of the libavutil ABI, so users should
 | 
			
		||||
     * never pass &cfg to any other library calls. This is included merely as
 | 
			
		||||
     * a way to look up the values of fields known at compile time.
 | 
			
		||||
     */
 | 
			
		||||
    AVDOVIDecoderConfigurationRecord cfg;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Currently active RPU data header, updates on every dovi_rpu_parse().
 | 
			
		||||
     */
 | 
			
		||||
@ -56,7 +66,6 @@ typedef struct DOVIContext {
 | 
			
		||||
    struct DOVIVdr *vdr[DOVI_MAX_DM_ID+1]; ///< RefStruct references
 | 
			
		||||
    uint8_t *rpu_buf; ///< temporary buffer
 | 
			
		||||
    unsigned rpu_buf_sz;
 | 
			
		||||
    uint8_t dv_profile;
 | 
			
		||||
 | 
			
		||||
} DOVIContext;
 | 
			
		||||
 | 
			
		||||
@ -68,17 +77,11 @@ void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext *s0);
 | 
			
		||||
void ff_dovi_ctx_unref(DOVIContext *s);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Partially reset the internal state. Resets per-frame state while preserving
 | 
			
		||||
 * fields parsed from the configuration record.
 | 
			
		||||
 * Partially reset the internal state. Resets per-frame state, but preserves
 | 
			
		||||
 * the stream-wide configuration record.
 | 
			
		||||
 */
 | 
			
		||||
void ff_dovi_ctx_flush(DOVIContext *s);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read the contents of an AVDOVIDecoderConfigurationRecord (usually provided
 | 
			
		||||
 * by stream side data) and update internal state accordingly.
 | 
			
		||||
 */
 | 
			
		||||
void ff_dovi_update_cfg(DOVIContext *s, const AVDOVIDecoderConfigurationRecord *cfg);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parse the contents of a Dovi RPU NAL and update the parsed values in the
 | 
			
		||||
 * DOVIContext struct.
 | 
			
		||||
 | 
			
		||||
@ -3365,14 +3365,13 @@ static int hevc_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sd = av_packet_get_side_data(avpkt, AV_PKT_DATA_DOVI_CONF, &sd_size);
 | 
			
		||||
    if (sd && sd_size > 0) {
 | 
			
		||||
        int old = s->dovi_ctx.dv_profile;
 | 
			
		||||
 | 
			
		||||
        ff_dovi_update_cfg(&s->dovi_ctx, (AVDOVIDecoderConfigurationRecord *) sd);
 | 
			
		||||
    if (sd && sd_size >= sizeof(s->dovi_ctx.cfg)) {
 | 
			
		||||
        int old = s->dovi_ctx.cfg.dv_profile;
 | 
			
		||||
        s->dovi_ctx.cfg = *(AVDOVIDecoderConfigurationRecord *) sd;
 | 
			
		||||
        if (old)
 | 
			
		||||
            av_log(avctx, AV_LOG_DEBUG,
 | 
			
		||||
                   "New DOVI configuration record from input packet (profile %d -> %u).\n",
 | 
			
		||||
                   old, s->dovi_ctx.dv_profile);
 | 
			
		||||
                   old, s->dovi_ctx.cfg.dv_profile);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->ref = s->collocated_ref = NULL;
 | 
			
		||||
@ -3660,8 +3659,8 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sd = ff_get_coded_side_data(avctx, AV_PKT_DATA_DOVI_CONF);
 | 
			
		||||
        if (sd && sd->size > 0)
 | 
			
		||||
            ff_dovi_update_cfg(&s->dovi_ctx, (AVDOVIDecoderConfigurationRecord *) sd->data);
 | 
			
		||||
        if (sd && sd->size >= sizeof(s->dovi_ctx.cfg))
 | 
			
		||||
            s->dovi_ctx.cfg = *(AVDOVIDecoderConfigurationRecord *) sd->data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
@ -290,10 +290,10 @@ static av_cold int libdav1d_init(AVCodecContext *c)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    dav1d->dovi.logctx = c;
 | 
			
		||||
    dav1d->dovi.dv_profile = 10; // default for AV1
 | 
			
		||||
    dav1d->dovi.cfg.dv_profile = 10; // default for AV1
 | 
			
		||||
    sd = ff_get_coded_side_data(c, AV_PKT_DATA_DOVI_CONF);
 | 
			
		||||
    if (sd && sd->size > 0)
 | 
			
		||||
        ff_dovi_update_cfg(&dav1d->dovi, (AVDOVIDecoderConfigurationRecord *) sd->data);
 | 
			
		||||
    if (sd && sd->size >= sizeof(dav1d->dovi.cfg))
 | 
			
		||||
        dav1d->dovi.cfg = *(AVDOVIDecoderConfigurationRecord *) sd->data;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user