/*
#  $Id$
# -----------------------------------------------------------------------------
#  The part of 'VideoNEXT MediaClient SDK'
# -----------------------------------------------------------------------------
#  Author: Petrov Maxim, 03/04/2009
#  Edited by:
#  QA by:
#  Copyright: videoNEXT LLC
# -----------------------------------------------------------------------------
*/

#include "avcodec.h"                                                                                                                     
#include "swscale.h"

FILE *vnlog;
                                                                                                                                 
AVCodecContext *avCodecCtx;                                                                                                        
AVCodec *avCodec;                                                                                                                  
AVFrame *avPicture;                                                                                                                 
AVFrame *avPictureDecoded;                                                                                                          
                                                                                                                                    
struct SwsContext *swsctx;   

void av_log_our_callback(void* ptr, int level, const char* fmt, va_list vl)                                                                                     
{                                                                                                                                                                   
    static int print_prefix=1;                                                                                                                                      
    AVClass* avc= ptr ? *(AVClass**)ptr : NULL;                                                                                                                     
	
    if(print_prefix && avc) {                                                                                                                                       
        fprintf(vnlog, "[%s @ %p]", avc->item_name(ptr), ptr);                                                                                                     
    }                                                                                                                                                               
	
    print_prefix= strstr(fmt, "\n") != NULL;                                                                                                                        
	
    vfprintf(vnlog, fmt, vl);
	
	fflush(vnlog);
}           



int main()
{

    vnlog = fopen("/var/tmp/vnlog", "w");
    av_log_set_callback(av_log_our_callback);
	
    // Preparing ffmpeg
    avcodec_init();
    avcodec_register_all();
      
    avCodec = avcodec_find_decoder(CODEC_ID_MJPEG);
  	
    if (!avCodec)
    {
	    fprintf(vnlog, "Cannot initialize decoding facility (unsupported codec: %s)", "MJPEG");
		fflush(vnlog);
        return ;
    }	

    avCodecCtx = avcodec_alloc_context();
	
    avPicture         = avcodec_alloc_frame();
    avPictureDecoded  = avcodec_alloc_frame();
    if (avPictureDecoded == NULL || avPicture == NULL)
    {
        fprintf(vnlog, "Memory allocation failed: \n"); fflush(vnlog);
        return;  
    }
	
    /* open it */
    if (avcodec_open(avCodecCtx, avCodec) < 0)
    {
        char errmsg[512];
        snprintf(errmsg, sizeof(errmsg), "Cannot initialize decoding facility (failed to open decoder: %s)", "MJPEG");
        
		
		fprintf(vnlog, "%s\n", errmsg); fflush(vnlog);
		
		return 0;
    }
	
	
	unsigned char *data = calloc(128000, 1);

	if (data == 0)
	{
		fprintf(vnlog, "Memory allocation failed\n"); fflush(vnlog);
		return 0;
	}
	
	FILE *fh = fopen("/var/tmp/1.jpg", "r");
	if (fh == 0)
	{
		fprintf(vnlog, "Open file failed\n"); fflush(vnlog);
		return 0;
	}
	
	
	int len, got_picture;

	int size = fread(data, 1, 128000, fh);
	unsigned char *inbuf_ptr = data;
	
	fprintf(vnlog, "did read: %d bytes\n", size); fflush(vnlog);
	
    while (size > 0)
    {
        len = avcodec_decode_video(avCodecCtx, avPicture, &got_picture, 
                                   inbuf_ptr, size);
		
        if (len < 0)
        {
            fprintf(vnlog, "Error while decoding frame (size: %d)\n", size); fflush(vnlog);
            return 0;
        }
        else if (len > size)
        {
            len = size;
        }
        if (got_picture)
        {
			
            if (NULL == avPictureDecoded->data[0])
            {
				fprintf(vnlog, "NULL == avPictureDecoded_->data[0]\n");fflush(vnlog);

				
			

				fprintf(vnlog, "Allocating avPictureDecoded_\n");fflush(vnlog);
				if (avpicture_alloc((AVPicture *)avPictureDecoded, PIX_FMT_BGR32, avCodecCtx->width, avCodecCtx->height) != 0)
				{
				    fprintf(vnlog, "Could not allocate avPictureDecoded_\n");fflush(vnlog);
					return;
				}
					
				swsctx = sws_getContext(avCodecCtx->width,  avCodecCtx->height, avCodecCtx->pix_fmt, 
											 avCodecCtx->width, avCodecCtx->height,
											 PIX_FMT_BGR32, SWS_FAST_BILINEAR, NULL, NULL, NULL);
					
				if (swsctx == NULL)
				{
					fprintf(vnlog, "Could not allocate swctx_\n");fflush(vnlog);
					return;

				}
				
            }
			
			
	     fprintf(vnlog, "Converting to color space\n");fflush(vnlog);
								
				      
			sws_scale(swsctx, avPicture->data, avPicture->linesize, 0,  
					  avCodecCtx->height, avPictureDecoded->data, avPictureDecoded->linesize);
				
				
			if (avPictureDecoded->data[0][0] == 0 && avPictureDecoded->data[0][1] ==0 
					&& avPictureDecoded->data[0][2] == 0 && avPictureDecoded->data[0][3] == 0)
			{
			}
			else
			{
				fprintf(vnlog, "Incorrect converting!\n");fflush(vnlog);
			}
         			
			{
				FILE *fout = fopen("/var/tmp/bitmap_console", "w");
				fwrite(avPictureDecoded->data[0], avCodecCtx->width*avCodecCtx->height*4, 1, fout);
				fclose(fout);
			
				FILE *fh=fopen("/var/tmp/y_console", "w");
				fwrite(avPicture->data[0], avPicture->linesize[0]*avCodecCtx->height, 1, fh);
				fclose(fh);
				
				fh=fopen("/var/tmp/u_console", "w");                                                                                                                    
				fwrite(avPicture->data[1], avPicture->linesize[1]*avCodecCtx->height, 1, fh);                                                                                              
				fclose(fh);  
				
				fh=fopen("/var/tmp/v_console", "w");                                                                                                                    
				fwrite(avPicture->data[2], avPicture->linesize[2]*avCodecCtx->height, 1, fh);                                                                                              
				fclose(fh);  
				fprintf(vnlog, "Save success\n");fflush(vnlog);
				
				
			}
			
        }
		
        size -= len;
        inbuf_ptr += len;
    }
	

}
