[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