如何识别一个影像文件是mpeg1或mpeg2的格式,不是用扩展名,给出源码者立即给分,用硬解压或软解压均可..............(100分)

  • 主题发起人 主题发起人 yym
  • 开始时间 开始时间
Y

yym

Unregistered / Unconfirmed
GUEST, unregistred user!
如何识别一个影像文件是mpeg1或mpeg2的格式,不是用扩展名,给出源码者立即给分,用神龙卡等硬解压或软解压均可..............谢!
 
type
TFileType=(VCDFile,DVDFile,UnKnowFile);

function GetFileType(FileHandle:Thandle):TFileType;

{判断文件格式 方法取最前面的4个字节如果是VCD的包头}
function Tform1.GetFileType(FileHandle:Thandle):TFileType;
var
HeadBuf:array[1..4] of Byte;
begin

result:=UnKnowFile;
FileRead(FileHandle,HeadBuf,4);
if (HeadBuf[1]=$52)and(HeadBuf[2]=$49)and(HeadBuf[3]=$46)and(HeadBuf[4]=$46) then

result:=VCDFile;
if (HeadBuf[1]=$00)and(HeadBuf[2]=$00)and(HeadBuf[3]=$01)and(HeadBuf[4]=$BA) then

result:=DVDfile;
end;
 
谢谢5220911
我分析了一下,如果对于VCD光盘是可以,但如果用用软件生成的MPEG文件头都是000001ba
就无从分析了,下面是一段英文介绍,可惜无从下手。哪位大虾帮帮忙

File type analysis
The following rules are only information on reader’s discretion and are subject to changes:
· The extension is not used to determine the file type.
· After opening the input file and reading MPEG data, the FMP driver will search for a MPEG pack header (0x000001BA), for a MPEG2 transport syncbyte (0x47), for a sequence header (0x000001B3) or for an audio syncword (0xFFF). The driver will consider immediately the file as a MPEG1 system file or a MPEG2 program file when a pack header is found. In the case of a MPEG2 transport stream, the driver will try to find at least 10 MPEG2 transport packets (188 bytes length, begin
ning with 0x47). In the last two cases, the diver will keep on searching for a header in order to verify the sequence header or the audio syncword is not inside a packet. When a minimum number of bytes has been looked (around 3000 bytes), the driver will decide whether the file is a video file (first choice) or an audio file (no sequence header has been found).
· When the file is considered as a MPEG1 system file or MPEG2 program system , the driver will start searching for information on the different video and audio streams. When a sequence header is found (there can be more than one to describe the streams), the driver will use it to calculate the number of video and audio streams. then
, the driver will try to retrieve information for those streams in the first 20 packets. If some streams remain not initialized (i.e. declare inside a sequence header, but no matching packets) the driver will keep on looking in the next 80 packets or until the first matching packet is found. If some streams are unknown (i.e. not declare in a sequence header), they will be treated the same way. Note that the driver will stop searching for streams when an invalid packet is found (i.e. the next packet headerdo
es not match with the previous packet header after adding the position of the previous packet and its size).
· When the file is considered as a MPEG2 transport stream, the driver will start searching for a program association table, then
for the program map tables to get the elementary streams. The, the driver will try to retrieve information for the elementary streams by using the random_access_indicator bit.
· When the file is considered as an audio file, the first audio syncword found will be considered as the begin
ning of an audio frame (which may not be true: audio syncword are allowed inside audio data).
· The first packet of a stream is used to determine some of its characteristics. Thus, the first video packet needs to have a sequence header fully contained inside the packet (itdo
es not have to be at the begin
ning of the packet). Same thing for the audio: the first audio syncword found in the packet - there must be at least one - will be considered as the begin
ning of a valid audio frame.
 
这个也容易啊,你读取一下,然后做个循环判断如果两个000001ba
之间是2324的话就是mpg1
 
MPEG1头
000001BA2100010009801B91000001BB
0009801B9103E1FFE0E02E000001BE08
F30FFFF...............全是FF
000001BA2100010941801B91000001BB
0009801B9107E0FFC0C020000001BE08DFFF
MPEG2头
000001BA440004000C4700DF03F80000
01BB0009806F8100E17FE0E101000001
BE07DDFF................全是FF
000001BA44000407FC9F00DF03F80000
01E007EC80C10D310003223911000306
 
晕晕……
我没说清楚
我的意思是两个000001ba之间(包括一个000001ba)有2324个字节,
意思是一个mpg1包是2324大小!
 
VCD 的 DAT 文件,一个包的大小是 2324.但很多 Mpg1 的码流并不是这样.还是分析文件头吧.
 
简单的写了一段,见笑.

