Libav
|
00001 /* 00002 * Aura 2 decoder 00003 * 00004 * This file is part of FFmpeg. 00005 * 00006 * FFmpeg is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * FFmpeg is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with FFmpeg; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00026 #include "avcodec.h" 00027 00028 typedef struct AuraDecodeContext { 00029 AVCodecContext *avctx; 00030 AVFrame frame; 00031 } AuraDecodeContext; 00032 00033 static av_cold int aura_decode_init(AVCodecContext *avctx) 00034 { 00035 AuraDecodeContext *s = avctx->priv_data; 00036 00037 s->avctx = avctx; 00038 /* width needs to be divisible by 4 for this codec to work */ 00039 if (avctx->width & 0x3) 00040 return -1; 00041 avctx->pix_fmt = PIX_FMT_YUV422P; 00042 00043 return 0; 00044 } 00045 00046 static int aura_decode_frame(AVCodecContext *avctx, 00047 void *data, int *data_size, 00048 AVPacket *pkt) 00049 { 00050 AuraDecodeContext *s=avctx->priv_data; 00051 00052 uint8_t *Y, *U, *V; 00053 uint8_t val; 00054 int x, y; 00055 const uint8_t *buf = pkt->data; 00056 00057 /* prediction error tables (make it clear that they are signed values) */ 00058 const int8_t *delta_table = (const int8_t*)buf + 16; 00059 00060 if (pkt->size != 48 + avctx->height * avctx->width) { 00061 av_log(avctx, AV_LOG_ERROR, "got a buffer with %d bytes when %d were expected\n", 00062 pkt->size, 48 + avctx->height * avctx->width); 00063 return -1; 00064 } 00065 00066 /* pixel data starts 48 bytes in, after 3x16-byte tables */ 00067 buf += 48; 00068 00069 if(s->frame.data[0]) 00070 avctx->release_buffer(avctx, &s->frame); 00071 00072 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; 00073 s->frame.reference = 0; 00074 if(avctx->get_buffer(avctx, &s->frame) < 0) { 00075 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 00076 return -1; 00077 } 00078 00079 Y = s->frame.data[0]; 00080 U = s->frame.data[1]; 00081 V = s->frame.data[2]; 00082 00083 /* iterate through each line in the height */ 00084 for (y = 0; y < avctx->height; y++) { 00085 /* reset predictors */ 00086 val = *buf++; 00087 U[0] = val & 0xF0; 00088 Y[0] = val << 4; 00089 val = *buf++; 00090 V[0] = val & 0xF0; 00091 Y[1] = Y[0] + delta_table[val & 0xF]; 00092 Y += 2; U++; V++; 00093 00094 /* iterate through the remaining pixel groups (4 pixels/group) */ 00095 for (x = 1; x < (avctx->width >> 1); x++) { 00096 val = *buf++; 00097 U[0] = U[-1] + delta_table[val >> 4]; 00098 Y[0] = Y[-1] + delta_table[val & 0xF]; 00099 val = *buf++; 00100 V[0] = V[-1] + delta_table[val >> 4]; 00101 Y[1] = Y[ 0] + delta_table[val & 0xF]; 00102 Y += 2; U++; V++; 00103 } 00104 Y += s->frame.linesize[0] - avctx->width; 00105 U += s->frame.linesize[1] - (avctx->width >> 1); 00106 V += s->frame.linesize[2] - (avctx->width >> 1); 00107 } 00108 00109 *data_size=sizeof(AVFrame); 00110 *(AVFrame*)data= s->frame; 00111 00112 return pkt->size; 00113 } 00114 00115 static av_cold int aura_decode_end(AVCodecContext *avctx) 00116 { 00117 AuraDecodeContext *s = avctx->priv_data; 00118 00119 if (s->frame.data[0]) 00120 avctx->release_buffer(avctx, &s->frame); 00121 00122 return 0; 00123 } 00124 00125 AVCodec aura2_decoder = { 00126 "aura2", 00127 AVMEDIA_TYPE_VIDEO, 00128 CODEC_ID_AURA2, 00129 sizeof(AuraDecodeContext), 00130 aura_decode_init, 00131 NULL, 00132 aura_decode_end, 00133 aura_decode_frame, 00134 CODEC_CAP_DR1, 00135 NULL, 00136 .long_name = NULL_IF_CONFIG_SMALL("Auravision Aura 2"), 00137 }; 00138