Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class ios_video_track_impl : public video_track_impl
- {
- public:
- // some assets loading management code / readers, outputs creation code
- /*
- m_reader and m_reader_videotrack_output creates by code:
- AVAssetReader* createAssetReader(AVAsset* asset)
- {
- NSError* error = nil;
- AVAssetReader* assetReader = [AVAssetReader assetReaderWithAsset:asset error:&error];
- if (error) {
- NSLog(@"Failed to ceate asset reader: %@", error);
- return nil;
- }
- NSDictionary* outputSettings = @{(NSString*) kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)};
- AVAssetReaderTrackOutput* readerVideoTrackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:[asset tracksWithMediaType:AVMediaTypeVideo][0] outputSettings:outputSettings];
- readerVideoTrackOutput.alwaysCopiesSampleData = NO;
- readerVideoTrackOutput.supportsRandomAccess = YES;
- [assetReader addOutput:readerVideoTrackOutput];
- return assetReader;
- }
- */
- frame request_next_frame()
- {
- if (m_next_buffer == nil) {
- m_curr_buffer.reset([m_reader_videotrack_output copyNextSampleBuffer]);
- } else {
- m_curr_buffer = std::move(m_next_buffer);
- }
- }
- // some ts calculation logic
- m_next_buffer.reset([m_reader_videotrack_output copyNextSampleBuffer]);
- if (m_next_buffer == nil) {
- // empty frame
- return frame::create();
- }
- return frame::create(std::move(m_curr_buffer);
- }
- private:
- AVAsset* m_asset{nil};
- AVAssetReader* m_reader{nil};
- AVAssetReaderOutput* m_reader_videotrack_output{nil};
- CMSampleBufferRef m_curr_buffer{nil};
- CMSampleBufferRef m_next_buffer{nil};
- };
- class video_track
- {
- public:
- void update()
- {
- // some threads sync logic
- frame new_frame = m_impl->request_next_frame();
- if (new_frame.is_empty() || m_frames_queue.size() > max_queue_size) {
- return;
- }
- m_frames_queue.push_front(m_impl->request_next_frame());
- }
- frame dequeue_next_frame()
- {
- if (m_frames_queue.empty()) {
- // empty frame
- return frame::create();
- }
- frame ret_frame = std::move(m_frames_queue.back());
- m_frames_queue.pop_back();
- return ret_frame;
- }
- private:
- video_track_impl* m_impl;
- inline static uint32_t max_queue_size = 3;
- std::deque<frame> m_frames_queue{};
- };
- // -------------------- THREAD 1 --------------------
- While (need_update){
- for (track : m_tracks /* m_tracks is collection of video_track instances */) {
- track.update();
- }
- }
- // -------------------- THREAD 2 --------------------
- /*
- frame pixels are getting by:
- data_t get_pixel_data() const override
- {
- if (sample_buffer == nil) {
- // empty buffer
- return {};
- }
- CVImageBufferRef movieFrame = CMSampleBufferGetImageBuffer(m_sample_buffer.get());
- CVPixelBufferLockBaseAddress(movieFrame, 0);
- void* pixels_data_ptr = CVPixelBufferGetBaseAddress(movieFrame);
- const auto bpr = CVPixelBufferGetBytesPerRow(movieFrame);
- const auto h = CVPixelBufferGetHeight(movieFrame);
- return data_t::create_non_owning(static_cast<uint8_t*>(pixels_data_ptr), bpr * h, [movieFrame](uint8_t*) { CVPixelBufferUnlockBaseAddress(movieFrame, 0); });
- }
- */
- While (need_update){
- frame new_frame = m_track.dequeue_next_frame(); /* m_track is instance of video_track */
- draw_frame(new_frame);
- }
Advertisement
Add Comment
Please, Sign In to add comment