From 8d535e795ef79b17394f3daeac11ed5600b36682 Mon Sep 17 00:00:00 2001
From: deva <deva>
Date: Sat, 7 May 2005 10:25:34 +0000
Subject: Removed ffmpeg code from img_encoder and corrected decoding errors in
 mov_encoder

---
 src/Makefile.am    |  6 ++--
 src/camera.cc      |  6 +++-
 src/camera.h       |  6 +++-
 src/decoder.h      |  6 +++-
 src/img_encoder.cc | 96 ++++++++++++++++++++++++------------------------------
 src/img_encoder.h  |  9 ++++-
 src/mov_encoder.cc | 77 +++++++++++++++++++++++++++++++++++--------
 src/queue.h        |  8 +++--
 8 files changed, 137 insertions(+), 77 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index b934ed1..11f5416 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,8 +4,7 @@
 AM_CXXFLAGS := $(CXXFLAGS) $(EXTRA_CXXFLAGS) -I../include $(QT_CXXFLAGS) \
 	-DQT_THREAD_SUPPORT \
 	-DPIXMAPS=\"$(datadir)/pixmaps\" \
-	-DETC=\"$(prefix)/etc/miav\" \
-	-I/usr/include/ffmpeg 
+	-DETC=\"$(prefix)/etc/miav\"
 
 bin_PROGRAMS = miav
 
@@ -64,8 +63,7 @@ EXTRA_DIST = \
 	info_gui.h \
 	info_console.h
 
-miav_LDADD := $(shell  if [ $QT_CXXFLAGS ] ; then ../tools/MocList o; fi ) \
-	-lavcodec -lavformat
+miav_LDADD := $(shell  if [ $QT_CXXFLAGS ] ; then ../tools/MocList o; fi )
 
 miav_MOC = $(shell  if [ $QT_CXXFLAGS ] ; then ../tools/MocList cc; fi )
 
diff --git a/src/camera.cc b/src/camera.cc
index 57f4a17..7bb1e79 100644
--- a/src/camera.cc
+++ b/src/camera.cc
@@ -31,6 +31,10 @@
 
 /*
  * $Log$
+ * Revision 1.15  2005/05/07 10:25:34  deva
+ *
+ * Removed ffmpeg code from img_encoder and corrected decoding errors in mov_encoder
+ *
  * Revision 1.14  2005/05/03 08:31:59  deva
  * Removed the error object, and replaced it with a more generic info object.
  *
@@ -76,7 +80,7 @@ void Camera::connect(const char *ip, const int port)
   */
   running = 1;
 
-	av_register_all();
+  //	av_register_all();
 
 	encode_queue = new Queue<Frame>(); // infinite size
 	player_queue = new Queue<Frame>(1); // fixed size of 1
