|
|
|
@@ -76,6 +76,8 @@ typedef struct IEC61937Context { |
|
|
|
/* AVOptions: */ |
|
|
|
int dtshd_rate; |
|
|
|
int dtshd_fallback; |
|
|
|
#define SPDIF_FLAG_BIGENDIAN 0x01 |
|
|
|
int spdif_flags; |
|
|
|
|
|
|
|
/// function, which generates codec dependent header information. |
|
|
|
/// Sets data_type and pkt_offset, and length_code, out_bytes, out_buf if necessary |
|
|
|
@@ -83,6 +85,8 @@ typedef struct IEC61937Context { |
|
|
|
} IEC61937Context; |
|
|
|
|
|
|
|
static const AVOption options[] = { |
|
|
|
{ "spdif_flags", "IEC 61937 encapsulation flags", offsetof(IEC61937Context, spdif_flags), FF_OPT_TYPE_FLAGS, 0, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "spdif_flags" }, |
|
|
|
{ "be", "output in big-endian format (for use as s16be)", 0, FF_OPT_TYPE_CONST, SPDIF_FLAG_BIGENDIAN, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "spdif_flags" }, |
|
|
|
{ "dtshd_rate", "mux complete DTS frames in HD mode at the specified IEC958 rate (in Hz, default 0=disabled)", offsetof(IEC61937Context, dtshd_rate), FF_OPT_TYPE_INT, 0, 0, 768000, AV_OPT_FLAG_ENCODING_PARAM }, |
|
|
|
{ "dtshd_fallback_time", "min secs to strip HD for after an overflow (-1: till the end, default 60)", offsetof(IEC61937Context, dtshd_fallback), FF_OPT_TYPE_INT, 60, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, |
|
|
|
{ NULL }, |
|
|
|
@@ -477,6 +481,15 @@ static int spdif_write_trailer(AVFormatContext *s) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static av_always_inline void spdif_put_16(IEC61937Context *ctx, |
|
|
|
ByteIOContext *pb, unsigned int val) |
|
|
|
{ |
|
|
|
if (ctx->spdif_flags & SPDIF_FLAG_BIGENDIAN) |
|
|
|
put_be16(pb, val); |
|
|
|
else |
|
|
|
put_le16(pb, val); |
|
|
|
} |
|
|
|
|
|
|
|
static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt) |
|
|
|
{ |
|
|
|
IEC61937Context *ctx = s->priv_data; |
|
|
|
@@ -501,13 +514,13 @@ static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt) |
|
|
|
} |
|
|
|
|
|
|
|
if (ctx->use_preamble) { |
|
|
|
put_le16(s->pb, SYNCWORD1); //Pa |
|
|
|
put_le16(s->pb, SYNCWORD2); //Pb |
|
|
|
put_le16(s->pb, ctx->data_type); //Pc |
|
|
|
put_le16(s->pb, ctx->length_code);//Pd |
|
|
|
spdif_put_16(ctx, s->pb, SYNCWORD1); //Pa |
|
|
|
spdif_put_16(ctx, s->pb, SYNCWORD2); //Pb |
|
|
|
spdif_put_16(ctx, s->pb, ctx->data_type); //Pc |
|
|
|
spdif_put_16(ctx, s->pb, ctx->length_code);//Pd |
|
|
|
} |
|
|
|
|
|
|
|
if (HAVE_BIGENDIAN ^ ctx->extra_bswap) { |
|
|
|
if (ctx->extra_bswap ^ (ctx->spdif_flags & SPDIF_FLAG_BIGENDIAN)) { |
|
|
|
put_buffer(s->pb, ctx->out_buf, ctx->out_bytes & ~1); |
|
|
|
} else { |
|
|
|
av_fast_malloc(&ctx->buffer, &ctx->buffer_size, ctx->out_bytes + FF_INPUT_BUFFER_PADDING_SIZE); |
|
|
|
@@ -517,8 +530,9 @@ static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt) |
|
|
|
put_buffer(s->pb, ctx->buffer, ctx->out_bytes & ~1); |
|
|
|
} |
|
|
|
|
|
|
|
/* a final lone byte has to be MSB aligned */ |
|
|
|
if (ctx->out_bytes & 1) |
|
|
|
put_be16(s->pb, ctx->out_buf[ctx->out_bytes - 1]); |
|
|
|
spdif_put_16(ctx, s->pb, ctx->out_buf[ctx->out_bytes - 1] << 8); |
|
|
|
|
|
|
|
put_nbyte(s->pb, 0, padding); |
|
|
|
|
|
|
|
|