Ticket #372: spdifenc.patch2

File spdifenc.patch2, 3.6 KB (added by naoya, 5 years ago)

spdifenc.patch2

Line 
1diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c
2index 04d4845..c520d43 100644
3--- a/libavformat/spdifenc.c
4+++ b/libavformat/spdifenc.c
5@@ -48,11 +48,16 @@
6 #include "avio_internal.h"
7 #include "spdif.h"
8 #include "libavcodec/ac3.h"
9+#include "libavcodec/ac3_parser.h"
10 #include "libavcodec/dca.h"
11 #include "libavcodec/dcadata.h"
12 #include "libavcodec/aacadtsdec.h"
13 #include "libavutil/opt.h"
14 
15+#ifndef AC3_HEADER_SIZE
16+#define AC3_HEADER_SIZE 7
17+#endif
18+
19 typedef struct IEC61937Context {
20     const AVClass *av_class;
21     enum IEC61937DataType data_type;///< burst info - reference to type of payload of the data-burst
22@@ -103,10 +108,26 @@ static const AVClass class = {
23 static int spdif_header_ac3(AVFormatContext *s, AVPacket *pkt)
24 {
25     IEC61937Context *ctx = s->priv_data;
26-    int bitstream_mode = pkt->data[5] & 0x7;
27+    AC3HeaderInfo hdr;
28+    GetBitContext gbc;
29+    int ret;
30 
31-    ctx->data_type  = IEC61937_AC3 | (bitstream_mode << 8);
32-    ctx->pkt_offset = AC3_FRAME_SIZE << 2;
33+    if (pkt->size < AC3_HEADER_SIZE)
34+        return AVERROR_INVALIDDATA;
35+    init_get_bits(&gbc, pkt->data, AC3_HEADER_SIZE * 8);
36+    ret = ff_ac3_parse_header(&gbc, &hdr);
37+    if (ret) {
38+        av_log(s, AV_LOG_ERROR, "Wrong AC3 file format\n");
39+        return AVERROR_INVALIDDATA;
40+    }
41+    if (hdr.num_blocks != 6) {
42+        av_log(s, AV_LOG_ERROR, "AC3 invalid num_blocks[%d]\n", hdr.num_blocks);
43+        return AVERROR_INVALIDDATA;
44+    }
45+    ctx->data_type   = IEC61937_AC3 | (hdr.bitstream_mode <<8);
46+    ctx->pkt_offset  = AC3_FRAME_SIZE <<2;
47+    ctx->out_bytes   = hdr.frame_size;
48+    ctx->length_code = ctx->out_bytes <<3;
49     return 0;
50 }
51 
52@@ -355,7 +376,9 @@ static int spdif_header_aac(AVFormatContext *s, AVPacket *pkt)
53         return AVERROR_INVALIDDATA;
54     }
55 
56-    ctx->pkt_offset = hdr.samples << 2;
57+    ctx->out_bytes   = ret;
58+    ctx->pkt_offset  = hdr.samples << 2;
59+    ctx->length_code = ctx->out_bytes <<3;
60     switch (hdr.num_aac_frames) {
61     case 1:
62         ctx->data_type = IEC61937_MPEG2_AAC;
63@@ -473,8 +496,8 @@ static int spdif_write_header(AVFormatContext *s)
64 static int spdif_write_trailer(AVFormatContext *s)
65 {
66     IEC61937Context *ctx = s->priv_data;
67-    av_freep(&ctx->buffer);
68-    av_freep(&ctx->hd_buf);
69+    av_free(ctx->buffer);
70+    av_free(ctx->hd_buf);
71     return 0;
72 }
73 
74@@ -503,6 +526,8 @@ static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt)
75         return ret;
76     if (!ctx->pkt_offset)
77         return 0;
78+    if (pkt->size < ctx->out_bytes)
79+        return -1;
80 
81     padding = (ctx->pkt_offset - ctx->use_preamble * BURST_HEADER_SIZE - ctx->out_bytes) & ~1;
82     if (padding < 0) {
83@@ -518,13 +543,14 @@ static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt)
84     }
85 
86     if (ctx->extra_bswap ^ (ctx->spdif_flags & SPDIF_FLAG_BIGENDIAN)) {
87-    avio_write(s->pb, ctx->out_buf, ctx->out_bytes & ~1);
88+        avio_write(s->pb, ctx->out_buf, ctx->out_bytes & ~1);
89     } else {
90-    av_fast_malloc(&ctx->buffer, &ctx->buffer_size, ctx->out_bytes + FF_INPUT_BUFFER_PADDING_SIZE);
91-    if (!ctx->buffer)
92-        return AVERROR(ENOMEM);
93-    ff_spdif_bswap_buf16((uint16_t *)ctx->buffer, (uint16_t *)ctx->out_buf, ctx->out_bytes >> 1);
94-    avio_write(s->pb, ctx->buffer, ctx->out_bytes & ~1);
95+        ctx->buffer = av_mallocz(ctx->out_bytes + FF_INPUT_BUFFER_PADDING_SIZE);
96+        if (!ctx->buffer)
97+            return AVERROR(ENOMEM);
98+        ff_spdif_bswap_buf16((uint16_t *)ctx->buffer, (uint16_t *)ctx->out_buf, ctx->out_bytes >> 1);
99+        avio_write(s->pb, ctx->buffer, ctx->out_bytes & ~1);
100+        spdif_write_trailer(s);
101     }
102 
103     /* a final lone byte has to be MSB aligned */