Opened 2 years ago

Closed 2 years ago

#13425 closed bug (fixed)

MediaExtractor for BUrl crashes on delete

Reported by: fishpond Owned by: Barrett
Priority: normal Milestone: Unscheduled
Component: Kits/Media Kit Version: R1/Development
Keywords: Cc:
Blocked By: Blocking:
Has a Patch: no Platform: All

Description

A MediaExtractor created with a BUrl will cause a crash when deleted in the BUrlProtocol.Http thread. Looks like the http stream still retrieves data but fails on writing that to an already deleted buffer.

Attachments (1)

Radio-12907-debug-12-04-2017-00-30-58.report (85.4 KB) - added by fishpond 2 years ago.
Debig Report

Download all attachments as: .zip

Change History (11)

comment:1 Changed 2 years ago by pulkomandy

Debug report from Debugger would be useful.

It is a bit tricky to properly stop HTTP request threads to cancel a running download. We should refactor the API to avoid the problem.

comment:2 Changed 2 years ago by fishpond

Hi Barrett, hi Pulkomandy,

just had a look at and also stepped through the ~MediaExtractor code (in assembly...). There is a neat little comment in there:

fSource is owned by the BMediaFile

I guess that's true when the BPositionIO comes from a file. When it comes from a stream it's getting orphaned at some point.

There is two solutions:

A - The StreamReader plugin must own and remember the PositionIO it created and delete it in it's destructor.

B - The MediaExtractor deletes fSource when it finds a non-zero fStreamer which indicates that the source is not a BMediafile

I've just successfully tried (B) but would assume that Barrett prefers (A) since it is more consistent in that the BMediaExtractor remains more agnostic about its source. But who am I to tell...

Deleting the BPositionIO is entirely sufficient to stop and delete the BHTTPRequest, since in case of streaming it's actually a HTTPMediaIO and "knows" about its running request. Barrett has implemented it all, it just doesn't get called at present.

comment:3 Changed 2 years ago by Barrett

Hi, the ownership of the source is exactly the opposite, when an entry_ref or a BUrl is used, then BMediaFile automatically delete it (this is because the stream is created internally). If it's a client-supplied BPositionIO, it's not owned by the BMediaFile.

I don't follow completely the issue you are having, can you upload a debug report?

Are you using MediaExtractor directly?

I'd bet it's mostly an on-exit synchronization issue. The cleanest solution might be to move the ownership to the extractor, but this should be done properly.

Changed 2 years ago by fishpond

Debig Report

comment:4 Changed 2 years ago by fishpond

Has a Patch: set

comment:5 Changed 2 years ago by fishpond

Hi Barrett,

sorry about the "patch set" don't know how that got set while fighting with the upload.

The application I'm building does the following:

  • Create a MediaExtractor based on a BUrl to an internet radio station, i.e. an endless stream.
  • Retrieve a MediaDecoder from the Extractor
  • Create a BSoundPlayer providing a custom GetDecodedChunk function which retrieves data from the MediaDecoder

All that works.

When the player is stopped:

  • Stop and delete BSoundplayer
  • Delete MediaDecoder
  • Delete MediaExtractor

Immediately after deleting the extractor, I get a segment violation in BUrlRequest.HTTP thread.

I checked MediaPlayer code which will use a BMediaFile instead of just a MediaExtractor. So probably I should be using that as well which on delete will also clean up the underlying DataIO and BUrlRequest.

Just implemented that and the problem has gone.

comment:6 Changed 2 years ago by fishpond

...except that now I find some streams that will cause the same crash in BUrlRequest.Http when deleting a BMediafile after a failed InitCheck, i.e. when no decoder could be found ("No Handler"). An example is http://89.16.185.174:8004/stream .

Mediaplayer will just display an "Out of Memory" error for that Url but not crash. It will however create and maintain two BUrlRequest.Http threads per try.

But that should probably go into a new ticket.

comment:7 Changed 2 years ago by Barrett

The problem is related to the ownership of the object. You pointed out an important issue which should be resolved cleanly, the problem is that the source should be deleted before the extractor, but this will not happen when the extractor is used directly. I will commit the changes ASAP and the problem should be solved hopefully.

Last edited 2 years ago by Barrett (previous) (diff)

comment:8 Changed 2 years ago by fishpond

Thank's Barrett. I think the ticket can be closed even though you're said you wanted to resolve the ownership issue for the HttpMediaIO between mediafile, extractor, decoder...

I've found the problem with Linn radio http://89.16.185.174:8004/stream meanwhile. Looks like they as well as some other stations are not starting streams on a framd border. Basically one has to "Sniff" a data area at least the size of the maximum mp3 frame. 1280 bytes should be enough for 448kbps.

When I filter out the data before the first frame, a decoder is always found, otherwise I get a "No handler" error in 90% of the cases. I just don't like that solution since it puts knowledge/assumptions about the mp3 format into the controlling application.

And: Thx again for your work.

comment:9 Changed 2 years ago by pulkomandy

Has a Patch: unset

comment:10 Changed 2 years ago by Barrett

Resolution: fixed
Status: newclosed

Fixed in hrev51151.

You can now use MediaStreamer to obtain an adapter directly.

Note: See TracTickets for help on using tickets.