[FFmpeg-devel] issue 1483

gordon pendleton wgordonw1 at gmail.com
Fri Jun 29 04:36:22 CEST 2012


On Thu, Jun 28, 2012 at 2:04 AM, Carl Eugen Hoyos <cehoyos at ag.or.at> wrote:

> gordon pendleton <wgordonw1 <at> gmail.com> writes:
>
> > This is my first contribution to FFmpeg, but I tried to follow:
> > http://ffmpeg.org/developer.html#patch-submission-checklist
>
> Purely cosmetic comments, I cannot comment on the actual code:
> Indentation is 4, some blocks look misaligned, you can try
> to use tools/patcheck to check your patch.
>
> -    if ((seg->has_video && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
> -        av_compare_ts(pkt->pts, st->time_base,
> -                      end_pts, AV_TIME_BASE_Q) >= 0 &&
> -        pkt->flags & AV_PKT_FLAG_KEY) {
> +    if (can_split && av_compare_ts(pkt->pts, st->time_base, end_pts,
> AV_TIME_BASE_Q) >= 0) {
>
> You can change this block to reduce the diff, since the new
> line is too long, this is wanted.
>
> Carl Eugen
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>


Thanks for looking at it Carl.  I don't know why but my eclipse settings
weren't set to replace tabs with spaces.  I ran the patch check tool and
this seems to look okay now.

I amended my git commit:
https://github.com/thenewguy/FFmpeg/commit/db7fbe2fa4160c0fb9e33ea8061f880fdcb58b97

Updated patch copied below:


>From db7fbe2fa4160c0fb9e33ea8061f880fdcb58b97 Mon Sep 17 00:00:00 2001
From: gordon <wgordonw1 at gmail.com>
Date: Wed, 27 Jun 2012 20:39:36 -0400
Subject: [PATCH] support a keyframe white list in the segment format.  if
 present, segments will only start with the provided frames.
 Signed-off-by: Gordon <wgordonw1 at gmail.com>

---
 libavformat/segment.c |   64
++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/libavformat/segment.c b/libavformat/segment.c
index 6025aad..7a32e4e 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -36,6 +36,8 @@ typedef struct {
     AVFormatContext *avf;
     char *format;          /**< Set by a private option. */
     char *list;            /**< Set by a private option. */
+    char *valid_frames;    /**< Set by a private option. */
+    const char *valid_frame_delimiter;
     float time;            /**< Set by a private option. */
     int  size;             /**< Set by a private option. */
     int  wrap;             /**< Set by a private option. */
@@ -43,6 +45,10 @@ typedef struct {
     int64_t recording_time;
     int has_video;
     AVIOContext *pb;
+    int64_t next_valid_frame;
+    char *next_valid_frame_ptr;
+    int64_t frame_count;
+    int observe_valid_frames;
 } SegmentContext;

 static int segment_start(AVFormatContext *s)
@@ -107,10 +113,26 @@ static int seg_write_header(AVFormatContext *s)
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc;
     int ret, i;
+    char* token;

     seg->number = 0;
     seg->offset_time = 0;
     seg->recording_time = seg->time * 1000000;
+    seg->frame_count = 0;
+    seg->valid_frame_delimiter = ",";
+    seg->next_valid_frame_ptr = NULL;
+
+    if (seg->valid_frames) {
+        token = av_strtok(seg->valid_frames, seg->valid_frame_delimiter,
&seg->next_valid_frame_ptr);
+        if (token) {
+            seg->next_valid_frame = strtol(token, NULL, 10);
+        }
+        seg->observe_valid_frames = 1;
+    } else {
+        seg->next_valid_frame = 0;
+        seg->observe_valid_frames = 0;
+    }
+

     oc = avformat_alloc_context();

@@ -189,14 +211,29 @@ static int seg_write_packet(AVFormatContext *s,
AVPacket *pkt)
     AVStream *st = oc->streams[pkt->stream_index];
     int64_t end_pts = seg->recording_time * seg->number;
     int ret;
+    char* token;
+    int can_split;
+
+    can_split = seg->has_video && st->codec->codec_type ==
AVMEDIA_TYPE_VIDEO && (pkt->flags & AV_PKT_FLAG_KEY);
+
+    if (seg->observe_valid_frames) {
+        if (seg->next_valid_frame < seg->frame_count) {
+            token = av_strtok(NULL, seg->valid_frame_delimiter,
&seg->next_valid_frame_ptr);
+            if (token) {
+                seg->next_valid_frame = strtol(token, NULL, 10);
+            }
+        }
+        if (seg->next_valid_frame != seg->frame_count) {
+            can_split = 0;
+        }
+    }

-    if ((seg->has_video && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
-        av_compare_ts(pkt->pts, st->time_base,
-                      end_pts, AV_TIME_BASE_Q) >= 0 &&
-        pkt->flags & AV_PKT_FLAG_KEY) {
+    if (can_split && av_compare_ts(pkt->pts, st->time_base, end_pts,
AV_TIME_BASE_Q) >= 0) {

-        av_log(s, AV_LOG_DEBUG, "Next segment starts at %d %"PRId64"\n",
-               pkt->stream_index, pkt->pts);
+        av_log(s, AV_LOG_DEBUG, "Next segment starts at %d %"PRId64" with
frame count of %"PRId64" \n",
+               pkt->stream_index, pkt->pts, seg->frame_count);
+
+        seg->next_valid_frame = -1;

         ret = segment_end(oc);

@@ -218,6 +255,10 @@ static int seg_write_packet(AVFormatContext *s,
AVPacket *pkt)
         }
     }

+    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+        seg->frame_count++;
+    }
+
     ret = oc->oformat->write_packet(oc, pkt);

 fail:
@@ -248,11 +289,12 @@ static int seg_write_trailer(struct AVFormatContext
*s)
 #define OFFSET(x) offsetof(SegmentContext, x)
 #define E AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "segment_format",    "container format used for the segments",
OFFSET(format),  AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E },
-    { "segment_time",      "segment length in seconds",
OFFSET(time),    AV_OPT_TYPE_FLOAT,  {.dbl = 2},     0, FLT_MAX, E },
-    { "segment_list",      "output the segment list",
OFFSET(list),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E },
-    { "segment_list_size", "maximum number of playlist entries",
OFFSET(size),    AV_OPT_TYPE_INT,    {.dbl = 5},     0, INT_MAX, E },
-    { "segment_wrap",      "number after which the index wraps",
OFFSET(wrap),    AV_OPT_TYPE_INT,    {.dbl = 0},     0, INT_MAX, E },
+    { "segment_format",          "container format used for the
segments",                              OFFSET(format),
AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E },
+    { "segment_time",            "segment length in
seconds",                                           OFFSET(time),
AV_OPT_TYPE_FLOAT,   {.dbl = 2},     0, FLT_MAX, E },
+    { "segment_valid_frames",    "comma separated list of frame numbers
allowed to start segments",     OFFSET(valid_frames),
AV_OPT_TYPE_STRING,  {.str = NULL},  0, 0,       E },
+    { "segment_list",            "output the segment
list",                                             OFFSET(list),
AV_OPT_TYPE_STRING,  {.str = NULL},  0, 0,       E },
+    { "segment_list_size",       "maximum number of playlist
entries",                                  OFFSET(size),
AV_OPT_TYPE_INT,     {.dbl = 5},     0, INT_MAX, E },
+    { "segment_wrap",            "number after which the index
wraps",                                  OFFSET(wrap),
AV_OPT_TYPE_INT,     {.dbl = 0},     0, INT_MAX, E },
     { NULL },
 };

-- 
1.7.6.msysgit.0


More information about the ffmpeg-devel mailing list