Click here to Skip to main content
15,906,463 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Hi everyone
I've got this project on MATLAB where i'm trying to read in a YUV file.

Below are the m files within my work directory

matlab
function [width,height,fps,startpos,NumberFrames]=readheader(fid)

%********************************************************
% This function will read the header of a bath yuv file
%
% This file is used by readyseq and should not be used on its own.
%
% N.Young
% 5 June 2001
%********************************************************

FileFormat = [];
%The first line will contain one of the following

%1.   YUV 4:2:0
%2.   RVS RAW YUV 4:2:0

%read the format descriptor
for i=1:17
  FileFormat = [FileFormat fscanf(fid,'%c',1)];

  %Check to see if it is yuv 420 (i.e. number 1 above)
  if i==9
    if FileFormat == 'YUV 4:2:0'
      disp('File format is : YUV 4:2:0');
      FileFormat=0;
      break;
    end
  end

  %Check to see if it is rvs raw yuv 420 (i.e. number 2 above)
  if i==17
    if FileFormat == 'RVS RAW YUV 4:2:0'
      disp('File format is : RVS RAW YUV 4:2:0');
      FileFormat=1;
      break;
    end
  end

  %if we get here and i is 17, we have an unsupported FileFormat
  if i==17
    disp('Unknown file format')
    FileFormat = 2;
  end
end

if FileFormat==0
  [width,height,fps,startpos,NumberFrames] = readyuvheader(fid);
end


matlab
function [width,height,y]=readyseq(filename,start,stop)
%********************************************************
% Function to load a bath yuv file
%
% Syntax : [width,height,ysequence] = readyseq(filename,start frame,end frame)
%
% NOTE: the frames are numbered from 0.
%
% A.N.Evans & N.Young
% 5 June 2001
%********************************************************

%Note that I have to use some C functions here.  I know some people dont like
%mixing matlab with c, I'm affraid its un avoidable.

%First we need to open the file
[fid,msg] = fopen(filename,'r');

%if msg is longer than 0, i.e. it has something in it, we have an error
if length(msg) > 0

  disp('Error opening the file.');

else
  %read the header info
  [width,height,fps,startpos,NumberFrames] = readheader(fid);

  if start < NumberFrames & stop < NumberFrames

     %Now we can read the given frames.
      i=1;
      for frame = start:stop
          %now read the required frame
          y(i,:,:)=readyframe(fid,width,height,startpos,frame);
          i=i+1;
      end
  end
end
fclose(fid);


matlab
function [width,height,fps,startpos,NumberFrames]=readyuvheader(fid)

%********************************************************
%This function will read the header of a bath yuv
%
% This file is used by readheader and should not be
% used on its own.
%
% N.Young
% 5 June 2001
%********************************************************

%we should have 1 null character for yuv now
fscanf(fid,'%c',1);

%Now read the width of the sequence
width='';
while ne(width,0)
  width = [width fscanf(fid,'%c',1)];
end

width = str2num(width);

%Now read the height of the sequence
height='';
while ne(height,0)
  height = [height fscanf(fid,'%c',1)];
end

height = str2num(height);

%Now read the fps
fps='';
while ne(fps,0)
  fps = [fps fscanf(fid,'%c',1)];
end

fps = str2num(fps);

%Finally, caluclate the number of frmes in the sequence
startpos = ftell(fid);  %get the current position (should be the start of the data)

fseek(fid,0,'eof'); %move to the end of the file
endpos = ftell(fid);

% now we can calculate the number of frames
FileLength = endpos-startpos;
FrameSize = width * height * 1.5; %quick HACK
NumberFrames = FileLength / FrameSize;

%Reset the file to the start of the data
fseek(fid,startpos,'bof');



matlab
function [y,u,v]=readframe(fid,width,height)

%read the required frame from the stream

elements = width*height;

%The reshape below turns the data we read in into 2d data and rotates it.

%read the y frame
[y,count] = fread(fid,elements,'uchar');

%if count is 0, then we have reached the end of the file
if count==0
    y=[];
    u=[];
    v=[];
else
    y=reshape(y,[width,height])';

    %read the u frame, remember this is 1/4 of the size of the y
    u = fread(fid,elements/4,'uchar');
    u=reshape(u,[width/2,height/2])';

    %read the v frame, remember this is 1/4 of the size of the y
    v = fread(fid,elements/4,'uchar');
    v=reshape(v,[width/2,height/2])';
end



matlab
function s = yuv2pgm(filename,startframe,stopframe)

%********************************************************
%Funtion to read in a yuv sequence, to memory and
%convert it to a series of pgm images at the same time
%
%Syntax : Y_Sequence = yuv2pgm(filename,startframe,stopframe);
%
%This will read the first n frames from the given sequence,
%and also save pgm copies to, frame0.pgm, frame1.pgm and so on,
%
%NOTE: The frames are numbered from 0.
%
% A.N.Evans & N.Young
% 5 June 2001
%********************************************************

%Read the y frames of the sequence
[width,height,y]=readyseq(filename,startframe,stopframe);

a = 'frame';
c = '.pgm';

%Note, You may not have the 'saveimg' file on your copy of matlab,
% in which case you will have to get a copy of matts 'pgmwrite'.

for i=1:stopframe-startframe+1
   b=[int2str(i+startframe-1)];
   saveimg(squeeze(y(i,:,:)),strcat(a,b,c));
%   pgmwrite(squeeze(y(i,:,:)),strcat(a,b,c));
end
s=y;


NOW A m file thats not a function, just to test the code works. This is saved as demo.m
matlab
%Sample yuv file reading

%Read the y frames 0 to 2 of the sequence test.yuv
y = yuv2pgm('test.yuv',0,2);

%the above will also have save 3 pgm files:
%
% frame0.pgm
% frame1.pgm
% frame2.pgm


frame0 = squeeze(y(1,:,:));
frame1 = squeeze(y(2,:,:));
frame2 = squeeze(y(3,:,:));

%show the frames
figure;
image(frame0);
colormap(gray(256))

figure;
image(frame1);
colormap(gray(256))

figure;
image(frame2);
colormap(gray(256))



So after all that i now type in the command window demo
The output is as follows
??? Error using ==> mrdivide
Matrix dimensions must agree.
Error in ==> readyuvheader at 49
NumberFrames = FileLength / FrameSize;
Error in ==> readheader at 48
  [width,height,fps,startpos,NumberFrames] = readyuvheader(fid);
Error in ==> readyseq at 26
  [width,height,fps,startpos,NumberFrames] = readheader(fid);
Error in ==> yuv2pgm at 19
[width,height,y]=readyseq(filename,startframe,stopframe);
Error in ==> demo2 at 4
y = yuv2pgm('test.yuv',0,2);


So now I change the description of FrameSize by changing it from width*height*1.5 by replacing width and height with the dimensions of a cif or Qcif format video.

Now i get this command
>> demo
File format is : YUV 4:2:0
??? Error using ==> fseek
Invalid offset.

Error in ==> readyframe at 16
fseek(fid,startpos + (frame * yuvElements),'bof');


Please Help

Many Thanks in Advance
Posted
Updated 29-Mar-10 3:42am
v2

Serious question: why do you post this on CodeProject rather than the MATLAB forum?
 
Share this answer
 
I've changed the code and managed to get this working. I will write a thorough article on this later
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900