diff --git a/src/camera.h b/src/camera.h
index a75acea..b1aef2e 100644
--- a/src/camera.h
+++ b/src/camera.h
@@ -31,6 +31,10 @@
 
 /*
  * $Log$
+ * Revision 1.11  2005/05/07 10:25:34  deva
+ *
+ * Removed ffmpeg code from img_encoder and corrected decoding errors in mov_encoder
+ *
  * Revision 1.10  2005/05/03 08:31:59  deva
  * Removed the error object, and replaced it with a more generic info object.
  *
@@ -55,7 +59,7 @@ using namespace std;
 #include <stdlib.h>
 #include <string.h>
 #include <getopt.h>
-#include <avformat.h>
+//#include <avformat.h>
 
 #include "util.h"
 #include "queue.h"
diff --git a/src/decoder.h b/src/decoder.h
index 68247f8..385858e 100644
--- a/src/decoder.h
+++ b/src/decoder.h
@@ -38,6 +38,10 @@
 
 /*
  * $Log$
+ * Revision 1.13  2005/05/07 10:25:34  deva
+ *
+ * Removed ffmpeg code from img_encoder and corrected decoding errors in mov_encoder
+ *
  * Revision 1.12  2005/05/03 08:31:59  deva
  * Removed the error object, and replaced it with a more generic info object.
  *
@@ -102,7 +106,7 @@ private:
   volatile bool b_record;
 
   Info *info;
-  AVCodecContext dvcodec;
+  //  AVCodecContext dvcodec;
 
   sem_t *encode_sem;
   sem_t *player_sem;
diff --git a/src/img_encoder.cc b/src/img_encoder.cc
index eeddec3..7aca367 100644
--- a/src/img_encoder.cc
+++ b/src/img_encoder.cc
@@ -39,6 +39,10 @@
 
 /*
  * $Log$
+ * Revision 1.8  2005/05/07 10:25:34  deva
+ *
+ * Removed ffmpeg code from img_encoder and corrected decoding errors in mov_encoder
+ *
  * Revision 1.7  2005/05/03 08:31:59  deva
  * Removed the error object, and replaced it with a more generic info object.
  *
@@ -48,76 +52,29 @@
 
 #include "img_encoder.h"
 #include <stdio.h>
-//#include <setjmp.h>
 
 #include "debug.h"
 
-//av_alloc_format_context
-//av_destruct_packet_nofree
+// Use libdv
+#include <libdv/dv.h>
+#include <libdv/dv_types.h>
 
 ImgEncoder::ImgEncoder()
 {
-  //////////////////// GLOBAL INIT
-	av_register_all();
-
-  //////////////////// DECODE INIT
-  AVCodec *deccodec;
-  
-  // find the dvvideo decoder
-  deccodec = avcodec_find_decoder(CODEC_ID_DVVIDEO);
-  if (!deccodec) {
-    fprintf(stderr, "codec not found\n");
-    exit(1);
-  }
-  
-  dcc= avcodec_alloc_context(); ALLOC(dcc, "img_encoder, dcc");
-  
-  // open it
-  if (avcodec_open(dcc, deccodec) < 0) {
-    fprintf(stderr, "could not open codec\n");
-    exit(1);
-  }
 }
 
 ImgEncoder::~ImgEncoder()
 {
-  // FIXME: free: deccodec and dcc
 }
 
 void ImgEncoder::encode(Frame *dvframe, 
                         char *filename, 
                         int quality)
 { 
-  int ret;
-  AVFrame *rawframe = avcodec_alloc_frame(); ALLOC(dcc, "img_encoder, rawframe");
-
-  ///////////////////////// DECODE
-  uint8_t *ptr;
-  int got_picture = 1;
-  int len;
-
-  ptr = (uint8_t *)dvframe->data;
-  len = dvframe->size;
+  unsigned char rgb[720*576*4];
 
-  ret = avcodec_decode_video(dcc, rawframe, &got_picture, ptr, len);
-
-  if(!ret) {
-    printf("Decoder fuckup!\n");
-    return;
-  }
-  
-  // TODO: Do image convertion here!
-  AVPicture pict;
-  avpicture_alloc(&pict,PIX_FMT_RGB24, 720, 576); ALLOC(dcc, "img_encoder, pict");
-
-  img_convert(&pict, PIX_FMT_RGB24, (AVPicture *)rawframe, 
-              PIX_FMT_YUV420P, 720, 576);
-  printf("converted\n");
-  writeJPEGFile(filename, quality, (JSAMPLE*)(pict.data[0]), 720, 576);
-  printf("written\n");
-
-  avpicture_free(&pict); FREE(&pict);
-  av_free(rawframe);  FREE(rawframe);
+  getRGB(dvframe, rgb);
+  writeJPEGFile(filename, quality, (JSAMPLE*)rgb, 720, 576);
 }
 ///////////////////////////////////////////////////////////////////////////////////////////
 
@@ -184,3 +141,36 @@ void ImgEncoder::writeJPEGFile(char *filename,
     // Step 7: release JPEG compression object 
     jpeg_destroy_compress(&cinfo);
 }
+
+void ImgEncoder::getRGB(Frame *frame, unsigned char *rgb)
+{
+  unsigned char *pixels[3];
+  int pitches[3];
+
+  pixels[ 0 ] = rgb;
+  pixels[ 1 ] = NULL;
+  pixels[ 2 ] = NULL;
+
+  pitches[ 0 ] = 720 * 3;
+  pitches[ 1 ] = 0;
+  pitches[ 2 ] = 0;
+  
+	dv_decoder_t *decoder = dv_decoder_new(FALSE/*this value is unused*/, FALSE, FALSE);
+  decoder->quality = DV_QUALITY_BEST;
+
+  dv_parse_header(decoder, frame->data);
+  
+  decoder->system = e_dv_system_625_50;  // PAL lines, PAL framerate
+  decoder->sampling = e_dv_sample_422;  // 4 bytes y, 2 bytes u, 2 bytes v
+  decoder->std = e_dv_std_iec_61834;
+  decoder->num_dif_seqs = 12;
+  
+  // libdv img decode to rgb
+  dv_decode_full_frame(decoder,
+                       frame->data,
+                       e_dv_color_rgb,
+                       pixels,
+                       pitches);
+  
+  dv_decoder_free(decoder);
+}
diff --git a/src/img_encoder.h b/src/img_encoder.h
index 693bba2..4ffec57 100644
--- a/src/img_encoder.h
+++ b/src/img_encoder.h
@@ -38,6 +38,10 @@
 
 /*
  * $Log$
+ * Revision 1.7  2005/05/07 10:25:34  deva
+ *
+ * Removed ffmpeg code from img_encoder and corrected decoding errors in mov_encoder
+ *
  * Revision 1.6  2005/05/03 08:31:59  deva
  * Removed the error object, and replaced it with a more generic info object.
  *
@@ -54,7 +58,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <avformat.h>
+//#include <avformat.h>
 extern "C" {
 #ifdef HAVE_STDLIB_H
 #undef HAVE_STDLIB_H
@@ -79,6 +83,8 @@ class ImgEncoder {
                      int image_height);      // Number of rows in image 
                      
  private:
+  void getRGB(Frame *frame, unsigned char *rgb);
+  /*
   // Decoder
   AVFormatContext *dfc;
   AVCodecContext *dcc;
@@ -89,6 +95,7 @@ class ImgEncoder {
   AVPacket epkt;
   unsigned char *video_buffer;
   //  AVPacket pkt;
+  */
 };
 
 #endif /*__RTVIDEOREC_IMGENCODER_H*/
diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc
index 4eae91b..bce80f7 100644
--- a/src/mov_encoder.cc
+++ b/src/mov_encoder.cc
@@ -39,6 +39,10 @@
 
 /*
  * $Log$
+ * Revision 1.13  2005/05/07 10:25:34  deva
+ *
+ * Removed ffmpeg code from img_encoder and corrected decoding errors in mov_encoder
+ *
  * Revision 1.12  2005/05/05 20:41:38  deva
  *
  * Removed the last pieces of ffmpeg... replaced it with libfame...
@@ -134,12 +138,12 @@ MovEncoder::MovEncoder(const char *filename)
 
   // frames_per_sequence is the maximum number of frames contained in a video 
   // sequence.
-  fame_par.frames_per_sequence = 25 * 60 * 60 * 2; // 25 fps in two hours.
+  fame_par.frames_per_sequence = 1024;//25 * 60 * 60 * 2; // 25 fps in two hours.
 
   // frame_rate_num/frame_rate_den specify the number of frames per second for 
   // playback.
-  fame_par.frame_rate_num = 25; // 25 / 1 fps = 25 fps
-  fame_par.frame_rate_den = 1;
+  fame_par.frame_rate_num = 10;//25; // 25 / 1 fps = 25 fps
+  fame_par.frame_rate_den = 30000;//1;
 
   // shape_quality is percentage determing the average binary shape accuracy in 
   // video with arbitrary shape.
@@ -148,7 +152,7 @@ MovEncoder::MovEncoder(const char *filename)
   // search_range specifies the motion estimation search range in pixel unit. 
   // Small search ranges work best with slow motion videos, whereas larger search 
   // ranges are rather for fast motion videos.
-  fame_par.search_range = 42; // FIXME: No idea what this should be!?
+  fame_par.search_range = 10; // FIXME: No idea what this should be!?
 
   // verbose when set to 1 outputs information on copyright, modules used and 
   // current frame on standard error.
@@ -175,18 +179,33 @@ void MovEncoder::encode(Frame *dvframe)
   encode_audio(dvframe);
 }
 
+
+#define _CLAMP(x) (unsigned char) ((x)<0?0:(((x)>255)?255:(x)))
+
+inline void rgb_to_yuv(unsigned char *rgb, unsigned char &y, unsigned char &u, unsigned char &v)
+{
+  y = _CLAMP( 0.257 * rgb[0] + 0.504 * rgb[1] + 0.098 * rgb[2] + 16);
+  v = _CLAMP( 0.439 * rgb[0] - 0.368 * rgb[1] - 0.071 * rgb[2] + 128);
+  u = _CLAMP(-0.148 * rgb[0] - 0.291 * rgb[1] + 0.439 * rgb[2] + 128);
+}
+
 void MovEncoder::encode_video(Frame *dvframe)
 {
   // Decode DV Frame to YUV
+  int w = 720;
+  int h = 576;
+  unsigned char rgb[720*576*4];
+
   unsigned char *pixels[3];
   int pitches[3];
 
-  pitches[0] = yuv.w;
-  pitches[1] = yuv.h;
-  pitches[2] = yuv.p;
-  pixels[0] = yuv.y;
-  pixels[1] = yuv.u;
-  pixels[2] = yuv.v;
+  pixels[ 0 ] = rgb;
+  pixels[ 1 ] = NULL;
+  pixels[ 2 ] = NULL;
+
+  pitches[ 0 ] = 720 * 3;
+  pitches[ 1 ] = 0;
+  pitches[ 2 ] = 0;
 
   if(!dvdecoder) {
     dvdecoder = dv_decoder_new(FALSE/*this value is unused*/, FALSE, FALSE);
