FFmpeg patches
各パッチの簡単な説明を記載しておきます。 | |
---------------------------------------------------------------------------------------------------- | |
■ ffmpeg-4.2.2-libavcodec-av-picture-structure.diff | |
---------------------------------------------------------------------------------------------------- | |
[パッチ対象] | |
-> libavcodec/mpegvideo_parser.c | |
libavformat のパーサーで取得する情報に、MPEG-2 Videoのフィールド構造ピクチャーの情報を追加します。 | |
フィールド構造ピクチャーにおけるフィールドオーダーの情報を正しく得る為に必要なパッチです。 | |
※ デフォルトだとフィールド構造ピクチャーは強制的にBFFとして扱われてしまう | |
---------------------------------------------------------------------------------------------------- | |
■ ffmpeg-4.2.2-ffprobe-field-order.diff | |
---------------------------------------------------------------------------------------------------- | |
[パッチ対象] | |
-> fftools/ffprobe.c | |
-> libavcodec/avcodec.h | |
-> libavcodec/mpegvideo_parser.c | |
-> libavcodec/utils.c | |
libavcodec/mpegvideo_parser: improve detection of progressive mpeg2 | |
https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/88e2dc7d0448d1d4656c78454bc5f17063b867e7 | |
https://github.com/FFmpeg/FFmpeg/commit/88e2dc7d0448d1d4656c78454bc5f17063b867e7 | |
FFmpeg 4.x以降は、上記コミット(ffprobeでのMPEG-2 Videoプログレッシブフレーム検出)が適応された事で、 | |
MPEG-2 VideoにおけるRFFを伴う2-3プルダウン処理対象となる24pフレームが有するフィールドオーダー情報が | |
取得できない状態になっています。 | |
これにより、L-SMASH WorksではMPEG-2 Videoへリピート制御を適応できなくなる不具合が発生します。 | |
本件に関して以下の変更を行う事で対策を図るパッチです。 | |
(1) 上記コミットをリバート | |
(2) libavcodec にプログレッシブフレーム判定に必要なフラグを追加 | |
(3) libavcodec と ffprobe にプログレッシブフレーム判定処理を追加 | |
【備考】 | |
ffprobe を初めて実行してみた程度の ffprobe 初心者なので、 | |
・24pにRFF&TFFフラグがセットされているデータに対して「progressive」とだけ表示した方が良いか? | |
・破損GOP部分を解析した場合に progressive_sequence が取得できない事で「progressive (bottom first)」 | |
となる(※補足参照)が、壊した人が求めている ffprobe での動作(表示)はコレで良いのか? | |
と言った点に関して、本パッチ内容の良し悪しを判断してかねています。 | |
【補足】 | |
尚、壊したコミットに記載されているサンプルデータ(720p.ts)はプログレッシブオンリーのデータですが、 | |
MPEG-TSの先頭がGOP先頭フレームではないので先頭フレームを対象に解析が行われると progressive_sequence | |
の値を取得する事ができません。 | |
その為、mpegvideo_parser 内ではインターレース用(=I/P混在)判定で処理が行われ、ffprobe 上で | |
「bottom frist」が表示されます。(本パッチを導入した場合は「progressive (bottom first)」) | |
このサンプルデータも、GOP先頭フレームがファイル先頭となる様にファイルカットを行えば、 | |
問題のコミット反映前の ffprobe でも「progressive」と表示される様になります。 | |
---------------------------------------------------------------------------------------------------- | |
■ ffmpeg-4.2.2-libavcodec-temporal-reference.diff | |
---------------------------------------------------------------------------------------------------- | |
[パッチ対象] | |
-> libavcodec/mpegvideo_parser.c | |
libavformat のパーサーで取得する情報に、MPEG-2 Videoのフレーム毎のGOP内参照順序の情報を追加します。 | |
L-SMASH Worksのインデックスファイル(.lwi)にフレームの表示順序(POC)が記載されるようになりますが、 | |
今のところ使用用途は有りません。 | |
※ とある問題を解析・対処できないか検討するために追加したパッチ | |
※ 優先度が低いので検討自体を保留中 | |
---------------------------------------------------------------------------------------------------- | |
■ ffmpeg-4.2.2-libavformat-fix-update-wrap-reference.diff | |
---------------------------------------------------------------------------------------------------- | |
[パッチ対象] | |
-> libavformat/utils.c | |
libavformat のラップアラウンド用タイムスタンプ補正処理を修正するパッチです。 | |
番組切り替えを含んだ放送MPEG-TSにおいて、ストリーム構成が変更される(例:主音声⇒主+副音声)場合に | |
FFmpegの持つラップアラウンド判定用情報が間違って更新される現象が発生する事を確認しました。 | |
これによりストリーム構成の変更前後がラップアラウンド発生中と見されタイムスタンプ補正処理が間違って | |
適応されてしまい、フレームが正しい順序で表示されなくなる現象が発生します。 | |
※ パッチ対象となるのはFFmpegのみ (Libavはラップアラウンド用タイムスタンプ補正処理が未搭載) | |
※ <2017/9/10 作成> 使用は各々の判断でお願いします | |
---------------------------------------------------------------------------------------------------- | |
■ ffmpeg-4.2.2-allpatches.diff | |
---------------------------------------------------------------------------------------------------- | |
[パッチ対象] | |
-> fftools/ffprobe.c | |
-> libavcodec/avcodec.h | |
-> libavcodec/mpegvideo_parser.c | |
-> libavcodec/utils.c | |
-> libavformat/utils.c | |
私作成パッチ全ての変更をまとめたパッチファイルです。私作成パッチを一括適用したい場合に使用して下さい。 | |
---------------------------------------------------------------------------------------------------- | |
■ ffmpeg-3.4.1-allpatches+field-pic-r2.diff | |
---------------------------------------------------------------------------------------------------- | |
3.4.x 用一括パッチ。 | |
上記パッチにnekopanda氏のFFmpeg修正パッチ(MPEG-2 Video フィールド構造ピクチャーのデコーダー修正) | |
をまとめたパッチファイルです。一括適用したい場合に使用してください。 | |
---------------------------------------------------------------------------------------------------- | |
■ ffmpeg-3.4.1-libavcodec-av-picture-structure.diff | |
■ ffmpeg-3.4.1-libavformat-fix-update-wrap-reference.diff | |
---------------------------------------------------------------------------------------------------- | |
外部参照されているこの2点のパッチは旧ファイル名の物を残しておきます。 | |
尚、各パッチのファイル名を ffmpeg-4.2.2-~ に更新しましたが、変更内容は3.4.x 用と変わりありません。 | |
---------------------------------------------------------------------------------------------------- | |
maki |
diff -ur ffmpeg-3.4.1/libavcodec/mpegvideo_parser.c ffmpeg-3.4.1/libavcodec/mpegvideo_parser.c | |
--- ffmpeg-3.4.1/libavcodec/mpegvideo_parser.c 2017-12-11 06:35:08.000000000 +0900 | |
+++ ffmpeg-3.4.1/libavcodec/mpegvideo_parser.c 2018-02-08 11:42:06.335134300 +0900 | |
@@ -41,7 +41,7 @@ | |
uint32_t start_code; | |
int frame_rate_index, ext_type, bytes_left; | |
int frame_rate_ext_n, frame_rate_ext_d; | |
- int top_field_first, repeat_first_field, progressive_frame; | |
+ int picture_structure, top_field_first, repeat_first_field, progressive_frame; | |
int horiz_size_ext, vert_size_ext, bit_rate_ext; | |
int did_set_size=0; | |
int set_dim_ret = 0; | |
@@ -51,6 +51,7 @@ | |
enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; | |
//FIXME replace the crap with get_bits() | |
s->repeat_pict = 0; | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN; | |
while (buf < buf_end) { | |
start_code= -1; | |
@@ -59,9 +60,10 @@ | |
switch(start_code) { | |
case PICTURE_START_CODE: | |
if (bytes_left >= 2) { | |
+ s->output_picture_number = (buf[0] << 2) | (buf[1] >> 6); | |
s->pict_type = (buf[1] >> 3) & 7; | |
if (bytes_left >= 4) | |
- vbv_delay = ((buf[1] & 0x07) << 13) | (buf[2] << 5) | (buf[3] >> 3); | |
+ vbv_delay = ((buf[1] & 0x07) << 13) | (buf[2] << 5) | (buf[3] >> 3); | |
} | |
break; | |
case SEQ_START_CODE: | |
@@ -114,6 +116,7 @@ | |
break; | |
case 0x8: /* picture coding extension */ | |
if (bytes_left >= 5) { | |
+ picture_structure = buf[2] & 0x03; | |
top_field_first = buf[3] & (1 << 7); | |
repeat_first_field = buf[3] & (1 << 1); | |
progressive_frame = buf[4] & (1 << 7); | |
@@ -138,6 +141,18 @@ | |
s->field_order = AV_FIELD_BB; | |
} else | |
s->field_order = AV_FIELD_PROGRESSIVE; | |
+ | |
+ switch (picture_structure) { | |
+ case PICT_TOP_FIELD: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD; | |
+ break; | |
+ case PICT_BOTTOM_FIELD: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD; | |
+ break; | |
+ case PICT_FRAME: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; | |
+ break; | |
+ } | |
} | |
break; | |
} | |
diff -ur ffmpeg-3.4.1/libavformat/utils.c ffmpeg-3.4.1/libavformat/utils.c | |
--- ffmpeg-3.4.1/libavformat/utils.c 2017-12-11 06:35:18.000000000 +0900 | |
+++ ffmpeg-3.4.1/libavformat/utils.c 2018-02-08 11:44:46.243111300 +0900 | |
@@ -777,8 +777,15 @@ | |
while (program) { | |
if (program->pts_wrap_reference != pts_wrap_reference) { | |
for (i = 0; i<program->nb_stream_indexes; i++) { | |
- s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; | |
- s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; | |
+ if (s->streams[program->stream_index[i]]->pts_wrap_reference != AV_NOPTS_VALUE && | |
+ (s->streams[program->stream_index[i]]->pts_wrap_reference - pts_wrap_reference > 1LL << st->pts_wrap_bits-3 || | |
+ s->streams[program->stream_index[i]]->pts_wrap_reference < pts_wrap_reference)) { | |
+ pts_wrap_reference = s->streams[program->stream_index[i]]->pts_wrap_reference; | |
+ pts_wrap_behavior = s->streams[program->stream_index[i]]->pts_wrap_behavior; | |
+ } else { | |
+ s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; | |
+ s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; | |
+ } | |
} | |
program->pts_wrap_reference = pts_wrap_reference; | |
diff -ur ffmpeg-3.4.1/libavcodec/mpeg12dec.c ffmpeg-3.4.1/libavcodec/mpeg12dec.c | |
--- ffmpeg-3.4.1/libavcodec/mpeg12dec.c 2017-12-11 06:35:08.000000000 +0900 | |
+++ ffmpeg-3.4.1/libavcodec/mpeg12dec.c 2018-02-08 11:53:41.714079000 +0900 | |
@@ -1984,6 +1984,8 @@ | |
s->mv[0][0][1] = s->last_mv[0][0][1]; | |
s->mv[1][0][0] = s->last_mv[1][0][0]; | |
s->mv[1][0][1] = s->last_mv[1][0][1]; | |
+ s->field_select[0][0] = (s->picture_structure - 1) & 1; | |
+ s->field_select[1][0] = (s->picture_structure - 1) & 1; | |
} | |
} | |
} | |
diff -ur ffmpeg-3.4.1/libavcodec/mpegvideo_motion.c ffmpeg-3.4.1/libavcodec/mpegvideo_motion.c | |
--- ffmpeg-3.4.1/libavcodec/mpegvideo_motion.c 2017-12-11 06:35:08.000000000 +0900 | |
+++ ffmpeg-3.4.1/libavcodec/mpegvideo_motion.c 2018-02-10 21:11:11.086291300 +0900 | |
@@ -239,20 +239,22 @@ | |
int motion_y, | |
int h, | |
int is_mpeg12, | |
+ int is_16x8, | |
int mb_y) | |
{ | |
uint8_t *ptr_y, *ptr_cb, *ptr_cr; | |
int dxy, uvdxy, mx, my, src_x, src_y, | |
- uvsrc_x, uvsrc_y, v_edge_pos; | |
+ uvsrc_x, uvsrc_y, v_edge_pos, block_y_half; | |
ptrdiff_t uvlinesize, linesize; | |
v_edge_pos = s->v_edge_pos >> field_based; | |
linesize = s->current_picture.f->linesize[0] << field_based; | |
uvlinesize = s->current_picture.f->linesize[1] << field_based; | |
+ block_y_half = (field_based | is_16x8); | |
dxy = ((motion_y & 1) << 1) | (motion_x & 1); | |
src_x = s->mb_x * 16 + (motion_x >> 1); | |
- src_y = (mb_y << (4 - field_based)) + (motion_y >> 1); | |
+ src_y = (mb_y << (4 - block_y_half)) + (motion_y >> 1); | |
if (!is_mpeg12 && s->out_format == FMT_H263) { | |
if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) { | |
@@ -260,7 +262,7 @@ | |
my = motion_y >> 1; | |
uvdxy = ((my & 1) << 1) | (mx & 1); | |
uvsrc_x = s->mb_x * 8 + (mx >> 1); | |
- uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1); | |
+ uvsrc_y = (mb_y << (3 - block_y_half)) + (my >> 1); | |
} else { | |
uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); | |
uvsrc_x = src_x >> 1; | |
@@ -279,7 +281,7 @@ | |
my = motion_y / 2; | |
uvdxy = ((my & 1) << 1) | (mx & 1); | |
uvsrc_x = s->mb_x * 8 + (mx >> 1); | |
- uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1); | |
+ uvsrc_y = (mb_y << (3 - block_y_half)) + (my >> 1); | |
} else { | |
if (s->chroma_x_shift) { | |
// Chroma422 | |
@@ -370,18 +372,18 @@ | |
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, | |
int field_select, uint8_t **ref_picture, | |
op_pixels_func (*pix_op)[4], | |
- int motion_x, int motion_y, int h, int mb_y) | |
+ int motion_x, int motion_y, int h, int is_16x8, int mb_y) | |
{ | |
#if !CONFIG_SMALL | |
if (s->out_format == FMT_MPEG1) | |
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0, | |
field_select, ref_picture, pix_op, | |
- motion_x, motion_y, h, 1, mb_y); | |
+ motion_x, motion_y, h, 1, is_16x8, mb_y); | |
else | |
#endif | |
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0, | |
field_select, ref_picture, pix_op, | |
- motion_x, motion_y, h, 0, mb_y); | |
+ motion_x, motion_y, h, 0, is_16x8, mb_y); | |
} | |
static void mpeg_motion_field(MpegEncContext *s, uint8_t *dest_y, | |
@@ -395,12 +397,12 @@ | |
if (s->out_format == FMT_MPEG1) | |
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1, | |
bottom_field, field_select, ref_picture, pix_op, | |
- motion_x, motion_y, h, 1, mb_y); | |
+ motion_x, motion_y, h, 1, 0, mb_y); | |
else | |
#endif | |
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1, | |
bottom_field, field_select, ref_picture, pix_op, | |
- motion_x, motion_y, h, 0, mb_y); | |
+ motion_x, motion_y, h, 0, 0, mb_y); | |
} | |
// FIXME: SIMDify, avg variant, 16x16 version | |
@@ -870,7 +872,7 @@ | |
} else { | |
mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, | |
ref_picture, pix_op, | |
- s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y); | |
+ s->mv[dir][0][0], s->mv[dir][0][1], 16, 0, mb_y); | |
} | |
break; | |
case MV_TYPE_8X8: | |
@@ -907,7 +909,7 @@ | |
mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
s->field_select[dir][0], | |
ref_picture, pix_op, | |
- s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y >> 1); | |
+ s->mv[dir][0][0], s->mv[dir][0][1], 16, 0, mb_y >> 1); | |
} | |
break; | |
case MV_TYPE_16X8: | |
@@ -924,8 +926,8 @@ | |
mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
s->field_select[dir][i], | |
ref2picture, pix_op, | |
- s->mv[dir][i][0], s->mv[dir][i][1] + 16 * i, | |
- 8, mb_y >> 1); | |
+ s->mv[dir][i][0], s->mv[dir][i][1], | |
+ 8, 1, (mb_y & ~1) + i); | |
dest_y += 16 * s->linesize; | |
dest_cb += (16 >> s->chroma_y_shift) * s->uvlinesize; | |
@@ -952,7 +954,7 @@ | |
s->picture_structure != i + 1, | |
ref_picture, pix_op, | |
s->mv[dir][2 * i][0], s->mv[dir][2 * i][1], | |
- 16, mb_y >> 1); | |
+ 16, 0, mb_y >> 1); | |
// after put we make avg of the same block | |
pix_op = s->hdsp.avg_pixels_tab; |
diff -ur ffmpeg-3.4.1/libavcodec/mpegvideo_parser.c ffmpeg-3.4.1/libavcodec/mpegvideo_parser.c | |
--- ffmpeg-3.4.1/libavcodec/mpegvideo_parser.c 2017-12-11 06:35:08.000000000 +0900 | |
+++ ffmpeg-3.4.1/libavcodec/mpegvideo_parser.c 2018-02-08 11:33:46.597449200 +0900 | |
@@ -41,7 +41,7 @@ | |
uint32_t start_code; | |
int frame_rate_index, ext_type, bytes_left; | |
int frame_rate_ext_n, frame_rate_ext_d; | |
- int top_field_first, repeat_first_field, progressive_frame; | |
+ int picture_structure, top_field_first, repeat_first_field, progressive_frame; | |
int horiz_size_ext, vert_size_ext, bit_rate_ext; | |
int did_set_size=0; | |
int set_dim_ret = 0; | |
@@ -51,6 +51,7 @@ | |
enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; | |
//FIXME replace the crap with get_bits() | |
s->repeat_pict = 0; | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN; | |
while (buf < buf_end) { | |
start_code= -1; | |
@@ -114,6 +115,7 @@ | |
break; | |
case 0x8: /* picture coding extension */ | |
if (bytes_left >= 5) { | |
+ picture_structure = buf[2] & 0x03; | |
top_field_first = buf[3] & (1 << 7); | |
repeat_first_field = buf[3] & (1 << 1); | |
progressive_frame = buf[4] & (1 << 7); | |
@@ -138,6 +140,18 @@ | |
s->field_order = AV_FIELD_BB; | |
} else | |
s->field_order = AV_FIELD_PROGRESSIVE; | |
+ | |
+ switch (picture_structure) { | |
+ case PICT_TOP_FIELD: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD; | |
+ break; | |
+ case PICT_BOTTOM_FIELD: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD; | |
+ break; | |
+ case PICT_FRAME: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; | |
+ break; | |
+ } | |
} | |
break; | |
} |
diff -ur ffmpeg-3.4.1/libavformat/utils.c ffmpeg-3.4.1/libavformat/utils.c | |
--- ffmpeg-3.4.1/libavformat/utils.c 2017-12-11 06:35:18.000000000 +0900 | |
+++ ffmpeg-3.4.1/libavformat/utils.c 2018-02-08 11:44:46.243111300 +0900 | |
@@ -777,8 +777,15 @@ | |
while (program) { | |
if (program->pts_wrap_reference != pts_wrap_reference) { | |
for (i = 0; i<program->nb_stream_indexes; i++) { | |
- s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; | |
- s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; | |
+ if (s->streams[program->stream_index[i]]->pts_wrap_reference != AV_NOPTS_VALUE && | |
+ (s->streams[program->stream_index[i]]->pts_wrap_reference - pts_wrap_reference > 1LL << st->pts_wrap_bits-3 || | |
+ s->streams[program->stream_index[i]]->pts_wrap_reference < pts_wrap_reference)) { | |
+ pts_wrap_reference = s->streams[program->stream_index[i]]->pts_wrap_reference; | |
+ pts_wrap_behavior = s->streams[program->stream_index[i]]->pts_wrap_behavior; | |
+ } else { | |
+ s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; | |
+ s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; | |
+ } | |
} | |
program->pts_wrap_reference = pts_wrap_reference; |
diff -ur ffmpeg-4.2.2/fftools/ffprobe.c ffmpeg-4.2.2/fftools/ffprobe.c | |
--- ffmpeg-4.2.2/fftools/ffprobe.c 2020-01-01 06:35:22.000000000 +0900 | |
+++ ffmpeg-4.2.2/fftools/ffprobe.c 2020-01-15 22:34:02.577458400 +0900 | |
@@ -2560,9 +2560,9 @@ | |
if (par->field_order == AV_FIELD_PROGRESSIVE) | |
print_str("field_order", "progressive"); | |
else if (par->field_order == AV_FIELD_TT) | |
- print_str("field_order", "tt"); | |
+ print_str("field_order", par->progressive_frame ? "progressive (tt)" : "tt"); | |
else if (par->field_order == AV_FIELD_BB) | |
- print_str("field_order", "bb"); | |
+ print_str("field_order", par->progressive_frame ? "progressive (bb)" : "bb"); | |
else if (par->field_order == AV_FIELD_TB) | |
print_str("field_order", "tb"); | |
else if (par->field_order == AV_FIELD_BT) | |
diff -ur ffmpeg-4.2.2/libavcodec/avcodec.h ffmpeg-4.2.2/libavcodec/avcodec.h | |
--- ffmpeg-4.2.2/libavcodec/avcodec.h 2020-01-01 06:35:23.000000000 +0900 | |
+++ ffmpeg-4.2.2/libavcodec/avcodec.h 2020-01-15 22:30:37.916578000 +0900 | |
@@ -2221,6 +2221,13 @@ | |
*/ | |
enum AVFieldOrder field_order; | |
+ /** | |
+ * Progressive frame flag. | |
+ * - encoding: unused | |
+ * - decoding: Set by libavcodec | |
+ */ | |
+ int progressive_frame; | |
+ | |
/* audio only */ | |
int sample_rate; ///< samples per second | |
int channels; ///< number of audio channels | |
@@ -4038,6 +4045,11 @@ | |
enum AVFieldOrder field_order; | |
/** | |
+ * Video only. Progressive frame flag. | |
+ */ | |
+ int progressive_frame; | |
+ | |
+ /** | |
* Video only. Additional colorspace characteristics. | |
*/ | |
enum AVColorRange color_range; | |
diff -ur ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c | |
--- ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c 2020-01-01 06:35:23.000000000 +0900 | |
+++ ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c 2020-01-15 22:45:56.367183400 +0900 | |
@@ -41,7 +41,7 @@ | |
uint32_t start_code; | |
int frame_rate_index, ext_type, bytes_left; | |
int frame_rate_ext_n, frame_rate_ext_d; | |
- int top_field_first, repeat_first_field, progressive_frame; | |
+ int picture_structure, top_field_first, repeat_first_field; | |
int horiz_size_ext, vert_size_ext, bit_rate_ext; | |
int did_set_size=0; | |
int set_dim_ret = 0; | |
@@ -51,6 +51,7 @@ | |
enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; | |
//FIXME replace the crap with get_bits() | |
s->repeat_pict = 0; | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN; | |
while (buf < buf_end) { | |
start_code= -1; | |
@@ -59,6 +60,7 @@ | |
switch(start_code) { | |
case PICTURE_START_CODE: | |
if (bytes_left >= 2) { | |
+ s->output_picture_number = (buf[0] << 2) | (buf[1] >> 6); | |
s->pict_type = (buf[1] >> 3) & 7; | |
if (bytes_left >= 4) | |
vbv_delay = ((buf[1] & 0x07) << 13) | (buf[2] << 5) | (buf[3] >> 3); | |
@@ -114,9 +116,10 @@ | |
break; | |
case 0x8: /* picture coding extension */ | |
if (bytes_left >= 5) { | |
+ picture_structure = buf[2] & 0x03; | |
top_field_first = buf[3] & (1 << 7); | |
repeat_first_field = buf[3] & (1 << 1); | |
- progressive_frame = buf[4] & (1 << 7); | |
+ avctx->progressive_frame = !!(buf[4] & (1 << 7)); | |
/* check if we must repeat the frame */ | |
s->repeat_pict = 1; | |
@@ -126,18 +129,30 @@ | |
s->repeat_pict = 5; | |
else | |
s->repeat_pict = 3; | |
- } else if (progressive_frame) { | |
+ } else if (avctx->progressive_frame) { | |
s->repeat_pict = 2; | |
} | |
} | |
- if (!pc->progressive_sequence && !progressive_frame) { | |
+ if (!pc->progressive_sequence) { | |
if (top_field_first) | |
s->field_order = AV_FIELD_TT; | |
else | |
s->field_order = AV_FIELD_BB; | |
} else | |
s->field_order = AV_FIELD_PROGRESSIVE; | |
+ | |
+ switch (picture_structure) { | |
+ case PICT_TOP_FIELD: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD; | |
+ break; | |
+ case PICT_BOTTOM_FIELD: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD; | |
+ break; | |
+ case PICT_FRAME: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; | |
+ break; | |
+ } | |
} | |
break; | |
} | |
diff -ur ffmpeg-4.2.2/libavcodec/utils.c ffmpeg-4.2.2/libavcodec/utils.c | |
--- ffmpeg-4.2.2/libavcodec/utils.c 2020-01-01 06:35:30.000000000 +0900 | |
+++ ffmpeg-4.2.2/libavcodec/utils.c 2020-01-15 22:32:43.318693200 +0900 | |
@@ -1274,9 +1274,9 @@ | |
if (enc->field_order != AV_FIELD_UNKNOWN) { | |
const char *field_order = "progressive"; | |
if (enc->field_order == AV_FIELD_TT) | |
- field_order = "top first"; | |
+ field_order = enc->progressive_frame ? "progressive (tff)" : "top first"; | |
else if (enc->field_order == AV_FIELD_BB) | |
- field_order = "bottom first"; | |
+ field_order = enc->progressive_frame ? "progressive (bff)" : "bottom first"; | |
else if (enc->field_order == AV_FIELD_TB) | |
field_order = "top coded first (swapped)"; | |
else if (enc->field_order == AV_FIELD_BT) | |
@@ -2076,6 +2076,7 @@ | |
par->width = codec->width; | |
par->height = codec->height; | |
par->field_order = codec->field_order; | |
+ par->progressive_frame = codec->progressive_frame; | |
par->color_range = codec->color_range; | |
par->color_primaries = codec->color_primaries; | |
par->color_trc = codec->color_trc; | |
@@ -2131,6 +2132,7 @@ | |
codec->width = par->width; | |
codec->height = par->height; | |
codec->field_order = par->field_order; | |
+ codec->progressive_frame = par->progressive_frame; | |
codec->color_range = par->color_range; | |
codec->color_primaries = par->color_primaries; | |
codec->color_trc = par->color_trc; | |
diff -ur ffmpeg-4.2.2/libavformat/utils.c ffmpeg-4.2.2/libavformat/utils.c | |
--- ffmpeg-4.2.2/libavformat/utils.c 2020-01-01 06:35:24.000000000 +0900 | |
+++ ffmpeg-4.2.2/libavformat/utils.c 2020-01-15 22:38:05.804552300 +0900 | |
@@ -815,8 +815,15 @@ | |
while (program) { | |
if (program->pts_wrap_reference != pts_wrap_reference) { | |
for (i = 0; i<program->nb_stream_indexes; i++) { | |
- s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; | |
- s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; | |
+ if (s->streams[program->stream_index[i]]->pts_wrap_reference != AV_NOPTS_VALUE && | |
+ (s->streams[program->stream_index[i]]->pts_wrap_reference - pts_wrap_reference > 1LL << st->pts_wrap_bits-3 || | |
+ s->streams[program->stream_index[i]]->pts_wrap_reference < pts_wrap_reference)) { | |
+ pts_wrap_reference = s->streams[program->stream_index[i]]->pts_wrap_reference; | |
+ pts_wrap_behavior = s->streams[program->stream_index[i]]->pts_wrap_behavior; | |
+ } else { | |
+ s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; | |
+ s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; | |
+ } | |
} | |
program->pts_wrap_reference = pts_wrap_reference; |
diff -ur ffmpeg-4.2.2/fftools/ffprobe.c ffmpeg-4.2.2/fftools/ffprobe.c | |
--- ffmpeg-4.2.2/fftools/ffprobe.c 2020-01-01 06:35:22.000000000 +0900 | |
+++ ffmpeg-4.2.2/fftools/ffprobe.c 2020-01-15 22:34:02.577458400 +0900 | |
@@ -2560,9 +2560,9 @@ | |
if (par->field_order == AV_FIELD_PROGRESSIVE) | |
print_str("field_order", "progressive"); | |
else if (par->field_order == AV_FIELD_TT) | |
- print_str("field_order", "tt"); | |
+ print_str("field_order", par->progressive_frame ? "progressive (tt)" : "tt"); | |
else if (par->field_order == AV_FIELD_BB) | |
- print_str("field_order", "bb"); | |
+ print_str("field_order", par->progressive_frame ? "progressive (bb)" : "bb"); | |
else if (par->field_order == AV_FIELD_TB) | |
print_str("field_order", "tb"); | |
else if (par->field_order == AV_FIELD_BT) | |
diff -ur ffmpeg-4.2.2/libavcodec/avcodec.h ffmpeg-4.2.2/libavcodec/avcodec.h | |
--- ffmpeg-4.2.2/libavcodec/avcodec.h 2020-01-01 06:35:23.000000000 +0900 | |
+++ ffmpeg-4.2.2/libavcodec/avcodec.h 2020-01-15 22:30:37.916578000 +0900 | |
@@ -2221,6 +2221,13 @@ | |
*/ | |
enum AVFieldOrder field_order; | |
+ /** | |
+ * Progressive frame flag. | |
+ * - encoding: unused | |
+ * - decoding: Set by libavcodec | |
+ */ | |
+ int progressive_frame; | |
+ | |
/* audio only */ | |
int sample_rate; ///< samples per second | |
int channels; ///< number of audio channels | |
@@ -4038,6 +4045,11 @@ | |
enum AVFieldOrder field_order; | |
/** | |
+ * Video only. Progressive frame flag. | |
+ */ | |
+ int progressive_frame; | |
+ | |
+ /** | |
* Video only. Additional colorspace characteristics. | |
*/ | |
enum AVColorRange color_range; | |
diff -ur ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c | |
--- ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c 2020-01-01 06:35:23.000000000 +0900 | |
+++ ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c 2020-01-15 22:30:37.924578300 +0900 | |
@@ -41,7 +41,7 @@ | |
uint32_t start_code; | |
int frame_rate_index, ext_type, bytes_left; | |
int frame_rate_ext_n, frame_rate_ext_d; | |
- int top_field_first, repeat_first_field, progressive_frame; | |
+ int top_field_first, repeat_first_field; | |
int horiz_size_ext, vert_size_ext, bit_rate_ext; | |
int did_set_size=0; | |
int set_dim_ret = 0; | |
@@ -116,7 +116,7 @@ | |
if (bytes_left >= 5) { | |
top_field_first = buf[3] & (1 << 7); | |
repeat_first_field = buf[3] & (1 << 1); | |
- progressive_frame = buf[4] & (1 << 7); | |
+ avctx->progressive_frame = !!(buf[4] & (1 << 7)); | |
/* check if we must repeat the frame */ | |
s->repeat_pict = 1; | |
@@ -126,12 +126,12 @@ | |
s->repeat_pict = 5; | |
else | |
s->repeat_pict = 3; | |
- } else if (progressive_frame) { | |
+ } else if (avctx->progressive_frame) { | |
s->repeat_pict = 2; | |
} | |
} | |
- if (!pc->progressive_sequence && !progressive_frame) { | |
+ if (!pc->progressive_sequence) { | |
if (top_field_first) | |
s->field_order = AV_FIELD_TT; | |
else | |
diff -ur ffmpeg-4.2.2/libavcodec/utils.c ffmpeg-4.2.2/libavcodec/utils.c | |
--- ffmpeg-4.2.2/libavcodec/utils.c 2020-01-01 06:35:30.000000000 +0900 | |
+++ ffmpeg-4.2.2/libavcodec/utils.c 2020-01-15 22:32:43.318693200 +0900 | |
@@ -1274,9 +1274,9 @@ | |
if (enc->field_order != AV_FIELD_UNKNOWN) { | |
const char *field_order = "progressive"; | |
if (enc->field_order == AV_FIELD_TT) | |
- field_order = "top first"; | |
+ field_order = enc->progressive_frame ? "progressive (tff)" : "top first"; | |
else if (enc->field_order == AV_FIELD_BB) | |
- field_order = "bottom first"; | |
+ field_order = enc->progressive_frame ? "progressive (bff)" : "bottom first"; | |
else if (enc->field_order == AV_FIELD_TB) | |
field_order = "top coded first (swapped)"; | |
else if (enc->field_order == AV_FIELD_BT) | |
@@ -2076,6 +2076,7 @@ | |
par->width = codec->width; | |
par->height = codec->height; | |
par->field_order = codec->field_order; | |
+ par->progressive_frame = codec->progressive_frame; | |
par->color_range = codec->color_range; | |
par->color_primaries = codec->color_primaries; | |
par->color_trc = codec->color_trc; | |
@@ -2131,6 +2132,7 @@ | |
codec->width = par->width; | |
codec->height = par->height; | |
codec->field_order = par->field_order; | |
+ codec->progressive_frame = par->progressive_frame; | |
codec->color_range = par->color_range; | |
codec->color_primaries = par->color_primaries; | |
codec->color_trc = par->color_trc; |
diff -ur ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c | |
--- ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c 2020-01-01 06:35:23.000000000 +0900 | |
+++ ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c 2020-01-15 22:20:57.922440600 +0900 | |
@@ -41,7 +41,7 @@ | |
uint32_t start_code; | |
int frame_rate_index, ext_type, bytes_left; | |
int frame_rate_ext_n, frame_rate_ext_d; | |
- int top_field_first, repeat_first_field, progressive_frame; | |
+ int picture_structure, top_field_first, repeat_first_field, progressive_frame; | |
int horiz_size_ext, vert_size_ext, bit_rate_ext; | |
int did_set_size=0; | |
int set_dim_ret = 0; | |
@@ -51,6 +51,7 @@ | |
enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; | |
//FIXME replace the crap with get_bits() | |
s->repeat_pict = 0; | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN; | |
while (buf < buf_end) { | |
start_code= -1; | |
@@ -114,6 +115,7 @@ | |
break; | |
case 0x8: /* picture coding extension */ | |
if (bytes_left >= 5) { | |
+ picture_structure = buf[2] & 0x03; | |
top_field_first = buf[3] & (1 << 7); | |
repeat_first_field = buf[3] & (1 << 1); | |
progressive_frame = buf[4] & (1 << 7); | |
@@ -138,6 +140,18 @@ | |
s->field_order = AV_FIELD_BB; | |
} else | |
s->field_order = AV_FIELD_PROGRESSIVE; | |
+ | |
+ switch (picture_structure) { | |
+ case PICT_TOP_FIELD: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD; | |
+ break; | |
+ case PICT_BOTTOM_FIELD: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD; | |
+ break; | |
+ case PICT_FRAME: | |
+ s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; | |
+ break; | |
+ } | |
} | |
break; | |
} |
diff -ur ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c | |
--- ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c 2020-01-01 06:35:23.000000000 +0900 | |
+++ ffmpeg-4.2.2/libavcodec/mpegvideo_parser.c 2020-01-15 22:25:18.030494400 +0900 | |
@@ -59,6 +59,7 @@ | |
switch(start_code) { | |
case PICTURE_START_CODE: | |
if (bytes_left >= 2) { | |
+ s->output_picture_number = (buf[0] << 2) | (buf[1] >> 6); | |
s->pict_type = (buf[1] >> 3) & 7; | |
if (bytes_left >= 4) | |
vbv_delay = ((buf[1] & 0x07) << 13) | (buf[2] << 5) | (buf[3] >> 3); |
diff -ur ffmpeg-4.2.2/libavformat/utils.c ffmpeg-4.2.2/libavformat/utils.c | |
--- ffmpeg-4.2.2/libavformat/utils.c 2020-01-01 06:35:24.000000000 +0900 | |
+++ ffmpeg-4.2.2/libavformat/utils.c 2020-01-15 22:38:05.804552300 +0900 | |
@@ -815,8 +815,15 @@ | |
while (program) { | |
if (program->pts_wrap_reference != pts_wrap_reference) { | |
for (i = 0; i<program->nb_stream_indexes; i++) { | |
- s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; | |
- s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; | |
+ if (s->streams[program->stream_index[i]]->pts_wrap_reference != AV_NOPTS_VALUE && | |
+ (s->streams[program->stream_index[i]]->pts_wrap_reference - pts_wrap_reference > 1LL << st->pts_wrap_bits-3 || | |
+ s->streams[program->stream_index[i]]->pts_wrap_reference < pts_wrap_reference)) { | |
+ pts_wrap_reference = s->streams[program->stream_index[i]]->pts_wrap_reference; | |
+ pts_wrap_behavior = s->streams[program->stream_index[i]]->pts_wrap_behavior; | |
+ } else { | |
+ s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; | |
+ s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; | |
+ } | |
} | |
program->pts_wrap_reference = pts_wrap_reference; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment