Skip to content

Instantly share code, notes, and snippets.

@maki-rxrz maki-rxrz/FFmpeg patches
Last active Feb 10, 2018

Embed
What would you like to do?
FFmpeg patches
各パッチの簡単な説明を記載しておきます。
----------------------------------------------------------------------------------------------------
■ ffmpeg-3.4.1-libavcodec-av-picture-structure.diff
----------------------------------------------------------------------------------------------------
[パッチ対象]
-> libavcodec/mpegvideo_parser.c
libavformat のパーサーで取得する情報に、MPEG-2 Videoのフィールド構造ピクチャーの情報を追加します。
フィールド構造ピクチャーにおけるフィールドオーダーの情報を正しく得る為に必要なパッチです。
※ デフォルトだとフィールド構造ピクチャーは強制的にBFFとして扱われてしまう
----------------------------------------------------------------------------------------------------
■ ffmpeg-3.4.1-libavcodec-temporal-reference.diff
----------------------------------------------------------------------------------------------------
[パッチ対象]
-> libavcodec/mpegvideo_parser.c
libavformat のパーサーで取得する情報に、MPEG-2 Videoのフレーム毎のGOP内参照順序の情報を追加します。
L-SMASH Worksのインデックスファイル(.lwi)にフレームの表示順序(POC)が記載されるようになりますが、
今のところ使用用途は有りません。
※ とある問題を解析・対処できないか検討するために追加したパッチ
※ 優先度が低いので検討自体を保留中
----------------------------------------------------------------------------------------------------
■ ffmpeg-3.4.1-libavformat-fix-update-wrap-reference.diff
----------------------------------------------------------------------------------------------------
[パッチ対象]
-> libavformat/utils.c
libavformat のラップアラウンド用タイムスタンプ補正処理を修正するパッチです。
番組切り替えを含んだ放送MPEG-TSにおいて、ストリーム構成が変更される(例:主音声⇒主+副音声)場合に
FFmpegの持つラップアラウンド判定用情報が間違って更新される現象が発生する事を確認しました。
これによりストリーム構成の変更前後がラップアラウンド発生中と見されタイムスタンプ補正処理が間違って
適応されてしまい、フレームが正しい順序で表示されなくなる現象が発生します。
※ パッチ対象となるのはFFmpegのみ (Libavはラップアラウンド用タイムスタンプ補正処理が未搭載)
※ <2017/9/10 作成> 使用は各々の判断でお願いします
----------------------------------------------------------------------------------------------------
■ ffmpeg-3.4.1-allpatches.diff
----------------------------------------------------------------------------------------------------
[パッチ対象]
-> libavcodec/mpegvideo_parser.c
-> libavformat/utils.c
私作成パッチ全ての変更をまとめたパッチファイルです。私作成パッチを一括適用したい場合に使用してください。
----------------------------------------------------------------------------------------------------
■ ffmpeg-3.4.1-allpatches+field-pic-r2.diff
----------------------------------------------------------------------------------------------------
[パッチ対象]
-> libavcodec/mpeg12dec.c
-> libavcodec/mpegvideo_motion.c
-> libavcodec/mpegvideo_parser.c
-> libavformat/utils.c
上記パッチにnekopanda氏のFFmpeg修正パッチ(MPEG-2 Video フィールド構造ピクチャーのデコーダー修正)
をまとめたパッチファイルです。一括適用したい場合に使用してください。
<nekopanda氏 FFmpeg(/Libav)修正パッチ>
https://github.com/nekopanda/FFmpeg
release/3.4
-> bf41380f667f5ad8def0638579f47f2b62ed12ed
-> 8c0f4820f3c027f90d31cb5b9058c480c2cce6de
-> 26df1f2f90487d62c875e65a10d13c50674fcc61 (ffmpeg-3.4.1-libavcodec-av-picture-structure.diff 同等)
----------------------------------------------------------------------------------------------------
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: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/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/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:37:35.039007300 +0900
@@ -59,9 +59,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:
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;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.