@@ -203,14 +222,44 @@ void MovEncoder::encode_video(Frame *dvframe)
 
   dv_decode_full_frame(dvdecoder, 
                        dvframe->data, 
-                       e_dv_color_yuv, 
+                       e_dv_color_rgb,
                        pixels,
                        pitches);
-  
+
+  /*
+                       e_dv_color_yuv,
+                       (uint8_t**) &yuv.y, //pixels,
+                       (int*) &yuv.w);//pitches);
+  */  
+  // cvt rgb to yuv
+  for (int y=0; y<h; y+=2)
+    {
+      for (int x=0; x<w; x+=2)
+        {
+          unsigned char vy[4],vu[4],vv[4];
+          
+          rgb_to_yuv(rgb + 3*((y+0)*w + (x+0)), vy[0],vu[0],vv[0]);
+          rgb_to_yuv(rgb + 3*((y+0)*w + (x+1)), vy[1],vu[1],vv[1]);
+          rgb_to_yuv(rgb + 3*((y+1)*w + (x+0)), vy[2],vu[2],vv[2]);
+          rgb_to_yuv(rgb + 3*((y+1)*w + (x+1)), vy[3],vu[3],vv[3]);
+          // Y
+          yuv.y[(y+0)*w+(x+0)] = vy[0];
+          yuv.y[(y+0)*w+(x+1)] = vy[1];
+          yuv.y[(y+1)*w+(x+0)] = vy[2];
+          yuv.y[(y+1)*w+(x+1)] = vy[3];
+          // Cb
+          yuv.u[y*w/4+x/2] = (vu[0]+vu[1]+vu[2]+vu[3])/4;
+          // Cr
+          yuv.v[y*w/4+x/2] = (vv[0]+vv[1]+vv[2]+vv[3])/4;
+        }
+    }
+
   // Encode YUV frame and write it to disk.
   fame_start_frame(fame_context, &yuv, 0);
-  int written = fame_encode_slice(fame_context);
-  fwrite(fame_buffer, written, 1, f);
+  int written;
+  while((written = fame_encode_slice(fame_context))) {
+    fwrite(fame_buffer, written, 1, f);
+  }
   fame_end_frame(fame_context,0);
 }
 
diff --git a/src/queue.h b/src/queue.h
index 475eabf..1967c0c 100644
--- a/src/queue.h
+++ b/src/queue.h
@@ -38,6 +38,10 @@
 
 /*
  * $Log$
+ * Revision 1.14  2005/05/07 10:25:34  deva
+ *
+ * Removed ffmpeg code from img_encoder and corrected decoding errors in mov_encoder
+ *
  * Revision 1.13  2005/05/03 08:31:59  deva
  * Removed the error object, and replaced it with a more generic info object.
  *
@@ -54,8 +58,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
-#include <avformat.h>
-#include <avcodec.h>
+//#include <avformat.h>
+//#include <avcodec.h>
 
 #include "thread.h"
 #include "util.h"
-- 
cgit v1.2.3