Merge branch 'master' into 0.11

Conflicts:
	gst/mpegtsdemux/tsdemux.c
	gst/videoparsers/gsth264parse.c
	tests/check/elements/camerabin2.c
This commit is contained in:
Sebastian Dröge 2012-01-10 15:50:37 +01:00
commit a01a4ea2d3
18 changed files with 329 additions and 73 deletions

View file

@ -345,6 +345,7 @@ gst_opus_enc_stop (GstAudioEncoder * benc)
gst_tag_list_free (enc->tags); gst_tag_list_free (enc->tags);
enc->tags = NULL; enc->tags = NULL;
g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL); g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL);
g_slist_free (enc->headers);
enc->headers = NULL; enc->headers = NULL;
gst_tag_setter_reset_tags (GST_TAG_SETTER (enc)); gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
@ -879,6 +880,7 @@ gst_opus_enc_handle_frame (GstAudioEncoder * benc, GstBuffer * buf)
GstCaps *caps; GstCaps *caps;
g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL); g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL);
g_slist_free (enc->headers);
enc->headers = NULL; enc->headers = NULL;
gst_opus_header_create_caps (&caps, &enc->headers, enc->n_channels, gst_opus_header_create_caps (&caps, &enc->headers, enc->n_channels,
@ -891,6 +893,7 @@ gst_opus_enc_handle_frame (GstAudioEncoder * benc, GstBuffer * buf)
GST_DEBUG_OBJECT (enc, "here are the caps: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (enc, "here are the caps: %" GST_PTR_FORMAT, caps);
gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc), caps); gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc), caps);
gst_caps_unref (caps);
enc->header_sent = TRUE; enc->header_sent = TRUE;
} }

7
ext/vp8/GstVP8Enc.prs Normal file
View file

@ -0,0 +1,7 @@
[_presets_]
version=0.10
element-name=GstVP8Enc
[Profile Realtime]
max-latency=1
speed=2

View file

@ -24,3 +24,8 @@ noinst_HEADERS = \
gstvp8dec.h \ gstvp8dec.h \
gstvp8enc.h \ gstvp8enc.h \
gstvp8utils.h gstvp8utils.h
presetdir = $(datadir)/gstreamer-$(GST_MAJORMINOR)/presets
preset_DATA = GstVP8Enc.prs
EXTRA_DIST = $(preset_DATA)

View file

@ -493,6 +493,7 @@ gst_vp8_dec_handle_frame (GstBaseVideoDecoder * decoder,
} }
} else { } else {
/* Invisible frame */ /* Invisible frame */
frame->decode_only = 1;
gst_base_video_decoder_finish_frame (decoder, frame); gst_base_video_decoder_finish_frame (decoder, frame);
} }

View file

@ -273,7 +273,7 @@ find_psc (GstByteReader * br)
/* Scan for the picture start code (22 bits - 0x0020) */ /* Scan for the picture start code (22 bits - 0x0020) */
while ((gst_byte_reader_get_remaining (br) >= 3)) { while ((gst_byte_reader_get_remaining (br) >= 3)) {
if (gst_byte_reader_peek_uint24_be (br, &psc) && if (gst_byte_reader_peek_uint24_be (br, &psc) &&
((psc & 0xffffc0) == 0x000080)) { ((psc & 0xfffffc) == 0x000080)) {
psc_pos = gst_byte_reader_get_pos (br); psc_pos = gst_byte_reader_get_pos (br);
break; break;
} else } else
@ -473,8 +473,7 @@ gst_mpeg4_parse (GstMpeg4Packet * packet, gboolean skip_user_data,
if (skip_user_data && data[off1 + 3] == GST_MPEG4_USER_DATA) if (skip_user_data && data[off1 + 3] == GST_MPEG4_USER_DATA)
/* If we are here, we know no resync code has been found the first time, so we /* If we are here, we know no resync code has been found the first time, so we
* don't look for it this time */ * don't look for it this time */
return gst_mpeg4_parse (packet, skip_user_data, NULL, data, off1 + 3, return gst_mpeg4_parse (packet, skip_user_data, NULL, data, off1 + 3, size);
size - off1 - 3);
packet->offset = off1 + 3; packet->offset = off1 + 3;
packet->data = data; packet->data = data;
@ -524,7 +523,7 @@ gst_h263_parse (GstMpeg4Packet * packet,
gint off1, off2; gint off1, off2;
GstByteReader br; GstByteReader br;
gst_byte_reader_init (&br, data, size); gst_byte_reader_init (&br, data + offset, size - offset);
g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR); g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
@ -541,9 +540,10 @@ gst_h263_parse (GstMpeg4Packet * packet,
return GST_MPEG4_PARSER_NO_PACKET; return GST_MPEG4_PARSER_NO_PACKET;
} }
packet->offset = off1; packet->offset = off1 + offset;
packet->data = data; packet->data = data;
gst_byte_reader_skip (&br, 3);
off2 = find_psc (&br); off2 = find_psc (&br);
if (off2 == -1) { if (off2 == -1) {
@ -1490,18 +1490,24 @@ gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr *
shorthdr, const guint8 * data, gsize size) shorthdr, const guint8 * data, gsize size)
{ {
guint8 zero_bits; guint8 zero_bits;
guint32 gob_resync;
GstBitReader br = GST_BIT_READER_INIT (data, size); GstBitReader br = GST_BIT_READER_INIT (data, size);
g_return_val_if_fail (shorthdr != NULL, GST_MPEG4_PARSER_ERROR); g_return_val_if_fail (shorthdr != NULL, GST_MPEG4_PARSER_ERROR);
if (gst_bit_reader_get_remaining (&br) < 26) if (gst_bit_reader_get_remaining (&br) < 48)
goto failed;
if (gst_bit_reader_get_bits_uint32_unchecked (&br, 22) != 0x20)
goto failed; goto failed;
shorthdr->temporal_reference = shorthdr->temporal_reference =
gst_bit_reader_get_bits_uint8_unchecked (&br, 8); gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
CHECK_MARKER (&br); CHECK_MARKER (&br);
zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
if (zero_bits != 0x00)
goto failed;
shorthdr->split_screen_indicator = shorthdr->split_screen_indicator =
gst_bit_reader_get_bits_uint8_unchecked (&br, 1); gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
shorthdr->document_camera_indicator = shorthdr->document_camera_indicator =
@ -1517,26 +1523,31 @@ gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr *
shorthdr->vop_height = 96; shorthdr->vop_height = 96;
shorthdr->num_macroblocks_in_gob = 8; shorthdr->num_macroblocks_in_gob = 8;
shorthdr->num_gobs_in_vop = 6; shorthdr->num_gobs_in_vop = 6;
break;
case 0x02: case 0x02:
shorthdr->vop_width = 176; shorthdr->vop_width = 176;
shorthdr->vop_height = 144; shorthdr->vop_height = 144;
shorthdr->num_macroblocks_in_gob = 11; shorthdr->num_macroblocks_in_gob = 11;
shorthdr->num_gobs_in_vop = 9; shorthdr->num_gobs_in_vop = 9;
break;
case 0x03: case 0x03:
shorthdr->vop_width = 352; shorthdr->vop_width = 352;
shorthdr->vop_height = 288; shorthdr->vop_height = 288;
shorthdr->num_macroblocks_in_gob = 22; shorthdr->num_macroblocks_in_gob = 22;
shorthdr->num_gobs_in_vop = 18; shorthdr->num_gobs_in_vop = 18;
break;
case 0x04: case 0x04:
shorthdr->vop_width = 704; shorthdr->vop_width = 704;
shorthdr->vop_height = 576; shorthdr->vop_height = 576;
shorthdr->num_macroblocks_in_gob = 88; shorthdr->num_macroblocks_in_gob = 88;
shorthdr->num_gobs_in_vop = 18; shorthdr->num_gobs_in_vop = 18;
break;
case 0x05: case 0x05:
shorthdr->vop_width = 1408; shorthdr->vop_width = 1408;
shorthdr->vop_height = 1152; shorthdr->vop_height = 1152;
shorthdr->num_macroblocks_in_gob = 352; shorthdr->num_macroblocks_in_gob = 352;
shorthdr->num_gobs_in_vop = 18; shorthdr->num_gobs_in_vop = 18;
break;
default: default:
shorthdr->vop_width = 0; shorthdr->vop_width = 0;
shorthdr->vop_height = 0; shorthdr->vop_height = 0;
@ -1565,26 +1576,6 @@ gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr *
} while (shorthdr->pei == 1); } while (shorthdr->pei == 1);
if (!gst_bit_reader_peek_bits_uint32 (&br, &gob_resync, 17))
goto failed;
/* gob_layer() */
/* Setting default values */
shorthdr->gob_header_empty = 1;
shorthdr->gob_number = 0;
shorthdr->gob_frame_id = 0;
shorthdr->quant_scale = 0;
if (gob_resync == 0x01) {
shorthdr->gob_header_empty = 0;
gst_bit_reader_skip_unchecked (&br, 17);
READ_UINT8 (&br, shorthdr->gob_number, 5);
READ_UINT8 (&br, shorthdr->gob_frame_id, 2);
READ_UINT8 (&br, shorthdr->quant_scale, 5);
}
shorthdr->size = gst_bit_reader_get_pos (&br); shorthdr->size = gst_bit_reader_get_pos (&br);
return GST_MPEG4_PARSER_OK; return GST_MPEG4_PARSER_OK;

View file

@ -126,6 +126,10 @@ struct _GstVideoFrameState
gboolean is_sync_point; gboolean is_sync_point;
gboolean is_eos; gboolean is_eos;
/* Frames that should not be pushed downstream and are
* not meant for display */
gboolean decode_only;
GstBuffer *sink_buffer; GstBuffer *sink_buffer;
GstBuffer *src_buffer; GstBuffer *src_buffer;

View file

@ -1397,6 +1397,11 @@ gst_base_video_decoder_prepare_finish_frame (GstBaseVideoDecoder *
} }
g_list_free (events); g_list_free (events);
/* Check if the data should not be displayed. For example altref/invisible
* frame in vp8. In this case we should not update the timestamps. */
if (frame->decode_only)
return;
if (GST_CLOCK_TIME_IS_VALID (frame->presentation_timestamp)) { if (GST_CLOCK_TIME_IS_VALID (frame->presentation_timestamp)) {
if (frame->presentation_timestamp != base_video_decoder->timestamp_offset) { if (frame->presentation_timestamp != base_video_decoder->timestamp_offset) {
GST_DEBUG_OBJECT (base_video_decoder, GST_DEBUG_OBJECT (base_video_decoder,
@ -1552,7 +1557,7 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
base_video_decoder->processed++; base_video_decoder->processed++;
/* no buffer data means this frame is skipped */ /* no buffer data means this frame is skipped */
if (!frame->src_buffer) { if (!frame->src_buffer || frame->decode_only) {
GST_DEBUG_OBJECT (base_video_decoder, "skipping frame %" GST_TIME_FORMAT, GST_DEBUG_OBJECT (base_video_decoder, "skipping frame %" GST_TIME_FORMAT,
GST_TIME_ARGS (frame->presentation_timestamp)); GST_TIME_ARGS (frame->presentation_timestamp));
goto done; goto done;

View file

@ -86,6 +86,8 @@ gst_color_effects_preset_get_type (void)
{GST_COLOR_EFFECTS_PRESET_XRAY, "Invert and slightly shade to blue", {GST_COLOR_EFFECTS_PRESET_XRAY, "Invert and slightly shade to blue",
"xray"}, "xray"},
{GST_COLOR_EFFECTS_PRESET_XPRO, "Cross processing toning", "xpro"}, {GST_COLOR_EFFECTS_PRESET_XPRO, "Cross processing toning", "xpro"},
{GST_COLOR_EFFECTS_PRESET_YELLOWBLUE,
"Yellow foreground Blue background color filter", "yellowblue"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };
@ -253,6 +255,38 @@ static const guint8 xpro_table[768] =
"\376\365\377\377\365\377\377\366\377\377\366\377\377\366\377\377\367\377" "\376\365\377\377\365\377\377\366\377\377\366\377\377\366\377\377\367\377"
"\377\367\377\377\367\377\377\370"; "\377\367\377\377\367\377\377\370";
/*Used for a video magnifer emulator in gnome-video-effects*/
static const guint8 yellowblue_table[768] =
"\0\0\377\1\1\376\2\2\375\3\3\374\4\4\373\5\5\372\6\6\371\7\7\370\10\10\367"
"\11\11\367\12\12\365\13\13\364\14\14\363\15\14\362\16\16\361\17\17\360\20"
"\20\357\20\21\356\22\22\355\23\23\354\24\24\354\24\25\352\26\26\351\27\27"
"\350\27\30\347\31\31\346\32\32\345\33\32\344\34\34\343\34\34\342\36\36\341"
"\37\36\340\40\40\337!!\336!!\335##\334$#\334%%\332&%\331'&\330((\327()\326"
"*)\325++\324,,\323--\322..\321//\320/0\31711\31722\31522\31444\31445\313"
"55\31276\31188\30799\3069:\305;;\305<<\304==\302>>\301>>\300@@\300@A\276"
"AB\275BC\274CD\273DE\272EE\272FF\270HH\270HI\266IJ\265KK\264KL\263MM\262"
"NN\262NN\261OO\257QP\256RQ\256RR\254TT\253UU\253VU\251VW\250XX\247XY\246"
"YZ\245[[\245[[\243]]\243^^\242^_\240_`\237`a\236aa\235bb\235dc\233de\233"
"ff\232gf\231hg\230hi\227ji\226kj\225lk\223lm\223nm\222nn\221op\217qq\216"
"rr\215ss\214st\213uu\213uu\211wv\210ww\207xx\207yz\205z{\205{{\204||\203"
"}}\202\177~\201\177\200\177\200\201\177\202\202~\203\202|\204\203|\204\204"
"{\205\206z\207\206x\207\207w\211\210w\211\211v\212\212u\213\214s\214\214"
"r\215\215r\216\217q\217\217p\221\220o\221\222n\223\222l\224\223k\224\224"
"k\225\225j\226\226i\227\227h\230\231f\231\231f\233\232e\233\233c\234\234"
"c\235\235b\236\236a\237\237`\241\240_\242\241^\242\242]\243\244\\\244\244"
"[\245\245Y\246\246Y\250\247X\250\250W\251\251V\252\252T\253\253T\254\255"
"S\256\255R\257\256Q\257\260P\260\261O\261\261N\262\262M\263\263L\264\265"
"K\265\265J\266\266I\267\270H\270\270G\271\271F\272\272E\273\273C\274\274"
"B\275\275B\276\276A\277\277@\300\300?\301\301>\302\302=\303\303<\304\304"
";\305\305:\306\3069\307\3078\310\3107\311\3116\312\3125\313\3134\314\314"
"3\315\3152\316\3161\317\3170\320\320/\321\321.\322\322-\323\323,\323\324"
"+\325\325*\326\326)\327\327(\330\330'\331\331&\332\331%\333\332$\334\334"
"#\334\335\"\336\336!\337\337\40\340\340\37\341\341\36\342\342\35\343\343"
"\34\344\344\33\345\345\32\345\346\31\347\347\30\350\350\27\351\351\26\352"
"\352\25\353\353\24\354\354\23\354\355\22\356\356\21\357\357\20\360\360\17"
"\361\361\16\362\362\15\363\362\14\364\364\13\365\365\12\365\366\11\367\367"
"\11\370\370\7\371\371\6\372\371\5\373\373\4\374\374\4\375\375\3\375\376\1";
static const int cog_ycbcr_to_rgb_matrix_8bit_sdtv[] = { static const int cog_ycbcr_to_rgb_matrix_8bit_sdtv[] = {
298, 0, 409, -57068, 298, 0, 409, -57068,
298, -100, -208, 34707, 298, -100, -208, 34707,
@ -543,6 +577,10 @@ gst_color_effects_set_property (GObject * object, guint prop_id,
filter->table = xpro_table; filter->table = xpro_table;
filter->map_luma = FALSE; filter->map_luma = FALSE;
break; break;
case GST_COLOR_EFFECTS_PRESET_YELLOWBLUE:
filter->table = yellowblue_table;
filter->map_luma = FALSE;
break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();

View file

@ -45,6 +45,7 @@ typedef struct _GstColorEffectsClass GstColorEffectsClass;
* @GST_CLUT_PRESET_SEPIA: Sepia toning filter * @GST_CLUT_PRESET_SEPIA: Sepia toning filter
* @GST_CLUT_PRESET_XRAY: Invert colors and slightly shade to cyan * @GST_CLUT_PRESET_XRAY: Invert colors and slightly shade to cyan
* @GST_CLUT_PRESET_XPRO: Cross Processing filter * @GST_CLUT_PRESET_XPRO: Cross Processing filter
* @GST_CLUT_PRESET_YELLOWBLUE: Visual magnifier high-contrast color filter. Since: 0.10.24
* *
* The lookup table to use to convert input colors * The lookup table to use to convert input colors
*/ */
@ -54,7 +55,8 @@ typedef enum
GST_COLOR_EFFECTS_PRESET_HEAT, GST_COLOR_EFFECTS_PRESET_HEAT,
GST_COLOR_EFFECTS_PRESET_SEPIA, GST_COLOR_EFFECTS_PRESET_SEPIA,
GST_COLOR_EFFECTS_PRESET_XRAY, GST_COLOR_EFFECTS_PRESET_XRAY,
GST_COLOR_EFFECTS_PRESET_XPRO GST_COLOR_EFFECTS_PRESET_XPRO,
GST_COLOR_EFFECTS_PRESET_YELLOWBLUE,
} GstColorEffectsPreset; } GstColorEffectsPreset;
/** /**

View file

@ -187,6 +187,7 @@ static gboolean gst_interlace_setcaps (GstPad * pad, GstCaps * caps);
static GstCaps *gst_interlace_getcaps (GstPad * pad); static GstCaps *gst_interlace_getcaps (GstPad * pad);
static GstStateChangeReturn gst_interlace_change_state (GstElement * element, static GstStateChangeReturn gst_interlace_change_state (GstElement * element,
GstStateChange transition); GstStateChange transition);
static void gst_interlace_finalize (GObject * obj);
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
@ -242,6 +243,7 @@ gst_interlace_class_init (GstInterlaceClass * klass)
object_class->set_property = gst_interlace_set_property; object_class->set_property = gst_interlace_set_property;
object_class->get_property = gst_interlace_get_property; object_class->get_property = gst_interlace_get_property;
object_class->finalize = gst_interlace_finalize;
element_class->change_state = gst_interlace_change_state; element_class->change_state = gst_interlace_change_state;
@ -268,6 +270,16 @@ gst_interlace_class_init (GstInterlaceClass * klass)
} }
static void
gst_interlace_finalize (GObject * obj)
{
GstInterlace *interlace = GST_INTERLACE (obj);
gst_caps_replace (&interlace->srccaps, NULL);
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
static void static void
gst_interlace_reset (GstInterlace * interlace) gst_interlace_reset (GstInterlace * interlace)
{ {
@ -328,6 +340,11 @@ gst_interlace_decorate_buffer (GstInterlace * interlace, GstBuffer * buf,
int n_fields) int n_fields)
{ {
/* field duration = src_fps_d / (2 * src_fps_n) */ /* field duration = src_fps_d / (2 * src_fps_n) */
if (interlace->src_fps_n == 0) {
/* If we don't know the fps, we can't generate timestamps/durations */
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
} else {
GST_BUFFER_TIMESTAMP (buf) = interlace->timebase + GST_BUFFER_TIMESTAMP (buf) = interlace->timebase +
gst_util_uint64_scale (GST_SECOND, gst_util_uint64_scale (GST_SECOND,
interlace->src_fps_d * interlace->fields_since_timebase, interlace->src_fps_d * interlace->fields_since_timebase,
@ -335,6 +352,7 @@ gst_interlace_decorate_buffer (GstInterlace * interlace, GstBuffer * buf,
GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (buf) =
gst_util_uint64_scale (GST_SECOND, interlace->src_fps_d * n_fields, gst_util_uint64_scale (GST_SECOND, interlace->src_fps_d * n_fields,
interlace->src_fps_n * 2); interlace->src_fps_n * 2);
}
/* increment the buffer timestamp by duration for the next buffer */ /* increment the buffer timestamp by duration for the next buffer */
gst_buffer_set_caps (buf, interlace->srccaps); gst_buffer_set_caps (buf, interlace->srccaps);
@ -457,6 +475,8 @@ gst_interlace_getcaps (GstPad * pad)
gst_caps_set_simple (icaps, "interlaced", G_TYPE_BOOLEAN, gst_caps_set_simple (icaps, "interlaced", G_TYPE_BOOLEAN,
pad == interlace->srcpad ? TRUE : FALSE, NULL); pad == interlace->srcpad ? TRUE : FALSE, NULL);
gst_object_unref (interlace);
return icaps; return icaps;
} }
@ -470,7 +490,7 @@ gst_interlace_setcaps (GstPad * pad, GstCaps * caps)
gboolean interlaced = TRUE; gboolean interlaced = TRUE;
int fps_n, fps_d; int fps_n, fps_d;
GstPad *otherpad; GstPad *otherpad;
GstCaps *othercaps; GstCaps *othercaps = NULL;
const PulldownFormat *pdformat; const PulldownFormat *pdformat;
interlace = GST_INTERLACE (gst_pad_get_parent (pad)); interlace = GST_INTERLACE (gst_pad_get_parent (pad));
@ -519,6 +539,8 @@ gst_interlace_setcaps (GstPad * pad, GstCaps * caps)
} }
error: error:
if (othercaps)
gst_caps_unref (othercaps);
g_object_unref (interlace); g_object_unref (interlace);
return ret; return ret;

View file

@ -63,6 +63,7 @@
#define PCR_SMALL 17775000 #define PCR_SMALL 17775000
/* maximal PCR time */ /* maximal PCR time */
#define PCR_MAX_VALUE (((((guint64)1)<<33) * 300) + 298) #define PCR_MAX_VALUE (((((guint64)1)<<33) * 300) + 298)
#define PTS_DTS_MAX_VALUE (((guint64)1) << 33)
/* seek to SEEK_TIMESTAMP_OFFSET before the desired offset and search then /* seek to SEEK_TIMESTAMP_OFFSET before the desired offset and search then
* either accurately or for the next timestamp * either accurately or for the next timestamp
@ -72,6 +73,8 @@
GST_DEBUG_CATEGORY_STATIC (ts_demux_debug); GST_DEBUG_CATEGORY_STATIC (ts_demux_debug);
#define GST_CAT_DEFAULT ts_demux_debug #define GST_CAT_DEFAULT ts_demux_debug
#define ABSDIFF(a,b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
static GQuark QUARK_TSDEMUX; static GQuark QUARK_TSDEMUX;
static GQuark QUARK_PID; static GQuark QUARK_PID;
static GQuark QUARK_PCR; static GQuark QUARK_PCR;
@ -114,8 +117,15 @@ struct _TSDemuxStream
/* Current data to be pushed out */ /* Current data to be pushed out */
GList *currentlist; GList *currentlist;
/* Current PTS for this stream */ /* Current PTS/DTS for this stream */
GstClockTime pts; GstClockTime pts;
GstClockTime dts;
/* Raw value of current PTS/DTS */
guint64 raw_pts;
guint64 raw_dts;
/* Number of rollover seen for PTS/DTS (default:0) */
guint nb_pts_rollover;
guint nb_dts_rollover;
}; };
#define VIDEO_CAPS \ #define VIDEO_CAPS \
@ -1238,7 +1248,13 @@ gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * bstream,
/* Create the pad */ /* Create the pad */
if (bstream->stream_type != 0xff) if (bstream->stream_type != 0xff)
stream->pad = create_pad_for_stream (base, bstream, program); stream->pad = create_pad_for_stream (base, bstream, program);
stream->pts = GST_CLOCK_TIME_NONE; stream->pts = GST_CLOCK_TIME_NONE;
stream->dts = GST_CLOCK_TIME_NONE;
stream->raw_pts = 0;
stream->raw_dts = 0;
stream->nb_pts_rollover = 0;
stream->nb_dts_rollover = 0;
} }
stream->flow_return = GST_FLOW_OK; stream->flow_return = GST_FLOW_OK;
} }
@ -1877,9 +1893,33 @@ gst_ts_demux_record_pts (GstTSDemux * demux, TSDemuxStream * stream,
{ {
MpegTSBaseStream *bs = (MpegTSBaseStream *) stream; MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
GST_LOG ("pid 0x%04x pts:%" GST_TIME_FORMAT " at offset %" GST_LOG ("pid 0x%04x pts:%" G_GUINT64_FORMAT " at offset %"
G_GUINT64_FORMAT, bs->pid, G_GUINT64_FORMAT, bs->pid, pts, offset);
GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (pts)), offset);
if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (stream->pts) &&
ABSDIFF (stream->raw_pts, pts) > 900000)) {
/* Detect rollover if diff > 10s */
GST_LOG ("Detected rollover (previous:%" G_GUINT64_FORMAT " new:%"
G_GUINT64_FORMAT ")", stream->raw_pts, pts);
if (pts < stream->raw_pts) {
/* Forward rollover */
GST_LOG ("Forward rollover, incrementing nb_pts_rollover");
stream->nb_pts_rollover++;
} else {
/* Reverse rollover */
GST_LOG ("Reverse rollover, decrementing nb_pts_rollover");
stream->nb_pts_rollover--;
}
}
/* Compute PTS in GstClockTime */
stream->raw_pts = pts;
stream->pts =
MPEGTIME_TO_GSTTIME (pts + stream->nb_pts_rollover * PTS_DTS_MAX_VALUE);
GST_LOG ("pid 0x%04x Stored PTS %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT ")",
bs->pid, stream->raw_pts, GST_TIME_ARGS (stream->pts));
if (G_UNLIKELY (demux->emit_statistics)) { if (G_UNLIKELY (demux->emit_statistics)) {
GstStructure *st; GstStructure *st;
@ -1899,9 +1939,32 @@ gst_ts_demux_record_dts (GstTSDemux * demux, TSDemuxStream * stream,
{ {
MpegTSBaseStream *bs = (MpegTSBaseStream *) stream; MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
GST_LOG ("pid 0x%04x dts:%" GST_TIME_FORMAT " at offset %" GST_LOG ("pid 0x%04x dts:%" G_GUINT64_FORMAT " at offset %"
G_GUINT64_FORMAT, bs->pid, G_GUINT64_FORMAT, bs->pid, dts, offset);
GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (dts)), offset);
if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (stream->dts) &&
ABSDIFF (stream->raw_dts, dts) > 900000)) {
/* Detect rollover if diff > 10s */
GST_LOG ("Detected rollover (previous:%" G_GUINT64_FORMAT " new:%"
G_GUINT64_FORMAT ")", stream->raw_dts, dts);
if (dts < stream->raw_dts) {
/* Forward rollover */
GST_LOG ("Forward rollover, incrementing nb_dts_rollover");
stream->nb_dts_rollover++;
} else {
/* Reverse rollover */
GST_LOG ("Reverse rollover, decrementing nb_dts_rollover");
stream->nb_dts_rollover--;
}
}
/* Compute DTS in GstClockTime */
stream->raw_dts = dts;
stream->dts =
MPEGTIME_TO_GSTTIME (dts + stream->nb_dts_rollover * PTS_DTS_MAX_VALUE);
GST_LOG ("pid 0x%04x Stored DTS %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT ")",
bs->pid, stream->raw_dts, GST_TIME_ARGS (stream->dts));
if (G_UNLIKELY (demux->emit_statistics)) { if (G_UNLIKELY (demux->emit_statistics)) {
GstStructure *st; GstStructure *st;
@ -1952,7 +2015,6 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
guint8 *data; guint8 *data;
gsize length; gsize length;
guint64 bufferoffset; guint64 bufferoffset;
GstClockTime time;
PESParsingResult parseres; PESParsingResult parseres;
GstClockTime origts; GstClockTime origts;
@ -1972,6 +2034,9 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
goto discont; goto discont;
} }
if (header.DTS != -1)
gst_ts_demux_record_dts (demux, stream, header.DTS, bufferoffset);
if (header.PTS != -1) { if (header.PTS != -1) {
gst_ts_demux_record_pts (demux, stream, header.PTS, bufferoffset); gst_ts_demux_record_pts (demux, stream, header.PTS, bufferoffset);
@ -1995,7 +2060,6 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
time = calc_gsttime_from_pts (&demux->index_pcr, pts); time = calc_gsttime_from_pts (&demux->index_pcr, pts);
#endif #endif
stream->pts = time = MPEGTIME_TO_GSTTIME (header.PTS);
GST_DEBUG_OBJECT (base, GST_DEBUG_OBJECT (base,
"stream PTS %" GST_TIME_FORMAT " DTS %" GST_TIME_FORMAT, "stream PTS %" GST_TIME_FORMAT " DTS %" GST_TIME_FORMAT,
GST_TIME_ARGS (stream->pts), GST_TIME_ARGS (stream->pts),
@ -2050,7 +2114,7 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
else else
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE; GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
} else } else
GST_BUFFER_TIMESTAMP (buf) = time + base->in_gap; GST_BUFFER_TIMESTAMP (buf) = stream->pts + base->in_gap;
GST_DEBUG ("buf %" GST_TIME_FORMAT, GST_DEBUG ("buf %" GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
} }
@ -2144,7 +2208,7 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
{ {
MpegTSBase *base = (MpegTSBase *) demux; MpegTSBase *base = (MpegTSBase *) demux;
GstEvent *newsegmentevent; GstEvent *newsegmentevent;
gint64 start, stop, position; gint64 start = 0, stop = GST_CLOCK_TIME_NONE, position = 0;
GstClockTime firstpts = GST_CLOCK_TIME_NONE; GstClockTime firstpts = GST_CLOCK_TIME_NONE;
GList *tmp; GList *tmp;
@ -2172,25 +2236,28 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
/* FIXME : We should use base->segment.format and a upstream latency query /* FIXME : We should use base->segment.format and a upstream latency query
* to decide if we need to use live values or not */ * to decide if we need to use live values or not */
GST_DEBUG ("push-based. base Segment start:%" GST_TIME_FORMAT " duration:%" GST_DEBUG ("push-based. base Segment start:%" GST_TIME_FORMAT " duration:%"
GST_TIME_FORMAT ", time:%" GST_TIME_FORMAT, GST_TIME_FORMAT ", stop:%" GST_TIME_FORMAT ", time:%" GST_TIME_FORMAT,
GST_TIME_ARGS (base->segment.start), GST_TIME_ARGS (base->segment.start),
GST_TIME_ARGS (base->segment.duration), GST_TIME_ARGS (base->segment.duration),
GST_TIME_ARGS (base->segment.time)); GST_TIME_ARGS (base->segment.stop), GST_TIME_ARGS (base->segment.time));
GST_DEBUG ("push-based. demux Segment start:%" GST_TIME_FORMAT " duration:%" GST_DEBUG ("push-based. demux Segment start:%" GST_TIME_FORMAT " duration:%"
GST_TIME_FORMAT ", time:%" GST_TIME_FORMAT, GST_TIME_FORMAT ", stop:%" GST_TIME_FORMAT ", time:%" GST_TIME_FORMAT,
GST_TIME_ARGS (demux->segment.start), GST_TIME_ARGS (demux->segment.start),
GST_TIME_ARGS (demux->segment.duration), GST_TIME_ARGS (demux->segment.duration),
GST_TIME_ARGS (demux->segment.stop),
GST_TIME_ARGS (demux->segment.time)); GST_TIME_ARGS (demux->segment.time));
GST_DEBUG ("stream pts: %" GST_TIME_FORMAT " first pts: %" GST_TIME_FORMAT, GST_DEBUG ("stream pts: %" GST_TIME_FORMAT " first pts: %" GST_TIME_FORMAT,
GST_TIME_ARGS (stream->pts), GST_TIME_ARGS (firstpts)); GST_TIME_ARGS (stream->pts), GST_TIME_ARGS (firstpts));
if (base->segment.format == GST_FORMAT_TIME) {
start = base->segment.start; start = base->segment.start;
stop = base->segment.stop; stop = base->segment.stop;
if (!base->upstream_live) { if (!base->upstream_live) {
/* Shift the start depending on our position in the stream */ /* Shift the start depending on our position in the stream */
start += firstpts + base->in_gap - base->first_buf_ts; start += firstpts + base->in_gap - base->first_buf_ts;
} }
}
position = start; position = start;
} else { } else {
/* pull mode */ /* pull mode */

View file

@ -178,6 +178,7 @@ gst_h264_parse_reset_frame (GstH264Parse * h264parse)
/* done parsing; reset state */ /* done parsing; reset state */
h264parse->nalu.valid = FALSE; h264parse->nalu.valid = FALSE;
h264parse->nalu.offset = 0; h264parse->nalu.offset = 0;
h264parse->nalu.sc_offset = 0;
h264parse->nalu.size = 0; h264parse->nalu.size = 0;
h264parse->current_off = 0; h264parse->current_off = 0;
@ -213,6 +214,10 @@ gst_h264_parse_reset (GstH264Parse * h264parse)
h264parse->have_pps = FALSE; h264parse->have_pps = FALSE;
h264parse->have_sps = FALSE; h264parse->have_sps = FALSE;
h264parse->dts = GST_CLOCK_TIME_NONE;
h264parse->ts_trn_nb = GST_CLOCK_TIME_NONE;
h264parse->do_ts = TRUE;
h264parse->pending_key_unit_ts = GST_CLOCK_TIME_NONE; h264parse->pending_key_unit_ts = GST_CLOCK_TIME_NONE;
h264parse->force_key_unit_event = NULL; h264parse->force_key_unit_event = NULL;
@ -319,7 +324,7 @@ gst_h264_parse_format_from_caps (GstCaps * caps, guint * format, guint * align)
/* check downstream caps to configure format and alignment */ /* check downstream caps to configure format and alignment */
static void static void
gst_h264_parse_negotiate (GstH264Parse * h264parse) gst_h264_parse_negotiate (GstH264Parse * h264parse, GstCaps * in_caps)
{ {
GstCaps *caps; GstCaps *caps;
guint format = GST_H264_PARSE_FORMAT_NONE; guint format = GST_H264_PARSE_FORMAT_NONE;
@ -328,10 +333,19 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse)
caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (h264parse)); caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (h264parse));
GST_DEBUG_OBJECT (h264parse, "allowed caps: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (h264parse, "allowed caps: %" GST_PTR_FORMAT, caps);
gst_h264_parse_format_from_caps (caps, &format, &align); if (in_caps && caps) {
if (gst_caps_can_intersect (in_caps, caps)) {
if (caps) GST_DEBUG_OBJECT (h264parse, "downstream accepts upstream caps");
gst_h264_parse_format_from_caps (in_caps, &format, &align);
gst_caps_unref (caps); gst_caps_unref (caps);
caps = NULL;
}
}
if (caps) {
gst_h264_parse_format_from_caps (caps, &format, &align);
gst_caps_unref (caps);
}
/* default */ /* default */
if (!format) if (!format)
@ -618,7 +632,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
guint current_off = 0; guint current_off = 0;
gboolean drain; gboolean drain;
GstH264NalParser *nalparser = h264parse->nalparser; GstH264NalParser *nalparser = h264parse->nalparser;
GstH264NalUnit nalu = h264parse->nalu; GstH264NalUnit nalu;
data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ); data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
@ -630,7 +644,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
/* need to configure aggregation */ /* need to configure aggregation */
if (G_UNLIKELY (h264parse->format == GST_H264_PARSE_FORMAT_NONE)) if (G_UNLIKELY (h264parse->format == GST_H264_PARSE_FORMAT_NONE))
gst_h264_parse_negotiate (h264parse); gst_h264_parse_negotiate (h264parse, NULL);
/* avoid stale cached parsing state */ /* avoid stale cached parsing state */
if (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_PARSING)) { if (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_PARSING)) {
@ -642,6 +656,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
} }
drain = FALSE; drain = FALSE;
nalu = h264parse->nalu;
current_off = h264parse->current_off; current_off = h264parse->current_off;
GST_DEBUG_OBJECT (h264parse, "last parse position %u", current_off); GST_DEBUG_OBJECT (h264parse, "last parse position %u", current_off);
@ -686,7 +701,9 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
current_off = size - 3; current_off = size - 3;
goto parsing_error; goto parsing_error;
case GST_H264_PARSER_NO_NAL: case GST_H264_PARSER_NO_NAL:
current_off = size - 3; /* don't expect to have found any NAL so far */
g_assert (h264parse->nalu.size == 0);
current_off = h264parse->nalu.sc_offset = size - 3;
goto more; goto more;
case GST_H264_PARSER_BROKEN_DATA: case GST_H264_PARSER_BROKEN_DATA:
GST_WARNING_OBJECT (h264parse, "input stream is corrupt; " GST_WARNING_OBJECT (h264parse, "input stream is corrupt; "
@ -1063,7 +1080,7 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps)
/* but not necessarily or reliably this */ /* but not necessarily or reliably this */
if (h264parse->fps_num > 0 && h264parse->fps_den > 0) if (h264parse->fps_num > 0 && h264parse->fps_den > 0)
gst_caps_set_simple (caps, "framerate", gst_caps_set_simple (caps, "framerate",
GST_TYPE_FRACTION, sps->fps_num, sps->fps_den, NULL); GST_TYPE_FRACTION, h264parse->fps_num, h264parse->fps_den, NULL);
} }
} }
@ -1243,6 +1260,9 @@ gst_h264_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
gst_h264_parse_update_src_caps (h264parse, NULL); gst_h264_parse_update_src_caps (h264parse, NULL);
/* don't mess with timestamps if provided by upstream,
* particularly since our ts not that good they handle seeking etc */
if (h264parse->do_ts)
gst_h264_parse_get_timestamp (h264parse, gst_h264_parse_get_timestamp (h264parse,
&GST_BUFFER_TIMESTAMP (buffer), &GST_BUFFER_DURATION (buffer), &GST_BUFFER_TIMESTAMP (buffer), &GST_BUFFER_DURATION (buffer),
h264parse->frame_start); h264parse->frame_start);
@ -1476,6 +1496,9 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
new_buf = gst_byte_writer_reset_and_get_buffer (&bw); new_buf = gst_byte_writer_reset_and_get_buffer (&bw);
gst_buffer_copy_into (new_buf, buffer, GST_BUFFER_COPY_METADATA, 0, gst_buffer_copy_into (new_buf, buffer, GST_BUFFER_COPY_METADATA, 0,
-1); -1);
/* should already be keyframe/IDR, but it may not have been,
* so mark it as such to avoid being discarded by picky decoder */
GST_BUFFER_FLAG_UNSET (new_buf, GST_BUFFER_FLAG_DELTA_UNIT);
gst_buffer_replace (&frame->buffer, new_buf); gst_buffer_replace (&frame->buffer, new_buf);
gst_buffer_unref (new_buf); gst_buffer_unref (new_buf);
} }
@ -1614,8 +1637,20 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
} }
} }
{
GstCaps *in_caps;
/* prefer input type determined above */
in_caps = gst_caps_new_simple ("video/x-h264",
"parsed", G_TYPE_BOOLEAN, TRUE,
"stream-format", G_TYPE_STRING,
gst_h264_parse_get_string (h264parse, TRUE, format),
"alignment", G_TYPE_STRING,
gst_h264_parse_get_string (h264parse, FALSE, align), NULL);
/* negotiate with downstream, sets ->format and ->align */ /* negotiate with downstream, sets ->format and ->align */
gst_h264_parse_negotiate (h264parse); gst_h264_parse_negotiate (h264parse, in_caps);
gst_caps_unref (in_caps);
}
if (format == h264parse->format && align == h264parse->align) { if (format == h264parse->format && align == h264parse->align) {
gst_base_parse_set_passthrough (parse, TRUE); gst_base_parse_set_passthrough (parse, TRUE);
@ -1732,6 +1767,22 @@ gst_h264_parse_event (GstBaseParse * parse, GstEvent * event)
gst_event_replace (&h264parse->force_key_unit_event, event); gst_event_replace (&h264parse->force_key_unit_event, event);
break; break;
} }
case GST_EVENT_FLUSH_STOP:
h264parse->dts = GST_CLOCK_TIME_NONE;
h264parse->ts_trn_nb = GST_CLOCK_TIME_NONE;
break;
case GST_EVENT_SEGMENT:
{
const GstSegment *segment;
gst_event_parse_segment (event, &segment);
/* don't try to mess with more subtle cases (e.g. seek) */
if (segment->format == GST_FORMAT_TIME &&
(segment->start != 0 || segment->rate != 1.0
|| segment->applied_rate != 1.0))
h264parse->do_ts = FALSE;
break;
}
default: default:
break; break;
} }

