
Author: ods15 Date: Sat Feb 2 14:50:18 2008 New Revision: 565 Log: abolish WORDS_BIGENDIAN nonsense from demux_avi.c, now it is CPU generic (i hope) Modified: src/trunk/config.mak src/trunk/nututils/demux_avi.c Modified: src/trunk/config.mak ============================================================================== --- src/trunk/config.mak (original) +++ src/trunk/config.mak Sat Feb 2 14:50:18 2008 @@ -1,10 +1,10 @@ PREFIX = /usr/local prefix = $(DESTDIR)$(PREFIX) -CFLAGS = -Os -fomit-frame-pointer -Wall -#CFLAGS = -g -DDEBUG -Wall +#CFLAGS += -DDEBUG + +CFLAGS += -Os -fomit-frame-pointer -g -Wall -#CFLAGS += -DWORDS_BIGENDIAN CFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 CC = cc Modified: src/trunk/nututils/demux_avi.c ============================================================================== --- src/trunk/nututils/demux_avi.c (original) +++ src/trunk/nututils/demux_avi.c Sat Feb 2 14:50:18 2008 @@ -7,18 +7,6 @@ #define mmioFOURCC(ch0, ch1, ch2, ch3) ((ch0) | ((ch1) << 8) | ((ch2) << 16) | ((ch3) << 24)) #define strFOURCC(str) mmioFOURCC((str)[0], (str)[1], (str)[2], (str)[3]) -#ifdef WORDS_BIGENDIAN -#define FIXENDIAN32(a) do { \ - (a) = (((a) & 0xFF00FF00) >> 8) | (((a) & 0x00FF00FF) << 8); \ - (a) = (((a) & 0xFFFF0000) >> 16) | (((a) & 0x0000FFFF) << 16); \ - } while(0) -#define FIXENDIAN16(a) \ - (a) = (((a) & 0xFF00) >> 8) | (((a) & 0x00FF) << 8) -#else -#define FIXENDIAN32(a) do{}while(0) -#define FIXENDIAN16(a) do{}while(0) -#endif - #define FREAD(file, len, var) do { if (fread((var), 1, (len), (file)) != (len)) return err_unexpected_eof; }while(0) typedef struct riff_tree_s { @@ -37,7 +25,7 @@ typedef struct { riff_tree_t * tree; } full_riff_tree_t; -typedef struct __attribute__((packed)) { +typedef struct { uint8_t wFormatTag[2]; uint16_t nChannels; uint32_t nSamplesPerSec; @@ -45,9 +33,9 @@ typedef struct __attribute__((packed)) uint16_t nBlockAlign; uint16_t wBitsPerSample; uint16_t cbSize; -} WAVEFORMATEX; +} audio_header_t; -typedef struct __attribute__((packed)) { +typedef struct { uint32_t biSize; uint32_t biWidth; uint32_t biHeight; @@ -59,9 +47,9 @@ typedef struct __attribute__((packed)) uint32_t biYPelsPerMeter; uint32_t biClrUsed; uint32_t biClrImportant; -} BITMAPINFOHEADER; +} video_header_t; -typedef struct __attribute__((packed)) { +typedef struct { uint32_t dwMicroSecPerFrame; uint32_t dwMaxBytesPerSec; uint32_t dwReserved1; @@ -76,9 +64,9 @@ typedef struct __attribute__((packed)) uint32_t dwRate; uint32_t dwStart; uint32_t dwLength; -} MainAVIHeader; +} avi_header_t; -typedef struct __attribute__((packed)) { +typedef struct { uint8_t fccType[4]; uint8_t fccHandler[4]; uint32_t dwFlags; @@ -92,45 +80,122 @@ typedef struct __attribute__((packed)) uint32_t dwQuality; uint32_t dwSampleSize; uint16_t rcframe[4]; -} AVIStreamHeader; +} avi_stream_header_t; -typedef struct __attribute__((packed)) { +typedef struct { uint8_t ckid[4]; uint32_t dwFlags; uint32_t dwChunkOffset; uint32_t dwChunkLength; -} AVIINDEXENTRY; +} avi_index_entry_t; typedef struct { int type; // 0 video, 1 audio - AVIStreamHeader * strh; // these are all pointers to data - BITMAPINFOHEADER * video; - WAVEFORMATEX * audio; + avi_stream_header_t * strh; + video_header_t * video; + audio_header_t * audio; int extra_len; int last_pts; uint8_t * extra; -} AVIStreamContext; +} avi_stream_context_t; struct demuxer_priv_s { FILE * in; full_riff_tree_t * riff; stream_t * s; - MainAVIHeader * avih; - AVIStreamContext * stream; // this is an array, free this - AVIINDEXENTRY * index; // this is an array and data + avi_header_t * avih; + avi_stream_context_t * stream; // this is an array, free this + avi_index_entry_t * index; // this is an array and data int packets; int cur; }; +#define READ_B(out, ptr, count) do { memcpy(out, ptr, count); ptr += count; } while (0) +#define READ_16(out, ptr) do { out = ((uint8_t*)ptr)[0] | (((uint8_t*)ptr)[1] << 8); ptr += 2; } while (0) +#define READ_32(out, ptr) do { out = ((uint8_t*)ptr)[0] | (((uint8_t*)ptr)[1] << 8) | (((uint8_t*)ptr)[2] << 16) | (((uint8_t*)ptr)[3] << 24); ptr += 4; } while (0) + +static void data_to_audio_header(void * data, audio_header_t * out) { + uint8_t * p = data; + READ_B(out->wFormatTag, p, 2); + READ_16(out->nChannels, p); + READ_32(out->nSamplesPerSec, p); + READ_32(out->nAvgBytesPerSec, p); + READ_16(out->nBlockAlign, p); + READ_16(out->wBitsPerSample, p); + READ_16(out->cbSize, p); +} + +static void data_to_video_header(void * data, video_header_t * out) { + uint8_t * p = data; + READ_32(out->biSize, p); + READ_32(out->biWidth, p); + READ_32(out->biHeight, p); + READ_16(out->biPlanes, p); + READ_16(out->biBitCount, p); + READ_B(out->biCompression, p, 4); + READ_32(out->biSizeImage, p); + READ_32(out->biXPelsPerMeter, p); + READ_32(out->biYPelsPerMeter, p); + READ_32(out->biClrUsed, p); + READ_32(out->biClrImportant, p); +} + +static void data_to_avi_header(void * data, avi_header_t * out) { + uint8_t * p = data; + READ_32(out->dwMicroSecPerFrame, p); + READ_32(out->dwMaxBytesPerSec, p); + READ_32(out->dwReserved1, p); + READ_32(out->dwFlags, p); + READ_32(out->dwTotalFrames, p); + READ_32(out->dwInitialFrames, p); + READ_32(out->dwStreams, p); + READ_32(out->dwSuggestedBufferSize, p); + READ_32(out->dwWidth, p); + READ_32(out->dwHeight, p); + READ_32(out->dwScale, p); + READ_32(out->dwRate, p); + READ_32(out->dwStart, p); + READ_32(out->dwLength, p); +} + +static void data_to_stream_header(void * data, avi_stream_header_t * out) { + uint8_t * p = data; + READ_B(out->fccType, p, 4); + READ_B(out->fccHandler, p, 4); + READ_32(out->dwFlags, p); + READ_32(out->dwReserved1, p); + READ_32(out->dwInitialFrames, p); + READ_32(out->dwScale, p); + READ_32(out->dwRate, p); + READ_32(out->dwStart, p); + READ_32(out->dwLength, p); + READ_32(out->dwSuggestedBufferSize, p); + READ_32(out->dwQuality, p); + READ_32(out->dwSampleSize, p); + READ_16(out->rcframe[0], p); + READ_16(out->rcframe[1], p); + READ_16(out->rcframe[2], p); + READ_16(out->rcframe[3], p); +} + +static void data_to_index_entry(void * data, avi_index_entry_t * out) { + uint8_t * p = data; + READ_B(out->ckid, p, 4); + READ_32(out->dwFlags, p); + READ_32(out->dwChunkOffset, p); + READ_32(out->dwChunkLength, p); +} + static int mk_riff_tree(FILE * in, riff_tree_t * tree) { + char lenc[4], * p = lenc; int left; tree->tree = NULL; tree->data = NULL; tree->amount = 0; tree->offset = ftell(in); FREAD(in, 4, tree->name); - FREAD(in, 4, &tree->len); - FIXENDIAN32(tree->len); + FREAD(in, 4, lenc); + READ_32(tree->len, p); left = tree->len; switch(strFOURCC(tree->name)) { @@ -201,22 +266,21 @@ static void uninit_riff(full_riff_tree_t free(full); } -static int avi_read_stream_header(AVIStreamContext * stream, riff_tree_t * tree) { - int i, j; +static int avi_read_stream_header(avi_stream_context_t * stream, riff_tree_t * tree) { + int i; assert(tree->type == 0); assert(strFOURCC(tree->listname) == mmioFOURCC('s','t','r','l')); for (i = 0; i < tree->amount; i++) { if (tree->tree[i].type == 1 && !strncmp(tree->tree[i].name, "strh", 4)) { if (tree->tree[i].len != 56) return err_avi_bad_strh_len; - stream->strh = (AVIStreamHeader*)tree->tree[i].data; + stream->strh = malloc(sizeof(avi_stream_header_t)); + data_to_stream_header(tree->tree[i].data, stream->strh); break; } } if (i == tree->amount) return err_avi_no_strh; - for(i = 2; i < 12; i++) FIXENDIAN32(((uint32_t*)stream->strh)[i]); - for (i = 0; i < tree->amount; i++) { if (tree->tree[i].type == 1 && !strncmp(tree->tree[i].name, "strf", 4)) { int len = tree->tree[i].len; @@ -224,20 +288,16 @@ static int avi_read_stream_header(AVIStr case mmioFOURCC('v','i','d','s'): if (len < 40) return err_avi_bad_vids_len; stream->type = 0; - stream->video = (BITMAPINFOHEADER*)tree->tree[i].data; - for(j = 0; j < 3; j++) FIXENDIAN32(((uint32_t*)stream->video)[j]); - for(j = 6; j < 8; j++) FIXENDIAN16(((uint16_t*)stream->video)[j]); - for(j = 5; j < 10; j++) FIXENDIAN32(((uint32_t*)stream->video)[j]); + stream->video = malloc(sizeof(video_header_t)); + data_to_video_header(tree->tree[i].data, stream->video); stream->extra_len = len - 40; if (len > 40) stream->extra = (uint8_t*)tree->tree[i].data + 40; break; case mmioFOURCC('a','u','d','s'): if (len < 18) return err_avi_bad_auds_len; stream->type = 1; - stream->audio = (WAVEFORMATEX *)tree->tree[i].data; - for(j = 1; j < 2; j++) FIXENDIAN16(((uint16_t*)stream->audio)[j]); - for(j = 1; j < 3; j++) FIXENDIAN32(((uint32_t*)stream->audio)[j]); - for(j = 6; j < 9; j++) FIXENDIAN16(((uint16_t*)stream->audio)[j]); + stream->audio = malloc(sizeof(audio_header_t)); + data_to_audio_header(tree->tree[i].data, stream->audio); stream->extra_len = len - 18; if (len > 18) stream->extra = (uint8_t*)tree->tree[i].data + 18; break; @@ -260,16 +320,15 @@ static int avi_read_main_header(demuxer_ for (i = 0; i < tree->amount; i++) { if (tree->tree[i].type == 1 && !strncmp(tree->tree[i].name, "avih", 4)) { if (tree->tree[i].len != 56) return err_avi_bad_avih_len; - avi->avih = (MainAVIHeader*)tree->tree[i].data; + avi->avih = malloc(sizeof(avi_header_t)); + data_to_avi_header(tree->tree[i].data, avi->avih); break; } } if (i == tree->amount) return err_avi_no_avih; - for(i = 0; i < 14; i++) FIXENDIAN32(((uint32_t*)avi->avih)[i]); - if (avi->avih->dwStreams > 200) return err_avi_stream_overflow; - avi->stream = malloc(avi->avih->dwStreams * sizeof(AVIStreamContext)); + avi->stream = malloc(avi->avih->dwStreams * sizeof(avi_stream_context_t)); for (i = 0; i < avi->avih->dwStreams; i++) { avi->stream[i].video = NULL; avi->stream[i].audio = NULL; @@ -302,16 +361,14 @@ static int avi_read_headers(demuxer_priv } if (i == tree->amount) return err_avi_no_hdrl; for (i = 0; i < avi->riff->amount; i++) { - int j; + int j, ii; tree = &avi->riff->tree[i]; for (j = 0; j < tree->amount; j++) { if (tree->tree[j].type == 1 && !strncmp(tree->tree[j].name, "idx1", 4)) { - avi->index = (AVIINDEXENTRY *)tree->tree[j].data; avi->packets = tree->tree[j].len / 16; - for (i = 0; i < avi->packets; i++) { - FIXENDIAN32(avi->index[i].dwFlags); - FIXENDIAN32(avi->index[i].dwChunkOffset); - FIXENDIAN32(avi->index[i].dwChunkLength); + avi->index = calloc(avi->packets, sizeof(avi_index_entry_t)); + for (ii = 0; ii < avi->packets; ii++) { + data_to_index_entry((char*)tree->tree[j].data + 16*ii, avi->index + ii); } break; } @@ -395,16 +452,16 @@ static int read_headers(demuxer_priv_t * } static int fill_buffer(demuxer_priv_t * avi) { - char fourcc[4]; - uint32_t len; + char fourcc[4], lenc[4], * plen = lenc; + int len; packet_t p; if (ftell(avi->in) & 1) fgetc(avi->in); if (avi->cur >= avi->packets) return -1; FREAD(avi->in, 4, fourcc); - FREAD(avi->in, 4, &len); - FIXENDIAN32(len); + FREAD(avi->in, 4, lenc); + READ_32(len, plen); p.p.len = len; p.p.flags = (avi->index[avi->cur++].dwFlags & 0x10) ? NUT_FLAG_KEY : 0; p.p.stream = (fourcc[0] - '0') * 10 + (fourcc[1] - '0'); @@ -443,8 +500,16 @@ static demuxer_priv_t * init(FILE * in) } static void uninit(demuxer_priv_t * avi) { + int i, streams = avi->avih ? avi->avih->dwStreams : 0; uninit_riff(avi->riff); + if (avi->stream) for (i = 0; i < streams; i++) { + free(avi->stream[i].strh); + free(avi->stream[i].video); + free(avi->stream[i].audio); + } free(avi->stream); + free(avi->avih); + free(avi->index); free_streams(avi->s); free(avi->s); free(avi);