Hi again,

I've changed my approach a bit to make it more general; instead of adding a
"carrier type" field to AVStream, I've added support for raising any event
through omission. Formats set `base_event_flags` whenever they create a stream,
denoting which events will be raised unless explicitly cleared. To make use of
this you must call the new function av_reset_event_flags() to clear flags, but
the old method of "event_flags = 0" will still work perfectly fine for events
that are explicitly raised.

I expect it won't break any existing code since NO_CARRIER is so far the only
event that may be raised in this manner, and any code that doesn't handle that
therefore doesn't need to use av_reset_event_flags() either.

I'm hoping this is a step in the right direction.  Thoughts?

Regards,
John Högberg
From b873039aa2a1cceab0a86bb690975111a395d1c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20H=C3=B6gberg?= <john.hogb...@ericsson.com>
Date: Fri, 8 May 2015 10:58:56 +0200
Subject: [RFC] Add a NO_CARRIER stream event, and a mechanism for raising
 events through omission

AVSTREAM_EVENT_FLAG_NO_CARRIER is an event indicating that no carrier was
present during the last call. It is distinct from the stream being dead or
there being no data on the stream.

av_reset_event_flags() is a proposed canonical way of clearing the event flags
of a stream, and is intended to support the new base_event_flags feature on
AVStream, which lets formats choose which events they want to trigger through
raising and which events they want to trigger through omission.
---
 libavformat/avformat.h | 19 +++++++++++++++++++
 libavformat/mpegts.c   |  9 +++++++++
 libavformat/utils.c    | 13 +++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index aa11cff..86c0c53 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -814,6 +814,11 @@ typedef struct AVStream {
      */
     int event_flags;
 #define AVSTREAM_EVENT_FLAG_METADATA_UPDATED 0x0001 ///< The call resulted in 
updated metadata.
+#define AVSTREAM_EVENT_FLAG_NO_CARRIER       0x0002 /**< No carrier for this 
stream was present during the call.
+                                                         This is distinct from 
there being no data or the stream
+                                                         being dead; it simply 
means that the stream had no
+                                                         presence at all 
during the last call, and it's up to
+                                                         the caller to 
interpret what this means. */
 
     /*****************************************************************
      * All fields below this line are not part of the public API. They
@@ -824,6 +829,13 @@ typedef struct AVStream {
      */
 
     /**
+     * The base event flags that event_flags should be set to on each reset, in
+     * order to support events that may be raised through omission like
+     * "NO_CARRIER" on some formats. Used internally by av_reset_event_flags()
+     */
+    int base_event_flags;
+
+    /**
      * Stream information used internally by av_find_stream_info()
      */
 #define MAX_STD_TIMEBASES (60*12+5)
@@ -1563,6 +1575,13 @@ int av_read_play(AVFormatContext *s);
 int av_read_pause(AVFormatContext *s);
 
 /**
+ * Reset the event flags on the given file and all its substreams.
+ *
+ * @param s media file handle
+ */
+void av_reset_event_flags(AVFormatContext *s);
+
+/**
  * Close an opened input AVFormatContext. Free it and all its contents
  * and set *s to NULL.
  */
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 8f61f17..929d37b 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -648,10 +648,14 @@ static int mpegts_set_stream_info(AVStream *st, 
PESContext *pes,
                                   uint32_t stream_type, uint32_t prog_reg_desc)
 {
     avpriv_set_pts_info(st, 33, 1, 90000);
+
     st->priv_data         = pes;
     st->codec->codec_type = AVMEDIA_TYPE_DATA;
     st->codec->codec_id   = AV_CODEC_ID_NONE;
     st->need_parsing      = AVSTREAM_PARSE_FULL;
+    st->base_event_flags  = AVSTREAM_EVENT_FLAG_NO_CARRIER;
+    st->event_flags       = st->base_event_flags;
+
     pes->st          = st;
     pes->stream_type = stream_type;
 
@@ -840,6 +844,10 @@ static int mpegts_push_data(MpegTSFilter *filter,
                     av_log(pes->stream, AV_LOG_TRACE, "pid=%x pes_code=%#x\n", 
pes->pid,
                             code);
 
+                    if(pes->st) {
+                        pes->st->event_flags &= 
~AVSTREAM_EVENT_FLAG_NO_CARRIER;
+                    }
+
                     if ((pes->st && pes->st->discard == AVDISCARD_ALL &&
                          (!pes->sub_st ||
                           pes->sub_st->discard == AVDISCARD_ALL)) ||
@@ -1507,6 +1515,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, 
AVStream *st, int stream_type
     default:
         break;
     }
+
     *pp = desc_end;
     return 0;
 }
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 18cd0d7..f91b056 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2430,6 +2430,19 @@ int av_read_pause(AVFormatContext *s)
     return AVERROR(ENOSYS);
 }
 
+void av_reset_event_flags(AVFormatContext *s)
+{
+    int i;
+
+    s->event_flags = 0;
+
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+
+        st->event_flags = st->base_event_flags;
+    }
+}
+
 void avformat_free_context(AVFormatContext *s)
 {
     int i, j;
-- 
2.1.0

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to