Skip to content
This repository has been archived by the owner on Jan 11, 2021. It is now read-only.

Commit

Permalink
fix & quick record
Browse files Browse the repository at this point in the history
  • Loading branch information
44 committed Mar 24, 2019
1 parent 02a748e commit 1289891
Show file tree
Hide file tree
Showing 11 changed files with 648 additions and 34 deletions.
3 changes: 2 additions & 1 deletion build.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
set PATH=%PATH%;C:\devkitPro\devkitARM\bin
build-jpeg.py
make
copy ntr_payload.bin ntr.n3ds.bin
129 changes: 129 additions & 0 deletions include/avifmt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#ifndef _AVIFMT_H_
#define _AVIFMT_H_


/* 4 bytes */
typedef int WORD;
typedef unsigned int DWORD;
/* 1 byte */
typedef char BYTE;


/* for use in AVI_avih.flags */
const DWORD AVIF_HASINDEX = 0x00000010; /* index at end of file */
const DWORD AVIF_MUSTUSEINDEX = 0x00000020;
const DWORD AVIF_ISINTERLEAVED = 0x00000100;
const DWORD AVIF_TRUSTCKTYPE = 0x00000800;
const DWORD AVIF_WASCAPTUREFILE = 0x00010000;
const DWORD AVIF_COPYRIGHTED = 0x00020000;


struct AVI_avih
{
DWORD us_per_frame; /* frame display rate (or 0L) */
DWORD max_bytes_per_sec; /* max. transfer rate */
DWORD padding; /* pad to multiples of this size; */
/* normally 2K */
DWORD flags;
DWORD tot_frames; /* # frames in file */
DWORD init_frames;
DWORD streams;
DWORD buff_sz;
DWORD width;
DWORD height;
DWORD reserved[4];
};


struct AVI_strh
{
unsigned char type[4]; /* stream type */
unsigned char handler[4];
DWORD flags;
DWORD priority;
DWORD init_frames; /* initial frames (???) */
DWORD scale;
DWORD rate;
DWORD start;
DWORD length;
DWORD buff_sz; /* suggested buffer size */
DWORD quality;
DWORD sample_sz;
};


struct AVI_strf
{
DWORD sz;
DWORD width;
DWORD height;
DWORD planes_bit_cnt;
unsigned char compression[4];
DWORD image_sz;
DWORD xpels_meter;
DWORD ypels_meter;
DWORD num_colors; /* used colors */
DWORD imp_colors; /* important colors */
/* may be more for some codecs */
};


/*
AVI_list_hdr
spc: a very ubiquitous AVI struct, used in list structures
to specify type and length
*/

struct AVI_list_hdr
{
unsigned char id[4]; /* "LIST" */
DWORD sz; /* size of owning struct minus 8 */
unsigned char type[4]; /* type of list */
};


struct AVI_list_odml
{
struct AVI_list_hdr list_hdr;

unsigned char id[4];
DWORD sz;
DWORD frames;
};


struct AVI_list_strl
{
struct AVI_list_hdr list_hdr;

/* chunk strh */
unsigned char strh_id[4];
DWORD strh_sz;
struct AVI_strh strh;

/* chunk strf */
unsigned char strf_id[4];
DWORD strf_sz;
struct AVI_strf strf;

/* list odml */
struct AVI_list_odml list_odml;
};


struct AVI_list_hdrl
{
struct AVI_list_hdr list_hdr;

/* chunk avih */
unsigned char avih_id[4];
DWORD avih_sz;
struct AVI_avih avih;

/* list strl */
struct AVI_list_strl strl;
};


#endif
6 changes: 5 additions & 1 deletion include/func.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#ifndef FUNC_H
#define FUNC_H

int sdf_open(char *filename, int mode);
int sdf_read(int fd, int offset, void *buf, int size);
int sdf_write(int fd, int offset, void *buf, int size);
int sdf_close(int fd);
int sdf_setsize(int fd, u64 size);

void setCpuClockLock(int v);
void lockCpuClock();
Expand Down
27 changes: 27 additions & 0 deletions include/mjpegwriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once


#include <stdint.h>



typedef struct _MPEG_CONTEXT {
uintptr_t fd;
int frameCount;
int dataStreamOffset;
int totalJpegSize;
int filePos;
} MJPEG_CONTEXT;

