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

View file

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