var
Mask: array[1..16] of Byte = ($FF, $FF, $FF, $FF, $F1, $00, $01, $00, $01,
$80, $00, $01, $FF, $FF, $FF, $FF);
Val: array[1..16] of Byte = ($00, $00, $01, $BA, $21, $00, $01, $00, $01, $80,
$00, $01, $00, $00, $01, $BB);
ReadCB: array[1..16] of Byte;

procedure GetMpeg1Format;
var
FileStream: TFileStream;
i: Integer;
begin

FileStream := TFileStream.Create('c:/1.mpg', fmOpenRead);
for i := 1 to 16do

begin

FileStream.Read(ReadCB, SizeOf(Byte));
ReadCB := ReadCB and Mask;
end;


for i := 1 to 16do

begin

if ReadCB <> Val then

Exit;
end;


ShowMessage('Mpeg-1 Format');
FileStream.Free;
end;

 
谢谢amakusa,但每一个MPEG1的文件头并不都是如下的值,我有试过了。
$FF, $FF, $FF, $FF, $F1, $00, $01, $00, $01,
$80, $00, $01, $FF, $FF, $FF, $FF);
 
var
Mask: array[1..5] of Byte = ($FF, $FF, $FF, $FF, $C0);
Val: array[1..5] of Byte = ($00, $00, $01, $BA, $40);
ReadCB: array[1..5] of Byte;

edure GetMpeg2Format;
var
FileStream: TFileStream;
i: Integer;
begin

FileStream := TFileStream.Create('c:/2.mpg', fmOpenRead);
for i := 1 to 5do

begin

FileStream.Read(ReadCB, SizeOf(Byte));
ReadCB := ReadCB and Mask;
end;


for i := 1 to 5do

begin

if ReadCB <> Val then

Exit;
end;


ShowMessage('Mpeg-2 Format');
FileStream.Free;
end;
 
原理是文件头的校验,
($FF, $FF, $FF, $FF, $F1, $00, $01, $00, $01,
$80, $00, $01, $FF, $FF, $FF, $FF);
等信息是在注册表读到的 mediatype
http://hqtech.nease.net/articles/RegisterCustom.htm
 
MEDIASUBTYPE_MPEG1Payload: TGUID = (D1:$E436EB81;D2:$524F;D3:$11CE;D4:($9F,$53,$00,$20,$AF,$0B,$A7,$70));

MEDIATYPE_MPEG1SystemStream: TGUID = (D1:$E436EB82;D2:$524F;D3:$11CE;D4:($9F,$53,$00,$20,$AF,$0B,$A7,$70));

MEDIASUBTYPE_MPEG1System: TGUID = (D1:$E436EB84;D2:$524F;D3:$11CE;D4:($9F,$53,$00,$20,$AF,$0B,$A7,$70));

MEDIASUBTYPE_MPEG1VideoCD: TGUID = (D1:$E436EB85;D2:$524F;D3:$11CE;D4:($9F,$53,$00,$20,$AF,$0B,$A7,$70));

MEDIASUBTYPE_MPEG1Video: TGUID = (D1:$E436EB86;D2:$524F;D3:$11CE;D4:($9F,$53,$00,$20,$AF,$0B,$A7,$70));

以上类型全部为 mpeg1 video 格式.
上面的 Mpeg-1 的文件头检查只做了 MEDIASUBTYPE_MPEG1System 的类型,其他的可以根据注册表信息来检查文件头.
 
我只知其一,不知其二,感谢!
 
MPEG-2为了兼容MPEG-1,文件头部都会有0x000001BA的。
而你说的VCD也分1.0、1.1、2.0,1.0和1.1是为了光驱好定位视频所以将MPEG-1 System Stream由打成每2324个字节一个Pack,而VCD2.0使用了MPEG-2的压缩格式。
MPEG-2分Program Stream和Transport Stream。
给你一个标准文档:
video_stream_descriptor(){
descriptor_tag 8 uimsbf
descriptor_length 8 uimsbf
multiple_frame_rate_flag 1 bslbf
frame_rate_code 4 uimsbf
MPEG_1_only_flag 1 bslbf
constrained_parameter_flag 1 bslbf
still_picture_flag 1 bslbf
if (MPEG_1_only_flag == 1){
profile_and_level_indication 8 uimsbf
chroma_format 2 uimsbf
frame_rate_extension_flag 1 bslbf
reserved 5 bslbf
}
}
其中的:
MPEG_1_only_flag -- This is a 1 bit field which when set to '1' indicates that the video stream contains
only ISO/IEC 11172-2 data. If set to '0' the video stream may contain both ISO/IEC 13818-2 video data and
constrained parameter ISO/IEC 11172-2 video data.
就可以判断出是MPEG-1还是MPEG-2。
 
几天没空看了,谢谢各位富翁,特别是amakusa ,先多放几天,这段子忙得都没时间去弄了,给点源码最好
 
多人接受答案了。
 
后退
顶部