00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00027 extern "C" {
00028 #include "avcodec.h"
00029 }
00030
00031 #include "libutvideo.h"
00032 #include "get_bits.h"
00033
00034 static av_cold int utvideo_decode_init(AVCodecContext *avctx)
00035 {
00036 UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
00037 UtVideoExtra info;
00038 int format;
00039 int begin_ret;
00040
00041 if (avctx->extradata_size != 4*4) {
00042 av_log(avctx, AV_LOG_ERROR, "Extradata size mismatch.\n");
00043 return -1;
00044 }
00045
00046
00047 info.version = AV_RL32(avctx->extradata);
00048 info.original_format = AV_RL32(avctx->extradata + 4);
00049 info.frameinfo_size = AV_RL32(avctx->extradata + 8);
00050 info.flags = AV_RL32(avctx->extradata + 12);
00051
00052
00053 switch (avctx->codec_tag) {
00054 case MKTAG('U', 'L', 'Y', '0'):
00055 avctx->pix_fmt = PIX_FMT_YUV420P;
00056 format = UTVF_YV12;
00057 break;
00058 case MKTAG('U', 'L', 'Y', '2'):
00059 avctx->pix_fmt = PIX_FMT_YUYV422;
00060 format = UTVF_YUY2;
00061 break;
00062 case MKTAG('U', 'L', 'R', 'G'):
00063 avctx->pix_fmt = PIX_FMT_BGR24;
00064 format = UTVF_RGB24_WIN;
00065 break;
00066 case MKTAG('U', 'L', 'R', 'A'):
00067 avctx->pix_fmt = PIX_FMT_RGB32;
00068 format = UTVF_RGB32_WIN;
00069 break;
00070 default:
00071 av_log(avctx, AV_LOG_ERROR,
00072 "Not a Ut Video FOURCC: %X\n", avctx->codec_tag);
00073 return -1;
00074 }
00075
00076
00077 utv->buf_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
00078 utv->buffer = (uint8_t *)av_malloc(utv->buf_size * sizeof(uint8_t));
00079
00080 if (utv->buffer == NULL) {
00081 av_log(avctx, AV_LOG_ERROR, "Unable to allocate output buffer.\n");
00082 return -1;
00083 }
00084
00085
00086 avctx->coded_frame = avcodec_alloc_frame();
00087
00088
00089 avctx->bits_per_raw_sample = 8;
00090
00091
00092 avctx->coded_frame->interlaced_frame = info.flags & 0x800 ? 1 : 0;
00093
00094
00095 avctx->coded_frame->top_field_first = 1;
00096
00097
00098
00099
00100
00101 utv->codec = CCodec::CreateInstance(UNFCC(avctx->codec_tag), "libavcodec");
00102
00103
00104 begin_ret = utv->codec->DecodeBegin(format, avctx->width, avctx->height,
00105 CBGROSSWIDTH_WINDOWS, &info, sizeof(UtVideoExtra));
00106
00107
00108 if (begin_ret != 0) {
00109 av_log(avctx, AV_LOG_ERROR,
00110 "Could not initialize decoder: %d\n", begin_ret);
00111 return -1;
00112 }
00113
00114 return 0;
00115 }
00116
00117 static int utvideo_decode_frame(AVCodecContext *avctx, void *data,
00118 int *data_size, AVPacket *avpkt)
00119 {
00120 UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
00121 AVFrame *pic = avctx->coded_frame;
00122 int w = avctx->width, h = avctx->height;
00123
00124
00125 pic->reference = 0;
00126 pic->pict_type = AV_PICTURE_TYPE_I;
00127 pic->key_frame = 1;
00128
00129
00130 utv->codec->DecodeFrame(utv->buffer, avpkt->data, true);
00131
00132
00133 switch (avctx->pix_fmt) {
00134 case PIX_FMT_YUV420P:
00135 pic->linesize[0] = w;
00136 pic->linesize[1] = pic->linesize[2] = w / 2;
00137 pic->data[0] = utv->buffer;
00138 pic->data[2] = utv->buffer + (w * h);
00139 pic->data[1] = pic->data[2] + (w * h / 4);
00140 break;
00141 case PIX_FMT_YUYV422:
00142 pic->linesize[0] = w * 2;
00143 pic->data[0] = utv->buffer;
00144 break;
00145 case PIX_FMT_BGR24:
00146 case PIX_FMT_RGB32:
00147
00148 pic->linesize[0] = -1 * w * (avctx->pix_fmt == PIX_FMT_BGR24 ? 3 : 4);
00149 pic->data[0] = utv->buffer + utv->buf_size + pic->linesize[0];
00150 break;
00151 }
00152
00153 *data_size = sizeof(AVFrame);
00154 *(AVFrame *)data = *pic;
00155
00156 return avpkt->size;
00157 }
00158
00159 static av_cold int utvideo_decode_close(AVCodecContext *avctx)
00160 {
00161 UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
00162
00163
00164 av_freep(&avctx->coded_frame);
00165 av_freep(&utv->buffer);
00166
00167
00168 utv->codec->DecodeEnd();
00169 CCodec::DeleteInstance(utv->codec);
00170
00171 return 0;
00172 }
00173
00174 AVCodec ff_libutvideo_decoder = {
00175 "libutvideo",
00176 NULL_IF_CONFIG_SMALL("Ut Video"),
00177 AVMEDIA_TYPE_VIDEO,
00178 AV_CODEC_ID_UTVIDEO,
00179 0,
00180 NULL,
00181 NULL,
00182 NULL,
00183 NULL,
00184 NULL,
00185 0,
00186 NULL,
00187 NULL,
00188 sizeof(UtVideoContext),
00189 NULL,
00190 NULL,
00191 NULL,
00192 NULL,
00193 NULL,
00194 utvideo_decode_init,
00195 NULL,
00196 NULL,
00197 utvideo_decode_frame,
00198 utvideo_decode_close,
00199 };