Example #1
0
// Iterate through the DOM tree to build output data
void Document::build()
{
    //build the TOC
    unsigned int visiblePages = 0;
    for( PageIter itr = pages.begin(); itr != pages.end(); ++itr ) {
        ( *itr )->buildTOC();
        if( ( *itr )->isVisible() )
            ++visiblePages;
    }
    if( !visiblePages )
        throw FatalError( ERR_INVISIBLETOC );
    tocOffsets.reserve( pages.size() );
    dict->convert( pages.size() );  //number each page
    extfiles->convert();            //number each external file
    makeBitmaps();                  //process images
    //for each page, linearize the DOM tree it contains and build local dictionary
    std::for_each( pages.begin(), pages.end(), std::mem_fun( &Page::linearize ) );
    makeIndexes();
    std::for_each( pages.begin(), pages.end(), std::mem_fun( &Page::buildLocalDictionary ) );
    std::for_each( cells.begin(), cells.end(), std::mem_fun( &Cell::build ) );
    if( compiler.searchable() && dict->buildFTS() ) //build FTS from GlobalDictionary
        hdr->recSize = true;
}
int main(int argc, char *argv[]) {
  
  char *filename = NULL;
  char *inputsource = NULL;
  char *outputDB = NULL;
  
  //Find the last / in passed filename.
  if (strrchr(argv[1],'/') == NULL) {
    if (strcmp(argv[1],"-") == 0) {
	  inputsource = "/dev/stdin";
	  if (argv[2] == NULL) {
	    printf("Please input a name for the movie!\n");
		return -1;
	  } else {
	    if (strrchr(argv[2],'/') == NULL) {
		  filename = argv[2];
		} else {
		  filename = strrchr(argv[2],'/') + 1;
		}
		  
		if (argv[3] != NULL && argc == 4) {
	      outputDB = argv[3];
        } else {
          outputDB = "/home/skillup/videofingerprint.db";
        }
		
	  }
	} else {
	  filename = argv[1];
	  inputsource = argv[1];
	
	  if (argv[2] != NULL && argc == 3) {
        outputDB = argv[2];
      } else {
        outputDB = "/home/skillup/videofingerprint.db";
      }
	}
  } else {
	filename = strrchr(argv[1],'/') + 1;
	inputsource = argv[1];
	
	if (argv[3] != NULL && argc == 4) {
	  outputDB = argv[3];
    } else {
      outputDB = "/home/skillup/videofingerprint.db";
    }
  }
  
  printf("Filename = %s Input source = %s DB output = %s argc = %d\n",filename,inputsource,outputDB, argc);

  /*** DB initialization ***/
  int retval = 0;

  // Create a handle for database connection, create a pointer to sqlite3
  sqlite3 *handle;
  
  //Full array init of size 5h@60fps (a.k.a large enough)
  //TO FIX: use dynamic array?
  int *fullArray = (int*) calloc ( (1080000-1), sizeof (int));

  // try to create the database. If it doesnt exist, it would be created
  // pass a pointer to the pointer to sqlite3, in short sqlite3**

  retval = sqlite3_open(outputDB,&handle);
  // If connection failed, handle returns NULL
  if(retval){
	printf("Database connection failed\n");
	return -1;
  }
  
  char query1[] = "create table allmovies (allmovieskey INTEGER PRIMARY KEY,name TEXT,fps INTEGER, date INTEGER);";
  // Execute the query for creating the table
  retval = sqlite3_exec(handle,query1,0,0,0);
  char query2[] = "PRAGMA count_changes = OFF";
  retval = sqlite3_exec(handle,query2,0,0,0);
  char query3[] = "PRAGMA synchronous = OFF";
  retval = sqlite3_exec(handle,query3,0,0,0);
  
  //Hashluma table
  char query_hash[] = "create table hashluma (avg_range int, movies TEXT)";
  retval = sqlite3_exec(handle,query_hash,0,0,0);
  
  if (!retval) {
    //Populating the hash tables
	printf("Populating hashluma table\n");
    char hashquery[50];
    memset(hashquery, 0, 50);
    int i = 0;
    for(i=0; i <= 254; i++) {
	  sprintf(hashquery, "insert into hashluma (avg_range) values (%d)", i);
	  retval = sqlite3_exec(handle,hashquery,0,0,0);
    }
  }
  
  char table_query[150];
  memset(table_query, 0, 150);
  sprintf(table_query,"create table '%s' (s_end FLOAT, luma INTEGER);",filename);
  
  int repeated = 0;
  
  retval = sqlite3_exec(handle,table_query,0,0,0);
  if (retval) {
	char error [100];
	memset(error, 0, 100);
	sprintf(error,"Table for movie %s already exists! Skipping fingerprinting ... \n",filename);
	printf("%s",error);
	//Decide which is the best policy, not FP? overwrite? new file?
	repeated = 1;
	sqlite3_close(handle);
	return 0;
  }
  /*** DB init finished ***/

  printf("Analyzing video %s\n",filename);

  av_register_all();
  
  AVFormatContext *pFormatCtx;

  // Open video file
  if(av_open_input_file(&pFormatCtx, inputsource, NULL, 0, NULL)!=0) {
	printf("Could't open file %s\n", argv[1]);
    return -1; // Couldn't open file
  }
  
  // Retrieve stream information
  if(av_find_stream_info(pFormatCtx)<0) {
    printf("Could't find stream information\n");
    return -1; // Couldn't find stream information
  }

  // Dump information about file onto standard error
  dump_format(pFormatCtx, 0, filename, 0);

  int i;
  AVCodecContext *pCodecCtx;

  // Find the first video stream
  int videoStream=-1;
  for(i=0; i<pFormatCtx->nb_streams; i++)
    if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
      videoStream=i;
      break;
    }
    
  if(videoStream==-1)
    return -1; // Didn't find a video stream
  
  // Get a pointer to the codec context for the video stream
  pCodecCtx=pFormatCtx->streams[videoStream]->codec;

  AVCodec *pCodec;

  // Find the decoder for the video stream
  pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  if(pCodec==NULL) {
    fprintf(stderr, "Unsupported codec!\n");
	sqlite3_close(handle);
    return -1; // Codec not found
  }
  // Open codec
  if(avcodec_open(pCodecCtx, pCodec)<0) {
    sqlite3_close(handle);
    return -1; // Could not open codec
  }

  AVFrame *pFrame;
  AVFrame *pFrameYUV;

  // Allocate video frame
  pFrame=avcodec_alloc_frame();
  
  // Allocate an AVFrame structure
  pFrameYUV=avcodec_alloc_frame();
  if(pFrameYUV==NULL) {
    sqlite3_close(handle);
    return -1;
  }
  
  uint8_t *buffer;

  int numBytes;
  // Determine required buffer size and allocate buffer
  numBytes=avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
  buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
  
  // Assign appropriate parts of buffer to image planes in pFrameYUV
  // Note that pFrameYUV is an AVFrame, but AVFrame is a superset
  // of AVPicture
  avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
  
  // Initialize arrays to store Motion Vector information
  int *prevLuma = (int*) calloc ( (pCodecCtx->width * pCodecCtx->height), sizeof (int));
  int *modLuma = (int*) calloc ( (pCodecCtx->width * pCodecCtx->height), sizeof (int));
  
  int frameFinished = 0;
  AVPacket packet;
  av_init_packet(&packet);
  struct SwsContext * sws_context;
  double fps = 0.0;
  
  struct timeval tv;
  gettimeofday(&tv, NULL);

  char allmovies_query[150];
  memset(allmovies_query, 0, 150);
  fps = (double)pFormatCtx->streams[videoStream]->r_frame_rate.num/(double)pFormatCtx->streams[videoStream]->r_frame_rate.den;
  //if (repeated) {
  //  filename_suffix = (int)tv.tv_sec;
  //  sprintf(filename, "%s_%d", filename, filename_suffix);
  //  sprintf(allmovies_query, "insert into allmovies (name,fps,date) values ('%s',%d,%d);", filename, (int)(fps*100), filename_suffix);
  //} else {
    sprintf(allmovies_query, "insert into allmovies (name,fps,date) values ('%s',%d,%d);", filename, (int)(fps*100), (int)tv.tv_sec);
  //}
	retval = sqlite3_exec(handle,allmovies_query,0,0,0);
  
  i=0;
  while(av_read_frame(pFormatCtx, &packet)>=0) {
  // Is this a packet from the video stream?
    if(packet.stream_index==videoStream) {
    // Decode video frame
	  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
      
      // Did we get a video frame?
      if(frameFinished) {
	    //if (pCodecCtx->pix_fmt != PIX_FMT_YUV420P) {
          // Convert the image from its native format to YUV (PIX_FMT_YUV420P)
          //img_convert((AVPicture *)pFrameYUV, PIX_FMT_YUV420P, (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
		  sws_context = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, 256, 256, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);
          
		  sws_scale(sws_context, (const uint8_t * const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
          sws_freeContext(sws_context);
		  
		  retval = MVFrameImport(pFrameYUV, pCodecCtx->width, pCodecCtx->height, i++, modLuma, prevLuma);
		//} else {
		//  retval = MVFrameImport(pFrame, pCodecCtx->width, pCodecCtx->height, i++, modLuma, prevLuma);
		//}
      }
    }
  }
  
  int y,x;
  for(y=0; y<256; y++) {
    for (x=0; x<256; x++) {
	  printf("%i ", (int) modLuma[x+(y*pCodecCtx->width)]);
	  fflush(stdout);
	}
	printf("\n");
	fflush(stdout);
  }
  
  //Cut the large fullArray to the movie actual size
  int *shortArray = (int*) calloc ( i, sizeof (int));
  memcpy(shortArray, fullArray, i*sizeof(int));
  free(fullArray);
  
  //Do magic
  makeIndexes(shortArray, handle, filename, threshold, i, fps);
  
  // Free the packet that was allocated by av_read_frame
  av_free_packet(&packet);
  
  // Free the YUV image
  av_free(buffer);
  av_free(pFrameYUV);

  // Free the YUV frame
  av_free(pFrame);

  // Close the codec
  avcodec_close(pCodecCtx);

  // Close the video file
  av_close_input_file(pFormatCtx);
  
  // Close DB handler
  sqlite3_close(handle);
  
  // Free full array
  free(shortArray);
  
  // Free Motion vector arrays
  free(prevLuma);
  free(modLuma);

  return 0;
}
int main(int argc, char *argv[]) {

    char *filename = NULL;
    //char *filename_suffix = NULL;
    char *inputsource = NULL;
    char *outputDB = NULL;

    //Find the last / in passed filename.
    if (strrchr(argv[1],'/') == NULL) {
        if (strcmp(argv[1],"-") == 0) {
            inputsource = "/dev/stdin";
            if (argv[2] == NULL) {
                printf("Please input a name for the movie!\n");
                return -1;
            } else {
                if (strrchr(argv[2],'/') == NULL) {
                    filename = argv[2];
                } else {
                    filename = strrchr(argv[2],'/') + 1;
                }

                if (argv[3] != NULL && argc == 4) {
                    outputDB = argv[3];
                } else {
                    outputDB = "/home/gsc/videoaudiofingerprint.db";
                }

            }
        } else {
            filename = argv[1];
            inputsource = argv[1];

            if (argv[2] != NULL && argc == 3) {
                outputDB = argv[2];
            } else {
                outputDB = "/home/gsc/videoaudiofingerprint.db";
            }
        }
    } else {
        filename = strrchr(argv[1],'/') + 1;
        inputsource = argv[1];

        if (argv[3] != NULL && argc == 4) {
            outputDB = argv[3];
        } else {
            outputDB = "/home/gsc/videoaudiofingerprint.db";
        }
    }

    printf("Filename = %s Input source = %s DB output = %s argc = %d\n",filename,inputsource,outputDB, argc);

    /*** DB initialization ***/
    int retval = 0;

    // Create a handle for database connection, create a pointer to sqlite3
    sqlite3 *handle;

    //Full array init of size 5h@60fps (a.k.a large enough)
    //TO FIX: use dynamic array?
    int *fullArray = (int*) calloc ( (1080000-1), sizeof (int));

    // Create the database. If it doesnt exist, it would be created
    // pass a pointer to the pointer to sqlite3, in short sqlite3**

    retval = sqlite3_open(outputDB,&handle);
    // If connection failed, handle returns NULL
    if(retval) {
        printf("Database connection failed\n");
        return -1;
    }

    char query1[] = "create table allmovies (allmovieskey INTEGER PRIMARY KEY,name TEXT,fps INTEGER, date INTEGER);";
    // Execute the query for creating the table
    retval = sqlite3_exec(handle,query1,0,0,0);
    char query2[] = "PRAGMA count_changes = OFF";
    retval = sqlite3_exec(handle,query2,0,0,0);
    char query3[] = "PRAGMA synchronous = OFF";
    retval = sqlite3_exec(handle,query3,0,0,0);

    //Hashluma table
    char query_hash[] = "create table hashluma (avg_range int, movies TEXT)";
    retval = sqlite3_exec(handle,query_hash,0,0,0);

    if (!retval) {
        //Populating the hash tables
        printf("Populating hashluma table\n");
        char hashquery[50];
        memset(hashquery, 0, 50);
        int i = 0;
        for(i=0; i <= 254; i++) {
            sprintf(hashquery, "insert into hashluma (avg_range) values (%d)", i);
            retval = sqlite3_exec(handle,hashquery,0,0,0);
        }
    }

    char table_query[150];
    memset(table_query, 0, 150);
    sprintf(table_query,"create table '%s' (s_end FLOAT, luma INTEGER);",filename);

    int repeated = 0;

    retval = sqlite3_exec(handle,table_query,0,0,0);
    if (retval) {
        char error [100];
        memset(error, 0, 100);
        sprintf(error,"Table for movie %s already exists! Skipping fingerprinting ... \n",filename);
        printf("%s",error);
        //Decide which is the best policy, not FP? overwrite? new file?
        repeated = 1;
        sqlite3_close(handle);
        return 0;
    }
    /*** DB init finished ***/

    printf("Analyzing video %s\n",filename);

    av_register_all();

    AVFormatContext *pFormatCtx;

    // Open video file
    if(av_open_input_file(&pFormatCtx, inputsource, NULL, 0, NULL)!=0) {
        printf("Could't open file %s\n", argv[1]);
        return -1; // Couldn't open file
    }

    // Retrieve stream information
    if(av_find_stream_info(pFormatCtx)<0) {
        printf("Could't find stream information\n");
        return -1; // Couldn't find stream information
    }

    // Dump information about file onto standard error
    dump_format(pFormatCtx, 0, filename, 0);

    int i;
    AVCodecContext *pVideoCodecCtx;
    AVCodecContext *pAudioCodecCtx;

    // Find the first video stream
    int videoStream=-1;
    int audioStream=-1;
    for(i=0; i<pFormatCtx->nb_streams; i++) {
        if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO && videoStream==-1)
            videoStream=i;

        if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO && audioStream==-1)
            audioStream=i;

    }

    if(videoStream==-1 || audioStream==-1)
        return -1; // Didn't find both streams

    // Get a pointer to the codec context for the video stream
    pVideoCodecCtx=pFormatCtx->streams[videoStream]->codec;
    // Similar, for audio stream
    pAudioCodecCtx=pFormatCtx->streams[audioStream]->codec;

    AVCodec *pVideoCodec;
    AVCodec *pAudioCodec;

    // Find the decoder for the streams
    pVideoCodec=avcodec_find_decoder(pVideoCodecCtx->codec_id);
    pAudioCodec=avcodec_find_decoder(pAudioCodecCtx->codec_id);
    if(pVideoCodec==NULL) {
        fprintf(stderr, "Unsupported video codec!\n");
        sqlite3_close(handle);
        return -1; // Codec not found
    }
    if(pAudioCodec==NULL) {
        fprintf(stderr, "Unsupported audio codec!\n");
        sqlite3_close(handle);
        return -1; // Codec not found
    }

    // Open codecs
    if(avcodec_open(pVideoCodecCtx, pVideoCodec)<0) {
        sqlite3_close(handle);
        return -1; // Could not open codec
    }
    if(avcodec_open(pAudioCodecCtx, pAudioCodec)<0) {
        sqlite3_close(handle);
        return -1; // Could not open codec
    }

    AVFrame *pVideoFrame;
    AVFrame *pVideoFrameYUV;
    AVFrame *pAudioFrame;

    int samples = 0;

    // Allocate audio/video frame
    pVideoFrame=avcodec_alloc_frame();
    pVideoFrameYUV=avcodec_alloc_frame();
    pAudioFrame=avcodec_alloc_frame();

    if(pVideoFrameYUV==NULL || pVideoFrame==NULL || pAudioFrame==NULL) {
        sqlite3_close(handle);
        return -1;
    }

    uint8_t *videoBuffer;
    int16_t *audioBuffer;

    int numVideoBytes;
    int numAudioBytes;
    // Determine required buffer size and allocate buffer
    numVideoBytes=avpicture_get_size(PIX_FMT_YUV420P, pVideoCodecCtx->width, pVideoCodecCtx->height);
    videoBuffer=(uint8_t *)av_mallocz(numVideoBytes*sizeof(uint8_t));
    numAudioBytes = AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE;
    audioBuffer=(int16_t *)av_mallocz(numAudioBytes);

    // Assign appropriate parts of videoBuffer to image planes in pVideoFrameYUV
    // Note that pVideoFrameYUV is an AVFrame, but AVFrame is a superset of AVPicture
    avpicture_fill((AVPicture *)pVideoFrameYUV, videoBuffer, PIX_FMT_YUV420P, pVideoCodecCtx->width, pVideoCodecCtx->height);

    int frameFinished = 0;
    AVPacket packet;
    av_init_packet(&packet);
    struct SwsContext * sws_context;
    double fps = 0.0;

    struct timeval tv;
    gettimeofday(&tv, NULL);

    char allmovies_query[150];
    memset(allmovies_query, 0, 150);
    fps = (double)pFormatCtx->streams[videoStream]->r_frame_rate.num/(double)pFormatCtx->streams[videoStream]->r_frame_rate.den;
    //if (repeated) {
    //  filename_suffix = (int)tv.tv_sec;
    //  sprintf(filename, "%s_%d", filename, filename_suffix);
    //  sprintf(allmovies_query, "insert into allmovies (name,fps,date) values ('%s',%d,%d);", filename, (int)(fps*100), filename_suffix);
    //} else {
    sprintf(allmovies_query, "insert into allmovies (name,fps,date) values ('%s',%d,%d);", filename, (int)(fps*100), (int)tv.tv_sec);
    //}
    retval = sqlite3_exec(handle,allmovies_query,0,0,0);

    printf("%d %d\n",pAudioCodecCtx->sample_rate,pAudioCodecCtx->channels);

    i = 0;
    unsigned int offset = 0; // bytes
    //fftw_complex *in;
    int totalSamples = 0;
    //in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
    int counter = 0;
    float audioTime = 0.0;

    while(av_read_frame(pFormatCtx, &packet)>=0) {
        // Decode video
        if(packet.stream_index==videoStream) {
            // Decode video frame
            avcodec_decode_video2(pVideoCodecCtx, pVideoFrame, &frameFinished, &packet);

            // Did we get a video frame?
            if(frameFinished) {
                if (pVideoCodecCtx->pix_fmt != PIX_FMT_YUV420P) {
                    // Convert the image from its native format to YUV (PIX_FMT_YUV420P)
                    //img_convert((AVPicture *)pVideoFrameYUV, PIX_FMT_YUV420P, (AVPicture*)pVideoFrame, pVideoCodecCtx->pix_fmt, pVideoCodecCtx->width, pVideoCodecCtx->height);
                    sws_context = sws_getContext(pVideoCodecCtx->width, pVideoCodecCtx->height, pVideoCodecCtx->pix_fmt, pVideoCodecCtx->width, pVideoCodecCtx->height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);

                    sws_scale(sws_context, pVideoFrame->data, pVideoFrame->linesize, 0, pVideoCodecCtx->height, pVideoFrameYUV->data, pVideoFrameYUV->linesize);
                    sws_freeContext(sws_context);

                    retval = AvgFrameImport(pVideoFrameYUV, pVideoCodecCtx->width, pVideoCodecCtx->height, i++, filename, handle, fps, fullArray);
                } else {
                    retval = AvgFrameImport(pVideoFrame, pVideoCodecCtx->width, pVideoCodecCtx->height, i++, filename, handle, fps, fullArray);
                }
            }
        }
        // Decode audio
        // http://qtdvd.com/guides/ffmpeg.html#decode
        if (packet.stream_index == audioStream) {

            offset = 0;
            int frameSize;
            int length = 0;
            memset(audioBuffer, 0, sizeof(audioBuffer));
            while (packet.size > 0) {
                //memset(audioBuffer, 0, sizeof(audioBuffer));
                frameSize = numAudioBytes;

                //Copy decoded information into audioBuffer
                //frameSize gets set as the decoded frameSize, in bytes
                length = avcodec_decode_audio3(pAudioCodecCtx, audioBuffer, &frameSize, &packet);
                if (length <= 0) { // Error, see if we can recover.
                    packet.size--;
                    packet.data++;
                }
                else {
                    //Slide pointer to next frame and update size
                    printf("read %d bytes\n", length);
                    packet.size -= length;
                    packet.data += length;

                    //Slide frame of audiobuffer
                    memcpy((uint16_t*)(audioBuffer+offset), audioBuffer, frameSize);
                    //Update offset
                    offset += frameSize;
                }

                //Do something with audioBuffer
                //in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
                //if (counter%2)
                //	printf("%f R: %d\n", audioTime, (int16_t)*audioBuffer);
                //else
                //	printf("%f L: %d\n", audioTime, (int16_t)*audioBuffer);
                printf("%f %d\n", audioTime, (int16_t)*audioBuffer);
                fflush(stdout);

            }


            if (offset == 0)
                samples = 0;
            else
                samples = (unsigned int)offset/sizeof(short);

            totalSamples+=samples;

            if (counter%2)
                audioTime+=samples*1.0/pAudioCodecCtx->sample_rate;

            counter++;

        }
    }

    printf("Total time (s) (per audio sample calculation): %f\n",(float)(totalSamples*1.0/pAudioCodecCtx->sample_rate/pAudioCodecCtx->channels));

    //Cut the large fullArray to the movie actual size
    int *shortArray = (int*) calloc ( i, sizeof (int));
    memcpy(shortArray, fullArray, i*sizeof(int));
    free(fullArray);

    //Do magic
    makeIndexes(shortArray, handle, filename, threshold, i, fps);

    // Free the packet that was allocated by av_read_frame
    av_free_packet(&packet);

    // Free the YUV image
    av_free(videoBuffer);
    av_free(audioBuffer);
    av_free(pVideoFrameYUV);

    // Free the YUV frame
    av_free(pVideoFrame);
    av_free(pAudioFrame);

    // Close the codec
    avcodec_close(pVideoCodecCtx);
    avcodec_close(pAudioCodecCtx);

    // Close the video file
    av_close_input_file(pFormatCtx);

    // Close DB handler
    sqlite3_close(handle);

    // Free full array
    free(shortArray);

    return 0;
}