diff --git a/samples/FFMpeg/decoding_encoding/decoding_encoding.dpr b/samples/FFMpeg/decoding_encoding/decoding_encoding.dpr
new file mode 100644
index 0000000..001bae7
--- /dev/null
+++ b/samples/FFMpeg/decoding_encoding/decoding_encoding.dpr
@@ -0,0 +1,693 @@
+(*
+ * Copyright (c) 2001 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+*)
+(* *
+ * @file
+ * libavcodec API use example.
+ *
+ * @example decoding_encoding.c
+ * Note that libavcodec only handles codecs (mpeg, mpeg4, etc...),
+ * not file formats (avi, vob, mp4, mov, mkv, mxf, flv, mpegts, mpegps, etc...). See library 'libavformat' for the
+ * format handling
+*)
+
+program decoding_encoding;
+
+{$APPTYPE CONSOLE}
+{$POINTERMATH ON}
+{$R *.res}
+
+uses
+ System.SysUtils,
+ System.Math,
+ ffm.libavcodec.avcodec,
+ ffm.pixfmt,
+ ffm.avformat,
+ ffm.samplefmt,
+ ffm.swscale,
+ ffm.avio,
+ ffm.frame,
+ ffm.channel_layout,
+ ffm.ctypes,
+ ffm.mem,
+ ffm.mathematics,
+ ffm.avutil,
+ ffm.opt,
+ ffm.imgutils;
+
+Const
+ INBUF_SIZE = 4096;
+ AUDIO_INBUF_SIZE = 20480;
+ AUDIO_REFILL_THRESH = 4096;
+
+ (* check that a given sample format is supported by the encoder *)
+function check_sample_fmt(const codec: pAVCodec; const sample_fmt: TAVSampleFormat): Boolean;
+Var
+ p: pAVSampleFormat;
+begin
+ p := codec^.sample_fmts;
+ while (p^ <> AV_SAMPLE_FMT_NONE) do
+ begin
+ if (p^ = sample_fmt) then
+ Exit(True);
+ inc(p);
+ end;
+ Result := False;
+end;
+
+(* just pick the highest supported samplerate *)
+function select_sample_rate(const codec: pAVCodec): Integer;
+Var
+ p: pInteger;
+ best_samplerate: Integer;
+begin
+ best_samplerate := 0;
+ if not Assigned(codec^.supported_samplerates) then
+ Exit(44100);
+ p := codec^.supported_samplerates;
+ while (p^ <> 0) do
+ begin
+ best_samplerate := MAX(p^, best_samplerate);
+ inc(p);
+ end;
+ Result := best_samplerate;
+end;
+
+(* select layout with the highest channel count *)
+function select_channel_layout(codec: pAVCodec): Integer;
+Var
+ p: PUInt64_t;
+ best_ch_layout: UInt64;
+ best_nb_channels: Integer;
+ nb_channels: Integer;
+begin
+ best_ch_layout := 0;
+ best_nb_channels := 0;
+ if not Assigned(codec^.channel_layouts) then
+ Exit(AV_CH_LAYOUT_STEREO);
+ p := codec^.channel_layouts;
+ while (p^ <> 0) do
+ begin
+ nb_channels := av_get_channel_layout_nb_channels(p^);
+ if (nb_channels > best_nb_channels) then
+ begin
+ best_ch_layout := p^;
+ best_nb_channels := nb_channels;
+ end;
+ inc(p);
+ end;
+ Result := best_ch_layout;
+end;
+
+(*
+ * Audio encoding example
+*)
+procedure audio_encode_example(const filename: String);
+Var
+ codec: pAVCodec;
+ c: pAVCodecContext;
+ frame: pAVFrame;
+ pkt: TAVPacket;
+ i, j, k, ret, got_output: Integer;
+ buffer_size: Integer;
+ f: File;
+ samples: ^Int16;
+ t, tincr: Single;
+begin
+ c := nil;
+ WriteLn('Encode audio file ', filename);
+ (* find the MP2 encoder *)
+ codec := avcodec_find_encoder(AV_CODEC_ID_MP2);
+ if not Assigned(codec) then
+ begin
+ WriteLn('Codec not found');
+ Exit;
+ end;
+ c := avcodec_alloc_context3(codec);
+ if not Assigned(c) then
+ begin
+ WriteLn('Could not allocate audio codec context\n');
+ Exit;
+ end;
+ (* put sample parameters *)
+ c^.bit_rate := 64000;
+ (* check that the encoder supports s16 pcm input *)
+ c^.sample_fmt := AV_SAMPLE_FMT_S16;
+ if not check_sample_fmt(codec, c^.sample_fmt) then
+ begin
+ WriteLn('Encoder does not support sample format ', av_get_sample_fmt_name(c^.sample_fmt));
+ Exit;
+ end;
+ (* select other audio parameters supported by the encoder *)
+ c^.sample_rate := select_sample_rate(codec);
+ c^.channel_layout := select_channel_layout(codec);
+ c^.channels := av_get_channel_layout_nb_channels(c^.channel_layout);
+ (* open it *)
+ if (avcodec_open2(c, codec, nil) < 0) then
+ begin
+ WriteLn('Could not open codec');
+ Exit;
+ end;
+ AssignFile(f, filename);
+ try
+ Rewrite(f, 1);
+ except
+ WriteLn('Could not open', filename);
+ Exit;
+ end;
+ (* frame containing input raw audio *)
+ frame := av_frame_alloc();
+ if not Assigned(frame) then
+ begin
+ WriteLn('Could not allocate audio frame');
+ Exit;
+ end;
+ frame^.nb_samples := c^.frame_size;
+ frame^.format := Integer(c^.sample_fmt);
+ frame^.channel_layout := c^.channel_layout;
+ (* the codec gives us the frame size, in samples,
+ * we calculate the size of the samples buffer in bytes *)
+ buffer_size := av_samples_get_buffer_size(nil, c^.channels, c^.frame_size, c^.sample_fmt, 0);
+ if (buffer_size < 0) then
+ begin
+ WriteLn('Could not get sample buffer size');
+ Exit;
+ end;
+ samples := av_malloc(buffer_size);
+ if not Assigned(samples) then
+ begin
+ WriteLn('Could not allocate %d bytes for samples buffer\n', buffer_size);
+ Exit;
+ end;
+ (* setup the data pointers in the AVFrame *)
+ ret := avcodec_fill_audio_frame(frame, c^.channels, c^.sample_fmt, pByte(samples), buffer_size, 0);
+ if (ret < 0) then
+ begin
+ WriteLn('Could not setup audio frame');
+ Exit;
+ end;
+ (* encode a single tone sound *)
+ t := 0;
+ tincr := 2 * M_PI * 440.0 / c^.sample_rate;
+ for i := 0 to 199 do
+ begin
+ av_init_packet(@pkt);
+ pkt.data := nil; // packet data will be allocated by the encoder
+ pkt.size := 0;
+ for j := 0 to c^.frame_size - 1 do
+ begin
+ samples[2 * j] := Trunc((sin(t) * 10000));
+ for k := 1 to c^.channels - 1 do
+ samples[2 * j + k] := samples[2 * j];
+ t := t + tincr;
+ end;
+ (* encode the samples *)
+ ret := avcodec_encode_audio2(c, @pkt, frame, got_output);
+ if (ret < 0) then
+ begin
+ WriteLn('Error encoding audio frame');
+ Exit;
+ end;
+ if (got_output <> 0) then
+ begin
+ BlockWrite(f, pkt.data^, pkt.size);
+ av_free_packet(pkt);
+ end;
+ end;
+ (* get the delayed frames *)
+ got_output := 1;
+ while got_output <> 0 do
+ // ; i++)
+ begin
+ ret := avcodec_encode_audio2(c, @pkt, nil, got_output);
+ if (ret < 0) then
+ begin
+ WriteLn('Error encoding frame');
+ Exit;
+ end;
+ if (got_output <> 0) then
+ begin
+ BlockWrite(f, pkt.data^, pkt.size);
+ av_free_packet(pkt);
+ end;
+ inc(i);
+ end;
+ Close(f);
+ av_freep(samples);
+ av_frame_free(frame);
+ avcodec_close(c);
+ av_free(c);
+end;
+
+(*
+ * Audio decoding.
+*)
+procedure audio_decode_example(const outfilename: String; const filename: String);
+Var
+ codec: pAVCodec;
+ c: pAVCodecContext;
+ len: Integer;
+ f, outfile: File;
+ inbuf: array [0 .. AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE - 1] of byte;
+ avpkt: TAVPacket;
+ decoded_frame: pAVFrame;
+ got_frame: Integer;
+ data_size: Integer;
+begin
+ c := nil;
+ decoded_frame := nil;
+ av_init_packet(@avpkt);
+ WriteLn('Decode audio file %s to ', filename, outfilename);
+ (* find the mpeg audio decoder *)
+ codec := avcodec_find_decoder(AV_CODEC_ID_MP2);
+ if not Assigned(codec) then
+ begin
+ WriteLn('Codec not found');
+ Exit;
+ end;
+ c := avcodec_alloc_context3(codec);
+ if not Assigned(c) then
+ begin
+ WriteLn('Could not allocate audio codec context');
+ Exit;
+ end;
+ (* open it *)
+ if (avcodec_open2(c, codec, nil) < 0) then
+ begin
+ WriteLn('Could not open codec');
+ Exit;
+ end;
+ AssignFile(f, filename);
+ try
+ Reset(f, 1);
+ except
+ WriteLn('Could not open ', filename);
+ Exit;
+ end;
+ AssignFile(outfile, outfilename);
+ try
+ Rewrite(outfile, 1);
+ except
+ av_free(c);
+ Exit;
+ end;
+ (* decode until eof *)
+ avpkt.data := @inbuf;
+ BlockRead(f, inbuf, AUDIO_INBUF_SIZE, avpkt.size);
+ while (avpkt.size > 0) do
+ begin
+ got_frame := 0;
+ if not Assigned(decoded_frame) then
+ begin
+ decoded_frame := av_frame_alloc();
+ if not Assigned(decoded_frame) then
+ begin
+ WriteLn('Could not allocate audio frame');
+ Exit;
+ end;
+ end;
+ len := avcodec_decode_audio4(c, decoded_frame, got_frame, @avpkt);
+ if (len < 0) then
+ begin
+ WriteLn('Error while decoding');
+ Exit;
+ end;
+ if (got_frame <> 0) then
+ begin
+ (* if a frame has been decoded, output it *)
+ data_size := av_samples_get_buffer_size(nil, c^.channels, decoded_frame^.nb_samples, c^.sample_fmt, 1);
+ if (data_size < 0) then
+ begin
+ (* This should not occur, checking just for paranoia *)
+ WriteLn('Failed to calculate data size');
+ Exit;
+ end;
+ BlockWrite(outfile, decoded_frame^.data[0]^, data_size);
+ end;
+ avpkt.size := avpkt.size - len;
+ avpkt.data := avpkt.data + len;
+ avpkt.dts := AV_NOPTS_VALUE;
+ avpkt.pts := AV_NOPTS_VALUE;
+ if (avpkt.size < AUDIO_REFILL_THRESH) then
+ begin
+ (* Refill the input buffer, to avoid trying to decode
+ * incomplete frames. Instead of this, one could also use
+ * a parser, or use a proper container format through
+ * libavformat. *)
+ Move(avpkt.data^, inbuf, avpkt.size);
+ avpkt.data := @inbuf;
+ BlockRead(f, avpkt.data[avpkt.size], AUDIO_INBUF_SIZE - avpkt.size, len);
+ if (len > 0) then
+ avpkt.size := avpkt.size + len;
+ end;
+ end;
+ Close(outfile);
+ Close(f);
+ avcodec_close(c);
+ av_free(c);
+ av_frame_free(decoded_frame);
+end;
+
+(*
+ * Video encoding example
+*)
+procedure video_encode_example(const filename: String; codec_id: TAVCodecID);
+Var
+ codec: pAVCodec;
+ c: pAVCodecContext;
+ i, ret, x, y, got_output: Integer;
+ f: File;
+ frame: pAVFrame;
+ pkt: TAVPacket;
+ endcode: array [0 .. 3] of byte;
+begin
+ c := nil;
+ endcode[0] := 0;
+ endcode[1] := 0;
+ endcode[2] := 1;
+ endcode[3] := $B7;
+ WriteLn('Encode video file ', filename);
+ (* find the mpeg1 video encoder *)
+ codec := avcodec_find_encoder(codec_id);
+ if not Assigned(codec) then
+ begin
+ WriteLn('Codec not found');
+ Exit;
+ end;
+ c := avcodec_alloc_context3(codec);
+ if not Assigned(c) then
+ begin
+ WriteLn('Could not allocate video codec context');
+ Exit;
+ end;
+ (* put sample parameters *)
+ c^.bit_rate := 400000;
+ (* resolution must be a multiple of two *)
+ c^.width := 352;
+ c^.height := 288;
+ (* frames per second *)
+ c^.time_base.num := 1;
+ c^.time_base.den := 25;
+ (* emit one intra frame every ten frames
+ * check frame pict_type before passing frame
+ * to encoder, if frame^.pict_type is AV_PICTURE_TYPE_I
+ * then gop_size is ignored and the output of encoder
+ * will always be I frame irrespective to gop_size
+ *)
+ c^.gop_size := 10;
+ c^.max_b_frames := 1;
+ c^.pix_fmt := AV_PIX_FMT_YUV420P;
+ if (codec_id = AV_CODEC_ID_H264) then
+ av_opt_set(c^.priv_data, 'preset', 'slow', 0);
+ (* open it *)
+ if (avcodec_open2(c, codec, nil) < 0) then
+ begin
+ WriteLn('Could not open codec');
+ Exit;
+ end;
+ AssignFile(f, filename);
+ try
+ Rewrite(f, 1);
+ except
+ WriteLn('Could not open ', filename);
+ Exit;
+ end;
+ frame := av_frame_alloc();
+ if not Assigned(frame) then
+ begin
+ WriteLn('Could not allocate video frame');
+ Exit;
+ end;
+ frame^.format := Integer(c^.pix_fmt);
+ frame^.width := c^.width;
+ frame^.height := c^.height;
+ (* the image can be allocated by any means and av_image_alloc() is
+ * just the most convenient way if av_malloc() is to be used *)
+ ret := av_image_alloc(frame^.data, frame^.linesize, c^.width, c^.height, c^.pix_fmt, 32);
+ if (ret < 0) then
+ begin
+ WriteLn('Could not allocate raw picture buffer');
+ Exit;
+ end;
+// got_output:=0;
+ (* encode 1 second of video *)
+ for i := 0 to 24 do
+ begin
+ av_init_packet(@pkt);
+ pkt.data := nil; // packet data will be allocated by the encoder
+ pkt.size := 0;
+ (* prepare a dummy image *)
+
+ (* Y *)
+ for y := 0 to c^.height - 1 do
+ for x := 0 to c^.width - 1 do
+ frame^.data[0][y * frame^.linesize[0] + x] := x + y + i * 3;
+
+ (* Cb and Cr *)
+ for y := 0 to (c^.height div 2) - 1 do
+ for x := 0 to (c^.width div 2) - 1 do
+ begin
+ frame^.data[1][y * frame^.linesize[1] + x] := 128 + y + i * 2;
+ frame^.data[2][y * frame^.linesize[2] + x] := 64 + x + i * 5;
+ end;
+
+ frame^.pts := i;
+ (* encode the image *)
+ ret := avcodec_encode_video2(c, @pkt, frame, got_output);
+ if (ret < 0) then
+ begin
+ WriteLn('Error encoding frame');
+ Exit;
+ end;
+ if (got_output <> 0) then
+ begin
+ WriteLn(format('Write frame %3d (size=%5d)', [i, pkt.size]));
+ BlockWrite(f, pkt.data^, pkt.size);
+ av_free_packet(pkt);
+ end;
+ end;
+ (* get the delayed frames *)
+ got_output := 1;
+ While got_output <> 0 do
+ begin
+ ret := avcodec_encode_video2(c, @pkt, nil, got_output);
+ if (ret < 0) then
+ begin
+ WriteLn('Error encoding frame');
+ Exit;
+ end;
+ if (got_output <> 0) then
+ begin
+ WriteLn(format('Write frame %3d (size=%5d)', [i, pkt.size]));
+ BlockWrite(f, pkt.data^, pkt.size);
+ av_free_packet(pkt);
+ end;
+ Inc(i);
+ end;
+ (* add sequence end code to have a real mpeg file *)
+ BlockWrite(f, endcode, sizeof(endcode));
+ Close(f);
+// avcodec_close(c);
+ av_free(c);
+// av_freep(frame^.data[0]);
+ av_frame_free(frame);
+end;
+
+(*
+ * Video decoding example
+*)
+procedure pgm_save(buf: pByte; wrap, xsize, ysize: Integer; filename: String);
+Var
+ f: TextFile;
+ fb: File;
+ i: Integer;
+begin
+ AssignFile(f, filename);
+ Rewrite(f);
+ WriteLn(f, format('P5' + #13#10 + '%d %d' + #13#10 + '%d', [xsize, ysize, 255]));
+ Close(f);
+ AssignFile(fb, filename);
+ Reset(fb, 1);
+ Seek(fb, FileSize(fb));
+ for i := 0 to ysize - 1 do
+ BlockWrite(fb, buf[i * wrap], xsize);
+ Close(fb);
+end;
+
+function decode_write_frame(const outfilename: String; avctx: pAVCodecContext; frame: pAVFrame;
+ Var frame_count: Integer; pkt: pAVPacket; last: Integer): Integer;
+Var
+ len, got_frame: Integer;
+ buf: array [0 .. 1023] of AnsiChar;
+
+begin
+ len := avcodec_decode_video2(avctx, frame, got_frame, pkt);
+ if (len < 0) then
+ begin
+ WriteLn('Error while decoding frame ', frame_count);
+ Exit(len);
+ end;
+ if (got_frame <> 0) then
+ begin
+ if last <> 0 then
+ WriteLn(format('Saving last frame %3d', [frame_count]))
+ else
+ WriteLn(format('Saving frame %3d', [frame_count]));
+ (* the picture is allocated by the decoder, no need to free it *)
+ pgm_save(frame^.data[0], frame^.linesize[0], avctx^.width, avctx^.height, Format(outfilename, [frame_count]));
+ inc(frame_count);
+ end;
+ if Assigned(pkt^.data) then
+ begin
+ pkt^.size := pkt^.size - len;
+ pkt^.data := pkt^.data + len;
+ end;
+ Result := 0;
+end;
+
+procedure video_decode_example(const outfilename: String; const filename: String);
+Var
+ codec: pAVCodec;
+ c: pAVCodecContext;
+ frame_count: Integer;
+ f: File;
+ frame: pAVFrame;
+ inbuf: array [0 .. INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE - 1] of byte;
+ avpkt: TAVPacket;
+begin
+ c := nil;
+ av_init_packet(@avpkt);
+ (* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) *)
+ FillChar(inbuf[INBUF_SIZE], FF_INPUT_BUFFER_PADDING_SIZE, 0);
+ WriteLn(format('Decode video file %s to %s', [filename, outfilename]));
+ (* find the mpeg1 video decoder *)
+ codec := avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
+ if not Assigned(codec) then
+ begin
+ WriteLn('Codec not found');
+ Exit;
+ end;
+ c := avcodec_alloc_context3(codec);
+ if not Assigned(c) then
+ begin
+ WriteLn('Could not allocate video codec context');
+ Exit;
+ end;
+ if (codec^.capabilities and CODEC_CAP_TRUNCATED) <> 0 then
+ c^.flags := c^.flags or CODEC_FLAG_TRUNCATED; (* we do not send complete frames *)
+ (* For some codecs, such as msmpeg4 and mpeg4, width and height
+ MUST be initialized there because this information is not
+ available in the bitstream. *)
+ (* open it *)
+ if (avcodec_open2(c, codec, nil) < 0) then
+ begin
+ WriteLn('Could not open codec');
+ Exit;
+ end;
+ AssignFile(f, filename);
+ try
+ Reset(f, 1);
+ except
+ WriteLn('Could not open ', filename);
+ Exit;
+ end;
+ frame := av_frame_alloc();
+ if not Assigned(frame) then
+ begin
+ WriteLn('Could not allocate video frame');
+ Exit;
+ end;
+ frame_count := 0;
+ While True do
+ begin
+ BlockRead(f, inbuf, INBUF_SIZE, avpkt.size);
+ if (avpkt.size = 0) then
+ break;
+ (* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
+ and this is the only method to use them because you cannot
+ know the compressed data size before analysing it.
+ BUT some other codecs (msmpeg4, mpeg4) are inherently frame
+ based, so you must call them with all the data for one
+ frame exactly. You must also initialize 'width' and
+ 'height' before initializing them. *)
+ (* NOTE2: some codecs allow the raw parameters (frame size,
+ sample rate) to be changed at any frame. We handle this, so
+ you should also take care of it *)
+ (* here, we use a stream based decoder (mpeg1video), so we
+ feed decoder and see if it could decode a frame *)
+ avpkt.data := @inbuf;
+ while (avpkt.size > 0) do
+ if (decode_write_frame(outfilename, c, frame, frame_count, @avpkt, 0) < 0) then
+ Exit;
+ end;
+ (* some codecs, such as MPEG, transmit the I and P frame with a
+ latency of one frame. You must do the following to have a
+ chance to get the last frame of the video *)
+ avpkt.data := nil;
+ avpkt.size := 0;
+ decode_write_frame(outfilename, c, frame, frame_count, @avpkt, 1);
+ Close(f);
+ avcodec_close(c);
+ av_free(c);
+ av_frame_free(frame);
+end;
+
+Var
+ output_type: String;
+
+begin
+ try
+ (* register all the codecs *)
+ avcodec_register_all();
+ if ParamCount = 0 then
+ begin
+ WriteLn('usage: ' + ExtractFileName(ParamStr(0)) + ' output_type' + #13#10 +
+ 'API example program to decode/encode a media stream with libavcodec.' + #13#10 +
+ 'This program generates a synthetic stream and encodes it to a file' + #13#10 +
+ 'named test.h264, test.mp2 or test.mpg depending on output_type.' + #13#10 +
+ 'The encoded stream is then decoded and written to a raw data output.' + #13#10 +
+ 'output_type must be chosen between "h264", "mp2", "mpg"');
+ Halt;
+ end;
+ output_type := ParamStr(1);
+ if (SameText(output_type, 'h264')) then
+ video_encode_example('test.h264', AV_CODEC_ID_H264)
+ else if (SameText(output_type, 'mp2')) then
+ begin
+ audio_encode_example('test.mp2');
+ audio_decode_example('test.sw', 'test.mp2');
+ end
+ else if (SameText(output_type, 'mpg')) then
+ begin
+ video_encode_example('test.mpg', AV_CODEC_ID_MPEG1VIDEO);
+ video_decode_example('test%02d.pgm', 'test.mpg');
+ end
+ else
+ begin
+ WriteLn(format('Invalid output type "%s", choose between "h264", "mp2", or "mpg"', [output_type]));
+ Halt;
+ end;
+ except
+ on E: Exception do
+ WriteLn(E.ClassName, ': ', E.Message);
+ end;
+
+end.
diff --git a/samples/FFMpeg/decoding_encoding/decoding_encoding.dproj b/samples/FFMpeg/decoding_encoding/decoding_encoding.dproj
new file mode 100644
index 0000000..c41beaa
--- /dev/null
+++ b/samples/FFMpeg/decoding_encoding/decoding_encoding.dproj
@@ -0,0 +1,121 @@
+
+
+ {CE0FA7DD-82F4-40E1-868E-89238AA4468B}
+ decoding_encoding.dpr
+ True
+ Debug
+ 1
+ Console
+ None
+ 15.4
+ Win32
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_2
+ true
+ true
+
+
+ ..\..\..\bin\$(Platform)
+ None
+ .\$(Platform)\$(Config)
+ decoding_encoding
+ false
+ 1049
+ false
+ CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=
+ false
+ false
+ 00400000
+ System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
+ false
+
+
+ 1033
+ Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+
+
+ 0
+ RELEASE;$(DCC_Define)
+ 0
+ false
+
+
+ 1033
+ CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+
+
+ DEBUG;$(DCC_Define)
+ false
+ true
+
+
+ 1033
+ CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+
+
+
+ MainSource
+
+
+ Cfg_2
+ Base
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+
+ Delphi.Personality.12
+
+
+
+
+
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Microsoft Office XP Sample Automation Server Wrapper Components
+
+
+
+ False
+ True
+ False
+
+
+ 12
+
+
+
+
diff --git a/samples/FFMpeg/decoding_encoding/decoding_encoding.res b/samples/FFMpeg/decoding_encoding/decoding_encoding.res
new file mode 100644
index 0000000..7435995
Binary files /dev/null and b/samples/FFMpeg/decoding_encoding/decoding_encoding.res differ
diff --git a/samples/FFMpeg/ffmpeg_sample_player/ffmpeg_sample_player.dproj b/samples/FFMpeg/ffmpeg_sample_player/ffmpeg_sample_player.dproj
index c9dbb7e..2170089 100644
--- a/samples/FFMpeg/ffmpeg_sample_player/ffmpeg_sample_player.dproj
+++ b/samples/FFMpeg/ffmpeg_sample_player/ffmpeg_sample_player.dproj
@@ -34,7 +34,16 @@
Basetrue
+
+ true
+ Cfg_2
+ true
+ true
+
+ ..\..\..\bin\$(Platform)
+ .\$(Platform)\$(Config)
+ Nonefalse1049System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
@@ -58,9 +67,6 @@
0
- .\$(Platform)\$(Config)
- ..\..\..\bin\$(Platform)
- NoneCompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=1033
@@ -69,6 +75,10 @@
DEBUG;$(DCC_Define)false
+
+ 1033
+ CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
+ MainSource
diff --git a/source/component/Delphi20/OpenCV200.dproj b/source/component/Delphi20/OpenCV200.dproj
index 3528721..2e4d653 100644
--- a/source/component/Delphi20/OpenCV200.dproj
+++ b/source/component/Delphi20/OpenCV200.dproj
@@ -230,7 +230,7 @@
..;$(DCC_UnitSearchPath)true1033
- CompanyName=;FileDescription=OpenCV Component;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=OpenCV Component;ProductVersion=1.0.0.0;Comments=;LastCompiledTime=18.07.2014 0:09:25
+ CompanyName=;FileDescription=OpenCV Component;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=OpenCV Component;ProductVersion=1.0.0.0;Comments=;LastCompiledTime=22.07.2014 15:39:50true
diff --git a/source/component/Delphi20/dclOpenCV200.dproj b/source/component/Delphi20/dclOpenCV200.dproj
index 3128ebd..7925a41 100644
--- a/source/component/Delphi20/dclOpenCV200.dproj
+++ b/source/component/Delphi20/dclOpenCV200.dproj
@@ -138,7 +138,7 @@
true1033
- CompanyName=;FileDescription=OpenCV Component;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=OpenCV Component;ProductVersion=1.0.0.0;Comments=;LastCompiledTime=18.07.2014 22:36:06
+ CompanyName=;FileDescription=OpenCV Component;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=OpenCV Component;ProductVersion=1.0.0.0;Comments=;LastCompiledTime=22.07.2014 15:39:57.\$(Platform)\$(Config)
diff --git a/source/component/Delphi20/dclOpenCV200.res b/source/component/Delphi20/dclOpenCV200.res
index 39bfedc..9d9867f 100644
Binary files a/source/component/Delphi20/dclOpenCV200.res and b/source/component/Delphi20/dclOpenCV200.res differ
diff --git a/source/component/ocv.comp.Source.pas b/source/component/ocv.comp.Source.pas
index 3299050..eeff70c 100644
--- a/source/component/ocv.comp.Source.pas
+++ b/source/component/ocv.comp.Source.pas
@@ -46,37 +46,37 @@ uses
type
TocvCameraCaptureSource =
//
- (CAP_ANY {= 0} , // autodetect
- CAP_CAM_0 {=0} , //
- CAP_CAM_1 {=1} , //
- CAP_CAM_2 {=2} , //
- CAP_CAM_3 {=3} , //
- CAP_CAM_4 {=4} , //
- CAP_CAM_5 {=5} , //
- CAP_MIL {= 100} , // MIL proprietary drivers
- CAP_VFW {= 200} , // platform native
- CAP_V4L {= 200} , //
- CAP_V4L2 {= 200} , //
- CAP_FIREWARE {= 300} , // IEEE 1394 drivers
- CAP_FIREWIRE {= 300} , //
- CAP_IEEE1394 {= 300} , //
- CAP_DC1394 {= 300} , //
- CAP_CMU1394 {= 300} , //
- CAP_STEREO {= 400} , // TYZX proprietary drivers
- CAP_TYZX {= 400} , //
- TYZX_LEFT {= 400} , //
- TYZX_RIGHT {= 401} , //
- TYZX_COLOR {= 402} , //
- TYZX_Z {= 403} , //
- CAP_QT {= 500} , // QuickTime
- CAP_UNICAP {= 600} , // Unicap drivers
- CAP_DSHOW {= 700} , // DirectShow (via videoInput)
- CAP_PVAPI {= 800} , // PvAPI, Prosilica GigE SDK
- CAP_OPENNI {= 900} , // OpenNI (for Kinect)
- CAP_OPENNI_ASUS {= 910} , // OpenNI (for Asus Xtion)
- CAP_ANDROID {= 1000} , // Android
- CAP_XIAPI {= 1100} , // XIMEA Camera API
- CAP_AVFOUNDATION {= 1200} );
+ (CAP_ANY { = 0 } , // autodetect
+ CAP_CAM_0 { =0 } , //
+ CAP_CAM_1 { =1 } , //
+ CAP_CAM_2 { =2 } , //
+ CAP_CAM_3 { =3 } , //
+ CAP_CAM_4 { =4 } , //
+ CAP_CAM_5 { =5 } , //
+ CAP_MIL { = 100 } , // MIL proprietary drivers
+ CAP_VFW { = 200 } , // platform native
+ CAP_V4L { = 200 } , //
+ CAP_V4L2 { = 200 } , //
+ CAP_FIREWARE { = 300 } , // IEEE 1394 drivers
+ CAP_FIREWIRE { = 300 } , //
+ CAP_IEEE1394 { = 300 } , //
+ CAP_DC1394 { = 300 } , //
+ CAP_CMU1394 { = 300 } , //
+ CAP_STEREO { = 400 } , // TYZX proprietary drivers
+ CAP_TYZX { = 400 } , //
+ TYZX_LEFT { = 400 } , //
+ TYZX_RIGHT { = 401 } , //
+ TYZX_COLOR { = 402 } , //
+ TYZX_Z { = 403 } , //
+ CAP_QT { = 500 } , // QuickTime
+ CAP_UNICAP { = 600 } , // Unicap drivers
+ CAP_DSHOW { = 700 } , // DirectShow (via videoInput)
+ CAP_PVAPI { = 800 } , // PvAPI, Prosilica GigE SDK
+ CAP_OPENNI { = 900 } , // OpenNI (for Kinect)
+ CAP_OPENNI_ASUS { = 910 } , // OpenNI (for Asus Xtion)
+ CAP_ANDROID { = 1000 } , // Android
+ CAP_XIAPI { = 1100 } , // XIMEA Camera API
+ CAP_AVFOUNDATION { = 1200 } );
type
@@ -164,6 +164,12 @@ type
property OnEndOfFile: TNotifyEvent read FOnEndOfFile Write FOnEndOfFile;
end;
+ TocvIPProtocol = ( //
+ ippHTTP, //
+ ippHTTPS, //
+ ippRTSP //
+ ); //
+
TocvIPCamSource = class(TocvCaptureSource)
private
FPort: Word;
@@ -171,6 +177,7 @@ type
FIP: string;
FUserName: String;
FURI: string;
+ FProtocol: TocvIPProtocol;
protected
function GetIPCamTarget: AnsiString;
procedure SetEnabled(Value: Boolean); override;
@@ -180,8 +187,9 @@ type
property UserName: String read FUserName write FUserName;
property Password: string read FPassword write FPassword;
property IP: string read FIP write FIP;
- property URI: string read FURI write FURI; {TODO: Need rename}
+ property URI: string read FURI write FURI; { TODO: Need rename }
property Port: Word read FPort write FPort default 554;
+ property Protocol: TocvIPProtocol read FProtocol write FProtocol default ippRTSP;
end;
TOnNotifyFFMpegPacket = procedure(Sender: TObject; const packet: TAVPacket; const isKeyFrame: Boolean) of object;
@@ -205,7 +213,7 @@ type
property UserName: String read FUserName write FUserName;
property Password: string read FPassword write FPassword;
property IP: string read FIP write FIP;
- property URI: string read FURI write FURI; {TODO: Need rename}
+ property URI: string read FURI write FURI; { TODO: Need rename }
property Port: Word read FPort write FPort default 554;
property OnFFMpegPacket: TOnNotifyFFMpegPacket read FOnNotifyFFMpegPacket write FOnNotifyFFMpegPacket;
end;
@@ -289,11 +297,11 @@ Type
end;
Const
- CameraResolution: array [TocvResolution] of TCameraResolution = ((cWidth: 160; cHeight: 120), (cWidth: 320; cHeight: 240),
- (cWidth: 424; cHeight: 240), (cWidth: 640; cHeight: 360), (cWidth: 800; cHeight: 448), (cWidth: 960; cHeight: 544),
- (cWidth: 1280; cHeight: 720));
+ CameraResolution: array [TocvResolution] of TCameraResolution = ((cWidth: 160; cHeight: 120), (cWidth: 320;
+ cHeight: 240), (cWidth: 424; cHeight: 240), (cWidth: 640; cHeight: 360), (cWidth: 800; cHeight: 448), (cWidth: 960;
+ cHeight: 544), (cWidth: 1280; cHeight: 720));
- {TOpenCVCameraThread}
+ { TOpenCVCameraThread }
procedure TocvCaptureThread.Execute;
Var
@@ -335,7 +343,7 @@ begin
Suspend;
end;
-{TOpenCVCamera}
+{ TOpenCVCamera }
constructor TocvCameraSource.Create(AOwner: TComponent);
begin
@@ -407,7 +415,7 @@ begin
end;
end;
-{TocvCustomSource}
+{ TocvCustomSource }
constructor TocvCustomSource.Create(AOwner: TComponent);
begin
@@ -459,7 +467,7 @@ begin
end;
-{TocvFileSourceclass}
+{ TocvFileSourceclass }
constructor TocvFileSource.Create(AOwner: TComponent);
begin
@@ -528,7 +536,7 @@ begin
end;
end;
-{TocvCustomSourceThread}
+{ TocvCustomSourceThread }
constructor TocvCustomSourceThread.Create(CreateSuspended: Boolean);
begin
@@ -543,17 +551,25 @@ begin
inherited;
end;
-{TocvIPCamSource}
+{ TocvIPCamSource }
constructor TocvIPCamSource.Create(AOwner: TComponent);
begin
inherited;
FPort := 554;
+ FProtocol := ippRTSP;
end;
function TocvIPCamSource.GetIPCamTarget: AnsiString;
+const
+ IPProtocolString: array [TocvIPProtocol] of AnsiString = ( //
+ 'http://', //
+ 'https://', //
+ 'rtsp://' //
+ );
+
begin
- Result := 'rtsp://';
+ Result := IPProtocolString[FProtocol];
if Length(Trim(UserName)) <> 0 then
Result := Result + AnsiString(Trim(UserName)) + ':' + AnsiString(Trim(Password)) + '@';
Result := Result + AnsiString(IP) + ':' + AnsiString(IntToStr(Port));
@@ -591,7 +607,7 @@ begin
end;
end;
-{TocvCaptureSource}
+{ TocvCaptureSource }
constructor TocvCaptureSource.Create(AOwner: TComponent);
begin
@@ -626,7 +642,7 @@ begin
end;
end;
-{TocvFFMpegIPCamSource}
+{ TocvFFMpegIPCamSource }
constructor TocvFFMpegIPCamSource.Create(AOwner: TComponent);
begin
@@ -692,7 +708,7 @@ begin
end;
end;
-{TocvFFMpegIPCamSourceThread}
+{ TocvFFMpegIPCamSourceThread }
constructor TocvFFMpegIPCamSourceThread.Create(AOwner: TocvFFMpegIPCamSource);
begin
@@ -831,7 +847,7 @@ begin
end;
if (pCodec^.capabilities and CODEC_CAP_TRUNCATED) = 0 then
- pCodecCtx^.flags := pCodecCtx^.flags or CODEC_FLAG_TRUNCATED; (*we dont send complete frames*)
+ pCodecCtx^.flags := pCodecCtx^.flags or CODEC_FLAG_TRUNCATED; (* we dont send complete frames *)
// Open codec
if avcodec_open2(pCodecCtx, pCodec, nil) < 0 then
begin
@@ -839,8 +855,8 @@ begin
Continue;
end;
- img_convert_context := sws_getCachedContext(nil, pCodecCtx^.Width, pCodecCtx^.Height, pCodecCtx^.pix_fmt, pCodecCtx^.Width,
- pCodecCtx^.Height, AV_PIX_FMT_BGR24, SWS_BILINEAR, nil, nil, nil);
+ img_convert_context := sws_getCachedContext(nil, pCodecCtx^.Width, pCodecCtx^.Height, pCodecCtx^.pix_fmt,
+ pCodecCtx^.Width, pCodecCtx^.Height, AV_PIX_FMT_BGR24, SWS_BILINEAR, nil, nil, nil);
if (img_convert_context = nil) then
begin
isReconnect := True;
@@ -866,7 +882,8 @@ begin
avcodec_decode_video2(pCodecCtx, frame, frame_finished, @packet);
if (frame_finished <> 0) then
begin
- sws_scale(img_convert_context, @frame^.data, @frame^.linesize, 0, pCodecCtx^.Height, @iplframe^.imageData, @linesize);
+ sws_scale(img_convert_context, @frame^.data, @frame^.linesize, 0, pCodecCtx^.Height, @iplframe^.imageData,
+ @linesize);
if Assigned(OnNotifyData) then
Synchronize(
procedure
diff --git a/source/component/ocv.comp.View.pas b/source/component/ocv.comp.View.pas
index a43c310..313c7e8 100644
--- a/source/component/ocv.comp.View.pas
+++ b/source/component/ocv.comp.View.pas
@@ -45,7 +45,8 @@ uses
Graphics,
{$ENDIF VER6P}
ocv.comp.Types,
- ocv.core.types_c, System.SyncObjs;
+ ocv.core.types_c,
+ System.SyncObjs;
type
diff --git a/source/ffmpeg/ffm.avformat.pas b/source/ffmpeg/ffm.avformat.pas
index 426a8ad..3a4fb2d 100644
--- a/source/ffmpeg/ffm.avformat.pas
+++ b/source/ffmpeg/ffm.avformat.pas
@@ -279,11 +279,11 @@ uses
* num is assumed to be 0 <= num < den.
*)
Type
- TAVFrac = {packed} record
+ TAVFrac = { packed } record
val, num, den: int64_t;
end;
- (************************************************/
+ (* ***********************************************/
* input/output formats
*)
@@ -380,8 +380,8 @@ const
AV_PROGRAM_RUNNING = 1;
//
- AVFMTCTX_NOHEADER = $0001; (*< signal that no header is present
- (streams are added dynamically)*)
+ AVFMTCTX_NOHEADER = $0001; (* < signal that no header is present
+ (streams are added dynamically) *)
//
RAW_PACKET_BUFFER_SIZE = 2500000;
@@ -397,15 +397,15 @@ type
*)
pAVProbeData = ^TAVProbeData;
- TAVProbeData = {packed} record
+ TAVProbeData = { packed } record
filename: pAnsiChar;
- buf: pByte; (*< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.*)
- buf_size: Integer; (*< Size of buf except extra allocated bytes*)
+ buf: pByte; (* < Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. *)
+ buf_size: Integer; (* < Size of buf except extra allocated bytes *)
end;
pAVOutputFormat = ^TAVOutputFormat;
- TAVOutputFormat = {packed} record
+ TAVOutputFormat = { packed } record
name: pAnsiChar;
(*
* Descriptive name for the format, meant to be more human-readable
@@ -433,7 +433,7 @@ type
codec_tag: ppAVCodecTag;
priv_class: pAVClass; // < AVClass for the private context
- (****************************************************************
+ (* ***************************************************************
* No fields below this line are part of the public API. They
* may not be used outside of libavformat and can be changed and
* removed at will.
@@ -479,7 +479,7 @@ type
pAVInputFormat = ^TAVInputFormat;
- TAVInputFormat = {packed} record
+ TAVInputFormat = { packed } record
(*
* A comma separated list of short names for the format. New names
* may be appended with a minor bump.
@@ -569,7 +569,8 @@ type
* @return the timestamp or AV_NOPTS_VALUE if an error occurred
*)
// int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, int64_t *pos, int64_t pos_limit);
- read_timestamp: function(s: pAVFormatContext; stream_index: Integer; pos: pint64_t; pos_limit: int64_t): int64_t; cdecl;
+ read_timestamp: function(s: pAVFormatContext; stream_index: Integer; pos: pint64_t; pos_limit: int64_t)
+ : int64_t; cdecl;
(*
* Start/resume playing - only meaningful if using a network-based format
* (RTSP).
@@ -594,16 +595,18 @@ type
TAVStreamParseType = ( //
AVSTREAM_PARSE_NONE, AVSTREAM_PARSE_FULL, // **< full parsing and repack */
AVSTREAM_PARSE_HEADERS, // **< Only parse headers, do not repack. */
- AVSTREAM_PARSE_TIMESTAMPS, // **< full parsing and interpolation of timestamps for frames not starting on a packet boundary */
- AVSTREAM_PARSE_FULL_ONCE, // **< full parsing and repack of the first frame only, only implemented for H.264 currently */
+ AVSTREAM_PARSE_TIMESTAMPS,
+ // **< full parsing and interpolation of timestamps for frames not starting on a packet boundary */
+ AVSTREAM_PARSE_FULL_ONCE,
+ // **< full parsing and repack of the first frame only, only implemented for H.264 currently */
AVSTREAM_PARSE_FULL_RAW = $57415230 // MKTAG(0,'R','A','W')
- (*< full parsing and repack with timestamp and position generation by parser for raw
+ (* < full parsing and repack with timestamp and position generation by parser for raw
this assumes that each packet in the file contains no demuxer level headers and
- just codec level data, otherwise position generation would fail*)
+ just codec level data, otherwise position generation would fail *)
);
pAVIndexEntry = ^TAVIndexEntry;
- TAVIndexEntry = {packed} record
+ TAVIndexEntry = { packed } record
pos: int64_t;
timestamp: int64_t;
// * Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are available
@@ -613,7 +616,8 @@ type
// int flags:2;
// int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment).
flag_size: int32;
- min_distance: Integer; (*< Minimum distance between this and the previous keyframe, used to avoid unneeded searching.*)
+ min_distance: Integer;
+ (* < Minimum distance between this and the previous keyframe, used to avoid unneeded searching. *)
end;
(*
* Track should be used during playback by default.
@@ -659,7 +663,7 @@ type
pInfo = ^TInfo;
- TInfo = {packed} record
+ TInfo = { packed } record
last_dts: int64_t;
duration_gcd: int64_t;
duration_count: Integer;
@@ -682,7 +686,7 @@ type
pAVStream = ^TAVStream;
ppAVStream = ^pAVStream;
- TAVStream = {packed} record
+ TAVStream = { packed } record
index: Integer; // **< stream index in AVFormatContext */
(*
* Format-specific stream ID.
@@ -755,7 +759,7 @@ type
* encoding: unused
*)
attached_pic: TAVPacket;
- (****************************************************************
+ (* ***************************************************************
* All fields below this line are not part of the public API. They
* may not be used outside of libavformat and can be changed and
* removed at will.
@@ -805,8 +809,8 @@ type
probe_data: TAVProbeData;
// #define MAX_REORDER_DELAY 16
pts_buffer: array [0 .. MAX_REORDER_DELAY] of int64_t;
- index_entries: pAVIndexEntry; (*< Only used if the format does not
- support seeking natively.*)
+ index_entries: pAVIndexEntry; (* < Only used if the format does not
+ support seeking natively. *)
nb_index_entries: Integer;
index_entries_allocated_size: Cardinal;
(*
@@ -887,7 +891,7 @@ type
pAVProgram = ^TAVProgram;
ppAVProgram = ^pAVProgram;
- TAVProgram = {packed} record
+ TAVProgram = { packed } record
id: Integer;
flags: Integer;
discard: TAVDiscard;
@@ -898,7 +902,7 @@ type
program_num: Integer;
pmt_pid: Integer;
pcr_pid: Integer;
- (****************************************************************
+ (* ***************************************************************
* All fields below this line are not part of the public API. They
* may not be used outside of libavformat and can be changed and
* removed at will.
@@ -916,7 +920,7 @@ type
pAVChapter = ^TAVChapter;
ppAVChapter = ^pAVChapter;
- TAVChapter = {packed} record
+ TAVChapter = { packed } record
id: Integer;
/// < unique ID to identify the chapter
time_base: TAVRational;
@@ -939,7 +943,7 @@ type
/// < Duration estimated from bitrate (less accurate)
);
- (**
+ (* *
* Format I/O context.
* New fields can be added to the end with minor version bumps.
* Removal, reordering and changes to existing fields require a major
@@ -948,7 +952,7 @@ type
* avformat_alloc_context() to create an AVFormatContext.
*)
- TAVFormatContext = {packed} record
+ TAVFormatContext = { packed } record
(*
* A class for logging and AVOptions. Set by avformat_alloc_context().
* Exports (de)muxer private options if they exist.
@@ -980,7 +984,7 @@ type
*)
pb: pAVIOContext;
- (*stream info*)
+ (* stream info *)
ctx_flags: Integer; // **< Format-specific flags, see AVFMTCTX_xx */
(*
@@ -1209,7 +1213,7 @@ type
*)
// int probe_score;
probe_score: Integer;
- (****************************************************************
+ (* ***************************************************************
* All fields below this line are not part of the public API. They
* may not be used outside of libavformat and can be changed and
* removed at will.
@@ -1227,7 +1231,7 @@ type
// struct AVPacketList *packet_buffer_end;
packet_buffer_end: pAVPacketList;
- (*av_seek_frame() support*)
+ (* av_seek_frame() support *)
// int64_t data_offset; /**< offset of the first packet */
data_offset: int64_t;
@@ -1320,7 +1324,7 @@ type
*)
// enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx);
- TAVPacketList = {packed} record
+ TAVPacketList = { packed } record
pkt: TAVPacket;
next: pAVPacketList;
end;
@@ -1460,8 +1464,8 @@ function avformat_new_stream(s: pAVFormatContext; const c: pAVCodec): pAVStream;
* failure
*)
// int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename);
-function avformat_alloc_output_context2(Var ctx: pAVFormatContext; oformat: pAVOutputFormat; const format_name: pAnsiChar;
- const filename: pAnsiChar): Integer; cdecl;
+function avformat_alloc_output_context2(Var ctx: pAVFormatContext; oformat: pAVOutputFormat;
+ const format_name: pAnsiChar; const filename: pAnsiChar): Integer; cdecl;
(*
// * @addtogroup lavf_decoding
// * @{
@@ -1550,8 +1554,8 @@ function avformat_alloc_output_context2(Var ctx: pAVFormatContext; oformat: pAVO
*)
// int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
-function avformat_open_input(var ps: pAVFormatContext; const filename: pAnsiChar; fmt: pAVInputFormat; options: ppAVDictionary)
- : Integer; cdecl;
+function avformat_open_input(var ps: pAVFormatContext; const filename: pAnsiChar; fmt: pAVInputFormat;
+ options: ppAVDictionary): Integer; cdecl;
// attribute_deprecated
// int av_demuxer_open(AVFormatContext *ic);
@@ -1641,8 +1645,8 @@ function avformat_find_stream_info(ic: pAVFormatContext; options: ppAVDictionary
// int related_stream,
// AVCodec **decoder_ret,
// int flags);
-function av_find_best_stream(ic: pAVFormatContext; _type: TAVMediaType; wanted_stream_nb: Integer; related_stream: Integer;
- Var decoder_ret: pAVCodec; flags: Integer): Integer; cdecl;
+function av_find_best_stream(ic: pAVFormatContext; _type: TAVMediaType; wanted_stream_nb: Integer;
+ related_stream: Integer; Var decoder_ret: pAVCodec; flags: Integer): Integer; cdecl;
// #if FF_API_READ_PACKET
(*
@@ -1815,7 +1819,7 @@ procedure avformat_close_input(Var s: pAVFormatContext); cdecl;
// * @see av_opt_find, av_dict_set, avio_open, av_oformat_next.
*)
// int avformat_write_header(AVFormatContext *s, AVDictionary **options);
-function avformat_write_header(s: pAVFormatContext; options: ppAVDictionary):Integer; cdecl;
+function avformat_write_header(s: pAVFormatContext; options: ppAVDictionary): Integer; cdecl;
(*
// * Write a packet to an output media file.
// *
@@ -1833,7 +1837,7 @@ function avformat_write_header(s: pAVFormatContext; options: ppAVDictionary):Int
// * @return < 0 on error, = 0 if OK, 1 if flushed and there is no more data to flush
*)
// int av_write_frame(AVFormatContext *s, AVPacket *pkt);
-//
+function av_write_frame(s: pAVFormatContext; pkt: pAVPacket): Integer; cdecl;
(*
// * Write a packet to an output media file ensuring correct interleaving.
// *
@@ -1861,7 +1865,7 @@ function avformat_write_header(s: pAVFormatContext; options: ppAVDictionary):Int
// * @return 0 on success, a negative AVERROR on error.
*)
// int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);
-function av_interleaved_write_frame(s:pAVFormatContext; pkt:pAVPacket):Integer; cdecl;
+function av_interleaved_write_frame(s: pAVFormatContext; pkt: pAVPacket): Integer; cdecl;
(*
// * Write the stream trailer to an output media file and free the
@@ -2223,5 +2227,6 @@ function avformat_write_header; external avformat_dll;
function av_write_trailer; external avformat_dll;
function avformat_new_stream; external avformat_dll;
function av_interleaved_write_frame; external avformat_dll;
+function av_write_frame; external avformat_dll;
end.
diff --git a/source/ffmpeg/ffm.channel_layout.pas b/source/ffmpeg/ffm.channel_layout.pas
new file mode 100644
index 0000000..1c73f5b
--- /dev/null
+++ b/source/ffmpeg/ffm.channel_layout.pas
@@ -0,0 +1,234 @@
+(*
+ * Copyright (c) 2006 Michael Niedermayer
+ * Copyright (c) 2008 Peter Ross
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*)
+
+unit ffm.channel_layout;
+
+{$i ffmpeg.inc}
+
+interface
+
+Uses
+ ffm.ctypes;
+
+(* *
+ * @file
+ * audio channel layout utility functions
+*)
+
+(* *
+ * @addtogroup lavu_audio
+ * @{
+*)
+
+(* *
+ * @defgroup channel_masks Audio channel masks
+ *
+ * A channel layout is a 64-bits integer with a bit set for every channel.
+ * The number of bits set must be equal to the number of channels.
+ * The value 0 means that the channel layout is not known.
+ * @note this data structure is not powerful enough to handle channels
+ * combinations that have the same channel multiple times, such as
+ * dual-mono.
+ *
+ * @{
+*)
+Const
+ AV_CH_FRONT_LEFT = $00000001;
+ AV_CH_FRONT_RIGHT = $00000002;
+ AV_CH_FRONT_CENTER = $00000004;
+ AV_CH_LOW_FREQUENCY = $00000008;
+ AV_CH_BACK_LEFT = $00000010;
+ AV_CH_BACK_RIGHT = $00000020;
+ AV_CH_FRONT_LEFT_OF_CENTER = $00000040;
+ AV_CH_FRONT_RIGHT_OF_CENTER = $00000080;
+ AV_CH_BACK_CENTER = $00000100;
+ AV_CH_SIDE_LEFT = $00000200;
+ AV_CH_SIDE_RIGHT = $00000400;
+ AV_CH_TOP_CENTER = $00000800;
+ AV_CH_TOP_FRONT_LEFT = $00001000;
+ AV_CH_TOP_FRONT_CENTER = $00002000;
+ AV_CH_TOP_FRONT_RIGHT = $00004000;
+ AV_CH_TOP_BACK_LEFT = $00008000;
+ AV_CH_TOP_BACK_CENTER = $00010000;
+ AV_CH_TOP_BACK_RIGHT = $00020000;
+ AV_CH_STEREO_LEFT = $20000000;
+ /// < Stereo downmix.
+ AV_CH_STEREO_RIGHT = $40000000;
+ /// < See AV_CH_STEREO_LEFT.
+ AV_CH_WIDE_LEFT = $0000000080000000;
+ AV_CH_WIDE_RIGHT = $0000000100000000;
+ AV_CH_SURROUND_DIRECT_LEFT = $0000000200000000;
+ AV_CH_SURROUND_DIRECT_RIGHT = $0000000400000000;
+ AV_CH_LOW_FREQUENCY_2 = $0000000800000000;
+
+ (* * Channel mask value used for AVCodecContext.request_channel_layout
+ to indicate that the user requests the channel order of the decoder output
+ to be the native codec channel order. *)
+ AV_CH_LAYOUT_NATIVE = $8000000000000000;
+
+ (* *
+ * @}
+ * @defgroup channel_mask_c Audio channel convenience macros
+ * @{
+ * *)
+ AV_CH_LAYOUT_MONO = (AV_CH_FRONT_CENTER);
+ AV_CH_LAYOUT_STEREO = (AV_CH_FRONT_LEFT or AV_CH_FRONT_RIGHT);
+ AV_CH_LAYOUT_2POINT1 = (AV_CH_LAYOUT_STEREO or AV_CH_LOW_FREQUENCY);
+ AV_CH_LAYOUT_2_1 = (AV_CH_LAYOUT_STEREO or AV_CH_BACK_CENTER);
+ AV_CH_LAYOUT_SURROUND = (AV_CH_LAYOUT_STEREO or AV_CH_FRONT_CENTER);
+ AV_CH_LAYOUT_3POINT1 = (AV_CH_LAYOUT_SURROUND or AV_CH_LOW_FREQUENCY);
+ AV_CH_LAYOUT_4POINT0 = (AV_CH_LAYOUT_SURROUND or AV_CH_BACK_CENTER);
+ AV_CH_LAYOUT_4POINT1 = (AV_CH_LAYOUT_4POINT0 or AV_CH_LOW_FREQUENCY);
+ AV_CH_LAYOUT_2_2 = (AV_CH_LAYOUT_STEREO or AV_CH_SIDE_LEFT or AV_CH_SIDE_RIGHT);
+ AV_CH_LAYOUT_QUAD = (AV_CH_LAYOUT_STEREO or AV_CH_BACK_LEFT or AV_CH_BACK_RIGHT);
+ AV_CH_LAYOUT_5POINT0 = (AV_CH_LAYOUT_SURROUND or AV_CH_SIDE_LEFT or AV_CH_SIDE_RIGHT);
+ AV_CH_LAYOUT_5POINT1 = (AV_CH_LAYOUT_5POINT0 or AV_CH_LOW_FREQUENCY);
+ AV_CH_LAYOUT_5POINT0_BACK = (AV_CH_LAYOUT_SURROUND or AV_CH_BACK_LEFT or AV_CH_BACK_RIGHT);
+ AV_CH_LAYOUT_5POINT1_BACK = (AV_CH_LAYOUT_5POINT0_BACK or AV_CH_LOW_FREQUENCY);
+ AV_CH_LAYOUT_6POINT0 = (AV_CH_LAYOUT_5POINT0 or AV_CH_BACK_CENTER);
+ AV_CH_LAYOUT_6POINT0_FRONT = (AV_CH_LAYOUT_2_2 or AV_CH_FRONT_LEFT_OF_CENTER or AV_CH_FRONT_RIGHT_OF_CENTER);
+ AV_CH_LAYOUT_HEXAGONAL = (AV_CH_LAYOUT_5POINT0_BACK or AV_CH_BACK_CENTER);
+ AV_CH_LAYOUT_6POINT1 = (AV_CH_LAYOUT_5POINT1 or AV_CH_BACK_CENTER);
+ AV_CH_LAYOUT_6POINT1_BACK = (AV_CH_LAYOUT_5POINT1_BACK or AV_CH_BACK_CENTER);
+ AV_CH_LAYOUT_6POINT1_FRONT = (AV_CH_LAYOUT_6POINT0_FRONT or AV_CH_LOW_FREQUENCY);
+ AV_CH_LAYOUT_7POINT0 = (AV_CH_LAYOUT_5POINT0 or AV_CH_BACK_LEFT or AV_CH_BACK_RIGHT);
+ AV_CH_LAYOUT_7POINT0_FRONT = (AV_CH_LAYOUT_5POINT0 or AV_CH_FRONT_LEFT_OF_CENTER or AV_CH_FRONT_RIGHT_OF_CENTER);
+ AV_CH_LAYOUT_7POINT1 = (AV_CH_LAYOUT_5POINT1 or AV_CH_BACK_LEFT or AV_CH_BACK_RIGHT);
+ AV_CH_LAYOUT_7POINT1_WIDE = (AV_CH_LAYOUT_5POINT1 or AV_CH_FRONT_LEFT_OF_CENTER or AV_CH_FRONT_RIGHT_OF_CENTER);
+ AV_CH_LAYOUT_7POINT1_WIDE_BACK = (AV_CH_LAYOUT_5POINT1_BACK or AV_CH_FRONT_LEFT_OF_CENTER or
+ AV_CH_FRONT_RIGHT_OF_CENTER);
+ AV_CH_LAYOUT_OCTAGONAL = (AV_CH_LAYOUT_5POINT0 or AV_CH_BACK_LEFT or AV_CH_BACK_CENTER or AV_CH_BACK_RIGHT);
+ AV_CH_LAYOUT_STEREO_DOWNMIX = (AV_CH_STEREO_LEFT or AV_CH_STEREO_RIGHT);
+
+Type
+ TAVMatrixEncoding = ( //
+ AV_MATRIX_ENCODING_NONE, //
+ AV_MATRIX_ENCODING_DOLBY, //
+ AV_MATRIX_ENCODING_DPLII, //
+ AV_MATRIX_ENCODING_DPLIIX, //
+ AV_MATRIX_ENCODING_DPLIIZ, //
+ AV_MATRIX_ENCODING_DOLBYEX, //
+ AV_MATRIX_ENCODING_DOLBYHEADPHONE, //
+ AV_MATRIX_ENCODING_NB);
+
+ (* *
+ * @}
+ *)
+
+ (* *
+ * Return a channel layout id that matches name, or 0 if no match is found.
+ *
+ * name can be one or several of the following notations,
+ * separated by '+' or ' or ':
+ * - the name of an usual channel layout (mono, stereo, 4.0, quad, 5.0,
+ * 5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix);
+ * - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC,
+ * SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR);
+ * - a number of channels, in decimal, optionally followed by 'c', yielding
+ * the default channel layout for that number of channels (@see
+ * av_get_default_channel_layout);
+ * - a channel layout mask, in hexadecimal starting with "$" (see the
+ * AV_CH_* macros).
+ *
+ * @warning Starting from the next major bump the trailing character
+ * 'c' to specify a number of channels will be required, while a
+ * channel layout mask could also be specified as a decimal number
+ * (if and only if not followed by "c").
+ *
+ * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "$7"
+ *)
+ // uint64_t av_get_channel_layout(const char *name);
+
+ (* *
+ * Return a description of a channel layout.
+ * If nb_channels is <= 0, it is guessed from the channel_layout.
+ *
+ * @param buf put here the string containing the channel layout
+ * @param buf_size size in bytes of the buffer
+ *)
+ // void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout);
+
+ // struct AVBPrint;
+ (* *
+ * Append a description of a channel layout to a bprint buffer.
+ *)
+ // void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout);
+
+ (* *
+ * Return the number of channels in the channel layout.
+ *)
+ // int av_get_channel_layout_nb_channels(uint64_t channel_layout);
+function av_get_channel_layout_nb_channels(channel_layout: uint64_t): Integer; cdecl;
+
+(* *
+ * Return default channel layout for a given number of channels.
+*)
+// int64_t av_get_default_channel_layout(int nb_channels);
+
+(* *
+ * Get the index of a channel in channel_layout.
+ *
+ * @param channel a channel layout describing exactly one channel which must be
+ * present in channel_layout.
+ *
+ * @return index of channel in channel_layout on success, a negative AVERROR
+ * on error.
+*)
+// int av_get_channel_layout_channel_index(uint64_t channel_layout,uint64_t channel);
+
+(* *
+ * Get the channel with the given index in channel_layout.
+*)
+// uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index);
+
+(* *
+ * Get the name of a given channel.
+ *
+ * @return channel name on success, NULL on error.
+*)
+// const char *av_get_channel_name(uint64_t channel);
+
+(* *
+ * Get the description of a given channel.
+ *
+ * @param channel a channel layout with a single channel
+ * @return channel description on success, NULL on error
+*)
+// const char *av_get_channel_description(uint64_t channel);
+
+(* *
+ * Get the value and name of a standard channel layout.
+ *
+ * @param[in] index index in an internal list, starting at 0
+ * @param[out] layout channel layout mask
+ * @param[out] name name of the layout
+ * @return 0 if the layout exists,
+ * <0 if index is beyond the limits
+*)
+// int av_get_standard_channel_layout(unsigned index, uint64_t *layout, const char **name);
+
+implementation
+
+uses ffm.lib;
+
+function av_get_channel_layout_nb_channels; external channel_layout_dll;
+
+end.
diff --git a/source/ffmpeg/ffm.cls.videoencoder.pas b/source/ffmpeg/ffm.cls.videoencoder.pas
index cdd8db4..22981ba 100644
--- a/source/ffmpeg/ffm.cls.videoencoder.pas
+++ b/source/ffmpeg/ffm.cls.videoencoder.pas
@@ -46,6 +46,9 @@ Type
nAudioBufferSizeCurrent: Integer;
W_VIDEO: Integer;
H_VIDEO: Integer;
+ fbit_rate: Integer;
+ ftime_base_den: Integer;
+ function flush_encoder: Integer;
protected
// Add video stream
function AddVideoStream(const pContext: pAVFormatContext; const codec_id: TAVCodecID): pAVStream;
@@ -75,6 +78,8 @@ Type
// init output file
function InitFile(const inputFile: AnsiString; const container: AnsiString; const AW_VIDEO: Integer = 320;
const AH_VIDEO: Integer = 200): boolean;
+ // Set video params
+ procedure SetVideoParams(const atime_base_den: Integer = 25; const abit_rate: Integer = 2000000);
// Add video and audio data
function AddFrame(const frame: pAVFrame; const soundBuffer: pByte; const soundBufferSize: Integer;
const framepixfmt: TAVPixelFormat = AV_PIX_FMT_RGB24): boolean;
@@ -90,7 +95,7 @@ Uses
System.Math,
ffm.mem, ffm.avutil, ffm.samplefmt, ffm.mathematics;
-{TNVRVideoEncoder}
+{ TNVRVideoEncoder }
function TFFMVideoEncoder.AddAudioSample(const pFormatContext: pAVFormatContext; const pStream: pAVStream;
const soundBuffer: pByte; const soundBufferSize: Integer): boolean;
@@ -312,6 +317,7 @@ begin
// Write packet with frame.
Result := av_interleaved_write_frame(pFormatContext, @pkt) = 0;
+ // Result := av_write_frame(pFormatContext, @pkt) = 0;
end
else
Result := false;
@@ -322,7 +328,6 @@ function TFFMVideoEncoder.AddVideoStream(const pContext: pAVFormatContext; const
Var
pCodecCxt: pAVCodecContext;
begin
-
pCodecCxt := nil;
Result := nil;
@@ -338,15 +343,15 @@ begin
pCodecCxt^.codec_type := AVMEDIA_TYPE_VIDEO;
pCodecCxt^.frame_number := 0;
// Put sample parameters.
- pCodecCxt^.bit_rate := 2000000;
+ pCodecCxt^.bit_rate := fbit_rate; // 2000000;
// Resolution must be a multiple of two.
pCodecCxt^.width := W_VIDEO;
pCodecCxt^.height := H_VIDEO;
- (*time base: this is the fundamental unit of time (in seconds) in terms
+ (* time base: this is the fundamental unit of time (in seconds) in terms
of which frame timestamps are represented. for fixed-fps content,
timebase should be 1/framerate and timestamp increments should be
- identically 1.*)
- pCodecCxt^.time_base.den := 25;
+ identically 1. *)
+ pCodecCxt^.time_base.den := ftime_base_den; // 25;
pCodecCxt^.time_base.num := 1;
pCodecCxt^.gop_size := 12; // emit one intra frame every twelve frames at most
@@ -358,9 +363,9 @@ begin
end;
if (pCodecCxt^.codec_id = AV_CODEC_ID_MPEG1VIDEO) then
begin
- (*Needed to avoid using macroblocks
+ (* Needed to avoid using macroblocks
in which some coeffs overflow.This does not happen with normal video, it just happens here as the motion of
- the chroma plane does not match the luma plane.*)
+ the chroma plane does not match the luma plane. *)
pCodecCxt^.mb_decision := 2;
end;
@@ -418,6 +423,7 @@ begin
nAudioBufferSize := 1024 * 1024 * 4;
audioBuffer := AllocMem(nAudioBufferSize);
nAudioBufferSizeCurrent := 0;
+ SetVideoParams;
end;
function TFFMVideoEncoder.CreateFFmpegPicture(const pix_fmt: TAVPixelFormat; const nWidth, nHeight: Integer): pAVFrame;
@@ -458,6 +464,7 @@ begin
// Todo: Maybe you need write audio samples from audioBuffer to file before cloasing.
if Assigned(pFormatContext) then
begin
+// flush_encoder;
av_write_trailer(pFormatContext);
Free;
end;
@@ -469,6 +476,32 @@ begin
end;
end;
+function TFFMVideoEncoder.flush_encoder: Integer;
+Var
+ ret, got_output: Integer;
+ pkt: TAVPacket;
+begin
+ (* get the delayed frames *)
+ av_init_packet(@pkt);
+ got_output := 1;
+ While got_output <> 0 do
+ begin
+ ret := avcodec_encode_video2(pVideoStream^.codec, @pkt, nil, got_output);
+ if (ret < 0) then
+ begin
+ // WriteLn('Error encoding frame');
+ Exit(ret);
+ end;
+ if (got_output <> 0) then
+ begin
+ // WriteLn(format('Write frame %3d (size=%5d)', [i, pkt.size]));
+ // BlockWrite(f, pkt.data^, pkt.size);
+ av_free_packet(pkt);
+ end;
+ // Inc(i);
+ end;
+end;
+
procedure TFFMVideoEncoder.Free;
Var
i: Integer;
@@ -542,8 +575,8 @@ begin
if Assigned(pAudioStream) then
Result := OpenAudio(pFormatContext, pAudioStream);
- if Result and ((pOutFormat^.flags and AVFMT_NOFILE) = 0) and (avio_open(pFormatContext^.pb, filename, AVIO_FLAG_WRITE) < 0)
- then
+ if Result and ((pOutFormat^.flags and AVFMT_NOFILE) = 0) and
+ (avio_open(pFormatContext^.pb, filename, AVIO_FLAG_WRITE) < 0) then
begin
Result := false;
// printf(" Cannot open file\ n ");
@@ -639,4 +672,10 @@ begin
Result := true;
end;
+procedure TFFMVideoEncoder.SetVideoParams(const atime_base_den, abit_rate: Integer);
+begin
+ fbit_rate := abit_rate;
+ ftime_base_den := atime_base_den;
+end;
+
end.
diff --git a/source/ffmpeg/ffm.frame.pas b/source/ffmpeg/ffm.frame.pas
index 225a09d..f95dd7a 100644
--- a/source/ffmpeg/ffm.frame.pas
+++ b/source/ffmpeg/ffm.frame.pas
@@ -136,6 +136,9 @@ Type
pAVBufferRefArray = ^TAVBufferRefArray;
TAVBufferRefArray = array [0 .. AV_NUM_DATA_POINTERS - 1] of pAVBufferRef;
+ TLinesizes = array [0 .. AV_NUM_DATA_POINTERS - 1] of Integer;
+ pLinesizes = ^TLinesizes;
+
TAVFrame = {packed} record
(*
* pointer to the picture/channel planes.
@@ -162,7 +165,7 @@ Type
* @note The linesize may be larger than the size of usable data -- there
* may be extra padding present for performance reasons.
*)
- linesize: array [0 .. AV_NUM_DATA_POINTERS - 1] of Integer;
+ linesize: TLinesizes;
(*
* pointers to the data planes/channels.
*
diff --git a/source/ffmpeg/ffm.imgutils.pas b/source/ffmpeg/ffm.imgutils.pas
index c298147..7158979 100644
--- a/source/ffmpeg/ffm.imgutils.pas
+++ b/source/ffmpeg/ffm.imgutils.pas
@@ -5,7 +5,7 @@ unit ffm.imgutils;
interface
uses
- ffm.pixfmt;
+ ffm.pixfmt, ffm.frame;
(*
* This file is part of ffm.
@@ -87,14 +87,16 @@ uses
*)
// int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
// int w, int h, enum AVPixelFormat pix_fmt, int align);
-Type
- TPointers = array [0 .. 3] of pByte;
- pPointers = ^TPointers;
- TLinesizes = array [0 .. 3] of integer;
- pLinesizes = ^TLinesizes;
+// Type
+// TPointers = array [0 .. 3] of pByte;
+// pPointers = ^TPointers;
+// TLinesizes = array [0 .. 3] of integer;
+// pLinesizes = ^TLinesizes;
-function av_image_alloc(Var pointers: TPointers; linesizes: TLinesizes; w: integer; h: integer; pix_fmt: TAVPixelFormat;
- align: integer): integer; cdecl;
+function av_image_alloc(Var pointers: TAVFrameByteArray; linesizes: TLinesizes; w: integer; h: integer;
+ pix_fmt: TAVPixelFormat; align: integer): integer; cdecl;
+// function av_image_alloc(pointers: pPointers; linesizes: TLinesizes; w: integer; h: integer; pix_fmt: TAVPixelFormat;
+// align: integer): integer; overload; cdecl;
(*
* Copy image plane from src to dst.
@@ -200,5 +202,9 @@ implementation
uses ffm.lib;
function av_image_alloc; external avutil_dll;
+// function av_image_alloc(Var pointers: TPointers; linesizes: TLinesizes; w: integer; h: integer; pix_fmt: TAVPixelFormat;
+// align: integer): integer; overload; cdecl; external avutil_dll name 'av_image_alloc';
+// function av_image_alloc(pointers: pPointers; linesizes: TLinesizes; w: integer; h: integer; pix_fmt: TAVPixelFormat;
+// align: integer): integer; overload; cdecl; external avutil_dll name 'av_image_alloc';
end.
diff --git a/source/ffmpeg/ffm.lib.pas b/source/ffmpeg/ffm.lib.pas
index 8360770..b1619c7 100644
--- a/source/ffmpeg/ffm.lib.pas
+++ b/source/ffmpeg/ffm.lib.pas
@@ -12,6 +12,7 @@ const
avfilter_dll = 'avfilter-4.dll';
avio_dll = avformat_dll;
samplefmt_dll = avutil_dll;
+ channel_layout_dll=avutil_dll;
implementation
diff --git a/source/ffmpeg/ffm.libavcodec.avcodec.pas b/source/ffmpeg/ffm.libavcodec.avcodec.pas
index ab7d93c..f8c3c39 100644
--- a/source/ffmpeg/ffm.libavcodec.avcodec.pas
+++ b/source/ffmpeg/ffm.libavcodec.avcodec.pas
@@ -322,7 +322,7 @@ Type
TAVCodecID = ( //
AV_CODEC_ID_NONE, //
- (*video codecs*)
+ (* video codecs *)
AV_CODEC_ID_MPEG1VIDEO, //
AV_CODEC_ID_MPEG2VIDEO, //
/// < preferred ID for MPEG-1/2 video decoding
@@ -730,7 +730,8 @@ Type
// AV_CODEC_ID_SMPTE_KLV = $4B4C5641, // MKBETAG('K','L','V','A'),
// AV_CODEC_ID_DVD_NAV = $444E4156, // MKBETAG('D','N','A','V'),
- AV_CODEC_ID_PROBE = $19000, // < codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it
+ AV_CODEC_ID_PROBE = $19000,
+ // < codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it
AV_CODEC_ID_MPEG2TS = $20000, // **< _FAKE_ codec to indicate a raw MPEG-2 TS
// * stream (only used by libavformat) *)
@@ -913,8 +914,8 @@ Type
* @ingroup lavc_decoding
*)
TAVDiscard = (
- (*We leave some space between them for extensions (drop some
- // * keyframes for intra-only or drop just some bidir frames).*)
+ (* We leave some space between them for extensions (drop some
+ // * keyframes for intra-only or drop just some bidir frames). *)
AVDISCARD_NONE = -16,
/// < discard nothing
AVDISCARD_DEFAULT = 0,
@@ -1025,7 +1026,7 @@ Type
// #define FF_MAX_B_FRAMES 16
// #endif
const
- (*encoding support
+ (* encoding support
These flags can be passed in AVCodecContext.flags before initialization.
Note: Not everything is supported yet.
* )
@@ -1063,8 +1064,8 @@ const
/// < Don't draw edges.
CODEC_FLAG_PSNR = $8000;
/// < error[?] variables will be set during encoding.
- CODEC_FLAG_TRUNCATED = $00010000; (** Input bitstream might be truncated at a random
- // location instead of only at frame boundaries.*)
+ CODEC_FLAG_TRUNCATED = $00010000; (* * Input bitstream might be truncated at a random
+ // location instead of only at frame boundaries. *)
CODEC_FLAG_NORMALIZE_AQP = $00020000;
/// < Normalize adaptive quantization.
CODEC_FLAG_INTERLACED_DCT = $00040000;
@@ -1075,7 +1076,7 @@ const
/// < Place global headers in extradata instead of every keyframe.
CODEC_FLAG_BITEXACT = $00800000;
/// < Use only bitexact stuff (except (I)DCT).
- (*Fx : Flag for h263+ extra options*)
+ (* Fx : Flag for h263+ extra options *)
CODEC_FLAG_AC_PRED = $01000000;
/// < H.263 advanced intra coding / MPEG-4 AC prediction
CODEC_FLAG_LOOP_FILTER = $00000800;
@@ -1099,12 +1100,12 @@ const
CODEC_FLAG2_SHOW_ALL = $00400000;
/// < Show all frames before the first keyframe
- (*Unsupported options :
+ (* Unsupported options :
* Syntax Arithmetic coding (SAC)
* Reference Picture Selection
- * Independent Segment Decoding*)
- (* /Fx*)
- (*codec capabilities*)
+ * Independent Segment Decoding *)
+ (* /Fx *)
+ (* codec capabilities *)
CODEC_CAP_DRAW_HORIZ_BAND = $0001;
/// < Decoder can use draw_horiz_band callback.
@@ -1116,7 +1117,7 @@ const
CODEC_CAP_DR1 = $0002;
CODEC_CAP_TRUNCATED = $0008;
// #if FF_API_XVMC
- (*Codec can export data for HW decoding (XvMC).*)
+ (* Codec can export data for HW decoding (XvMC). *)
// #define CODEC_CAP_HWACCEL $0010
// #endif (* FF_API_XVMC *)
(*
@@ -1528,8 +1529,8 @@ Type
// int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
TExecuteFunc = function(c2: pAVCodecContext; arg: pointer): Integer; cdecl;
- TExecute = function(c: pAVCodecContext; ExecuteFunc: TExecuteFunc; arg2: pointer; ret: PInteger; count: Integer; size: Integer)
- : Integer; cdecl;
+ TExecute = function(c: pAVCodecContext; ExecuteFunc: TExecuteFunc; arg2: pointer; ret: PInteger; count: Integer;
+ size: Integer): Integer; cdecl;
// int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
TExecuteFunc2 = function(c2: pAVCodecContext; arg: pointer; jobnr: Integer; threadnr: Integer): Integer; cdecl;
@@ -1690,7 +1691,7 @@ Type
*)
delay: cint;
- (*video only*)
+ (* video only *)
(*
* picture width / height.
* - encoding: MUST be set by user.
@@ -1785,7 +1786,7 @@ Type
* - decoding: unused
*)
b_quant_factor: cfloat;
- (*obsolete FIXME remove*)
+ (* obsolete FIXME remove *)
rc_strategy: cint;
// #define FF_RC_STRATEGY_XVID 1
b_frame_strategy: cint;
@@ -2003,12 +2004,12 @@ Type
* - decoding: Set by libavcodec.
*)
inter_matrix: pWord;
- {*
+ { *
* scene change detection threshold
* 0 is default, larger means fewer detected scene changes.
* - encoding: Set by user.
* - decoding: unused
- *}
+ * }
scenechange_threshold: cint;
(*
* noise reduction strength
@@ -2160,12 +2161,12 @@ Type
* - decoding: unused
*)
slices: cint;
- (*Field order
+ (* Field order
* - encoding: set by libavcodec
* - decoding: Set by user.
*)
field_order: TAVFieldOrder;
- (*audio only*)
+ (* audio only *)
sample_rate: cint;
/// < samples per second
channels: cint;
@@ -2177,7 +2178,7 @@ Type
*)
sample_fmt: TAVSampleFormat;
/// < sample format
- (*The following data should not be initialized.*)
+ (* The following data should not be initialized. *)
(*
* Number of samples per channel in an audio frame.
*
@@ -2324,7 +2325,7 @@ Type
*)
// attribute_deprecated
// void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
- release_buffer: procedure(c: pAVCodecContext; pic: pAVFrame); cdecl; {deprecated;}
+ release_buffer: procedure(c: pAVCodecContext; pic: pAVFrame); cdecl; { deprecated; }
(*
* Called at the beginning of a frame to get cr buffer for it.
@@ -2340,7 +2341,7 @@ Type
*)
// attribute_deprecated
// int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
- reget_buffer: function(c: pAVCodecContext; pic: pAVFrame): cint; cdecl; {deprecated;}
+ reget_buffer: function(c: pAVCodecContext; pic: pAVFrame): cint; cdecl; { deprecated; }
{$ENDIF}
(*
* This callback is called at the beginning of each frame to get data
@@ -2623,22 +2624,22 @@ Type
*)
timecode_frame_start: cint64;
- (*The RTP callback: This function is called*)
- (*every time the encoder has a packet to send.*)
- (*It depends on the encoder if the data starts*)
- (*with a Start Code (it should). H.263 does.*)
- (*mb_nb contains the number of macroblocks*)
- (*encoded in the RTP payload.*)
+ (* The RTP callback: This function is called *)
+ (* every time the encoder has a packet to send. *)
+ (* It depends on the encoder if the data starts *)
+ (* with a Start Code (it should). H.263 does. *)
+ (* mb_nb contains the number of macroblocks *)
+ (* encoded in the RTP payload. *)
// void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb);
rtp_callback: procedure(avctx: pAVCodecContext; data: pointer; size: cint; mb_nb: cint); cdecl;
rtp_payload_size: cint; // * The size of the RTP payload: the coder will *)
- (*do its best to deliver a chunk with size*)
- (*below rtp_payload_size, the chunk will start*)
- (*with a start code on some codecs like H.263.*)
- (*This doesn't take account of any particular*)
- (*headers inside the transmitted RTP payload.*)
+ (* do its best to deliver a chunk with size *)
+ (* below rtp_payload_size, the chunk will start *)
+ (* with a start code on some codecs like H.263. *)
+ (* This doesn't take account of any particular *)
+ (* headers inside the transmitted RTP payload. *)
//
- (*statistics, used for 2-pass encoding*)
+ (* statistics, used for 2-pass encoding *)
mv_bits: cint;
header_bits: cint;
i_tex_bits: cint;
@@ -2712,11 +2713,11 @@ Type
*)
debug_mv: cint;
{$ENDIF}
- {*
+ { *
* Error recognition; may misdetect some more or less valid parts as errors.
* - encoding: unused
* - decoding: Set by user.
- *}
+ * }
err_recognition: cint;
(*
@@ -2850,7 +2851,8 @@ Type
* - decoding: Set by libavcodec, user can override.
*)
// int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
- execute: function(c: pAVCodecContext; func: TExecuteFunc; arg2: pointer; Var ret: cint; count: cint; size: cint): cint; cdecl;
+ execute: function(c: pAVCodecContext; func: TExecuteFunc; arg2: pointer; Var ret: cint; count: cint; size: cint)
+ : cint; cdecl;
(*
* The codec may call this to execute several independent things.
@@ -3122,7 +3124,7 @@ Type
profiles: pAVProfile;
/// < array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}
- (****************************************************************
+ (* ***************************************************************
// * No fields below this line are part of the public API. They
// * may not be used outside of libavcodec and can be changed and
// * removed at will.
@@ -3955,9 +3957,9 @@ function avcodec_find_decoder(id: TAVCodecID): pAVCodec; cdecl;
* decoding, otherwise the number of bytes consumed from the input
* AVPacket is returned.
*)
-// int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame,
-// int *got_frame_ptr, const AVPacket *avpkt);
-//
+// int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, const AVPacket *avpkt);
+function avcodec_decode_audio4(avctx: pAVCodecContext; frame: pAVFrame; var got_frame_ptr: Integer;
+ const avpkt: pAVPacket):Integer; cdecl;
(*
* Decode the video frame of size avpkt->size from avpkt->data into picture.
* Some decoders may support multiple frames in a single AVPacket, such
@@ -4051,12 +4053,12 @@ Type
TAVCodecParserContext = record
priv_data: pointer;
parser: pAVCodecParser;
- frame_offset: int64_t; (*offset of the current frame*)
- cur_offset: int64_t; (*current offset
- (* (incremented by each av_parser_parse())*)
- next_frame_offset: int64_t; (*offset of the next frame*)
- (*video info*)
- pict_type: Integer; (*XXX: Put it back in AVCodecContext.*)
+ frame_offset: int64_t; (* offset of the current frame *)
+ cur_offset: int64_t; (* current offset
+ (* (incremented by each av_parser_parse()) *)
+ next_frame_offset: int64_t; (* offset of the next frame *)
+ (* video info *)
+ pict_type: Integer; (* XXX: Put it back in AVCodecContext. *)
(*
* This field is used for proper frame duration computation in lavf.
* It signals, how much longer the frame duration of the current frame
@@ -4066,10 +4068,10 @@ Type
*
* It is used by codecs like H.264 to display telecined material.
*)
- repeat_pict: Integer; (*XXX: Put it back in AVCodecContext.*)
- pts: int64_t; (*pts of the current frame*)
- dts: int64_t; (*dts of the current frame*)
- (*private data*)
+ repeat_pict: Integer; (* XXX: Put it back in AVCodecContext. *)
+ pts: int64_t; (* pts of the current frame *)
+ dts: int64_t; (* dts of the current frame *)
+ (* private data *)
last_pts: int64_t;
last_dts: int64_t;
fetch_timestamp: Integer;
@@ -4187,7 +4189,7 @@ Type
ppByte = ^pByte;
TAVCodecParser = record
- codec_ids: array [0 .. 4] of Integer; (*several codec IDs are permitted*)
+ codec_ids: array [0 .. 4] of Integer; (* several codec IDs are permitted *)
priv_data_size: Integer;
// int (*parser_init)(AVCodecParserContext *s);
parser_init: function(s: pAVCodecParserContext): Integer; cdecl;
@@ -4195,8 +4197,8 @@ Type
// AVCodecContext *avctx,
// const uint8_t **poutbuf, int *poutbuf_size,
// const uint8_t *buf, int buf_size);
- parser_parse: function(s: pAVCodecParserContext; avctx: pAVCodecContext; const poutbuf: ppByte; poutbuf_size: PInteger;
- const buf: pByte; buf_size: Integer): Integer; cdecl;
+ parser_parse: function(s: pAVCodecParserContext; avctx: pAVCodecContext; const poutbuf: ppByte;
+ poutbuf_size: PInteger; const buf: pByte; buf_size: Integer): Integer; cdecl;
// void (*parser_close)(AVCodecParserContext *s);
parser_close: procedure(s: pAVCodecParserContext); cdecl;
// int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
@@ -4341,8 +4343,8 @@ function avcodec_find_encoder(id: TAVCodecID): pAVCodec; cdecl;
*)
// int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt,
// const AVFrame *frame, int *got_packet_ptr);
-function avcodec_encode_audio2(avctx: pAVCodecContext; avpkt: pAVPacket; const frame: pAVFrame; Var got_packet_ptr: Integer)
- : Integer; cdecl;
+function avcodec_encode_audio2(avctx: pAVCodecContext; avpkt: pAVPacket; const frame: pAVFrame;
+ Var got_packet_ptr: Integer): Integer; cdecl;
// #if FF_API_OLD_ENCODE_VIDEO
(*
@@ -4400,8 +4402,8 @@ function avcodec_encode_audio2(avctx: pAVCodecContext; avpkt: pAVPacket; const f
*)
// int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt,
// const AVFrame *frame, int *got_packet_ptr);
-function avcodec_encode_video2(avctx: pAVCodecContext; avpkt: pAVPacket; const frame: pAVFrame; Var got_packet_ptr: Integer)
- : Integer; cdecl;
+function avcodec_encode_video2(avctx: pAVCodecContext; avpkt: pAVPacket; const frame: pAVFrame;
+ Var got_packet_ptr: Integer): Integer; cdecl;
// int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
// const AVSubtitle *sub);
@@ -4811,7 +4813,8 @@ function avcodec_fill_audio_frame(frame: pAVFrame; nb_channels: Integer; sample_
// * keep internally, but the caller's reference remains valid.
*)
// void avcodec_flush_buffers(AVCodecContext *avctx);
-//
+procedure avcodec_flush_buffers(avctx: pAVCodecContext); cdecl;
+
(*
// * Return codec bits per sample.
// *
@@ -4941,7 +4944,7 @@ function avcodec_fill_audio_frame(frame: pAVFrame; nb_channels: Integer; sample_
*)
// AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f);
//
-(*memory*)
+(* memory *)
//
(*
// * Same behaviour av_fast_malloc but the buffer has additional
@@ -5125,5 +5128,7 @@ function avcodec_find_encoder; external avcodec_dll;
function avcodec_encode_video2; external avcodec_dll;
function avcodec_fill_audio_frame; external avcodec_dll;
function avcodec_encode_audio2; external avcodec_dll;
+procedure avcodec_flush_buffers; external avcodec_dll;
+function avcodec_decode_audio4; external avcodec_dll;
end.
diff --git a/source/ffmpeg/ffm.opt.pas b/source/ffmpeg/ffm.opt.pas
index a394933..618feec 100644
--- a/source/ffmpeg/ffm.opt.pas
+++ b/source/ffmpeg/ffm.opt.pas
@@ -234,7 +234,8 @@ Type
{ } AV_OPT_TYPE_BINARY,
// < offset must point to a pointer immediately followed by an int for the length
{ } AV_OPT_TYPE_CONST = 128,
- { } AV_OPT_TYPE_IMAGE_SIZE = $53495A45, // MKBETAG('S', 'I', 'Z', 'E'), // < offset must point to two consecutive integers
+ { } AV_OPT_TYPE_IMAGE_SIZE = $53495A45,
+ // MKBETAG('S', 'I', 'Z', 'E'), // < offset must point to two consecutive integers
{ } AV_OPT_TYPE_PIXEL_FMT = $50464D54, // MKBETAG('P', 'F', 'M', 'T'),
{ } AV_OPT_TYPE_SAMPLE_FMT = $53464D54, // MKBETAG('S', 'F', 'M', 'T'),
{ } AV_OPT_TYPE_VIDEO_RATE = $56524154, // MKBETAG('V', 'R', 'A', 'T'), // < offset must point to AVRational
@@ -674,115 +675,118 @@ const
// * AVERROR(EINVAL) if the value is not valid
// */
// int av_opt_set (void *obj, const char *name, const char *val, int search_flags);
- // int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags);
- // int av_opt_set_double(void *obj, const char *name, double val, int search_flags);
- // int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags);
- // int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags);
-function av_opt_set_bin(obj: Pointer; const name: pAnsiChar; const val: PByte; size: Integer; search_flags: Integer):Integer; cdecl;
-// int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags);
-// int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags);
-// int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags);
-// int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags);
-// int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);
-//
-/// **
-// * Set a binary option to an integer list.
-// *
-// * @param obj AVClass object to set options on
-// * @param name name of the binary option
-// * @param val pointer to an integer list (must have the correct type with
-// * regard to the contents of the list)
-// * @param term list terminator (usually 0 or -1)
-// * @param flags search flags
-// */
-// #define av_opt_set_int_list(obj, name, val, term, flags) \
-// (av_int_list_length(val, term) > INT_MAX / sizeof(*(val)) ? \
-// AVERROR(EINVAL) : \
-// av_opt_set_bin(obj, name, (const uint8_t *)(val), \
-// av_int_list_length(val, term) * sizeof(*(val)), flags))
-/// **
-// * @}
-// */
-//
-/// **
-// * @defgroup opt_get_funcs Option getting functions
-// * @{
-// * Those functions get a value of the option with the given name from an object.
-// *
-// * @param[in] obj a struct whose first element is a pointer to an AVClass.
-// * @param[in] name name of the option to get.
-// * @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
-// * is passed here, then the option may be found in a child of obj.
-// * @param[out] out_val value of the option will be written here
-// * @return >=0 on success, a negative error code otherwise
-// */
-/// **
-// * @note the returned string will be av_malloc()ed and must be av_free()ed by the caller
-// */
-// int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val);
-// int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val);
-// int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val);
-// int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val);
-// int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out);
-// int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt);
-// int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt);
-// int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val);
-// int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout);
-/// **
-// * @}
-// */
-/// **
-// * Gets a pointer to the requested field in a struct.
-// * This function allows accessing a struct even when its fields are moved or
-// * renamed since the application making the access has been compiled,
-// *
-// * @returns a pointer to the field, it can be cast to the correct type and read
-// * or written to.
-// */
-// void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
-//
-/// **
-// * Free an AVOptionRanges struct and set it to NULL.
-// */
-// void av_opt_freep_ranges(AVOptionRanges **ranges);
-//
-/// **
-// * Get a list of allowed ranges for the given option.
-// *
-// * The returned list may depend on other fields in obj like for example profile.
-// *
-// * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
-// * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
-// *
-// * The result must be freed with av_opt_freep_ranges.
-// *
-// * @return >= 0 on success, a negative errro code otherwise
-// */
-// int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags);
-//
-/// **
-// * Get a default list of allowed ranges for the given option.
-// *
-// * This list is constructed without using the AVClass.query_ranges() callback
-// * and can be used as fallback from within the callback.
-// *
-// * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
-// * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
-// *
-// * The result must be freed with av_opt_free_ranges.
-// *
-// * @return >= 0 on success, a negative errro code otherwise
-// */
-// int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags);
-//
-/// **
-// * @}
-// */
+function av_opt_set(obj: Pointer; const name: pAnsiChar; const val: pAnsiChar; search_flags: Integer): Integer; cdecl;
+// int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags);
+// int av_opt_set_double(void *obj, const char *name, double val, int search_flags);
+// int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags);
+// int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags);
+ function av_opt_set_bin(obj: Pointer; const name: pAnsiChar; const val: PByte; size: Integer; search_flags: Integer)
+ : Integer; cdecl;
+ // int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags);
+ // int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags);
+ // int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags);
+ // int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags);
+ // int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);
+ //
+ /// **
+ // * Set a binary option to an integer list.
+ // *
+ // * @param obj AVClass object to set options on
+ // * @param name name of the binary option
+ // * @param val pointer to an integer list (must have the correct type with
+ // * regard to the contents of the list)
+ // * @param term list terminator (usually 0 or -1)
+ // * @param flags search flags
+ // */
+ // #define av_opt_set_int_list(obj, name, val, term, flags) \
+ // (av_int_list_length(val, term) > INT_MAX / sizeof(*(val)) ? \
+ // AVERROR(EINVAL) : \
+ // av_opt_set_bin(obj, name, (const uint8_t *)(val), \
+ // av_int_list_length(val, term) * sizeof(*(val)), flags))
+ /// **
+ // * @}
+ // */
+ //
+ /// **
+ // * @defgroup opt_get_funcs Option getting functions
+ // * @{
+ // * Those functions get a value of the option with the given name from an object.
+ // *
+ // * @param[in] obj a struct whose first element is a pointer to an AVClass.
+ // * @param[in] name name of the option to get.
+ // * @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
+ // * is passed here, then the option may be found in a child of obj.
+ // * @param[out] out_val value of the option will be written here
+ // * @return >=0 on success, a negative error code otherwise
+ // */
+ /// **
+ // * @note the returned string will be av_malloc()ed and must be av_free()ed by the caller
+ // */
+ // int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val);
+ // int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val);
+ // int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val);
+ // int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val);
+ // int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out);
+ // int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt);
+ // int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt);
+ // int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val);
+ // int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout);
+ /// **
+ // * @}
+ // */
+ /// **
+ // * Gets a pointer to the requested field in a struct.
+ // * This function allows accessing a struct even when its fields are moved or
+ // * renamed since the application making the access has been compiled,
+ // *
+ // * @returns a pointer to the field, it can be cast to the correct type and read
+ // * or written to.
+ // */
+ // void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
+ //
+ /// **
+ // * Free an AVOptionRanges struct and set it to NULL.
+ // */
+ // void av_opt_freep_ranges(AVOptionRanges **ranges);
+ //
+ /// **
+ // * Get a list of allowed ranges for the given option.
+ // *
+ // * The returned list may depend on other fields in obj like for example profile.
+ // *
+ // * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
+ // * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
+ // *
+ // * The result must be freed with av_opt_freep_ranges.
+ // *
+ // * @return >= 0 on success, a negative errro code otherwise
+ // */
+ // int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags);
+ //
+ /// **
+ // * Get a default list of allowed ranges for the given option.
+ // *
+ // * This list is constructed without using the AVClass.query_ranges() callback
+ // * and can be used as fallback from within the callback.
+ // *
+ // * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
+ // * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
+ // *
+ // * The result must be freed with av_opt_free_ranges.
+ // *
+ // * @return >= 0 on success, a negative errro code otherwise
+ // */
+ // int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags);
+ //
+ /// **
+ // * @}
+ // */
implementation
uses ffm.lib;
function av_opt_set_bin; external avutil_dll;
+function av_opt_set; external avutil_dll;
end.
diff --git a/source/ffmpeg/ffm.samplefmt.pas b/source/ffmpeg/ffm.samplefmt.pas
index 2730c84..b520639 100644
--- a/source/ffmpeg/ffm.samplefmt.pas
+++ b/source/ffmpeg/ffm.samplefmt.pas
@@ -45,7 +45,8 @@ interface
*)
Type
pAVSampleFormat = ^TAVSampleFormat;
- TAVSampleFormat = (AV_SAMPLE_FMT_NONE = -1, //
+ TAVSampleFormat = ( //
+ AV_SAMPLE_FMT_NONE = -1, //
AV_SAMPLE_FMT_U8,
/// < unsigned 8 bits
AV_SAMPLE_FMT_S16,
@@ -56,7 +57,6 @@ Type
/// < float
AV_SAMPLE_FMT_DBL,
/// < double
-
AV_SAMPLE_FMT_U8P,
/// < unsigned 8 bits, planar
AV_SAMPLE_FMT_S16P,
@@ -67,7 +67,6 @@ Type
/// < float, planar
AV_SAMPLE_FMT_DBLP,
/// < double, planar
-
AV_SAMPLE_FMT_NB
/// < Number of sample formats. DO NOT USE if linking dynamically
);
@@ -77,72 +76,73 @@ Type
* recognized.
*)
// const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt);
+function av_get_sample_fmt_name(sample_fmt: TAVSampleFormat): pAnsiChar; cdecl;
- (*
- * Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE
- * on error.
- *)
- // enum AVSampleFormat av_get_sample_fmt(const char *name);
+(*
+ * Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE
+ * on error.
+*)
+// enum AVSampleFormat av_get_sample_fmt(const char *name);
- (*
- * Return the planar<->{packed} alternative form of the given sample format, or
- * AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the
- * requested planar/{packed} format, the format returned is the same as the
- * input.
- *)
- // enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar);
+(*
+ * Return the planar<->{packed} alternative form of the given sample format, or
+ * AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the
+ * requested planar/{packed} format, the format returned is the same as the
+ * input.
+*)
+// enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar);
- (*
- * Get the {packed} alternative form of the given sample format.
- *
- * If the passed sample_fmt is already in {packed} format, the format returned is
- * the same as the input.
- *
- * @return the {packed} alternative form of the given sample format or
- AV_SAMPLE_FMT_NONE on error.
- *)
- // enum AVSampleFormat av_get_{packed}_sample_fmt(enum AVSampleFormat sample_fmt);
+(*
+ * Get the {packed} alternative form of the given sample format.
+ *
+ * If the passed sample_fmt is already in {packed} format, the format returned is
+ * the same as the input.
+ *
+ * @return the {packed} alternative form of the given sample format or
+ AV_SAMPLE_FMT_NONE on error.
+*)
+// enum AVSampleFormat av_get_{packed}_sample_fmt(enum AVSampleFormat sample_fmt);
- (*
- * Get the planar alternative form of the given sample format.
- *
- * If the passed sample_fmt is already in planar format, the format returned is
- * the same as the input.
- *
- * @return the planar alternative form of the given sample format or
- AV_SAMPLE_FMT_NONE on error.
- *)
- // enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt);
+(*
+ * Get the planar alternative form of the given sample format.
+ *
+ * If the passed sample_fmt is already in planar format, the format returned is
+ * the same as the input.
+ *
+ * @return the planar alternative form of the given sample format or
+ AV_SAMPLE_FMT_NONE on error.
+*)
+// enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt);
- (*
- * Generate a string corresponding to the sample format with
- * sample_fmt, or a header if sample_fmt is negative.
- *
- * @param buf the buffer where to write the string
- * @param buf_size the size of buf
- * @param sample_fmt the number of the sample format to print the
- * corresponding info string, or a negative value to print the
- * corresponding header.
- * @return the pointer to the filled buffer or NULL if sample_fmt is
- * unknown or in case of other errors
- *)
- // char *av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt);
+(*
+ * Generate a string corresponding to the sample format with
+ * sample_fmt, or a header if sample_fmt is negative.
+ *
+ * @param buf the buffer where to write the string
+ * @param buf_size the size of buf
+ * @param sample_fmt the number of the sample format to print the
+ * corresponding info string, or a negative value to print the
+ * corresponding header.
+ * @return the pointer to the filled buffer or NULL if sample_fmt is
+ * unknown or in case of other errors
+*)
+// char *av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt);
{$IFDEF FF_API_GET_BITS_PER_SAMPLE_FMT}
- (*
- * @deprecated Use av_get_bytes_per_sample() instead.
- *)
- // attribute_deprecated
- // int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt);
+(*
+ * @deprecated Use av_get_bytes_per_sample() instead.
+*)
+// attribute_deprecated
+// int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt);
{$ENDIF}
- (*
- * Return number of bytes per sample.
- *
- * @param sample_fmt the sample format
- * @return number of bytes per sample or zero if unknown for the given
- * sample format
- *)
- // int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt);
+(*
+ * Return number of bytes per sample.
+ *
+ * @param sample_fmt the sample format
+ * @return number of bytes per sample or zero if unknown for the given
+ * sample format
+*)
+// int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt);
function av_get_bytes_per_sample(sample_fmt: TAVSampleFormat): integer; cdecl;
(*
@@ -163,8 +163,9 @@ function av_get_bytes_per_sample(sample_fmt: TAVSampleFormat): integer; cdecl;
* @param align buffer size alignment (0 = default, 1 = no alignment)
* @return required buffer size, or negative error code on failure
*)
-// int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
-// enum AVSampleFormat sample_fmt, int align);
+// int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align);
+function av_samples_get_buffer_size(linesize: pInteger; nb_channels: integer; nb_samples: integer;
+ sample_fmt: TAVSampleFormat; align: integer): integer; cdecl;
(*
* Fill plane data pointers and linesize for samples with sample
@@ -267,5 +268,7 @@ implementation
uses ffm.lib;
function av_get_bytes_per_sample; external samplefmt_dll;
+function av_get_sample_fmt_name; external samplefmt_dll;
+function av_samples_get_buffer_size; external samplefmt_dll;
end.