]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mpeg12enc.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / mpeg12enc.c
index dd433215f3511eff7aa5e0bcb92854f071efd577..441e9bbd78ccd93b2aa5f6a526cd98dc4f1577e0 100644 (file)
@@ -3,20 +3,20 @@
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "mpeg12.h"
 #include "mpeg12data.h"
 #include "bytestream.h"
-
+#include "timecode.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
+#include "libavutil/avassert.h"
 
 static const uint8_t inv_non_linear_qscale[13] = {
     0, 2, 4, 6, 8,
@@ -145,6 +146,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
 #if FF_API_MPEGVIDEO_GLOBAL_OPTS
     if (avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE)
         s->drop_frame_timecode = 1;
+    if (avctx->flags & CODEC_FLAG_SVCD_SCAN_OFFSET)
+        s->scan_offset = 1;
 #endif
 
     if(find_frame_rate_index(s) < 0){
@@ -179,11 +182,18 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
+    s->drop_frame_timecode = s->tc.drop = s->drop_frame_timecode || !!(avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE);
     if (s->drop_frame_timecode && s->frame_rate_index != 4) {
         av_log(avctx, AV_LOG_ERROR, "Drop frame time code only allowed with 1001/30000 fps\n");
         return -1;
     }
 
+    if (s->tc.str) {
+        s->tc.rate = ff_frame_rate_tab[s->frame_rate_index];
+        if (ff_init_smtpe_timecode(s, &s->tc) < 0)
+            return -1;
+        s->avctx->timecode_frame_start = s->tc.start;
+    }
     return 0;
 }
 
@@ -297,13 +307,9 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
             time_code = s->current_picture_ptr->f.coded_picture_number + s->avctx->timecode_frame_start;
 
             s->gop_picture_number = s->current_picture_ptr->f.coded_picture_number;
-            if (s->drop_frame_timecode) {
-                /* only works for NTSC 29.97 */
-                int d = time_code / 17982;
-                int m = time_code % 17982;
-                //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */
-                time_code += 18 * d + 2 * ((m - 2) / 1798);
-            }
+            av_assert0(s->drop_frame_timecode == s->tc.drop);
+            if (s->tc.drop)
+                time_code = ff_framenum_to_drop_timecode(time_code);
             put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24));
             put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60));
             put_bits(&s->pb, 1, 1);
@@ -420,7 +426,7 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
         put_bits(&s->pb, 1, s->progressive_frame);
         put_bits(&s->pb, 1, 0); //composite_display_flag
     }
-    if(s->flags & CODEC_FLAG_SVCD_SCAN_OFFSET){
+    if (s->scan_offset) {
         int i;
 
         put_header(s, USER_START_CODE);
@@ -934,9 +940,22 @@ static void mpeg1_encode_block(MpegEncContext *s,
 
 #define OFFSET(x) offsetof(MpegEncContext, x)
 #define VE AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
-static const AVOption options[] = {
-    { "intra_vlc",           "Use MPEG-2 intra VLC table.",       OFFSET(intra_vlc_format),    FF_OPT_TYPE_INT, { 0 }, 0, 1, VE },
-    { "drop_frame_timecode", "Timecode is in drop frame format.", OFFSET(drop_frame_timecode), FF_OPT_TYPE_INT, { 0 }, 0, 1, VE},
+#define COMMON_OPTS\
+        {TIMECODE_OPT(MpegEncContext,\
+         AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)},\
+    { "intra_vlc",           "Use MPEG-2 intra VLC table.",       OFFSET(intra_vlc_format),    FF_OPT_TYPE_INT, { 0 }, 0, 1, VE },\
+    { "drop_frame_timecode", "Timecode is in drop frame format.", OFFSET(drop_frame_timecode), FF_OPT_TYPE_INT, { 0 }, 0, 1, VE}, \
+    { "scan_offset",         "Reserve space for SVCD scan offset user data.", OFFSET(scan_offset), FF_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+
+static const AVOption mpeg1_options[] = {
+    COMMON_OPTS
+    { NULL },
+};
+
+static const AVOption mpeg2_options[] = {
+    COMMON_OPTS
+    { "non_linear_quant",    "Use nonlinear quantizer.",          OFFSET(q_scale_type),         FF_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+    { "alternate_scan",      "Enable alternate scantable.",       OFFSET(alternate_scan),       FF_OPT_TYPE_INT, { 0 }, 0, 1, VE },
     { NULL },
 };
 
@@ -944,7 +963,7 @@ static const AVOption options[] = {
 static const AVClass mpeg## x ##_class = {\
     .class_name   = "mpeg" #x "video encoder",\
     .item_name    = av_default_item_name,\
-    .option       = options,\
+    .option       = mpeg## x ##_options,\
     .version      = LIBAVUTIL_VERSION_INT,\
 };