On Tue, Jul 30, 2013 at 4:26 PM, Vittorio Giovara
<[email protected]> wrote:
> ---
> libavcodec/h264.c | 31 +++++++++++++++++++++++++++++++
> libavcodec/h264.h | 22 +++++++++++++++++++++-
> libavcodec/h264_sei.c | 36 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 88 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/h264.c b/libavcodec/h264.c
> index d53907e..725831a 100644
> --- a/libavcodec/h264.c
> +++ b/libavcodec/h264.c
> @@ -27,6 +27,7 @@
>
> #include "libavutil/avassert.h"
> #include "libavutil/imgutils.h"
> +#include "libavutil/stereoscopy.h"
> #include "internal.h"
> #include "cabac.h"
> #include "cabac_functions.h"
> @@ -1924,6 +1925,36 @@ static void decode_postinit(H264Context *h, int
> setup_finished)
> }
> }
>
> + if (h->sei_frame_packing_present) {
> + AVFrameSideData *side_data =
> + av_frame_new_side_data(&cur->f,
> + AV_FRAME_DATA_STEREO3D,
> + sizeof(uint32_t));
Unchecked allocation
> +
> + switch (h->frame_packing_arrangement_type) {
> + case SEI_FPA_CHECKERBOARD:
> + *side_data->data = AV_STEREO3D_CHECKERS; break;
> + case SEI_FPA_LINE_INTERLEAVED:
> + *side_data->data = AV_STEREO3D_LINES; break;
> + case SEI_FPA_COLUMN_INTERLEAVED:
> + *side_data->data = AV_STEREO3D_COLUMNS; break;
> + case SEI_FPA_SIDE_BY_SIDE:
> + *side_data->data = AV_STEREO3D_SIDEBYSIDE; break;
> + case SEI_FPA_TOP_AND_BOTTOM:
> + *side_data->data = AV_STEREO3D_TOPBOTTOM; break;
> + case SEI_FPA_FRAME_ALTERNATE:
> + *side_data->data = AV_STEREO3D_FRAMESEQUENCE; break;
> + }
> +
> + if (h->content_interpretation_type == 2)
> + *side_data->data |= AV_STEREO3D_ORDER_RL;
> + else
> + *side_data->data |= AV_STEREO3D_ORDER_LR;
> +
> + if (*side_data->data != AV_STEREO3D_FRAMESEQUENCE)
> + *side_data->data |= AV_STEREO3D_SIZE_HALF;
> + }
> +
> // FIXME do something with unavailable reference frames
>
> /* Sort B-frames into display order */
> diff --git a/libavcodec/h264.h b/libavcodec/h264.h
> index 3ef8420..09e230a 100644
> --- a/libavcodec/h264.h
> +++ b/libavcodec/h264.h
> @@ -123,7 +123,8 @@ typedef enum {
> SEI_BUFFERING_PERIOD = 0, ///< buffering period (H.264,
> D.1.1)
> SEI_TYPE_PIC_TIMING = 1, ///< picture timing
> 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;
>
> /**
> @@ -142,6 +143,18 @@ typedef enum {
> } SEI_PicStructType;
>
> /**
> + * type in frame packing arrangement SEI message
> + */
> +typedef enum {
> + SEI_FPA_CHECKERBOARD = 0, ///< 0: quincux
> + SEI_FPA_LINE_INTERLEAVED = 1, ///< 1: line interleaving
> + SEI_FPA_COLUMN_INTERLEAVED = 2, ///< 2: column interleaving
> + SEI_FPA_SIDE_BY_SIDE = 3, ///< 3: side by side
> + SEI_FPA_TOP_AND_BOTTOM = 4, ///< 4: top and bottom
> + SEI_FPA_FRAME_ALTERNATE = 5, ///< 5: frame alternate
> +} SEI_FramePackingType;
> +
> +/**
> * Sequence parameter set
> */
> typedef struct SPS {
> @@ -586,6 +599,13 @@ typedef struct H264Context {
> int prev_interlaced_frame;
>
> /**
> + * frame_packing_arrangment SEI message
> + */
> + int sei_frame_packing_present;
> + SEI_FramePackingType frame_packing_arrangement_type;
> + int content_interpretation_type;
> +
> + /**
> * Bit set of clock types for fields/frames in picture timing SEI
> message.
> * For each found ct_type, appropriate bit is set (e.g., bit 1 for
> * interlaced).
> diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
> index df4c49f..8fd4874 100644
> --- a/libavcodec/h264_sei.c
> +++ b/libavcodec/h264_sei.c
> @@ -42,6 +42,7 @@ void ff_h264_reset_sei(H264Context *h) {
> h->sei_dpb_output_delay = 0;
> h->sei_cpb_removal_delay = -1;
> h->sei_buffering_period_present = 0;
> + h->sei_frame_packing_present = 0;
> }
>
> static int decode_picture_timing(H264Context *h){
> @@ -156,6 +157,37 @@ static int decode_buffering_period(H264Context *h){
> return 0;
> }
>
> +static int decode_frame_packing_arrangement(H264Context *h){
> + int cancel, quincunx;
> + int content = -1;
> + int type = -1;
> +
> + get_ue_golomb(&h->gb); // frame_packing_arrangement_id
> + cancel = get_bits1(&h->gb); //
> frame_packing_arrangement_cancel_flag
> + if (cancel == 0) {
> + type = get_bits(&h->gb, 7); // frame_packing_arrangement_type
> + quincunx = get_bits1(&h->gb); // quincunx_sampling_flag
> + content = get_bits(&h->gb, 6); // content_interpretation_type
> +
> + // the following skips spatial_flipping_flag frame0_flipped_flag
> + // field_views_flag current_frame_is_frame0_flag
> + // frame0_self_contained_flag frame1_self_contained_flag
> + skip_bits(&h->gb, 6);
> +
> + if ( quincunx == 0 && type != 5 )
> + skip_bits(&h->gb, 16); // frame[01]_grid_position_[xy]
> + skip_bits(&h->gb, 8); //
> frame_packing_arrangement_reserved_byte
> + get_ue_golomb(&h->gb); //
> frame_packing_arrangement_repetition_period
> + }
> + skip_bits1(&h->gb); //
> frame_packing_arrangement_extension_flag
> +
> + h->sei_frame_packing_present = (cancel == 0);
> + h->frame_packing_arrangement_type = type;
> + h->content_interpretation_type = content;
> +
> + return 0;
> +}
> +
> int ff_h264_decode_sei(H264Context *h){
> while (get_bits_left(&h->gb) > 16) {
> int size, type;
> @@ -187,6 +219,10 @@ 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_arrangement(h) < 0)
> + return -1;
This should ideally preserve the return value of
decode_frame_packing_arrangement
> + break;
> default:
> skip_bits(&h->gb, 8*size);
> }
> --
> 1.7.9.5
>
> _______________________________________________
> libav-devel mailing list
> [email protected]
> https://lists.libav.org/mailman/listinfo/libav-devel
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel