| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Cirrus Logic AccuPak (CLJR) codec | 
					
						
							|  |  |  |  * Copyright (c) 2003 Alex Beregszaszi | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2011-03-18 17:35:10 +00:00
										 |  |  |  * This file is part of Libav. | 
					
						
							| 
									
										
										
										
											2006-10-07 15:30:46 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2011-03-18 17:35:10 +00:00
										 |  |  |  * Libav is free software; you can redistribute it and/or | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2006-10-07 15:30:46 +00:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2011-03-18 17:35:10 +00:00
										 |  |  |  * Libav is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |  * 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 | 
					
						
							| 
									
										
										
										
											2011-03-18 17:35:10 +00:00
										 |  |  |  * License along with Libav; if not, write to the Free Software | 
					
						
							| 
									
										
										
										
											2006-01-12 22:43:26 +00:00
										 |  |  |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2010-04-20 14:45:34 +00:00
										 |  |  |  * @file | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |  * Cirrus Logic AccuPak codec. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | #include "avcodec.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-13 16:20:26 +00:00
										 |  |  | #include "get_bits.h"
 | 
					
						
							| 
									
										
										
										
											2011-12-08 00:05:23 +00:00
										 |  |  | #include "put_bits.h"
 | 
					
						
							| 
									
										
										
										
											2008-09-03 12:43:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | typedef struct CLJRContext{ | 
					
						
							|  |  |  |     AVCodecContext *avctx; | 
					
						
							|  |  |  |     AVFrame picture; | 
					
						
							|  |  |  | } CLJRContext; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-08 14:48:12 +00:00
										 |  |  | static av_cold int common_init(AVCodecContext *avctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CLJRContext * const a = avctx->priv_data; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-08 14:50:48 +00:00
										 |  |  |     avctx->coded_frame = &a->picture; | 
					
						
							| 
									
										
										
										
											2011-12-08 14:48:12 +00:00
										 |  |  |     a->avctx = avctx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if CONFIG_CLJR_DECODER
 | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  | static int decode_frame(AVCodecContext *avctx, | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |                         void *data, int *data_size, | 
					
						
							| 
									
										
										
										
											2009-04-07 15:59:50 +00:00
										 |  |  |                         AVPacket *avpkt) | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-07 15:59:50 +00:00
										 |  |  |     const uint8_t *buf = avpkt->data; | 
					
						
							|  |  |  |     int buf_size = avpkt->size; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |     CLJRContext * const a = avctx->priv_data; | 
					
						
							| 
									
										
										
										
											2011-12-06 17:45:37 +00:00
										 |  |  |     GetBitContext gb; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |     AVFrame *picture = data; | 
					
						
							| 
									
										
										
										
											2011-12-08 14:50:48 +00:00
										 |  |  |     AVFrame * const p = &a->picture; | 
					
						
							| 
									
										
										
										
											2003-08-24 22:08:22 +00:00
										 |  |  |     int x, y; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if(p->data[0]) | 
					
						
							|  |  |  |         avctx->release_buffer(avctx, p); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 21:54:52 +00:00
										 |  |  |     if(buf_size/avctx->height < avctx->width) { | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "Resolution larger than buffer size. Invalid header?\n"); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |     p->reference= 0; | 
					
						
							|  |  |  |     if(avctx->get_buffer(avctx, p) < 0){ | 
					
						
							| 
									
										
										
										
											2003-11-03 13:26:22 +00:00
										 |  |  |         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-04-29 18:53:57 +02:00
										 |  |  |     p->pict_type= AV_PICTURE_TYPE_I; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |     p->key_frame= 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-06 17:45:37 +00:00
										 |  |  |     init_get_bits(&gb, buf, buf_size * 8); | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for(y=0; y<avctx->height; y++){ | 
					
						
							|  |  |  |         uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ]; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:45:09 +00:00
										 |  |  |         uint8_t *cb= &a->picture.data[1][ y*a->picture.linesize[1] ]; | 
					
						
							|  |  |  |         uint8_t *cr= &a->picture.data[2][ y*a->picture.linesize[2] ]; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |         for(x=0; x<avctx->width; x+=4){ | 
					
						
							| 
									
										
										
										
											2011-12-06 17:45:37 +00:00
										 |  |  |             luma[3] = get_bits(&gb, 5) << 3; | 
					
						
							|  |  |  |             luma[2] = get_bits(&gb, 5) << 3; | 
					
						
							|  |  |  |             luma[1] = get_bits(&gb, 5) << 3; | 
					
						
							|  |  |  |             luma[0] = get_bits(&gb, 5) << 3; | 
					
						
							| 
									
										
										
										
											2005-12-22 01:10:11 +00:00
										 |  |  |             luma+= 4; | 
					
						
							| 
									
										
										
										
											2011-12-06 17:45:37 +00:00
										 |  |  |             *(cb++) = get_bits(&gb, 6) << 2; | 
					
						
							|  |  |  |             *(cr++) = get_bits(&gb, 6) << 2; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-08 14:50:48 +00:00
										 |  |  |     *picture = a->picture; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |     *data_size = sizeof(AVPicture); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return buf_size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-08 14:48:12 +00:00
										 |  |  | static av_cold int decode_init(AVCodecContext *avctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     avctx->pix_fmt = PIX_FMT_YUV411P; | 
					
						
							|  |  |  |     return common_init(avctx); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static av_cold int decode_end(AVCodecContext *avctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CLJRContext *a = avctx->priv_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (a->picture.data[0]) | 
					
						
							|  |  |  |         avctx->release_buffer(avctx, &a->picture); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AVCodec ff_cljr_decoder = { | 
					
						
							|  |  |  |     .name           = "cljr", | 
					
						
							|  |  |  |     .type           = AVMEDIA_TYPE_VIDEO, | 
					
						
							|  |  |  |     .id             = CODEC_ID_CLJR, | 
					
						
							|  |  |  |     .priv_data_size = sizeof(CLJRContext), | 
					
						
							|  |  |  |     .init           = decode_init, | 
					
						
							|  |  |  |     .close          = decode_end, | 
					
						
							|  |  |  |     .decode         = decode_frame, | 
					
						
							|  |  |  |     .capabilities   = CODEC_CAP_DR1, | 
					
						
							|  |  |  |     .long_name      = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-13 23:44:16 +00:00
										 |  |  | #if CONFIG_CLJR_ENCODER
 | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ | 
					
						
							| 
									
										
										
										
											2011-12-08 00:05:23 +00:00
										 |  |  |     PutBitContext pb; | 
					
						
							|  |  |  |     AVFrame *p = data; | 
					
						
							|  |  |  |     int x, y; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-29 18:53:57 +02:00
										 |  |  |     p->pict_type= AV_PICTURE_TYPE_I; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  |     p->key_frame= 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-08 00:05:23 +00:00
										 |  |  |     init_put_bits(&pb, buf, buf_size / 8); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (y = 0; y < avctx->height; y++) { | 
					
						
							|  |  |  |         uint8_t *luma = &p->data[0][y * p->linesize[0]]; | 
					
						
							|  |  |  |         uint8_t *cb   = &p->data[1][y * p->linesize[1]]; | 
					
						
							|  |  |  |         uint8_t *cr   = &p->data[2][y * p->linesize[2]]; | 
					
						
							|  |  |  |         for (x = 0; x < avctx->width; x += 4) { | 
					
						
							|  |  |  |             put_bits(&pb, 5, luma[3] >> 3); | 
					
						
							|  |  |  |             put_bits(&pb, 5, luma[2] >> 3); | 
					
						
							|  |  |  |             put_bits(&pb, 5, luma[1] >> 3); | 
					
						
							|  |  |  |             put_bits(&pb, 5, luma[0] >> 3); | 
					
						
							|  |  |  |             luma += 4; | 
					
						
							|  |  |  |             put_bits(&pb, 6, *(cb++) >> 2); | 
					
						
							|  |  |  |             put_bits(&pb, 6, *(cr++) >> 2); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-08 00:05:23 +00:00
										 |  |  |     flush_put_bits(&pb); | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-08 00:05:23 +00:00
										 |  |  |     return put_bits_count(&pb) / 8; | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-25 21:40:11 +00:00
										 |  |  | AVCodec ff_cljr_encoder = { | 
					
						
							| 
									
										
										
										
											2011-07-17 12:54:31 +02:00
										 |  |  |     .name           = "cljr", | 
					
						
							|  |  |  |     .type           = AVMEDIA_TYPE_VIDEO, | 
					
						
							|  |  |  |     .id             = CODEC_ID_CLJR, | 
					
						
							|  |  |  |     .priv_data_size = sizeof(CLJRContext), | 
					
						
							| 
									
										
										
										
											2011-12-08 14:48:12 +00:00
										 |  |  |     .init           = common_init, | 
					
						
							| 
									
										
										
										
											2011-07-17 12:54:31 +02:00
										 |  |  |     .encode         = encode_frame, | 
					
						
							| 
									
										
										
										
											2011-12-08 00:05:23 +00:00
										 |  |  |     .pix_fmts       = (const enum PixelFormat[]) { PIX_FMT_YUV411P, | 
					
						
							|  |  |  |                                                    PIX_FMT_NONE }, | 
					
						
							|  |  |  |     .long_name      = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), | 
					
						
							| 
									
										
										
										
											2003-07-27 20:20:31 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2008-09-03 12:33:21 +00:00
										 |  |  | #endif
 |