From 2f10a73cbbe4333e2a41e87a94eda7fb3d442dc5 Mon Sep 17 00:00:00 2001 From: deva Date: Mon, 17 Mar 2008 09:10:42 +0000 Subject: Major code changes... FFMPEG introduced. Project splitup into subfolders. --- miavd/img_encoder.cc | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 miavd/img_encoder.cc (limited to 'miavd/img_encoder.cc') diff --git a/miavd/img_encoder.cc b/miavd/img_encoder.cc new file mode 100644 index 0000000..b326749 --- /dev/null +++ b/miavd/img_encoder.cc @@ -0,0 +1,232 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * img_encoder.cc + * + * Mon Nov 15 19:45:07 CET 2004 + * Copyright 2004 Bent Bisballe + * deva@aasimon.org + ****************************************************************************/ + +/* + * Originally from: + * RTVideoRec Realtime video recoder and encoder for Linux + * + * Copyright (C) 2004 B. Stultiens + * Copyright (C) 2004 Koen Otter and Glenn van der Meyden + */ + +/* + * This file is part of MIaV. + * + * MIaV is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MIaV is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MIaV; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "img_encoder.h" +#include + +#include +#include +#include +#include +#include + +#include + +#include "debug.h" + +extern "C" { +#include +} + +#include "jpeg_mem_dest.h" + +// Use libdv +#include +#include + +ImgEncoder::ImgEncoder(const char* cpr) +{ + // Create path and filename + char filename[256]; + string *server_root; + char birthmonth[3]; + char date[32]; + char encrypted_cpr[32]; + + // Get server root + server_root = config->readString("server_image_root"); + + // Copy the bytes representing the birth month from the cpr + // [dd][mm][yy]-[nn][nn] + strncpy(birthmonth, &cpr[2], 2); + birthmonth[2] = 0; + + // Create date (today) in [yyyy][mm][dd] + struct tm *ltime; + time_t t = time(NULL); + ltime = localtime(&t); + sprintf(date, "%.4d%.2d%.2d", + ltime->tm_year + 1900, + ltime->tm_mon, + ltime->tm_mday); + + // Create 'encrypted' cpr, reverse numbers, skip month, and subtract from 9 + // [d1][d2][m1][m2][y1][y2]-[n1][n2][n3][n4] + // => + // [9-n4][9-n3][9-n2][9-n1][9-y2][9-y1][9-d2][9-d1] + memset(encrypted_cpr, 0, sizeof(encrypted_cpr)); + int p = strlen(cpr) - 1; + int cnt = 0; + while(p) { + encrypted_cpr[cnt] = cpr[p]; + p--; + if(p == 2) p--; + if(cpr[p] == '-' || p == 3) p--; + cnt++; + } + + sprintf(filename, "%s/%s/%s/%s-%s-", server_root->c_str(), birthmonth, encrypted_cpr, cpr, date); + char extension[] = "jpg"; + + // + // Open unique file. + // + fd = -1; + int num = 0; + char buf[512]; + + while(fd == -1 && num < 999) { + sprintf(buf, "%s%.3d.%s", filename, num, extension); + + // Try to open exclusively, fails if file already exists. + fd = open(buf, O_CREAT | O_WRONLY | O_ASYNC | O_EXCL, //| O_LARGEFILE + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + if(fd == -1) { + switch(errno) { + case EEXIST: + num ++; + break; + default: + MIaV::info->error("Something is wrong with the path [%s] - %s!", filename, strerror(errno)); + return; + } + } + } + + MIaV::info->info("Writing screenshot to file: %s", buf); + +} + + +ImgEncoder::~ImgEncoder() +{ + if(fd != -1) close(fd); +} + + +void ImgEncoder::encode(Frame *dvframe, int quality) +{ + unsigned char rgb[720*576*4]; + + getRGB(dvframe, rgb); + writeJPEGFile(quality, rgb, 720, 576); +} + + +void ImgEncoder::writeJPEGFile(int quality, unsigned char *rgb, int image_width, int image_height) +{ + JSAMPLE *image_buffer = (JSAMPLE*)rgb; + + size_t buffersize = (image_width * image_height * 3) + JPEG_HEADER_PAD; + char *jpeg_output_buffer = new char [buffersize]; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + + JSAMPROW row_pointer[1]; // pointer to JSAMPLE row[s] + int row_stride; // physical row width in image buffer + + // Allocate and initialize JPEG compression object + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + + // Specify data destination (see jpeg_mem_dest) + jpeg_mem_dest(&cinfo, jpeg_output_buffer, &buffersize); + + // Set compression parameters + cinfo.image_width = image_width; // image width and height, in pixels + cinfo.image_height = image_height; + cinfo.input_components = 3; // # of color components per pixel + cinfo.in_color_space = JCS_RGB; // colorspace of input image + + jpeg_set_defaults(&cinfo); + + jpeg_set_quality(&cinfo, quality, TRUE); // limit to baseline-JPEG values + + // Start compressor + jpeg_start_compress(&cinfo, TRUE); + + // While (scan lines remain to be written) + row_stride = image_width * 3; // JSAMPLEs per row in image_buffer + + while (cinfo.next_scanline < cinfo.image_height) { + row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; + (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + + // Finish compression + jpeg_finish_compress(&cinfo); + + // Release JPEG compression object + jpeg_destroy_compress(&cinfo); + + // MIaV::info->info("JPEG buffersize: %d", buffersize); + + if(fd != -1) write(fd, jpeg_output_buffer, buffersize); + + delete jpeg_output_buffer; +} + +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); +} -- cgit v1.2.3