ac3parse: add support for "audio/x-private1-ac3"
This commit is contained in:
		
							parent
							
								
									53da901cc9
								
							
						
					
					
						commit
						4531381541
					
				| @ -35,7 +35,7 @@ | ||||
|  */ | ||||
| 
 | ||||
| /* TODO:
 | ||||
|  *  - add support for audio/x-private1-ac3 as well | ||||
|  *  - audio/ac3 to audio/x-private1-ac3 is not implemented (done in the muxer) | ||||
|  *  - should accept framed and unframed input (needs decodebin fixes first) | ||||
|  */ | ||||
| 
 | ||||
| @ -153,7 +153,8 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", | ||||
| static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", | ||||
|     GST_PAD_SINK, | ||||
|     GST_PAD_ALWAYS, | ||||
|     GST_STATIC_CAPS ("audio/x-ac3; " "audio/x-eac3; " "audio/ac3")); | ||||
|     GST_STATIC_CAPS ("audio/x-ac3; " "audio/x-eac3; " "audio/ac3; " | ||||
|         "audio/x-private1-ac3")); | ||||
| 
 | ||||
| static void gst_ac3_parse_finalize (GObject * object); | ||||
| 
 | ||||
| @ -165,6 +166,8 @@ static gboolean gst_ac3_parse_src_event (GstBaseParse * parse, | ||||
|     GstEvent * event); | ||||
| static GstCaps *gst_ac3_parse_get_sink_caps (GstBaseParse * parse, | ||||
|     GstCaps * filter); | ||||
| static gboolean gst_ac3_parse_set_sink_caps (GstBaseParse * parse, | ||||
|     GstCaps * caps); | ||||
| 
 | ||||
| #define gst_ac3_parse_parent_class parent_class | ||||
| G_DEFINE_TYPE (GstAc3Parse, gst_ac3_parse, GST_TYPE_BASE_PARSE); | ||||
| @ -195,6 +198,7 @@ gst_ac3_parse_class_init (GstAc3ParseClass * klass) | ||||
|   parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_ac3_parse_handle_frame); | ||||
|   parse_class->src_event = GST_DEBUG_FUNCPTR (gst_ac3_parse_src_event); | ||||
|   parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_ac3_parse_get_sink_caps); | ||||
|   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_ac3_parse_set_sink_caps); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -212,6 +216,8 @@ gst_ac3_parse_init (GstAc3Parse * ac3parse) | ||||
| { | ||||
|   gst_base_parse_set_min_frame_size (GST_BASE_PARSE (ac3parse), 6); | ||||
|   gst_ac3_parse_reset (ac3parse); | ||||
|   ac3parse->baseparse_chainfunc = | ||||
|       GST_BASE_PARSE_SINK_PAD (GST_BASE_PARSE (ac3parse))->chainfunc; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -660,6 +666,43 @@ cleanup: | ||||
|   return res; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * MPEG-PS private1 streams add a 2 bytes "Audio Substream Headers" for each | ||||
|  * buffer (not each frame) with the offset of the next frame's start. | ||||
|  * | ||||
|  * Buffer 1: | ||||
|  * ------------------------------------------- | ||||
|  * |firstAccUnit|AC3SyncWord|xxxxxxxxxxxxxxxxx | ||||
|  * ------------------------------------------- | ||||
|  * Buffer 2: | ||||
|  * ------------------------------------------- | ||||
|  * |firstAccUnit|xxxxxx|AC3SyncWord|xxxxxxxxxx | ||||
|  * ------------------------------------------- | ||||
|  * | ||||
|  * These 2 bytes can be dropped safely as they do not include any timing | ||||
|  * information, only the offset to the start of the next frame. | ||||
|  * | ||||
|  * From http://stnsoft.com/DVD/ass-hdr.html:
 | ||||
|  * "FirstAccUnit offset to frame which corresponds to PTS value offset 0 is the | ||||
|  * last byte of FirstAccUnit, ie add the offset of byte 2 to get the AU's offset | ||||
|  * The value 0000 indicates there is no first access unit" | ||||
|  * */ | ||||
| 
 | ||||
| static GstFlowReturn | ||||
| gst_ac3_parse_chain_priv (GstPad * pad, GstObject * parent, GstBuffer * buffer) | ||||
| { | ||||
|   GstBuffer *newbuf; | ||||
|   GstFlowReturn ret; | ||||
|   GstAc3Parse *ac3parse = GST_AC3_PARSE (parent); | ||||
| 
 | ||||
|   newbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, | ||||
|       2, gst_buffer_get_size (buffer) - 2); | ||||
|   ret = ac3parse->baseparse_chainfunc (pad, parent, newbuf); | ||||
|   gst_buffer_unref (buffer); | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| static gboolean | ||||
| gst_ac3_parse_src_event (GstBaseParse * parse, GstEvent * event) | ||||
| { | ||||
| @ -737,3 +780,18 @@ gst_ac3_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter) | ||||
| 
 | ||||
|   return res; | ||||
| } | ||||
| 
 | ||||
| static gboolean | ||||
| gst_ac3_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps) | ||||
| { | ||||
|   GstStructure *s; | ||||
|   GstAc3Parse *ac3parse = GST_AC3_PARSE (parse); | ||||
| 
 | ||||
|   s = gst_caps_get_structure (caps, 0); | ||||
|   if (gst_structure_has_name (s, "audio/x-private1-ac3")) { | ||||
|     gst_pad_set_chain_function (parse->sinkpad, gst_ac3_parse_chain_priv); | ||||
|   } else { | ||||
|     gst_pad_set_chain_function (parse->sinkpad, ac3parse->baseparse_chainfunc); | ||||
|   } | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| @ -57,11 +57,12 @@ struct _GstAc3Parse { | ||||
|   GstBaseParse baseparse; | ||||
| 
 | ||||
|   /*< private >*/ | ||||
|   gint          sample_rate; | ||||
|   gint          channels; | ||||
|   gint          blocks; | ||||
|   gboolean      eac; | ||||
|   volatile gint align; | ||||
|   gint                  sample_rate; | ||||
|   gint                  channels; | ||||
|   gint                  blocks; | ||||
|   gboolean              eac; | ||||
|   volatile gint         align; | ||||
|   GstPadChainFunction   baseparse_chainfunc; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user