typedef struct _MJPEG_JPEG_FILE {
int offsetInStream;
int alignedSize;
int offsetInBuffer;
} MJPEG_JPEG_FILE;


int mjpegInitWithFile(MJPEG_CONTEXT *ctx, uintptr_t fd);
int mjpegAppendJPEGFile(MJPEG_CONTEXT *ctx, char* buffer, int size, MJPEG_JPEG_FILE* jpegFile);
int mjpegStartFileIndex(MJPEG_CONTEXT *ctx);
int mjpegAppendFileIndex(MJPEG_CONTEXT *ctx, MJPEG_JPEG_FILE* jpegFile);
int mjpegFinish(MJPEG_CONTEXT *ctx, int width, int height, int usecPerFrame);
4 changes: 3 additions & 1 deletion source/jpeg/jdatadst.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ typedef my_mem_destination_mgr *my_mem_dest_ptr;
METHODDEF(void)
init_destination(j_compress_ptr cinfo)
{
showDbg((u8*) "init_destination", 0, 0);
//showDbg((u8*) "init_destination", 0, 0);
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;

/* Allocate the output buffer --- it will be released when done with image */
Expand Down Expand Up @@ -184,11 +184,13 @@ term_destination(j_compress_ptr cinfo)
size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;

/* Write any data remaining in the buffer */
/*
if (datacount > 0) {
if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
ERREXIT(cinfo, JERR_FILE_WRITE);
}
fflush(dest->outfile);
*/
/* Make sure we wrote the output file OK
if (ferror(dest->outfile))
ERREXIT(cinfo, JERR_FILE_WRITE);
Expand Down
1 change: 0 additions & 1 deletion source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ void threadStart() {
//magicKillProcess(0x27);
//disp(100, 0x100ff00);
while (1) {

if ((getKey()) == NTRMenuHotkey) {

if (allowDirectScreenAccess) {
Expand Down
172 changes: 172 additions & 0 deletions source/mjpegwriter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@


#include "global.h"
#include "mjpegwriter.h"
#include "avifmt.h"

void rpMjpegWriteCached(int fd, int offset, void *buf, int size);

#define WRITE_BUFFER(buf, len) rpMjpegWriteCached(ctx->fd, ctx->filePos, buf, (len)); ctx->filePos += (len);
#define WRITE_U32(dat) tmp = (dat); WRITE_BUFFER(&tmp, 4);
#define LILEND4(x) (x)



int mjpegInitWithFile(MJPEG_CONTEXT *ctx, uintptr_t fd) {
ctx->fd = fd;
ctx->filePos = 0;
ctx->frameCount = 0;
ctx->dataStreamOffset = 0;
ctx->totalJpegSize = 0;
char tmpBuffer[12 + sizeof(struct AVI_list_hdrl) + 12] = { 0 };
WRITE_BUFFER(tmpBuffer, sizeof(tmpBuffer));
return 0;
}

int mjpegAppendJPEGFile(MJPEG_CONTEXT *ctx, char* buffer, int size, MJPEG_JPEG_FILE* jpegFile) {
uint32_t tmp;
int padding = (4 - (size % 4)) % 4;
jpegFile->alignedSize = size + padding;
WRITE_BUFFER("00db", 4);
WRITE_U32(size + padding);
ctx->dataStreamOffset += 4;
jpegFile->offsetInStream = ctx->dataStreamOffset;
buffer[6] = 'A';
buffer[7] = 'V';
buffer[8] = 'I';
buffer[9] = '1';
WRITE_BUFFER(buffer, size);
WRITE_BUFFER(" ", padding);
ctx->dataStreamOffset += size + padding + 4;
ctx->totalJpegSize += size + padding;
ctx->frameCount++;
return 0;
}

int mjpegStartFileIndex(MJPEG_CONTEXT *ctx) {
uint32_t tmp;

WRITE_BUFFER("idx1", 4);
WRITE_U32(16 * ctx->frameCount);
return 0;
}

int mjpegAppendFileIndex(MJPEG_CONTEXT *ctx, MJPEG_JPEG_FILE* jpegFile) {
uint32_t tmp;

WRITE_BUFFER("00db", 4);
WRITE_U32(18);
WRITE_U32(jpegFile->offsetInStream);
WRITE_U32(jpegFile->alignedSize);
return 0;
}

int mjpegFinish(MJPEG_CONTEXT *ctx, int width, int height, int usecPerFrame) {
uint32_t tmp;
struct AVI_list_hdrl hdrl = {
/* header */
{
{ 'L', 'I', 'S', 'T' },
LILEND4(sizeof(struct AVI_list_hdrl) - 8),
{ 'h', 'd', 'r', 'l' }
},

/* chunk avih */
{ 'a', 'v', 'i', 'h' },
LILEND4(sizeof(struct AVI_avih)),
{
LILEND4(usecPerFrame),
LILEND4(1000000 * (ctx->totalJpegSize / ctx->frameCount) / usecPerFrame),
LILEND4(0),
LILEND4(AVIF_HASINDEX),
LILEND4(ctx->frameCount),
LILEND4(0),
LILEND4(1),
LILEND4(0),
LILEND4(width),
LILEND4(height),
{ LILEND4(0), LILEND4(0), LILEND4(0), LILEND4(0) }
},

/* list strl */
{
{
{ 'L', 'I', 'S', 'T' },
LILEND4(sizeof(struct AVI_list_strl) - 8),
{ 's', 't', 'r', 'l' }
},

/* chunk strh */
{ 's', 't', 'r', 'h' },
LILEND4(sizeof(struct AVI_strh)),
{
{ 'v', 'i', 'd', 's' },
{ 'M', 'J', 'P', 'G' },
LILEND4(0),
LILEND4(0),
LILEND4(0),
LILEND4(usecPerFrame),
LILEND4(1000000),
LILEND4(0),
LILEND4(ctx->frameCount),
LILEND4(0),
LILEND4(0),
LILEND4(0)
},

/* chunk strf */
{ 's', 't', 'r', 'f' },
sizeof(struct AVI_strf),
{
LILEND4(sizeof(struct AVI_strf)),
LILEND4(width),
LILEND4(height),
LILEND4(1 + 24 * 256 * 256),
{ 'M', 'J', 'P', 'G' },
LILEND4(width * height * 3),
LILEND4(0),
LILEND4(0),
LILEND4(0),
LILEND4(0)
},

/* list odml */
{
{
{ 'L', 'I', 'S', 'T' },
LILEND4(16),
{ 'o', 'd', 'm', 'l' }
},
{ 'd', 'm', 'l', 'h' },
LILEND4(4),
LILEND4(ctx->frameCount)
}
}
};
uint32_t riffSize = sizeof(struct AVI_list_hdrl) + 4 + 4 +
ctx->totalJpegSize + 8 * ctx->frameCount +
8 + 8 + 16 * ctx->frameCount;
ctx->filePos = 0;
WRITE_BUFFER("RIFF", 4);
WRITE_U32(riffSize);
WRITE_BUFFER("AVI ", 4);
/* list hdrl */
hdrl.avih.us_per_frame = LILEND4(usecPerFrame);
hdrl.avih.max_bytes_per_sec = LILEND4(1000000 * (ctx->totalJpegSize / ctx->frameCount)
/ usecPerFrame);
hdrl.avih.tot_frames = LILEND4(ctx->frameCount);
hdrl.avih.width = LILEND4(width);
hdrl.avih.height = LILEND4(height);
hdrl.strl.strh.scale = LILEND4(usecPerFrame);
hdrl.strl.strh.rate = LILEND4(1000000);
hdrl.strl.strh.length = LILEND4(ctx->frameCount);
hdrl.strl.strf.width = LILEND4(width);
hdrl.strl.strf.height = LILEND4(height);
hdrl.strl.strf.image_sz = LILEND4(width * height * 3);
hdrl.strl.list_odml.frames = LILEND4(ctx->frameCount); /* */
WRITE_BUFFER(&hdrl, sizeof(hdrl));
WRITE_BUFFER("LIST", 4);
WRITE_U32(ctx->totalJpegSize + 8 * ctx->frameCount + 4);
WRITE_BUFFER("movi", 4);
return 0;
}
Loading

0 comments on commit 1289891

Please sign in to comment.