static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt ) { raw_hnd_t *h = (raw_hnd_t*)malloc( sizeof(raw_hnd_t) ); if( !h ) return -1; if( !opt->resolution ) { /* try to parse the file name */ for( char *p = psz_filename; *p; p++ ) if( *p >= '0' && *p <= '9' && sscanf( p, "%ux%u", &info->width, &info->height ) == 2 ) break; } else sscanf( opt->resolution, "%ux%u", &info->width, &info->height ); FAIL_IF_ERROR( !info->width || !info->height, "raw input requires a resolution.\n" ) if( opt->colorspace ) { for( info->csp = X264_CSP_CLI_MAX-1; x264_cli_csps[info->csp].name && strcasecmp( x264_cli_csps[info->csp].name, opt->colorspace ); ) info->csp--; FAIL_IF_ERROR( info->csp == X264_CSP_NONE, "unsupported colorspace `%s'\n", opt->colorspace ); } else /* default */ info->csp = X264_CSP_I420; h->next_frame = 0; info->vfr = 0; if( !strcmp( psz_filename, "-" ) ) h->fh = stdin; else h->fh = fopen( psz_filename, "rb" ); if( h->fh == NULL ) return -1; info->thread_safe = 1; info->num_frames = 0; h->frame_size = 0; for( int i = 0; i < x264_cli_csps[info->csp].planes; i++ ) { h->plane_size[i] = x264_cli_pic_plane_size( info->csp, info->width, info->height, i ); h->frame_size += h->plane_size[i]; } if( x264_is_regular_file( h->fh ) ) { fseek( h->fh, 0, SEEK_END ); uint64_t size = ftell( h->fh ); fseek( h->fh, 0, SEEK_SET ); info->num_frames = size / h->frame_size; } *p_handle = h; return 0; }
uint64_t x264_cli_pic_size( int csp, int width, int height ) { if( x264_cli_csp_is_invalid( csp ) ) return 0; uint64_t size = 0; int csp_mask = csp & X264_CSP_MASK; for( int i = 0; i < x264_cli_csps[csp_mask].planes; i++ ) size += x264_cli_pic_plane_size( csp, width, height, i ); return size; }
int x264_cli_pic_alloc( cli_pic_t *pic, int csp, int width, int height ) { memset( pic, 0, sizeof(cli_pic_t) ); int csp_mask = csp & X264_CSP_MASK; if( x264_cli_csp_is_invalid( csp ) ) pic->img.planes = 0; else pic->img.planes = x264_cli_csps[csp_mask].planes; pic->img.csp = csp; pic->img.width = width; pic->img.height = height; for( int i = 0; i < pic->img.planes; i++ ) { pic->img.plane[i] = x264_malloc( x264_cli_pic_plane_size( csp, width, height, i ) ); if( !pic->img.plane[i] ) return -1; pic->img.stride[i] = width * x264_cli_csps[csp_mask].width[i]; } return 0; }
static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt ) { raw_hnd_t *h = calloc( 1, sizeof(raw_hnd_t) ); if( !h ) return -1; if( !opt->resolution ) { /* try to parse the file name */ for( char *p = psz_filename; *p; p++ ) if( *p >= '0' && *p <= '9' && sscanf( p, "%dx%d", &info->width, &info->height ) == 2 ) break; } else sscanf( opt->resolution, "%dx%d", &info->width, &info->height ); FAIL_IF_ERROR( !info->width || !info->height, "raw input requires a resolution.\n" ) if( opt->colorspace ) { for( info->csp = X264_CSP_CLI_MAX-1; info->csp > X264_CSP_NONE; info->csp-- ) { if( x264_cli_csps[info->csp].name && !strcasecmp( x264_cli_csps[info->csp].name, opt->colorspace ) ) break; } FAIL_IF_ERROR( info->csp == X264_CSP_NONE, "unsupported colorspace `%s'\n", opt->colorspace ); } else /* default */ info->csp = X264_CSP_I420; h->bit_depth = opt->bit_depth; FAIL_IF_ERROR( h->bit_depth < 8 || h->bit_depth > 16, "unsupported bit depth `%d'\n", h->bit_depth ); if( h->bit_depth > 8 ) info->csp |= X264_CSP_HIGH_DEPTH; if( !strcmp( psz_filename, "-" ) ) h->fh = stdin; else h->fh = x264_fopen( psz_filename, "rb" ); if( h->fh == NULL ) return -1; info->thread_safe = 1; info->num_frames = 0; info->vfr = 0; const x264_cli_csp_t *csp = x264_cli_get_csp( info->csp ); for( int i = 0; i < csp->planes; i++ ) { h->plane_size[i] = x264_cli_pic_plane_size( info->csp, info->width, info->height, i ); h->frame_size += h->plane_size[i]; /* x264_cli_pic_plane_size returns the size in bytes, we need the value in pixels from here on */ h->plane_size[i] /= x264_cli_csp_depth_factor( info->csp ); } if( x264_is_regular_file( h->fh ) ) { fseek( h->fh, 0, SEEK_END ); uint64_t size = ftell( h->fh ); fseek( h->fh, 0, SEEK_SET ); info->num_frames = size / h->frame_size; /* Attempt to use memory-mapped input frames if possible */ if( !(h->bit_depth & 7) ) h->use_mmap = !x264_cli_mmap_init( &h->mmap, h->fh ); } *p_handle = h; return 0; }
static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt ) { y4m_hnd_t *h = malloc( sizeof(y4m_hnd_t) ); int i; uint32_t n, d; char header[MAX_YUV4_HEADER+10]; char *tokend, *header_end; int colorspace = X264_CSP_NONE; int alt_colorspace = X264_CSP_NONE; int alt_bit_depth = 8; if( !h ) return -1; h->next_frame = 0; info->vfr = 0; if( !strcmp( psz_filename, "-" ) ) h->fh = stdin; else h->fh = fopen(psz_filename, "rb"); if( h->fh == NULL ) return -1; h->frame_header_len = strlen( Y4M_FRAME_MAGIC )+1; /* Read header */ for( i = 0; i < MAX_YUV4_HEADER; i++ ) { header[i] = fgetc( h->fh ); if( header[i] == '\n' ) { /* Add a space after last option. Makes parsing "444" vs "444alpha" easier. */ header[i+1] = 0x20; header[i+2] = 0; break; } } if( i == MAX_YUV4_HEADER || strncmp( header, Y4M_MAGIC, strlen( Y4M_MAGIC ) ) ) return -1; /* Scan properties */ header_end = &header[i+1]; /* Include space */ h->seq_header_len = i+1; for( char *tokstart = &header[strlen( Y4M_MAGIC )+1]; tokstart < header_end; tokstart++ ) { if( *tokstart == 0x20 ) continue; switch( *tokstart++ ) { case 'W': /* Width. Required. */ info->width = strtol( tokstart, &tokend, 10 ); tokstart=tokend; break; case 'H': /* Height. Required. */ info->height = strtol( tokstart, &tokend, 10 ); tokstart=tokend; break; case 'C': /* Color space */ colorspace = parse_csp_and_depth( tokstart, &h->bit_depth ); tokstart = strchr( tokstart, 0x20 ); break; case 'I': /* Interlace type */ switch( *tokstart++ ) { case 't': info->interlaced = 1; info->tff = 1; break; case 'b': info->interlaced = 1; info->tff = 0; break; case 'm': info->interlaced = 1; break; //case '?': //case 'p': default: break; } break; case 'F': /* Frame rate - 0:0 if unknown */ if( sscanf( tokstart, "%u:%u", &n, &d ) == 2 && n && d ) { x264_reduce_fraction( &n, &d ); info->fps_num = n; info->fps_den = d; } tokstart = strchr( tokstart, 0x20 ); break; case 'A': /* Pixel aspect - 0:0 if unknown */ /* Don't override the aspect ratio if sar has been explicitly set on the commandline. */ if( sscanf( tokstart, "%u:%u", &n, &d ) == 2 && n && d ) { x264_reduce_fraction( &n, &d ); info->sar_width = n; info->sar_height = d; } tokstart = strchr( tokstart, 0x20 ); break; case 'X': /* Vendor extensions */ if( !strncmp( "YSCSS=", tokstart, 6 ) ) { /* Older nonstandard pixel format representation */ tokstart += 6; alt_colorspace = parse_csp_and_depth( tokstart, &alt_bit_depth ); } tokstart = strchr( tokstart, 0x20 ); break; } } if( colorspace == X264_CSP_NONE ) { colorspace = alt_colorspace; h->bit_depth = alt_bit_depth; } // default to 8bit 4:2:0 if nothing is specified if( colorspace == X264_CSP_NONE ) { colorspace = X264_CSP_I420; h->bit_depth = 8; } FAIL_IF_ERROR( colorspace <= X264_CSP_NONE || colorspace >= X264_CSP_MAX, "colorspace unhandled\n" ) FAIL_IF_ERROR( h->bit_depth < 8 || h->bit_depth > 16, "unsupported bit depth `%d'\n", h->bit_depth ); info->thread_safe = 1; info->num_frames = 0; info->csp = colorspace; h->frame_size = h->frame_header_len; if( h->bit_depth > 8 ) info->csp |= X264_CSP_HIGH_DEPTH; const x264_cli_csp_t *csp = x264_cli_get_csp( info->csp ); for( i = 0; i < csp->planes; i++ ) { h->plane_size[i] = x264_cli_pic_plane_size( info->csp, info->width, info->height, i ); h->frame_size += h->plane_size[i]; /* x264_cli_pic_plane_size returns the size in bytes, we need the value in pixels from here on */ h->plane_size[i] /= x264_cli_csp_depth_factor( info->csp ); } /* Most common case: frame_header = "FRAME" */ if( x264_is_regular_file( h->fh ) ) { uint64_t init_pos = ftell( h->fh ); fseek( h->fh, 0, SEEK_END ); uint64_t i_size = ftell( h->fh ); fseek( h->fh, init_pos, SEEK_SET ); info->num_frames = (i_size - h->seq_header_len) / h->frame_size; } *p_handle = h; return 0; }