unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, SDL, StdCtrls;type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;implementation
  uses
  avformat, avcodec, avutil, mem, swscale,FFMPEGDynamiccall;
{$R *.dfm}
function SDL_Auxilipitary_ForDelphi(var pict:PAVPicture;var bmp:PSDL_Overlay):Integer;stdcall;external 'delphiSDL.dll';
function SDL_GetOverlayPix(const bmp:PSDL_Overlay;const i : integer):System.PByte;stdcall;external 'delphiSDL.dll';
function SDL_GetOverlayPit(const bmp:PSDL_Overlay;const i : integer):Integer;stdcall;external 'delphiSDL.dll';
procedure TForm1.FormCreate(Sender: TObject);
begin
  // 初始化 SDL
if(SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO or SDL_INIT_TIMER) < 0) then
  showmessage(Format('Couldn''t initialize SDL : %s',[SDL_GetError]));
  // 初始化 FFMPEG 库
  // 动态调用
  FFCall_AddLibrary('D:\Delphi\ffmpeg 研究工程\avcodeclib\pthreadGC2.dll');
  FFCall_AddLibrary('D:\Delphi\ffmpeg 研究工程\avcodeclib\xvidcore.dll');
  FFCall_AddLibrary('D:\Delphi\ffmpeg 研究工程\avcodeclib\avutil.dll');
  FFCall_AddLibrary('D:\Delphi\ffmpeg 研究工程\avcodeclib\swscale.dll');
  FFCall_AddLibrary('D:\Delphi\ffmpeg 研究工程\avcodeclib\avcodec.dll');
  FFCall_AddLibrary('D:\Delphi\ffmpeg 研究工程\avcodeclib\avfilter.dll');
  FFCall_AddLibrary('D:\Delphi\ffmpeg 研究工程\avcodeclib\avformat.dll');
  FFCall_AddLibrary('D:\Delphi\ffmpeg 研究工程\avcodeclib\avdevice.dll');
  FFCall_Init;
end;procedure TForm1.Button1Click(Sender: TObject);
const
  filename = 'E:\Sample.avi'; // 得到 H.264 也可以 保存为图片
var
  pFormatCtx: PAVFormatContext;
  pCodecCtx: PAVCodecContext;
  pCodec: PAVCodec;
  pFrame: PAVFrame;
  pScaleCtx: PSwsContext;
  numBytes: integer;
  buffer: PByte;
  frameFinished : int ;
  pict: TAVPicture;
  i, videoStream: integer;
  ptk : TAVPacket;
  CRect : TRect;
  // sdl
  screen : PSDL_Surface;
  bmp:PSDL_Overlay;
begin
  av_register_all();
  // Open video file
  if av_open_input_file ( pFormatCtx, filename, nil, 0, nil ) <> 0 then
    raise exception.Create ( 'WTF?! Couldn''t open file!!!' );
  // Retrieve stream information
  if av_find_stream_info ( pFormatCtx ) < 0 then
    raise exception.Create ( 'WTF?! Couldn''t find stream information!!!' );
  dump_format ( pFormatCtx, 0, filename, 0 ); // <<<<<< i dont know how its works
  // Get a pointer to the codec context for the video stream
  videoStream := -1;
  for i := 0 to pFormatCtx.nb_streams - 1 do
  begin
    if pFormatCtx.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 := pFormatCtx.streams [videoStream].codec;
  // Open codec
  pCodec := avcodec_find_decoder ( pCodecCtx.codec_id );
  
  if pCodec = nil then
    raise exception.Create ( 'WTF?! Codec not found!' );
   if avcodec_open(pCodecCtx,pCodec) < 0 then
    raise exception.Create ( 'WTF?! Could not open codec!');
  // Allocate video frame
pFrame:=avcodec_alloc_frame();
  // Determine required buffer size and allocate buffer
  numBytes := avpicture_get_size(PIX_FMT_RGB24, pCodecCtx.width,pCodecCtx.height);
{$ifndef __DARWIN__}
screen := SDL_SetVideoMode(pCodecCtx.width, pCodecCtx.height, 0, 0);
{$else}
screen := SDL_SetVideoMode(pCodecCtx.width, pCodecCtx.height, 24, 0);
{$endif}
if not assigned(screen) then showmessage(Format('SDL: could not set video mode : %s',[SDL_GetError]));
  bmp := SDL_CreateYUVOverlay(pCodecCtx.width, pCodecCtx.height,
  SDL_YV12_OVERLAY, screen);
  // pFrameRGB := avcodec_alloc_frame;
  // avpicture_alloc ( PAVPicture (pFrameRGB), PIX_FMT_RGB32, pCodecCtx.width, pCodecCtx.height );
  pScaleCtx := sws_getContext ( pCodecCtx.width, pCodecCtx.height, pCodecCtx.pix_fmt,
                                pCodecCtx.width, pCodecCtx.height, PIX_FMT_RGB32, SWS_BICUBIC, nil, nil, nil  );
  i := 0;
  while(av_read_frame(pFormatCtx, @ptk)>=0) do begin
    i := i + 1;
    if(ptk.stream_index = videoStream) then begin
