public void Deserialize([CanBeNull] string AString, string AKeyValSep, string APairsSep) { const char C_Null = '\0'; const char C_Slash = '\\'; if (AString == null) { return; } if (AKeyValSep == null) { throw new ArgumentNullException(nameof(AKeyValSep)); } if (APairsSep == null) { throw new ArgumentNullException(nameof(APairsSep)); } if (AKeyValSep.Length == 0 || AKeyValSep.Any(X => X == C_Null || X == C_Slash)) { throw new ArgumentException("Invalid character(s).", nameof(AKeyValSep)); } if (APairsSep.Length == 0 || APairsSep.Any(X => X == C_Null || X == C_Slash)) { throw new ArgumentException("Invalid character(s).", nameof(APairsSep)); } if (AKeyValSep.Union(APairsSep).Any()) { throw new ArgumentException("Separators overlap."); } AVDictionary.ParseString(ref Ref, AString, AKeyValSep, APairsSep, Flags); }
/// <summary> /// Find streams from here. /// </summary> /// <param name="AOptions">The options <see cref="Dictionary"/>.</param> /// <exception cref="ObjectDisposedException">This instance is disposed.</exception> /// <exception cref="InvalidOperationException">Stream is closed.</exception> /// <exception cref="FFmpegError">Error finding stream info.</exception> public void FindStreamInfo([CanBeNull] Dictionary AOptions = null) { ThrowIfDisposed(); if (Mode != StreamOpenMode.Input) { throw new InvalidOperationException("Stream is closed."); } Ref <Unsafe.AVDictionary> opt = null; if (AOptions != null) { opt = AOptions.Ref; } try { AVFormatContext.FindStreamInfo(Ref, ref opt); } finally { if (AOptions != null) { // Options were provided, update them. AOptions.Ref = opt; } else { // Options are unwanted, free them. AVDictionary.Free(ref opt); } } }
public unsafe bool TryGetValue(string AKey, [CanBeNull] out string AValue) { if (AKey == null) { throw new ArgumentNullException(nameof(AKey)); } var get = AVDictionary.Get(Ref, AKey, default, Flags);
public void CopyTo(Dictionary ADictionary) { if (ADictionary == null) { throw new ArgumentNullException(nameof(ADictionary)); } AVDictionary.Copy(ref ADictionary.Ref, Ref, Flags); }
/// <summary> /// Create a new <see cref="Dictionary"/> instance. /// </summary> /// <param name="AIgnoreCase">If <c>true</c>, ignore case when comparing keys.</param> public Dictionary(bool AIgnoreCase = true) : this( AVDictionary.Alloc(), AIgnoreCase ? AVDictFlags.NONE : AVDictFlags.AV_DICT_MATCH_CASE ) { }
/// <summary> /// Open the output context. /// </summary> /// <param name="AUrl">The output URL.</param> /// <param name="AMuxer">The <see cref="Muxer"/>.</param> /// <param name="AOptions">The options <see cref="Dictionary"/>.</param> /// <exception cref="ObjectDisposedException">This instance is disposed.</exception> /// <exception cref="InvalidOperationException">Stream is already open.</exception> /// <exception cref="ArgumentNullException"> /// <paramref name="AUrl"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentNullException"> /// <paramref name="AMuxer"/> is <see langword="null"/>. /// </exception> /// <exception cref="FFmpegError">Error opening context.</exception> public unsafe void Open( string AUrl, Muxer AMuxer, [CanBeNull] Dictionary AOptions = null ) { ThrowIfDisposed(); if (Mode != StreamOpenMode.Closed) { throw new InvalidOperationException("Stream is already open."); } if (AUrl == null) { throw new ArgumentNullException(nameof(AUrl)); } if (AMuxer == null) { throw new ArgumentNullException(nameof(AMuxer)); } Ref <Unsafe.AVIOContext> pb = Ref.Ptr->pb; Ref <Unsafe.AVDictionary> opt = null; if (AOptions != null) { opt = AOptions.Ref; } try { AVIO.Open(ref pb, AUrl, AVIOOpenFlags.AVIO_FLAG_WRITE, null, ref opt); Ref.Ptr->pb = pb; } finally { if (AOptions != null) { // Options were provided, update them. AOptions.Ref = opt; } else { // Options are unwanted, free them. AVDictionary.Free(ref opt); } } Ref.Ptr->oformat = AMuxer.Ref; Mode = StreamOpenMode.Output; State = OutputState.Opened; }
/// <summary> /// Open the input context. /// </summary> /// <param name="AUrl">The input URL.</param> /// <param name="ADemuxer">The <see cref="Demuxer"/>.</param> /// <param name="AOptions">The options <see cref="Dictionary"/>.</param> /// <exception cref="ObjectDisposedException">This instance is disposed.</exception> /// <exception cref="InvalidOperationException">Stream is already open.</exception> /// <exception cref="ArgumentNullException"> /// <paramref name="AUrl"/> is <see langword="null"/>. /// </exception> /// <exception cref="FFmpegError">Error opening context.</exception> public void Open( string AUrl, [CanBeNull] Demuxer ADemuxer = null, [CanBeNull] Dictionary AOptions = null ) { ThrowIfDisposed(); if (Mode != StreamOpenMode.Closed) { throw new InvalidOperationException("Stream is already open."); } if (AUrl == null) { throw new ArgumentNullException(nameof(AUrl)); } Ref <Unsafe.AVDictionary> opt = null; // If options were provided, input them. if (AOptions != null) { opt = AOptions.Ref; } try { AVFormatContext.OpenInput( ref Ref, AUrl, ADemuxer != null ? ADemuxer.Ref : null, ref opt ); Mode = StreamOpenMode.Input; } finally { if (AOptions != null) { // Options were provided, update them. AOptions.Ref = opt; } else { // Options are unwanted, free them. AVDictionary.Free(ref opt); } } }
public Dictionary Clone() { var clone = new Dictionary(AVDictionary.Alloc(), Flags); try { AVDictionary.Copy(ref clone.Ref, Ref, Flags); } catch { clone.Clear(); throw; } return(clone); }
public string Serialize(char AKeyValSep, char APairsSep) { const byte C_Null = (byte)'\0'; const byte C_Slash = (byte)'\\'; var seps = Encoding.ASCII.GetBytes(new[] { AKeyValSep, APairsSep }); if (seps.Length != 2) { throw new ArgumentException("Separators are non-ASCII."); } if (seps.Any(X => X == C_Null || X == C_Slash)) { throw new ArgumentException("Separators contain invalid characters."); } if (seps[0] == seps[1]) { throw new ArgumentException("Separators are the same."); } return(AVDictionary.GetString(Ref, seps[0], seps[1])); }
/// <summary> /// Begin writing stream data. /// </summary> /// <param name="AOptions"></param> /// <exception cref="ObjectDisposedException">This instance is disposed.</exception> /// <exception cref="InvalidOperationException"> /// Stream is not in the Opened state. /// </exception> /// <exception cref="FFmpegError">Error writing header.</exception> public void BeginData([CanBeNull] Dictionary AOptions = null) { ThrowIfDisposed(); if (State != OutputState.Opened) { throw new InvalidOperationException("Stream is not in the Opened state."); } // TODO : Implement stream check. Ref <Unsafe.AVDictionary> opt = null; // If options were provided, input them. if (AOptions != null) { opt = AOptions.Ref; } try { AVFormatContext.WriteHeader(Ref, ref opt); State = OutputState.Ready; } finally { if (AOptions != null) { // Options were provided, update them. AOptions.Ref = opt; } else { // Options are unwanted, free them. AVDictionary.Free(ref opt); } } }
public static extern int avformat_open_input(AVFormatContext** @ps, [MarshalAs(UnmanagedType.LPStr)] string @url, AVInputFormat* @fmt, AVDictionary** @options);
public static extern int avdevice_capabilities_create(AVDeviceCapabilitiesQuery** caps, AVFormatContext* s, AVDictionary** device_options);
public static extern int avformat_find_stream_info(AVFormatContext* ic, AVDictionary** options);
public static extern int avio_open2(AVIOContext** s, String url, int flags, AVIOInterruptCB* int_cb, AVDictionary** options);
public static extern int av_opt_set_dict_val(void* obj, String name, AVDictionary* val, int search_flags);
public static extern int av_opt_set_dict(void* obj, AVDictionary** options);
public static extern byte* av_packet_pack_dictionary(AVDictionary* dict, int* size);
public static extern void av_frame_set_metadata(AVFrame* frame, AVDictionary* val);
public static extern int avio_open2(AVIOContext** @s, [MarshalAs(UnmanagedType.LPStr)] string @url, int @flags, AVIOInterruptCB* @int_cb, AVDictionary** @options);
public static extern int avio_open_dir(AVIODirContext** @s, [MarshalAs(UnmanagedType.LPStr)] string @url, AVDictionary** @options);
public static extern int avdevice_list_output_sinks(AVOutputFormat* @device, [MarshalAs(UnmanagedType.LPStr)] string @device_name, AVDictionary* @device_options, AVDeviceInfoList** @device_list);
private unsafe static Dictionary<string, string> ToDictionary(AVDictionary* dict) { Dictionary<string, string> result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); int size = ffmpeg.av_dict_count(dict); int AV_DICT_IGNORE_SUFFIX = 2; AVDictionaryEntry* curr = null; for (int n = 0; n < size; n++) { curr = ffmpeg.av_dict_get(dict, "", curr, AV_DICT_IGNORE_SUFFIX); string key = new String(curr->key); string val = new String(curr->value); result[key] = val; } return result; }
public static extern int av_packet_unpack_dictionary(sbyte* @data, int @size, AVDictionary** @dict);
public static extern sbyte* av_packet_pack_dictionary(AVDictionary* @dict, int* @size);
public static extern int avcodec_open2(AVCodecContext* avctx, AVCodec* codec, AVDictionary** options);
public static extern int avformat_init_output(AVFormatContext* @s, AVDictionary** @options);
public static extern int av_packet_unpack_dictionary(byte* data, int size, AVDictionary** dict);
public static extern AVDictionaryEntry* av_dict_get(AVDictionary* m, String key, AVDictionaryEntry* prev, int flags);
public static extern int av_opt_set_dict2(void* obj, AVDictionary** options, int search_flags);
public static extern int av_dict_count(AVDictionary* m);
public static extern int av_opt_get_dict_val(void* obj, String name, int search_flags, AVDictionary** out_val);
public static extern int av_dict_set_int(AVDictionary** pm, String key, long value, int flags);
public static extern int avformat_open_input(AVFormatContext** ps, String filename, AVInputFormat* fmt, AVDictionary** options);
public static extern void av_dict_copy(AVDictionary** dst, AVDictionary* src, int flags);
public static extern int avformat_write_header(AVFormatContext* s, AVDictionary** options);
public static extern void av_dict_free(AVDictionary** m);
public static extern int avfilter_init_dict(AVFilterContext* ctx, AVDictionary** options);
public static extern int av_dict_get_string(AVDictionary* m, sbyte** buffer, sbyte key_val_sep, sbyte pairs_sep);
public static extern int av_dict_parse_string(AVDictionary** pm, String str, String key_val_sep, String pairs_sep, int flags);
public static extern int av_bsf_list_append2(AVBSFList* @lst, [MarshalAs(UnmanagedType.LPStr)] string @bsf_name, AVDictionary** @options);