You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	RoQ-encoder: introducing Quake 3 compatibility option
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
				
					committed by
					
						 Michael Niedermayer
						Michael Niedermayer
					
				
			
			
				
	
			
			
			
						parent
						
							80a79f2641
						
					
				
				
					commit
					392b0345d6
				
			| @@ -43,6 +43,7 @@ struct RoqTempData; | ||||
|  | ||||
| typedef struct RoqContext { | ||||
|  | ||||
|     const AVClass *class; | ||||
|     AVCodecContext *avctx; | ||||
|     AVFrame *last_frame; | ||||
|     AVFrame *current_frame; | ||||
| @@ -69,6 +70,9 @@ typedef struct RoqContext { | ||||
|     const AVFrame *frame_to_enc; | ||||
|     uint8_t *out_buf; | ||||
|     struct RoqTempData *tmpData; | ||||
|  | ||||
|     int quake3_compat; // Quake 3 compatibility option | ||||
|  | ||||
| } RoqContext; | ||||
|  | ||||
| #define RoQ_INFO              0x1001 | ||||
|   | ||||
| @@ -57,6 +57,7 @@ | ||||
| #include <string.h> | ||||
|  | ||||
| #include "libavutil/attributes.h" | ||||
| #include "libavutil/opt.h" | ||||
| #include "roqvideo.h" | ||||
| #include "bytestream.h" | ||||
| #include "elbg.h" | ||||
| @@ -69,7 +70,7 @@ | ||||
|  * Maximum number of generated 4x4 codebooks. Can't be 256 to workaround a | ||||
|  * Quake 3 bug. | ||||
|  */ | ||||
| #define MAX_CBS_4x4 255 | ||||
| #define MAX_CBS_4x4 256 | ||||
|  | ||||
| #define MAX_CBS_2x2 256 ///< Maximum number of 2x2 codebooks. | ||||
|  | ||||
| @@ -540,7 +541,7 @@ static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData) | ||||
|     int i, j, idx=0; | ||||
|  | ||||
|     /* Make remaps for the final codebook usage */ | ||||
|     for (i=0; i<MAX_CBS_4x4; i++) { | ||||
|     for (i=0; i<(enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4); i++) { | ||||
|         if (tempData->codebooks.usedCB4[i]) { | ||||
|             tempData->i2f4[i] = idx; | ||||
|             tempData->f2i4[idx] = i; | ||||
| @@ -847,9 +848,9 @@ static void generate_new_codebooks(RoqContext *enc, RoqTempdata *tempData) | ||||
|     } | ||||
|  | ||||
|     /* Create 4x4 codebooks */ | ||||
|     generate_codebook(enc, tempData, points, max, results4, 4, MAX_CBS_4x4); | ||||
|     generate_codebook(enc, tempData, points, max, results4, 4, (enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4)); | ||||
|  | ||||
|     codebooks->numCB4 = MAX_CBS_4x4; | ||||
|     codebooks->numCB4 = (enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4); | ||||
|  | ||||
|     tempData->closest_cb2 = av_malloc(max*4*sizeof(int)); | ||||
|  | ||||
| @@ -901,10 +902,10 @@ static void roq_encode_video(RoqContext *enc) | ||||
|         gather_data_for_cel(tempData->cel_evals + i, enc, tempData); | ||||
|  | ||||
|     /* Quake 3 can't handle chunks bigger than 65535 bytes */ | ||||
|     if (tempData->mainChunkSize/8 > 65535) { | ||||
|     if (tempData->mainChunkSize/8 > 65535 && enc->quake3_compat) { | ||||
|         av_log(enc->avctx, AV_LOG_ERROR, | ||||
|                "Warning, generated a frame too big (%d > 65535), " | ||||
|                "try using a smaller qscale value.\n", | ||||
|                "Warning, generated a frame too big for Quake (%d > 65535), " | ||||
|                "now switching to a bigger qscale value.\n", | ||||
|                tempData->mainChunkSize/8); | ||||
|         enc->lambda *= 1.5; | ||||
|         tempData->mainChunkSize = 0; | ||||
| @@ -1073,6 +1074,20 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #define OFFSET(x) offsetof(RoqContext, x) | ||||
| #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM | ||||
| static const AVOption options[] = { | ||||
|     { "quake3_compat", "Whether to respect known limitations in Quake 3 decoder", OFFSET(quake3_compat), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE }, | ||||
|     { NULL }, | ||||
| }; | ||||
|  | ||||
| static const AVClass roq_class = { | ||||
|     .class_name = "RoQ", | ||||
|     .item_name  = av_default_item_name, | ||||
|     .option     = options, | ||||
|     .version    = LIBAVUTIL_VERSION_INT, | ||||
| }; | ||||
|  | ||||
| AVCodec ff_roq_encoder = { | ||||
|     .name                 = "roqvideo", | ||||
|     .long_name            = NULL_IF_CONFIG_SMALL("id RoQ video"), | ||||
| @@ -1085,4 +1100,5 @@ AVCodec ff_roq_encoder = { | ||||
|     .supported_framerates = (const AVRational[]){ {30,1}, {0,0} }, | ||||
|     .pix_fmts             = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P, | ||||
|                                                         AV_PIX_FMT_NONE }, | ||||
|     .priv_class     = &roq_class, | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user