// Decode video frame
avcodec_decode_video(pCodecCtx, pFrame, @frameFinished,ptk.data, ptk.size);
// Did we get a video frame?
if frameFinished <> 0 then begin
        
        //*************************************************************
//        问题来了
//        SDL_GetOverlayPix 我用 C++ 写的动态链接库
{
         pict->data[0] = bmp->pixels[0];
pict->data[1] = bmp->pixels[2];
pict->data[2] = bmp->pixels[1];
pict->linesize[0] = bmp->pitches[0];
pict->linesize[1] = bmp->pitches[2];
         pict->linesize[2] = bmp->pitches[1];
return 1;
         问题就是 这样 黑屏 无法播放!
         如果用 delphi 实现 
         delphi SDL
         TSDL_Overlay = record
           format: UInt32; // Overlay format
           w, h: Integer; // Width and height of overlay
           planes: Integer; // Number of planes in the overlay. Usually either 1 or 3
           pitches: PUInt16;
           // An array of pitches, one for each plane. Pitch is the length of a row in bytes.
           pixels: PPUInt8; // 可以看出来 是 数组指针 不是数值
             // An array of pointers to the data of each plane. The overlay should be locked before these pointers are used.
           hw_overlay: UInt32;
             // This will be set to 1 if the overlay is hardware accelerated.
         end;         如何还原为数组呢???
}
        //*************************************************************
SDL_LockYUVOverlay(bmp);
        {showmessage(inttostr(integer(SDL_GetOverlayPix(bmp,0))));
        showmessage(inttostr(integer(SDL_GetOverlayPix(bmp,1))));
        showmessage(inttostr(integer(SDL_GetOverlayPix(bmp,2))));}
        OutputDebugString(PChar(inttostr(SDL_GetOverlayPit(bmp,1))));
        // pict := getpict(bmp)^;
        pict.data[0] := SDL_GetOverlayPix(bmp,0);
        pict.data[1] := SDL_GetOverlayPix(bmp,2);
        pict.data[2] := SDL_GetOverlayPix(bmp,1);
        pict.linesize[0] := SDL_GetOverlayPit(bmp,0);
        pict.linesize[1] := SDL_GetOverlayPit(bmp,2);
        pict.linesize[2] := SDL_GetOverlayPit(bmp,1);
        OutputDebugString(PChar(inttostr(pict.linesize[2])));
        OutputDebugString(PChar(inttostr(integer(SDL_GetOverlayPix(bmp,1)))));
        OutputDebugString(PChar(inttostr(integer(pict.data[2]))));
        {img_convert(@pict, PIX_FMT_YUV420P,
        PAVPicture(pFrame), pCodecCtx.pix_fmt, pCodecCtx.width, pCodecCtx.height);}        sws_scale(pScaleCtx, @pFrame.data, @pFrame.linesize,
0, pCodecCtx.height, @pict.data, @pict.linesize);
SDL_UnlockYUVOverlay(bmp);
Crect.Left := 0;
Crect.top := 0;
Crect.Right := pCodecCtx.width;
Crect.Bottom := pCodecCtx.height;
SDL_DisplayYUVOverlay(bmp, @CRect);
        Sleep(4);
        if i > 1000 then break;
      end;
    end;
  end;
 {
// Convert the image from its native format to RGB
/*sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,
                      0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);*/
// Save the frame to disk
/*if(++i<=5)
SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);*/
SDL_LockYUVOverlay(bmp);
AVPicture pict;
// Convert the image into YUV format that SDL uses
/*img_convert(&pict, PIX_FMT_YUV420P,
(AVPicture *)pFrame, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height);*/
sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,
0, pCodecCtx->height, pict.data, pict.linesize);
SDL_UnlockYUVOverlay(bmp);
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
SDL_DisplayYUVOverlay(bmp, &rect);
//Sleep(60); }
end;end.