summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2005-05-05 20:41:38 +0000
committerdeva <deva>2005-05-05 20:41:38 +0000
commit19bc99be32db5a65c1596ee8beb49a2b3c0d5abd (patch)
treec20099c11bd22f5a1651a33ce938b17476bb8f5f
parent099291cc4cc648c1938a7245d9abccbc6738a46d (diff)
Removed the last pieces of ffmpeg... replaced it with libfame...
Not quite working yet, but all the major code is in place!
-rw-r--r--TODO3
-rw-r--r--configure.in10
-rw-r--r--etc/miav.conf2
-rw-r--r--src/mov_encoder.cc423
-rw-r--r--src/mov_encoder.h34
5 files changed, 172 insertions, 300 deletions
diff --git a/TODO b/TODO
index 00ab3f2..a55bfab 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,6 @@
+// This is how it's done!
+http://lists.debian.org/debian-user-spanish/2005/01/msg00380.html
+
==========================================================================
TASKS (client)
diff --git a/configure.in b/configure.in
index 1d48f84..4a4b171 100644
--- a/configure.in
+++ b/configure.in
@@ -43,8 +43,14 @@ fi
dnl ======================
dnl Check for Jpeg library
dnl ======================
-AC_CHECK_HEADER(jpeglib.h, , AC_MSG_ERROR([*** LibJpeg not found!]))
-AC_CHECK_LIB(jpeg, jpeg_start_compress, , AC_MSG_ERROR([*** LibJpeg not found!]))
+AC_CHECK_HEADER(jpeglib.h, , AC_MSG_ERROR([*** libJpeg not found!]))
+AC_CHECK_LIB(jpeg, jpeg_start_compress, , AC_MSG_ERROR([*** libJpeg not found!]))
+
+dnl ======================
+dnl Check for Fame library
+dnl ======================
+AC_CHECK_HEADER(fame.h, , AC_MSG_ERROR([*** libFame include files not found!]))
+AC_CHECK_LIB(fame, fame_init, , AC_MSG_ERROR([*** libFame not found!]))
AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
diff --git a/etc/miav.conf b/etc/miav.conf
index 5e8843f..240d2a0 100644
--- a/etc/miav.conf
+++ b/etc/miav.conf
@@ -17,7 +17,7 @@ pixel_width = 1024
pixel_height = 768
# How and where to connect to the miav server?
-server_addr = "192.168.0.10"
+server_addr = "127.0.0.1"
server_port = 30000
# Where top store the files recieved by the server
diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc
index 917cd32..4eae91b 100644
--- a/src/mov_encoder.cc
+++ b/src/mov_encoder.cc
@@ -39,6 +39,11 @@
/*
* $Log$
+ * Revision 1.12 2005/05/05 20:41:38 deva
+ *
+ * Removed the last pieces of ffmpeg... replaced it with libfame...
+ * Not quite working yet, but all the major code is in place!
+ *
* Revision 1.11 2005/05/03 17:12:53 deva
* Fixed a bug (forgot to set the frametime).
*
@@ -60,310 +65,156 @@
MovEncoder::MovEncoder(const char *filename)
{
- //////////////////// GLOBAL INIT
- av_register_all();
-
- //////////////////// ENCODE INIT
- AVStream *st;
- AVCodec *enc_codec;
-
- if(!(efc = av_alloc_format_context())) {
- fprintf(stderr, "Could not alloc output format context\n"); fflush(stderr);
- exit(1);
- }
-
- // efc->oformat = guess_format("avi", NULL, NULL);
- efc->oformat = guess_format("mpeg", NULL, NULL);
- //efc->oformat = guess_format(NULL, filename, NULL);
-
- if(!(st = av_new_stream(efc, 0))) {
- fprintf(stderr, "Could not alloc stream\n"); fflush(stderr);
- switch((int)st) {
- case AVERROR_UNKNOWN : fprintf(stderr, "unknown error\n"); fflush(stderr);
- break;
- case AVERROR_IO : fprintf(stderr, "i/o error\n"); fflush(stderr);
- break;
- case AVERROR_NUMEXPECTED : fprintf(stderr, "number syntax expected in filename\n"); fflush(stderr);
- break;
- case AVERROR_INVALIDDATA : fprintf(stderr, "invalid data found\n"); fflush(stderr);
- break;
- case AVERROR_NOMEM : fprintf(stderr, "not enough memory\n"); fflush(stderr);
- break;
- case AVERROR_NOFMT : fprintf(stderr, "unknown format\n"); fflush(stderr);
- break;
- case AVERROR_NOTSUPP : fprintf(stderr, "operation not supported\n"); fflush(stderr);
- break;
- }
- exit(1);
- }
-
- //enc_codec = avcodec_find_encoder(CODEC_ID_MPEG4);
- enc_codec = avcodec_find_encoder(CODEC_ID_MPEG2VIDEO);
- if(!enc_codec) {
- fprintf(stderr, "Unsupported codec for output stream\n"); fflush(stderr);
- exit(1);
- }
- avcodec_get_context_defaults(&st->codec);
- ecc = &st->codec;
- //ecc->codec_id = CODEC_ID_MPEG4;
- ecc->codec_id = CODEC_ID_MPEG2VIDEO;
- ecc->bit_rate = 8192*1000;
- //ecc->bit_rate = 4096*1000;
- ecc->bit_rate_tolerance = 8000*1000;
- ecc->frame_rate = 25;
- ecc->frame_rate_base = 1;
-
- ecc->width = 720;
- ecc->height = 576;
- ecc->pix_fmt = PIX_FMT_YUV420P;
- ecc->gop_size = 0;
- ecc->mb_decision = FF_MB_DECISION_SIMPLE;
- ecc->qmin = 2;
- ecc->qmax = 31;
- ecc->mb_qmin = 2;
- ecc->mb_qmax = 31;
- ecc->max_qdiff = 3;
- ecc->qblur = 0.5;
- ecc->qcompress = 0.5;
- ecc->rc_eq = "tex^qComp";
- ecc->debug= 0;
-
- ecc->rc_override_count=0;
- ecc->rc_max_rate = 0;
- ecc->rc_min_rate = 0;
- ecc->rc_buffer_size = 0;
- ecc->rc_buffer_aggressivity = 1.0;
- ecc->rc_initial_cplx= 0;
- ecc->i_quant_factor = -0.8;
- ecc->b_quant_factor = 1.25;
- ecc->i_quant_offset = 0.8;
- ecc->b_quant_offset = 1.25;
- ecc->dct_algo = 0;
- ecc->idct_algo = 0;
- ecc->strict_std_compliance = 0;
- ecc->me_method = ME_EPZS;
-
- if(avcodec_open(&st->codec, enc_codec) < 0) {
- fprintf(stderr, "Error while opening codec for stream\n"); fflush(stderr);
- exit(1);
- }
-
- if(url_fopen(&efc->pb, filename, URL_RDWR) < 0) {
- fprintf(stderr, "Could not open '%s'\n", filename); fflush(stderr);
- exit(1);
- }
-
- if(av_set_parameters(efc, NULL) < 0) {
- fprintf(stderr, "%s: Invalid encoding parameters\n", filename); fflush(stderr);
- exit(1);
- }
-
- dump_format(efc, 0, filename, 1);
-
- if(av_write_header(efc) < 0) {
- fprintf(stderr, "Could not write header for output file \n"); fflush(stderr);
- exit(1);
- }
-
- video_buffer = (unsigned char *)av_malloc(VIDEO_BUFFER_SIZE);
-
- av_init_packet(&epkt);
-
- epkt.stream_index = efc->streams[0]->index;
-
- // ecc = &efc->streams[0]->codec;
-
- //////////////////// DECODE INIT
- AVCodec *deccodec;
- // AVCodecContext *dcc= NULL;
- fprintf(stderr, "Video decoding\n");
-
- // find the dvvideo decoder
- deccodec = avcodec_find_decoder(CODEC_ID_DVVIDEO);
- if (!deccodec) {
- fprintf(stderr, "codec not found\n"); fflush(stderr);
- exit(1);
- }
-
- dcc= avcodec_alloc_context();
+ // FIXME: Hmmm... should this be detected somewhere?!
+ static int w = 720;
+ static int h = 576;
+
+ // Initialize yuv strucutre.
+ yuv.w = w;
+ yuv.h = h;
+ yuv.p = w;
+ yuv.y = new unsigned char [w*h];
+ yuv.u = new unsigned char [w*h/4];
+ yuv.v = new unsigned char [w*h/4];
+
+ ////////////LIBDV STUFF///////////////
- // open it
- if (avcodec_open(dcc, deccodec) < 0) {
- fprintf(stderr, "could not open codec\n"); fflush(stderr);
- exit(1);
- }
+ dvdecoder = NULL; // Initialize in encode method
+
+ /////////LIBFAME STUFF///////////
+
+ // Allocate the output buffer.
+ fame_buffer = new unsigned char [FAME_BUFFER_SIZE];
+
+ // Open output file
+ f=fopen(filename, "wb");
+ // FIXME: check f == NULL
+
+ // Open a new session of the fame library.
+ fame_context = fame_open();
+ // FIXME: check fame_context == NULL
+ // (If initialization was successful, it returns a non-null context which
+ // can then be used for subsequent library calls.)
+
+ /*
+ typedef struct _fame_parameters_ {
+ int width; // width of the video sequence
+ int height; // height of the video sequence
+ char const *coding; // coding sequence
+ int quality; // video quality
+ int slices_per_frame; // number of slices per frame
+ unsigned int frames_per_sequence; // number of frames per sequence
+ int frame_rate_num; // numerator of frames per second
+ int frame_rate_den; // denominator of frames per second
+ unsigned int shape_quality; // binary shape quality
+ unsigned int search_range; // motion estimation search range
+ unsigned char verbose; // verbosity
+ } fame_parameters_t;
+ */
+ // width and height specify the size of each frames of the video sequence.
+ // Both must be multiple of 16. width and height must be less than 4096x4096
+ fame_par.width = 720;
+ fame_par.height = 576;
+
+ // coding is a string of I, P or B characters representing the sequence of
+ // frames the encoder must produce. I frames are intra-coded frames (similar
+ // to JPEG), whereas P and B frames are motion compressed, respectively
+ // predicted from past reference (I or P) frame, or bidirectionally predicted
+ // from past and future reference frame.
+ static const char coding[] = "I\0";
+ fame_par.coding = coding;
+
+ // quality is a percentage, which controls compression versus quality.
+ fame_par.quality = 100;
+
+ // slices_per_frame is the number of frame slices per frame. More slices provide
+ // better error recovery. There must be at least one slice per frame, and at most
+ // height / 16
+ fame_par.slices_per_frame = fame_par.height / 16;
+
+ // 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.
+
+ // 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;
+
+ // shape_quality is percentage determing the average binary shape accuracy in
+ // video with arbitrary shape.
+ fame_par.shape_quality = 100;
+
+ // 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!?
+
+ // verbose when set to 1 outputs information on copyright, modules used and
+ // current frame on standard error.
+ fame_par.verbose = 0;
+
+ fame_init(fame_context, &fame_par, fame_buffer, FAME_BUFFER_SIZE);
+ // FIXME: fame_init return a new context, or NULL if an error occurred.
}
MovEncoder::~MovEncoder()
{
- av_free(video_buffer); FREE(video_buffer);
- url_fclose(&efc->pb);
+ int written = fame_close(fame_context);
+ fwrite(fame_buffer, written, 1, f);
+ fclose(f);
+ delete [] fame_buffer;
+ delete [] yuv.y;
+ delete [] yuv.u;
+ delete [] yuv.v;
}
void MovEncoder::encode(Frame *dvframe)
{
encode_video(dvframe);
- // encode_audio(dvframe);
+ encode_audio(dvframe);
}
-#define WOW(x) fprintf(stderr, x); fflush(stderr);
-
void MovEncoder::encode_video(Frame *dvframe)
{
- int ret;
- AVFrame *rawframe = avcodec_alloc_frame();
- static int64_t timestamp = 0LL;
- int got_picture = 1;
-
- // uint8_t *ptr;
- // int len;
-
- // ptr = (uint8_t *)dvframe->data;
- // len = dvframe->size;
-
- ///////////////////////// DECODE VIDEO
-
- // ret = avcodec_decode_video(dcc, rawframe, &got_picture, ptr, len);
- ret = avcodec_decode_video(dcc, rawframe, &got_picture, dvframe->data, dvframe->size);
- rawframe->pts = timestamp;
- timestamp += 40000;
- fprintf(stderr, "ret fra decode: %d\n", ret); fflush(stderr);
-
- if(ret <= 0) {
- fprintf(stderr, "Decoder fuckup during video decoding!\n"); fflush(stderr);
- return;
- }
- ///////////////////////// ENCODE VIDEO
-
- ret = avcodec_encode_video(ecc, video_buffer, VIDEO_BUFFER_SIZE, rawframe);
-
- if(ret <= 0) {
- fprintf(stderr, "MovEncoder fuckup during video encoding!\n"); fflush(stderr);
- return;
+ // Decode DV Frame to YUV
+ 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;
+
+ if(!dvdecoder) {
+ dvdecoder = dv_decoder_new(FALSE/*this value is unused*/, FALSE, FALSE);
+ dvdecoder->quality = DV_QUALITY_BEST;
+
+ dv_parse_header(dvdecoder, dvframe->data);
+ //dv_parse_packs(decoder, frame->data); // Not needed anyway!
+
+ dvdecoder->system = e_dv_system_625_50; // PAL lines, PAL framerate
+ dvdecoder->sampling = e_dv_sample_422; // 4 bytes y, 2 bytes u, 2 bytes v
+ dvdecoder->std = e_dv_std_iec_61834;
+ dvdecoder->num_dif_seqs = 12;
}
- epkt.data = video_buffer;
- epkt.size = ret;
- if(ecc->coded_frame) epkt.pts = ecc->coded_frame->pts;
- if(ecc->coded_frame && ecc->coded_frame->key_frame) epkt.flags |= PKT_FLAG_KEY;
-
- av_write_frame(efc, &epkt);
- av_free(rawframe);
+ dv_decode_full_frame(dvdecoder,
+ dvframe->data,
+ e_dv_color_yuv,
+ pixels,
+ pitches);
+
+ // 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);
+ fame_end_frame(fame_context,0);
}
-#define INBUF_SIZE 48000
void MovEncoder::encode_audio(Frame *dvframe)
{
- uint8_t *decbuf;
-
- ///////////////////////// DECODE AUDIO
- {
- AVCodec *codec;
- AVCodecContext *c= NULL;
- int out_size, size, len;
- uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
-
- printf("Audio decoding\n");
-
- /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
- memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-
- /* find the mpeg audio decoder */
- codec = avcodec_find_decoder(CODEC_ID_DVAUDIO);
- if (!codec) {
- fprintf(stderr, "codec not found\n");
- exit(1);
- }
-
- c= avcodec_alloc_context();
-
- /* open it */
- if (avcodec_open(c, codec) < 0) {
- fprintf(stderr, "could not open codec\n");
- exit(1);
- }
-
- decbuf = (uint8_t*)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
-
-
- /* decode until eof */
- size = dvframe->size;
- inbuf_ptr = dvframe->data;
-
- while (size > 0) {
- len = avcodec_decode_audio(c, (short *)decbuf, &out_size,
- inbuf_ptr, size);
- if (len < 0) {
- fprintf(stderr, "Error while decoding\n");
- exit(1);
- }
- if (out_size > 0) {
- /* if a frame has been decoded, output it */
- }
- size -= len;
- inbuf_ptr += len;
- }
-
- avcodec_close(c);
- av_free(c);
- }
- ///////////////////////// ENCODE AUDIO
- {
- char filename[]="audio.mp2";
- AVCodec *codec;
- AVCodecContext *c= NULL;
- int frame_size, i, j, out_size, outbuf_size;
- FILE *f;
- short *samples;
- float t, tincr;
- uint8_t *outbuf;
-
- printf("Audio encoding\n");
-
- /* find the MP2 encoder */
- codec = avcodec_find_encoder(CODEC_ID_MP2);
- if (!codec) {
- fprintf(stderr, "codec not found\n");
- exit(1);
- }
-
- c= avcodec_alloc_context();
-
- /* put sample parameters */
- c->bit_rate = 64000;
- c->sample_rate = 44100;
- c->channels = 2;
-
- /* open it */
- if (avcodec_open(c, codec) < 0) {
- fprintf(stderr, "could not open codec\n");
- exit(1);
- }
-
- /* the codec gives us the frame size, in samples */
- frame_size = c->frame_size;
- samples = (short int*)malloc(frame_size * 2 * c->channels);
- outbuf_size = 10000;
- outbuf = (uint8_t*)malloc(outbuf_size);
-
- f = fopen(filename, "a");
- if (!f) {
- fprintf(stderr, "could not open %s\n", filename);
- exit(1);
- }
-
- // encode the sample
- out_size = avcodec_encode_audio(c, outbuf, outbuf_size, (const short int*)decbuf);
- fwrite(outbuf, 1, out_size, f);
-
- fclose(f);
- free(outbuf);
- free(samples);
-
- avcodec_close(c);
- av_free(c);
- }
-
- // Don't free outputbuffer until this point!
- free(decbuf);
+ // TODO: Do some audio stuff here sometime!
}
diff --git a/src/mov_encoder.h b/src/mov_encoder.h
index 2e3eca3..17412a2 100644
--- a/src/mov_encoder.h
+++ b/src/mov_encoder.h
@@ -36,6 +36,11 @@
/*
* $Log$
+ * Revision 1.6 2005/05/05 20:41:38 deva
+ *
+ * Removed the last pieces of ffmpeg... replaced it with libfame...
+ * Not quite working yet, but all the major code is in place!
+ *
* Revision 1.5 2005/05/03 08:31:59 deva
* Removed the error object, and replaced it with a more generic info object.
*
@@ -49,13 +54,20 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <avformat.h>
+
+// Use libfame
+#include <fame.h>
+
+// Use libdv
+#include <libdv/dv.h>
+#include <libdv/dv_types.h>
#include "frame.h"
#include "util.h"
-#define VIDEO_BUFFER_SIZE (1024*1024) // FIXME: One size fits all...
+// size specifies the length of the buffer.
+#define FAME_BUFFER_SIZE (2*1024*1024) // FIXME: One size fits all...
class MovEncoder {
public:
@@ -67,16 +79,16 @@ class MovEncoder {
void encode_video(Frame *frame);
void encode_audio(Frame *frame);
- // Decoder
- AVFormatContext *dfc;
- AVCodecContext *dcc;
+ // buffer is the buffer where encoded data will be written to. It must be large
+ // enough to contain a few frames.
+ unsigned char *fame_buffer;
+ fame_parameters_t fame_par;
+ fame_context_t *fame_context;
+ fame_yuv_t yuv;
+ FILE *f;
- // Encoder
- AVFormatContext *efc;
- AVCodecContext *ecc;
- AVPacket epkt;
- unsigned char *video_buffer;
- // AVPacket pkt;
+ // libdv decoder
+ dv_decoder_t *dvdecoder;
};
#endif