libavcodec/libutvideodec.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011 Derek Buitenhuis
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 General Public
00008  * License as published by the Free Software Foundation;
00009  * version 2 of the License.
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  * General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU 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 
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 /* Read extradata */
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 /* Pick format based on FOURCC */
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 /* Only allocate the buffer once */
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 /* Allocate the output frame */
00086 avctx->coded_frame = avcodec_alloc_frame();
00087 
00088 /* Ut Video only supports 8-bit */
00089 avctx->bits_per_raw_sample = 8;
00090 
00091 /* Is it interlaced? */
00092 avctx->coded_frame->interlaced_frame = info.flags & 0x800 ? 1 : 0;
00093 
00094 /* Apparently Ut Video doesn't store this info... */
00095 avctx->coded_frame->top_field_first = 1;
00096 
00097 /*
00098  * Create a Ut Video instance. Since the function wants
00099  * an "interface name" string, pass it the name of the lib.
00100  */
00101 utv->codec = CCodec::CreateInstance(UNFCC(avctx->codec_tag), "libavcodec");
00102 
00103 /* Initialize Decoding */
00104 begin_ret = utv->codec->DecodeBegin(format, avctx->width, avctx->height,
00105 CBGROSSWIDTH_WINDOWS, &info, sizeof(UtVideoExtra));
00106 
00107 /* Check to see if the decoder initlized properly */
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 /* Set flags */
00125 pic->reference = 0;
00126 pic->pict_type = AV_PICTURE_TYPE_I;
00127 pic->key_frame = 1;
00128 
00129 /* Decode the frame */
00130 utv->codec->DecodeFrame(utv->buffer, avpkt->data, true);
00131 
00132 /* Set the output data depending on the colorspace */
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 /* Make the linesize negative, since Ut Video uses bottom-up BGR */
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 /* Free output */
00164 av_freep(&avctx->coded_frame);
00165 av_freep(&utv->buffer);
00166 
00167 /* Finish decoding and clean up the instance */
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, //capabilities
00180 NULL, //supported_framerates
00181 NULL, //pix_fmts
00182 NULL, //supported_samplerates
00183 NULL, //sample_fmts
00184 NULL, //channel_layouts
00185 0, //max_lowres
00186 NULL, //priv_class
00187 NULL, //profiles
00188 sizeof(UtVideoContext),
00189 NULL, //next
00190 NULL, //init_thread_copy
00191 NULL, //update_thread_context
00192 NULL, //defaults
00193 NULL, //init_static_data
00194 utvideo_decode_init,
00195 NULL, //encode
00196 NULL, //encode2
00197 utvideo_decode_frame,
00198 utvideo_decode_close,
00199 };

Generated on Fri Oct 26 02:49:51 2012 for FFmpeg by doxygen 1.5.8

AltStyle によって変換されたページ (->オリジナル) /