[FFmpeg-devel] [PATCH 1/2] spdifenc: IEC 61937 encapsulation of DTS-HD for HDMI

Justin Ruggles justin.ruggles
Thu Jan 27 18:50:16 CET 2011


Hi,

On 01/21/2011 01:32 PM, Anssi Hannula wrote:

> ---
> 
> This time the default mode of operation is to passthrough DTS-core only
> unless the HD mode is explicitely requested by the user via an AVOption.
> 
> This way we avoid exporting the final bitrate in avctx->bit_rate as I
> previously planned, as now the caller always specifies the output rate
> themselves and therefore already knows the output rate (as is the case
> for other formats as well).
> 
> An AVOption is used instead of the previously planned muxrate as the
> usage doesn't exactly match muxrate semantics.
> 
>  Changelog              |    2 +-
>  libavformat/avformat.h |    2 +-
>  libavformat/spdifenc.c |  147 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 149 insertions(+), 2 deletions(-)
> 
> +static int spdif_header_dts4(AVFormatContext *s, AVPacket *pkt, int core_size,
> +                             int sample_rate, int blocks)
> +{
> +    IEC61937Context *ctx = s->priv_data;
> +    const char dtshd_start_code[10] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe };


dtshd_start_code could be made static.

> +    int pkt_size = pkt->size;
> +    int period;
> +    int subtype;
> +
> +    if (!core_size) {
> +        av_log(s, AV_LOG_ERROR, "HD mode not supported for this format\n");
> +        return AVERROR(EINVAL);
> +    }
> +
> +    if (!sample_rate) {
> +        av_log(s, AV_LOG_ERROR, "Unknown DTS sample rate for HD\n");
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    period = ctx->dtshd_rate * (blocks << 5) / sample_rate;
> +    subtype = spdif_dts4_subtype(period);
> +
> +    if (subtype < 0) {
> +        av_log(s, AV_LOG_ERROR, "Specified HD rate of %d Hz would require an "
> +               "impossible repetition period of %d for the current DTS stream"
> +               " (blocks = %d, sample rate = %d)\n", ctx->dtshd_rate, period,
> +               blocks << 5, sample_rate);
> +        return AVERROR(EINVAL);
> +    }
> +
> +    /* set pkt_offset and DTS IV subtype according to the requested output
> +     * rate */
> +    ctx->pkt_offset = period * 4;
> +    ctx->data_type = IEC61937_DTSHD | subtype << 8;
> +
> +    /* If the bitrate is too high for transmitting at the selected
> +     * repetition period setting, strip DTS-HD until a good amount
> +     * of consecutive non-overflowing HD frames have been observed.
> +     * This generally only happens if the caller is cramming a Master
> +     * Audio stream into 192kHz IEC 60958 (which may or may not fit). */
> +    if (sizeof(dtshd_start_code) + 2 + pkt_size
> +            > ctx->pkt_offset - BURST_HEADER_SIZE && core_size) {
> +        if (!ctx->dtshd_skip)
> +            av_log(s, AV_LOG_WARNING, "DTS-HD bitrate too high, "
> +                                      "temporarily sending core only\n");
> +        if (ctx->dtshd_fallback > 0)
> +            ctx->dtshd_skip = sample_rate * ctx->dtshd_fallback / (blocks << 5);
> +        else
> +            /* skip permanently (-1) or just once (0) */
> +            ctx->dtshd_skip = 1;
> +    }
> +    if (ctx->dtshd_skip && core_size) {
> +        pkt_size = core_size;
> +        if (ctx->dtshd_fallback >= 0)
> +            --ctx->dtshd_skip;
> +    }
> +
> +    ctx->hd_buf = av_fast_realloc(ctx->hd_buf, &ctx->hd_buf_size,
> +                                  sizeof(dtshd_start_code) + 2 + pkt_size);
> +    if (!ctx->hd_buf)
> +        return AVERROR(ENOMEM);
> +
> +    memcpy(ctx->hd_buf, dtshd_start_code, sizeof(dtshd_start_code));
> +    AV_WB16(ctx->hd_buf + sizeof(dtshd_start_code), pkt_size);
> +    memcpy(ctx->hd_buf + sizeof(dtshd_start_code) + 2, pkt->data, pkt_size);
> +
> +    ctx->out_buf     = ctx->hd_buf;
> +    ctx->out_bytes   = sizeof(dtshd_start_code) + 2 + pkt_size;
> +    ctx->length_code = ctx->out_bytes;
> +
> +    return 0;
> +}


I see quite a few "sizeof(dtshd_start_code) + 2 + pkt_size".  Could
these be factored out?  Also, is sizeof(char) guaranteed to be 1?  Maybe
uint8_t would be safer.

-Justin



More information about the ffmpeg-devel mailing list