You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	v410 encoder and decoder
v410 is a packed 10-bit 4:4:4 YCbCr format used in QuickTime. Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
				
					committed by
					
						 Michael Niedermayer
						Michael Niedermayer
					
				
			
			
				
	
			
			
			
						parent
						
							635a301683
						
					
				
				
					commit
					309ffa4fe3
				
			| @@ -134,7 +134,7 @@ easier to use. The changes are: | ||||
| - new option: -report | ||||
| - Dxtory capture format decoder | ||||
| - cellauto source | ||||
|  | ||||
| - v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder | ||||
|  | ||||
| version 0.8: | ||||
|  | ||||
|   | ||||
| @@ -218,6 +218,7 @@ Codecs: | ||||
|   tta.c                                 Alex Beregszaszi, Jaikrishnan Menon | ||||
|   txd.c                                 Ivo van Poorten | ||||
|   ulti*                                 Kostya Shishkov | ||||
|   v410*.c                               Derek Buitenhuis | ||||
|   vb.c                                  Kostya Shishkov | ||||
|   vble.c                                Derek Buitenhuis | ||||
|   vc1*                                  Kostya Shishkov | ||||
|   | ||||
| @@ -602,6 +602,7 @@ following image formats are supported: | ||||
|     @tab Codec used in DOS CD-ROM FlashBack game. | ||||
| @item Ut Video               @tab     @tab  X | ||||
| @item V210 Quicktime Uncompressed 4:2:2 10-bit     @tab  X  @tab  X | ||||
| @item v410 Quicktime Uncompressed 4:4:4 10-bit     @tab  X  @tab  X | ||||
| @item VBLE Lossless Codec    @tab     @tab  X | ||||
| @item VMware Screen Codec / VMware Video  @tab     @tab  X | ||||
|     @tab Codec used in videos captured by VMware. | ||||
|   | ||||
| @@ -413,6 +413,8 @@ OBJS-$(CONFIG_ULTI_DECODER)            += ulti.o | ||||
| OBJS-$(CONFIG_UTVIDEO_DECODER)         += utvideo.o | ||||
| OBJS-$(CONFIG_V210_DECODER)            += v210dec.o | ||||
| OBJS-$(CONFIG_V210_ENCODER)            += v210enc.o | ||||
| OBJS-$(CONFIG_V410_DECODER)            += v410dec.o | ||||
| OBJS-$(CONFIG_V410_ENCODER)            += v410enc.o | ||||
| OBJS-$(CONFIG_V210X_DECODER)           += v210x.o | ||||
| OBJS-$(CONFIG_VB_DECODER)              += vb.o | ||||
| OBJS-$(CONFIG_VBLE_DECODER)            += vble.o | ||||
|   | ||||
| @@ -215,6 +215,7 @@ void avcodec_register_all(void) | ||||
|     REGISTER_DECODER (UTVIDEO, utvideo); | ||||
|     REGISTER_ENCDEC  (V210,  v210); | ||||
|     REGISTER_DECODER (V210X, v210x); | ||||
|     REGISTER_ENCDEC  (V410, v410); | ||||
|     REGISTER_DECODER (VB, vb); | ||||
|     REGISTER_DECODER (VBLE, vble); | ||||
|     REGISTER_DECODER (VC1, vc1); | ||||
|   | ||||
| @@ -254,6 +254,7 @@ enum CodecID { | ||||
|     CODEC_ID_BMV_VIDEO, | ||||
|     CODEC_ID_VBLE, | ||||
|     CODEC_ID_DXTORY, | ||||
|     CODEC_ID_V410, | ||||
|     CODEC_ID_UTVIDEO = 0x800, | ||||
|     CODEC_ID_ESCAPE130  = MKBETAG('E','1','3','0'), | ||||
|  | ||||
|   | ||||
							
								
								
									
										113
									
								
								libavcodec/v410dec.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								libavcodec/v410dec.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| /* | ||||
|  * v410 decoder | ||||
|  * | ||||
|  * Copyright (c) 2011 Derek Buitenhuis | ||||
|  * | ||||
|  * This file is part of FFmpeg. | ||||
|  * | ||||
|  * FFmpeg is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2.1 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * FFmpeg is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with FFmpeg; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  */ | ||||
|  | ||||
| #include "avcodec.h" | ||||
| #include "get_bits.h" | ||||
|  | ||||
| static av_cold int v410_decode_init(AVCodecContext *avctx) | ||||
| { | ||||
|     avctx->pix_fmt             = PIX_FMT_YUV444P10; | ||||
|     avctx->bits_per_raw_sample = 10; | ||||
|  | ||||
|     if (avctx->width & 1) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "v410 requires width to be even.\n"); | ||||
|         return AVERROR_INVALIDDATA; | ||||
|     } | ||||
|  | ||||
|     avctx->coded_frame = avcodec_alloc_frame(); | ||||
|  | ||||
|     if (!avctx->coded_frame) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); | ||||
|         return AVERROR(ENOMEM); | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int v410_decode_frame(AVCodecContext *avctx, void *data, | ||||
|                              int *data_size, AVPacket *avpkt) | ||||
| { | ||||
|     AVFrame *pic = avctx->coded_frame; | ||||
|     uint8_t *src = avpkt->data; | ||||
|     uint16_t *y, *u, *v; | ||||
|     uint32_t val; | ||||
|     int i, j; | ||||
|  | ||||
|     if (pic->data[0]) | ||||
|         avctx->release_buffer(avctx, pic); | ||||
|  | ||||
|     pic->reference = 0; | ||||
|  | ||||
|     if (avctx->get_buffer(avctx, pic) < 0) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); | ||||
|         return AVERROR(ENOMEM); | ||||
|     } | ||||
|  | ||||
|     pic->key_frame = 1; | ||||
|     pic->pict_type = FF_I_TYPE; | ||||
|  | ||||
|     y = (uint16_t *)pic->data[0]; | ||||
|     u = (uint16_t *)pic->data[1]; | ||||
|     v = (uint16_t *)pic->data[2]; | ||||
|  | ||||
|     for (i = 0; i < avctx->height; i++) { | ||||
|         for (j = 0; j < avctx->width; j++) { | ||||
|             val = AV_RL32(src); | ||||
|  | ||||
|             u[j] = (val >>  2) & 0x3FF; | ||||
|             y[j] = (val >> 12) & 0x3FF; | ||||
|             v[j] = (val >> 22); | ||||
|  | ||||
|             src += 4; | ||||
|         } | ||||
|  | ||||
|         y += pic->linesize[0] >> 1; | ||||
|         u += pic->linesize[1] >> 1; | ||||
|         v += pic->linesize[2] >> 1; | ||||
|     } | ||||
|  | ||||
|     *data_size = sizeof(AVFrame); | ||||
|     *(AVFrame *)data = *pic; | ||||
|  | ||||
|     return avpkt->size; | ||||
| } | ||||
|  | ||||
| static av_cold int v410_decode_close(AVCodecContext *avctx) | ||||
| { | ||||
|     if (avctx->coded_frame->data[0]) | ||||
|         avctx->release_buffer(avctx, avctx->coded_frame); | ||||
|  | ||||
|     av_freep(&avctx->coded_frame); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| AVCodec ff_v410_decoder = { | ||||
|     .name         = "v410", | ||||
|     .type         = AVMEDIA_TYPE_VIDEO, | ||||
|     .id           = CODEC_ID_V410, | ||||
|     .init         = v410_decode_init, | ||||
|     .decode       = v410_decode_frame, | ||||
|     .close        = v410_decode_close, | ||||
|     .capabilities = CODEC_CAP_DR1, | ||||
|     .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"), | ||||
| }; | ||||
							
								
								
									
										99
									
								
								libavcodec/v410enc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								libavcodec/v410enc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| /* | ||||
|  * v410 encoder | ||||
|  * | ||||
|  * Copyright (c) 2011 Derek Buitenhuis | ||||
|  * | ||||
|  * This file is part of FFmpeg. | ||||
|  * | ||||
|  * FFmpeg is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2.1 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * FFmpeg is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with FFmpeg; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  */ | ||||
|  | ||||
| #include "avcodec.h" | ||||
| #include "put_bits.h" | ||||
|  | ||||
| static av_cold int v410_encode_init(AVCodecContext *avctx) | ||||
| { | ||||
|     if (avctx->width & 1) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "v410 requires width to be even.\n"); | ||||
|         return AVERROR_INVALIDDATA; | ||||
|     } | ||||
|  | ||||
|     avctx->coded_frame = avcodec_alloc_frame(); | ||||
|  | ||||
|     if (!avctx->coded_frame) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); | ||||
|         return AVERROR(ENOMEM); | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int v410_encode_frame(AVCodecContext *avctx, uint8_t *buf, | ||||
|                              int buf_size, void *data) | ||||
| { | ||||
|     AVFrame *pic = data; | ||||
|     uint8_t *dst = buf; | ||||
|     uint16_t *y, *u, *v; | ||||
|     uint32_t val; | ||||
|     int i, j; | ||||
|     int output_size = 0; | ||||
|  | ||||
|     if (buf_size < avctx->width * avctx->height * 3) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "Out buffer is too small.\n"); | ||||
|         return AVERROR(ENOMEM); | ||||
|     } | ||||
|  | ||||
|     avctx->coded_frame->reference = 0; | ||||
|     avctx->coded_frame->key_frame = 1; | ||||
|     avctx->coded_frame->pict_type = FF_I_TYPE; | ||||
|  | ||||
|     y = (uint16_t *)pic->data[0]; | ||||
|     u = (uint16_t *)pic->data[1]; | ||||
|     v = (uint16_t *)pic->data[2]; | ||||
|  | ||||
|     for (i = 0; i < avctx->height; i++) { | ||||
|         for (j = 0; j < avctx->width; j++) { | ||||
|             val  = u[j] << 2; | ||||
|             val |= y[j] << 12; | ||||
|             val |= v[j] << 22; | ||||
|             AV_WL32(dst, val); | ||||
|             dst += 4; | ||||
|             output_size += 4; | ||||
|         } | ||||
|         y += pic->linesize[0] >> 1; | ||||
|         u += pic->linesize[1] >> 1; | ||||
|         v += pic->linesize[2] >> 1; | ||||
|     } | ||||
|  | ||||
|     return output_size; | ||||
| } | ||||
|  | ||||
| static av_cold int v410_encode_close(AVCodecContext *avctx) | ||||
| { | ||||
|     av_freep(&avctx->coded_frame); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| AVCodec ff_v410_encoder = { | ||||
|     .name         = "v410", | ||||
|     .type         = AVMEDIA_TYPE_VIDEO, | ||||
|     .id           = CODEC_ID_V410, | ||||
|     .init         = v410_encode_init, | ||||
|     .encode       = v410_encode_frame, | ||||
|     .close        = v410_encode_close, | ||||
|     .pix_fmts     = (const enum PixelFormat[]){ PIX_FMT_YUV444P10, PIX_FMT_NONE }, | ||||
|     .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"), | ||||
| }; | ||||
| @@ -21,7 +21,7 @@ | ||||
| #define AVCODEC_VERSION_H | ||||
|  | ||||
| #define LIBAVCODEC_VERSION_MAJOR 53 | ||||
| #define LIBAVCODEC_VERSION_MINOR 43 | ||||
| #define LIBAVCODEC_VERSION_MINOR 44 | ||||
| #define LIBAVCODEC_VERSION_MICRO  0 | ||||
|  | ||||
| #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | ||||
|   | ||||
| @@ -90,6 +90,7 @@ const AVCodecTag codec_movvideo_tags[] = { | ||||
|     { CODEC_ID_R10K,   MKTAG('R', '1', '0', 'g') }, /* UNCOMPRESSED 10BIT RGB */ | ||||
|     { CODEC_ID_R210,   MKTAG('r', '2', '1', '0') }, /* UNCOMPRESSED 10BIT RGB */ | ||||
|     { CODEC_ID_V210,   MKTAG('v', '2', '1', '0') }, /* UNCOMPRESSED 10BIT 4:2:2 */ | ||||
|     { CODEC_ID_V410,   MKTAG('v', '4', '1', '0') }, /* UNCOMPRESSED 10BIT 4:4:4 */ | ||||
|  | ||||
|     { CODEC_ID_MJPEG,  MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */ | ||||
|     { CODEC_ID_MJPEG,  MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */ | ||||
|   | ||||
| @@ -198,6 +198,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { | ||||
|     { CODEC_ID_R10K,         MKTAG('R', '1', '0', 'k') }, | ||||
|     { CODEC_ID_R210,         MKTAG('r', '2', '1', '0') }, | ||||
|     { CODEC_ID_V210,         MKTAG('v', '2', '1', '0') }, | ||||
|     { CODEC_ID_V410,         MKTAG('v', '4', '1', '0') }, | ||||
|     { CODEC_ID_INDEO3,       MKTAG('I', 'V', '3', '1') }, | ||||
|     { CODEC_ID_INDEO3,       MKTAG('I', 'V', '3', '2') }, | ||||
|     { CODEC_ID_INDEO4,       MKTAG('I', 'V', '4', '1') }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user