History

avcodec: add TrueMotion 2.0 Real Time decoder

Paul B Mahol committed 10 years ago

Commit c85d0421 parent aa40df48 files · +233 −1Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t