]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/truehd_core_bsf.c
avfilter/avfilter: Remove compatibility code for old filter options
[ffmpeg] / libavcodec / truehd_core_bsf.c
index be021af8e83c63b32d898c0840da2dcb00af5917..cc2779cc2e3715384fadc9f769f542e92a6d8d2c 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "avcodec.h"
 #include "bsf.h"
+#include "bsf_internal.h"
 #include "get_bits.h"
-#include "mlp_parser.h"
+#include "mlp_parse.h"
 #include "mlp.h"
 
 typedef struct AccessUnit {
@@ -31,100 +31,96 @@ typedef struct AccessUnit {
 } AccessUnit;
 
 typedef struct TrueHDCoreContext {
-    const AVClass *class;
-
     MLPHeaderInfo hdr;
 } TrueHDCoreContext;
 
-static int truehd_core_filter(AVBSFContext *ctx, AVPacket *out)
+static int truehd_core_filter(AVBSFContext *ctx, AVPacket *pkt)
 {
     TrueHDCoreContext *s = ctx->priv_data;
     GetBitContext gbc;
     AccessUnit units[MAX_SUBSTREAMS];
-    AVPacket *in;
-    int ret, i, size, last_offset = 0;
+    int ret, i, last_offset = 0;
     int in_size, out_size;
     int have_header = 0;
-    int substream_bits = 0;
-    int start, end;
-    uint16_t dts;
+    int substream_bytes = 0;
+    int end;
 
-    ret = ff_bsf_get_packet(ctx, &in);
+    ret = ff_bsf_get_packet_ref(ctx, pkt);
     if (ret < 0)
         return ret;
 
-    if (in->size < 4)
-        goto fail;
-
-    ret = init_get_bits(&gbc, in->data, 32);
-    if (ret < 0)
+    if (pkt->size < 4) {
+        ret = AVERROR_INVALIDDATA;
         goto fail;
+    }
 
-    skip_bits(&gbc, 4);
-    in_size = get_bits(&gbc, 12) * 2;
-    if (in_size < 4 || in_size > in->size)
+    in_size = (AV_RB16(pkt->data) & 0xFFF) * 2;
+    if (in_size < 4 || in_size > pkt->size) {
+        ret = AVERROR_INVALIDDATA;
         goto fail;
+    }
 
-    out_size = in_size;
-    dts = get_bits(&gbc, 16);
-
-    ret = init_get_bits8(&gbc, in->data + 4, in->size - 4);
+    ret = init_get_bits8(&gbc, pkt->data + 4, pkt->size - 4);
     if (ret < 0)
         goto fail;
 
     if (show_bits_long(&gbc, 32) == 0xf8726fba) {
-        if ((ret = ff_mlp_read_major_sync(ctx, &s->hdr, &gbc)) != 0)
+        if ((ret = ff_mlp_read_major_sync(ctx, &s->hdr, &gbc)) < 0)
             goto fail;
         have_header = 1;
     }
 
-    if (s->hdr.num_substreams > MAX_SUBSTREAMS)
+    if (s->hdr.num_substreams > MAX_SUBSTREAMS) {
+        ret = AVERROR_INVALIDDATA;
         goto fail;
+    }
 
-    start = get_bits_count(&gbc);
     for (i = 0; i < s->hdr.num_substreams; i++) {
         for (int j = 0; j < 4; j++)
             units[i].bits[j] = get_bits1(&gbc);
 
-        units[i].offset = get_bits(&gbc, 12) * 2;
-        if (i < FFMIN(s->hdr.num_substreams, 3)) {
-            last_offset = units[i].offset;
-            substream_bits += 16;
+        units[i].offset = get_bits(&gbc, 12);
+        if (i < 3) {
+            last_offset = units[i].offset * 2;
+            substream_bytes += 2;
         }
 
         if (units[i].bits[0]) {
             units[i].optional = get_bits(&gbc, 16);
-            if (i < FFMIN(s->hdr.num_substreams, 3))
-                substream_bits += 16;
+            if (i < 3)
+                substream_bytes += 2;
         }
     }
-    end = get_bits_count(&gbc);
+    end = get_bits_count(&gbc) >> 3;
 
-    size = ((end + 7) >> 3) + 4 + last_offset;
-    if (size >= 0 && size <= in->size)
-        out_size = size;
+    out_size = end + 4 + last_offset;
     if (out_size < in_size) {
-        int bpos = 0, reduce = (end - start - substream_bits) >> 4;
-        uint16_t parity_nibble = 0;
+        int bpos = 0, reduce = end - have_header * 28 - substream_bytes;
+        uint16_t parity_nibble, dts = AV_RB16(pkt->data + 2);
         uint16_t auheader;
+        uint8_t header[28];
+
+        av_assert1(reduce >= 0 && reduce % 2 == 0);
+
+        if (have_header) {
+            memcpy(header, pkt->data + 4, 28);
+            header[16]  = (header[16] & 0x0c) | (FFMIN(s->hdr.num_substreams, 3) << 4);
+            header[17] &= 0x7f;
+            header[25] &= 0xfe;
+            AV_WL16(header + 26, ff_mlp_checksum16(header, 26));
+        }
+
+        pkt->data += reduce;
+        out_size  -= reduce;
+        pkt->size  = out_size;
 
-        ret = av_new_packet(out, out_size);
+        ret = av_packet_make_writable(pkt);
         if (ret < 0)
             goto fail;
 
-        AV_WB16(out->data + 2, dts);
+        AV_WB16(pkt->data + 2, dts);
         parity_nibble = dts;
-        out->size -= reduce * 2;
-        parity_nibble ^= out->size / 2;
-
-        if (have_header) {
-            memcpy(out->data + 4, in->data + 4, 28);
-            out->data[16 + 4] = (out->data[16 + 4] & 0x0f) | (FFMIN(s->hdr.num_substreams, 3) << 4);
-            out->data[25 + 4] = out->data[25 + 4] & 0xfe;
-            out->data[26 + 4] = 0xff;
-            out->data[27 + 4] = 0xff;
-            AV_WL16(out->data + 4 + 26, ff_mlp_checksum16(out->data + 4, 26));
-        }
+        parity_nibble ^= out_size / 2;
 
         for (i = 0; i < FFMIN(s->hdr.num_substreams, 3); i++) {
             uint16_t substr_hdr = 0;
@@ -133,18 +129,18 @@ static int truehd_core_filter(AVBSFContext *ctx, AVPacket *out)
             substr_hdr |= (units[i].bits[1] << 14);
             substr_hdr |= (units[i].bits[2] << 13);
             substr_hdr |= (units[i].bits[3] << 12);
-            substr_hdr |= (units[i].offset / 2) & 0x0FFF;
+            substr_hdr |=  units[i].offset;
 
-            AV_WB16(out->data + have_header * 28 + 4 + bpos, substr_hdr);
+            AV_WB16(pkt->data + have_header * 28 + 4 + bpos, substr_hdr);
 
-            parity_nibble ^= out->data[have_header * 28 + 4 + bpos++];
-            parity_nibble ^= out->data[have_header * 28 + 4 + bpos++];
+            parity_nibble ^= substr_hdr;
+            bpos          += 2;
 
             if (units[i].bits[0]) {
-                AV_WB16(out->data + have_header * 28 + 4 + bpos, units[i].optional);
+                AV_WB16(pkt->data + have_header * 28 + 4 + bpos, units[i].optional);
 
-                parity_nibble ^= out->data[have_header * 28 + 4 + bpos++];
-                parity_nibble ^= out->data[have_header * 28 + 4 + bpos++];
+                parity_nibble ^= units[i].optional;
+                bpos          += 2;
             }
         }
 
@@ -152,26 +148,27 @@ static int truehd_core_filter(AVBSFContext *ctx, AVPacket *out)
         parity_nibble ^= parity_nibble >> 4;
         parity_nibble &= 0xF;
 
-        memcpy(out->data + have_header * 28 + 4 + bpos,
-               in->data + 4 + (end >> 3),
-               out_size - (4 + (end >> 3)));
         auheader  = (parity_nibble ^ 0xF) << 12;
-        auheader |= (out->size / 2) & 0x0fff;
-        AV_WB16(out->data, auheader);
+        auheader |= (out_size / 2) & 0x0fff;
+        AV_WB16(pkt->data, auheader);
 
-        ret = av_packet_copy_props(out, in);
-    } else {
-        av_packet_move_ref(out, in);
+        if (have_header)
+            memcpy(pkt->data + 4, header, 28);
     }
 
 fail:
     if (ret < 0)
-        av_packet_unref(out);
-    av_packet_free(&in);
+        av_packet_unref(pkt);
 
     return ret;
 }
 
+static void truehd_core_flush(AVBSFContext *ctx)
+{
+    TrueHDCoreContext *s = ctx->priv_data;
+    memset(&s->hdr, 0, sizeof(s->hdr));
+}
+
 static const enum AVCodecID codec_ids[] = {
     AV_CODEC_ID_TRUEHD, AV_CODEC_ID_NONE,
 };
@@ -180,5 +177,6 @@ const AVBitStreamFilter ff_truehd_core_bsf = {
     .name           = "truehd_core",
     .priv_data_size = sizeof(TrueHDCoreContext),
     .filter         = truehd_core_filter,
+    .flush          = truehd_core_flush,
     .codec_ids      = codec_ids,
 };