mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
ffmpeg: add upstream patch
Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
parent
fe1224fc57
commit
9dbc9b038e
@ -0,0 +1,236 @@
|
||||
From 3a6ea59e122d5bc981a2a5c8f9bafcba0f9f8754 Mon Sep 17 00:00:00 2001
|
||||
From: Joakim Plate <elupus@ecce.se>
|
||||
Date: Wed, 26 Jun 2013 22:07:28 +0200
|
||||
Subject: [PATCH 1/1] h264: expose h264 frame packing as stereo_mode metadata
|
||||
|
||||
---
|
||||
libavcodec/h264.c | 3 ++
|
||||
libavcodec/h264.h | 35 ++++++++++++++-
|
||||
libavcodec/h264_parser.c | 1 +
|
||||
libavcodec/h264_sei.c | 85 +++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 123 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
|
||||
index 937ad7a..85f2372 100644
|
||||
--- a/libavcodec/h264.c
|
||||
+++ b/libavcodec/h264.c
|
||||
@@ -1437,6 +1437,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
|
||||
h->prev_poc_msb = 1 << 16;
|
||||
h->prev_frame_num = -1;
|
||||
h->x264_build = -1;
|
||||
+ h->sei_fpa.frame_packing_arrangement_cancel_flag = -1;
|
||||
ff_h264_reset_sei(h);
|
||||
if (avctx->codec_id == AV_CODEC_ID_H264) {
|
||||
if (avctx->ticks_per_frame == 1) {
|
||||
@@ -4783,6 +4784,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
out->f.reference &= ~DELAYED_PIC_REF;
|
||||
*got_frame = 1;
|
||||
*pict = out->f;
|
||||
+ av_dict_set(&pict->metadata, "stereo_mode", ff_h264_sei_stereo_mode(h), 0);
|
||||
}
|
||||
|
||||
return buf_index;
|
||||
@@ -4839,6 +4841,7 @@ not_extra:
|
||||
if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) {
|
||||
*got_frame = 1;
|
||||
*pict = h->next_output_pic->f;
|
||||
+ av_dict_set(&pict->metadata, "stereo_mode", ff_h264_sei_stereo_mode(h), 0);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
|
||||
index 7ea613c..15a0b21 100644
|
||||
--- a/libavcodec/h264.h
|
||||
+++ b/libavcodec/h264.h
|
||||
@@ -126,7 +126,8 @@ typedef enum {
|
||||
SEI_TYPE_PIC_TIMING = 1, ///< picture timing
|
||||
SEI_TYPE_USER_DATA_ITU_T_T35 = 4, ///< user data registered by ITU-T Recommendation T.35
|
||||
SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data
|
||||
- SEI_TYPE_RECOVERY_POINT = 6 ///< recovery point (frame # to decoder sync)
|
||||
+ SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync)
|
||||
+ SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement
|
||||
} SEI_Type;
|
||||
|
||||
/**
|
||||
@@ -145,6 +146,19 @@ typedef enum {
|
||||
} SEI_PicStructType;
|
||||
|
||||
/**
|
||||
+ * frame_packing_arrangement types
|
||||
+ */
|
||||
+typedef enum {
|
||||
+ SEI_FPA_TYPE_CHECKERBOARD = 0,
|
||||
+ SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1,
|
||||
+ SEI_FPA_TYPE_INTERLEAVE_ROW = 2,
|
||||
+ SEI_FPA_TYPE_SIDE_BY_SIDE = 3,
|
||||
+ SEI_FPA_TYPE_TOP_BOTTOM = 4,
|
||||
+ SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5,
|
||||
+ SEI_FPA_TYPE_2D = 6,
|
||||
+} SEI_FpaType;
|
||||
+
|
||||
+/**
|
||||
* Sequence parameter set
|
||||
*/
|
||||
typedef struct SPS {
|
||||
@@ -230,6 +244,17 @@ typedef struct PPS {
|
||||
} PPS;
|
||||
|
||||
/**
|
||||
+ * Frame Packing Arrangement Type
|
||||
+ */
|
||||
+typedef struct FPA {
|
||||
+ int frame_packing_arrangement_id;
|
||||
+ int frame_packing_arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received
|
||||
+ SEI_FpaType frame_packing_arrangement_type;
|
||||
+ int content_interpretation_type;
|
||||
+ int quincunx_sampling_flag;
|
||||
+} FPA;
|
||||
+
|
||||
+/**
|
||||
* Memory management control operation opcode.
|
||||
*/
|
||||
typedef enum MMCOOpcode {
|
||||
@@ -626,6 +651,8 @@ typedef struct H264Context {
|
||||
*/
|
||||
int valid_recovery_point;
|
||||
|
||||
+ FPA sei_fpa;
|
||||
+
|
||||
int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag
|
||||
int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag
|
||||
|
||||
@@ -771,6 +798,12 @@ void ff_h264_filter_mb(H264Context *h, int mb_x, int mb_y,
|
||||
*/
|
||||
void ff_h264_reset_sei(H264Context *h);
|
||||
|
||||
+/**
|
||||
+ * Get stereo_mode string from the h264 frame_packing_arrangement
|
||||
+ * @param h H.264 context.
|
||||
+ */
|
||||
+const char* ff_h264_sei_stereo_mode(H264Context *h);
|
||||
+
|
||||
/*
|
||||
* o-o o-o
|
||||
* / / /
|
||||
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
|
||||
index 44b92b7..aff9ba1 100644
|
||||
--- a/libavcodec/h264_parser.c
|
||||
+++ b/libavcodec/h264_parser.c
|
||||
@@ -158,6 +158,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
|
||||
h->sei_dpb_output_delay = 0;
|
||||
h->sei_cpb_removal_delay = -1;
|
||||
h->sei_buffering_period_present = 0;
|
||||
+ h->sei_fpa.frame_packing_arrangement_cancel_flag = -1;
|
||||
|
||||
if (!buf_size)
|
||||
return 0;
|
||||
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
|
||||
index ece54f1..fc9b96f 100644
|
||||
--- a/libavcodec/h264_sei.c
|
||||
+++ b/libavcodec/h264_sei.c
|
||||
@@ -194,6 +194,43 @@ static int decode_buffering_period(H264Context *h){
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int decode_frame_packing(H264Context *h, int size){
|
||||
+ int bits = get_bits_left(&h->gb);
|
||||
+
|
||||
+ h->sei_fpa.frame_packing_arrangement_id = get_ue_golomb(&h->gb);
|
||||
+ h->sei_fpa.frame_packing_arrangement_cancel_flag = get_bits(&h->gb, 1);
|
||||
+ if (!h->sei_fpa.frame_packing_arrangement_cancel_flag) {
|
||||
+ h->sei_fpa.frame_packing_arrangement_type = get_bits(&h->gb, 7);
|
||||
+ h->sei_fpa.quincunx_sampling_flag = get_bits(&h->gb, 1);
|
||||
+ h->sei_fpa.content_interpretation_type = get_bits(&h->gb, 6);
|
||||
+ skip_bits(&h->gb, 1); /* spatial_flipping_flag */
|
||||
+ skip_bits(&h->gb, 1); /* frame0_flipped_flag */
|
||||
+ skip_bits(&h->gb, 1); /* field_views_flag */
|
||||
+ skip_bits(&h->gb, 1); /* current_frame_is_frame0_flag */
|
||||
+ skip_bits(&h->gb, 1); /* frame0_self_contained_flag */
|
||||
+ skip_bits(&h->gb, 1); /* frame1_self_contained_flag */
|
||||
+ if (!h->sei_fpa.quincunx_sampling_flag && h->sei_fpa.frame_packing_arrangement_type != 5) {
|
||||
+ skip_bits(&h->gb, 4); /* frame0_grid_position_x */
|
||||
+ skip_bits(&h->gb, 4); /* frame0_grid_position_y */
|
||||
+ skip_bits(&h->gb, 4); /* frame1_grid_position_x */
|
||||
+ skip_bits(&h->gb, 4); /* frame1_grid_position_y */
|
||||
+ }
|
||||
+ skip_bits(&h->gb, 8); /* frame_packing_arrangement_reserved_byte */
|
||||
+ get_ue_golomb(&h->gb) /* frame_packing_arrangement_repetition_period */;
|
||||
+ }
|
||||
+ skip_bits(&h->gb, 1); /* frame_packing_arrangement_extension_flag */
|
||||
+
|
||||
+ if (h->avctx->debug & FF_DEBUG_PICT_INFO)
|
||||
+ av_log(h->avctx, AV_LOG_DEBUG, "SEI FPA %d %d %d %d %d\n",
|
||||
+ h->sei_fpa.frame_packing_arrangement_id,
|
||||
+ h->sei_fpa.frame_packing_arrangement_cancel_flag,
|
||||
+ h->sei_fpa.frame_packing_arrangement_type,
|
||||
+ h->sei_fpa.quincunx_sampling_flag,
|
||||
+ h->sei_fpa.content_interpretation_type);
|
||||
+ skip_bits(&h->gb, 8*size - (bits - get_bits_left(&h->gb)));
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int ff_h264_decode_sei(H264Context *h){
|
||||
while (get_bits_left(&h->gb) > 16) {
|
||||
int size, type;
|
||||
@@ -236,6 +273,9 @@ int ff_h264_decode_sei(H264Context *h){
|
||||
if(decode_buffering_period(h) < 0)
|
||||
return -1;
|
||||
break;
|
||||
+ case SEI_TYPE_FRAME_PACKING:
|
||||
+ if(decode_frame_packing(h, size) < 0)
|
||||
+ return -1;
|
||||
default:
|
||||
skip_bits(&h->gb, 8*size);
|
||||
}
|
||||
@@ -246,3 +286,48 @@ int ff_h264_decode_sei(H264Context *h){
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+const char* ff_h264_sei_stereo_mode(H264Context *h)
|
||||
+{
|
||||
+ if (h->sei_fpa.frame_packing_arrangement_cancel_flag == 0) {
|
||||
+ switch (h->sei_fpa.frame_packing_arrangement_type) {
|
||||
+ case SEI_FPA_TYPE_CHECKERBOARD:
|
||||
+ if (h->sei_fpa.content_interpretation_type == 2)
|
||||
+ return "checkerboard_rl";
|
||||
+ else
|
||||
+ return "checkerboard_lr";
|
||||
+ case SEI_FPA_TYPE_INTERLEAVE_COLUMN:
|
||||
+ if (h->sei_fpa.content_interpretation_type == 2)
|
||||
+ return "col_interleaved_rl";
|
||||
+ else
|
||||
+ return "col_interleaved_lr";
|
||||
+ case SEI_FPA_TYPE_INTERLEAVE_ROW:
|
||||
+ if (h->sei_fpa.content_interpretation_type == 2)
|
||||
+ return "row_interleaved_rl";
|
||||
+ else
|
||||
+ return "row_interleaved_lr";
|
||||
+ case SEI_FPA_TYPE_SIDE_BY_SIDE:
|
||||
+ if (h->sei_fpa.content_interpretation_type == 2)
|
||||
+ return "right_left";
|
||||
+ else
|
||||
+ return "left_right";
|
||||
+ case SEI_FPA_TYPE_TOP_BOTTOM:
|
||||
+ if (h->sei_fpa.content_interpretation_type == 2)
|
||||
+ return "bottom_top";
|
||||
+ else
|
||||
+ return "top_bottom";
|
||||
+ case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL:
|
||||
+ if (h->sei_fpa.content_interpretation_type == 2)
|
||||
+ return "block_rl";
|
||||
+ else
|
||||
+ return "block_lr";
|
||||
+ case SEI_FPA_TYPE_2D:
|
||||
+ default:
|
||||
+ return "mono";
|
||||
+ }
|
||||
+ } else if (h->sei_fpa.frame_packing_arrangement_cancel_flag == 1) {
|
||||
+ return "mono";
|
||||
+ } else {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
1.8.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user