Mercurial > libavcodec.hg
annotate tmv.c @ 11333:e7c30cba2c7b libavcodec
Support B-frames when decoding MPEG-4 with VDPAU hardware acceleration.
Based on a patch by NVIDIA.
author | cehoyos |
---|---|
date | Wed, 03 Mar 2010 00:09:57 +0000 |
parents | 569849bc0f40 |
children | 8a4984c5cacc |
rev | line source |
---|---|
9616 | 1 /* |
2 * 8088flex TMV video decoder | |
3 * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu> | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 /** | |
23 * 8088flex TMV video decoder | |
24 * @file libavcodec/tmv.c | |
25 * @author Daniel Verkamp | |
26 * @sa http://www.oldskool.org/pc/8088_Corruption | |
27 */ | |
28 | |
29 #include "avcodec.h" | |
30 | |
31 #include "cga_data.h" | |
32 | |
33 typedef struct TMVContext { | |
34 AVFrame pic; | |
35 } TMVContext; | |
36 | |
37 static int tmv_decode_frame(AVCodecContext *avctx, void *data, | |
38 int *data_size, AVPacket *avpkt) | |
39 { | |
40 TMVContext *tmv = avctx->priv_data; | |
41 const uint8_t *src = avpkt->data; | |
42 uint8_t *dst, *dst_char; | |
43 unsigned char_cols = avctx->width >> 3; | |
44 unsigned char_rows = avctx->height >> 3; | |
45 unsigned x, y, mask, char_y, fg, bg, c; | |
46 | |
47 if (tmv->pic.data[0]) | |
48 avctx->release_buffer(avctx, &tmv->pic); | |
49 | |
50 if (avctx->get_buffer(avctx, &tmv->pic) < 0) { | |
51 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
52 return -1; | |
53 } | |
54 | |
9663
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
55 if (avpkt->size < 2*char_rows*char_cols) { |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
56 av_log(avctx, AV_LOG_ERROR, |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
57 "Input buffer too small, truncated sample?\n"); |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
58 *data_size = 0; |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
59 return -1; |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
60 } |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
61 |
9616 | 62 tmv->pic.pict_type = FF_I_TYPE; |
63 tmv->pic.key_frame = 1; | |
64 dst = tmv->pic.data[0]; | |
65 | |
66 tmv->pic.palette_has_changed = 1; | |
67 memcpy(tmv->pic.data[1], ff_cga_palette, 16 * 4); | |
68 | |
69 for (y = 0; y < char_rows; y++) { | |
70 for (x = 0; x < char_cols; x++) { | |
71 c = *src++ * 8; | |
72 bg = *src >> 4; | |
73 fg = *src++ & 0xF; | |
74 | |
75 dst_char = dst + x * 8; | |
76 for (char_y = 0; char_y < 8; char_y++) { | |
77 for (mask = 0x80; mask; mask >>= 1) { | |
78 *dst_char++ = ff_cga_font[c + char_y] & mask ? fg : bg; | |
79 } | |
80 dst_char += tmv->pic.linesize[0] - 8; | |
81 } | |
82 } | |
83 dst += tmv->pic.linesize[0] * 8; | |
84 } | |
85 | |
86 *data_size = sizeof(AVFrame); | |
87 *(AVFrame *)data = tmv->pic; | |
88 return avpkt->size; | |
89 } | |
90 | |
91 static av_cold int tmv_decode_close(AVCodecContext *avctx) | |
92 { | |
93 TMVContext *tmv = avctx->priv_data; | |
94 | |
95 if (tmv->pic.data[0]) | |
96 avctx->release_buffer(avctx, &tmv->pic); | |
97 | |
98 return 0; | |
99 } | |
100 | |
101 AVCodec tmv_decoder = { | |
102 .name = "tmv", | |
103 .type = CODEC_TYPE_VIDEO, | |
104 .id = CODEC_ID_TMV, | |
105 .priv_data_size = sizeof(TMVContext), | |
106 .close = tmv_decode_close, | |
107 .decode = tmv_decode_frame, | |
9813 | 108 .capabilities = CODEC_CAP_DR1, |
9616 | 109 .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"), |
110 }; |