00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #include "avcodec.h"
00026
00027 typedef struct RawVideoContext {
00028 unsigned char * buffer;
00029 unsigned char * p;
00030 int length;
00031 AVFrame pic;
00032 } RawVideoContext;
00033
00034 typedef struct PixleFormatTag {
00035 int pix_fmt;
00036 unsigned int fourcc;
00037 } PixelFormatTag;
00038
00039 const PixelFormatTag pixelFormatTags[] = {
00040 { PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') },
00041 { PIX_FMT_YUV420P, MKTAG('I', 'Y', 'U', 'V') },
00042 { PIX_FMT_YUV410P, MKTAG('Y', 'U', 'V', '9') },
00043 { PIX_FMT_YUV411P, MKTAG('Y', '4', '1', 'B') },
00044 { PIX_FMT_YUV422P, MKTAG('Y', '4', '2', 'B') },
00045 { PIX_FMT_GRAY8, MKTAG('Y', '8', '0', '0') },
00046 { PIX_FMT_GRAY8, MKTAG(' ', ' ', 'Y', '8') },
00047
00048
00049 { PIX_FMT_YUV422, MKTAG('Y', '4', '2', '2') },
00050 { PIX_FMT_UYVY422, MKTAG('U', 'Y', 'V', 'Y') },
00051 { PIX_FMT_GRAY8, MKTAG('G', 'R', 'E', 'Y') },
00052
00053 { -1, 0 },
00054 };
00055
00056 static int findPixelFormat(unsigned int fourcc)
00057 {
00058 const PixelFormatTag * tags = pixelFormatTags;
00059 while (tags->pix_fmt >= 0) {
00060 if (tags->fourcc == fourcc)
00061 return tags->pix_fmt;
00062 tags++;
00063 }
00064 return PIX_FMT_YUV420P;
00065 }
00066
00067 unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat fmt)
00068 {
00069 const PixelFormatTag * tags = pixelFormatTags;
00070 while (tags->pix_fmt >= 0) {
00071 if (tags->pix_fmt == fmt)
00072 return tags->fourcc;
00073 tags++;
00074 }
00075 return 0;
00076 }
00077
00078
00079
00080 static int raw_init_decoder(AVCodecContext *avctx)
00081 {
00082 RawVideoContext *context = avctx->priv_data;
00083
00084 if (avctx->codec_tag)
00085 avctx->pix_fmt = findPixelFormat(avctx->codec_tag);
00086 else if (avctx->bits_per_sample){
00087 switch(avctx->bits_per_sample){
00088 case 15: avctx->pix_fmt= PIX_FMT_RGB555; break;
00089 case 16: avctx->pix_fmt= PIX_FMT_RGB565; break;
00090 case 24: avctx->pix_fmt= PIX_FMT_BGR24 ; break;
00091 case 32: avctx->pix_fmt= PIX_FMT_RGBA32; break;
00092 }
00093 }
00094
00095 context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
00096 context->buffer = av_malloc(context->length);
00097 context->p = context->buffer;
00098 context->pic.pict_type = FF_I_TYPE;
00099 context->pic.key_frame = 1;
00100
00101 avctx->coded_frame= &context->pic;
00102
00103 if (!context->buffer)
00104 return -1;
00105
00106 return 0;
00107 }
00108
00109 static void flip(AVCodecContext *avctx, AVPicture * picture){
00110 if(!avctx->codec_tag && avctx->bits_per_sample && picture->linesize[1]==0){
00111 picture->data[0] += picture->linesize[0] * (avctx->height-1);
00112 picture->linesize[0] *= -1;
00113 }
00114 }
00115
00116 static int raw_decode(AVCodecContext *avctx,
00117 void *data, int *data_size,
00118 uint8_t *buf, int buf_size)
00119 {
00120 RawVideoContext *context = avctx->priv_data;
00121 int bytesNeeded;
00122
00123 AVPicture * picture = (AVPicture *) data;
00124
00125
00126 if (buf_size == context->length && context->p == context->buffer) {
00127 avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height);
00128 flip(avctx, picture);
00129 *data_size = sizeof(AVPicture);
00130 return buf_size;
00131 }
00132
00133 bytesNeeded = context->length - (context->p - context->buffer);
00134 if (buf_size < bytesNeeded) {
00135 memcpy(context->p, buf, buf_size);
00136 context->p += buf_size;
00137 return buf_size;
00138 }
00139
00140 memcpy(context->p, buf, bytesNeeded);
00141 context->p = context->buffer;
00142 avpicture_fill(picture, context->buffer, avctx->pix_fmt, avctx->width, avctx->height);
00143 flip(avctx, picture);
00144 *data_size = sizeof(AVPicture);
00145 return bytesNeeded;
00146 }
00147
00148 static int raw_close_decoder(AVCodecContext *avctx)
00149 {
00150 RawVideoContext *context = avctx->priv_data;
00151
00152 av_freep(&context->buffer);
00153 return 0;
00154 }
00155
00156
00157
00158 static int raw_init_encoder(AVCodecContext *avctx)
00159 {
00160 avctx->coded_frame = (AVFrame *)avctx->priv_data;
00161 avctx->coded_frame->pict_type = FF_I_TYPE;
00162 avctx->coded_frame->key_frame = 1;
00163 if(!avctx->codec_tag)
00164 avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt);
00165 return 0;
00166 }
00167
00168 static int raw_encode(AVCodecContext *avctx,
00169 unsigned char *frame, int buf_size, void *data)
00170 {
00171 return avpicture_layout((AVPicture *)data, avctx->pix_fmt, avctx->width,
00172 avctx->height, frame, buf_size);
00173 }
00174
00175 #ifdef CONFIG_RAWVIDEO_ENCODER
00176 AVCodec rawvideo_encoder = {
00177 "rawvideo",
00178 CODEC_TYPE_VIDEO,
00179 CODEC_ID_RAWVIDEO,
00180 sizeof(AVFrame),
00181 raw_init_encoder,
00182 raw_encode,
00183 };
00184 #endif // CONFIG_RAWVIDEO_ENCODER
00185
00186 AVCodec rawvideo_decoder = {
00187 "rawvideo",
00188 CODEC_TYPE_VIDEO,
00189 CODEC_ID_RAWVIDEO,
00190 sizeof(RawVideoContext),
00191 raw_init_decoder,
00192 NULL,
00193 raw_close_decoder,
00194 raw_decode,
00195 };