[FFmpeg-devel] [PATCH 1/2] mpeg12: raise timecode string to codec context.

Clément Bœsch ubitux at gmail.com
Mon Nov 28 09:33:11 CET 2011


On Tue, Nov 22, 2011 at 06:15:34PM +0100, Michael Niedermayer wrote:
> On Tue, Nov 22, 2011 at 06:01:10PM +0100, Clément Bœsch wrote:
> > On Wed, Nov 16, 2011 at 06:07:50PM +0100, Michael Niedermayer wrote:
> > > On Wed, Nov 16, 2011 at 05:52:33PM +0100, Clément Bœsch wrote:
> > > > From: Clément Bœsch <clement.boesch at smartjog.com>
> > > > 
> > > > ---
> > > >  doc/APIchanges       |    3 +++
> > > >  libavcodec/avcodec.h |    7 +++++++
> > > >  libavcodec/mpeg12.c  |   10 ++++++----
> > > >  libavcodec/version.h |    2 +-
> > > >  4 files changed, 17 insertions(+), 5 deletions(-)
> > > > 
> > > > diff --git a/doc/APIchanges b/doc/APIchanges
> > > > index 8a2a9de..cc72063 100644
> > > > --- a/doc/APIchanges
> > > > +++ b/doc/APIchanges
> > > > @@ -13,6 +13,9 @@ libavutil:   2011-04-18
> > > >  
> > > >  API changes, most recent first:
> > > >  
> > > > +2011-11-xx - xxxxxxx - lavc 53.35.0
> > > > +  Add timecode string (timecode_str) to AVCodecContext.
> > > > +
> > > >  2011-11-03 - 96949da - lavu 51.23.0
> > > >    Add av_strcasecmp() and av_strncasecmp() to avstring.h.
> > > >  
> > > > diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> > > > index d62cbfb..88ebbad 100644
> > > > --- a/libavcodec/avcodec.h
> > > > +++ b/libavcodec/avcodec.h
> > > > @@ -2679,6 +2679,13 @@ typedef struct AVCodecContext {
> > > >       */
> > > >      int64_t timecode_frame_start;
> > > >  
> > > > +    /**
> > > > +     * Codec timecode string
> > > > +     * - encoding: unused
> > > > +     * - decoding: set by libavcodec
> > > > +     */
> > > > +    char timecode_str[16];
> > > > +
> > > >  #if FF_API_REQUEST_CHANNELS
> > > 
> > > adding it in the middle can cause ABI issues
> > > also a note saying that it should only be accessed via av_opt*
> > > would avoid ABI issues if it moves
> > > char [16] might not work well with av_opt though
> > > 
> > 
> > Here is another way (with just a micro bump) of solving that issue: I used
> > the timecode_frame_start to store the 25-bit value from the GOP header
> > since it is ATM only used for encoding.
> > 
> > Maybe the timecode code could be exported so we can add a helper in order
> > to get the string representation.
> > 
> > About using av_opt* functions instead, it is not an easy solution: adding
> > a user RO field in the options doesn't work for probing since the context
> > is reset (avformat_find_stream_info → avcodec_close → av_opt_free) and
> > thus the field is freed and set to NULL. Because of that issue, having it
> > in ffprobe is compromised.
> > 
> > Here is a way to test the attached patch:
> >   ./ffmpeg -debug 1 -i foo.mpg -f null -|& grep GOP
> > 
> > The second patch (for ffprobe) will be sent in a moment.
> > 
> > -- 
> > Clément B.
> 
> >  avcodec.h |    2 +-
> >  mpeg12.c  |   20 +++++++++-----------
> >  version.h |    2 +-
> >  3 files changed, 11 insertions(+), 13 deletions(-)
> > a5367bf57ba13e03733ad0d95414d75cd426e471  0001-mpeg12-raise-timecode-to-codec-context.patch
> > From 4fff640feda72baed7426eceaab8cc36f4ae9ecb Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <clement.boesch at smartjog.com>
> > Date: Wed, 16 Nov 2011 17:40:00 +0100
> > Subject: [PATCH 1/2] mpeg12: raise timecode to codec context.
> 
> LGTM
> 

I'd like to push the new attached version instead, making a distinction
between a set and unset timecode.

ffprobe patch also attached to this mail as a usage example.

-- 
Clément B.
-------------- next part --------------
From c01b60755d3424565701514d0a522100a846f78a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <clement.boesch at smartjog.com>
Date: Wed, 16 Nov 2011 17:40:00 +0100
Subject: [PATCH 1/2] mpeg12: raise timecode to codec context.

---
 libavcodec/avcodec.h   |    6 +++---
 libavcodec/mpeg12.c    |   20 +++++++++-----------
 libavcodec/mpeg12enc.c |    2 ++
 libavcodec/options.c   |    1 +
 libavcodec/version.h   |    2 +-
 5 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index c9165ad..1381a3e 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2710,9 +2710,9 @@ typedef struct AVCodecContext {
 #endif
 
     /**
-     * GOP timecode frame start number, in non drop frame format
-     * - encoding: Set by user.
-     * - decoding: unused
+     * GOP timecode frame start number
+     * - encoding: Set by user, in non drop frame format
+     * - decoding: Set by libavcodec (timecode in the 25 bits format, -1 if unset)
      */
     int64_t timecode_frame_start;
 
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 5385748..fde4e02 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -2141,20 +2141,12 @@ static void mpeg_decode_gop(AVCodecContext *avctx,
 {
     Mpeg1Context *s1  = avctx->priv_data;
     MpegEncContext *s = &s1->mpeg_enc_ctx;
-
-    int drop_frame_flag;
-    int time_code_hours, time_code_minutes;
-    int time_code_seconds, time_code_pictures;
     int broken_link;
+    int64_t tc;
 
     init_get_bits(&s->gb, buf, buf_size*8);
 
-    drop_frame_flag   = get_bits(&s->gb, 1);
-    time_code_hours   = get_bits(&s->gb, 5);
-    time_code_minutes = get_bits(&s->gb, 6);
-    skip_bits1(&s->gb); // marker bit
-    time_code_seconds  = get_bits(&s->gb, 6);
-    time_code_pictures = get_bits(&s->gb, 6);
+    tc = avctx->timecode_frame_start = get_bits(&s->gb, 25);
 
     s->closed_gop = get_bits1(&s->gb);
     /*broken_link indicate that after editing the
@@ -2162,11 +2154,17 @@ static void mpeg_decode_gop(AVCodecContext *avctx,
       are missing (open gop)*/
     broken_link = get_bits1(&s->gb);
 
-    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+    if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
+        int time_code_hours    = tc>>19 & 0x1f;
+        int time_code_minutes  = tc>>13 & 0x3f;
+        int time_code_seconds  = tc>>6  & 0x3f;
+        int drop_frame_flag    = tc     & 1<<24;
+        int time_code_pictures = tc     & 0x3f;
         av_log(s->avctx, AV_LOG_DEBUG, "GOP (%02d:%02d:%02d%c%02d) closed_gop=%d broken_link=%d\n",
                time_code_hours, time_code_minutes, time_code_seconds,
                drop_frame_flag ? ';' : ':',
                time_code_pictures, s->closed_gop, broken_link);
+    }
 }
 /**
  * Find the end of the current frame in the bitstream.
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 653fb40..3cfe733 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -185,6 +185,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
         if (ff_init_smtpe_timecode(s, &s->tc) < 0)
             return -1;
         s->avctx->timecode_frame_start = s->tc.start;
+    } else {
+        s->avctx->timecode_frame_start = 0; // default is -1
     }
     return 0;
 }
diff --git a/libavcodec/options.c b/libavcodec/options.c
index e8fbb6b..0a82d50 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -578,6 +578,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){
     s->sample_aspect_ratio = (AVRational){0,1};
     s->pix_fmt             = PIX_FMT_NONE;
     s->sample_fmt          = AV_SAMPLE_FMT_NONE;
+    s->timecode_frame_start = -1;
 
     s->reget_buffer        = avcodec_default_reget_buffer;
     s->reordered_opaque    = AV_NOPTS_VALUE;
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 31145db..b955116 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -21,7 +21,7 @@
 #define AVCODEC_VERSION_H
 
 #define LIBAVCODEC_VERSION_MAJOR 53
-#define LIBAVCODEC_VERSION_MINOR 38
+#define LIBAVCODEC_VERSION_MINOR 39
 #define LIBAVCODEC_VERSION_MICRO  1
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
-- 
1.7.7.3

-------------- next part --------------
From dd73c942494daf92e2b23dcac2e0427abf767f87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <clement.boesch at smartjog.com>
Date: Wed, 16 Nov 2011 17:42:48 +0100
Subject: [PATCH 2/2] ffprobe: print codec timecode if available.

---
 ffprobe.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/ffprobe.c b/ffprobe.c
index f58b77c..6af7695 100644
--- a/ffprobe.c
+++ b/ffprobe.c
@@ -993,6 +993,17 @@ static void show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_i
             if (s) print_str    ("pix_fmt", s);
             else   print_str_opt("pix_fmt", "unknown");
             print_int("level",   dec_ctx->level);
+            if (dec_ctx->timecode_frame_start >= 0) {
+                uint32_t tc = dec_ctx->timecode_frame_start;
+                print_fmt("timecode", "%02d:%02d:%02d%c%02d",
+                          tc>>19 & 0x1f,              // hours
+                          tc>>13 & 0x3f,              // minutes
+                          tc>>6  & 0x3f,              // seconds
+                          tc     & 1<<24 ? ';' : ':', // drop
+                          tc     & 0x3f);             // frames
+            } else {
+                print_str_opt("timecode", "N/A");
+            }
             break;
 
         case AVMEDIA_TYPE_AUDIO:
-- 
1.7.7.3

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20111128/f6f54475/attachment.asc>


More information about the ffmpeg-devel mailing list