View file

@ -92,6 +92,7 @@ struct _GstH264Parse
GstClockTime dts; GstClockTime dts;
/* dts at start of last buffering period */ /* dts at start of last buffering period */
GstClockTime ts_trn_nb; GstClockTime ts_trn_nb;
gboolean do_ts;
/* frame parsing */ /* frame parsing */
/*guint last_nal_pos;*/ /*guint last_nal_pos;*/

View file

@ -642,12 +642,13 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse)
* 3 => SNR Scalable, 4 => Main, 5 => Simple * 3 => SNR Scalable, 4 => Main, 5 => Simple
* 4:2:2 and Multi-view have profile = 0, with the escape bit set to 1 * 4:2:2 and Multi-view have profile = 0, with the escape bit set to 1
*/ */
const gchar *profiles[] = { "high", "spatial", "snr", "main", "simple" }; const gchar *const profiles[] =
{ "high", "spatial", "snr", "main", "simple" };
/* /*
* Level indication - 4 => High, 6 => High-1440, 8 => Main, 10 => Low, * Level indication - 4 => High, 6 => High-1440, 8 => Main, 10 => Low,
* except in the case of profile = 0 * except in the case of profile = 0
*/ */
const gchar *levels[] = { "high", "high-1440", "main", "low" }; const gchar *const levels[] = { "high", "high-1440", "main", "low" };
if (profile_c > 0 && profile_c < 6) if (profile_c > 0 && profile_c < 6)
profile = profiles[profile_c - 1]; profile = profiles[profile_c - 1];

