00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "avcodec.h"
00024 #include "libavutil/intreadwrite.h"
00025
00026 static av_cold int decode_init(AVCodecContext *avctx)
00027 {
00028 avctx->pix_fmt = PIX_FMT_YUV420P;
00029 avctx->coded_frame = avcodec_alloc_frame();
00030 if (!avctx->coded_frame)
00031 return AVERROR(ENOMEM);
00032
00033 return 0;
00034 }
00035
00036 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
00037 AVPacket *avpkt)
00038 {
00039 int h, w;
00040 AVFrame *pic = avctx->coded_frame;
00041 const uint8_t *src = avpkt->data;
00042 uint8_t *Y1, *Y2, *U, *V;
00043 int ret;
00044
00045 if (pic->data[0])
00046 avctx->release_buffer(avctx, pic);
00047
00048 if (avpkt->size < avctx->width * avctx->height * 3 / 2 + 16) {
00049 av_log(avctx, AV_LOG_ERROR, "packet too small\n");
00050 return AVERROR_INVALIDDATA;
00051 }
00052
00053 pic->reference = 0;
00054 if ((ret = avctx->get_buffer(avctx, pic)) < 0)
00055 return ret;
00056
00057 pic->pict_type = AV_PICTURE_TYPE_I;
00058 pic->key_frame = 1;
00059
00060 if (AV_RL32(src) != 0x01000002) {
00061 av_log_ask_for_sample(avctx, "Unknown frame header %X\n", AV_RL32(src));
00062 return AVERROR_PATCHWELCOME;
00063 }
00064 src += 16;
00065
00066 Y1 = pic->data[0];
00067 Y2 = pic->data[0] + pic->linesize[0];
00068 U = pic->data[1];
00069 V = pic->data[2];
00070 for (h = 0; h < avctx->height; h += 2) {
00071 for (w = 0; w < avctx->width; w += 2) {
00072 AV_WN16A(Y1 + w, AV_RN16A(src));
00073 AV_WN16A(Y2 + w, AV_RN16A(src + 2));
00074 U[w >> 1] = src[4] + 0x80;
00075 V[w >> 1] = src[5] + 0x80;
00076 src += 6;
00077 }
00078 Y1 += pic->linesize[0] << 1;
00079 Y2 += pic->linesize[0] << 1;
00080 U += pic->linesize[1];
00081 V += pic->linesize[2];
00082 }
00083
00084 *data_size = sizeof(AVFrame);
00085 *(AVFrame*)data = *pic;
00086
00087 return avpkt->size;
00088 }
00089
00090 static av_cold int decode_close(AVCodecContext *avctx)
00091 {
00092 AVFrame *pic = avctx->coded_frame;
00093 if (pic->data[0])
00094 avctx->release_buffer(avctx, pic);
00095 av_freep(&avctx->coded_frame);
00096
00097 return 0;
00098 }
00099
00100 AVCodec ff_dxtory_decoder = {
00101 .name = "dxtory",
00102 .long_name = NULL_IF_CONFIG_SMALL("Dxtory"),
00103 .type = AVMEDIA_TYPE_VIDEO,
00104 .id = CODEC_ID_DXTORY,
00105 .init = decode_init,
00106 .close = decode_close,
00107 .decode = decode_frame,
00108 .capabilities = CODEC_CAP_DR1,
00109 };