mpegvideoparse: Store information in GstMpegVideo12Meta

FIXME : Only do so if we know downstream will need it
This commit is contained in:
Edward Hervey 2012-09-20 18:27:11 +02:00 committed by Edward Hervey
parent 67ac84c7b5
commit 14e7e78b7a
2 changed files with 84 additions and 14 deletions

View file

@ -28,6 +28,7 @@
#include <string.h>
#include <gst/base/gstbytereader.h>
#include <gst/codecparsers/gstmpegvideometa.h>
#include "gstmpegvideoparse.h"
@ -185,6 +186,8 @@ gst_mpegv_parse_reset_frame (GstMpegvParse * mpvparse)
mpvparse->frame_repeat_count = 0;
memset (mpvparse->ext_offsets, 0, sizeof (mpvparse->ext_offsets));
mpvparse->ext_count = 0;
mpvparse->slice_count = 0;
mpvparse->slice_offset = 0;
}
static void
@ -200,6 +203,13 @@ gst_mpegv_parse_reset (GstMpegvParse * mpvparse)
memset (&mpvparse->sequenceext, 0, sizeof (mpvparse->sequenceext));
memset (&mpvparse->sequencedispext, 0, sizeof (mpvparse->sequencedispext));
memset (&mpvparse->pichdr, 0, sizeof (mpvparse->pichdr));
memset (&mpvparse->picext, 0, sizeof (mpvparse->picext));
mpvparse->seqhdr_updated = FALSE;
mpvparse->seqext_updated = FALSE;
mpvparse->seqdispext_updated = FALSE;
mpvparse->picext_updated = FALSE;
mpvparse->quantmatrext_updated = FALSE;
}
static gboolean
@ -269,6 +279,8 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
return FALSE;
}
mpvparse->seqhdr_updated = TRUE;
GST_LOG_OBJECT (mpvparse, "accepting parsed config size %d", size);
/* Set mpeg version, and parse sequence extension */
@ -281,11 +293,16 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
map.data, size, offset)) {
GST_LOG_OBJECT (mpvparse, "Read Sequence Extension");
mpvparse->config_flags |= FLAG_SEQUENCE_EXT;
} else
if (gst_mpeg_video_parse_sequence_display_extension
mpvparse->seqext_updated = TRUE;
} else if (gst_mpeg_video_parse_sequence_display_extension
(&mpvparse->sequencedispext, map.data, size, offset)) {
GST_LOG_OBJECT (mpvparse, "Read Sequence Display Extension");
mpvparse->config_flags |= FLAG_SEQUENCE_DISPLAY_EXT;
mpvparse->seqdispext_updated = TRUE;
} else if (gst_mpeg_video_parse_quant_matrix_extension
(&mpvparse->quantmatrext, map.data, size, offset)) {
GST_LOG_OBJECT (mpvparse, "Read Quantization Matrix Extension");
mpvparse->quantmatrext_updated = TRUE;
}
}
}
@ -382,26 +399,27 @@ picture_type_name (guint8 pct)
#endif /* GST_DISABLE_GST_DEBUG */
static void
parse_picture_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off)
parse_packet_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off)
{
GstMpegVideoPictureExt ext;
GstMapInfo map;
gst_buffer_map (buf, &map, GST_MAP_READ);
if (gst_mpeg_video_parse_picture_extension (&ext, map.data, map.size, off)) {
if (gst_mpeg_video_parse_picture_extension (&mpvparse->picext, map.data,
map.size, off)) {
mpvparse->frame_repeat_count = 1;
if (ext.repeat_first_field) {
if (mpvparse->picext.repeat_first_field) {
if (mpvparse->sequenceext.progressive) {
if (ext.top_field_first)
if (mpvparse->picext.top_field_first)
mpvparse->frame_repeat_count = 5;
else
mpvparse->frame_repeat_count = 3;
} else if (ext.progressive_frame) {
} else if (mpvparse->picext.progressive_frame) {
mpvparse->frame_repeat_count = 2;
}
}
mpvparse->picext_updated = TRUE;
}
gst_buffer_unmap (buf, &map);
@ -418,8 +436,8 @@ gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse,
g_return_val_if_fail (buf && gst_buffer_get_size (buf) >= 4, FALSE);
GST_LOG_OBJECT (mpvparse, "process startcode %x (%s)", code,
picture_start_code_name (code));
GST_LOG_OBJECT (mpvparse, "process startcode %x (%s) offset:%d", code,
picture_start_code_name (code), off);
switch (code) {
case GST_MPEG_VIDEO_PACKET_PICTURE:
@ -449,11 +467,17 @@ gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse,
break;
case GST_MPEG_VIDEO_PACKET_EXTENSION:
GST_LOG_OBJECT (mpvparse, "startcode is VIDEO PACKET EXTENSION");
parse_picture_extension (mpvparse, buf, off);
parse_packet_extension (mpvparse, buf, off);
if (mpvparse->ext_count < G_N_ELEMENTS (mpvparse->ext_offsets))
mpvparse->ext_offsets[mpvparse->ext_count++] = off;
/* fall-through */
packet = FALSE;
break;
default:
if (GST_MPEG_VIDEO_PACKET_IS_SLICE (code)) {
mpvparse->slice_count++;
if (mpvparse->slice_offset == 0)
mpvparse->slice_offset = off - 4;
}
packet = FALSE;
break;
}
@ -508,6 +532,7 @@ static GstFlowReturn
gst_mpegv_parse_handle_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, gint * skipsize)
{
GstFlowReturn flowret = GST_FLOW_OK;
GstMpegvParse *mpvparse = GST_MPEGVIDEO_PARSE (parse);
GstBuffer *buf = frame->buffer;
gboolean ret = FALSE;
@ -616,10 +641,16 @@ exit:
res = gst_mpegv_parse_parse_frame (parse, frame);
if (res == GST_BASE_PARSE_FLOW_DROPPED)
frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
return gst_base_parse_finish_frame (parse, frame, off);
flowret = gst_base_parse_finish_frame (parse, frame, off);
/* Reset local information */
mpvparse->seqhdr_updated = FALSE;
mpvparse->seqext_updated = FALSE;
mpvparse->seqdispext_updated = FALSE;
mpvparse->picext_updated = FALSE;
mpvparse->quantmatrext_updated = FALSE;
}
return GST_FLOW_OK;
return flowret;
}
static void
@ -805,6 +836,13 @@ gst_mpegv_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
GstMpegvParse *mpvparse = GST_MPEGVIDEO_PARSE (parse);
GstTagList *taglist;
GstMpegVideoMeta *meta;
GstMpegVideoSequenceHdr *seq_hdr = NULL;
GstMpegVideoSequenceExt *seq_ext = NULL;
GstMpegVideoSequenceDisplayExt *disp_ext = NULL;
GstMpegVideoPictureHdr *pic_hdr = NULL;
GstMpegVideoPictureExt *pic_ext = NULL;
GstMpegVideoQuantMatrixExt *quant_ext = NULL;
/* tag sending done late enough in hook to ensure pending events
* have already been sent */
@ -828,6 +866,28 @@ gst_mpegv_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
/* usual clipping applies */
frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;
if (mpvparse->seqhdr_updated)
seq_hdr = &mpvparse->sequencehdr;
if (mpvparse->seqext_updated)
seq_ext = &mpvparse->sequenceext;
if (mpvparse->seqdispext_updated)
disp_ext = &mpvparse->sequencedispext;
if (mpvparse->picext_updated)
pic_ext = &mpvparse->picext;
if (mpvparse->quantmatrext_updated)
quant_ext = &mpvparse->quantmatrext;
pic_hdr = &mpvparse->pichdr;
GST_DEBUG_OBJECT (mpvparse,
"Adding GstMpegVideoMeta (slice_count:%d, slice_offset:%d)",
mpvparse->slice_count, mpvparse->slice_offset);
meta =
gst_buffer_add_mpeg_video_meta (frame->
out_buffer ? frame->out_buffer : frame->buffer, seq_hdr, seq_ext,
disp_ext, pic_hdr, pic_ext, quant_ext);
meta->num_slices = mpvparse->slice_count;
meta->slice_offset = mpvparse->slice_offset;
return GST_FLOW_OK;
}

View file

@ -65,6 +65,8 @@ struct _GstMpegvParse {
gint seq_offset;
gint seq_size;
gint pic_offset;
guint slice_count;
guint slice_offset;
gboolean update_caps;
gboolean send_codec_tag;
@ -75,6 +77,14 @@ struct _GstMpegvParse {
GstMpegVideoSequenceExt sequenceext;
GstMpegVideoSequenceDisplayExt sequencedispext;
GstMpegVideoPictureHdr pichdr;
GstMpegVideoPictureExt picext;
GstMpegVideoQuantMatrixExt quantmatrext;
gboolean seqhdr_updated;
gboolean seqext_updated;
gboolean seqdispext_updated;
gboolean picext_updated;
gboolean quantmatrext_updated;
/* properties */
gboolean drop;