/*****************************************************************************
* muxers.c: h264 file i/o plugins
*****************************************************************************
- * Copyright (C) 2003-2006 x264 project
+ * Copyright (C) 2003-2008 x264 project
+ *
+ * Authors: Laurent Aimar <fenrir@via.ecp.fr>
+ * Loren Merritt <lorenm@u.washington.edu>
*
* 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
*
* 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, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
*****************************************************************************/
-#define _LARGEFILE_SOURCE
-#define _FILE_OFFSET_BITS 64
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
#include "common/common.h"
#include "x264.h"
#include "matroska.h"
#include "config.h"
#endif
+#include <sys/types.h>
+
#ifdef AVIS_INPUT
#include <windows.h>
#include <vfw.h>
#include <gpac/isomedia.h>
#endif
+static int64_t gcd( int64_t a, int64_t b )
+{
+ while (1)
+ {
+ int64_t c = a % b;
+ if( !c )
+ return b;
+ a = b;
+ b = c;
+ }
+}
+
typedef struct {
FILE *fh;
int width, height;
yuv_input_t *h = handle;
if( !h || !h->fh )
return 0;
- return fclose(h->fh);
+ fclose( h->fh );
+ free( h );
+ return 0;
}
/* YUV4MPEG2 raw 420 yuv file operation */
tokstart = strchr(tokstart, 0x20);
break;
case 'A': /* Pixel aspect - 0:0 if unknown */
- if( sscanf(tokstart, "%d:%d", &n, &d) == 2 && n && d )
+ /* Don't override the aspect ratio if sar has been explicitly set on the commandline. */
+ if( sscanf(tokstart, "%d:%d", &n, &d) == 2 && n && d && !p_param->vui.i_sar_width && !p_param->vui.i_sar_height )
{
x264_reduce_fraction( &n, &d );
p_param->vui.i_sar_width = n;
{
y4m_input_t *h = handle;
int i_frame_total = 0;
- off_t init_pos = ftell(h->fh);
+ uint64_t init_pos = ftell(h->fh);
if( !fseek( h->fh, 0, SEEK_END ) )
{
/* Read frame header - without terminating '\n' */
if (fread(header, 1, slen, h->fh) != slen)
return -1;
-
+
header[slen] = 0;
if (strncmp(header, Y4M_FRAME_MAGIC, slen))
{
- fprintf(stderr, "Bad header magic (%08X <=> %s)\n",
+ fprintf(stderr, "Bad header magic (%"PRIx32" <=> %s)\n",
*((uint32_t*)header), header);
return -1;
}
-
+
/* Skip most of it */
while (i<MAX_FRAME_HEADER && fgetc(h->fh) != '\n')
i++;
y4m_input_t *h = handle;
if( !h || !h->fh )
return 0;
- return fclose(h->fh);
+ fclose( h->fh );
+ free( h );
+ return 0;
}
/* avs/avi input file support under cygwin */
int width, height;
} avis_input_t;
-int gcd(int a, int b)
-{
- int c;
-
- while (1)
- {
- c = a % b;
- if (!c)
- return b;
- a = b;
- b = c;
- }
-}
-
int open_file_avis( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param )
{
avis_input_t *h = malloc(sizeof(avis_input_t));
int (*p_close_infile)( hnd_t handle );
hnd_t p_handle;
x264_picture_t pic;
- pthread_t tid;
+ x264_pthread_t tid;
int next_frame;
int frame_total;
+ int in_progress;
struct thread_input_arg_t *next_args;
} thread_input_t;
h->p_read_frame = p_read_frame;
h->p_close_infile = p_close_infile;
h->p_handle = *p_handle;
+ h->in_progress = 0;
h->next_frame = -1;
h->next_args = malloc(sizeof(thread_input_arg_t));
h->next_args->h = h;
return h->frame_total;
}
-void read_frame_thread_int( thread_input_arg_t *i )
+static void read_frame_thread_int( thread_input_arg_t *i )
{
i->status = i->h->p_read_frame( i->pic, i->h->p_handle, i->i_frame );
}
if( h->next_frame >= 0 )
{
- pthread_join( h->tid, &stuff );
+ x264_pthread_join( h->tid, &stuff );
ret |= h->next_args->status;
+ h->in_progress = 0;
}
if( h->next_frame == i_frame )
h->next_frame =
h->next_args->i_frame = i_frame+1;
h->next_args->pic = &h->pic;
- pthread_create( &h->tid, NULL, (void*)read_frame_thread_int, h->next_args );
+ x264_pthread_create( &h->tid, NULL, (void*)read_frame_thread_int, h->next_args );
+ h->in_progress = 1;
}
else
h->next_frame = -1;
thread_input_t *h = handle;
h->p_close_infile( h->p_handle );
x264_picture_clean( &h->pic );
+ if( h->in_progress )
+ x264_pthread_join( h->tid, NULL );
+ free( h->next_args );
free( h );
return 0;
}
} mp4_t;
-void recompute_bitrate_mp4(GF_ISOFile *p_file, int i_track)
+static void recompute_bitrate_mp4(GF_ISOFile *p_file, int i_track)
{
u32 i, count, di, timescale, time_wnd, rate;
u64 offset;
gf_isom_set_visual_info(p_mp4->p_file, p_mp4->i_track, p_mp4->i_descidx,
p_param->i_width, p_param->i_height);
+ if( p_param->vui.i_sar_width && p_param->vui.i_sar_height )
+ {
+ uint64_t dw = p_param->i_width << 16;
+ uint64_t dh = p_param->i_height << 16;
+ double sar = (double)p_param->vui.i_sar_width / p_param->vui.i_sar_height;
+ if( sar > 1.0 )
+ dw *= sar ;
+ else
+ dh /= sar;
+ gf_isom_set_track_layout_info( p_mp4->p_file, p_mp4->i_track, dw, dh, 0, 0, 0 );
+ }
+
p_mp4->p_sample->data = (char *)malloc(p_param->i_width * p_param->i_height * 3 / 2);
if (p_mp4->p_sample->data == NULL)
return -1;
char b_writing_frame;
} mkv_t;
-int write_header_mkv( mkv_t *p_mkv )
+static int write_header_mkv( mkv_t *p_mkv )
{
int ret;
uint8_t *avcC;
if( dw > 0 && dh > 0 )
{
- int64_t a = dw, b = dh;
-
- for (;;)
- {
- int64_t c = a % b;
- if( c == 0 )
- break;
- a = b;
- b = c;
- }
-
- dw /= b;
- dh /= b;
+ int64_t x = gcd( dw, dh );
+ dw /= x;
+ dh /= x;
}
p_mkv->d_width = (int)dw;