10 /* YUV4MPEG2 raw 420 yuv file operation */
14 int par_width
, par_height
;
16 int seq_header_len
, frame_header_len
;
22 #define Y4M_MAGIC "YUV4MPEG2"
23 #define MAX_YUV4_HEADER 80
24 #define Y4M_FRAME_MAGIC "FRAME"
25 #define MAX_FRAME_HEADER 80
27 int open_file_y4m( char *psz_filename
, hnd_t
*p_handle
)
31 char header
[MAX_YUV4_HEADER
+10];
32 char *tokstart
, *tokend
, *header_end
;
33 y4m_input_t
*h
= calloc(1, sizeof(*h
));
37 if( !strcmp(psz_filename
, "-") )
40 h
->fh
= fopen(psz_filename
, "rb");
44 h
->frame_header_len
= strlen(Y4M_FRAME_MAGIC
)+1;
47 for( i
=0; i
<MAX_YUV4_HEADER
; i
++ )
49 header
[i
] = fgetc(h
->fh
);
50 if( header
[i
] == '\n' )
52 /* Add a space after last option. Makes parsing "444" vs
59 if( i
== MAX_YUV4_HEADER
|| strncmp(header
, Y4M_MAGIC
, strlen(Y4M_MAGIC
)) )
63 header_end
= &header
[i
+1]; /* Include space */
64 h
->seq_header_len
= i
+1;
65 for( tokstart
= &header
[strlen(Y4M_MAGIC
)+1]; tokstart
< header_end
; tokstart
++ )
67 if(*tokstart
==0x20) continue;
70 case 'W': /* Width. Required. */
71 h
->width
= strtol(tokstart
, &tokend
, 10);
74 case 'H': /* Height. Required. */
75 h
->height
= strtol(tokstart
, &tokend
, 10);
78 case 'C': /* Color space */
79 if( strncmp("420", tokstart
, 3) )
81 fprintf(stderr
, "Colorspace unhandled\n");
84 tokstart
= strchr(tokstart
, 0x20);
86 case 'I': /* Interlace type */
89 case 'p': interlaced
= 0; break;
94 default: interlaced
= 1;
95 fprintf(stderr
, "Warning, this sequence might be interlaced\n");
98 case 'F': /* Frame rate - 0:0 if unknown */
99 /* Frame rate in unimportant. */
100 if( sscanf(tokstart
, "%d:%d", &n
, &d
) == 2 && n
&& d
)
102 reduce_fraction( &n
, &d
);
106 tokstart
= strchr(tokstart
, 0x20);
108 case 'A': /* Pixel aspect - 0:0 if unknown */
109 /* Don't override the aspect ratio if sar has been explicitly set on the commandline. */
110 if( sscanf(tokstart
, "%d:%d", &n
, &d
) == 2 && n
&& d
)
112 reduce_fraction( &n
, &d
);
116 tokstart
= strchr(tokstart
, 0x20);
118 case 'X': /* Vendor extensions */
119 if( !strncmp("YSCSS=",tokstart
,6) )
121 /* Older nonstandard pixel format representation */
123 if( strncmp("420JPEG",tokstart
,7) &&
124 strncmp("420MPEG2",tokstart
,8) &&
125 strncmp("420PALDV",tokstart
,8) )
127 fprintf(stderr
, "Unsupported extended colorspace\n");
131 tokstart
= strchr(tokstart
, 0x20);
136 fprintf(stderr
, "yuv4mpeg: %ix%i@%i/%ifps, %i:%i\n",
137 h
->width
, h
->height
, h
->fps_num
, h
->fps_den
,
138 h
->par_width
, h
->par_height
);
140 *p_handle
= (hnd_t
)h
;
144 int read_frame_y4m( hnd_t handle
, picture_t
*p_pic
, int i_frame
)
146 int slen
= strlen(Y4M_FRAME_MAGIC
);
149 y4m_input_t
*h
= handle
;
151 if( i_frame
!= h
->next_frame
)
153 if (fseek(h
->fh
, (uint64_t)i_frame
*(3*(h
->width
*h
->height
)/2+h
->frame_header_len
)
154 + h
->seq_header_len
, SEEK_SET
))
158 /* Read frame header - without terminating '\n' */
159 if (fread(header
, 1, slen
, h
->fh
) != slen
)
163 if (strncmp(header
, Y4M_FRAME_MAGIC
, slen
))
165 fprintf(stderr
, "Bad header magic (%"PRIx32
" <=> %s)\n",
166 *((uint32_t*)header
), header
);
170 /* Skip most of it */
171 while (i
<MAX_FRAME_HEADER
&& fgetc(h
->fh
) != '\n')
173 if (i
== MAX_FRAME_HEADER
)
175 fprintf(stderr
, "Bad frame header!\n");
178 h
->frame_header_len
= i
+slen
+1;
180 if( fread(p_pic
->img
.plane
[0], 1, h
->width
*h
->height
, h
->fh
) <= 0
181 || fread(p_pic
->img
.plane
[1], 1, h
->width
* h
->height
/ 4, h
->fh
) <= 0
182 || fread(p_pic
->img
.plane
[2], 1, h
->width
* h
->height
/ 4, h
->fh
) <= 0)
185 h
->next_frame
= i_frame
+1;
190 int close_file_y4m(hnd_t handle
)
192 y4m_input_t
*h
= handle
;