| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/base/video_frame.h" | 5 #include "media/base/video_frame.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <climits> | 8 #include <climits> |
| 9 | 9 |
| 10 #include "base/atomic_sequence_num.h" | 10 #include "base/atomic_sequence_num.h" |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 natural_size.width() > limits::kMaxDimension || | 118 natural_size.width() > limits::kMaxDimension || |
| 119 natural_size.height() > limits::kMaxDimension) | 119 natural_size.height() > limits::kMaxDimension) |
| 120 return false; | 120 return false; |
| 121 | 121 |
| 122 // TODO(mcasas): Remove parameter |storage_type| when the opaque storage types | 122 // TODO(mcasas): Remove parameter |storage_type| when the opaque storage types |
| 123 // comply with the checks below. Right now we skip them. | 123 // comply with the checks below. Right now we skip them. |
| 124 if (!IsStorageTypeMappable(storage_type)) | 124 if (!IsStorageTypeMappable(storage_type)) |
| 125 return true; | 125 return true; |
| 126 | 126 |
| 127 // Make sure new formats are properly accounted for in the method. | 127 // Make sure new formats are properly accounted for in the method. |
| 128 static_assert(PIXEL_FORMAT_MAX == 21, | 128 static_assert(PIXEL_FORMAT_MAX == 23, |
| 129 "Added pixel format, please review IsValidConfig()"); | 129 "Added pixel format, please review IsValidConfig()"); |
| 130 | 130 |
| 131 if (format == PIXEL_FORMAT_UNKNOWN) { | 131 if (format == PIXEL_FORMAT_UNKNOWN) { |
| 132 return coded_size.IsEmpty() && visible_rect.IsEmpty() && | 132 return coded_size.IsEmpty() && visible_rect.IsEmpty() && |
| 133 natural_size.IsEmpty(); | 133 natural_size.IsEmpty(); |
| 134 } | 134 } |
| 135 | 135 |
| 136 // Check that software-allocated buffer formats are not empty. | 136 // Check that software-allocated buffer formats are not empty. |
| 137 return !coded_size.IsEmpty() && !visible_rect.IsEmpty() && | 137 return !coded_size.IsEmpty() && !visible_rect.IsEmpty() && |
| 138 !natural_size.IsEmpty(); | 138 !natural_size.IsEmpty(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 163 scoped_refptr<VideoFrame> VideoFrame::WrapNativeTextures( | 163 scoped_refptr<VideoFrame> VideoFrame::WrapNativeTextures( |
| 164 VideoPixelFormat format, | 164 VideoPixelFormat format, |
| 165 const gpu::MailboxHolder (&mailbox_holders)[kMaxPlanes], | 165 const gpu::MailboxHolder (&mailbox_holders)[kMaxPlanes], |
| 166 const ReleaseMailboxCB& mailbox_holder_release_cb, | 166 const ReleaseMailboxCB& mailbox_holder_release_cb, |
| 167 const gfx::Size& coded_size, | 167 const gfx::Size& coded_size, |
| 168 const gfx::Rect& visible_rect, | 168 const gfx::Rect& visible_rect, |
| 169 const gfx::Size& natural_size, | 169 const gfx::Size& natural_size, |
| 170 base::TimeDelta timestamp) { | 170 base::TimeDelta timestamp) { |
| 171 if (format != PIXEL_FORMAT_ARGB && format != PIXEL_FORMAT_XRGB && | 171 if (format != PIXEL_FORMAT_ARGB && format != PIXEL_FORMAT_XRGB && |
| 172 format != PIXEL_FORMAT_UYVY && format != PIXEL_FORMAT_NV12 && | 172 format != PIXEL_FORMAT_UYVY && format != PIXEL_FORMAT_NV12 && |
| 173 format != PIXEL_FORMAT_I420) { | 173 format != PIXEL_FORMAT_I420 && format != PIXEL_FORMAT_Y8 && |
| 174 format != PIXEL_FORMAT_Y16) { |
| 174 LOG(DFATAL) << "Unsupported pixel format supported, got " | 175 LOG(DFATAL) << "Unsupported pixel format supported, got " |
| 175 << VideoPixelFormatToString(format); | 176 << VideoPixelFormatToString(format); |
| 176 return nullptr; | 177 return nullptr; |
| 177 } | 178 } |
| 178 const StorageType storage = STORAGE_OPAQUE; | 179 const StorageType storage = STORAGE_OPAQUE; |
| 179 if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { | 180 if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { |
| 180 LOG(DFATAL) << __func__ << " Invalid config." | 181 LOG(DFATAL) << __func__ << " Invalid config." |
| 181 << ConfigToString(format, storage, coded_size, visible_rect, | 182 << ConfigToString(format, storage, coded_size, visible_rect, |
| 182 natural_size); | 183 natural_size); |
| 183 return nullptr; | 184 return nullptr; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 211 size_t data_size, | 212 size_t data_size, |
| 212 base::SharedMemoryHandle handle, | 213 base::SharedMemoryHandle handle, |
| 213 size_t data_offset, | 214 size_t data_offset, |
| 214 base::TimeDelta timestamp) { | 215 base::TimeDelta timestamp) { |
| 215 return WrapExternalStorage(format, STORAGE_SHMEM, coded_size, visible_rect, | 216 return WrapExternalStorage(format, STORAGE_SHMEM, coded_size, visible_rect, |
| 216 natural_size, data, data_size, timestamp, handle, | 217 natural_size, data, data_size, timestamp, handle, |
| 217 data_offset); | 218 data_offset); |
| 218 } | 219 } |
| 219 | 220 |
| 220 // static | 221 // static |
| 222 scoped_refptr<VideoFrame> VideoFrame::WrapExternalGpuMemoryBuffer( |
| 223 VideoPixelFormat format, |
| 224 const gfx::Size& coded_size, |
| 225 const gfx::Rect& visible_rect, |
| 226 const gfx::Size& natural_size, |
| 227 uint8_t* data, |
| 228 const gfx::GpuMemoryBufferHandle& handle, |
| 229 base::TimeDelta timestamp) { |
| 230 const StorageType storage = STORAGE_GPU_MEMORY_BUFFERS; |
| 231 if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { |
| 232 LOG(DFATAL) << __func__ << " Invalid config." |
| 233 << ConfigToString(format, storage, coded_size, visible_rect, |
| 234 natural_size); |
| 235 return nullptr; |
| 236 } |
| 237 |
| 238 scoped_refptr<VideoFrame> frame(new VideoFrame( |
| 239 format, storage, coded_size, visible_rect, natural_size, timestamp)); |
| 240 frame->strides_[0] = coded_size.width() * BytesPerElement(format, 0); |
| 241 frame->data_[0] = data; |
| 242 frame->gpu_memory_buffer_handles_.push_back(handle); |
| 243 return frame; |
| 244 } |
| 245 |
| 246 // static |
| 221 scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( | 247 scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( |
| 222 VideoPixelFormat format, | 248 VideoPixelFormat format, |
| 223 const gfx::Size& coded_size, | 249 const gfx::Size& coded_size, |
| 224 const gfx::Rect& visible_rect, | 250 const gfx::Rect& visible_rect, |
| 225 const gfx::Size& natural_size, | 251 const gfx::Size& natural_size, |
| 226 int32_t y_stride, | 252 int32_t y_stride, |
| 227 int32_t u_stride, | 253 int32_t u_stride, |
| 228 int32_t v_stride, | 254 int32_t v_stride, |
| 229 uint8_t* y_data, | 255 uint8_t* y_data, |
| 230 uint8_t* u_data, | 256 uint8_t* u_data, |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 // static | 554 // static |
| 529 size_t VideoFrame::NumPlanes(VideoPixelFormat format) { | 555 size_t VideoFrame::NumPlanes(VideoPixelFormat format) { |
| 530 switch (format) { | 556 switch (format) { |
| 531 case PIXEL_FORMAT_UYVY: | 557 case PIXEL_FORMAT_UYVY: |
| 532 case PIXEL_FORMAT_YUY2: | 558 case PIXEL_FORMAT_YUY2: |
| 533 case PIXEL_FORMAT_ARGB: | 559 case PIXEL_FORMAT_ARGB: |
| 534 case PIXEL_FORMAT_XRGB: | 560 case PIXEL_FORMAT_XRGB: |
| 535 case PIXEL_FORMAT_RGB24: | 561 case PIXEL_FORMAT_RGB24: |
| 536 case PIXEL_FORMAT_RGB32: | 562 case PIXEL_FORMAT_RGB32: |
| 537 case PIXEL_FORMAT_MJPEG: | 563 case PIXEL_FORMAT_MJPEG: |
| 564 case PIXEL_FORMAT_Y8: |
| 565 case PIXEL_FORMAT_Y16: |
| 538 return 1; | 566 return 1; |
| 539 case PIXEL_FORMAT_NV12: | 567 case PIXEL_FORMAT_NV12: |
| 540 case PIXEL_FORMAT_NV21: | 568 case PIXEL_FORMAT_NV21: |
| 541 case PIXEL_FORMAT_MT21: | 569 case PIXEL_FORMAT_MT21: |
| 542 return 2; | 570 return 2; |
| 543 case PIXEL_FORMAT_I420: | 571 case PIXEL_FORMAT_I420: |
| 544 case PIXEL_FORMAT_YV12: | 572 case PIXEL_FORMAT_YV12: |
| 545 case PIXEL_FORMAT_YV16: | 573 case PIXEL_FORMAT_YV16: |
| 546 case PIXEL_FORMAT_YV24: | 574 case PIXEL_FORMAT_YV24: |
| 547 case PIXEL_FORMAT_YUV420P9: | 575 case PIXEL_FORMAT_YUV420P9: |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 for (int row = 0; row < frame->rows(plane); ++row) { | 665 for (int row = 0; row < frame->rows(plane); ++row) { |
| 638 base::MD5Update( | 666 base::MD5Update( |
| 639 context, | 667 context, |
| 640 base::StringPiece(reinterpret_cast<char*>(frame->data(plane) + | 668 base::StringPiece(reinterpret_cast<char*>(frame->data(plane) + |
| 641 frame->stride(plane) * row), | 669 frame->stride(plane) * row), |
| 642 frame->row_bytes(plane))); | 670 frame->row_bytes(plane))); |
| 643 } | 671 } |
| 644 } | 672 } |
| 645 } | 673 } |
| 646 | 674 |
| 675 // static |
| 676 gfx::BufferFormat VideoFrame::BufferFormat(VideoPixelFormat format) { |
| 677 switch (format) { |
| 678 case PIXEL_FORMAT_I420: |
| 679 case PIXEL_FORMAT_Y8: |
| 680 return gfx::BufferFormat::R_8; |
| 681 case PIXEL_FORMAT_NV12: |
| 682 return gfx::BufferFormat::YUV_420_BIPLANAR; |
| 683 case PIXEL_FORMAT_UYVY: |
| 684 return gfx::BufferFormat::UYVY_422; |
| 685 case PIXEL_FORMAT_Y16: |
| 686 return gfx::BufferFormat::RG_88; |
| 687 default: |
| 688 NOTREACHED(); |
| 689 return gfx::BufferFormat::BGRA_8888; |
| 690 } |
| 691 } |
| 692 |
| 647 bool VideoFrame::IsMappable() const { | 693 bool VideoFrame::IsMappable() const { |
| 648 return IsStorageTypeMappable(storage_type_); | 694 return IsStorageTypeMappable(storage_type_); |
| 649 } | 695 } |
| 650 | 696 |
| 651 bool VideoFrame::HasTextures() const { | 697 bool VideoFrame::HasTextures() const { |
| 652 return !mailbox_holders_[0].mailbox.IsZero(); | 698 return !mailbox_holders_[0].mailbox.IsZero(); |
| 653 } | 699 } |
| 654 | 700 |
| 655 gfx::ColorSpace VideoFrame::ColorSpace() const { | 701 gfx::ColorSpace VideoFrame::ColorSpace() const { |
| 656 if (color_space_ == gfx::ColorSpace()) { | 702 if (color_space_ == gfx::ColorSpace()) { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 const gfx::Size& natural_size, | 878 const gfx::Size& natural_size, |
| 833 uint8_t* data, | 879 uint8_t* data, |
| 834 size_t data_size, | 880 size_t data_size, |
| 835 base::TimeDelta timestamp, | 881 base::TimeDelta timestamp, |
| 836 base::SharedMemoryHandle handle, | 882 base::SharedMemoryHandle handle, |
| 837 size_t data_offset) { | 883 size_t data_offset) { |
| 838 DCHECK(IsStorageTypeMappable(storage_type)); | 884 DCHECK(IsStorageTypeMappable(storage_type)); |
| 839 | 885 |
| 840 // TODO(miu): This function should support any pixel format. | 886 // TODO(miu): This function should support any pixel format. |
| 841 // http://crbug.com/555909 | 887 // http://crbug.com/555909 |
| 842 if (format != PIXEL_FORMAT_I420) { | 888 if (format != PIXEL_FORMAT_I420 && format != PIXEL_FORMAT_Y8 && |
| 843 LOG(DFATAL) << "Only PIXEL_FORMAT_I420 format supported: " | 889 format != PIXEL_FORMAT_Y16) { |
| 890 LOG(DFATAL) << "Only PIXEL_FORMAT_I420, PIXEL_FORMAT_Y8 and " |
| 891 "PIXEL_FORMAT_Y16 formats are supported: " |
| 844 << VideoPixelFormatToString(format); | 892 << VideoPixelFormatToString(format); |
| 845 return nullptr; | 893 return nullptr; |
| 846 } | 894 } |
| 847 | 895 |
| 848 if (!IsValidConfig(format, storage_type, coded_size, visible_rect, | 896 if (!IsValidConfig(format, storage_type, coded_size, visible_rect, |
| 849 natural_size)) { | 897 natural_size)) { |
| 850 LOG(DFATAL) << __func__ << " Invalid config." | 898 LOG(DFATAL) << __func__ << " Invalid config." |
| 851 << ConfigToString(format, storage_type, coded_size, | 899 << ConfigToString(format, storage_type, coded_size, |
| 852 visible_rect, natural_size); | 900 visible_rect, natural_size); |
| 853 return nullptr; | 901 return nullptr; |
| 854 } | 902 } |
| 855 | 903 |
| 856 scoped_refptr<VideoFrame> frame; | 904 scoped_refptr<VideoFrame> frame; |
| 857 if (storage_type == STORAGE_SHMEM) { | 905 if (storage_type == STORAGE_SHMEM) { |
| 858 frame = new VideoFrame(format, storage_type, coded_size, visible_rect, | 906 frame = new VideoFrame(format, storage_type, coded_size, visible_rect, |
| 859 natural_size, timestamp, handle, data_offset); | 907 natural_size, timestamp, handle, data_offset); |
| 860 } else { | 908 } else { |
| 861 frame = new VideoFrame(format, storage_type, coded_size, visible_rect, | 909 frame = new VideoFrame(format, storage_type, coded_size, visible_rect, |
| 862 natural_size, timestamp); | 910 natural_size, timestamp); |
| 863 } | 911 } |
| 912 if (format == PIXEL_FORMAT_Y8 || format == PIXEL_FORMAT_Y16) { |
| 913 // TODO(astojilj) Make this code generic for all and move format specifics |
| 914 // to static methods. |
| 915 DCHECK_EQ(NumPlanes(format), 1U); |
| 916 const size_t i = 0; |
| 917 frame->strides_[i] = coded_size.width() * BytesPerElement(format, i); |
| 918 frame->data_[i] = data; |
| 919 return frame; |
| 920 } |
| 864 frame->strides_[kYPlane] = coded_size.width(); | 921 frame->strides_[kYPlane] = coded_size.width(); |
| 865 // TODO(miu): This always rounds widths down, whereas VideoFrame::RowBytes() | 922 // TODO(miu): This always rounds widths down, whereas VideoFrame::RowBytes() |
| 866 // always rounds up. This inconsistency must be resolved. Perhaps a | 923 // always rounds up. This inconsistency must be resolved. Perhaps a |
| 867 // CommonAlignment() check should be made in IsValidConfig()? | 924 // CommonAlignment() check should be made in IsValidConfig()? |
| 868 // http://crbug.com/555909 | 925 // http://crbug.com/555909 |
| 869 frame->strides_[kUPlane] = coded_size.width() / 2; | 926 frame->strides_[kUPlane] = coded_size.width() / 2; |
| 870 frame->strides_[kVPlane] = coded_size.width() / 2; | 927 frame->strides_[kVPlane] = coded_size.width() / 2; |
| 871 frame->data_[kYPlane] = data; | 928 frame->data_[kYPlane] = data; |
| 872 frame->data_[kUPlane] = data + coded_size.GetArea(); | 929 frame->data_[kUPlane] = data + coded_size.GetArea(); |
| 873 frame->data_[kVPlane] = data + (coded_size.GetArea() * 5 / 4); | 930 frame->data_[kVPlane] = data + (coded_size.GetArea() * 5 / 4); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1033 case kYPlane: | 1090 case kYPlane: |
| 1034 case kAPlane: | 1091 case kAPlane: |
| 1035 return gfx::Size(1, 1); | 1092 return gfx::Size(1, 1); |
| 1036 | 1093 |
| 1037 case kUPlane: // and kUVPlane: | 1094 case kUPlane: // and kUVPlane: |
| 1038 case kVPlane: | 1095 case kVPlane: |
| 1039 switch (format) { | 1096 switch (format) { |
| 1040 case PIXEL_FORMAT_YV24: | 1097 case PIXEL_FORMAT_YV24: |
| 1041 case PIXEL_FORMAT_YUV444P9: | 1098 case PIXEL_FORMAT_YUV444P9: |
| 1042 case PIXEL_FORMAT_YUV444P10: | 1099 case PIXEL_FORMAT_YUV444P10: |
| 1100 case PIXEL_FORMAT_Y8: |
| 1101 case PIXEL_FORMAT_Y16: |
| 1043 return gfx::Size(1, 1); | 1102 return gfx::Size(1, 1); |
| 1044 | 1103 |
| 1045 case PIXEL_FORMAT_YV16: | 1104 case PIXEL_FORMAT_YV16: |
| 1046 case PIXEL_FORMAT_YUV422P9: | 1105 case PIXEL_FORMAT_YUV422P9: |
| 1047 case PIXEL_FORMAT_YUV422P10: | 1106 case PIXEL_FORMAT_YUV422P10: |
| 1048 return gfx::Size(2, 1); | 1107 return gfx::Size(2, 1); |
| 1049 | 1108 |
| 1050 case PIXEL_FORMAT_YV12: | 1109 case PIXEL_FORMAT_YV12: |
| 1051 case PIXEL_FORMAT_I420: | 1110 case PIXEL_FORMAT_I420: |
| 1052 case PIXEL_FORMAT_YV12A: | 1111 case PIXEL_FORMAT_YV12A: |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1083 case PIXEL_FORMAT_RGB24: | 1142 case PIXEL_FORMAT_RGB24: |
| 1084 return 3; | 1143 return 3; |
| 1085 case PIXEL_FORMAT_UYVY: | 1144 case PIXEL_FORMAT_UYVY: |
| 1086 case PIXEL_FORMAT_YUY2: | 1145 case PIXEL_FORMAT_YUY2: |
| 1087 case PIXEL_FORMAT_YUV420P9: | 1146 case PIXEL_FORMAT_YUV420P9: |
| 1088 case PIXEL_FORMAT_YUV422P9: | 1147 case PIXEL_FORMAT_YUV422P9: |
| 1089 case PIXEL_FORMAT_YUV444P9: | 1148 case PIXEL_FORMAT_YUV444P9: |
| 1090 case PIXEL_FORMAT_YUV420P10: | 1149 case PIXEL_FORMAT_YUV420P10: |
| 1091 case PIXEL_FORMAT_YUV422P10: | 1150 case PIXEL_FORMAT_YUV422P10: |
| 1092 case PIXEL_FORMAT_YUV444P10: | 1151 case PIXEL_FORMAT_YUV444P10: |
| 1152 case PIXEL_FORMAT_Y16: |
| 1093 return 2; | 1153 return 2; |
| 1094 case PIXEL_FORMAT_NV12: | 1154 case PIXEL_FORMAT_NV12: |
| 1095 case PIXEL_FORMAT_NV21: | 1155 case PIXEL_FORMAT_NV21: |
| 1096 case PIXEL_FORMAT_MT21: { | 1156 case PIXEL_FORMAT_MT21: { |
| 1097 static const int bytes_per_element[] = {1, 2}; | 1157 static const int bytes_per_element[] = {1, 2}; |
| 1098 DCHECK_LT(plane, arraysize(bytes_per_element)); | 1158 DCHECK_LT(plane, arraysize(bytes_per_element)); |
| 1099 return bytes_per_element[plane]; | 1159 return bytes_per_element[plane]; |
| 1100 } | 1160 } |
| 1101 case PIXEL_FORMAT_YV12: | 1161 case PIXEL_FORMAT_YV12: |
| 1102 case PIXEL_FORMAT_I420: | 1162 case PIXEL_FORMAT_I420: |
| 1103 case PIXEL_FORMAT_YV16: | 1163 case PIXEL_FORMAT_YV16: |
| 1104 case PIXEL_FORMAT_YV12A: | 1164 case PIXEL_FORMAT_YV12A: |
| 1105 case PIXEL_FORMAT_YV24: | 1165 case PIXEL_FORMAT_YV24: |
| 1166 case PIXEL_FORMAT_Y8: |
| 1106 return 1; | 1167 return 1; |
| 1107 case PIXEL_FORMAT_MJPEG: | 1168 case PIXEL_FORMAT_MJPEG: |
| 1108 return 0; | 1169 return 0; |
| 1109 case PIXEL_FORMAT_UNKNOWN: | 1170 case PIXEL_FORMAT_UNKNOWN: |
| 1110 break; | 1171 break; |
| 1111 } | 1172 } |
| 1112 NOTREACHED(); | 1173 NOTREACHED(); |
| 1113 return 0; | 1174 return 0; |
| 1114 } | 1175 } |
| 1115 | 1176 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 if (zero_initialize_memory) | 1215 if (zero_initialize_memory) |
| 1155 memset(data, 0, data_size); | 1216 memset(data, 0, data_size); |
| 1156 | 1217 |
| 1157 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) | 1218 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) |
| 1158 data_[plane] = data + offset[plane]; | 1219 data_[plane] = data + offset[plane]; |
| 1159 | 1220 |
| 1160 AddDestructionObserver(base::Bind(&base::AlignedFree, data)); | 1221 AddDestructionObserver(base::Bind(&base::AlignedFree, data)); |
| 1161 } | 1222 } |
| 1162 | 1223 |
| 1163 } // namespace media | 1224 } // namespace media |
| OLD | NEW |