Browse code

avcodec: add TrueMotion 2.0 Real Time decoder

Signed-off-by: Paul B Mahol <onemda@gmail.com>

Paul B Mahol authored on 2016/04/06 18:02:39
Showing 8 changed files
... ...
@@ -28,6 +28,7 @@ version <next>:
28 28
 - readvitc filter
29 29
 - VAAPI-accelerated format conversion and scaling
30 30
 - libnpp/CUDA-accelerated format conversion and scaling
31
+- Duck TrueMotion 2.0 Real Time decoder
31 32
 
32 33
 version 3.0:
33 34
 - Common Encryption (CENC) MP4 encoding and decoding support
... ...
@@ -524,6 +524,7 @@ OBJS-$(CONFIG_TMV_DECODER)             += tmv.o cga_data.o
524 524
 OBJS-$(CONFIG_TRUEHD_DECODER)          += mlpdec.o mlpdsp.o
525 525
 OBJS-$(CONFIG_TRUEMOTION1_DECODER)     += truemotion1.o
526 526
 OBJS-$(CONFIG_TRUEMOTION2_DECODER)     += truemotion2.o
527
+OBJS-$(CONFIG_TRUEMOTION2RT_DECODER)   += truemotion2rt.o
527 528
 OBJS-$(CONFIG_TRUESPEECH_DECODER)      += truespeech.o
528 529
 OBJS-$(CONFIG_TSCC_DECODER)            += tscc.o msrledec.o
529 530
 OBJS-$(CONFIG_TSCC2_DECODER)           += tscc2.o
... ...
@@ -310,6 +310,7 @@ void avcodec_register_all(void)
310 310
     REGISTER_DECODER(TMV,               tmv);
311 311
     REGISTER_DECODER(TRUEMOTION1,       truemotion1);
312 312
     REGISTER_DECODER(TRUEMOTION2,       truemotion2);
313
+    REGISTER_DECODER(TRUEMOTION2RT,     truemotion2rt);
313 314
     REGISTER_DECODER(TSCC,              tscc);
314 315
     REGISTER_DECODER(TSCC2,             tscc2);
315 316
     REGISTER_DECODER(TXD,               txd);
... ...
@@ -404,6 +404,7 @@ enum AVCodecID {
404 404
     AV_CODEC_ID_APNG,
405 405
     AV_CODEC_ID_DAALA,
406 406
     AV_CODEC_ID_CFHD,
407
+    AV_CODEC_ID_TRUEMOTION2RT,
407 408
 
408 409
     /* various PCM "codecs" */
409 410
     AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
... ...
@@ -1528,6 +1528,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
1528 1528
         .long_name = NULL_IF_CONFIG_SMALL("Cineform HD"),
1529 1529
         .props     = AV_CODEC_PROP_LOSSY,
1530 1530
     },
1531
+    {
1532
+        .id        = AV_CODEC_ID_TRUEMOTION2RT,
1533
+        .type      = AVMEDIA_TYPE_VIDEO,
1534
+        .name      = "truemotion2rt",
1535
+        .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"),
1536
+        .props     = AV_CODEC_PROP_LOSSY,
1537
+    },
1531 1538
 
1532 1539
     /* various PCM "codecs" */
