1,185
社区成员




unit testUnit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,sdl;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
avformat, avcodec, avutil, mem, swscale;
{$R *.dfm}
var
packet: TAVPacket;
bytesRemaining: integer = 0;
rawData: PByte;
fFirstTime: boolean = true;
pOverlay : PSDL_Overlay;
surface : PSDL_Surface;
rect : TSDL_Rect;
procedure mem_copy( src, dest : PUint8; src_width, dest_width : word; lines : word );
var
c : word;
begin
for c := 1 to lines do
begin
move( src^, dest^, src_width );
inc( src, src_width );
inc( dest, dest_width );
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
const
filename = 'd:\mp4.mp4';
// filename = 'd:\1.avi';
//filename = 'D:\MyTestAll_ffmpeg_sdl\MyTestAll\vs\MyTestAll\mp4.mp4';
//D:\MyTestAll_ffmpeg_sdl\MyTestAll\vs\MyTestAll
var
pAVFCtx: PAVFormatContext;
pCodecCtx: PAVCodecContext;
pCodec: PAVCodec;
pFrame,pFrameRGB: PAVFrame;
pScaleCtx: PSwsContext;
pitch : PUInt16;
plane : PPUInt8;
i, videoStream,hasVideo: integer;
picture:TAVPicture;
f,w,h:integer;
begin
av_register_all();
if SDL_Init( SDL_INIT_VIDEO or SDL_INIT_AUDIO or SDL_INIT_TIMER ) > 0 then
raise exception.Create ( 'yp_init_sdl: SDL_Init failed' );
if av_open_input_file ( pAVFCtx, filename, nil, 0, nil ) <> 0 then
raise exception.Create ( 'WTF?! Couldn''t open file!!!' );
if av_find_stream_info ( pAVFCtx ) < 0 then
raise exception.Create ( 'WTF?! Couldn''t find stream information!!!' );
dump_format ( pAVFCtx, 0, filename, 0 );
videoStream := -1;
for i := 0 to pAVFCtx.nb_streams - 1 do
begin
if pAVFCtx.streams [i].codec.codec_type = CODEC_TYPE_VIDEO then
begin
videoStream := i;
break;
end;
end;
if videoStream = -1 then
raise exception.Create ( 'WTF?! Didn''t find a video stream!' );
pCodecCtx := pAVFCtx.streams [videoStream].codec;
pCodec := avcodec_find_decoder ( pCodecCtx.codec_id );
if pCodec = nil then
raise exception.Create ( 'WTF?! Codec not found!' );
if ( pCodec.capabilities and CODEC_CAP_TRUNCATED ) = CODEC_CAP_TRUNCATED then
pCodecCtx.flags := pCodecCtx.flags or CODEC_FLAG_TRUNCATED;
if avcodec_open ( pCodecCtx, pCodec ) < 0 then
raise exception.Create ( 'WTF?! Could not open codec!' );
surface := SDL_SetVideoMode( pCodecCtx.width, pCodecCtx.height, 0, 0 );
if surface = nil then
raise exception.Create ( 'yp_init_sdl: SDL_SetVideoMode failed' );
pOverlay := SDL_CreateYUVOverlay(pCodecCtx.width, pCodecCtx.height, SDL_YV12_OVERLAY, surface);
if pOverlay = nil then
raise exception.Create ( 'yp_init_sdl: SDL_CreateYUVOverlay failed' );
pFrame := avcodec_alloc_frame();
pFrameRGB:= avcodec_alloc_frame();
avpicture_alloc (PAVPicture(pFrameRGB), PIX_FMT_YUV420P, pCodecCtx.width, pCodecCtx.height );
// fillchar(picture,sizeof(picture),0);
while(av_read_frame(pAVFCtx, @packet)=0) do
begin
if packet.stream_index=videoStream then
begin
avcodec_decode_video(pCodecCtx, pFrame, @hasVideo, packet.data, packet.size );
if hasVideo<>0 then
begin
SDL_LockYUVOverlay(pOverlay);
pScaleCtx := sws_getContext ( pCodecCtx.width, pCodecCtx.height, pCodecCtx.pix_fmt,
pCodecCtx.width, pCodecCtx.height, PIX_FMT_RGB32, SWS_BICUBIC, nil, nil, nil );
sws_scale ( pScaleCtx, @pFrame.data, @pFrame.linesize,0, pCodecCtx.height,@pFrameRGB.data, @pFrameRGB.linesize );
pitch := poverlay^.pitches; //set to first pitch
plane := PPUInt8( poverlay^.pixels ); //set to first plane
mem_copy( PUInt8(pFrameRGB.data[0]), plane^, pCodecCtx.width, pitch^, pCodecCtx.height ); //copy y plane to overlay
inc( pitch ); //next pitch
inc( plane ); //next plane
mem_copy( PUInt8(pFrameRGB.data[1]), plane^, pCodecCtx.width div 4, pitch^, pCodecCtx.height div 4 ); //copy
inc( pitch );
inc( plane );
mem_copy( PUInt8(pFrameRGB.data[2]), plane^, pCodecCtx.width div 4, pitch^, pCodecCtx.height div 4 );
// // CopyMemory ( bmp.ScanLine [i], pointer (integer (pFrameRGB.data [0]) + bmp.Width * 4 * i), bmp.Width * 4 );
//CopyMemory ( @poverlay^.pixels, pointer (integer (pFrameRGB.data [0])), pCodecCtx.height );
SDL_UnlockYUVOverlay( pOverlay );
rect.x := 0;
rect.y := 0;
rect.h := pCodecCtx.height;
rect.w := pCodecCtx.width ;
SDL_DisplayYUVOverlay( pOverlay, @rect );
end;
end;
end;
av_free ( pFrame );
avcodec_close ( pCodecCtx );
av_close_input_file ( pAVFCtx );
sws_freeContext ( pScaleCtx );
end;
end.