17 #include <glog/logging.h> 27 std::shared_ptr<shaka::media::DecodedFrame>
frame;
32 void FreeFrameBytes(
void* info,
const void*,
size_t) {
33 auto*
frame =
reinterpret_cast<FrameInfo*
>(info);
37 void FreeFramePlanar(
void* info,
const void*,
size_t,
size_t,
const void**) {
38 auto*
frame =
reinterpret_cast<FrameInfo*
>(info);
49 CGImageRef RenderPackedFrame(std::shared_ptr<DecodedFrame>
frame);
50 CGImageRef RenderPlanarFrame(std::shared_ptr<DecodedFrame> frame);
52 std::shared_ptr<DecodedFrame> prev_frame_;
57 std::shared_ptr<DecodedFrame>
frame;
58 const double loc_delay = GetCurrentFrame(&frame);
62 if (!frame || frame == prev_frame_)
65 if (sample_aspect_ratio)
66 *sample_aspect_ratio = frame->stream_info->sample_aspect_ratio;
68 switch (get<PixelFormat>(frame->format)) {
70 return RenderPackedFrame(frame);
74 return RenderPlanarFrame(frame);
77 LOG(DFATAL) <<
"Unsupported pixel format: " << frame->format;
82 CGImageRef AppleVideoRenderer::Impl::RenderPackedFrame(
83 std::shared_ptr<DecodedFrame>
frame) {
84 const uint32_t
width = frame->stream_info->width;
85 const uint32_t
height = frame->stream_info->height;
86 const size_t bytes_per_row = frame->linesize[0];
87 CFIndex size = bytes_per_row *
height;
94 const uint8_t* data = frame->data[0];
95 auto* info =
new FrameInfo;
97 CGDataProviderRef provider =
98 CGDataProviderCreateWithData(info, data, size, &FreeFrameBytes);
102 CGColorSpaceRef color_space = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
105 const size_t bits_per_pixel = 24;
106 const size_t bits_per_component = 8;
107 const bool should_interpolate =
false;
108 CGImage* image = CGImageCreate(width, height, bits_per_component,
109 bits_per_pixel, bytes_per_row, color_space,
110 kCGBitmapByteOrderDefault, provider,
nullptr,
111 should_interpolate, kCGRenderingIntentDefault);
114 CGColorSpaceRelease(color_space);
115 CGDataProviderRelease(provider);
120 CGImageRef AppleVideoRenderer::Impl::RenderPlanarFrame(
121 std::shared_ptr<DecodedFrame> frame) {
122 CVPixelBufferRef pixel_buffer;
123 bool free_pixel_buffer;
124 auto pix_fmt = get<PixelFormat>(frame->format);
126 uint8_t* data =
const_cast<uint8_t*
>(frame->data[0]);
127 pixel_buffer =
reinterpret_cast<CVPixelBufferRef
>(data);
128 free_pixel_buffer =
false;
133 const OSType cv_pix_fmt = kCVPixelFormatType_420YpCbCr8Planar;
134 auto* info =
new FrameInfo;
136 info->widths[0] = frame->stream_info->width;
137 info->widths[1] = info->widths[2] = frame->stream_info->width / 2;
138 info->heights[0] = frame->stream_info->height;
139 info->heights[1] = info->heights[2] = frame->stream_info->height / 2;
141 const auto status = CVPixelBufferCreateWithPlanarBytes(
142 nullptr, frame->stream_info->width, frame->stream_info->height,
143 cv_pix_fmt,
nullptr, 0, frame->data.size(),
144 reinterpret_cast<void**
>(
const_cast<uint8_t**
>(frame->data.data())),
145 info->widths, info->heights,
146 const_cast<size_t*
>(frame->linesize.data()), &FreeFramePlanar, info,
147 nullptr, &pixel_buffer);
149 LOG(ERROR) <<
"CVPixelBufferCreateWithPlanarBytes error " << status;
154 free_pixel_buffer =
true;
160 VTCreateCGImageFromCVPixelBuffer(pixel_buffer,
nullptr, &ret);
161 if (free_pixel_buffer)
162 CVPixelBufferRelease(pixel_buffer);
165 LOG(ERROR) <<
"VTCreateCGImageFromCVPixelBuffer error " << status;
176 return impl_->fill_mode();
181 return impl_->Render(delay, sample_aspect_ratio);
185 impl_->SetPlayer(player);
189 impl_->Attach(stream);
197 return impl_->VideoPlaybackQuality();
201 return impl_->SetVideoFillMode(mode);
std::shared_ptr< shaka::media::DecodedFrame > frame