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 + + + + + decoding_encoding.dpr + + + 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 @@ Base true + + true + Cfg_2 + true + true + + ..\..\..\bin\$(Platform) + .\$(Platform)\$(Config) + None false 1049 System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) @@ -58,9 +67,6 @@ 0 - .\$(Platform)\$(Config) - ..\..\..\bin\$(Platform) - None CompanyName=;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) true 1033 - 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:50 true 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 @@ true 1033 - 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.