#2451 Le 04/09/2010, à 08:45
- cm-t
Re : /* Topic des codeurs couche-tard [1] */
pas de 'Bobot
Actu Ubuntu ☺/
Pauses Ubuntu sur Paris \_< -t
[(π)] La Quadrature du net
Hors ligne
#2452 Le 04/09/2010, à 08:49
- helly
Re : /* Topic des codeurs couche-tard [1] */
On respire de nouveau ^^.
Prochaine étape : la gogole !
edit : .
Dernière modification par helly (Le 04/09/2010, à 22:37)
Archlinux-wmii-dwb.
Un problème résolu ? Faites le savoir en mettant [résolu] à côté du titre de votre topic.
Un problème non résolu ? Faites le savoir en insultant ceux qui cherchent à vous aider.
Un site bleu super remasterised©, un wiki cherchant des volontaires pour traduire un site.
Hors ligne
#2453 Le 04/09/2010, à 22:37
- pfriedz
Re : /* Topic des codeurs couche-tard [1] */
Je m'indigne vivement !
Hors ligne
#2454 Le 04/09/2010, à 22:39
- Pylades
Re : /* Topic des codeurs couche-tard [1] */
pfriedZ va quadrupler ses points ! \o/
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#2455 Le 04/09/2010, à 22:39
- helly
Re : /* Topic des codeurs couche-tard [1] */
Ouais mais il double post .
Archlinux-wmii-dwb.
Un problème résolu ? Faites le savoir en mettant [résolu] à côté du titre de votre topic.
Un problème non résolu ? Faites le savoir en insultant ceux qui cherchent à vous aider.
Un site bleu super remasterised©, un wiki cherchant des volontaires pour traduire un site.
Hors ligne
#2456 Le 04/09/2010, à 22:44
- pfriedz
Re : /* Topic des codeurs couche-tard [1] */
Quel double post ?
pfriedZ va quadrupler ses points ! \o/
Je poste tellement ici que vous ne faites pas le poids .
Hors ligne
#2457 Le 05/09/2010, à 01:06
- \\Ouranos//
Re : /* Topic des codeurs couche-tard [1] */
Ubuntu facile, c'est :
- Dire "Bonjour"
- Lire la doc et les règles du forum avant de poster. Savoir poser une question intelligemment.
- Mettre des balises url autour des liens et un tiret à su.
Hors ligne
#2458 Le 05/09/2010, à 01:07
- Кຼزດ
Re : /* Topic des codeurs couche-tard [1] */
mpo
dou
Hors ligne
#2459 Le 05/09/2010, à 01:14
- The Uploader
Re : /* Topic des codeurs couche-tard [1] */
(oups, suppression du message, et changement de topic)
salut
Pour ma première contribution au topic des codeurs couche tard, j'ai du lourd.
A partir de ce code (à dl dans le premier post), qui implémente un SDL_thread pour la capture vidéo ZMBV de DOSBox, voici mon maigre et ultime code de tentative d'enlever un bug de crash aléatoire dans le temps (sur la ligne "free(videohandle->q.front().videobuf);") dudit SDL_thread :
code d'origine :
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: hardware.cpp,v 1.23 2009/10/11 18:09:22 qbix79 Exp $ */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "dosbox.h"
#include "hardware.h"
#include "setup.h"
#include "support.h"
#include "mem.h"
#include "mapper.h"
#include "pic.h"
#include "render.h"
#include "cross.h"
#if (C_SSHOT)
#define C_THREADED_CAPTURE 1
#include <png.h>
#include "../libs/zmbv/zmbv.cpp"
#if (C_THREADED_CAPTURE)
#define MAX_QUEUE_SIZE 400
#include "SDL.h"
#include <queue>
SDL_Thread *video_thread;
#endif
#endif
static std::string capturedir;
extern const char* RunningProgram;
Bitu CaptureState;
#define WAVE_BUF 16*1024
#define MIDI_BUF 4*1024
#define AVI_HEADER_SIZE 500
#if (C_SSHOT)
typedef struct {
Bit16s *audiobuf;
Bitu audioused;
Bit8u *videobuf;
Bit8u *pal;
} video_chunk_t;
typedef struct {
FILE *handle;
Bitu frames;
Bit16s audiobuf[WAVE_BUF][2];
Bitu audioused;
Bitu audiorate;
Bitu audiowritten;
VideoCodec *codec;
Bitu width, height, bpp;
Bitu written;
float fps;
int bufSize;
void *buf;
Bit8u *index;
Bitu indexsize, indexused;
Bitu flags;
Bitu pitch;
zmbv_format_t format;
bool thread_running;
#if (C_THREADED_CAPTURE)
std::queue<video_chunk_t> q;
#endif
} video_capture_t;
#endif
static struct {
struct {
FILE * handle;
Bit16s buf[WAVE_BUF][2];
Bitu used;
Bit32u length;
Bit32u freq;
} wave;
struct {
FILE * handle;
Bit8u buffer[MIDI_BUF];
Bitu used,done;
Bit32u last;
} midi;
struct {
Bitu rowlen;
} image;
#if (C_SSHOT)
video_capture_t video;
#endif
} capture;
FILE * OpenCaptureFile(const char * type,const char * ext) {
if(capturedir.empty()) {
LOG_MSG("Please specify a capture directory");
return 0;
}
Bitu last=0;
char file_start[16];
dir_information * dir;
/* Find a filename to open */
dir = open_directory(capturedir.c_str());
if (!dir) {
//Try creating it first
Cross::CreateDir(capturedir);
dir=open_directory(capturedir.c_str());
if(!dir) {
LOG_MSG("Can't open dir %s for capturing %s",capturedir.c_str(),type);
return 0;
}
}
strcpy(file_start,RunningProgram);
lowcase(file_start);
strcat(file_start,"_");
bool is_directory;
char tempname[CROSS_LEN];
bool testRead = read_directory_first(dir, tempname, is_directory );
for ( ; testRead; testRead = read_directory_next(dir, tempname, is_directory) ) {
char * test=strstr(tempname,ext);
if (!test || strlen(test)!=strlen(ext))
continue;
*test=0;
if (strncasecmp(tempname,file_start,strlen(file_start))!=0) continue;
Bitu num=atoi(&tempname[strlen(file_start)]);
if (num>=last) last=num+1;
}
close_directory( dir );
char file_name[CROSS_LEN];
sprintf(file_name,"%s%c%s%03d%s",capturedir.c_str(),CROSS_FILESPLIT,file_start,last,ext);
/* Open the actual file */
FILE * handle=fopen(file_name,"wb");
if (handle) {
LOG_MSG("Capturing %s to %s",type,file_name);
} else {
LOG_MSG("Failed to open %s for capturing %s",file_name,type);
}
return handle;
}
#if (C_SSHOT)
static void CAPTURE_AddAviChunk(const char * tag, Bit32u size, void * data, Bit32u flags) {
Bit8u chunk[8];Bit8u *index;Bit32u pos, writesize;
chunk[0] = tag[0];chunk[1] = tag[1];chunk[2] = tag[2];chunk[3] = tag[3];
host_writed(&chunk[4], size);
/* Write the actual data */
fwrite(chunk,1,8,capture.video.handle);
writesize = (size+1)&~1;
fwrite(data,1,writesize,capture.video.handle);
pos = capture.video.written + 4;
capture.video.written += writesize + 8;
if (capture.video.indexused + 16 >= capture.video.indexsize ) {
capture.video.index = (Bit8u*)realloc( capture.video.index, capture.video.indexsize + 16 * 4096);
if (!capture.video.index)
E_Exit("Ran out of memory during AVI capturing");
capture.video.indexsize += 16*4096;
}
index = capture.video.index+capture.video.indexused;
capture.video.indexused += 16;
index[0] = tag[0];
index[1] = tag[1];
index[2] = tag[2];
index[3] = tag[3];
host_writed(index+4, flags);
host_writed(index+8, pos);
host_writed(index+12, size);
}
static void CAPTURE_VideoHeader() {
Bit8u avi_header[AVI_HEADER_SIZE];
Bitu main_list;
Bitu header_pos=0;
Bitu save_pos=ftell(capture.video.handle);
#define AVIOUT4(_S_) memcpy(&avi_header[header_pos],_S_,4);header_pos+=4;
#define AVIOUTw(_S_) host_writew(&avi_header[header_pos], _S_);header_pos+=2;
#define AVIOUTd(_S_) host_writed(&avi_header[header_pos], _S_);header_pos+=4;
/* Try and write an avi header */
AVIOUT4("RIFF"); // Riff header
AVIOUTd(AVI_HEADER_SIZE + capture.video.written - 8 + capture.video.indexused);
AVIOUT4("AVI ");
AVIOUT4("LIST"); // List header
main_list = header_pos;
AVIOUTd(0); // TODO size of list
AVIOUT4("hdrl");
AVIOUT4("avih");
AVIOUTd(56); /* # of bytes to follow */
AVIOUTd((Bit32u)(1000000 / capture.video.fps)); /* Microseconds per frame */
AVIOUTd(0);
AVIOUTd(0); /* PaddingGranularity (whatever that might be) */
AVIOUTd(0x110); /* Flags,0x10 has index, 0x100 interleaved */
AVIOUTd(capture.video.frames); /* TotalFrames */
AVIOUTd(0); /* InitialFrames */
AVIOUTd(2); /* Stream count */
AVIOUTd(0); /* SuggestedBufferSize */
AVIOUTd(capture.video.width); /* Width */
AVIOUTd(capture.video.height); /* Height */
AVIOUTd(0); /* TimeScale: Unit used to measure time */
AVIOUTd(0); /* DataRate: Data rate of playback */
AVIOUTd(0); /* StartTime: Starting time of AVI data */
AVIOUTd(0); /* DataLength: Size of AVI data chunk */
/* Video stream list */
AVIOUT4("LIST");
AVIOUTd(4 + 8 + 56 + 8 + 40); /* Size of the list */
AVIOUT4("strl");
/* video stream header */
AVIOUT4("strh");
AVIOUTd(56); /* # of bytes to follow */
AVIOUT4("vids"); /* Type */
AVIOUT4(CODEC_4CC); /* Handler */
AVIOUTd(0); /* Flags */
AVIOUTd(0); /* Reserved, MS says: wPriority, wLanguage */
AVIOUTd(0); /* InitialFrames */
AVIOUTd(1000000); /* Scale */
AVIOUTd((Bit32u)(1000000 * capture.video.fps)); /* Rate: Rate/Scale == samples/second */
AVIOUTd(0); /* Start */
AVIOUTd(capture.video.frames); /* Length */
AVIOUTd(0); /* SuggestedBufferSize */
AVIOUTd(~0); /* Quality */
AVIOUTd(0); /* SampleSize */
AVIOUTd(0); /* Frame */
AVIOUTd(0); /* Frame */
/* The video stream format */
AVIOUT4("strf");
AVIOUTd(40); /* # of bytes to follow */
AVIOUTd(40); /* Size */
AVIOUTd(capture.video.width); /* Width */
AVIOUTd(capture.video.height); /* Height */
// OUTSHRT(1); OUTSHRT(24); /* Planes, Count */
AVIOUTd(0);
AVIOUT4(CODEC_4CC); /* Compression */
AVIOUTd(capture.video.width * capture.video.height*4); /* SizeImage (in bytes?) */
AVIOUTd(0); /* XPelsPerMeter */
AVIOUTd(0); /* YPelsPerMeter */
AVIOUTd(0); /* ClrUsed: Number of colors used */
AVIOUTd(0); /* ClrImportant: Number of colors important */
/* Audio stream list */
AVIOUT4("LIST");
AVIOUTd(4 + 8 + 56 + 8 + 16); /* Length of list in bytes */
AVIOUT4("strl");
/* The audio stream header */
AVIOUT4("strh");
AVIOUTd(56); /* # of bytes to follow */
AVIOUT4("auds");
AVIOUTd(0); /* Format (Optionally) */
AVIOUTd(0); /* Flags */
AVIOUTd(0); /* Reserved, MS says: wPriority, wLanguage */
AVIOUTd(0); /* InitialFrames */
AVIOUTd(4); /* Scale */
AVIOUTd(capture.video.audiorate*4); /* Rate, actual rate is scale/rate */
AVIOUTd(0); /* Start */
if (!capture.video.audiorate)
capture.video.audiorate = 1;
AVIOUTd(capture.video.audiowritten/4); /* Length */
AVIOUTd(0); /* SuggestedBufferSize */
AVIOUTd(~0); /* Quality */
AVIOUTd(4); /* SampleSize */
AVIOUTd(0); /* Frame */
AVIOUTd(0); /* Frame */
/* The audio stream format */
AVIOUT4("strf");
AVIOUTd(16); /* # of bytes to follow */
AVIOUTw(1); /* Format, WAVE_ZMBV_FORMAT_PCM */
AVIOUTw(2); /* Number of channels */
AVIOUTd(capture.video.audiorate); /* SamplesPerSec */
AVIOUTd(capture.video.audiorate*4); /* AvgBytesPerSec*/
AVIOUTw(4); /* BlockAlign */
AVIOUTw(16); /* BitsPerSample */
int nmain = header_pos - main_list - 4;
/* Finish stream list, i.e. put number of bytes in the list to proper pos */
int njunk = AVI_HEADER_SIZE - 8 - 12 - header_pos;
AVIOUT4("JUNK");
AVIOUTd(njunk);
/* Fix the size of the main list */
header_pos = main_list;
AVIOUTd(nmain);
header_pos = AVI_HEADER_SIZE - 12;
AVIOUT4("LIST");
AVIOUTd(capture.video.written+4); /* Length of list in bytes */
AVIOUT4("movi");
/* First add the index table to the end */
memcpy(capture.video.index, "idx1", 4);
host_writed( capture.video.index+4, capture.video.indexused - 8 );
fwrite( capture.video.index, 1, capture.video.indexused, capture.video.handle);
fseek(capture.video.handle, 0, SEEK_SET);
fwrite(&avi_header, 1, AVI_HEADER_SIZE, capture.video.handle);
fseek(capture.video.handle, save_pos, SEEK_SET);
}
static void CAPTURE_VideoEvent(bool pressed) {
if (!pressed)
return;
if (CaptureState & CAPTURE_VIDEO) {
/* Close the video */
CaptureState &= ~CAPTURE_VIDEO;
#if (C_THREADED_CAPTURE)
/* Waits for thread to finish */
if (capture.video.thread_running) {
LOG_MSG("Finalizing video. Please wait...");
SDL_WaitThread(video_thread,NULL);
}
#endif
/* Adds AVI header to the file */
CAPTURE_VideoHeader();
/* Close video file and free memory */
fclose( capture.video.handle );
free( capture.video.index );
free( capture.video.buf );
delete capture.video.codec;
capture.video.handle = 0;
LOG_MSG("Stopped capturing video.");
} else {
if (!capture.video.thread_running)
CaptureState |= CAPTURE_VIDEO;
}
}
int CAPTURE_VideoCompressFrame(video_capture_t *videohandle, video_chunk_t chunk) {
Bit8u doubleRow[SCALER_MAXWIDTH*4];
Bitu countWidth = videohandle->width;
int codecFlags;
if (videohandle->frames % 300 == 0)
codecFlags = 1;
else codecFlags = 0;
if (!videohandle->codec->PrepareCompressFrame( codecFlags, videohandle->format, (char *)chunk.pal, videohandle->buf, videohandle->bufSize))
{
CAPTURE_VideoEvent(TRUE);
return 1;
}
for (Bit32u i=0;i<videohandle->height;i++) {
void * rowPointer;
if (videohandle->flags & CAPTURE_FLAG_DBLW) {
void *srcLine;
Bitu x;
Bitu countWidth = videohandle->width >> 1;
if (videohandle->flags & CAPTURE_FLAG_DBLH)
srcLine=(chunk.videobuf+(i >> 1)*videohandle->pitch);
else
srcLine=(chunk.videobuf+(i >> 0)*videohandle->pitch);
switch ( videohandle->bpp) {
case 8:
for (x=0;x<countWidth;x++)
((Bit8u *)doubleRow)[x*2+0] =
((Bit8u *)doubleRow)[x*2+1] = ((Bit8u *)srcLine)[x];
break;
case 15:
case 16:
for (x=0;x<countWidth;x++)
((Bit16u *)doubleRow)[x*2+0] =
((Bit16u *)doubleRow)[x*2+1] = ((Bit16u *)srcLine)[x];
break;
case 32:
for (x=0;x<countWidth;x++)
((Bit32u *)doubleRow)[x*2+0] =
((Bit32u *)doubleRow)[x*2+1] = ((Bit32u *)srcLine)[x];
break;
}
rowPointer=doubleRow;
} else {
if (videohandle->flags & CAPTURE_FLAG_DBLH)
rowPointer=(chunk.videobuf+(i >> 1)*videohandle->pitch);
else
rowPointer=(chunk.videobuf+(i >> 0)*videohandle->pitch);
}
videohandle->codec->CompressLines( 1, &rowPointer );
}
int written = videohandle->codec->FinishCompressFrame();
if (written < 0) {
CAPTURE_VideoEvent(TRUE);
return 1;
}
CAPTURE_AddAviChunk( "00dc", written, videohandle->buf, codecFlags & 1 ? 0x10 : 0x0);
videohandle->frames++;
// LOG_MSG("Frame %d video %d audio %d",videohandle->frames, written, videohandle->audioused *4 );
if ( chunk.audioused ) {
CAPTURE_AddAviChunk( "01wb", chunk.audioused * 4, chunk.audiobuf, 0);
videohandle->audiowritten = chunk.audioused*4;
}
/* Adds AVI header to the file */
CAPTURE_VideoHeader();
return 0;
}
#if (C_THREADED_CAPTURE)
int CAPTURE_VideoThread(void *videohandleptr) {
video_capture_t *videohandle=(video_capture_t*)videohandleptr;
videohandle->thread_running = true;
int rc = 0;
/* Process queue */
while (!videohandle->q.empty()) {
// LOG_MSG("queue size %d",videohandle->q.size());
/* Process a block and write it to disk */
if (!rc) rc = CAPTURE_VideoCompressFrame(videohandle,videohandle->q.front());
else CaptureState &= ~CAPTURE_VIDEO;
free(videohandle->q.front().videobuf);
free(videohandle->q.front().audiobuf);
free(videohandle->q.front().pal);
/* Delete chunk from queue */
videohandle->q.pop();
}
videohandle->thread_running = false;
return rc;
}
#endif // C_THREADED_CAPTURE
#endif // C_SSHOT
void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, float fps, Bit8u * data, Bit8u * pal) {
#if (C_SSHOT)
Bitu i;
Bit8u doubleRow[SCALER_MAXWIDTH*4];
Bitu countWidth = width;
if (flags & CAPTURE_FLAG_DBLH)
height *= 2;
if (flags & CAPTURE_FLAG_DBLW)
width *= 2;
if (height > SCALER_MAXHEIGHT)
return;
if (width > SCALER_MAXWIDTH)
return;
if (CaptureState & CAPTURE_IMAGE) {
png_structp png_ptr;
png_infop info_ptr;
png_color palette[256];
CaptureState &= ~CAPTURE_IMAGE;
/* Open the actual file */
FILE * fp=OpenCaptureFile("Screenshot",".png");
if (!fp) goto skip_shot;
/* First try to alloacte the png structures */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL);
if (!png_ptr) goto skip_shot;
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
goto skip_shot;
}
/* Finalize the initing of png library */
png_init_io(png_ptr, fp);
png_set_compression_level(png_ptr,Z_BEST_COMPRESSION);
/* set other zlib parameters */
png_set_compression_mem_level(png_ptr, 8);
png_set_compression_strategy(png_ptr,Z_DEFAULT_STRATEGY);
png_set_compression_window_bits(png_ptr, 15);
png_set_compression_method(png_ptr, 8);
png_set_compression_buffer_size(png_ptr, 8192);
if (bpp==8) {
png_set_IHDR(png_ptr, info_ptr, width, height,
8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
for (i=0;i<256;i++) {
palette[i].red=pal[i*4+0];
palette[i].green=pal[i*4+1];
palette[i].blue=pal[i*4+2];
}
png_set_PLTE(png_ptr, info_ptr, palette,256);
} else {
png_set_bgr( png_ptr );
png_set_IHDR(png_ptr, info_ptr, width, height,
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
}
png_write_info(png_ptr, info_ptr);
for (i=0;i<height;i++) {
void *rowPointer;
void *srcLine;
if (flags & CAPTURE_FLAG_DBLH)
srcLine=(data+(i >> 1)*pitch);
else
srcLine=(data+(i >> 0)*pitch);
rowPointer=srcLine;
switch (bpp) {
case 8:
if (flags & CAPTURE_FLAG_DBLW) {
for (Bitu x=0;x<countWidth;x++)
doubleRow[x*2+0] =
doubleRow[x*2+1] = ((Bit8u *)srcLine)[x];
rowPointer = doubleRow;
}
break;
case 15:
if (flags & CAPTURE_FLAG_DBLW) {
for (Bitu x=0;x<countWidth;x++) {
Bitu pixel = ((Bit16u *)srcLine)[x];
doubleRow[x*6+0] = doubleRow[x*6+3] = ((pixel& 0x001f) * 0x21) >> 2;
doubleRow[x*6+1] = doubleRow[x*6+4] = ((pixel& 0x03e0) * 0x21) >> 7;
doubleRow[x*6+2] = doubleRow[x*6+5] = ((pixel& 0x7c00) * 0x21) >> 12;
}
} else {
for (Bitu x=0;x<countWidth;x++) {
Bitu pixel = ((Bit16u *)srcLine)[x];
doubleRow[x*3+0] = ((pixel& 0x001f) * 0x21) >> 2;
doubleRow[x*3+1] = ((pixel& 0x03e0) * 0x21) >> 7;
doubleRow[x*3+2] = ((pixel& 0x7c00) * 0x21) >> 12;
}
}
rowPointer = doubleRow;
break;
case 16:
if (flags & CAPTURE_FLAG_DBLW) {
for (Bitu x=0;x<countWidth;x++) {
Bitu pixel = ((Bit16u *)srcLine)[x];
doubleRow[x*6+0] = doubleRow[x*6+3] = ((pixel& 0x001f) * 0x21) >> 2;
doubleRow[x*6+1] = doubleRow[x*6+4] = ((pixel& 0x07e0) * 0x41) >> 9;
doubleRow[x*6+2] = doubleRow[x*6+5] = ((pixel& 0xf800) * 0x21) >> 13;
}
} else {
for (Bitu x=0;x<countWidth;x++) {
Bitu pixel = ((Bit16u *)srcLine)[x];
doubleRow[x*3+0] = ((pixel& 0x001f) * 0x21) >> 2;
doubleRow[x*3+1] = ((pixel& 0x07e0) * 0x41) >> 9;
doubleRow[x*3+2] = ((pixel& 0xf800) * 0x21) >> 13;
}
}
rowPointer = doubleRow;
break;
case 32:
if (flags & CAPTURE_FLAG_DBLW) {
for (Bitu x=0;x<countWidth;x++) {
doubleRow[x*6+0] = doubleRow[x*6+3] = ((Bit8u *)srcLine)[x*4+0];
doubleRow[x*6+1] = doubleRow[x*6+4] = ((Bit8u *)srcLine)[x*4+1];
doubleRow[x*6+2] = doubleRow[x*6+5] = ((Bit8u *)srcLine)[x*4+2];
}
} else {
for (Bitu x=0;x<countWidth;x++) {
doubleRow[x*3+0] = ((Bit8u *)srcLine)[x*4+0];
doubleRow[x*3+1] = ((Bit8u *)srcLine)[x*4+1];
doubleRow[x*3+2] = ((Bit8u *)srcLine)[x*4+2];
}
}
rowPointer = doubleRow;
break;
}
png_write_row(png_ptr, (png_bytep)rowPointer);
}
/* Finish writing */
png_write_end(png_ptr, 0);
/*Destroy PNG structs*/
png_destroy_write_struct(&png_ptr, &info_ptr);
/*close file*/
fclose(fp);
}
skip_shot:
if (CaptureState & CAPTURE_VIDEO) {
/* Restarts capturing if any of the test fails */
if (capture.video.handle && (
capture.video.width != width ||
capture.video.height != height ||
capture.video.bpp != bpp ||
capture.video.fps != fps)) {
/* Ends current capturing */
CAPTURE_VideoEvent(true);
/* Toggle video capture event */
CaptureState |= CAPTURE_VIDEO;
}
/* Choose video format */
switch (bpp) {
case 8:capture.video.format = ZMBV_FORMAT_8BPP;break;
case 15:capture.video.format = ZMBV_FORMAT_15BPP;break;
case 16:capture.video.format = ZMBV_FORMAT_16BPP;break;
case 32:capture.video.format = ZMBV_FORMAT_32BPP;break;
default:
CAPTURE_VideoEvent(TRUE);
return;
}
/* Initialize video handle */
if (!capture.video.handle) {
capture.video.handle = OpenCaptureFile("Video",".avi");
if (!capture.video.handle) {
CAPTURE_VideoEvent(TRUE);
return;
}
capture.video.codec = new VideoCodec();
if (!capture.video.codec) {
CAPTURE_VideoEvent(TRUE);
return;
}
if (!capture.video.codec->SetupCompress( width, height)) {
CAPTURE_VideoEvent(TRUE);
return;
}
capture.video.bufSize = capture.video.codec->NeededSize(width, height, capture.video.format);
capture.video.buf = malloc( capture.video.bufSize );
if (!capture.video.buf) {
CAPTURE_VideoEvent(TRUE);
return;
}
capture.video.index = (Bit8u*)malloc( 16*4096 );
if (!capture.video.index) {
CAPTURE_VideoEvent(TRUE);
return;
}
capture.video.indexsize = 16*4096;
capture.video.indexused = 8;
capture.video.width = width;
capture.video.height = height;
capture.video.pitch = pitch;
capture.video.flags = flags;
capture.video.bpp = bpp;
capture.video.fps = fps;
for (int i=0;i<AVI_HEADER_SIZE;i++)
fputc(0,capture.video.handle);
capture.video.frames = 0;
capture.video.written = 0;
capture.video.audioused = 0;
capture.video.audiowritten = 0;
capture.video.thread_running = false;
}
video_chunk_t chunk;
#if (C_THREADED_CAPTURE)
/* Create video chunk buffers */
chunk.videobuf = (Bit8u *)malloc(capture.video.height*capture.video.pitch);
if (!chunk.videobuf) {
CAPTURE_VideoEvent(true);
return;
}
chunk.audiobuf = (Bit16s *)malloc(capture.video.audioused*4);
if (!chunk.audiobuf) {
CAPTURE_VideoEvent(true);
return;
}
chunk.pal = (Bit8u *)malloc(256*4);
if (!chunk.pal) {
CAPTURE_VideoEvent(true);
return;
}
/* Copy data to chunk */
memcpy(chunk.videobuf,data,capture.video.height*capture.video.pitch);
memcpy(chunk.audiobuf,&capture.video.audiobuf, capture.video.audioused*4);
memcpy(chunk.pal,pal,256*4);
chunk.audioused = capture.video.audioused;
capture.video.audioused = 0;
/* Push avi chunk to queue */
capture.video.q.push(chunk);
/* If queue exceeds size limit, wait for capture thread to empty queue */
if (capture.video.q.size()>MAX_QUEUE_SIZE) {
LOG_MSG("Writing video to disk. Please wait...");
SDL_WaitThread(video_thread,NULL);
}
/* If thread is not already running, start it */
if (!capture.video.thread_running)
video_thread = SDL_CreateThread(CAPTURE_VideoThread, (void*)&capture.video);
#else
/* Compress frame directly (no thread) */
chunk.videobuf = data;
chunk.audiobuf = (Bit16s*)&capture.video.audiobuf;
chunk.audioused = capture.video.audioused;
chunk.pal = pal;
capture.video.audioused = 0;
CAPTURE_VideoCompressFrame(&capture.video,chunk);
#endif
}
#endif
return;
}
#if (C_SSHOT)
static void CAPTURE_ScreenShotEvent(bool pressed) {
if (!pressed)
return;
CaptureState |= CAPTURE_IMAGE;
}
#endif
(suivi des sections des fonctions de capture MIDI et WAV)
class HARDWARE:public Module_base{
public:
HARDWARE(Section* configuration):Module_base(configuration){
Section_prop * section = static_cast<Section_prop *>(configuration);
Prop_path* proppath= section->Get_path("captures");
capturedir = proppath->realpath;
CaptureState = 0;
MAPPER_AddHandler(CAPTURE_WaveEvent,MK_f6,MMOD1,"recwave","Rec Wave");
MAPPER_AddHandler(CAPTURE_MidiEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI");
#if (C_SSHOT)
MAPPER_AddHandler(CAPTURE_ScreenShotEvent,MK_f5,MMOD1,"scrshot","Screenshot");
MAPPER_AddHandler(CAPTURE_VideoEvent,MK_f5,MMOD1|MMOD2,"video","Video");
#endif
}
~HARDWARE(){
if (capture.wave.handle) CAPTURE_WaveEvent(true);
if (capture.midi.handle) CAPTURE_MidiEvent(true);
}
};
a47 1 SDL_Thread *video_thread=NULL; a215 1 AVIOUTd((Bit32u)(1000000 / 10)); /* Microseconds per frame */ a243 1 AVIOUTd((Bit32u)(1000000 * 10)); /* Rate: Rate/Scale == samples/second */ a331 1 if (video_thread) { a333 1 video_thread=NULL; d338 1 a349 1 if (!video_thread) a353 2 int secframescount=0; a354 4 secframescount++; if(secframescount==9) secframescount=1; if(secframescount==1||secframescount==8){ a413 1 } a452 1 int thread_count=0; a696 1 //LOG_MSG("threads %d",thread_count); a700 2 video_thread=NULL; thread_count--; a704 2 if (!video_thread) thread_count++;
Ci dessus, j'essaie thread(!)=NULL au lieu d'un bool global (la doc de la SDL conseille un bool mais je suis plus ou moins désespéré).
Je fais aussi passer la capture vidéo à 10 fps (avec secframescount et la modif du header .AVI). -> ça, ça marche.
J'essaie aussi de compter le nombre de threads actifs (pas facile! j'ai un peu de mal avec valgrind, que j'ai essayé aussi).
C'est un arrachage de cheveux depuis des mois. j'ai même essayé les std::auto_ptr, sans succès (bon faut dire que le make plantait sans message d'erreur clair. Je n'ai même pas pu essayer la solution des auto_ptr en situation de debug, en fait... ). C'est officiel, je hais les threads.
Bon sinon, j'aurai bien du code QT, mais pas encore. ^^
Dernière modification par The Uploader (Le 05/09/2010, à 01:17)
- Oldies PC : Intel Pentium 3 @ 800 Mhz sur CM ASUS P2B-F, GeForce 4 Ti4800 SE, Disque Dur Hitachi 160 Go, 512 Mo de RAM, 3DFX Voodoo 2, Sound Blaster 16 ISA PnP, Windows 98 SE / XP)
- Desktop : Intel Core i7 6700K @ 4 GHz sur CM ASUS Z170-P, GeForce GTX 1070, SSD Samsung 850 EVO 1 To, 16 Go de RAM, Disque Dur Seagate Barracuda 3 To, Windows 10
Hors ligne
#2460 Le 05/09/2010, à 01:31
- Pylades
Re : /* Topic des codeurs couche-tard [1] */
Mouais, les threads, je n’en raffole pas…
Bon, et si je finissais mon bout de code commencé pendant le voyage et que je le mettais en FTP ?
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#2461 Le 05/09/2010, à 01:46
- Pylades
Re : /* Topic des codeurs couche-tard [1] */
Bon, mon bout de code à l’air de marcher à peu près. Il y a deux bugs, mais pas critiques. Je le publierai bientôt.
Sous licence BSD…
Édit : bonne nuit.
Dernière modification par Pylade (Le 05/09/2010, à 02:03)
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#2462 Le 05/09/2010, à 02:03
- tshirtman
Re : /* Topic des codeurs couche-tard [1] */
@the upploader: j'ai tenté de comprendre un peu, mais c'est un peu trop le bordel pour cette heure ^^, je pense qu'il faudrait que tu marque tes sections critiques avec des sémaphores (peut être sur ton test s'il faut attendre le thread) pour éviter que les temps aléatoires te foutent le boxon quand c'est trop rapide…
Hors ligne
#2463 Le 05/09/2010, à 02:19
- nesthib
Re : /* Topic des codeurs couche-tard [1] */
GUL Bordeaux : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde auto – ♥ awk
⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn
Hors ligne
#2464 Le 05/09/2010, à 02:25
- samυncle
Re : /* Topic des codeurs couche-tard [1] */
Hello world
Hors ligne
#2465 Le 05/09/2010, à 02:47
- Sir Na Kraïou
Re : /* Topic des codeurs couche-tard [1] */
Descendant de Charlemagne et de LUCA.
Bleu, en l'hommage d'un truc bleu. :'(
C'est pas du bleu.
C'est pas le lac de Genève, c'est le Lac Léman.
Hors ligne
#2466 Le 05/09/2010, à 06:42
- Compteur du TdCCT
Re : /* Topic des codeurs couche-tard [1] */
Scores totaux, depuis le début :
1) 1231 nesthib
2) 1156 Pylade
3) 1152 samuncle
4) 706 mathieuI
5) 668+5 grim7reaper /* ./viewtopic.php?pid=3486252#p3486252 */
6) 556 cm-t
7) 517 helly
8) 469 \\Ouranos//
9) 447 Р'tite G☢gole :mad:
10) 302 Lagierl
11) 198 tshirtman
12) 193 gnuuat
13) 121 ǤƦƯƝƬ
14) 110 Kanor
15) 93 petifrancais
16) 78 edge_one
17) 64 gulp
18) 60 Askelon
19) 54 pierguiard
20) 53 kamui57
21) 37 ilagas
22) 30 keny
23) 25 GentooUser
24) 24 louiz'
25) 20 Morgiver
26) 19 Le Rouge
27) 18 Ph3nix_
27) 18 xapantu
29) 15 timsy
30) 14 kouskous
31) 12 stratoboy
31) 12 sailing
33) 11 alexises
34) 10 CROWD
34) 10 Toineo
34) 10 NutMotion
34) 10 pseudovingtcinqcaracteres
38) 8 Mornagest
39) 7 Vista
40) 6 Zeibux
40) 6 ubuntlin
40) 6 The Uploader
43) 4 danychou56
43) 4 Neros
43) 4 Biaise
46) 3 pfriedZ
47) 2 SoJaS
47) 2 ceric
49) 1 pfriedK
49) 1 geenux
Codez-vous trop tard le soir ?
Demandez au Compteur du TdCCT pour le savoir !
J’ai été généreusement codé par tshirtman ; d’ailleurs, voici mon code source. TdCCT CEP : ./viewtopic.php?pid=3493579#p3493579 (p3492608).
Hors ligne
#2467 Le 05/09/2010, à 06:42
- Compteur du TdCCT
Re : /* Topic des codeurs couche-tard [1] */
Scores de la période en cours :
1) 40 samuncle
1) 40 Pylade
1) 40 nesthib
1) 40 Р'tite G☢gole :mad:
5) 22 cm-t
6) 17 mathieuI
7) 11 helly
7) 11 \\Ouranos//
9) 10 Askelon
9) 10 tshirtman
11) 8 gulp
12) 6 Lagierl
12) 6 kamui57
12) 6 The Uploader
15) 3 pfriedZ
Codez-vous trop tard le soir ?
Demandez au Compteur du TdCCT pour le savoir !
J’ai été généreusement codé par tshirtman ; d’ailleurs, voici mon code source. TdCCT CEP : ./viewtopic.php?pid=3493579#p3493579 (p3492608).
Hors ligne
#2468 Le 05/09/2010, à 11:12
- Pylades
Re : /* Topic des codeurs couche-tard [1] */
Ah !
J’ai oublié de renommer les points de pfriedZ.
Je vais faire un merge…
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#2469 Le 05/09/2010, à 18:25
- gulp
Re : /* Topic des codeurs couche-tard [1] */
salut GMT+9
Hors ligne
#2470 Le 05/09/2010, à 20:38
- Pylades
Re : /* Topic des codeurs couche-tard [1] */
On ferme !
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#2471 Le 05/09/2010, à 20:39
- Pylades
Re : /* Topic des codeurs couche-tard [1] */
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#2472 Le 05/09/2010, à 20:42
- helly
Re : /* Topic des codeurs couche-tard [1] */
Ok va, j'accèpte !
/me a le dernier post du topic \o/ !
Archlinux-wmii-dwb.
Un problème résolu ? Faites le savoir en mettant [résolu] à côté du titre de votre topic.
Un problème non résolu ? Faites le savoir en insultant ceux qui cherchent à vous aider.
Un site bleu super remasterised©, un wiki cherchant des volontaires pour traduire un site.
Hors ligne
#2473 Le 05/09/2010, à 21:38
- nesthib
Re : /* Topic des codeurs couche-tard [1] */
… bon /me va corriger les choses avant que helly et Pylade laissent tout bugguer…
GUL Bordeaux : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde auto – ♥ awk
⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn
Hors ligne
#2474 Le 05/09/2010, à 21:38
- nesthib
Re : /* Topic des codeurs couche-tard [1] */
GUL Bordeaux : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde auto – ♥ awk
⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn
Hors ligne
#2475 Le 06/09/2010, à 15:05
- helly
Re : /* Topic des codeurs couche-tard [1] */
Finale !
http://forum.ubuntu-fr.org/viewtopic.php?id=416210
Archlinux-wmii-dwb.
Un problème résolu ? Faites le savoir en mettant [résolu] à côté du titre de votre topic.
Un problème non résolu ? Faites le savoir en insultant ceux qui cherchent à vous aider.
Un site bleu super remasterised©, un wiki cherchant des volontaires pour traduire un site.
Hors ligne