diff -Naur lavtools.org/lavaddwav.c lavtools/lavaddwav.c --- lavtools.org/lavaddwav.c 2003-02-08 23:33:16.000000000 +0100 +++ lavtools/lavaddwav.c 2005-07-31 07:52:45.000000000 +0200 @@ -155,7 +155,7 @@ } lav_out = lav_open_output_file(argv[3], - lav_filetype(lav_fd), + lav_fd->format, lav_video_width (lav_fd), lav_video_height(lav_fd), lav_video_interlacing(lav_fd), diff -Naur lavtools.org/lav_io.c lavtools/lav_io.c --- lavtools.org/lav_io.c 2003-11-17 20:28:53.000000000 +0100 +++ lavtools/lav_io.c 2005-07-31 07:57:38.000000000 +0200 @@ -36,7 +36,8 @@ #endif #ifdef HAVE_LIBQUICKTIME -#include +#include +#include #endif extern int AVI_errno; @@ -275,6 +276,7 @@ int asize, int achans, long arate) { lav_file_t *lav_fd = (lav_file_t*) malloc(sizeof(lav_file_t)); + char *extension, *tempfile; if(lav_fd==0) { internal_error=ERROR_MALLOC; return 0; } @@ -284,28 +286,43 @@ lav_fd->qt_fd = 0; lav_fd->format = format; /* Sanity check: do not create a quicktime file that is named with .avi */ - if(rindex(filename, '.') != NULL) + extension = rindex(filename, '.'); + if (extension != NULL) { - if((format == 'a' || format == 'A') && strcmp(rindex(filename, '.')+1, "avi")) { - internal_error = ERROR_FORMAT; - return 0; - } - if(format == 'q' && (strcmp(rindex(filename, '.')+1, "qt") - && strcmp(rindex(filename, '.')+1, "mov") && strcmp(rindex(filename, '.')+1,"moov"))) { - internal_error = ERROR_FORMAT; - return 0; - } - if(format == 'j' && strcmp(rindex(filename, '.')+1, "jpg") - && strcmp(rindex(filename, '.')+1, "jpeg")) { - internal_error = ERROR_FORMAT; - return 0; - } + extension++; + switch(format) + { + case 'a': + case 'A': + if (strcmp(extension, "avi") && strcmp(extension, "AVI")) + { + internal_error = ERROR_FORMAT; + return 0; + } + break; + case 'q': + if (strcmp(extension, "qt") && strcmp(extension, "QT") && + strcmp(extension, "mov") && strcmp(extension, "MOV") && + strcmp(extension,"moov") && strcmp(extension,"MOOV")) + { + internal_error = ERROR_FORMAT; + return 0; + } + break; + case 'j': + if (strcmp(extension, "jpg") && strcmp(extension, "jpg") && + strcmp(extension,"jpeg") && strcmp(extension,"JPEG")) + { + internal_error = ERROR_FORMAT; + return 0; + } + break; + } } lav_fd->interlacing = interlaced ? lav_query_polarity(format) : LAV_NOT_INTERLACED; lav_fd->has_audio = (asize>0 && achans>0); lav_fd->bps = (asize*achans+7)/8; - lav_fd->is_MJPG = 1; lav_fd->MJPG_chroma = CHROMAUNKNOWN; switch(format) @@ -321,21 +338,22 @@ if (asize) AVI_set_audio(lav_fd->avi_fd, achans, arate, asize, WAVE_FORMAT_PCM); return lav_fd; - case 'j': { - + case 'j': /* Open JPEG output file */ - char tempfile[256]; - + tempfile = (char *)malloc(strlen(filename) + strlen(TMP_EXTENSION) + 1); + if (tempfile == NULL) + { + internal_error=ERROR_MALLOC; + return(0); + } strcpy(tempfile, filename); strcat(tempfile, TMP_EXTENSION); - lav_fd->jpeg_filename = strdup(filename); lav_fd->jpeg_fd = open(tempfile, O_CREAT | O_TRUNC | O_WRONLY, 0644); - + free(tempfile); return lav_fd; - } - case 'q': + case 'q': #ifdef HAVE_LIBQUICKTIME /* open quicktime output file */ @@ -364,26 +382,33 @@ } int lav_close(lav_file_t *lav_file) -{ + { int res; + char *tempfile; video_format = lav_file->format; internal_error = 0; /* for error messages */ - switch(lav_file->format) - { + switch (lav_file->format) + { case 'a': case 'A': res = AVI_close( lav_file->avi_fd ); break; - case 'j': { - char tempfile[256]; + case 'j': + tempfile = (char *)malloc(strlen(lav_file->jpeg_filename) + + strlen(TMP_EXTENSION) + 1); + if (tempfile == NULL) + { + res = -1; + break; + } strcpy(tempfile, lav_file->jpeg_filename); strcat(tempfile, TMP_EXTENSION); res = close(lav_file->jpeg_fd); rename(tempfile, lav_file->jpeg_filename); + free(tempfile); free(lav_file->jpeg_filename); break; - } #ifdef HAVE_LIBQUICKTIME case 'q': res = quicktime_close( lav_file->qt_fd ); @@ -391,12 +416,10 @@ #endif default: res = -1; - } - + } free(lav_file); - return res; -} + } int lav_write_frame(lav_file_t *lav_file, uint8_t *buff, long size, long count) { @@ -523,10 +546,12 @@ int lav_write_audio(lav_file_t *lav_file, uint8_t *buff, long samps) { - int res; -#ifdef HAVE_LIBQUICKTIME - int n, nb; - uint8_t *hbuff; + int res = -1; +#ifdef HAVE_LIBQUICKTIME + int i, j; + int16_t *buff16 = (int16_t *)buff, **qt_audion; + int channels = lav_audio_channels(lav_file); + int bits = lav_audio_bits(lav_file); #endif video_format = lav_file->format; internal_error = 0; /* for error messages */ @@ -535,33 +560,48 @@ { case 'a': case 'A': - res = AVI_write_audio( lav_file->avi_fd, buff, samps*lav_file->bps); + res = AVI_write_audio(lav_file->avi_fd, buff, samps * lav_file->bps); break; #ifdef HAVE_LIBQUICKTIME case 'q': - if(lav_audio_bits(lav_file)==16) - { - nb = samps*2*lav_audio_channels(lav_file); - hbuff = (uint8_t *) malloc(nb); - if(!hbuff) { internal_error=ERROR_MALLOC; return -1; } - for(n=0;nqt_fd, (char*)hbuff, samps, 0 ); - free(hbuff); - } - else - res = quicktime_write_audio( lav_file->qt_fd, (char*)buff, samps, 0 ); - break; + if (bits != 16 || channels > 1) + { + /* Deinterleave the audio into the two channels and/or convert + * bits per sample to the required format. + */ + qt_audion = malloc(channels * sizeof(*qt_audion)); + for (i = 0; i < channels; i++) + qt_audion[i] = malloc(samps * sizeof(**qt_audion)); + + if (bits == 16) + for (i = 0; i < samps; i++) + for (j = 0; j < channels; j++) + qt_audion[j][i] = buff16[channels * i + j]; + else + if (bits == 8) + for (i = 0; i < samps; i++) + for (j = 0; j < channels; j++) + qt_audion[j][i] = ((int16_t)(buff[channels * i + j]) << 8) ^ 0x8000; + + if (bits == 8 || bits == 16) + res = lqt_encode_audio_track(lav_file->qt_fd, qt_audion, NULL, samps, 0); + + for (i = 0; i < channels; i++) + free(qt_audion[i]); + free(qt_audion); + } else { + qt_audion = &buff16; + res = lqt_encode_audio_track(lav_file->qt_fd, qt_audion, NULL, samps, 0); + } + break; #endif default: - res = -1; + break; } return res; } - - long lav_video_frames(lav_file_t *lav_file) { video_format = lav_file->format; internal_error = 0; /* for error messages */ @@ -638,17 +678,11 @@ return; } -int lav_video_is_MJPG(lav_file_t *lav_file) -{ - return lav_file->is_MJPG; -} - int lav_video_MJPG_chroma(lav_file_t *lav_file) { return lav_file->MJPG_chroma; } - const char *lav_video_compressor(lav_file_t *lav_file) { video_format = lav_file->format; internal_error = 0; /* for error messages */ @@ -797,7 +831,6 @@ return -1; } - int lav_set_audio_position(lav_file_t *lav_file, long sample) { if(!lav_file->has_audio) return 0; @@ -809,7 +842,7 @@ return AVI_set_audio_position(lav_file->avi_fd,sample*lav_file->bps); #ifdef HAVE_LIBQUICKTIME case 'q': - return quicktime_set_audio_position(lav_file->qt_fd,sample,0); + quicktime_set_audio_position(lav_file->qt_fd,sample,0); #endif } return -1; @@ -818,13 +851,17 @@ long lav_read_audio(lav_file_t *lav_file, uint8_t *audbuf, long samps) { #ifdef HAVE_LIBQUICKTIME - long res, n, t; + int64_t last_pos, start_pos; + int res, i, j; + int16_t *audbuf16 = (int16_t *)audbuf, **qt_audion; + int channels = lav_audio_channels(lav_file); + int bits = lav_audio_bits(lav_file); #endif if(!lav_file->has_audio) { internal_error = ERROR_NOAUDIO; - return -1; + return(-1); } video_format = lav_file->format; internal_error = 0; /* for error messages */ switch(lav_file->format) @@ -834,28 +871,48 @@ return AVI_read_audio(lav_file->avi_fd,audbuf,samps*lav_file->bps)/lav_file->bps; #ifdef HAVE_LIBQUICKTIME case 'q': - res = quicktime_read_audio(lav_file->qt_fd,(char*)audbuf,samps,0)/lav_file->bps; - if(res<=0) return res; - if(lav_audio_bits(lav_file)==16) - { - for(n=0;n 1) + { + qt_audion = malloc(channels * sizeof(*qt_audion)); + for (i = 0; i < channels; i++) + qt_audion[i] = malloc(samps * sizeof(**qt_audion)); + } else { + qt_audion = &audbuf16; + } + + start_pos = quicktime_audio_position(lav_file->qt_fd, 0); + lqt_decode_audio_track(lav_file->qt_fd, qt_audion, NULL, samps, 0); + last_pos = lqt_last_audio_position(lav_file->qt_fd, 0); + res = last_pos - start_pos; + + if (res > 0 && (bits != 16 || channels > 1)) + { + /* Interleave the channels of audio into the one buffer provided + * and/or convert bits per sample to the required format. + */ + if (bits == 16) + for (i = 0; i < res; i++) + for (j = 0; j < channels; j++) + audbuf16[channels * i + j] = qt_audion[j][i]; + else + if (bits == 8) + for (i = 0; i < res; i++) + for (j = 0; j < channels; j++) + audbuf[channels * i + j] = (qt_audion[j][i] >> 8) + 0x80; + } + + if (bits != 16 || channels > 1) + { + for (i = 0; i < channels; i++) + free(qt_audion[i]); + free(qt_audion); + } + return res; #endif } return -1; } -int lav_filetype(lav_file_t *lav_file) -{ - return lav_file->format; -} - lav_file_t *lav_open_input_file(char *filename) { int n; @@ -878,11 +935,10 @@ lav_fd->qt_fd = 0; lav_fd->format = 0; lav_fd->interlacing = LAV_INTER_UNKNOWN; - lav_fd->sar_w = 0; /* (0,0) == unknown */ - lav_fd->sar_h = 0; + lav_fd->sar_w = 1; /* unknown - assume square pixels */ + lav_fd->sar_h = 1; lav_fd->has_audio = 0; lav_fd->bps = 0; - lav_fd->is_MJPG = 0; lav_fd->MJPG_chroma = CHROMAUNKNOWN; /* open video file, try AVI first */ @@ -1010,8 +1066,6 @@ return lav_fd; } - lav_fd->is_MJPG = 1; - /* Make some checks on the video source, we read the first frame for that */ ierr = 0; @@ -1200,8 +1254,6 @@ } } - - #ifdef HAVE_LIBDV static int check_DV2_input(lav_file_t *lav_fd) { @@ -1209,8 +1261,6 @@ double len = 0; unsigned char *frame = NULL; - lav_fd->is_MJPG = 0; - /* Make some checks on the video source, we read the first frame for that */ if ( lav_set_video_position(lav_fd,0) ) goto ERREXIT; @@ -1261,16 +1311,12 @@ } #endif - - static int check_YUV420_input(lav_file_t *lav_fd) { int ierr = 0; double len = 0; unsigned char *frame = NULL; - lav_fd->is_MJPG = 0; - /* Make some checks on the video source, we read the first frame for that */ if ( lav_set_video_position(lav_fd,0) ) goto ERREXIT; @@ -1312,17 +1358,3 @@ return res; } - - - - - - - - - - - - - - diff -Naur lavtools.org/lav_io.h lavtools/lav_io.h --- lavtools.org/lav_io.h 2003-11-15 04:36:17.000000000 +0100 +++ lavtools/lav_io.h 2005-07-31 07:52:45.000000000 +0200 @@ -24,7 +24,7 @@ typedef void avi_t; #endif -#include "yuv4mpeg.h" +#include #define LAV_INTER_UNKNOWN Y4M_UNKNOWN #define LAV_NOT_INTERLACED Y4M_ILACE_NONE @@ -88,7 +88,6 @@ int lav_read_frame(lav_file_t *lav_file, uint8_t *vidbuf); int lav_set_audio_position(lav_file_t *lav_file, long sample); long lav_read_audio(lav_file_t *lav_file, uint8_t *audbuf, long samps); -int lav_filetype(lav_file_t *lav_file); lav_file_t *lav_open_input_file(char *filename); int lav_get_field_size(uint8_t * jpegdata, long jpeglen); const char *lav_strerror(void);