View file

@ -26,6 +26,7 @@
#include <unistd.h> #include <unistd.h>
#include <glib.h> #include <glib.h>
#include <glib/gstdio.h>
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/check/gstcheck.h> #include <gst/check/gstcheck.h>
#include <gst/interfaces/photography.h> #include <gst/interfaces/photography.h>
@ -501,6 +502,16 @@ check_file_validity (const gchar * filename, gint num, GstTagList * taglist)
return TRUE; return TRUE;
} }
static void
remove_file (const gchar * fn_template, guint num)
{
const gchar *fn;
fn = make_test_file_name (fn_template, num);
GST_INFO ("removing %s", fn);
g_unlink (fn);
}
GST_START_TEST (test_single_image_capture) GST_START_TEST (test_single_image_capture)
{ {
gboolean ready = FALSE; gboolean ready = FALSE;
@ -544,6 +555,7 @@ GST_START_TEST (test_single_image_capture)
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (SINGLE_IMAGE_FILENAME, 0, NULL); check_file_validity (SINGLE_IMAGE_FILENAME, 0, NULL);
remove_file (SINGLE_IMAGE_FILENAME, 0);
} }
GST_END_TEST; GST_END_TEST;
@ -568,6 +580,7 @@ GST_START_TEST (test_single_image_capture_with_flags)
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (SINGLE_IMAGE_WITH_FLAGS_FILENAME, 0, NULL); check_file_validity (SINGLE_IMAGE_WITH_FLAGS_FILENAME, 0, NULL);
remove_file (SINGLE_IMAGE_WITH_FLAGS_FILENAME, 0);
} }
GST_END_TEST; GST_END_TEST;
@ -617,6 +630,7 @@ GST_START_TEST (test_video_recording)
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (VIDEO_WITH_FLAGS_FILENAME, 0, NULL); check_file_validity (VIDEO_WITH_FLAGS_FILENAME, 0, NULL);
remove_file (VIDEO_WITH_FLAGS_FILENAME, 0);
} }
GST_END_TEST; GST_END_TEST;
@ -653,6 +667,7 @@ GST_START_TEST (test_video_recording_with_flags)
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (VIDEO_FILENAME, 0, NULL); check_file_validity (VIDEO_FILENAME, 0, NULL);
remove_file (VIDEO_FILENAME, 0);
} }
GST_END_TEST; GST_END_TEST;
@ -704,6 +719,7 @@ GST_START_TEST (test_video_recording_pause)
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (VIDEO_PAUSE_FILENAME, 0, NULL); check_file_validity (VIDEO_PAUSE_FILENAME, 0, NULL);
remove_file (VIDEO_PAUSE_FILENAME, 0);
} }
GST_END_TEST; GST_END_TEST;
@ -740,6 +756,7 @@ GST_START_TEST (test_video_recording_no_audio)
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (VIDEO_NOAUDIO_FILENAME, 0, NULL); check_file_validity (VIDEO_NOAUDIO_FILENAME, 0, NULL);
remove_file (VIDEO_NOAUDIO_FILENAME, 0);
} }
GST_END_TEST; GST_END_TEST;
@ -767,7 +784,9 @@ GST_START_TEST (test_image_video_cycle)
/* validate all the files */ /* validate all the files */
for (i = 2; i > 0; i--) { for (i = 2; i > 0; i--) {
check_file_validity (CYCLE_IMAGE_FILENAME, i, NULL); check_file_validity (CYCLE_IMAGE_FILENAME, i, NULL);
remove_file (CYCLE_IMAGE_FILENAME, i);
check_file_validity (CYCLE_VIDEO_FILENAME, i, NULL); check_file_validity (CYCLE_VIDEO_FILENAME, i, NULL);
remove_file (CYCLE_VIDEO_FILENAME, i);
} }
} }
@ -796,6 +815,7 @@ GST_START_TEST (test_image_tags_setting)
for (i = 0; i < SEQUENTIAL_IMAGES_COUNT; i++) { for (i = 0; i < SEQUENTIAL_IMAGES_COUNT; i++) {
check_file_validity (SEQUENTIAL_IMAGES_FILENAME, i, check_file_validity (SEQUENTIAL_IMAGES_FILENAME, i,
taglists[i % TAGLISTS_COUNT]); taglists[i % TAGLISTS_COUNT]);
remove_file (SEQUENTIAL_IMAGES_FILENAME, i);
} }
} }

