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 };