From: kt920.kim Date: Mon, 12 Dec 2011 15:08:07 +0000 (+0900) Subject: [Title] Solved the problem codec module does not work. X-Git-Tag: 2.2.1_release^2~182^2~14 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b5321d2dd97195689c4f766e96833b80c0a18108;p=sdk%2Femulator%2Femulator-kernel.git [Title] Solved the problem codec module does not work. [Type] Bug fix [Module] Enhancement [Priority] [CQ#] [Redmine#] [Problem] AVCodecContext struct has been updated in the guest. [Cause] [Solution] Update AVCodecContext struct in the kernel and qemu. [TestCase] --- diff --git a/drivers/samsung/Kconfig b/drivers/samsung/Kconfig index 50efdba5b466..7b389e7851aa 100755 --- a/drivers/samsung/Kconfig +++ b/drivers/samsung/Kconfig @@ -1,4 +1,4 @@ -menu "Virtual_3D_Accelerator" +menu "Virtual device drivers for emulator" config HW_ACCELERATOR tristate "Samsung Virtual 3D Accelerator driver" diff --git a/drivers/samsung/avcodec.h b/drivers/samsung/avcodec.h index e480098e6f47..7c6b19f6d252 100644 --- a/drivers/samsung/avcodec.h +++ b/drivers/samsung/avcodec.h @@ -1179,6 +1179,11 @@ typedef struct AVCodecContext { */ int frame_size; int frame_number; ///< audio or video frame number + + /* add i_frame_number and stts_count because gstreamer plugin has been updated */ + int i_frame_number; + int stts_count; + #if LIBAVCODEC_VERSION_MAJOR < 53 int real_pict_num; ///< Returns the real picture number of previous encoded frame. #endif diff --git a/drivers/samsung/emul_codec.c b/drivers/samsung/emul_codec.c index 8d018c24db70..c476925b6545 100644 --- a/drivers/samsung/emul_codec.c +++ b/drivers/samsung/emul_codec.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,7 @@ #include "avformat.h" -#define DRIVER_NAME "SVCODEC" +#define DRIVER_NAME "svcodec" #define CODEC_MAJOR 240 MODULE_LICENSE("GPL"); @@ -48,42 +49,33 @@ MODULE_DESCRIPTION("Virtual Codec Driver for Emulator"); struct _param { uint32_t apiIndex; uint32_t in_args_num; - uint32_t in_args[20]; + uint32_t in_args[10]; uint32_t ret; }; enum svodec_param_offset { CODEC_API_INDEX = 0, CODEC_IN_PARAM, - CODEC_RETURN_VALUE + CODEC_RETURN_VALUE, + CODEC_READY_TO_GET_DATA, + CODEC_GET_RESULT_DATA, }; -struct codec_buf { - AVFormatContext *pFormatCtx; - AVClass *pClass; - struct AVInputFormat *pInputFmt; - ByteIOContext *pByteIOCtx; - AVStream *pStream; - - AVCodecContext *pCodecCtx; - AVFrame *pFrame; - AVCodec *pCodec; -}; - -struct svcodec_dev { +typedef struct _svcodec_dev { struct pci_dev *dev; /* pci device */ - volatile unsigned long *ioaddr; /* memory mapped registers */ - volatile unsigned long *memaddr; /* memory mapped registers */ + volatile unsigned int *ioaddr; + volatile unsigned int *memaddr; resource_size_t io_start; resource_size_t io_size; resource_size_t mem_start; resource_size_t mem_size; - /* image buffer */ -// uint8_t *img_buf; -}; + uint8_t *imgBuf; +/* struct semaphore sem; + int wake_up; */ +} svcodec_dev; static struct pci_device_id svcodec_pci_table[] __devinitdata = { { @@ -95,12 +87,13 @@ static struct pci_device_id svcodec_pci_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(pci, svcodec_pci_table); -static struct svcodec_dev *svcodec; - -// static void call_workqueue(void *data); +static svcodec_dev *svcodec; -// DECLARE_WAIT_QUEUE_HEAD(waitqueue_read); -// DECLARE_WORK(work_queue, call_workqueue); +#if 0 +static void call_workqueue(void *data); +DECLARE_WAIT_QUEUE_HEAD(waitqueue_read); +DECLARE_WORK(work_queue, call_workqueue); +#endif static int svcodec_open (struct inode *inode, struct file *file) { @@ -108,50 +101,75 @@ static int svcodec_open (struct inode *inode, struct file *file) try_module_get(THIS_MODULE); /* register interrupt handler */ -/* if (request_irq(svcodec->dev->irq, svcodec_interrupt, IRQF_SHARED, +/* if (request_irq(svcodec->dev->irq, svcodec_irq_handler, IRQF_SHARED, DRIVER_NAME, svcodec)) { printk(KERN_ERR "[%s] : request_irq failed\n", __func__); - } */ + return -EBUSY; + } + init_MUTEX(&svcodec->sem); */ - SVCODEC_LOG("\n"); return 0; } -static long tempCnt = 0; +static int get_picture_size (int pix_fmt, int width, int height) +{ + int size; + + switch (pix_fmt) { + case PIX_FMT_YUV420P: + case PIX_FMT_YUV422P: + case PIX_FMT_YUV444P: + case PIX_FMT_YUV410P: + case PIX_FMT_YUV411P: + case PIX_FMT_YUVJ420P: + case PIX_FMT_YUVJ422P: + case PIX_FMT_YUVJ444P: + size = (width * height * 3) / 2; + break; + case PIX_FMT_RGB24: + case PIX_FMT_BGR24: + size = width * height * 3; + break; +/* case PIX_FMT_RGB32: + size = width * height * 4; + break; + case PIX_FMT_RGB555: + case PIX_FMT_RGB565: + case PIX_FMT_YUYV422: + case PIX_FMT_UYVY422: + size = widht * height * 2; + break; */ + default: + size = -1; + } + return size; +} + static ssize_t svcodec_write (struct file *file, const char __user *buf, size_t count, loff_t *fops) { struct _param paramInfo; AVCodecContext tempCtx; - uint8_t *ptr = NULL; - int i; if (!svcodec) { - printk(KERN_ERR "[%s] : Fail to get codec device info\n", __func__); + printk(KERN_ERR "[%s]:Fail to get codec device info\n", __func__); } - if(copy_from_user(¶mInfo, buf, sizeof(struct _param))) - { - // error handling !!! + if (copy_from_user(¶mInfo, buf, sizeof(struct _param))) { + printk(KERN_ERR "[%s]:Fail to get codec parameter info from user\n", __func__); } - for (i = 0; i < paramInfo.in_args_num; i++) { - writel(paramInfo.in_args[i], svcodec->ioaddr + CODEC_IN_PARAM); - } /* guest to host */ if (paramInfo.apiIndex == 2) { AVCodecContext *ctx; AVCodec *codec; int size, size1; -// int *id; -// char *bEncode; ctx = (AVCodecContext*)paramInfo.in_args[0]; codec = (AVCodec*)paramInfo.in_args[1]; -/* id = (int*)paramInfo.in_args[2]; - bEncode = (char*)paramInfo.in_args[3]; */ size = sizeof(AVCodecContext); + printk(KERN_DEBUG "[%s]:AVCodecContext size:%d\n", sizeof(AVCodecContext)); memcpy(&tempCtx, ctx, size); memcpy_toio(svcodec->memaddr, ctx, size); @@ -159,9 +177,6 @@ static ssize_t svcodec_write (struct file *file, const char __user *buf, size1 = size + sizeof(AVCodec); memcpy_toio((uint8_t*)svcodec->memaddr + size1, ctx->extradata, ctx->extradata_size); - -// memcpy_toio(svcodec->memaddr + size + 4, bEncode, sizeof(char)); -// writel((uint32_t)ctx->extradata, svcodec->ioaddr + CODEC_IN_PARAM); } else if (paramInfo.apiIndex == 6) { int value = -1; value = *(int*)paramInfo.ret; @@ -181,19 +196,13 @@ static ssize_t svcodec_write (struct file *file, const char __user *buf, size = sizeof(AVCodecContext); memcpy(&tempCtx, ctx, size); - memcpy_toio(svcodec->memaddr, ctx, size); +// memcpy_toio(svcodec->memaddr, ctx, size); memcpy_toio((uint8_t*)svcodec->memaddr + size, &buf_size, sizeof(int)); if (buf_size > 0) { size += sizeof(int); memcpy_toio((uint8_t*)svcodec->memaddr + size, buf, buf_size); } - -/* writel((uint32_t)&ctx->frame_number, svcodec->ioaddr + CODEC_IN_PARAM); - writel((uint32_t)&ctx->pix_fmt, svcodec->ioaddr + CODEC_IN_PARAM); - writel((uint32_t)&ctx->coded_frame, svcodec->ioaddr + CODEC_IN_PARAM); - writel((uint32_t)&ctx->sample_aspect_ratio, svcodec->ioaddr + CODEC_IN_PARAM); - writel((uint32_t)&ctx->reordered_opaque, svcodec->ioaddr + CODEC_IN_PARAM); */ } else if (paramInfo.apiIndex == 22) { AVCodecContext *ctx = NULL; AVFrame *pict = NULL; @@ -209,10 +218,11 @@ static ssize_t svcodec_write (struct file *file, const char __user *buf, pict = (AVFrame*)paramInfo.in_args[3]; pict_buf = (uint8_t*)paramInfo.in_args[4]; pict_buf_size = (ctx->height * ctx->width) * 3 / 2; - -// writel((uint32_t)ctx->coded_frame, svcodec->ioaddr + CODEC_IN_PARAM); - ptr = kmalloc(buf_size, GFP_KERNEL); -// writel((uint32_t)ptr, svcodec->ioaddr + CODEC_IN_PARAM); + + svcodec->imgBuf = kmalloc(buf_size, GFP_KERNEL); + if (!svcodec->imgBuf) { + printk(KERN_ERR "[%s]Failed to allocate image buffer\n", __func__); + } memcpy_toio(svcodec->memaddr, &buf_size, sizeof(int)); memcpy_toio((uint8_t*)svcodec->memaddr + 4, buf, buf_size); @@ -226,39 +236,42 @@ static ssize_t svcodec_write (struct file *file, const char __user *buf, size += sizeof(AVFrame); SVCODEC_LOG("AVCODEC_ENCODE_VIDEO 1\n"); memcpy_toio((uint8_t*)svcodec->memaddr + size, pict_buf, pict_buf_size); - SVCODEC_LOG("ENCODE Count :%ld\n", ++tempCnt); } else { int pict_temp = 0; memcpy_toio((uint8_t*)svcodec->memaddr + size, &pict_temp, sizeof(int)); SVCODEC_LOG("AVCODEC_ENCODE_VIDEO 2\n"); } } else if (paramInfo.apiIndex == 24) { + int pix_fmt; int width, height; - int size, size2; + int size; + pix_fmt = *(int*)paramInfo.in_args[1]; width = *(int*)paramInfo.in_args[2]; height = *(int*)paramInfo.in_args[3]; - size = width * height; - size2 = size / 4; - ptr = kmalloc(size + size2 * 2, GFP_KERNEL); - writel((uint32_t)ptr, svcodec->ioaddr + CODEC_IN_PARAM); + size = get_picture_size(pix_fmt, width, height); + svcodec->imgBuf = kmalloc(size, GFP_KERNEL); + if (!svcodec->imgBuf) { + printk(KERN_ERR "[%s]Failed to allocate image buffer\n", __func__); + } } - // return value - writel(paramInfo.ret, svcodec->ioaddr + CODEC_RETURN_VALUE); - // api index writel((uint32_t)paramInfo.apiIndex, svcodec->ioaddr + CODEC_API_INDEX); /* host to guest */ if (paramInfo.apiIndex == 2) { AVCodecContext *avctx; + AVCodec *codec; int *ret, size; avctx = (AVCodecContext*)paramInfo.in_args[0]; + codec = (AVCodec*)paramInfo.in_args[1]; + ret = (int*)paramInfo.ret; size = sizeof(AVCodecContext); memcpy_fromio(avctx, svcodec->memaddr, size); -#if 1 + memcpy_fromio(ret, (uint8_t*)svcodec->memaddr + size, sizeof(int)); + avctx->av_class = tempCtx.av_class; - avctx->codec = (AVCodec*)paramInfo.in_args[1]; + avctx->codec = codec; // avctx->priv_data = tempCtx.priv_data; avctx->extradata = tempCtx.extradata; avctx->opaque = tempCtx.opaque; @@ -277,10 +290,10 @@ static ssize_t svcodec_write (struct file *file, const char __user *buf, avctx->execute = tempCtx.execute; avctx->thread_opaque = tempCtx.thread_opaque; avctx->execute2 = tempCtx.execute2; -#endif - ret = (int*)paramInfo.ret; - memcpy_fromio(ret, (uint8_t*)svcodec->memaddr + size, sizeof(int)); - + + if (copy_to_user((void*)(paramInfo.in_args[0]), avctx, sizeof(AVCodecContext))) { + printk(KERN_ERR "[%s]:Fail to copy AVCodecContext to user\n", __func__); + } } else if (paramInfo.apiIndex == 3) { int *ret; ret = (int*)paramInfo.ret; @@ -288,7 +301,11 @@ static ssize_t svcodec_write (struct file *file, const char __user *buf, } else if (paramInfo.apiIndex == 20) { AVCodecContext *avctx; AVFrame *frame; - int size, *got_picture_ptr, *ret, buf_size; + int size; + int *got_picture_ptr; + int *ret; + int buf_size; + avctx = (AVCodecContext*)paramInfo.in_args[0]; frame = (AVFrame*)paramInfo.in_args[1]; got_picture_ptr = (int*)paramInfo.in_args[2]; @@ -299,8 +316,8 @@ static ssize_t svcodec_write (struct file *file, const char __user *buf, size = sizeof(AVCodecContext); memcpy_fromio(avctx, svcodec->memaddr, size); memcpy_fromio(frame, (uint8_t*)svcodec->memaddr + size, sizeof(AVFrame)); - size += sizeof(AVFrame); + size += sizeof(AVFrame); memcpy_fromio(got_picture_ptr, (uint8_t*)svcodec->memaddr + size, sizeof(int)); size += sizeof(int); memcpy_fromio(ret, (uint8_t*)svcodec->memaddr + size , sizeof(int)); @@ -308,10 +325,9 @@ static ssize_t svcodec_write (struct file *file, const char __user *buf, *got_picture_ptr = 0; memcpy_fromio(ret, svcodec->memaddr, sizeof(int)); } -#if 1 avctx->coded_frame = frame; avctx->av_class = tempCtx.av_class; - avctx->codec = (AVCodec*)paramInfo.in_args[1]; + avctx->codec = tempCtx.codec; avctx->extradata = tempCtx.extradata; avctx->opaque = tempCtx.opaque; avctx->get_buffer = tempCtx.get_buffer; @@ -329,81 +345,44 @@ static ssize_t svcodec_write (struct file *file, const char __user *buf, avctx->execute = tempCtx.execute; avctx->thread_opaque = tempCtx.thread_opaque; avctx->execute2 = tempCtx.execute2; -#endif + if (copy_to_user((void*)(paramInfo.in_args[0]), avctx, sizeof(AVCodecContext))) { + printk(KERN_ERR "[%s]:Fail to copy AVCodecContext to user\n", __func__); + } } else if (paramInfo.apiIndex == 22) { -// AVCodecContext *ctx; uint32_t buf_size; - int *ret; -// ctx = (AVCodecContext*)paramInfo.in_args[0]; buf_size = *(uint32_t*)paramInfo.in_args[2]; ret = (int*)paramInfo.ret; if (buf_size > 0) { - memcpy_fromio(ptr, svcodec->memaddr, buf_size); - if(copy_to_user((void *)(paramInfo.in_args[1]), ptr, buf_size)) - { - // error handling !!! + memcpy_fromio(svcodec->imgBuf, svcodec->memaddr, buf_size); + if (copy_to_user((void *)(paramInfo.in_args[1]), svcodec->imgBuf, buf_size)) { + printk(KERN_ERR "[%s]:Fail to copy image buffers to user\n", __func__); } memcpy_fromio(ret, (uint8_t*)svcodec->memaddr + buf_size , sizeof(int)); } else { memcpy_fromio(ret, svcodec->memaddr , sizeof(int)); } - kfree(ptr); + kfree(svcodec->imgBuf); + svcodec->imgBuf = NULL; } else if (paramInfo.apiIndex == 24) { + int pix_fmt; int width, height; - int size, size2; + int size; + pix_fmt = *(int*)paramInfo.in_args[1]; width = *(int*)paramInfo.in_args[2]; height = *(int*)paramInfo.in_args[3]; - size = width * height; - size2 = size / 4; - memcpy_fromio(ptr, svcodec->memaddr, (size * 3 / 2)); - if(copy_to_user((void *)(paramInfo.in_args[4]), ptr, size + size2 * 2)) - { - // error handling !!! + size = get_picture_size(pix_fmt, width, height); + memcpy_fromio(svcodec->imgBuf, svcodec->memaddr, size); + if (copy_to_user((void*)paramInfo.in_args[4], svcodec->imgBuf, size)) { + printk(KERN_ERR "[%s]:Fail to copy image buffers to user\n", __func__); } - kfree(ptr); + kfree(svcodec->imgBuf); + svcodec->imgBuf = NULL; } return 0; } -// FIX ME -/* static int get_image_size (int pixelFormat) -{ - int size; - int width; - int height; - - switch (pixelFormat) { - case PIX_FMT_YUV420P: - case PIX_FMT_YUV422P: - case PIX_FMT_YUV444P: - case PIX_FMT_YUV410P: - case PIX_FMT_YUV411P: - case PIX_FMT_YUVJ420P: - case PIX_FMT_YUVJ422P: - case PIX_FMT_YUVJ444P: - size = (width * height * 3) / 2; - break; - case PIX_FMT_RGB24: - case PIX_FMT_BGR24: - size = width * height * 3; - break; - case PIX_FMT_RGB32: - size = width * height * 4; - break; - case PIX_FMT_RGB555: - case PIX_FMT_RGB565: - case PIX_FMT_YUYV422: - case PIX_FMT_UYVY422: - size = widht * height * 2; - break; - default: - size = -1; - } - return size; -} */ - static ssize_t svcodec_read (struct file *file, char __user *buf, size_t count, loff_t *fops) { @@ -411,7 +390,6 @@ static ssize_t svcodec_read (struct file *file, char __user *buf, if (!svcodec) { printk(KERN_ERR "[%s] : Fail to get codec device info\n", __func__); } -// readl(svcodec->ioaddr); return 0; } @@ -446,35 +424,38 @@ static int svcodec_release (struct inode *inode, struct file *file) free_irq(svcodec->dev->irq, svcodec); } */ -/* if (svcodec->img_buf) { - kfree(svcodec->img_buf); - svcodec->img_buf = NULL; - } */ - tempCnt = 0; + if (svcodec->imgBuf) { + kfree(svcodec->imgBuf); + svcodec->imgBuf = NULL; + } module_put(THIS_MODULE); SVCODEC_LOG("\n"); return 0; } -// static void call_workqueue(void *data) -//{ -// SVCODEC_LOG("\n"); -//} - -/* - * Interrupt handler - */ #if 0 -static irqreturn_t svcodec_interrupt (int irq, void *dev_id); +static void call_workqueue(void *data) +{ + SVCODEC_LOG("\n"); +} -static irqreturn_t svcodec_interrupt (int irq, void *dev_id) +static irqreturn_t svcodec_irq_handler (int irq, void *dev_id) { -// SVCODEC_LOG("\n"); - // schedule_work(&work_queue); + int ret = -1; + svcodec_dev *dev = (svcodec_dev*)dev_id; + + ret = ioread32(dev->ioaddr + CODEC_READY_TO_GET_DATA); + if (ret == 0) { + return IRQ_NONE; + } + SVCODEC_LOG("\n"); + dev->wake_up = ret; + wake_up_interruptible(&waitqueue); + schedule_work(&work_queue); + iowrite32(0, dev->ioaddr + CODEC_GET_RESULT_DATA); /* need more implementation */ -// return IRQ_HANDLED; - return IRQ_NONE; + return IRQ_HANDLED; } #endif @@ -485,13 +466,11 @@ struct file_operations codec_fops = { .open = svcodec_open, .mmap = svcodec_mmap, .release = svcodec_release, -// .ioctl = svcodec_ioctl, }; static void __devinit svcodec_remove (struct pci_dev *pci_dev) { if (svcodec) { - if (svcodec->ioaddr) { iounmap(svcodec->ioaddr); svcodec->ioaddr = 0; @@ -524,8 +503,8 @@ static int __devinit svcodec_probe (struct pci_dev *pci_dev, { int ret; - svcodec = (struct svcodec_dev*)kmalloc(sizeof(struct svcodec_dev), GFP_KERNEL); - memset(svcodec, 0x00, sizeof(struct svcodec_dev)); + svcodec = (svcodec_dev*)kmalloc(sizeof(svcodec_dev), GFP_KERNEL); + memset(svcodec, 0x00, sizeof(svcodec_dev)); svcodec->dev = pci_dev; @@ -550,8 +529,6 @@ static int __devinit svcodec_probe (struct pci_dev *pci_dev, printk(KERN_ERR "[%s] : pci_resource_start failed\n", __func__); goto err_out; } - - SVCODEC_LOG("mem_start:0x%x, mem_size:0x%x\n", svcodec->mem_start, svcodec->mem_size); if (!request_mem_region(svcodec->mem_start, svcodec->mem_size, DRIVER_NAME)) { printk(KERN_ERR "[%s] : request_mem_region failed\n", __func__); @@ -566,8 +543,6 @@ static int __devinit svcodec_probe (struct pci_dev *pci_dev, goto err_mem_region; } - SVCODEC_LOG("io_start:0x%x, io_size:0x%x\n", svcodec->io_start, svcodec->io_size); - if (!request_mem_region(svcodec->io_start, svcodec->io_size, DRIVER_NAME)) { printk(KERN_ERR "[%s] : request_io_region failed\n", __func__); goto err_mem_region; @@ -584,7 +559,6 @@ static int __devinit svcodec_probe (struct pci_dev *pci_dev, printk(KERN_ERR "[%s] : ioremap failed\n", __func__); goto err_mem_unmap; } - SVCODEC_LOG("MEM_ADDR:0x%lx, IO_ADDR:0x%lx\n", (unsigned long)svcodec->memaddr, (unsigned long)svcodec->ioaddr); // pci_set_drvdata(pci_dev, svcodec); if (register_chrdev(CODEC_MAJOR, DRIVER_NAME, &codec_fops)) { @@ -621,7 +595,7 @@ static struct pci_driver driver = { static int __init svcodec_init (void) { - SVCODEC_LOG("Codec accelerator initialized\n"); + SVCODEC_LOG("SVCODEC initialized\n"); return pci_register_driver(&driver); } diff --git a/drivers/samsung/pixfmt.h b/drivers/samsung/pixfmt.h index a78aee2950ca..b554331f28d5 100644 --- a/drivers/samsung/pixfmt.h +++ b/drivers/samsung/pixfmt.h @@ -161,5 +161,4 @@ enum PixelFormat { #define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422P16BE, YUV422P16LE) #define PIX_FMT_YUV444P16 PIX_FMT_NE(YUV444P16BE, YUV444P16LE) */ - #endif /* AVUTIL_PIXFMT_H */