Example #1
0
int
film::process ()
{
  int audioSize;
  uint8_t *buffer;
  uint8_t *buffer2;
  int frameFinished;
  int numBytes;
  shot s;
  static struct SwsContext *img_convert_ctx = NULL;

  create_main_dir ();

  string graphpath = this->global_path + "/";
  g = new graph (600, 400, graphpath, threshold, this);
  g->set_title ("Motion quantity");

  /*
   * Register all formats and codecs 
   */
  av_register_all ();

  if (av_open_input_file (&pFormatCtx, input_path.c_str (), NULL, 0, NULL) != 0)
    {
      string error_msg = "Impossible to open file";
      error_msg += input_path;
      shotlog (error_msg);
      return -1;		// Couldn't open file
    }

  /*
   * Retrieve stream information 
   */
  if (av_find_stream_info (pFormatCtx) < 0)
    return -1;			// Couldn't find stream information


  // dump_format (pFormatCtx, 0, path.c_str (), false);
  videoStream = -1;
  audioStream = -1;


  /*
   * Detect streams types 
   */
  for (int j = 0; j < pFormatCtx->nb_streams; j++)
    {
      switch (pFormatCtx->streams[j]->codec->codec_type)
	{
	case AVMEDIA_TYPE_VIDEO:
	  videoStream = j;
	  break;

	case AVMEDIA_TYPE_AUDIO:
	  audioStream = j;
	  break;

	default:
	  break;
	}
    }



  /*
   * Get a pointer to the codec context for the video stream 
   */
  if (audioStream != -1)
    {
          if (audio_set)
    {
      string xml_audio = graphpath + "/" + "audio.xml";
      init_xml (xml_audio);
    }

      pCodecCtxAudio = pFormatCtx->streams[audioStream]->codec;
      pCodecAudio = avcodec_find_decoder (pCodecCtxAudio->codec_id);

      if (pCodecAudio == NULL)
	return -1;		// Codec not found
      if (avcodec_open (pCodecCtxAudio, pCodecAudio) < 0)
	return -1;		// Could not open codec

    }
  update_metadata ();
  /*
   * Find the decoder for the video stream 
   */
  if (videoStream != -1)
    {
      pCodecCtx = pFormatCtx->streams[videoStream]->codec;
      pCodec = avcodec_find_decoder (pCodecCtx->codec_id);

      if (pCodec == NULL)
	return -1;		// Codec not found
      if (avcodec_open (pCodecCtx, pCodec) < 0)
	return -1;		// Could not open codec

      /*
       * Allocate video frame 
       */
      pFrame = avcodec_alloc_frame ();
      pFrameRGB = avcodec_alloc_frame ();
      pFrameRGBprev = avcodec_alloc_frame ();

      /*
       * Determine required buffer size and allocate buffer 
       */
      numBytes = avpicture_get_size (PIX_FMT_RGB24, width, height);

      buffer = (uint8_t *) malloc (sizeof (uint8_t) * numBytes);
      buffer2 = (uint8_t *) malloc (sizeof (uint8_t) * numBytes);

      /*
       * Assign appropriate parts of buffer to image planes in pFrameRGB 
       */
      avpicture_fill ((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGB24, width, height);

      avpicture_fill ((AVPicture *) pFrameRGBprev, buffer2, PIX_FMT_RGB24, width, height);


      /*
       * Mise en place du premier plan 
       */
      s.fbegin = 0;
      s.msbegin = 0;
      s.myid = 0;
      shots.push_back (s);



    }


  checknumber = (samplerate * samplearg) / 1000;

  /*
   * Boucle de traitement principale du flux 
   */
  this->frame_number = 0;
  while (av_read_frame (pFormatCtx, &packet) >= 0)
    {
      if (packet.stream_index == videoStream)
	{
          AVPacket pkt;
          av_init_packet (&pkt);
          pkt.data = packet.data;
          pkt.size = packet.size;
          avcodec_decode_video2 (pCodecCtx, pFrame, &frameFinished, &pkt);

        if (frameFinished)
	    {
	      // Convert the image into RGB24
	      if (! img_convert_ctx)
		{
		  img_convert_ctx = sws_getContext(width, height, pCodecCtx->pix_fmt,
						   width, height, PIX_FMT_RGB24, SWS_BICUBIC, 
						   NULL, NULL, NULL);
		  if (! img_convert_ctx) 
		  {
		    fprintf(stderr, "Cannot initialize the conversion context!\n");
		    exit(1);
		  }
		}
	      
	      /* API: int sws_scale(SwsContext *c, uint8_t *src, int srcStride[], int srcSliceY, int srcSliceH, uint8_t dst[], int dstStride[] )
	       */
	      sws_scale(img_convert_ctx, pFrame->data, 
			pFrame->linesize, 0, 
			pCodecCtx->height,
			pFrameRGB->data, pFrameRGB->linesize);

	      /*
		Old API doc (cf http://www.dranger.com/ffmpeg/functions.html )
		int img_convert(AVPicture *dst, int dst_pix_fmt,
		                const AVPicture *src, int src_pix_fmt,
				int src_width, int src_height)
	      */
	      /*
	      img_convert ((AVPicture *) pFrameRGB, PIX_FMT_RGB24, (AVPicture *) pFrame, pCodecCtx->pix_fmt, width, height);
	      */

            this->frame_number ++;
	      /* Si ce n'est pas la permiere image */
        if ( this->frame_number  > 2)
		{
		  CompareFrame (pFrameRGB, pFrameRGBprev);
		}
	      else
		{
		  /*
		   * Cas ou c'est la premiere image, on cree la premiere image dans tous les cas 
		   */
		  image *begin_i = new image (this, width, height, s.myid, BEGIN);
		  begin_i->create_img_dir ();
		  begin_i->SaveFrame (pFrameRGB);
		  shots.back ().img_begin = begin_i;
		}
	     memcpy (buffer2, buffer, numBytes);
	    }
	}
      if (audio_set && (packet.stream_index == audioStream))
	{
	  process_audio ();
	}
      /*
       * Free the packet that was allocated by av_read_frame 
       */
      if (packet.data != NULL)
	av_free_packet (&packet);
    }

  if (videoStream != -1)
    {
      /* Mise en place de la dernière image */
      int lastFrame = this->frame_number;
      shots.back ().fduration = lastFrame - shots.back ().fbegin;
      shots.back ().msduration = int (((shots.back ().fduration) * 1000) / fps);
      duration.mstotal = int (shots.back ().msduration + shots.back ().msbegin);
	  image *end_i = new image (this, width, height, shots.back ().myid, END);
	  end_i->SaveFrame (pFrameRGB);
	  shots.back ().img_end = end_i;

      /*
       * Graphe de la qté de mvmt 
       */
      g->init_gd ();
      g->draw_all_canvas ();
      g->draw_color_datas ();
      g->draw_datas ();
      if (video_set)
	{
	  string xml_color = graphpath + "/" + "video.xml";
	  g->write_xml (xml_color);
	}
      g->save ();

      /*
       * Free the RGB images 
       */
      free (buffer);
      free (buffer2);
      av_free (pFrameRGB);
      av_free (pFrame);
      av_free (pFrameRGBprev);
      avcodec_close (pCodecCtx);
    }
  /*
   * Close the codec 
   */
  if (audioStream != -1)
    {
        /* Fermetrure du fichier xml */
      if (audio_set) close_xml ();
      avcodec_close (pCodecCtxAudio);
    }

  /*
   * Close the video file 
   */
  av_close_input_file (pFormatCtx);


}
BOOST_DATA_TEST_CASE(vcm_encdec, make_data_from_tuple_container(vecEncDecClips), src, dst, fmt, config, tolerance)
{
	VideoClip srcClip(src);
	VideoClip dstClip(dst);
	DWORD fccCodec = FCC(fmt);

	BOOST_REQUIRE(srcClip.GetWidth() == dstClip.GetWidth());
	BOOST_REQUIRE(srcClip.GetHeight() == dstClip.GetHeight());

	DWORD fccSrc = srcClip.GetFourCC();
	DWORD fccDst = dstClip.GetFourCC();
	unsigned int nWidth = srcClip.GetWidth();
	unsigned int nHeight = srcClip.GetHeight();

	size_t cbSrcData;
	size_t cbDstData;
	size_t cbCompressedData;

	HIC hicEncode, hicDecode;
	LRESULT lr;
	union
	{
		BITMAPINFOHEADER bihCompressed;
		char bihCompressedBuf[128];
	};
	BITMAPINFOHEADER bihSrc;
	BITMAPINFOHEADER bihDst;

	hicEncode = ICOpen(ICTYPE_VIDEO, fccCodec, ICMODE_COMPRESS);
	BOOST_REQUIRE(hicEncode != NULL);
	ICCloser iccloserEnc(hicEncode);

	lr = ICSetState(hicEncode, &config.front(), config.size());
	BOOST_REQUIRE(lr == config.size());

	hicDecode = ICOpen(ICTYPE_VIDEO, fccCodec, ICMODE_DECOMPRESS);
	BOOST_REQUIRE(hicDecode != NULL);
	ICCloser iccloserDec(hicDecode);

	memset(&bihSrc, 0, sizeof(BITMAPINFOHEADER));
	bihSrc.biSize = sizeof(BITMAPINFOHEADER);
	bihSrc.biWidth = nWidth;
	bihSrc.biHeight = nHeight;
	bihSrc.biPlanes = 1;
	bihSrc.biBitCount = FCC2BitCount(fccSrc);
	bihSrc.biCompression = FCC2Compression(fccSrc);
	bihSrc.biSizeImage = 10000000;

	memset(&bihDst, 0, sizeof(BITMAPINFOHEADER));
	bihDst.biSize = sizeof(BITMAPINFOHEADER);
	bihDst.biWidth = nWidth;
	bihDst.biHeight = nHeight;
	bihDst.biPlanes = 1;
	bihDst.biBitCount = FCC2BitCount(fccDst);
	bihDst.biCompression = FCC2Compression(fccDst);
	bihDst.biSizeImage = 10000000;

	lr = ICCompressGetFormat(hicEncode, &bihSrc, &bihCompressed);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);
	cbCompressedData = ICCompressGetSize(hicEncode, &bihSrc, &bihCompressed);

	lr = ICCompressBegin(hicEncode, &bihSrc, &bihCompressed);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);

	lr = ICDecompressBegin(hicDecode, &bihCompressed, &bihDst);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);

	void *pSrcData;
	void *pDstData;
	void *pEncoderOut = malloc(cbCompressedData);
	void *pDecoderOut = NULL;
	int retSrc, retDst;
	LONG lFrameNum = 0;
	while ((retSrc = srcClip.GetNextFrame(&pSrcData, &cbSrcData, NULL)) == 0 &&
		(retDst = dstClip.GetNextFrame(&pDstData, &cbDstData, NULL) == 0))
	{
		DWORD dwFlags = 0;
		lr = ICCompress(hicEncode, 0, &bihCompressed, pEncoderOut, &bihSrc, pSrcData, NULL, &dwFlags, lFrameNum++, 0, 0, &bihSrc, NULL);
		BOOST_REQUIRE(lr == ICERR_OK);

		if (pDecoderOut == NULL)
			pDecoderOut = malloc(cbDstData);

		lr = ICDecompress(hicDecode, (dwFlags & AVIIF_KEYFRAME) ? 0 : ICDECOMPRESS_NOTKEYFRAME, &bihCompressed, pEncoderOut, &bihDst, pDecoderOut);
		BOOST_REQUIRE(lr == ICERR_OK);

		BOOST_CHECK(bihDst.biSizeImage == cbDstData);
		BOOST_CHECK(CompareFrame(pDstData, pDecoderOut, nWidth, cbDstData, fccDst, tolerance) == 0);
	}

	BOOST_CHECK(retSrc != 0 && retDst != 0);
	if (pDecoderOut != NULL)
		free(pDecoderOut);
	free(pEncoderOut);

	lr = ICDecompressEnd(hicDecode);
	BOOST_CHECK(lr == ICERR_OK);

	lr = ICCompressEnd(hicEncode);
	BOOST_CHECK(lr == ICERR_OK);
}