View file

@ -27,6 +27,7 @@
#include <unistd.h> #include <unistd.h>
#include <glib.h> #include <glib.h>
#include <glib/gstdio.h>
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/video/video.h> #include <gst/video/video.h>
#include <gst/check/gstcheck.h> #include <gst/check/gstcheck.h>
@ -450,8 +451,9 @@ teardown (void)
tags_found = NULL; tags_found = NULL;
g_free (video_filename); g_free (video_filename);
g_free (image_filename);
video_filename = NULL; video_filename = NULL;
g_free (image_filename);
image_filename = NULL; image_filename = NULL;
GST_INFO ("done"); GST_INFO ("done");
@ -585,6 +587,16 @@ check_file_validity (const gchar * filename, gint num, GstTagList * taglist,
return TRUE; return TRUE;
} }
static void
remove_file (const gchar * fn_template, guint num)
{
const gchar *fn;
fn = make_const_file_name (fn_template, num);
GST_INFO ("removing %s", fn);
g_unlink (fn);
}
static GstPadProbeReturn static GstPadProbeReturn
filter_buffer_count (GstPad * pad, GstPadProbeInfo * info, gpointer data) filter_buffer_count (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{ {
@ -692,6 +704,7 @@ GST_START_TEST (test_single_image_capture)
wait_for_idle_state (); wait_for_idle_state ();
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (image_filename, 0, NULL, 0, 0, NO_AUDIO); check_file_validity (image_filename, 0, NULL, 0, 0, NO_AUDIO);
remove_file (image_filename, 0);
} }
GST_END_TEST; GST_END_TEST;
@ -746,6 +759,7 @@ GST_START_TEST (test_multiple_image_captures)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
check_file_validity (image_filename, i, NULL, widths[i], heights[i], check_file_validity (image_filename, i, NULL, widths[i], heights[i],
NO_AUDIO); NO_AUDIO);
remove_file (image_filename, i);
} }
} }
@ -795,6 +809,8 @@ GST_START_TEST (test_single_video_recording)
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO); check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO);
remove_file (video_filename, 0);
} }
GST_END_TEST; GST_END_TEST;
@ -866,6 +882,7 @@ GST_START_TEST (test_multiple_video_recordings)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
check_file_validity (video_filename, i, NULL, widths[i], heights[i], check_file_validity (video_filename, i, NULL, widths[i], heights[i],
WITH_AUDIO); WITH_AUDIO);
remove_file (video_filename, i);
} }
} }
@ -930,7 +947,9 @@ GST_START_TEST (test_image_video_cycle)
/* validate all the files */ /* validate all the files */
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
check_file_validity (image_filename, i, NULL, 0, 0, NO_AUDIO); check_file_validity (image_filename, i, NULL, 0, 0, NO_AUDIO);
remove_file (image_filename, i);
check_file_validity (video_filename, i, NULL, 0, 0, WITH_AUDIO); check_file_validity (video_filename, i, NULL, 0, 0, WITH_AUDIO);
remove_file (video_filename, i);
} }
} }
@ -977,6 +996,7 @@ GST_START_TEST (test_image_capture_previews)
gst_message_unref (msg); gst_message_unref (msg);
check_preview_image (camera, image_filename, i); check_preview_image (camera, image_filename, i);
remove_file (image_filename, i);
if (preview_buffer) if (preview_buffer)
gst_buffer_unref (preview_buffer); gst_buffer_unref (preview_buffer);
@ -1056,6 +1076,7 @@ GST_START_TEST (test_image_capture_with_tags)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
check_file_validity (image_filename, i, taglists[i], 0, 0, NO_AUDIO); check_file_validity (image_filename, i, taglists[i], 0, 0, NO_AUDIO);
gst_tag_list_free (taglists[i]); gst_tag_list_free (taglists[i]);
remove_file (image_filename, i);
} }
} }
@ -1133,6 +1154,7 @@ GST_START_TEST (test_video_capture_with_tags)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
check_file_validity (video_filename, i, taglists[i], 0, 0, NO_AUDIO); check_file_validity (video_filename, i, taglists[i], 0, 0, NO_AUDIO);
gst_tag_list_free (taglists[i]); gst_tag_list_free (taglists[i]);
remove_file (video_filename, i);
} }
} }
@ -1234,6 +1256,7 @@ GST_START_TEST (test_idle_property)
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO); check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO);
remove_file (video_filename, 0);
} }
GST_END_TEST; GST_END_TEST;
@ -1300,6 +1323,7 @@ GST_START_TEST (test_image_custom_filter)
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (image_filename, 0, NULL, 0, 0, NO_AUDIO); check_file_validity (image_filename, 0, NULL, 0, 0, NO_AUDIO);
remove_file (image_filename, 0);
fail_unless (vf_probe_counter > 0); fail_unless (vf_probe_counter > 0);
fail_unless (image_probe_counter == 1); fail_unless (image_probe_counter == 1);
@ -1381,6 +1405,7 @@ GST_START_TEST (test_video_custom_filter)
gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO); check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO);
remove_file (video_filename, 0);
fail_unless (vf_probe_counter > 0); fail_unless (vf_probe_counter > 0);
fail_unless (video_probe_counter > 0); fail_unless (video_probe_counter > 0);
@ -1483,6 +1508,7 @@ GST_START_TEST (test_image_location_switching)
} }
for (i = 0; i < LOCATION_SWITCHING_FILENAMES_COUNT; i++) { for (i = 0; i < LOCATION_SWITCHING_FILENAMES_COUNT; i++) {
g_unlink (filenames[i]);
g_free (filenames[i]); g_free (filenames[i]);
} }
g_signal_handler_disconnect (src, notify_id); g_signal_handler_disconnect (src, notify_id);

