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

Anssi Hannula anssi.hannula
Thu Jan 27 19:21:41 CET 2011


On 27.01.2011 19:50, Justin Ruggles wrote:
> Hi,

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.

Hm, what difference would it make?

Since it is a constant, the values are retained over calls by definition
even without "static" keyword, and indeed there seems to be no
difference between "const" or "static const" inside a function in output
of gcc.

>> +    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?

Ok, will do.

Thanks,
-- 
Anssi Hannula



More information about the ffmpeg-devel mailing list