[Bug 736924] New: iOS 8 issue mp4 recording not playable

GStreamer (bugzilla.gnome.org) bugzilla at gnome.org
Thu Sep 18 11:15:02 PDT 2014


https://bugzilla.gnome.org/show_bug.cgi?id=736924
  GStreamer | don't know | 2.x

           Summary: iOS 8 issue mp4 recording not playable
    Classification: Platform
           Product: GStreamer
           Version: 2.x
        OS/Version: other
            Status: UNCONFIRMED
          Severity: blocker
          Priority: Normal
         Component: don't know
        AssignedTo: gstreamer-bugs at lists.freedesktop.org
        ReportedBy: michelle211 at comcast.net
         QAContact: gstreamer-bugs at lists.freedesktop.org
     GNOME version: ---


We are using the following code to create mp4's on IOS using Gstreamer, this
works fine on iOS 7.x and below but on IOS we cannot play partially recorded
files, or files that haven't finished recording.
this is a severe error.


We can confirm these files will not play outside IOS using vlc either.



i  // pipeline def
        NSString *source = [NSString stringWithFormat:@"udpsrc address=%@
port=%@ name=zeVideoRecordSource", self.host, port];
        source = [source stringByAppendingString:@" ! application/x-rtp,
media=video, clock-rate=90000, encoding-name=H264, payload=96"];
        //source = [source stringByAppendingString:@" ! rtpjitterbuffer"];   
// this may or may not be needed
         source = [source stringByAppendingString:@" ! rtph264depay ! queue"];
        //source = [source stringByAppendingString:@" ! rtph264depay"];
        source = [source stringByAppendingString:@" ! h264parse"];
        source = [source stringByAppendingString:@" ! video/x-h264,
framerate=24/1"];
        source = [source stringByAppendingString:@" ! queue name=zeQueue"];


and the processing bin code

-(NSString *) buildNewProcessingBin
{
    // TODO: element cleanup in fail state?
    NSString *errMsg = nil;

    // create initial elements
    NSString *processingBinName = [NSString
stringWithFormat:@"processing_bin_%u", _processingBinCount];
    GstElement *processingBin = gst_bin_new([processingBinName
cStringUsingEncoding:NSUTF8StringEncoding]);
    GstElement *muxer = gst_element_factory_make("mp4mux", NULL);
    GstElement *writer = gst_element_factory_make("filesink", NULL);
    if (processingBin == NULL || muxer == NULL || writer == NULL)
    {
        errMsg = @"Could not create at least one element in processing bin";
        LOG_ERROR(GSTR,errMsg, nil);
    }

    // set up the file writer, creating base directory if necessary
    if (errMsg == nil)
    {
        // formatter for storage of video file
        NSString * streamName = [[DateManager sharedInstance]
recordingTimeStampAsString];
        streamName = [streamName stringByAppendingFormat:@"_%@", [self
getStreamName]];
        NSString *file = [streamName stringByAppendingFormat:@"_%u",
_processingBinCount];
        NSString *ext = @"mp4";
        NSString *fileWithExt = [file stringByAppendingPathExtension:ext];
        NSString *path = [self getStreamStorageLocation];
        NSString *pathWithFile = [path
stringByAppendingPathComponent:fileWithExt];

        LOG_DEBUG(GSTR,@"file storage location = %@", pathWithFile);

        // remove old recordings so we don't exceed our storage limit
        NSUInteger maxFiles = 110;
        [self removeStaleRecordingsInStreamStorageLocation:maxFiles
doRemove:YES];

        // set filesink properties
        NSError *dirCreateError = nil;
        BOOL didCreateDirectory = NO;
        BOOL isDirectory = NO;
        if (![[NSFileManager defaultManager] fileExistsAtPath:path
isDirectory:&isDirectory])
        {
            [[NSFileManager defaultManager] createDirectoryAtPath:path
withIntermediateDirectories:NO attributes:nil error:&dirCreateError];
            didCreateDirectory = YES;
        }

        if (dirCreateError != nil)
        {
            errMsg = [NSString stringWithFormat:@"Unable to create directory at
path %@", path];
            LOG_ERROR(GSTR,errMsg, nil);
            LOG_ERROR(GSTR,@"Directory create error: %@",
dirCreateError.description);
        }
        else if (!didCreateDirectory && !isDirectory)
        {
            errMsg = [NSString stringWithFormat:@"File already exists at
directory path %@", path];
            LOG_ERROR(GSTR,errMsg, nil);
        }
        else
        {
            g_object_set(writer,
                         "location", [pathWithFile
cStringUsingEncoding:NSUTF8StringEncoding],
                         NULL);
        }
    }

    // add and link elements in processing bin
    if (errMsg == nil)
    {
        gst_bin_add_many(GST_BIN(processingBin), muxer, writer, NULL);
        if (!gst_element_link_many(muxer, writer, NULL))
        {
            errMsg = @"Could not link muxing and writing elements together in
processing bin";
            LOG_ERROR(GSTR,errMsg, nil);
        }
    }

    // add a ghost pad, but first we need a template to request the muxer sink
pad
    GstPadTemplate *muxSinkPadTemplate = NULL;
    if (errMsg == nil)
    {
        muxSinkPadTemplate =
gst_element_class_get_pad_template(GST_ELEMENT_GET_CLASS(muxer), "video_%u");
        if (muxSinkPadTemplate == NULL)
        {
            errMsg = @"Could not get muxer sink pad template in processing
bin";
            LOG_ERROR(GSTR,errMsg, nil);
        }
    }

    // now request the muxer sink pad
    GstPad *lastSinkPad = NULL;
    if (errMsg == nil)
    {
        GstPad *sinkPad = gst_element_request_pad(muxer, muxSinkPadTemplate,
NULL, NULL);
        GstPad *ghostPad = gst_ghost_pad_new("sink", sinkPad);
        if (sinkPad == NULL || ghostPad == NULL)
        {
            errMsg = @"Could not get muxer sink pad or create ghost pad in
processing bin";
            LOG_ERROR(GSTR,errMsg, nil);
        }
        else
        {
            gst_element_add_pad(processingBin, ghostPad);
            lastSinkPad = gst_element_get_static_pad(writer, "sink");
        }
        gst_object_unref(muxSinkPadTemplate);
    }

    // save a reference to our new processing bin, and last sink pad in the
processing bin
    if (errMsg == nil)
    {
        if (lastSinkPad == NULL)
        {
            errMsg = @"Could not get last sink pad in processing bin";
            LOG_ERROR(GSTR,errMsg, nil);
        }
        else
        {
            _processingElement = processingBin;
            _processingElementLastSinkPad = lastSinkPad;
            _processingBinCount++;
        }
    }

    return errMsg;
}

-- 
Configure bugmail: https://bugzilla.gnome.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list