View file

@ -27,6 +27,8 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <glib/gstdio.h>
#include <gst/check/gstcheck.h> #include <gst/check/gstcheck.h>
#include <gst/tag/tag.h> #include <gst/tag/tag.h>
@ -1200,6 +1202,7 @@ GST_START_TEST (test_jifmux_tags)
tmpfile); tmpfile);
libexif_check_tags (FILE_SOURCE_TAG ("transparent-scanner"), tmpfile); libexif_check_tags (FILE_SOURCE_TAG ("transparent-scanner"), tmpfile);
g_unlink (tmpfile);
g_free (tmpfile); g_free (tmpfile);
} }

View file

@ -257,9 +257,10 @@ bus_callback (GstBus * bus, GstMessage * message, gpointer data)
return TRUE; return TRUE;
} }
static void static gboolean
init_gtkwidgets_data (void) init_gtkwidgets_data (void)
{ {
#if GTK_CHECK_VERSION(2,24,0)
gint i; gint i;
GtkComboBoxText *combobox = GtkComboBoxText *combobox =
GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "formatComboBox")); GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "formatComboBox"));
@ -273,6 +274,11 @@ init_gtkwidgets_data (void)
/* default to the first one -> ogg */ /* default to the first one -> ogg */
gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 0); gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 0);
return TRUE;
#else
g_warning ("This needs a newer version of GTK (2.24 at least)");
return FALSE;
#endif
} }
int int
@ -298,7 +304,9 @@ main (int argc, char *argv[])
gst_bus_set_sync_handler (bus, bus_sync_callback, NULL); gst_bus_set_sync_handler (bus, bus_sync_callback, NULL);
gst_object_unref (bus); gst_object_unref (bus);
init_gtkwidgets_data (); if (!init_gtkwidgets_data ()) {
goto error;
}
ui_main_window = GTK_WIDGET (gtk_builder_get_object (builder, "mainWindow")); ui_main_window = GTK_WIDGET (gtk_builder_get_object (builder, "mainWindow"));
gtk_builder_connect_signals (builder, NULL); gtk_builder_connect_signals (builder, NULL);
@ -308,6 +316,7 @@ main (int argc, char *argv[])
gtk_main (); gtk_main ();
error:
gst_element_set_state (camera, GST_STATE_NULL); gst_element_set_state (camera, GST_STATE_NULL);
gst_object_unref (camera); gst_object_unref (camera);
return ret; return ret;