00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <unistd.h>
00035
00036 #include "avcodec.h"
00037 #include "dsputil.h"
00038 #include "mpegvideo.h"
00039
00040
00041 typedef struct CyuvDecodeContext {
00042 AVCodecContext *avctx;
00043 int width, height;
00044 AVFrame frame;
00045 } CyuvDecodeContext;
00046
00047 static int cyuv_decode_init(AVCodecContext *avctx)
00048 {
00049 CyuvDecodeContext *s = avctx->priv_data;
00050
00051 s->avctx = avctx;
00052 s->width = avctx->width;
00053
00054 if (s->width & 0x3)
00055 return -1;
00056 s->height = avctx->height;
00057 avctx->pix_fmt = PIX_FMT_YUV411P;
00058
00059 return 0;
00060 }
00061
00062 static int cyuv_decode_frame(AVCodecContext *avctx,
00063 void *data, int *data_size,
00064 const uint8_t *buf, int buf_size)
00065 {
00066 CyuvDecodeContext *s=avctx->priv_data;
00067
00068 unsigned char *y_plane;
00069 unsigned char *u_plane;
00070 unsigned char *v_plane;
00071 int y_ptr;
00072 int u_ptr;
00073 int v_ptr;
00074
00075
00076 const signed char *y_table = (const signed char*)buf + 0;
00077 const signed char *u_table = (const signed char*)buf + 16;
00078 const signed char *v_table = (const signed char*)buf + 32;
00079
00080 unsigned char y_pred, u_pred, v_pred;
00081 int stream_ptr;
00082 unsigned char cur_byte;
00083 int pixel_groups;
00084
00085
00086
00087
00088
00089 if (buf_size != 48 + s->height * (s->width * 3 / 4)) {
00090 av_log(avctx, AV_LOG_ERROR, "ffmpeg: cyuv: got a buffer with %d bytes when %d were expected\n",
00091 buf_size,
00092 48 + s->height * (s->width * 3 / 4));
00093 return -1;
00094 }
00095
00096
00097 stream_ptr = 48;
00098
00099 if(s->frame.data[0])
00100 avctx->release_buffer(avctx, &s->frame);
00101
00102 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
00103 s->frame.reference = 0;
00104 if(avctx->get_buffer(avctx, &s->frame) < 0) {
00105 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00106 return -1;
00107 }
00108
00109 y_plane = s->frame.data[0];
00110 u_plane = s->frame.data[1];
00111 v_plane = s->frame.data[2];
00112
00113
00114 for (y_ptr = 0, u_ptr = 0, v_ptr = 0;
00115 y_ptr < (s->height * s->frame.linesize[0]);
00116 y_ptr += s->frame.linesize[0] - s->width,
00117 u_ptr += s->frame.linesize[1] - s->width / 4,
00118 v_ptr += s->frame.linesize[2] - s->width / 4) {
00119
00120
00121 cur_byte = buf[stream_ptr++];
00122 u_plane[u_ptr++] = u_pred = cur_byte & 0xF0;
00123 y_plane[y_ptr++] = y_pred = (cur_byte & 0x0F) << 4;
00124
00125 cur_byte = buf[stream_ptr++];
00126 v_plane[v_ptr++] = v_pred = cur_byte & 0xF0;
00127 y_pred += y_table[cur_byte & 0x0F];
00128 y_plane[y_ptr++] = y_pred;
00129
00130 cur_byte = buf[stream_ptr++];
00131 y_pred += y_table[cur_byte & 0x0F];
00132 y_plane[y_ptr++] = y_pred;
00133 y_pred += y_table[(cur_byte & 0xF0) >> 4];
00134 y_plane[y_ptr++] = y_pred;
00135
00136
00137 pixel_groups = s->width / 4 - 1;
00138 while (pixel_groups--) {
00139
00140 cur_byte = buf[stream_ptr++];
00141 u_pred += u_table[(cur_byte & 0xF0) >> 4];
00142 u_plane[u_ptr++] = u_pred;
00143 y_pred += y_table[cur_byte & 0x0F];
00144 y_plane[y_ptr++] = y_pred;
00145
00146 cur_byte = buf[stream_ptr++];
00147 v_pred += v_table[(cur_byte & 0xF0) >> 4];
00148 v_plane[v_ptr++] = v_pred;
00149 y_pred += y_table[cur_byte & 0x0F];
00150 y_plane[y_ptr++] = y_pred;
00151
00152 cur_byte = buf[stream_ptr++];
00153 y_pred += y_table[cur_byte & 0x0F];
00154 y_plane[y_ptr++] = y_pred;
00155 y_pred += y_table[(cur_byte & 0xF0) >> 4];
00156 y_plane[y_ptr++] = y_pred;
00157
00158 }
00159 }
00160
00161 *data_size=sizeof(AVFrame);
00162 *(AVFrame*)data= s->frame;
00163
00164 return buf_size;
00165 }
00166
00167 static int cyuv_decode_end(AVCodecContext *avctx)
00168 {
00169
00170
00171 return 0;
00172 }
00173
00174 AVCodec cyuv_decoder = {
00175 "cyuv",
00176 CODEC_TYPE_VIDEO,
00177 CODEC_ID_CYUV,
00178 sizeof(CyuvDecodeContext),
00179 cyuv_decode_init,
00180 NULL,
00181 cyuv_decode_end,
00182 cyuv_decode_frame,
00183 CODEC_CAP_DR1,
00184 NULL
00185 };
00186