1533 1540
     {
1534 1541
new file mode 100644
... ...
@@ -0,0 +1,220 @@
0
+/*
1
+ * Duck TrueMotion 2.0 Real Time Decoder
2
+ *
3
+ * This file is part of FFmpeg.
4
+ *
5
+ * FFmpeg is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * FFmpeg is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with FFmpeg; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
+
20
+#include <stdio.h>
21
+#include <stdlib.h>
22
+#include <string.h>
23
+
24
+#include "avcodec.h"
25
+#define BITSTREAM_READER_LE
26
+#include "get_bits.h"
27
+#include "internal.h"
28
+#include "libavutil/imgutils.h"
29
+#include "libavutil/internal.h"
30
+#include "libavutil/intreadwrite.h"
31
+#include "libavutil/mem.h"
32
+
33
+typedef struct TrueMotion2RTContext {
34
+    GetBitContext gb;
35
+    const uint8_t *buf;
36
+    int size;
37
+    int delta_size;
38
+    int hscale;
39
+} TrueMotion2RTContext;
40
+
41
+static av_cold int decode_init(AVCodecContext *avctx)
42
+{
43
+    avctx->pix_fmt = AV_PIX_FMT_YUV410P;
44
+    return 0;
45
+}
46
+
47
+/* Returns the number of bytes consumed from the bytestream. Returns -1 if
48
+ * there was an error while decoding the header */
49
+static int truemotion2rt_decode_header(AVCodecContext *avctx)
50
+{
51
+    TrueMotion2RTContext *s = avctx->priv_data;
52
+    uint8_t header_buffer[128] = { 0 };  /* logical maximum size of the header */
53
+    int i, header_size;
54
+
55
+    header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f;
56
+    if (header_size < 10) {
57
+        av_log(avctx, AV_LOG_ERROR, "invalid header size (%d)\n", header_size);
58
+        return AVERROR_INVALIDDATA;
59
+    }
60
+
61
+    if (header_size + 1 > s->size) {
62
+        av_log(avctx, AV_LOG_ERROR, "Input packet too small.\n");
63
+        return AVERROR_INVALIDDATA;
64
+    }
65
+
66
+    /* unscramble the header bytes with a XOR operation */
67
+    for (i = 1; i < header_size; i++)
68
+        header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1];
69
+
70
+    s->delta_size = header_buffer[1];
71
+    s->hscale = 1 + !!header_buffer[3];
72
+    if (s->delta_size < 2 || s->delta_size > 4)
73
+        return AVERROR_INVALIDDATA;
74
+
75
+    avctx->height = AV_RL16(header_buffer + 5);
76
+    avctx->width  = AV_RL16(header_buffer + 7);
77
+
78
+    return header_size;
79
+}
80
+
81
+static const int16_t delta_tab4[] = {
82
+    1, -1, 2, -3, 8, -8, 18, -18, 36, -36, 54, -54, 96, -96, 144, -144
83
+};
84
+
85
+static const int16_t delta_tab3[] = {
86
+    2, -3, 8, -8, 18, -18, 36, -36
87
+};
88
+
89
+static const int16_t delta_tab2[] = {
90
+    5, -7, 36, -36
91
+};
92
+
93
+static const int16_t *const delta_tabs[] = {
94
+    delta_tab2, delta_tab3, delta_tab4,
95
+};
96
+
97
+static int decode_frame(AVCodecContext *avctx,
98
+                        void *data, int *got_frame,
99
+                        AVPacket *avpkt)
100
+{
101
+    TrueMotion2RTContext *s = avctx->priv_data;
102
+    const uint8_t *buf = avpkt->data;
103
+    int ret, buf_size = avpkt->size;
104
+    AVFrame * const p = data;
105
+    GetBitContext *gb = &s->gb;
106
+    uint8_t *dst;
107
+    int x, y, delta_mode;
108
+
109
+    s->buf = buf;
110
+    s->size = buf_size;
111
+
112
+    if ((ret = truemotion2rt_decode_header(avctx)) < 0)
113
+        return ret;
114
+
115
+    if ((ret = init_get_bits8(gb, buf + ret, buf_size - ret)) < 0)
116
+        return ret;
117
+
118
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
119
+        return ret;
120
+
121
+    skip_bits(gb, 32);
122
+    delta_mode = s->delta_size - 2;
123
+    dst = p->data[0];
124
+    for (y = 0; y < avctx->height; y++) {
125
+        int diff = 0;
126
+        for (x = 0; x < avctx->width; x += s->hscale) {
127
+            diff  += delta_tabs[delta_mode][get_bits(gb, s->delta_size)];
128
+            dst[x] = av_clip_uint8((y ? dst[x - p->linesize[0]] : 0) + diff);
129
+        }
130
+        dst += p->linesize[0];
131
+    }
132
+
133
+    if (s->hscale > 1) {
134
+        dst = p->data[0];
135
+        for (y = 0; y < avctx->height; y++) {
136
+            for (x = 1; x < avctx->width; x += s->hscale) {
137
+                dst[x] = dst[x - 1];
138
+            }
139
+            dst += p->linesize[0];
140
+        }
141
+    }
142
+
143
+    dst = p->data[0];
144
+    for (y = 0; y < avctx->height; y++) {
145
+        for (x = 0; x < avctx->width; x++)
146
+            dst[x] = av_clip_uint8(dst[x] + (dst[x] - 128) / 3);
147
+        dst += p->linesize[0];
148
+    }
149
+
150
+    dst = p->data[1];
151
+    for (y = 0; y < avctx->height >> 2; y++) {
152
+        int diff = 0;
153
+        for (x = 0; x < avctx->width >> 2; x += s->hscale) {
154
+            diff  += delta_tabs[delta_mode][get_bits(gb, s->delta_size)];
155
+            dst[x] = av_clip_uint8((y ? dst[x - p->linesize[1]] : 128) + diff);
156
+        }
157
+        dst += p->linesize[1];
158
+    }
159
+
160
+    if (s->hscale > 1) {
161
+        dst = p->data[1];
162
+        for (y = 0; y < avctx->height >> 2; y++) {
163
+            for (x = 1; x < avctx->width >> 2; x += s->hscale) {
164
+                dst[x] = dst[x - 1];
165
+            }
166
+            dst += p->linesize[1];
167
+        }
168
+    }
169
+
170
+    dst = p->data[1];
171
+    for (y = 0; y < avctx->height >> 2; y++) {
172
+        for (x = 0; x < avctx->width >> 2; x++)
173
+            dst[x] += (dst[x] - 128) / 8;
174
+        dst += p->linesize[1];
175
+    }
176
+
177
+    dst = p->data[2];
178
+    for (y = 0; y < avctx->height >> 2; y++) {
179
+        int diff = 0;
180
+        for (x = 0; x < avctx->width >> 2; x += s->hscale) {
181
+            diff  += delta_tabs[delta_mode][get_bits(gb, s->delta_size)];
182
+            dst[x] = av_clip_uint8((y ? dst[x - p->linesize[2]] : 128) + diff);
183
+        }
184
+        dst += p->linesize[2];
185
+    }
186
+
187
+    if (s->hscale > 1) {
188
+        dst = p->data[2];
189
+        for (y = 0; y < avctx->height >> 2; y++) {
190
+            for (x = 1; x < avctx->width >> 2; x += s->hscale) {
191
+                dst[x] = dst[x - 1];
192
+            }
193
+            dst += p->linesize[2];
194
+        }
195
+    }
196
+
197
+    dst = p->data[2];
198
+    for (y = 0; y < avctx->height >> 2; y++) {
199
+        for (x = 0; x < avctx->width >> 2; x++)
200
+            dst[x] += (dst[x] - 128) / 8;
201
+        dst += p->linesize[2];
202
+    }
203
+
204
+    p->pict_type = AV_PICTURE_TYPE_I;
205
+    *got_frame   = 1;
206
+
207
+    return buf_size;
208
+}
209
+
210
+AVCodec ff_truemotion2rt_decoder = {
211
+    .name           = "truemotion2rt",
212
+    .long_name      = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"),
213
+    .type           = AVMEDIA_TYPE_VIDEO,
214
+    .id             = AV_CODEC_ID_TRUEMOTION2RT,
215
+    .priv_data_size = sizeof(TrueMotion2RTContext),
216
+    .init           = decode_init,
217
+    .decode         = decode_frame,
218
+    .capabilities   = AV_CODEC_CAP_DR1,
219
+};
... ...
@@ -28,7 +28,7 @@
28 28
 #include "libavutil/version.h"
29 29
 
30 30
 #define LIBAVCODEC_VERSION_MAJOR  57
31
-#define LIBAVCODEC_VERSION_MINOR  37
31
+#define LIBAVCODEC_VERSION_MINOR  38
32 32
 #define LIBAVCODEC_VERSION_MICRO 100
33 33
 
34 34
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
... ...
@@ -352,6 +352,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
352 352
     { AV_CODEC_ID_FRAPS,        MKTAG('F', 'P', 'S', '1') },
353 353
     { AV_CODEC_ID_THEORA,       MKTAG('t', 'h', 'e', 'o') },
354 354
     { AV_CODEC_ID_TRUEMOTION2,  MKTAG('T', 'M', '2', '0') },
355
+    { AV_CODEC_ID_TRUEMOTION2RT,MKTAG('T', 'R', '2', '0') },
355 356
     { AV_CODEC_ID_CSCD,         MKTAG('C', 'S', 'C', 'D') },
356 357
     { AV_CODEC_ID_ZMBV,         MKTAG('Z', 'M', 'B', 'V') },
357 358
     { AV_CODEC_ID_KMVC,         MKTAG('K', 'M', 'V', 'C') },