int VCMFormatToUtVideoFormat(utvf_t *utvf, DWORD biCompression, WORD biBitCount) { DWORD dwtmp; WORD wtmp; if (biCompression == BI_RGB) { switch (biBitCount) { case 24: *utvf = UTVF_NFCC_BGR_BU; return 0; case 32: *utvf = UTVF_NFCC_BGRX_BU; return 0; default: return -1; } } if (UtVideoFormatToVCMFormat(&dwtmp, &wtmp, (utvf_t)UNFCC(biCompression)) != 0) return -1; if (dwtmp != biCompression) // biBitCount はチェックしない return -1; *utvf = UNFCC(biCompression); return 0; }
static av_cold int utvideo_decode_init(AVCodecContext *avctx) { UtVideoContext *utv = (UtVideoContext *)avctx->priv_data; UtVideoExtra info; int format; int begin_ret; if (avctx->extradata_size != 16 && avctx->extradata_size != 8 ) { av_log(avctx, AV_LOG_ERROR, "Extradata size (%d) mismatch.\n", avctx->extradata_size); return -1; } /* Read extradata */ info.version = AV_RL32(avctx->extradata); info.original_format = AV_RL32(avctx->extradata + 4); info.frameinfo_size = AV_RL32(avctx->extradata + 8); info.flags = AV_RL32(avctx->extradata + 12); /* Pick format based on FOURCC */ switch (avctx->codec_tag) { #ifdef UTV_BT709 case MKTAG('U', 'L', 'H', '0'): avctx->pix_fmt = AV_PIX_FMT_YUV420P; avctx->colorspace = AVCOL_SPC_BT709; format = UTVF_YV12; break; case MKTAG('U', 'L', 'H', '2'): avctx->pix_fmt = AV_PIX_FMT_YUYV422; avctx->colorspace = AVCOL_SPC_BT709; format = UTVF_YUY2; break; #endif case MKTAG('U', 'L', 'Y', '0'): avctx->pix_fmt = AV_PIX_FMT_YUV420P; format = UTVF_YV12; break; case MKTAG('U', 'L', 'Y', '2'): avctx->pix_fmt = AV_PIX_FMT_YUYV422; format = UTVF_YUY2; break; case MKTAG('U', 'L', 'R', 'G'): avctx->pix_fmt = AV_PIX_FMT_BGR24; format = UTVF_NFCC_BGR_BU; break; case MKTAG('U', 'L', 'R', 'A'): avctx->pix_fmt = AV_PIX_FMT_RGB32; format = UTVF_NFCC_BGRA_BU; break; #ifdef UTVF_UQY2 case MKTAG('U', 'Q', 'Y', '2'): avctx->pix_fmt = AV_PIX_FMT_YUV422P10; format = UTVF_v210; break; #endif default: av_log(avctx, AV_LOG_ERROR, "Not a Ut Video FOURCC: %X\n", avctx->codec_tag); return -1; } /* Only allocate the buffer once */ utv->buf_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); #ifdef UTVF_UQY2 if (format == UTVF_v210) utv->buf_size += avctx->height * ((avctx->width + 47) / 48) * 128; // the linesize used by the decoder, this does not seem to be exported #endif utv->buffer = (uint8_t *)av_malloc(utv->buf_size * sizeof(uint8_t)); if (utv->buffer == NULL) { av_log(avctx, AV_LOG_ERROR, "Unable to allocate output buffer.\n"); return -1; } /* Allocate the output frame */ avctx->coded_frame = av_frame_alloc(); /* Ut Video only supports 8-bit */ avctx->bits_per_raw_sample = 8; /* Is it interlaced? */ avctx->coded_frame->interlaced_frame = info.flags & 0x800 ? 1 : 0; /* Apparently Ut Video doesn't store this info... */ avctx->coded_frame->top_field_first = 1; /* * Create a Ut Video instance. Since the function wants * an "interface name" string, pass it the name of the lib. */ utv->codec = CCodec::CreateInstance(UNFCC(avctx->codec_tag), "libavcodec"); /* Initialize Decoding */ begin_ret = utv->codec->DecodeBegin(format, avctx->width, avctx->height, CBGROSSWIDTH_WINDOWS, &info, sizeof(UtVideoExtra)); /* Check to see if the decoder initlized properly */ if (begin_ret != 0) { av_log(avctx, AV_LOG_ERROR, "Could not initialize decoder: %d\n", begin_ret); return -1; } return 0; }
static av_cold int utvideo_decode_init(AVCodecContext *avctx) { UtVideoContext *utv = (UtVideoContext *)avctx->priv_data; UtVideoExtra info; int defined_fourcc = 0; if(avctx->extradata_size != 4*4) { av_log(avctx, AV_LOG_ERROR, "Extradata size mismatch.\n"); return -1; } /* Read extradata */ info.version = AV_RL32(avctx->extradata); info.original_format = AV_RL32(avctx->extradata + 4); info.stripes = AV_RL32(avctx->extradata + 8); info.flags = AV_RL32(avctx->extradata + 12); /* Try to output the original format */ switch(UNFCC(info.original_format)) { case UTVF_YV12: avctx->pix_fmt = PIX_FMT_YUV420P; break; case UTVF_YUY2: case UTVF_YUYV: case UTVF_YUNV: avctx->pix_fmt = PIX_FMT_YUYV422; break; case UTVF_UYVY: case UTVF_UYNV: avctx->pix_fmt = PIX_FMT_UYVY422; break; case UTVF_RGB24_WIN: avctx->pix_fmt = PIX_FMT_BGR24; break; case UTVF_RGB32_WIN: avctx->pix_fmt = PIX_FMT_RGB32; break; case UTVF_ARGB32_WIN: avctx->pix_fmt = PIX_FMT_ARGB; break; case 0: /* Fall back on FOURCC */ switch(UNFCC(avctx->codec_tag)) { case UTVF_ULY0: avctx->pix_fmt = PIX_FMT_YUV420P; defined_fourcc = UTVF_YV12; break; case UTVF_ULY2: avctx->pix_fmt = PIX_FMT_YUYV422; defined_fourcc = UTVF_YUY2; break; case UTVF_ULRG: avctx->pix_fmt = PIX_FMT_BGR24; defined_fourcc = UTVF_RGB24_WIN; break; case UTVF_ULRA: avctx->pix_fmt = PIX_FMT_RGB32; defined_fourcc = UTVF_RGB32_WIN; break; } break; default: av_log(avctx, AV_LOG_ERROR, "Codec ExtraData is Corrupt or Invalid: %X\n", info.original_format); return -1; } /* Only allocate the buffer once */ utv->buf_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); utv->output = (uint8_t *)av_malloc(utv->buf_size * sizeof(uint8_t)); if(utv->output == NULL) { av_log(avctx, AV_LOG_ERROR, "Unable to allocate output buffer.\n"); return -1; } /* Allocate the output frame */ avctx->coded_frame = avcodec_alloc_frame(); /* Ut Video only supports 8-bit */ avctx->bits_per_raw_sample = 8; /* Is it interlaced? */ avctx->coded_frame->interlaced_frame = info.flags & 0x800 ? 1 : 0; /* Apparently Ut Video doesn't store this info... */ avctx->coded_frame->top_field_first = 1; /* * Create a Ut Video instance. Since the function wants * an "interface name" string, pass it the name of the lib. */ utv->codec = CCodec::CreateInstance(UNFCC(avctx->codec_tag), "libavcodec"); /* Initialize Decoding */ utv->codec->DecodeBegin(defined_fourcc ? defined_fourcc : UNFCC(info.original_format), avctx->width, avctx->height, CBGROSSWIDTH_WINDOWS, &info, sizeof(UtVideoExtra)); return 0; }
static av_cold int utvideo_encode_init(AVCodecContext *avctx) { UtVideoContext *utv = (UtVideoContext *)avctx->priv_data; UtVideoExtra *info; uint32_t flags, in_format; int ret; switch (avctx->pix_fmt) { case AV_PIX_FMT_YUV420P: in_format = UTVF_YV12; avctx->bits_per_coded_sample = 12; if (avctx->colorspace == AVCOL_SPC_BT709) avctx->codec_tag = MKTAG('U', 'L', 'H', '0'); else avctx->codec_tag = MKTAG('U', 'L', 'Y', '0'); break; case AV_PIX_FMT_YUYV422: in_format = UTVF_YUYV; avctx->bits_per_coded_sample = 16; if (avctx->colorspace == AVCOL_SPC_BT709) avctx->codec_tag = MKTAG('U', 'L', 'H', '2'); else avctx->codec_tag = MKTAG('U', 'L', 'Y', '2'); break; case AV_PIX_FMT_BGR24: in_format = UTVF_NFCC_BGR_BU; avctx->bits_per_coded_sample = 24; avctx->codec_tag = MKTAG('U', 'L', 'R', 'G'); break; case AV_PIX_FMT_RGB32: in_format = UTVF_NFCC_BGRA_BU; avctx->bits_per_coded_sample = 32; avctx->codec_tag = MKTAG('U', 'L', 'R', 'A'); break; default: return AVERROR(EINVAL); } /* Check before we alloc anything */ if (avctx->prediction_method != 0 && avctx->prediction_method != 2) { av_log(avctx, AV_LOG_ERROR, "Invalid prediction method.\n"); return AVERROR(EINVAL); } flags = ((avctx->prediction_method + 1) << 8) | (avctx->thread_count - 1); avctx->priv_data = utv; avctx->coded_frame = av_frame_alloc(); /* Alloc extradata buffer */ info = (UtVideoExtra *)av_malloc(sizeof(*info)); if (!info) { av_log(avctx, AV_LOG_ERROR, "Could not allocate extradata buffer.\n"); return AVERROR(ENOMEM); } /* * We use this buffer to hold the data that Ut Video returns, * since we cannot decode planes separately with it. */ ret = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); if (ret < 0) { av_free(info); return ret; } utv->buf_size = ret; utv->buffer = (uint8_t *)av_malloc(utv->buf_size); if (utv->buffer == NULL) { av_log(avctx, AV_LOG_ERROR, "Could not allocate output buffer.\n"); av_free(info); return AVERROR(ENOMEM); } /* * Create a Ut Video instance. Since the function wants * an "interface name" string, pass it the name of the lib. */ utv->codec = CCodec::CreateInstance(UNFCC(avctx->codec_tag), "libavcodec"); /* Initialize encoder */ utv->codec->EncodeBegin(in_format, avctx->width, avctx->height, CBGROSSWIDTH_WINDOWS); /* Get extradata from encoder */ avctx->extradata_size = utv->codec->EncodeGetExtraDataSize(); utv->codec->EncodeGetExtraData(info, avctx->extradata_size, in_format, avctx->width, avctx->height, CBGROSSWIDTH_WINDOWS); avctx->extradata = (uint8_t *)info; /* Set flags */ utv->codec->SetState(&flags, sizeof(flags)); return 0; }