diff --git a/TelegramUI/ChannelVisibilityController.swift b/TelegramUI/ChannelVisibilityController.swift index 26de8dc850..74d045d1fe 100644 --- a/TelegramUI/ChannelVisibilityController.swift +++ b/TelegramUI/ChannelVisibilityController.swift @@ -9,6 +9,7 @@ private final class ChannelVisibilityControllerArguments { let updateCurrentType: (CurrentChannelType) -> Void let updatePublicLinkText: (String?, String) -> Void + let scrollToPublicLinkText: () -> Void let displayPrivateLinkMenu: (String) -> Void let setPeerIdWithRevealedOptions: (PeerId?, PeerId?) -> Void let revokePeerId: (PeerId) -> Void @@ -16,10 +17,11 @@ private final class ChannelVisibilityControllerArguments { let revokePrivateLink: () -> Void let sharePrivateLink: () -> Void - init(account: Account, updateCurrentType: @escaping (CurrentChannelType) -> Void, updatePublicLinkText: @escaping (String?, String) -> Void, displayPrivateLinkMenu: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, revokePeerId: @escaping (PeerId) -> Void, copyPrivateLink: @escaping () -> Void, revokePrivateLink: @escaping () -> Void, sharePrivateLink: @escaping () -> Void) { + init(account: Account, updateCurrentType: @escaping (CurrentChannelType) -> Void, updatePublicLinkText: @escaping (String?, String) -> Void, scrollToPublicLinkText: @escaping () -> Void, displayPrivateLinkMenu: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, revokePeerId: @escaping (PeerId) -> Void, copyPrivateLink: @escaping () -> Void, revokePrivateLink: @escaping () -> Void, sharePrivateLink: @escaping () -> Void) { self.account = account self.updateCurrentType = updateCurrentType self.updatePublicLinkText = updatePublicLinkText + self.scrollToPublicLinkText = scrollToPublicLinkText self.displayPrivateLinkMenu = displayPrivateLinkMenu self.setPeerIdWithRevealedOptions = setPeerIdWithRevealedOptions self.revokePeerId = revokePeerId @@ -35,8 +37,17 @@ private enum ChannelVisibilitySection: Int32 { case linkActions } -private enum ChannelVisibilityEntryTag { +private enum ChannelVisibilityEntryTag: ItemListItemTag { + case publicLink case privateLink + + func isEqual(to other: ItemListItemTag) -> Bool { + if let other = other as? ChannelVisibilityEntryTag, self == other { + return true + } else { + return false + } + } } private enum ChannelVisibilityEntry: ItemListNodeEntry { @@ -252,10 +263,11 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry { } }, tag: ChannelVisibilityEntryTag.privateLink) case let .editablePublicLink(theme, currentText): - return ItemListSingleLineInputItem(theme: theme, title: NSAttributedString(string: "t.me/", textColor: theme.list.itemPrimaryTextColor), text: currentText, placeholder: "", sectionId: self.section, textUpdated: { updatedText in + return ItemListSingleLineInputItem(theme: theme, title: NSAttributedString(string: "t.me/", textColor: theme.list.itemPrimaryTextColor), text: currentText, placeholder: "", tag: ChannelVisibilityEntryTag.publicLink, sectionId: self.section, textUpdated: { updatedText in arguments.updatePublicLinkText(currentText, updatedText) + }, receivedFocus: { + arguments.scrollToPublicLinkText() }, action: { - }) case let .privateLinkInfo(theme, text): return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section) @@ -650,6 +662,7 @@ public func channelVisibilityController(account: Account, peerId: PeerId, mode: var dismissImpl: (() -> Void)? var nextImpl: (() -> Void)? var displayPrivateLinkMenuImpl: ((String) -> Void)? + var scrollToPublicLinkTextImpl: (() -> Void)? var presentControllerImpl: ((ViewController, Any?) -> Void)? let actionsDisposable = DisposableSet() @@ -697,6 +710,8 @@ public func channelVisibilityController(account: Account, peerId: PeerId, mode: } })) } + }, scrollToPublicLinkText: { + scrollToPublicLinkTextImpl?() }, displayPrivateLinkMenu: { text in displayPrivateLinkMenuImpl?(text) }, setPeerIdWithRevealedOptions: { peerId, fromPeerId in @@ -940,6 +955,7 @@ public func channelVisibilityController(account: Account, peerId: PeerId, mode: let controller = ItemListController(account: account, state: signal) dismissImpl = { [weak controller] in + controller?.view.endEditing(true) controller?.dismiss() } nextImpl = { [weak controller] in @@ -1007,6 +1023,27 @@ public func channelVisibilityController(account: Account, peerId: PeerId, mode: } } } + scrollToPublicLinkTextImpl = { [weak controller] in + DispatchQueue.main.async { + if let strongController = controller { + var resultItemNode: ListViewItemNode? + let _ = strongController.frameForItemNode({ itemNode in + if let itemNode = itemNode as? ItemListSingleLineInputItemNode { + if let tag = itemNode.tag as? ChannelVisibilityEntryTag { + if tag == .publicLink { + resultItemNode = itemNode + return true + } + } + } + return false + }) + if let resultItemNode = resultItemNode { + strongController.ensureItemNodeVisible(resultItemNode) + } + } + } + } presentControllerImpl = { [weak controller] c, a in controller?.present(c, in: .window(.root), with: a) } diff --git a/TelegramUI/ChatMessageActionButtonsNode.swift b/TelegramUI/ChatMessageActionButtonsNode.swift index 767e56b14d..95ee579b30 100644 --- a/TelegramUI/ChatMessageActionButtonsNode.swift +++ b/TelegramUI/ChatMessageActionButtonsNode.swift @@ -73,7 +73,7 @@ private final class ChatMessageActionButtonNode: ASDisplayNode { } } - let (titleSize, titleApply) = titleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: titleFont, textColor: incoming ? theme.theme.chat.bubble.actionButtonsIncomingTextColor : theme.theme.chat.bubble.actionButtonsOutgoingTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(1.0, constrainedWidth - minimumSideInset - minimumSideInset), height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets(top: 1.0, left: 0.0, bottom: 1.0, right: 0.0))) + let (titleSize, titleApply) = titleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: titleFont, textColor: incoming ? theme.theme.chat.bubble.actionButtonsIncomingTextColor : theme.theme.chat.bubble.actionButtonsOutgoingTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(44.0, constrainedWidth - minimumSideInset - minimumSideInset), height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets(top: 1.0, left: 0.0, bottom: 1.0, right: 0.0))) let graphics = PresentationResourcesChat.additionalGraphics(theme.theme, wallpaper: theme.wallpaper) let backgroundImage: UIImage? diff --git a/TelegramUI/ChatMessageBubbleItemNode.swift b/TelegramUI/ChatMessageBubbleItemNode.swift index 923de86f5a..2394f596d9 100644 --- a/TelegramUI/ChatMessageBubbleItemNode.swift +++ b/TelegramUI/ChatMessageBubbleItemNode.swift @@ -365,7 +365,9 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { } var needShareButton = false - if item.message.id.peerId == item.account.peerId { + if item.message.flags.contains(.Failed) { + needShareButton = false + } else if item.message.id.peerId == item.account.peerId { for attribute in item.content.firstMessage.attributes { if let _ = attribute as? SourceReferenceMessageAttribute { needShareButton = true diff --git a/TelegramUI/ConfirmPhoneNumberController.swift b/TelegramUI/ConfirmPhoneNumberController.swift index 811ccfa9ba..4fb3ab7bdb 100644 --- a/TelegramUI/ConfirmPhoneNumberController.swift +++ b/TelegramUI/ConfirmPhoneNumberController.swift @@ -324,6 +324,7 @@ func confirmPhoneNumberCodeController(account: Account, phoneNumber: String, cod } } dismissImpl = { [weak controller] in + controller?.view.endEditing(true) controller?.dismiss() } diff --git a/TelegramUI/DeviceContactInfoController.swift b/TelegramUI/DeviceContactInfoController.swift index 0b2c258697..07cd709682 100644 --- a/TelegramUI/DeviceContactInfoController.swift +++ b/TelegramUI/DeviceContactInfoController.swift @@ -474,14 +474,7 @@ private enum DeviceContactInfoEntry: ItemListNodeEntry { } private struct DeviceContactInfoEditingState: Equatable { - let editingName: ItemListAvatarAndNameInfoItemName? - - static func ==(lhs: DeviceContactInfoEditingState, rhs: DeviceContactInfoEditingState) -> Bool { - if lhs.editingName != rhs.editingName { - return false - } - return true - } + var editingName: ItemListAvatarAndNameInfoItemName? } private struct EditingPhoneNumber: Equatable { @@ -663,7 +656,7 @@ public enum DeviceContactInfoSubject { return peer case let .filter(peer, _, _, _): return peer - case let .create(peer, _, _): + case let .create(_, _, _): return nil } } @@ -740,7 +733,6 @@ public func deviceContactInfoController(account: Account, subject: DeviceContact var addToExistingImpl: (() -> Void)? var openChatImpl: ((PeerId) -> Void)? - var pushControllerImpl: ((ViewController) -> Void)? var replaceControllerImpl: ((ViewController) -> Void)? var presentControllerImpl: ((ViewController, Any?) -> Void)? var openUrlImpl: ((String) -> Void)? @@ -926,90 +918,106 @@ public func deviceContactInfoController(account: Account, subject: DeviceContact let previousEditingPhoneIds = Atomic?>(value: nil) let signal = combineLatest((account.applicationContext as! TelegramApplicationContext).presentationData, statePromise.get(), contactData) - |> map { presentationData, state, peerAndContactData -> (ItemListControllerState, (ItemListNodeState, DeviceContactInfoEntry.ItemGenerationArguments)) in - var leftNavigationButton: ItemListNavigationButton? - switch subject { - case .vcard: - break - case .filter, .create: - leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { - dismissImpl?(true) - cancelled?() - }) - } - - var rightNavigationButton: ItemListNavigationButton? - if case let .filter(_, _, _, completion) = subject { - let filteredData = filteredContactData(contactData: peerAndContactData.2, excludedComponents: state.excludedComponents) - rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.ShareMenu_Send), style: .bold, enabled: !filteredData.basicData.phoneNumbers.isEmpty, action: { - completion(peerAndContactData.0, filteredData) + |> map { presentationData, state, peerAndContactData -> (ItemListControllerState, (ItemListNodeState, DeviceContactInfoEntry.ItemGenerationArguments)) in + var leftNavigationButton: ItemListNavigationButton? + switch subject { + case .vcard: + break + case .filter, .create: + leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { dismissImpl?(true) + cancelled?() }) - } else if case let .create(_, _, completion) = subject { - let filteredData = filteredContactData(contactData: peerAndContactData.2, excludedComponents: state.excludedComponents) - var filteredPhoneNumbers: [DeviceContactPhoneNumberData] = [] - for phoneNumber in state.phoneNumbers { - if !phoneNumber.value.isEmpty && phoneNumber.value != "+" { - filteredPhoneNumbers.append(DeviceContactPhoneNumberData(label: phoneNumber.label, value: phoneNumber.value)) - } + } + + var rightNavigationButton: ItemListNavigationButton? + if state.savingData { + rightNavigationButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {}) + } else if case let .filter(_, _, _, completion) = subject { + let filteredData = filteredContactData(contactData: peerAndContactData.2, excludedComponents: state.excludedComponents) + rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.ShareMenu_Send), style: .bold, enabled: !filteredData.basicData.phoneNumbers.isEmpty, action: { + completion(peerAndContactData.0, filteredData) + dismissImpl?(true) + }) + } else if case let .create(_, _, completion) = subject { + let filteredData = filteredContactData(contactData: peerAndContactData.2, excludedComponents: state.excludedComponents) + var filteredPhoneNumbers: [DeviceContactPhoneNumberData] = [] + for phoneNumber in state.phoneNumbers { + if !phoneNumber.value.isEmpty && phoneNumber.value != "+" { + filteredPhoneNumbers.append(DeviceContactPhoneNumberData(label: phoneNumber.label, value: phoneNumber.value)) } - var composedContactData: DeviceContactExtendedData? - if let editingName = state.editingState?.editingName, case let .personName(firstName, lastName) = editingName, (!firstName.isEmpty || !lastName.isEmpty) { - composedContactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: firstName, lastName: lastName, phoneNumbers: filteredPhoneNumbers), middleName: filteredData.middleName, prefix: filteredData.prefix, suffix: filteredData.suffix, organization: filteredData.organization, jobTitle: filteredData.jobTitle, department: filteredData.department, emailAddresses: filteredData.emailAddresses, urls: filteredData.urls, addresses: filteredData.addresses, birthdayDate: filteredData.birthdayDate, socialProfiles: filteredData.socialProfiles, instantMessagingProfiles: filteredData.instantMessagingProfiles) - } - rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Compose_Create), style: .bold, enabled: !filteredPhoneNumbers.isEmpty && composedContactData != nil, action: { - if let composedContactData = composedContactData { - let _ = (account.telegramApplicationContext.contactDataManager.createContactWithData(composedContactData) - |> deliverOnMainQueue).start(next: { contactIdAndData in - completed?() - dismissImpl?(true) - }) + } + var composedContactData: DeviceContactExtendedData? + if let editingName = state.editingState?.editingName, case let .personName(firstName, lastName) = editingName, (!firstName.isEmpty || !lastName.isEmpty) { + composedContactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: firstName, lastName: lastName, phoneNumbers: filteredPhoneNumbers), middleName: filteredData.middleName, prefix: filteredData.prefix, suffix: filteredData.suffix, organization: filteredData.organization, jobTitle: filteredData.jobTitle, department: filteredData.department, emailAddresses: filteredData.emailAddresses, urls: filteredData.urls, addresses: filteredData.addresses, birthdayDate: filteredData.birthdayDate, socialProfiles: filteredData.socialProfiles, instantMessagingProfiles: filteredData.instantMessagingProfiles) + } + rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Compose_Create), style: .bold, enabled: !filteredPhoneNumbers.isEmpty && composedContactData != nil, action: { + if let composedContactData = composedContactData { + updateState { state in + var state = state + state.savingData = true + return state } - }) - } - - var editingPhones = false - var selecting = false - switch subject { - case .vcard: - break - case .filter: - selecting = true - case .create: - selecting = true - editingPhones = true - } - if case .filter = subject { - selecting = true - } - - let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.UserInfo_Title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: nil) - - let editingPhoneIds = Set(state.phoneNumbers.map({ $0.id })) - let previousPhoneIds = previousEditingPhoneIds.swap(editingPhoneIds) - let insertedPhoneIds = editingPhoneIds.subtracting(previousPhoneIds ?? Set()) - var insertedPhoneId: Int64? - if insertedPhoneIds.count == 1, let id = insertedPhoneIds.first { - for phoneNumber in state.phoneNumbers { - if phoneNumber.id == id { - if phoneNumber.value.isEmpty || phoneNumber.value == "+" { - insertedPhoneId = id + let _ = (account.telegramApplicationContext.contactDataManager.createContactWithData(composedContactData) + |> deliverOnMainQueue).start(next: { contactIdAndData in + updateState { state in + var state = state + state.savingData = false + return state } - break + if let contactIdAndData = contactIdAndData { + //completion(nil, contactIdAndData.0, contactIdAndData.1) + } + completed?() + dismissImpl?(true) + }) + } + }) + } + + var editingPhones = false + var selecting = false + switch subject { + case .vcard: + break + case .filter: + selecting = true + case .create: + selecting = true + editingPhones = true + } + if case .filter = subject { + selecting = true + } + + let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.UserInfo_Title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: nil) + + let editingPhoneIds = Set(state.phoneNumbers.map({ $0.id })) + let previousPhoneIds = previousEditingPhoneIds.swap(editingPhoneIds) + let insertedPhoneIds = editingPhoneIds.subtracting(previousPhoneIds ?? Set()) + var insertedPhoneId: Int64? + if insertedPhoneIds.count == 1, let id = insertedPhoneIds.first { + for phoneNumber in state.phoneNumbers { + if phoneNumber.id == id { + if phoneNumber.value.isEmpty || phoneNumber.value == "+" { + insertedPhoneId = id } + break } } - - var focusItemTag: ItemListItemTag? - if let insertedPhoneId = insertedPhoneId { - focusItemTag = DeviceContactInfoEntryTag.editingPhone(insertedPhoneId) - } - - let listState = ItemListNodeState(entries: deviceContactInfoEntries(account: account, presentationData: presentationData, peer: peerAndContactData.0, contactData: peerAndContactData.2, isContact: peerAndContactData.1 != nil, state: state, selecting: selecting, editingPhoneNumbers: editingPhones), style: .plain, focusItemTag: focusItemTag) - - return (controllerState, (listState, arguments)) - } |> afterDisposed { - actionsDisposable.dispose() + } + + var focusItemTag: ItemListItemTag? + if let insertedPhoneId = insertedPhoneId { + focusItemTag = DeviceContactInfoEntryTag.editingPhone(insertedPhoneId) + } + + let listState = ItemListNodeState(entries: deviceContactInfoEntries(account: account, presentationData: presentationData, peer: peerAndContactData.0, contactData: peerAndContactData.2, isContact: peerAndContactData.1 != nil, state: state, selecting: selecting, editingPhoneNumbers: editingPhones), style: .plain, focusItemTag: focusItemTag) + + return (controllerState, (listState, arguments)) + } + |> afterDisposed { + actionsDisposable.dispose() } let controller = DeviceContactInfoController(account: account, state: signal) @@ -1026,9 +1034,6 @@ public func deviceContactInfoController(account: Account, subject: DeviceContact navigateToChatController(navigationController: navigationController, account: account, chatLocation: .peer(peerId)) } } - pushControllerImpl = { [weak controller] value in - (controller?.navigationController as? NavigationController)?.pushViewController(value) - } replaceControllerImpl = { [weak controller] value in (controller?.navigationController as? NavigationController)?.replaceTopController(value, animated: true) } diff --git a/TelegramUI/FFMpegMediaFrameSourceContext.swift b/TelegramUI/FFMpegMediaFrameSourceContext.swift index 3db0180361..baf108cdf8 100644 --- a/TelegramUI/FFMpegMediaFrameSourceContext.swift +++ b/TelegramUI/FFMpegMediaFrameSourceContext.swift @@ -259,16 +259,19 @@ final class FFMpegMediaFrameSourceContext: NSObject { avFormatContext.pointee.pb = avIoContext - /*avFormatContext.pointee.flags |= AVFMT_FLAG_FAST_SEEK + //avFormatContext.pointee.flags |= AVFMT_FLAG_FAST_SEEK + //print(String.init(cString: avutil_configuration())) - var options: UnsafeMutablePointer - av_dict_set(&options, "usetoc", "1", 0)*/ + var options: OpaquePointer? + av_dict_set(&options, "usetoc", "1", 0) - guard avformat_open_input(&avFormatContextRef, nil, nil, nil) >= 0 else { + guard avformat_open_input(&avFormatContextRef, nil, nil, &options) >= 0 else { self.readingError = true return } + av_dict_free(&options) + guard avformat_find_stream_info(avFormatContext, nil) >= 0 else { self.readingError = true return diff --git a/TelegramUI/GroupInfoController.swift b/TelegramUI/GroupInfoController.swift index c68a6e4371..0362c7075f 100644 --- a/TelegramUI/GroupInfoController.swift +++ b/TelegramUI/GroupInfoController.swift @@ -1088,11 +1088,7 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa if case .creator = group.role, state.editingState != nil { entries.append(.convertToSupergroup(presentationData.theme, presentationData.strings.GroupInfo_ConvertToSupergroup)) } - if case .creator = group.role { - entries.append(.leave(presentationData.theme, presentationData.strings.GroupInfo_DeleteAndExit)) - } else { - entries.append(.leave(presentationData.theme, presentationData.strings.Group_LeaveGroup)) - } + entries.append(.leave(presentationData.theme, presentationData.strings.Group_LeaveGroup)) } } else if let channel = view.peers[view.peerId] as? TelegramChannel { if case .member = channel.participationStatus, let cachedChannelData = view.cachedData as? CachedChannelData, let memberCount = cachedChannelData.participantsSummary.memberCount, memberCount <= 200 { @@ -1635,7 +1631,7 @@ public func groupInfoController(account: Account, peerId: PeerId) -> ViewControl if peerId.namespace == Namespaces.Peer.CloudGroup { items.append(ActionSheetTextItem(title: presentationData.strings.GroupInfo_DeleteAndExitConfirmation)) } - items.append(ActionSheetButtonItem(title: presentationData.strings.DialogList_DeleteConversationConfirmation, color: .destructive, action: { + items.append(ActionSheetButtonItem(title: presentationData.strings.Group_LeaveGroup, color: .destructive, action: { dismissAction() let _ = (removePeerChat(postbox: account.postbox, peerId: peerId, reportChatSpam: false) |> deliverOnMainQueue).start(completed: { diff --git a/TelegramUI/ItemListController.swift b/TelegramUI/ItemListController.swift index 4b02f74056..3a009d20f7 100644 --- a/TelegramUI/ItemListController.swift +++ b/TelegramUI/ItemListController.swift @@ -461,4 +461,8 @@ class ItemListController: ViewController { } } } + + func ensureItemNodeVisible(_ itemNode: ListViewItemNode) { + (self.displayNode as! ItemListControllerNode).listNode.ensureItemNodeVisible(itemNode) + } } diff --git a/TelegramUI/ItemListSingleLineInputItem.swift b/TelegramUI/ItemListSingleLineInputItem.swift index a9bc815045..f6aa3b5b25 100644 --- a/TelegramUI/ItemListSingleLineInputItem.swift +++ b/TelegramUI/ItemListSingleLineInputItem.swift @@ -24,9 +24,10 @@ class ItemListSingleLineInputItem: ListViewItem, ItemListItem { let action: () -> Void let textUpdated: (String) -> Void let processPaste: ((String) -> String)? + let receivedFocus: (() -> Void)? let tag: ItemListItemTag? - init(theme: PresentationTheme, title: NSAttributedString, text: String, placeholder: String, type: ItemListSingleLineInputItemType = .regular(capitalization: true, autocorrection: true), returnKeyType: UIReturnKeyType = .`default`, spacing: CGFloat = 0.0, clearButton: Bool = false, tag: ItemListItemTag? = nil, sectionId: ItemListSectionId, textUpdated: @escaping (String) -> Void, processPaste: ((String) -> String)? = nil, action: @escaping () -> Void) { + init(theme: PresentationTheme, title: NSAttributedString, text: String, placeholder: String, type: ItemListSingleLineInputItemType = .regular(capitalization: true, autocorrection: true), returnKeyType: UIReturnKeyType = .`default`, spacing: CGFloat = 0.0, clearButton: Bool = false, tag: ItemListItemTag? = nil, sectionId: ItemListSectionId, textUpdated: @escaping (String) -> Void, processPaste: ((String) -> String)? = nil, receivedFocus: (() -> Void)? = nil, action: @escaping () -> Void) { self.theme = theme self.title = title self.text = text @@ -39,6 +40,7 @@ class ItemListSingleLineInputItem: ListViewItem, ItemListItem { self.sectionId = sectionId self.textUpdated = textUpdated self.processPaste = processPaste + self.receivedFocus = receivedFocus self.action = action } @@ -365,4 +367,8 @@ class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDelegate, It self.item?.action() return false } + + @objc internal func textFieldDidBeginEditing(_ textField: UITextField) { + self.item?.receivedFocus?() + } } diff --git a/TelegramUI/MediaNavigationAccessoryHeaderNode.swift b/TelegramUI/MediaNavigationAccessoryHeaderNode.swift index 0fd345da76..3dfb4e73eb 100644 --- a/TelegramUI/MediaNavigationAccessoryHeaderNode.swift +++ b/TelegramUI/MediaNavigationAccessoryHeaderNode.swift @@ -269,7 +269,7 @@ final class MediaNavigationAccessoryHeaderNode: ASDisplayNode { var titleSideInset: CGFloat = 80.0 if !self.rateButton.isHidden { - titleSideInset += 46.0 + titleSideInset += 52.0 } let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .middle, constrainedSize: CGSize(width: size.width - titleSideInset, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) diff --git a/TelegramUI/MediaPlayerScrubbingNode.swift b/TelegramUI/MediaPlayerScrubbingNode.swift index 81c5467f52..ee30658756 100644 --- a/TelegramUI/MediaPlayerScrubbingNode.swift +++ b/TelegramUI/MediaPlayerScrubbingNode.swift @@ -33,18 +33,18 @@ private final class MediaPlayerScrubbingNodeButton: ASDisplayNode { } @objc func panGesture(_ recognizer: UIPanGestureRecognizer) { + var location = recognizer.location(in: self.view) + location.x -= self.bounds.minX switch recognizer.state { case .began: - self.scrubbingStartLocation = recognizer.location(in: self.view) + self.scrubbingStartLocation = location self.beginScrubbing?() case .changed: - let location = recognizer.location(in: self.view) if let scrubbingStartLocation = self.scrubbingStartLocation { let delta = location.x - scrubbingStartLocation.x self.updateScrubbing?(delta / self.bounds.size.width) } case .ended, .cancelled: - let location = recognizer.location(in: self.view) if let scrubbingStartLocation = self.scrubbingStartLocation { self.scrubbingStartLocation = nil let delta = location.x - scrubbingStartLocation.x @@ -59,12 +59,19 @@ private final class MediaPlayerScrubbingNodeButton: ASDisplayNode { private final class MediaPlayerScrubbingForegroundNode: ASDisplayNode { var onEnterHierarchy: (() -> Void)? + var onExitHierarchy: (() -> Void)? override func willEnterHierarchy() { super.willEnterHierarchy() self.onEnterHierarchy?() } + + override func didExitHierarchy() { + super.didExitHierarchy() + + self.onExitHierarchy?() + } } enum MediaPlayerScrubbingNodeHandle { @@ -171,6 +178,9 @@ private final class MediaPlayerScrubbingBufferingNode: ASDisplayNode { final class MediaPlayerScrubbingNode: ASDisplayNode { private var contentNodes: MediaPlayerScrubbingNodeContentNodes + private var displayLink: CADisplayLink? + private var isInHierarchyValue: Bool = false + private var playbackStatusValue: MediaPlayerPlaybackStatus? private var scrubbingBeginTimestamp: Double? private var scrubbingTimestampValue: Double? @@ -206,7 +216,7 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { if let value = value, value.seekId == self.ignoreSeekId { } else { self._statusValue = value - self.updateProgress() + self.updateProgressAnimations() let playbackStatus = value?.status if self.playbackStatusValue != playbackStatus { @@ -250,70 +260,70 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { private static func contentNodesFromContent(_ content: MediaPlayerScrubbingNodeContent, enableScrubbing: Bool) -> MediaPlayerScrubbingNodeContentNodes { switch content { - case let .standard(lineHeight, lineCap, scrubberHandle, backgroundColor, foregroundColor): - let backgroundNode = ASImageNode() - backgroundNode.isLayerBacked = true - backgroundNode.displaysAsynchronously = false - backgroundNode.displayWithoutProcessing = true - - let bufferingNode = MediaPlayerScrubbingBufferingNode(color: foregroundColor.withAlphaComponent(0.5), lineCap: lineCap, lineHeight: lineHeight) - - let foregroundContentNode = ASImageNode() - foregroundContentNode.isLayerBacked = true - foregroundContentNode.displaysAsynchronously = false - foregroundContentNode.displayWithoutProcessing = true - - switch lineCap { - case .round: - backgroundNode.image = generateStretchableFilledCircleImage(diameter: lineHeight, color: backgroundColor) - foregroundContentNode.image = generateStretchableFilledCircleImage(diameter: lineHeight, color: foregroundColor) - case .square: - backgroundNode.backgroundColor = backgroundColor - foregroundContentNode.backgroundColor = foregroundColor - } - - let foregroundNode = MediaPlayerScrubbingForegroundNode() - foregroundNode.isLayerBacked = true - foregroundNode.clipsToBounds = true - - var handleNodeImpl: ASImageNode? - var handleNodeContainerImpl: MediaPlayerScrubbingNodeButton? - - switch scrubberHandle { - case .none: - break - case .line: - let handleNode = ASImageNode() - handleNode.image = generateHandleBackground(color: foregroundColor) - handleNode.isLayerBacked = true - handleNodeImpl = handleNode + case let .standard(lineHeight, lineCap, scrubberHandle, backgroundColor, foregroundColor): + let backgroundNode = ASImageNode() + backgroundNode.isLayerBacked = true + backgroundNode.displaysAsynchronously = false + backgroundNode.displayWithoutProcessing = true + + let bufferingNode = MediaPlayerScrubbingBufferingNode(color: foregroundColor.withAlphaComponent(0.5), lineCap: lineCap, lineHeight: lineHeight) + + let foregroundContentNode = ASImageNode() + foregroundContentNode.isLayerBacked = true + foregroundContentNode.displaysAsynchronously = false + foregroundContentNode.displayWithoutProcessing = true + + switch lineCap { + case .round: + backgroundNode.image = generateStretchableFilledCircleImage(diameter: lineHeight, color: backgroundColor) + foregroundContentNode.image = generateStretchableFilledCircleImage(diameter: lineHeight, color: foregroundColor) + case .square: + backgroundNode.backgroundColor = backgroundColor + foregroundContentNode.backgroundColor = foregroundColor + } + + let foregroundNode = MediaPlayerScrubbingForegroundNode() + foregroundNode.isLayerBacked = true + foregroundNode.clipsToBounds = true + + var handleNodeImpl: ASImageNode? + var handleNodeContainerImpl: MediaPlayerScrubbingNodeButton? + + switch scrubberHandle { + case .none: + break + case .line: + let handleNode = ASImageNode() + handleNode.image = generateHandleBackground(color: foregroundColor) + handleNode.isLayerBacked = true + handleNodeImpl = handleNode + + let handleNodeContainer = MediaPlayerScrubbingNodeButton() + handleNodeContainer.addSubnode(handleNode) + handleNodeContainerImpl = handleNodeContainer + case .circle: + let handleNode = ASImageNode() + handleNode.image = generateFilledCircleImage(diameter: lineHeight + 4.0, color: foregroundColor) + handleNode.isLayerBacked = true + handleNodeImpl = handleNode + + let handleNodeContainer = MediaPlayerScrubbingNodeButton() + handleNodeContainer.addSubnode(handleNode) + handleNodeContainerImpl = handleNodeContainer + } + + handleNodeContainerImpl?.isUserInteractionEnabled = enableScrubbing + + return .standard(StandardMediaPlayerScrubbingNodeContentNode(lineHeight: lineHeight, lineCap: lineCap, backgroundNode: backgroundNode, bufferingNode: bufferingNode, foregroundContentNode: foregroundContentNode, foregroundNode: foregroundNode, handle: scrubberHandle, handleNode: handleNodeImpl, handleNodeContainer: handleNodeContainerImpl)) + case let .custom(backgroundNode, foregroundContentNode): + let foregroundNode = MediaPlayerScrubbingForegroundNode() + foregroundNode.isLayerBacked = true + foregroundNode.clipsToBounds = true let handleNodeContainer = MediaPlayerScrubbingNodeButton() - handleNodeContainer.addSubnode(handleNode) - handleNodeContainerImpl = handleNodeContainer - case .circle: - let handleNode = ASImageNode() - handleNode.image = generateFilledCircleImage(diameter: lineHeight + 4.0, color: foregroundColor) - handleNode.isLayerBacked = true - handleNodeImpl = handleNode + handleNodeContainer.isUserInteractionEnabled = enableScrubbing - let handleNodeContainer = MediaPlayerScrubbingNodeButton() - handleNodeContainer.addSubnode(handleNode) - handleNodeContainerImpl = handleNodeContainer - } - - handleNodeContainerImpl?.isUserInteractionEnabled = enableScrubbing - - return .standard(StandardMediaPlayerScrubbingNodeContentNode(lineHeight: lineHeight, lineCap: lineCap, backgroundNode: backgroundNode, bufferingNode: bufferingNode, foregroundContentNode: foregroundContentNode, foregroundNode: foregroundNode, handle: scrubberHandle, handleNode: handleNodeImpl, handleNodeContainer: handleNodeContainerImpl)) - case let .custom(backgroundNode, foregroundContentNode): - let foregroundNode = MediaPlayerScrubbingForegroundNode() - foregroundNode.isLayerBacked = true - foregroundNode.clipsToBounds = true - - let handleNodeContainer = MediaPlayerScrubbingNodeButton() - handleNodeContainer.isUserInteractionEnabled = enableScrubbing - - return .custom(CustomMediaPlayerScrubbingNodeContentNode(backgroundNode: backgroundNode, foregroundContentNode: foregroundContentNode, foregroundNode: foregroundNode, handleNodeContainer: handleNodeContainer)) + return .custom(CustomMediaPlayerScrubbingNodeContentNode(backgroundNode: backgroundNode, foregroundContentNode: foregroundContentNode, foregroundNode: foregroundNode, handleNodeContainer: handleNodeContainer)) } } @@ -368,7 +378,7 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { strongSelf.scrubbingBeginTimestamp = statusValue.timestamp strongSelf.scrubbingTimestampValue = statusValue.timestamp strongSelf._scrubbingTimestamp.set(.single(strongSelf.scrubbingTimestampValue)) - strongSelf.updateProgress() + strongSelf.updateProgressAnimations() } } } @@ -377,7 +387,7 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { if let statusValue = strongSelf.statusValue, let scrubbingBeginTimestamp = strongSelf.scrubbingBeginTimestamp, Double(0.0).isLess(than: statusValue.duration) { strongSelf.scrubbingTimestampValue = max(0.0, min(statusValue.duration, scrubbingBeginTimestamp + statusValue.duration * Double(addedFraction))) strongSelf._scrubbingTimestamp.set(.single(strongSelf.scrubbingTimestampValue)) - strongSelf.updateProgress() + strongSelf.updateProgressAnimations() } } } @@ -398,13 +408,18 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { } strongSelf.seek?(scrubbingTimestampValue) } - strongSelf.updateProgress() + strongSelf.updateProgressAnimations() } } } node.foregroundNode.onEnterHierarchy = { [weak self] in - self?.updateProgress() + self?.isInHierarchyValue = true + self?.updateProgressAnimations() + } + node.foregroundNode.onExitHierarchy = { [weak self] in + self?.isInHierarchyValue = false + self?.updateProgressAnimations() } case let .custom(node): self.addSubnode(node.backgroundNode) @@ -418,7 +433,7 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { if let statusValue = strongSelf.statusValue, Double(0.0).isLess(than: statusValue.duration) { strongSelf.scrubbingBeginTimestamp = statusValue.timestamp strongSelf.scrubbingTimestampValue = statusValue.timestamp - strongSelf.updateProgress() + strongSelf.updateProgressAnimations() } } } @@ -426,7 +441,7 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { if let strongSelf = self { if let statusValue = strongSelf.statusValue, let scrubbingBeginTimestamp = strongSelf.scrubbingBeginTimestamp, Double(0.0).isLess(than: statusValue.duration) { strongSelf.scrubbingTimestampValue = scrubbingBeginTimestamp + statusValue.duration * Double(addedFraction) - strongSelf.updateProgress() + strongSelf.updateProgressAnimations() } } } @@ -438,13 +453,18 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { if let scrubbingTimestampValue = scrubbingTimestampValue, apply { strongSelf.seek?(scrubbingTimestampValue) } - strongSelf.updateProgress() + strongSelf.updateProgressAnimations() } } } node.foregroundNode.onEnterHierarchy = { [weak self] in - self?.updateProgress() + self?.isInHierarchyValue = true + self?.updateProgressAnimations() + } + node.foregroundNode.onExitHierarchy = { [weak self] in + self?.isInHierarchyValue = false + self?.updateProgressAnimations() } } } @@ -454,10 +474,11 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { self.setupContentNodes() - self.updateProgress() + self.updateProgressAnimations() } deinit { + self.displayLink?.invalidate() self.statusDisposable?.dispose() self.bufferingStatusDisposable?.dispose() } @@ -465,7 +486,7 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { override var frame: CGRect { didSet { if self.frame.size != oldValue.size { - self.updateProgress() + self.updateProgressAnimations() } } } @@ -489,32 +510,76 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { } } - private func preparedAnimation(keyPath: String, from: NSValue, to: NSValue, duration: Double, beginTime: Double?, offset: Double, speed: Float, repeatForever: Bool = false) -> CAAnimation { - let animation = CABasicAnimation(keyPath: keyPath) - animation.fromValue = from - animation.toValue = to - animation.duration = duration - animation.fillMode = kCAFillModeBoth - animation.speed = speed - animation.timeOffset = offset - animation.isAdditive = false - if let beginTime = beginTime { - animation.beginTime = beginTime + private func updateProgressAnimations() { + self.updateProgress() + + let needsAnimation: Bool + + if !self.isInHierarchyValue { + needsAnimation = false + } else if let _ = scrubbingTimestampValue { + needsAnimation = false + } else if let statusValue = self.statusValue { + if case .buffering(true, _) = statusValue.status { + needsAnimation = false + } else if Double(0.0).isLess(than: statusValue.duration) { + needsAnimation = true + } else { + needsAnimation = false + } + } else { + needsAnimation = false + } + + if needsAnimation { + if self.displayLink == nil { + class DisplayLinkProxy: NSObject { + var f: () -> Void + init(_ f: @escaping () -> Void) { + self.f = f + } + + @objc func displayLinkEvent() { + self.f() + } + } + let displayLink = CADisplayLink(target: DisplayLinkProxy({ [weak self] in + self?.updateProgress() + }), selector: #selector(DisplayLinkProxy.displayLinkEvent)) + displayLink.add(to: .main, forMode: .commonModes) + self.displayLink = displayLink + } + self.displayLink?.isPaused = false + } else { + self.displayLink?.isPaused = true } - return animation } private func updateProgress() { let bounds = self.bounds + var isPlaying = false + var timestampAndDuration: (timestamp: Double, duration: Double)? + if let statusValue = self.statusValue { + switch statusValue.status { + case .playing: + isPlaying = true + default: + break + } + if case .buffering(true, _) = statusValue.status { + //initialBuffering = true + } else if Double(0.0).isLess(than: statusValue.duration) { + if let scrubbingTimestampValue = self.scrubbingTimestampValue { + timestampAndDuration = (max(0.0, min(scrubbingTimestampValue, statusValue.duration)), statusValue.duration) + } else { + timestampAndDuration = (statusValue.timestamp, statusValue.duration) + } + } + } + switch self.contentNodes { case let .standard(node): - node.foregroundNode.layer.removeAnimation(forKey: "playback-bounds") - node.foregroundNode.layer.removeAnimation(forKey: "playback-position") - if let handleNodeContainer = node.handleNodeContainer { - handleNodeContainer.layer.removeAnimation(forKey: "playback-bounds") - } - let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: floor((bounds.size.height - node.lineHeight) / 2.0)), size: CGSize(width: bounds.size.width, height: node.lineHeight)) node.backgroundNode.frame = backgroundFrame node.foregroundContentNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: backgroundFrame.size.width, height: backgroundFrame.size.height)) @@ -524,107 +589,47 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { if let handleNode = node.handleNode { var handleSize: CGSize = CGSize(width: 2.0, height: bounds.size.height) - if case .circle = node.handle, let handleNode = handleNode as? ASImageNode, let image = handleNode.image { handleSize = image.size } handleNode.frame = CGRect(origin: CGPoint(x: 0.0, y: floor((bounds.size.height - handleSize.height) / 2.0)), size: handleSize) - handleNode.layer.removeAnimation(forKey: "playback-position") } if let handleNodeContainer = node.handleNodeContainer { handleNodeContainer.frame = bounds } - var initialBuffering = false - var timestampAndDuration: (timestamp: Double, duration: Double)? - if let statusValue = self.statusValue { - if case .buffering(true, _) = statusValue.status { - initialBuffering = true - } else if Double(0.0).isLess(than: statusValue.duration) { - if let scrubbingTimestampValue = self.scrubbingTimestampValue { - timestampAndDuration = (max(0.0, min(scrubbingTimestampValue, statusValue.duration)), statusValue.duration) - } else { - timestampAndDuration = (statusValue.timestamp, statusValue.duration) - } - } - } - if let (timestamp, duration) = timestampAndDuration { - let progress = CGFloat(timestamp / duration) - if let _ = scrubbingTimestampValue { - let fromRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: 0.0, height: backgroundFrame.size.height)) - let toRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: backgroundFrame.size.width, height: backgroundFrame.size.height)) - - let fromBounds = CGRect(origin: CGPoint(), size: fromRect.size) - let toBounds = CGRect(origin: CGPoint(), size: toRect.size) - - node.foregroundNode.frame = toRect - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "bounds", from: NSValue(cgRect: fromBounds), to: NSValue(cgRect: toBounds), duration: duration, beginTime: nil, offset: timestamp, speed: 0.0), forKey: "playback-bounds") - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "position", from: NSValue(cgPoint: CGPoint(x: fromRect.midX, y: fromRect.midY)), to: NSValue(cgPoint: CGPoint(x: toRect.midX, y: toRect.midY)), duration: duration, beginTime: nil, offset: timestamp, speed: 0.0), forKey: "playback-position") + if let scrubbingTimestampValue = scrubbingTimestampValue { + var progress = CGFloat(scrubbingTimestampValue / duration) + if progress.isNaN || !progress.isFinite { + progress = 0.0 + } + progress = min(1.0, progress) + node.foregroundNode.frame = CGRect(origin: backgroundFrame.origin, size: CGSize(width: floorToScreenPixels(progress * backgroundFrame.size.width), height: backgroundFrame.size.height)) if let handleNodeContainer = node.handleNodeContainer { - let fromBounds = bounds - let toBounds = bounds.offsetBy(dx: -bounds.size.width, dy: 0.0) - + handleNodeContainer.bounds = bounds.offsetBy(dx: -floorToScreenPixels(bounds.size.width * progress), dy: 0.0) handleNodeContainer.isHidden = false - handleNodeContainer.layer.add(self.preparedAnimation(keyPath: "bounds", from: NSValue(cgRect: fromBounds), to: NSValue(cgRect: toBounds), duration: duration, beginTime: nil, offset: timestamp, speed: 0.0), forKey: "playback-bounds") } - - if let handleNode = node.handleNode { - let fromPosition = handleNode.position - let toPosition = CGPoint(x: fromPosition.x - 1.0, y: fromPosition.y) - handleNode.layer.add(self.preparedAnimation(keyPath: "position", from: NSValue(cgPoint: fromPosition), to: NSValue(cgPoint: toPosition), duration: duration / Double(bounds.size.width), beginTime: nil, offset: timestamp, speed: 0.0, repeatForever: true), forKey: "playback-position") - } - } else if let statusValue = self.statusValue, !progress.isNaN && progress.isFinite { - if statusValue.generationTimestamp.isZero { - let fromRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: 0.0, height: backgroundFrame.size.height)) - let toRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: backgroundFrame.size.width, height: backgroundFrame.size.height)) - - let fromBounds = CGRect(origin: CGPoint(), size: fromRect.size) - let toBounds = CGRect(origin: CGPoint(), size: toRect.size) - - node.foregroundNode.frame = toRect - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "bounds", from: NSValue(cgRect: fromBounds), to: NSValue(cgRect: toBounds), duration: duration, beginTime: nil, offset: timestamp, speed: 0.0), forKey: "playback-bounds") - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "position", from: NSValue(cgPoint: CGPoint(x: fromRect.midX, y: fromRect.midY)), to: NSValue(cgPoint: CGPoint(x: toRect.midX, y: toRect.midY)), duration: duration, beginTime: nil, offset: timestamp, speed: 0.0), forKey: "playback-position") - - if let handleNodeContainer = node.handleNodeContainer { - let fromBounds = bounds - let toBounds = bounds.offsetBy(dx: -bounds.size.width, dy: 0.0) - - handleNodeContainer.isHidden = false - handleNodeContainer.layer.add(self.preparedAnimation(keyPath: "bounds", from: NSValue(cgRect: fromBounds), to: NSValue(cgRect: toBounds), duration: duration, beginTime: nil, offset: timestamp, speed: 0.0), forKey: "playback-bounds") - } - - if let handleNode = node.handleNode { - let fromPosition = handleNode.position - let toPosition = CGPoint(x: fromPosition.x - 1.0, y: fromPosition.y) - handleNode.layer.add(self.preparedAnimation(keyPath: "position", from: NSValue(cgPoint: fromPosition), to: NSValue(cgPoint: toPosition), duration: duration / Double(bounds.size.width), beginTime: nil, offset: timestamp, speed: 0.0, repeatForever: true), forKey: "playback-position") - } + } else if let statusValue = self.statusValue { + let actualTimestamp: Double + if statusValue.generationTimestamp.isZero || !isPlaying { + actualTimestamp = timestamp } else { - let fromRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: 0.0, height: backgroundFrame.size.height)) - let toRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: backgroundFrame.size.width, height: backgroundFrame.size.height)) - - let fromBounds = CGRect(origin: CGPoint(), size: fromRect.size) - let toBounds = CGRect(origin: CGPoint(), size: toRect.size) - - node.foregroundNode.frame = toRect - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "bounds", from: NSValue(cgRect: fromBounds), to: NSValue(cgRect: toBounds), duration: duration, beginTime: statusValue.generationTimestamp, offset: timestamp, speed: statusValue.status == .playing ? Float(statusValue.baseRate) : 0.0), forKey: "playback-bounds") - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "position", from: NSValue(cgPoint: CGPoint(x: fromRect.midX, y: fromRect.midY)), to: NSValue(cgPoint: CGPoint(x: toRect.midX, y: toRect.midY)), duration: duration, beginTime: statusValue.generationTimestamp, offset: timestamp, speed: statusValue.status == .playing ? Float(statusValue.baseRate) : 0.0), forKey: "playback-position") - - if let handleNodeContainer = node.handleNodeContainer { - let fromBounds = bounds - let toBounds = bounds.offsetBy(dx: -bounds.size.width, dy: 0.0) - - handleNodeContainer.isHidden = false - handleNodeContainer.layer.add(self.preparedAnimation(keyPath: "bounds", from: NSValue(cgRect: fromBounds), to: NSValue(cgRect: toBounds), duration: statusValue.duration, beginTime: statusValue.generationTimestamp, offset: statusValue.timestamp, speed: statusValue.status == .playing ? Float(statusValue.baseRate) : 0.0), forKey: "playback-bounds") - } - - if let handleNode = node.handleNode { - let fromPosition = handleNode.position - let toPosition = CGPoint(x: fromPosition.x - 1.0, y: fromPosition.y) - handleNode.layer.add(self.preparedAnimation(keyPath: "position", from: NSValue(cgPoint: fromPosition), to: NSValue(cgPoint: toPosition), duration: duration / Double(bounds.size.width), beginTime: statusValue.generationTimestamp, offset: timestamp, speed: statusValue.status == .playing ? Float(statusValue.baseRate) : 0.0, repeatForever: true), forKey: "playback-position") - } + let currentTimestamp = CACurrentMediaTime() + actualTimestamp = timestamp + (currentTimestamp - statusValue.generationTimestamp) * statusValue.baseRate + } + var progress = CGFloat(actualTimestamp / duration) + if progress.isNaN || !progress.isFinite { + progress = 0.0 + } + progress = min(1.0, progress) + node.foregroundNode.frame = CGRect(origin: backgroundFrame.origin, size: CGSize(width: floorToScreenPixels(progress * backgroundFrame.size.width), height: backgroundFrame.size.height)) + + if let handleNodeContainer = node.handleNodeContainer { + handleNodeContainer.bounds = bounds.offsetBy(dx: -floorToScreenPixels(bounds.size.width * progress), dy: 0.0) + handleNodeContainer.isHidden = false } } else { node.handleNodeContainer?.isHidden = true @@ -634,20 +639,11 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { node.foregroundNode.frame = CGRect(origin: backgroundFrame.origin, size: CGSize(width: 0.0, height: backgroundFrame.size.height)) node.handleNodeContainer?.isHidden = true } - - if initialBuffering { - - } else { - - } case let .custom(node): if let handleNodeContainer = node.handleNodeContainer { handleNodeContainer.frame = bounds } - node.foregroundNode.layer.removeAnimation(forKey: "playback-bounds") - node.foregroundNode.layer.removeAnimation(forKey: "playback-position") - let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: bounds.size.width, height: bounds.size.height)) node.backgroundNode.frame = backgroundFrame node.foregroundContentNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: backgroundFrame.size.width, height: backgroundFrame.size.height)) @@ -664,39 +660,27 @@ final class MediaPlayerScrubbingNode: ASDisplayNode { } if let (timestamp, duration) = timestampAndDuration { - let progress = CGFloat(timestamp / duration) - if let _ = scrubbingTimestampValue { - let fromRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: 0.0, height: backgroundFrame.size.height)) - let toRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: backgroundFrame.size.width, height: backgroundFrame.size.height)) - - let fromBounds = CGRect(origin: CGPoint(), size: fromRect.size) - let toBounds = CGRect(origin: CGPoint(), size: toRect.size) - - node.foregroundNode.frame = toRect - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "bounds", from: NSValue(cgRect: fromBounds), to: NSValue(cgRect: toBounds), duration: duration, beginTime: nil, offset: timestamp, speed: 0.0), forKey: "playback-bounds") - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "position", from: NSValue(cgPoint: CGPoint(x: fromRect.midX, y: fromRect.midY)), to: NSValue(cgPoint: CGPoint(x: toRect.midX, y: toRect.midY)), duration: duration, beginTime: nil, offset: timestamp, speed: 0.0), forKey: "playback-position") - } else if let statusValue = self.statusValue, !progress.isNaN && progress.isFinite { - if statusValue.generationTimestamp.isZero { - let fromRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: 0.0, height: backgroundFrame.size.height)) - let toRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: backgroundFrame.size.width, height: backgroundFrame.size.height)) - - let fromBounds = CGRect(origin: CGPoint(), size: fromRect.size) - let toBounds = CGRect(origin: CGPoint(), size: toRect.size) - - node.foregroundNode.frame = toRect - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "bounds", from: NSValue(cgRect: fromBounds), to: NSValue(cgRect: toBounds), duration: duration, beginTime: nil, offset: timestamp, speed: 0.0), forKey: "playback-bounds") - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "position", from: NSValue(cgPoint: CGPoint(x: fromRect.midX, y: fromRect.midY)), to: NSValue(cgPoint: CGPoint(x: toRect.midX, y: toRect.midY)), duration: duration, beginTime: nil, offset: timestamp, speed: 0.0), forKey: "playback-position") - } else { - let fromRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: 0.0, height: backgroundFrame.size.height)) - let toRect = CGRect(origin: backgroundFrame.origin, size: CGSize(width: backgroundFrame.size.width, height: backgroundFrame.size.height)) - - let fromBounds = CGRect(origin: CGPoint(), size: fromRect.size) - let toBounds = CGRect(origin: CGPoint(), size: toRect.size) - - node.foregroundNode.frame = toRect - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "bounds", from: NSValue(cgRect: fromBounds), to: NSValue(cgRect: toBounds), duration: duration, beginTime: statusValue.generationTimestamp, offset: timestamp, speed: statusValue.status == .playing ? Float(statusValue.baseRate) : 0.0), forKey: "playback-bounds") - node.foregroundNode.layer.add(self.preparedAnimation(keyPath: "position", from: NSValue(cgPoint: CGPoint(x: fromRect.midX, y: fromRect.midY)), to: NSValue(cgPoint: CGPoint(x: toRect.midX, y: toRect.midY)), duration: duration, beginTime: statusValue.generationTimestamp, offset: timestamp, speed: statusValue.status == .playing ? Float(statusValue.baseRate) : 0.0), forKey: "playback-position") + if let scrubbingTimestampValue = scrubbingTimestampValue { + var progress = CGFloat(scrubbingTimestampValue / duration) + if progress.isNaN || !progress.isFinite { + progress = 0.0 } + progress = min(1.0, progress) + node.foregroundNode.frame = CGRect(origin: backgroundFrame.origin, size: CGSize(width: floorToScreenPixels(progress * backgroundFrame.size.width), height: backgroundFrame.size.height)) + } else if let statusValue = self.statusValue { + let actualTimestamp: Double + if statusValue.generationTimestamp.isZero || !isPlaying { + actualTimestamp = timestamp + } else { + let currentTimestamp = CACurrentMediaTime() + actualTimestamp = timestamp + (currentTimestamp - statusValue.generationTimestamp) * statusValue.baseRate + } + var progress = CGFloat(actualTimestamp / duration) + if progress.isNaN || !progress.isFinite { + progress = 0.0 + } + progress = min(1.0, progress) + node.foregroundNode.frame = CGRect(origin: backgroundFrame.origin, size: CGSize(width: floorToScreenPixels(progress * backgroundFrame.size.width), height: backgroundFrame.size.height)) } else { node.foregroundNode.frame = CGRect(origin: backgroundFrame.origin, size: CGSize(width: 0.0, height: backgroundFrame.size.height)) } diff --git a/TelegramUI/MediaPlayerTimeTextNode.swift b/TelegramUI/MediaPlayerTimeTextNode.swift index 202338c942..87ac345c32 100644 --- a/TelegramUI/MediaPlayerTimeTextNode.swift +++ b/TelegramUI/MediaPlayerTimeTextNode.swift @@ -55,7 +55,11 @@ final class MediaPlayerTimeTextNode: ASDisplayNode { var alignment: NSTextAlignment = .left var mode: MediaPlayerTimeTextNodeMode = .normal private let textColor: UIColor - var defaultDuration: Double? + var defaultDuration: Double? { + didSet { + self.updateTimestamp() + } + } private var updateTimer: SwiftSignalKit.Timer? diff --git a/TelegramUI/PeerMediaCollectionControllerNode.swift b/TelegramUI/PeerMediaCollectionControllerNode.swift index 9cc6f4f116..4dbbe91011 100644 --- a/TelegramUI/PeerMediaCollectionControllerNode.swift +++ b/TelegramUI/PeerMediaCollectionControllerNode.swift @@ -219,6 +219,11 @@ class PeerMediaCollectionControllerNode: ASDisplayNode { var sectionOffset: CGFloat = 0.0 if primaryNavigationBarHeight.isZero { sectionOffset = -sectionsHeight - navigationBarHeightDelta + } else { + //layout.statusBarHeight ?? 0.0 + if navigationBarHeightAndPrimaryHeight.0 > navigationBarHeightAndPrimaryHeight.1 { + sectionOffset += 1.0 + } } transition.updateFrame(node: self.sectionsNode, frame: CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight + sectionOffset), size: CGSize(width: layout.size.width, height: sectionsHeight))) diff --git a/TelegramUI/PhotoResources.swift b/TelegramUI/PhotoResources.swift index dda90d78f3..a58417bf73 100644 --- a/TelegramUI/PhotoResources.swift +++ b/TelegramUI/PhotoResources.swift @@ -1280,7 +1280,6 @@ func mediaGridMessagePhoto(account: Account, photoReference: ImageMediaReference return signal |> map { (thumbnailData, fullSizeData, fullSizeComplete) in return { arguments in - assertNotOnMainThread() let context = DrawingContext(size: arguments.drawingSize, clear: true) let drawingRect = arguments.drawingRect diff --git a/TelegramUI/SaveToCameraRoll.swift b/TelegramUI/SaveToCameraRoll.swift index a23648ed6f..33adefdded 100644 --- a/TelegramUI/SaveToCameraRoll.swift +++ b/TelegramUI/SaveToCameraRoll.swift @@ -6,7 +6,12 @@ import TelegramCore import Photos import Display -func saveToCameraRoll(applicationContext: TelegramApplicationContext, postbox: Postbox, mediaReference: AnyMediaReference) -> Signal { +private enum SaveToCameraRollState { + case progress(Float) + case data(MediaResourceData) +} + +func saveToCameraRoll(applicationContext: TelegramApplicationContext, postbox: Postbox, mediaReference: AnyMediaReference) -> Signal { var resource: MediaResource? var isImage = true var fileExtension: String? @@ -37,67 +42,80 @@ func saveToCameraRoll(applicationContext: TelegramApplicationContext, postbox: P } if let resource = resource { - let fetchedData: Signal = Signal { subscriber in + let fetchedData: Signal = Signal { subscriber in let fetched = fetchedMediaResource(postbox: postbox, reference: mediaReference.resourceReference(resource)).start() + let status = postbox.mediaBox.resourceStatus(resource).start(next: { status in + switch status { + case .Local: + subscriber.putNext(.progress(1.0)) + case .Remote: + subscriber.putNext(.progress(0.0)) + case let .Fetching(_, progress): + subscriber.putNext(.progress(progress)) + } + }) let data = postbox.mediaBox.resourceData(resource, pathExtension: fileExtension, option: .complete(waitUntilFetchStatus: true)).start(next: { next in - subscriber.putNext(next) + subscriber.putNext(.data(next)) }, completed: { subscriber.putCompletion() }) return ActionDisposable { fetched.dispose() + status.dispose() data.dispose() } } return fetchedData - |> mapToSignal { data -> Signal in - if data.complete { - return Signal { subscriber in - DeviceAccess.authorizeAccess(to: .mediaLibrary(.save), presentationData: applicationContext.currentPresentationData.with { $0 }, present: { c, a in - applicationContext.presentGlobalController(c, a) - }, openSettings: applicationContext.applicationBindings.openSettings, { authorized in - if !authorized { - subscriber.putCompletion() - return - } - - let tempVideoPath = NSTemporaryDirectory() + "\(arc4random64()).mp4" - PHPhotoLibrary.shared().performChanges({ - if isImage { - if let fileData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) { - if #available(iOSApplicationExtension 9.0, *) { - PHAssetCreationRequest.forAsset().addResource(with: .photo, data: fileData, options: nil) + |> mapToSignal { state -> Signal in + switch state { + case let .progress(value): + return .single(value) + case let .data(data): + if data.complete { + return Signal { subscriber in + DeviceAccess.authorizeAccess(to: .mediaLibrary(.save), presentationData: applicationContext.currentPresentationData.with { $0 }, present: { c, a in + applicationContext.presentGlobalController(c, a) + }, openSettings: applicationContext.applicationBindings.openSettings, { authorized in + if !authorized { + subscriber.putCompletion() + return + } + + let tempVideoPath = NSTemporaryDirectory() + "\(arc4random64()).mp4" + PHPhotoLibrary.shared().performChanges({ + if isImage { + if let fileData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) { + if #available(iOSApplicationExtension 9.0, *) { + PHAssetCreationRequest.forAsset().addResource(with: .photo, data: fileData, options: nil) + } else { + if let image = UIImage(data: fileData) { + PHAssetChangeRequest.creationRequestForAsset(from: image) + } + } + } } else { - if let image = UIImage(data: fileData) { - PHAssetChangeRequest.creationRequestForAsset(from: image) + if let _ = try? FileManager.default.copyItem(atPath: data.path, toPath: tempVideoPath) { + PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: URL(fileURLWithPath: tempVideoPath)) } } - } - } else { - if let _ = try? FileManager.default.copyItem(atPath: data.path, toPath: tempVideoPath) { - PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: URL(fileURLWithPath: tempVideoPath)) - } + }, completionHandler: { _, error in + if let error = error { + print("\(error)") + } + let _ = try? FileManager.default.removeItem(atPath: tempVideoPath) + subscriber.putNext(1.0) + subscriber.putCompletion() + }) + }) + + return ActionDisposable { } - }, completionHandler: { _, error in - if let error = error { - print("\(error)") - } - let _ = try? FileManager.default.removeItem(atPath: tempVideoPath) - subscriber.putNext(Void()) - subscriber.putCompletion() - }) - }) - - return ActionDisposable { + } + } else { + return .complete() } - } - } else { - return .complete() } } - |> take(1) - |> mapToSignal { _ -> Signal in return .complete() - } } else { return .complete() } diff --git a/TelegramUI/ShareController.swift b/TelegramUI/ShareController.swift index 2e2c48973a..f9ee8ae072 100644 --- a/TelegramUI/ShareController.swift +++ b/TelegramUI/ShareController.swift @@ -531,7 +531,7 @@ public final class ShareController: ViewController { private func saveToCameraRoll(messages: [Message]) { let postbox = self.account.postbox - let signals: [Signal] = messages.compactMap { message -> Signal? in + let signals: [Signal] = messages.compactMap { message -> Signal? in if let media = message.media.first { return TelegramUI.saveToCameraRoll(applicationContext: self.account.telegramApplicationContext, postbox: postbox, mediaReference: .message(message: MessageReference(message), media: media)) } else { @@ -539,16 +539,25 @@ public final class ShareController: ViewController { } } if !signals.isEmpty { - self.controllerNode.transitionToProgress(signal: combineLatest(signals) |> mapToSignal { _ -> Signal in return .complete() }) + let total = combineLatest(signals) + |> map { values -> Float? in + var total: Float = 0.0 + for value in values { + total += value + } + total /= Float(values.count) + return total + } + self.controllerNode.transitionToProgressWithValue(signal: total) } } private func saveToCameraRoll(representations: [ImageRepresentationWithReference]) { let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations.map({ $0.representation }), reference: nil, partialReference: nil) - self.controllerNode.transitionToProgress(signal: TelegramUI.saveToCameraRoll(applicationContext: self.account.telegramApplicationContext, postbox: self.account.postbox, mediaReference: .standalone(media: media))) + self.controllerNode.transitionToProgressWithValue(signal: TelegramUI.saveToCameraRoll(applicationContext: self.account.telegramApplicationContext, postbox: self.account.postbox, mediaReference: .standalone(media: media)) |> map(Optional.init)) } private func saveToCameraRoll(mediaReference: AnyMediaReference) { - self.controllerNode.transitionToProgress(signal: TelegramUI.saveToCameraRoll(applicationContext: self.account.telegramApplicationContext, postbox: self.account.postbox, mediaReference: mediaReference)) + self.controllerNode.transitionToProgressWithValue(signal: TelegramUI.saveToCameraRoll(applicationContext: self.account.telegramApplicationContext, postbox: self.account.postbox, mediaReference: mediaReference) |> map(Optional.init)) } } diff --git a/TelegramUI/ShareControllerNode.swift b/TelegramUI/ShareControllerNode.swift index 321f47cb8a..622baf16eb 100644 --- a/TelegramUI/ShareControllerNode.swift +++ b/TelegramUI/ShareControllerNode.swift @@ -702,4 +702,47 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate }) })) } + + func transitionToProgressWithValue(signal: Signal) { + self.inputFieldNode.deactivateInput() + let transition = ContainedViewLayoutTransition.animated(duration: 0.12, curve: .easeInOut) + transition.updateAlpha(node: self.actionButtonNode, alpha: 0.0) + transition.updateAlpha(node: self.inputFieldNode, alpha: 0.0) + transition.updateAlpha(node: self.actionSeparatorNode, alpha: 0.0) + transition.updateAlpha(node: self.actionsBackgroundNode, alpha: 0.0) + + self.transitionToContentNode(ShareLoadingContainerNode(theme: self.presentationData.theme, forceNativeAppearance: true), fastOut: true) + + let timestamp = CACurrentMediaTime() + var wasDone = false + let doneImpl: (Bool) -> Void = { [weak self] shouldDelay in + let minDelay: Double = shouldDelay ? 0.9 : 0.6 + let delay = max(minDelay, (timestamp + minDelay) - CACurrentMediaTime()) + Queue.mainQueue().after(delay, { + if let strongSelf = self { + strongSelf.animateOut(shared: true) + } + }) + } + self.shareDisposable.set((signal + |> deliverOnMainQueue).start(next: { [weak self] status in + guard let strongSelf = self, let contentNode = strongSelf.contentNode as? ShareLoadingContainerNode else { + return + } + if let status = status { + contentNode.state = .progress(status) + } else { + + } + }, completed: { [weak self] in + guard let strongSelf = self, let contentNode = strongSelf.contentNode as? ShareLoadingContainerNode else { + return + } + contentNode.state = .done + if !wasDone { + wasDone = true + doneImpl(true) + } + })) + } } diff --git a/TelegramUI/TelegramController.swift b/TelegramUI/TelegramController.swift index 1a5e0f2235..56c2eebd98 100644 --- a/TelegramUI/TelegramController.swift +++ b/TelegramUI/TelegramController.swift @@ -71,6 +71,7 @@ public class TelegramController: ViewController { private var presentationData: PresentationData private var presentationDataDisposable: Disposable? + private var playlistPreloadDisposable: Disposable? override public var navigationHeight: CGFloat { var height = super.navigationHeight @@ -223,6 +224,7 @@ public class TelegramController: ViewController { self.mediaStatusDisposable?.dispose() self.locationBroadcastDisposable?.dispose() self.presentationDataDisposable?.dispose() + self.playlistPreloadDisposable?.dispose() } required public init(coder aDecoder: NSCoder) { @@ -478,15 +480,77 @@ public class TelegramController: ViewController { } } mediaAccessoryPanel.tapAction = { [weak self] in - if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController, let (state, order, type) = strongSelf.playlistStateAndType { - if let id = state.id as? PeerMessagesMediaPlaylistItemId { - if type == .music { - let controller = OverlayPlayerController(account: strongSelf.account, peerId: id.messageId.peerId, type: type, initialMessageId: id.messageId, initialOrder: order, parentNavigationController: strongSelf.navigationController as? NavigationController) - strongSelf.displayNode.view.window?.endEditing(true) - strongSelf.present(controller, in: .window(.root)) - } else { - navigateToChatController(navigationController: navigationController, account: strongSelf.account, chatLocation: .peer(id.messageId.peerId), messageId: id.messageId) + guard let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController, let (state, order, type) = strongSelf.playlistStateAndType else { + return + } + if let id = state.id as? PeerMessagesMediaPlaylistItemId { + if type == .music { + let historyView = chatHistoryViewForLocation(.InitialSearch(location: .id(id.messageId), count: 60), account: strongSelf.account, chatLocation: .peer(id.messageId.peerId), fixedCombinedReadStates: nil, tagMask: MessageTags.music, additionalData: []) + let signal = historyView + |> mapToSignal { historyView -> Signal<(MessageIndex?, Bool), NoError> in + switch historyView { + case .Loading: + return .single((nil, true)) + case let .HistoryView(view, _, _, _, _): + for entry in view.entries { + if case let .MessageEntry(message, _, _, _) = entry { + if message.id == id.messageId { + return .single((MessageIndex(message), false)) + } + } + } + return .single((nil, false)) + } } + |> take(until: { index in + return SignalTakeAction(passthrough: true, complete: !index.1) + }) + + var cancelImpl: (() -> Void)? + let presentationData = strongSelf.account.telegramApplicationContext.currentPresentationData.with { $0 } + let progressSignal = Signal { subscriber in + let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: { + cancelImpl?() + })) + self?.present(controller, in: .window(.root)) + return ActionDisposable { [weak controller] in + Queue.mainQueue().async() { + controller?.dismiss() + } + } + } + |> runOn(Queue.mainQueue()) + |> delay(0.15, queue: Queue.mainQueue()) + let progressDisposable = MetaDisposable() + var progressStarted = false + strongSelf.playlistPreloadDisposable?.dispose() + strongSelf.playlistPreloadDisposable = (signal + |> afterDisposed { + Queue.mainQueue().async { + progressDisposable.dispose() + } + } + |> deliverOnMainQueue).start(next: { index in + guard let strongSelf = self else { + return + } + if let _ = index.0 { + let controller = OverlayPlayerController(account: strongSelf.account, peerId: id.messageId.peerId, type: type, initialMessageId: id.messageId, initialOrder: order, parentNavigationController: strongSelf.navigationController as? NavigationController) + strongSelf.displayNode.view.window?.endEditing(true) + strongSelf.present(controller, in: .window(.root)) + } else if index.1 { + if !progressStarted { + progressStarted = true + progressDisposable.set(progressSignal.start()) + } + } + }, completed: { + }) + cancelImpl = { + self?.playlistPreloadDisposable?.dispose() + } + } else { + navigateToChatController(navigationController: navigationController, account: strongSelf.account, chatLocation: .peer(id.messageId.peerId), messageId: id.messageId) } } } diff --git a/third-party/FFmpeg-iOS/include/libavcodec/ac3_parser.h b/third-party/FFmpeg-iOS/include/libavcodec/ac3_parser.h new file mode 100644 index 0000000000..ff8cc4cf09 --- /dev/null +++ b/third-party/FFmpeg-iOS/include/libavcodec/ac3_parser.h @@ -0,0 +1,36 @@ +/* + * AC-3 parser prototypes + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AC3_PARSER_H +#define AVCODEC_AC3_PARSER_H + +#include +#include + +/** + * Extract the bitstream ID and the frame size from AC-3 data. + */ +int av_ac3_parse_header(const uint8_t *buf, size_t size, + uint8_t *bitstream_id, uint16_t *frame_size); + + +#endif /* AVCODEC_AC3_PARSER_H */ diff --git a/third-party/FFmpeg-iOS/include/libavcodec/adts_parser.h b/third-party/FFmpeg-iOS/include/libavcodec/adts_parser.h new file mode 100644 index 0000000000..f85becd131 --- /dev/null +++ b/third-party/FFmpeg-iOS/include/libavcodec/adts_parser.h @@ -0,0 +1,37 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_ADTS_PARSER_H +#define AVCODEC_ADTS_PARSER_H + +#include +#include + +#define AV_AAC_ADTS_HEADER_SIZE 7 + +/** + * Extract the number of samples and frames from AAC data. + * @param[in] buf pointer to AAC data buffer + * @param[out] samples Pointer to where number of samples is written + * @param[out] frames Pointer to where number of frames is written + * @return Returns 0 on success, error code on failure. + */ +int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, + uint8_t *frames); + +#endif /* AVCODEC_ADTS_PARSER_H */ diff --git a/third-party/FFmpeg-iOS/include/libavcodec/avcodec.h b/third-party/FFmpeg-iOS/include/libavcodec/avcodec.h index 7e60333cb6..2fec61908a 100644 --- a/third-party/FFmpeg-iOS/include/libavcodec/avcodec.h +++ b/third-party/FFmpeg-iOS/include/libavcodec/avcodec.h @@ -36,6 +36,7 @@ #include "../libavutil/channel_layout.h" #include "../libavutil/dict.h" #include "../libavutil/frame.h" +#include "../libavutil/hwcontext.h" #include "../libavutil/log.h" #include "../libavutil/pixfmt.h" #include "../libavutil/rational.h" @@ -217,9 +218,6 @@ enum AVCodecID { /* video codecs */ AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding -#if FF_API_XVMC - AV_CODEC_ID_MPEG2VIDEO_XVMC, -#endif /* FF_API_XVMC */ AV_CODEC_ID_H261, AV_CODEC_ID_H263, AV_CODEC_ID_RV10, @@ -411,6 +409,7 @@ enum AVCodecID { AV_CODEC_ID_DXV, AV_CODEC_ID_SCREENPRESSO, AV_CODEC_ID_RSCC, + AV_CODEC_ID_AVS2, AV_CODEC_ID_Y41P = 0x8000, AV_CODEC_ID_AVRP, @@ -448,6 +447,11 @@ enum AVCodecID { AV_CODEC_ID_SVG, AV_CODEC_ID_GDV, AV_CODEC_ID_FITS, + AV_CODEC_ID_IMM4, + AV_CODEC_ID_PROSUMER, + AV_CODEC_ID_MWSC, + AV_CODEC_ID_WCMV, + AV_CODEC_ID_RASC, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs @@ -487,6 +491,7 @@ enum AVCodecID { AV_CODEC_ID_PCM_S64BE, AV_CODEC_ID_PCM_F16LE, AV_CODEC_ID_PCM_F24LE, + AV_CODEC_ID_PCM_VIDC, /* various ADPCM codecs */ AV_CODEC_ID_ADPCM_IMA_QT = 0x11000, @@ -520,9 +525,6 @@ enum AVCodecID { AV_CODEC_ID_ADPCM_G722, AV_CODEC_ID_ADPCM_IMA_APC, AV_CODEC_ID_ADPCM_VIMA, -#if FF_API_VIMA_DECODER - AV_CODEC_ID_VIMA = AV_CODEC_ID_ADPCM_VIMA, -#endif AV_CODEC_ID_ADPCM_AFC = 0x11800, AV_CODEC_ID_ADPCM_IMA_OKI, @@ -585,9 +587,6 @@ enum AVCodecID { AV_CODEC_ID_MLP, AV_CODEC_ID_GSM_MS, /* as found in WAV */ AV_CODEC_ID_ATRAC3, -#if FF_API_VOXWARE - AV_CODEC_ID_VOXWARE, -#endif AV_CODEC_ID_APE, AV_CODEC_ID_NELLYMOSER, AV_CODEC_ID_MUSEPACK8, @@ -623,6 +622,7 @@ enum AVCodecID { AV_CODEC_ID_PAF_AUDIO, AV_CODEC_ID_ON2AVC, AV_CODEC_ID_DSS_SP, + AV_CODEC_ID_CODEC2, AV_CODEC_ID_FFWAVESYNTH = 0x15800, AV_CODEC_ID_SONIC, @@ -641,6 +641,10 @@ enum AVCodecID { AV_CODEC_ID_ATRAC3AL, AV_CODEC_ID_ATRAC3PAL, AV_CODEC_ID_DOLBY_E, + AV_CODEC_ID_APTX, + AV_CODEC_ID_APTX_HD, + AV_CODEC_ID_SBC, + AV_CODEC_ID_ATRAC9, /* subtitle codecs */ AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. @@ -669,6 +673,7 @@ enum AVCodecID { AV_CODEC_ID_PJS, AV_CODEC_ID_ASS, AV_CODEC_ID_HDMV_TEXT_SUBTITLE, + AV_CODEC_ID_TTML, /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. @@ -774,7 +779,7 @@ typedef struct AVCodecDescriptor { * Note: If the first 23 bits of the additional bytes are not 0, then damaged * MPEG bitstreams could cause overread and segfault. */ -#define AV_INPUT_BUFFER_PADDING_SIZE 32 +#define AV_INPUT_BUFFER_PADDING_SIZE 64 /** * @ingroup lavc_encoding @@ -783,38 +788,6 @@ typedef struct AVCodecDescriptor { */ #define AV_INPUT_BUFFER_MIN_SIZE 16384 -#if FF_API_WITHOUT_PREFIX -/** - * @deprecated use AV_INPUT_BUFFER_PADDING_SIZE instead - */ -#define FF_INPUT_BUFFER_PADDING_SIZE 32 - -/** - * @deprecated use AV_INPUT_BUFFER_MIN_SIZE instead - */ -#define FF_MIN_BUFFER_SIZE 16384 -#endif /* FF_API_WITHOUT_PREFIX */ - -/** - * @ingroup lavc_encoding - * motion estimation type. - * @deprecated use codec private option instead - */ -#if FF_API_MOTION_EST -enum Motion_Est_ID { - ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed - ME_FULL, - ME_LOG, - ME_PHODS, - ME_EPZS, ///< enhanced predictive zonal search - ME_X1, ///< reserved for experiments - ME_HEX, ///< hexagon based search - ME_UMH, ///< uneven multi-hexagon search - ME_TESA, ///< transformed exhaustive search algorithm - ME_ITER=50, ///< iterative search -}; -#endif - /** * @ingroup lavc_decoding */ @@ -853,13 +826,6 @@ typedef struct RcOverride{ float quality_factor; } RcOverride; -#if FF_API_MAX_BFRAMES -/** - * @deprecated there is no libavcodec-wide limit on the number of B-frames - */ -#define FF_MAX_B_FRAMES 16 -#endif - /* encoding support These flags can be passed in AVCodecContext.flags before initialization. Note: Not everything is supported yet. @@ -1031,13 +997,6 @@ typedef struct RcOverride{ */ #define AV_CODEC_CAP_SMALL_LAST_FRAME (1 << 6) -#if FF_API_CAP_VDPAU -/** - * Codec can export data for HW decoding (VDPAU). - */ -#define AV_CODEC_CAP_HWACCEL_VDPAU (1 << 7) -#endif - /** * Codec can output multiple frames per AVPacket * Normally demuxers return one frame at a time, demuxers which do not do @@ -1098,231 +1057,26 @@ typedef struct RcOverride{ */ #define AV_CODEC_CAP_LOSSLESS 0x80000000 - -#if FF_API_WITHOUT_PREFIX /** - * Allow decoders to produce frames with data planes that are not aligned - * to CPU requirements (e.g. due to cropping). + * Codec is backed by a hardware implementation. Typically used to + * identify a non-hwaccel hardware decoder. For information about hwaccels, use + * avcodec_get_hw_config() instead. */ -#define CODEC_FLAG_UNALIGNED AV_CODEC_FLAG_UNALIGNED -#define CODEC_FLAG_QSCALE AV_CODEC_FLAG_QSCALE -#define CODEC_FLAG_4MV AV_CODEC_FLAG_4MV -#define CODEC_FLAG_OUTPUT_CORRUPT AV_CODEC_FLAG_OUTPUT_CORRUPT -#define CODEC_FLAG_QPEL AV_CODEC_FLAG_QPEL -#if FF_API_GMC -/** - * @deprecated use the "gmc" private option of the libxvid encoder - */ -#define CODEC_FLAG_GMC 0x0020 ///< Use GMC. -#endif -#if FF_API_MV0 -/** - * @deprecated use the flag "mv0" in the "mpv_flags" private option of the - * mpegvideo encoders - */ -#define CODEC_FLAG_MV0 0x0040 -#endif -#if FF_API_INPUT_PRESERVED -/** - * @deprecated passing reference-counted frames to the encoders replaces this - * flag - */ -#define CODEC_FLAG_INPUT_PRESERVED 0x0100 -#endif -#define CODEC_FLAG_PASS1 AV_CODEC_FLAG_PASS1 -#define CODEC_FLAG_PASS2 AV_CODEC_FLAG_PASS2 -#define CODEC_FLAG_GRAY AV_CODEC_FLAG_GRAY -#if FF_API_EMU_EDGE -/** - * @deprecated edges are not used/required anymore. I.e. this flag is now always - * set. - */ -#define CODEC_FLAG_EMU_EDGE 0x4000 -#endif -#define CODEC_FLAG_PSNR AV_CODEC_FLAG_PSNR -#define CODEC_FLAG_TRUNCATED AV_CODEC_FLAG_TRUNCATED - -#if FF_API_NORMALIZE_AQP -/** - * @deprecated use the flag "naq" in the "mpv_flags" private option of the - * mpegvideo encoders - */ -#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 -#endif -#define CODEC_FLAG_INTERLACED_DCT AV_CODEC_FLAG_INTERLACED_DCT -#define CODEC_FLAG_LOW_DELAY AV_CODEC_FLAG_LOW_DELAY -#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER -#define CODEC_FLAG_BITEXACT AV_CODEC_FLAG_BITEXACT -#define CODEC_FLAG_AC_PRED AV_CODEC_FLAG_AC_PRED -#define CODEC_FLAG_LOOP_FILTER AV_CODEC_FLAG_LOOP_FILTER -#define CODEC_FLAG_INTERLACED_ME AV_CODEC_FLAG_INTERLACED_ME -#define CODEC_FLAG_CLOSED_GOP AV_CODEC_FLAG_CLOSED_GOP -#define CODEC_FLAG2_FAST AV_CODEC_FLAG2_FAST -#define CODEC_FLAG2_NO_OUTPUT AV_CODEC_FLAG2_NO_OUTPUT -#define CODEC_FLAG2_LOCAL_HEADER AV_CODEC_FLAG2_LOCAL_HEADER -#define CODEC_FLAG2_DROP_FRAME_TIMECODE AV_CODEC_FLAG2_DROP_FRAME_TIMECODE -#define CODEC_FLAG2_IGNORE_CROP AV_CODEC_FLAG2_IGNORE_CROP - -#define CODEC_FLAG2_CHUNKS AV_CODEC_FLAG2_CHUNKS -#define CODEC_FLAG2_SHOW_ALL AV_CODEC_FLAG2_SHOW_ALL -#define CODEC_FLAG2_EXPORT_MVS AV_CODEC_FLAG2_EXPORT_MVS -#define CODEC_FLAG2_SKIP_MANUAL AV_CODEC_FLAG2_SKIP_MANUAL - -/* Unsupported options : - * Syntax Arithmetic coding (SAC) - * Reference Picture Selection - * Independent Segment Decoding */ -/* /Fx */ -/* codec capabilities */ - -#define CODEC_CAP_DRAW_HORIZ_BAND AV_CODEC_CAP_DRAW_HORIZ_BAND ///< Decoder can use draw_horiz_band callback. -/** - * Codec uses get_buffer() for allocating buffers and supports custom allocators. - * If not set, it might not use get_buffer() at all or use operations that - * assume the buffer was allocated by avcodec_default_get_buffer. - */ -#define CODEC_CAP_DR1 AV_CODEC_CAP_DR1 -#define CODEC_CAP_TRUNCATED AV_CODEC_CAP_TRUNCATED -#if FF_API_XVMC -/* Codec can export data for HW decoding. This flag indicates that - * the codec would call get_format() with list that might contain HW accelerated - * pixel formats (XvMC, VDPAU, VAAPI, etc). The application can pick any of them - * including raw image format. - * The application can use the passed context to determine bitstream version, - * chroma format, resolution etc. - */ -#define CODEC_CAP_HWACCEL 0x0010 -#endif /* FF_API_XVMC */ -/** - * Encoder or decoder requires flushing with NULL input at the end in order to - * give the complete and correct output. - * - * NOTE: If this flag is not set, the codec is guaranteed to never be fed with - * with NULL data. The user can still send NULL data to the public encode - * or decode function, but libavcodec will not pass it along to the codec - * unless this flag is set. - * - * Decoders: - * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL, - * avpkt->size=0 at the end to get the delayed data until the decoder no longer - * returns frames. - * - * Encoders: - * The encoder needs to be fed with NULL data at the end of encoding until the - * encoder no longer returns data. - * - * NOTE: For encoders implementing the AVCodec.encode2() function, setting this - * flag also means that the encoder must set the pts and duration for - * each output packet. If this flag is not set, the pts and duration will - * be determined by libavcodec from the input frame. - */ -#define CODEC_CAP_DELAY AV_CODEC_CAP_DELAY -/** - * Codec can be fed a final frame with a smaller size. - * This can be used to prevent truncation of the last audio samples. - */ -#define CODEC_CAP_SMALL_LAST_FRAME AV_CODEC_CAP_SMALL_LAST_FRAME -#if FF_API_CAP_VDPAU -/** - * Codec can export data for HW decoding (VDPAU). - */ -#define CODEC_CAP_HWACCEL_VDPAU AV_CODEC_CAP_HWACCEL_VDPAU -#endif -/** - * Codec can output multiple frames per AVPacket - * Normally demuxers return one frame at a time, demuxers which do not do - * are connected to a parser to split what they return into proper frames. - * This flag is reserved to the very rare category of codecs which have a - * bitstream that cannot be split into frames without timeconsuming - * operations like full decoding. Demuxers carrying such bitstreams thus - * may return multiple frames in a packet. This has many disadvantages like - * prohibiting stream copy in many cases thus it should only be considered - * as a last resort. - */ -#define CODEC_CAP_SUBFRAMES AV_CODEC_CAP_SUBFRAMES -/** - * Codec is experimental and is thus avoided in favor of non experimental - * encoders - */ -#define CODEC_CAP_EXPERIMENTAL AV_CODEC_CAP_EXPERIMENTAL -/** - * Codec should fill in channel configuration and samplerate instead of container - */ -#define CODEC_CAP_CHANNEL_CONF AV_CODEC_CAP_CHANNEL_CONF -#if FF_API_NEG_LINESIZES -/** - * @deprecated no codecs use this capability - */ -#define CODEC_CAP_NEG_LINESIZES 0x0800 -#endif -/** - * Codec supports frame-level multithreading. - */ -#define CODEC_CAP_FRAME_THREADS AV_CODEC_CAP_FRAME_THREADS -/** - * Codec supports slice-based (or partition-based) multithreading. - */ -#define CODEC_CAP_SLICE_THREADS AV_CODEC_CAP_SLICE_THREADS -/** - * Codec supports changed parameters at any point. - */ -#define CODEC_CAP_PARAM_CHANGE AV_CODEC_CAP_PARAM_CHANGE -/** - * Codec supports avctx->thread_count == 0 (auto). - */ -#define CODEC_CAP_AUTO_THREADS AV_CODEC_CAP_AUTO_THREADS -/** - * Audio encoder supports receiving a different number of samples in each call. - */ -#define CODEC_CAP_VARIABLE_FRAME_SIZE AV_CODEC_CAP_VARIABLE_FRAME_SIZE -/** - * Codec is intra only. - */ -#define CODEC_CAP_INTRA_ONLY AV_CODEC_CAP_INTRA_ONLY -/** - * Codec is lossless. - */ -#define CODEC_CAP_LOSSLESS AV_CODEC_CAP_LOSSLESS +#define AV_CODEC_CAP_HARDWARE (1 << 18) /** - * HWAccel is experimental and is thus avoided in favor of non experimental - * codecs + * Codec is potentially backed by a hardware implementation, but not + * necessarily. This is used instead of AV_CODEC_CAP_HARDWARE, if the + * implementation provides some sort of internal fallback. */ -#define HWACCEL_CODEC_CAP_EXPERIMENTAL 0x0200 -#endif /* FF_API_WITHOUT_PREFIX */ - -#if FF_API_MB_TYPE -//The following defines may change, don't expect compatibility if you use them. -#define MB_TYPE_INTRA4x4 0x0001 -#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific -#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific -#define MB_TYPE_16x16 0x0008 -#define MB_TYPE_16x8 0x0010 -#define MB_TYPE_8x16 0x0020 -#define MB_TYPE_8x8 0x0040 -#define MB_TYPE_INTERLACED 0x0080 -#define MB_TYPE_DIRECT2 0x0100 //FIXME -#define MB_TYPE_ACPRED 0x0200 -#define MB_TYPE_GMC 0x0400 -#define MB_TYPE_SKIP 0x0800 -#define MB_TYPE_P0L0 0x1000 -#define MB_TYPE_P1L0 0x2000 -#define MB_TYPE_P0L1 0x4000 -#define MB_TYPE_P1L1 0x8000 -#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) -#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) -#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) -#define MB_TYPE_QUANT 0x00010000 -#define MB_TYPE_CBP 0x00020000 -// Note bits 24-31 are reserved for codec specific use (H.264 ref0, MPEG-1 0mv, ...) -#endif +#define AV_CODEC_CAP_HYBRID (1 << 19) /** * Pan Scan area. * This specifies the area which should be displayed. * Note there may be multiple such areas for one frame. */ -typedef struct AVPanScan{ +typedef struct AVPanScan { /** * id * - encoding: Set by user. @@ -1344,7 +1098,7 @@ typedef struct AVPanScan{ * - decoding: Set by libavcodec. */ int16_t position[3][2]; -}AVPanScan; +} AVPanScan; /** * This structure describes the bitrate properties of an encoded bitstream. It @@ -1384,13 +1138,6 @@ typedef struct AVCPBProperties { uint64_t vbv_delay; } AVCPBProperties; -#if FF_API_QSCALE_TYPE -#define FF_QSCALE_TYPE_MPEG1 0 -#define FF_QSCALE_TYPE_MPEG2 1 -#define FF_QSCALE_TYPE_H264 2 -#define FF_QSCALE_TYPE_VP56 3 -#endif - /** * The decoder will keep a reference to the frame and may reuse it later. */ @@ -1518,7 +1265,7 @@ enum AVPacketSideDataType { * u8 reason for end skip (0=padding silence, 1=convergence) * @endcode */ - AV_PKT_DATA_SKIP_SAMPLES=70, + AV_PKT_DATA_SKIP_SAMPLES, /** * An AV_PKT_DATA_JP_DUALMONO side data packet indicates that @@ -1607,7 +1354,26 @@ enum AVPacketSideDataType { AV_PKT_DATA_A53_CC, /** - * The number of side data elements (in fact a bit more than it). + * This side data is encryption initialization data. + * The format is not part of ABI, use av_encryption_init_info_* methods to + * access. + */ + AV_PKT_DATA_ENCRYPTION_INIT_INFO, + + /** + * This side data contains encryption info for how to decrypt the packet. + * The format is not part of ABI, use av_encryption_info_* methods to access. + */ + AV_PKT_DATA_ENCRYPTION_INFO, + + /** + * Active Format Description data consisting of a single byte as specified + * in ETSI TS 101 154 using AVActiveFormatDescription enum. + */ + AV_PKT_DATA_AFD, + + /** + * The number of side data types. * This is not part of the public API/ABI in the sense that it may * change when new side data types are added. * This must stay the last enum value. @@ -1723,6 +1489,12 @@ typedef struct AVPacket { * outside the packet may be followed. */ #define AV_PKT_FLAG_TRUSTED 0x0008 +/** + * Flag is used to indicate packets that contain frames that can + * be discarded by the decoder. I.e. Non-reference frames. + */ +#define AV_PKT_FLAG_DISPOSABLE 0x0010 + enum AVSideDataParamChangeFlags { AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001, @@ -1768,13 +1540,6 @@ typedef struct AVCodecContext { enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */ const struct AVCodec *codec; -#if FF_API_CODEC_NAME - /** - * @deprecated this field is not used for anything in libavcodec - */ - attribute_deprecated - char codec_name[32]; -#endif enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */ /** @@ -1792,14 +1557,6 @@ typedef struct AVCodecContext { */ unsigned int codec_tag; -#if FF_API_STREAM_CODEC_TAG - /** - * @deprecated this field is unused - */ - attribute_deprecated - unsigned int stream_codec_tag; -#endif - void *priv_data; /** @@ -1870,6 +1627,7 @@ typedef struct AVCodecContext { * The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger * than extradata_size to avoid problems if it is read with the bitstream reader. * The bytewise contents of extradata must not depend on the architecture or CPU endianness. + * Must be allocated with the av_malloc() family of functions. * - encoding: Set/allocated/freed by libavcodec. * - decoding: Set/allocated/freed by user. */ @@ -1962,10 +1720,6 @@ typedef struct AVCodecContext { */ int coded_width, coded_height; -#if FF_API_ASPECT_EXTENDED -#define FF_ASPECT_EXTENDED 15 -#endif - /** * the number of pictures in a group of pictures, or 0 for intra_only * - encoding: Set by user. @@ -1988,14 +1742,6 @@ typedef struct AVCodecContext { */ enum AVPixelFormat pix_fmt; -#if FF_API_MOTION_EST - /** - * This option does nothing - * @deprecated use codec private options instead - */ - attribute_deprecated int me_method; -#endif - /** * If non NULL, 'draw_horiz_band' is called by the libavcodec * decoder to draw a horizontal band. It improves cache usage. Not @@ -2055,12 +1801,6 @@ typedef struct AVCodecContext { */ float b_quant_factor; -#if FF_API_RC_STRATEGY - /** @deprecated use codec private option instead */ - attribute_deprecated int rc_strategy; -#define FF_RC_STRATEGY_XVID 1 -#endif - #if FF_API_PRIVATE_OPT /** @deprecated use encoder private options instead */ attribute_deprecated @@ -2254,26 +1994,6 @@ typedef struct AVCodecContext { */ int me_subpel_quality; -#if FF_API_AFD - /** - * DTG active format information (additional aspect ratio - * information only used in DVB MPEG-2 transport streams) - * 0 if not set. - * - * - encoding: unused - * - decoding: Set by decoder. - * @deprecated Deprecated in favor of AVSideData - */ - attribute_deprecated int dtg_active_format; -#define FF_DTG_AFD_SAME 8 -#define FF_DTG_AFD_4_3 9 -#define FF_DTG_AFD_16_9 10 -#define FF_DTG_AFD_14_9 11 -#define FF_DTG_AFD_4_3_SP_14_9 13 -#define FF_DTG_AFD_16_9_SP_14_9 14 -#define FF_DTG_AFD_SP_4_3 15 -#endif /* FF_API_AFD */ - /** * maximum motion estimation search range in subpel units * If 0 then no limit. @@ -2283,19 +2003,6 @@ typedef struct AVCodecContext { */ int me_range; -#if FF_API_QUANT_BIAS - /** - * @deprecated use encoder private option instead - */ - attribute_deprecated int intra_quant_bias; -#define FF_DEFAULT_QUANT_BIAS 999999 - - /** - * @deprecated use encoder private option instead - */ - attribute_deprecated int inter_quant_bias; -#endif - /** * slice flags * - encoding: unused @@ -2306,16 +2013,6 @@ typedef struct AVCodecContext { #define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG-2 field pics) #define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1) -#if FF_API_XVMC - /** - * XVideo Motion Acceleration - * - encoding: forbidden - * - decoding: set by decoder - * @deprecated XvMC doesn't need it anymore. - */ - attribute_deprecated int xvmc_acceleration; -#endif /* FF_API_XVMC */ - /** * macroblock decision mode * - encoding: Set by user. @@ -2350,20 +2047,6 @@ typedef struct AVCodecContext { int noise_reduction; #endif -#if FF_API_MPV_OPT - /** - * @deprecated this field is unused - */ - attribute_deprecated - int me_threshold; - - /** - * @deprecated this field is unused - */ - attribute_deprecated - int mb_threshold; -#endif - /** * precision of the intra DC coefficient - 8 * - encoding: Set by user. @@ -2385,14 +2068,6 @@ typedef struct AVCodecContext { */ int skip_bottom; -#if FF_API_MPV_OPT - /** - * @deprecated use encoder private options instead - */ - attribute_deprecated - float border_masking; -#endif - /** * minimum MB Lagrange multiplier * - encoding: Set by user. @@ -2447,15 +2122,6 @@ typedef struct AVCodecContext { int chromaoffset; #endif -#if FF_API_UNUSED_MEMBERS - /** - * Multiplied by qscale for each frame and added to scene_change_score. - * - encoding: Set by user. - * - decoding: unused - */ - attribute_deprecated int scenechange_factor; -#endif - /** * Note: Value depends upon the compare function used for fullpel ME. * - encoding: Set by user. @@ -2718,19 +2384,6 @@ typedef struct AVCodecContext { */ int max_qdiff; -#if FF_API_MPV_OPT - /** - * @deprecated use encoder private options instead - */ - attribute_deprecated - float rc_qsquish; - - attribute_deprecated - float rc_qmod_amp; - attribute_deprecated - int rc_qmod_freq; -#endif - /** * decoder bitstream buffer size * - encoding: Set by user. @@ -2746,14 +2399,6 @@ typedef struct AVCodecContext { int rc_override_count; RcOverride *rc_override; -#if FF_API_MPV_OPT - /** - * @deprecated use encoder private options instead - */ - attribute_deprecated - const char *rc_eq; -#endif - /** * maximum bitrate * - encoding: Set by user. @@ -2768,17 +2413,6 @@ typedef struct AVCodecContext { */ int64_t rc_min_rate; -#if FF_API_MPV_OPT - /** - * @deprecated use encoder private options instead - */ - attribute_deprecated - float rc_buffer_aggressivity; - - attribute_deprecated - float rc_initial_cplx; -#endif - /** * Ratecontrol attempt to use, at maximum, of what can be used without an underflow. * - encoding: Set by user. @@ -2805,9 +2439,6 @@ typedef struct AVCodecContext { #define FF_CODER_TYPE_AC 1 #define FF_CODER_TYPE_RAW 2 #define FF_CODER_TYPE_RLE 3 -#if FF_API_UNUSED_MEMBERS -#define FF_CODER_TYPE_DEFLATE 4 -#endif /* FF_API_UNUSED_MEMBERS */ /** * @deprecated use encoder private options instead */ @@ -2821,20 +2452,6 @@ typedef struct AVCodecContext { int context_model; #endif -#if FF_API_MPV_OPT - /** - * @deprecated use encoder private options instead - */ - attribute_deprecated - int lmin; - - /** - * @deprecated use encoder private options instead - */ - attribute_deprecated - int lmax; -#endif - #if FF_API_PRIVATE_OPT /** @deprecated use encoder private options instead */ attribute_deprecated @@ -2945,16 +2562,10 @@ typedef struct AVCodecContext { */ int workaround_bugs; #define FF_BUG_AUTODETECT 1 ///< autodetection -#if FF_API_OLD_MSMPEG4 -#define FF_BUG_OLD_MSMPEG4 2 -#endif #define FF_BUG_XVID_ILACE 4 #define FF_BUG_UMP4 8 #define FF_BUG_NO_PADDING 16 #define FF_BUG_AMV 32 -#if FF_API_AC_VLC -#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default. -#endif #define FF_BUG_QPEL_CHROMA 64 #define FF_BUG_STD_QPEL 128 #define FF_BUG_QPEL_CHROMA2 256 @@ -3015,9 +2626,6 @@ typedef struct AVCodecContext { #define FF_DEBUG_DCT_COEFF 0x00000040 #define FF_DEBUG_SKIP 0x00000080 #define FF_DEBUG_STARTCODE 0x00000100 -#if FF_API_UNUSED_MEMBERS -#define FF_DEBUG_PTS 0x00000200 -#endif /* FF_API_UNUSED_MEMBERS */ #define FF_DEBUG_ER 0x00000400 #define FF_DEBUG_MMCO 0x00000800 #define FF_DEBUG_BUGS 0x00001000 @@ -3079,7 +2687,7 @@ typedef struct AVCodecContext { * - encoding: unused. * - decoding: Set by libavcodec */ - struct AVHWAccel *hwaccel; + const struct AVHWAccel *hwaccel; /** * Hardware accelerator context. @@ -3125,27 +2733,12 @@ typedef struct AVCodecContext { #define FF_IDCT_SIMPLEMMX 3 #define FF_IDCT_ARM 7 #define FF_IDCT_ALTIVEC 8 -#if FF_API_ARCH_SH4 -#define FF_IDCT_SH4 9 -#endif #define FF_IDCT_SIMPLEARM 10 -#if FF_API_UNUSED_MEMBERS -#define FF_IDCT_IPP 13 -#endif /* FF_API_UNUSED_MEMBERS */ #define FF_IDCT_XVID 14 -#if FF_API_IDCT_XVIDMMX -#define FF_IDCT_XVIDMMX 14 -#endif /* FF_API_IDCT_XVIDMMX */ #define FF_IDCT_SIMPLEARMV5TE 16 #define FF_IDCT_SIMPLEARMV6 17 -#if FF_API_ARCH_SPARC -#define FF_IDCT_SIMPLEVIS 18 -#endif #define FF_IDCT_FAAN 20 #define FF_IDCT_SIMPLENEON 22 -#if FF_API_ARCH_ALPHA -#define FF_IDCT_SIMPLEALPHA 23 -#endif #define FF_IDCT_NONE 24 /* Used by XvMC to extract IDCT coefficients with FF_IDCT_PERM_NONE */ #define FF_IDCT_SIMPLEAUTO 128 @@ -3356,6 +2949,18 @@ typedef struct AVCodecContext { #define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3 #define FF_PROFILE_HEVC_REXT 4 +#define FF_PROFILE_AV1_MAIN 0 +#define FF_PROFILE_AV1_HIGH 1 +#define FF_PROFILE_AV1_PROFESSIONAL 2 + +#define FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT 0xc0 +#define FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT 0xc1 +#define FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT 0xc2 +#define FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS 0xc3 +#define FF_PROFILE_MJPEG_JPEG_LS 0xf7 + +#define FF_PROFILE_SBC_MSBC 1 + /** * level * - encoding: Set by user. @@ -3396,15 +3001,6 @@ typedef struct AVCodecContext { uint8_t *subtitle_header; int subtitle_header_size; -#if FF_API_ERROR_RATE - /** - * @deprecated use the 'error_rate' private AVOption of the mpegvideo - * encoders - */ - attribute_deprecated - int error_rate; -#endif - #if FF_API_VBV_DELAY /** * VBV delay coded in the last frame (in periods of a 27 MHz clock). @@ -3516,6 +3112,7 @@ typedef struct AVCodecContext { #define FF_SUB_CHARENC_MODE_DO_NOTHING -1 ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance) #define FF_SUB_CHARENC_MODE_AUTOMATIC 0 ///< libavcodec will select the mode itself #define FF_SUB_CHARENC_MODE_PRE_DECODER 1 ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv +#define FF_SUB_CHARENC_MODE_IGNORE 2 ///< neither convert the subtitles, nor check them for valid UTF-8 /** * Skip processing alpha if supported by codec. @@ -3702,24 +3299,57 @@ typedef struct AVCodecContext { * (with the display dimensions being determined by the crop_* fields). */ int apply_cropping; + + /* + * Video decoding only. Sets the number of extra hardware frames which + * the decoder will allocate for use by the caller. This must be set + * before avcodec_open2() is called. + * + * Some hardware decoders require all frames that they will use for + * output to be defined in advance before decoding starts. For such + * decoders, the hardware frame pool must therefore be of a fixed size. + * The extra frames set here are on top of any number that the decoder + * needs internally in order to operate normally (for example, frames + * used as reference pictures). + */ + int extra_hw_frames; } AVCodecContext; +#if FF_API_CODEC_GET_SET +/** + * Accessors for some AVCodecContext fields. These used to be provided for ABI + * compatibility, and do not need to be used anymore. + */ +attribute_deprecated AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); +attribute_deprecated void av_codec_set_pkt_timebase (AVCodecContext *avctx, AVRational val); +attribute_deprecated const AVCodecDescriptor *av_codec_get_codec_descriptor(const AVCodecContext *avctx); +attribute_deprecated void av_codec_set_codec_descriptor(AVCodecContext *avctx, const AVCodecDescriptor *desc); +attribute_deprecated unsigned av_codec_get_codec_properties(const AVCodecContext *avctx); +#if FF_API_LOWRES +attribute_deprecated int av_codec_get_lowres(const AVCodecContext *avctx); +attribute_deprecated void av_codec_set_lowres(AVCodecContext *avctx, int val); +#endif +attribute_deprecated int av_codec_get_seek_preroll(const AVCodecContext *avctx); +attribute_deprecated void av_codec_set_seek_preroll(AVCodecContext *avctx, int val); +attribute_deprecated uint16_t *av_codec_get_chroma_intra_matrix(const AVCodecContext *avctx); +attribute_deprecated void av_codec_set_chroma_intra_matrix(AVCodecContext *avctx, uint16_t *val); +#endif /** * AVProfile. @@ -3729,6 +3359,61 @@ typedef struct AVProfile { const char *name; ///< short name for the profile } AVProfile; +enum { + /** + * The codec supports this format via the hw_device_ctx interface. + * + * When selecting this format, AVCodecContext.hw_device_ctx should + * have been set to a device of the specified type before calling + * avcodec_open2(). + */ + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX = 0x01, + /** + * The codec supports this format via the hw_frames_ctx interface. + * + * When selecting this format for a decoder, + * AVCodecContext.hw_frames_ctx should be set to a suitable frames + * context inside the get_format() callback. The frames context + * must have been created on a device of the specified type. + */ + AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX = 0x02, + /** + * The codec supports this format by some internal method. + * + * This format can be selected without any additional configuration - + * no device or frames context is required. + */ + AV_CODEC_HW_CONFIG_METHOD_INTERNAL = 0x04, + /** + * The codec supports this format by some ad-hoc method. + * + * Additional settings and/or function calls are required. See the + * codec-specific documentation for details. (Methods requiring + * this sort of configuration are deprecated and others should be + * used in preference.) + */ + AV_CODEC_HW_CONFIG_METHOD_AD_HOC = 0x08, +}; + +typedef struct AVCodecHWConfig { + /** + * A hardware pixel format which the codec can use. + */ + enum AVPixelFormat pix_fmt; + /** + * Bit set of AV_CODEC_HW_CONFIG_METHOD_* flags, describing the possible + * setup methods which can be used with this configuration. + */ + int methods; + /** + * The device type associated with the configuration. + * + * Must be set for AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX and + * AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, otherwise unused. + */ + enum AVHWDeviceType device_type; +} AVCodecHWConfig; + typedef struct AVCodecDefault AVCodecDefault; struct AVSubtitle; @@ -3765,6 +3450,18 @@ typedef struct AVCodec { const AVClass *priv_class; ///< AVClass for the private context const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} + /** + * Group name of the codec implementation. + * This is a short symbolic name of the wrapper backing this codec. A + * wrapper uses some kind of external implementation for the codec, such + * as an external library, or a codec implementation provided by the OS or + * the hardware. + * If this field is NULL, this is a builtin, libavcodec native codec. + * If non-NULL, this will be the suffix in AVCodec.name in most cases + * (usually AVCodec.name will be of the form "_"). + */ + const char *wrapper_name; + /***************************************************************** * No fields below this line are part of the public API. They * may not be used outside of libavcodec and can be changed and @@ -3801,6 +3498,9 @@ typedef struct AVCodec { /** * Initialize codec static data, called from avcodec_register(). + * + * This is not intended for time consuming operations as it is + * run for every codec regardless of that codec being used. */ void (*init_static_data)(struct AVCodec *codec); @@ -3854,14 +3554,39 @@ typedef struct AVCodec { * packets before decoding. */ const char *bsfs; + + /** + * Array of pointers to hardware configurations supported by the codec, + * or NULL if no hardware supported. The array is terminated by a NULL + * pointer. + * + * The user can only access this field via avcodec_get_hw_config(). + */ + const struct AVCodecHWConfigInternal **hw_configs; } AVCodec; +#if FF_API_CODEC_GET_SET +attribute_deprecated int av_codec_get_max_lowres(const AVCodec *codec); +#endif struct MpegEncContext; +/** + * Retrieve supported hardware configurations for a codec. + * + * Values of index from zero to some maximum return the indexed configuration + * descriptor; all other values return NULL. If the codec does not support + * any hardware configurations then it will always return NULL. + */ +const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index); + /** * @defgroup lavc_hwaccel AVHWAccel + * + * @note Nothing in this structure should be accessed by the user. At some + * point in future it will not be externally visible at all. + * * @{ */ typedef struct AVHWAccel { @@ -3906,7 +3631,6 @@ typedef struct AVHWAccel { * New public fields should be added right above. ***************************************************************** */ - struct AVHWAccel *next; /** * Allocate a custom buffer @@ -3929,6 +3653,20 @@ typedef struct AVHWAccel { */ int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + /** + * Callback for parameter data (SPS/PPS/VPS etc). + * + * Useful for hardware decoders which keep persistent state about the + * video parameters, and need to receive any changes to update that state. + * + * @param avctx the codec context + * @param type the nal unit type + * @param buf the nal unit data buffer + * @param buf_size the size of the nal unit in bytes + * @return zero if successful, a negative value otherwise + */ + int (*decode_params)(AVCodecContext *avctx, int type, const uint8_t *buf, uint32_t buf_size); + /** * Callback for each slice. * @@ -4001,6 +3739,16 @@ typedef struct AVHWAccel { * Internal hwaccel capabilities. */ int caps_internal; + + /** + * Fill the given hw_frames context with current codec parameters. Called + * from get_format. Refer to avcodec_get_hw_frames_parameters() for + * details. + * + * This CAN be called before AVHWAccel.init is called, and you must assume + * that avctx->hwaccel_priv_data is invalid. + */ + int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx); } AVHWAccel; /** @@ -4292,12 +4040,26 @@ typedef struct AVCodecParameters { int seek_preroll; } AVCodecParameters; +/** + * Iterate over all registered codecs. + * + * @param opaque a pointer where libavcodec will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered codec or NULL when the iteration is + * finished + */ +const AVCodec *av_codec_iterate(void **opaque); + +#if FF_API_NEXT /** * If c is NULL, returns the first registered codec, * if c is non-NULL, returns the next registered codec after c, * or NULL if c is the last one. */ +attribute_deprecated AVCodec *av_codec_next(const AVCodec *c); +#endif /** * Return the LIBAVCODEC_VERSION_INT constant. @@ -4314,6 +4076,7 @@ const char *avcodec_configuration(void); */ const char *avcodec_license(void); +#if FF_API_NEXT /** * Register the codec codec and initialize libavcodec. * @@ -4322,6 +4085,7 @@ const char *avcodec_license(void); * * @see avcodec_register_all() */ +attribute_deprecated void avcodec_register(AVCodec *codec); /** @@ -4334,7 +4098,9 @@ void avcodec_register(AVCodec *codec); * @see av_register_codec_parser * @see av_register_bitstream_filter */ +attribute_deprecated void avcodec_register_all(void); +#endif /** * Allocate an AVCodecContext and set its fields to default values. The @@ -4615,7 +4381,7 @@ int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size); * @warning This is a hack - the packet memory allocation stuff is broken. The * packet is allocated if it was not really allocated. * - * @deprecated Use av_packet_ref + * @deprecated Use av_packet_ref or av_packet_make_refcounted */ attribute_deprecated int av_dup_packet(AVPacket *pkt); @@ -4786,6 +4552,33 @@ void av_packet_move_ref(AVPacket *dst, AVPacket *src); */ int av_packet_copy_props(AVPacket *dst, const AVPacket *src); +/** + * Ensure the data described by a given packet is reference counted. + * + * @note This function does not ensure that the reference will be writable. + * Use av_packet_make_writable instead for that purpose. + * + * @see av_packet_ref + * @see av_packet_make_writable + * + * @param pkt packet whose data should be made reference counted. + * + * @return 0 on success, a negative AVERROR on error. On failure, the + * packet is unchanged. + */ +int av_packet_make_refcounted(AVPacket *pkt); + +/** + * Create a writable reference for the data described by a given packet, + * avoiding data copy if possible. + * + * @param pkt Packet whose data should be made writable. + * + * @return 0 on success, a negative AVERROR on failure. On failure, the + * packet is unchanged. + */ +int av_packet_make_writable(AVPacket *pkt); + /** * Convert valid timing fields (timestamps / durations) in a packet from one * timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be @@ -4831,21 +4624,6 @@ AVCodec *avcodec_find_decoder_by_name(const char *name); */ int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags); -#if FF_API_EMU_EDGE -/** - * Return the amount of padding in pixels which the get_buffer callback must - * provide around the edge of the image for codecs which do not have the - * CODEC_FLAG_EMU_EDGE flag. - * - * @return Required padding in pixels. - * - * @deprecated CODEC_FLAG_EMU_EDGE is deprecated, so this function is no longer - * needed - */ -attribute_deprecated -unsigned avcodec_get_edge_width(void); -#endif - /** * Modify width and height values so that they will result in a memory * buffer that is acceptable for the codec if you do not use any horizontal @@ -5151,6 +4929,109 @@ int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame); */ int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt); +/** + * Create and return a AVHWFramesContext with values adequate for hardware + * decoding. This is meant to get called from the get_format callback, and is + * a helper for preparing a AVHWFramesContext for AVCodecContext.hw_frames_ctx. + * This API is for decoding with certain hardware acceleration modes/APIs only. + * + * The returned AVHWFramesContext is not initialized. The caller must do this + * with av_hwframe_ctx_init(). + * + * Calling this function is not a requirement, but makes it simpler to avoid + * codec or hardware API specific details when manually allocating frames. + * + * Alternatively to this, an API user can set AVCodecContext.hw_device_ctx, + * which sets up AVCodecContext.hw_frames_ctx fully automatically, and makes + * it unnecessary to call this function or having to care about + * AVHWFramesContext initialization at all. + * + * There are a number of requirements for calling this function: + * + * - It must be called from get_format with the same avctx parameter that was + * passed to get_format. Calling it outside of get_format is not allowed, and + * can trigger undefined behavior. + * - The function is not always supported (see description of return values). + * Even if this function returns successfully, hwaccel initialization could + * fail later. (The degree to which implementations check whether the stream + * is actually supported varies. Some do this check only after the user's + * get_format callback returns.) + * - The hw_pix_fmt must be one of the choices suggested by get_format. If the + * user decides to use a AVHWFramesContext prepared with this API function, + * the user must return the same hw_pix_fmt from get_format. + * - The device_ref passed to this function must support the given hw_pix_fmt. + * - After calling this API function, it is the user's responsibility to + * initialize the AVHWFramesContext (returned by the out_frames_ref parameter), + * and to set AVCodecContext.hw_frames_ctx to it. If done, this must be done + * before returning from get_format (this is implied by the normal + * AVCodecContext.hw_frames_ctx API rules). + * - The AVHWFramesContext parameters may change every time time get_format is + * called. Also, AVCodecContext.hw_frames_ctx is reset before get_format. So + * you are inherently required to go through this process again on every + * get_format call. + * - It is perfectly possible to call this function without actually using + * the resulting AVHWFramesContext. One use-case might be trying to reuse a + * previously initialized AVHWFramesContext, and calling this API function + * only to test whether the required frame parameters have changed. + * - Fields that use dynamically allocated values of any kind must not be set + * by the user unless setting them is explicitly allowed by the documentation. + * If the user sets AVHWFramesContext.free and AVHWFramesContext.user_opaque, + * the new free callback must call the potentially set previous free callback. + * This API call may set any dynamically allocated fields, including the free + * callback. + * + * The function will set at least the following fields on AVHWFramesContext + * (potentially more, depending on hwaccel API): + * + * - All fields set by av_hwframe_ctx_alloc(). + * - Set the format field to hw_pix_fmt. + * - Set the sw_format field to the most suited and most versatile format. (An + * implication is that this will prefer generic formats over opaque formats + * with arbitrary restrictions, if possible.) + * - Set the width/height fields to the coded frame size, rounded up to the + * API-specific minimum alignment. + * - Only _if_ the hwaccel requires a pre-allocated pool: set the initial_pool_size + * field to the number of maximum reference surfaces possible with the codec, + * plus 1 surface for the user to work (meaning the user can safely reference + * at most 1 decoded surface at a time), plus additional buffering introduced + * by frame threading. If the hwaccel does not require pre-allocation, the + * field is left to 0, and the decoder will allocate new surfaces on demand + * during decoding. + * - Possibly AVHWFramesContext.hwctx fields, depending on the underlying + * hardware API. + * + * Essentially, out_frames_ref returns the same as av_hwframe_ctx_alloc(), but + * with basic frame parameters set. + * + * The function is stateless, and does not change the AVCodecContext or the + * device_ref AVHWDeviceContext. + * + * @param avctx The context which is currently calling get_format, and which + * implicitly contains all state needed for filling the returned + * AVHWFramesContext properly. + * @param device_ref A reference to the AVHWDeviceContext describing the device + * which will be used by the hardware decoder. + * @param hw_pix_fmt The hwaccel format you are going to return from get_format. + * @param out_frames_ref On success, set to a reference to an _uninitialized_ + * AVHWFramesContext, created from the given device_ref. + * Fields will be set to values required for decoding. + * Not changed if an error is returned. + * @return zero on success, a negative value on error. The following error codes + * have special semantics: + * AVERROR(ENOENT): the decoder does not support this functionality. Setup + * is always manual, or it is a decoder which does not + * support setting AVCodecContext.hw_frames_ctx at all, + * or it is a software format. + * AVERROR(EINVAL): it is known that hardware decoding is not supported for + * this configuration, or the device_ref is not supported + * for the hwaccel referenced by hw_pix_fmt. + */ +int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, + AVBufferRef *device_ref, + enum AVPixelFormat hw_pix_fmt, + AVBufferRef **out_frames_ref); + + /** * @defgroup lavc_parsing Frame parsing @@ -5346,8 +5227,21 @@ typedef struct AVCodecParser { struct AVCodecParser *next; } AVCodecParser; +/** + * Iterate over all registered codec parsers. + * + * @param opaque a pointer where libavcodec will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered codec parser or NULL when the iteration is + * finished + */ +const AVCodecParser *av_parser_iterate(void **opaque); + +attribute_deprecated AVCodecParser *av_parser_next(const AVCodecParser *c); +attribute_deprecated void av_register_codec_parser(AVCodecParser *parser); AVCodecParserContext *av_parser_init(int codec_id); @@ -5516,103 +5410,6 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, * @} */ -#if FF_API_AVCODEC_RESAMPLE -/** - * @defgroup lavc_resample Audio resampling - * @ingroup libavc - * @deprecated use libswresample instead - * - * @{ - */ -struct ReSampleContext; -struct AVResampleContext; - -typedef struct ReSampleContext ReSampleContext; - -/** - * Initialize audio resampling context. - * - * @param output_channels number of output channels - * @param input_channels number of input channels - * @param output_rate output sample rate - * @param input_rate input sample rate - * @param sample_fmt_out requested output sample format - * @param sample_fmt_in input sample format - * @param filter_length length of each FIR filter in the filterbank relative to the cutoff frequency - * @param log2_phase_count log2 of the number of entries in the polyphase filterbank - * @param linear if 1 then the used FIR filter will be linearly interpolated - between the 2 closest, if 0 the closest will be used - * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate - * @return allocated ReSampleContext, NULL if error occurred - */ -attribute_deprecated -ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, - int output_rate, int input_rate, - enum AVSampleFormat sample_fmt_out, - enum AVSampleFormat sample_fmt_in, - int filter_length, int log2_phase_count, - int linear, double cutoff); - -attribute_deprecated -int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); - -/** - * Free resample context. - * - * @param s a non-NULL pointer to a resample context previously - * created with av_audio_resample_init() - */ -attribute_deprecated -void audio_resample_close(ReSampleContext *s); - - -/** - * Initialize an audio resampler. - * Note, if either rate is not an integer then simply scale both rates up so they are. - * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq - * @param log2_phase_count log2 of the number of entries in the polyphase filterbank - * @param linear If 1 then the used FIR filter will be linearly interpolated - between the 2 closest, if 0 the closest will be used - * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate - */ -attribute_deprecated -struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff); - -/** - * Resample an array of samples using a previously configured context. - * @param src an array of unconsumed samples - * @param consumed the number of samples of src which have been consumed are returned here - * @param src_size the number of unconsumed samples available - * @param dst_size the amount of space in samples available in dst - * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context. - * @return the number of samples written in dst or -1 if an error occurred - */ -attribute_deprecated -int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); - - -/** - * Compensate samplerate/timestamp drift. The compensation is done by changing - * the resampler parameters, so no audible clicks or similar distortions occur - * @param compensation_distance distance in output samples over which the compensation should be performed - * @param sample_delta number of output samples which should be output less - * - * example: av_resample_compensate(c, 10, 500) - * here instead of 510 samples only 500 samples would be output - * - * note, due to rounding the actual compensation might be slightly different, - * especially if the compensation_distance is large and the in_rate used during init is small - */ -attribute_deprecated -void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); -attribute_deprecated -void av_resample_close(struct AVResampleContext *c); - -/** - * @} - */ -#endif - #if FF_API_AVPICTURE /** * @addtogroup lavc_picture @@ -5753,14 +5550,6 @@ enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const en * @} */ -#if FF_API_SET_DIMENSIONS -/** - * @deprecated this function is not supposed to be used from outside of lavc - */ -attribute_deprecated -void avcodec_set_dimensions(AVCodecContext *s, int width, int height); -#endif - #if FF_API_TAG_STRING /** * Put a string representing the codec tag codec_tag in buf. @@ -5993,88 +5782,47 @@ typedef struct AVBitStreamFilter { int (*init)(AVBSFContext *ctx); int (*filter)(AVBSFContext *ctx, AVPacket *pkt); void (*close)(AVBSFContext *ctx); + void (*flush)(AVBSFContext *ctx); } AVBitStreamFilter; #if FF_API_OLD_BSF /** - * Register a bitstream filter. - * - * The filter will be accessible to the application code through - * av_bitstream_filter_next() or can be directly initialized with - * av_bitstream_filter_init(). - * - * @see avcodec_register_all() + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use the new bitstream filtering API (using AVBSFContext). */ attribute_deprecated void av_register_bitstream_filter(AVBitStreamFilter *bsf); - /** - * Create and initialize a bitstream filter context given a bitstream - * filter name. - * - * The returned context must be freed with av_bitstream_filter_close(). - * - * @param name the name of the bitstream filter - * @return a bitstream filter context if a matching filter was found - * and successfully initialized, NULL otherwise + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_get_by_name(), av_bsf_alloc(), and av_bsf_init() + * from the new bitstream filtering API (using AVBSFContext). */ attribute_deprecated AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); - /** - * Filter bitstream. - * - * This function filters the buffer buf with size buf_size, and places the - * filtered buffer in the buffer pointed to by poutbuf. - * - * The output buffer must be freed by the caller. - * - * @param bsfc bitstream filter context created by av_bitstream_filter_init() - * @param avctx AVCodecContext accessed by the filter, may be NULL. - * If specified, this must point to the encoder context of the - * output stream the packet is sent to. - * @param args arguments which specify the filter configuration, may be NULL - * @param poutbuf pointer which is updated to point to the filtered buffer - * @param poutbuf_size pointer which is updated to the filtered buffer size in bytes - * @param buf buffer containing the data to filter - * @param buf_size size in bytes of buf - * @param keyframe set to non-zero if the buffer to filter corresponds to a key-frame packet data - * @return >= 0 in case of success, or a negative error code in case of failure - * - * If the return value is positive, an output buffer is allocated and - * is available in *poutbuf, and is distinct from the input buffer. - * - * If the return value is 0, the output buffer is not allocated and - * should be considered identical to the input buffer, or in case - * *poutbuf was set it points to the input buffer (not necessarily to - * its starting address). A special case is if *poutbuf was set to NULL and - * *poutbuf_size was set to 0, which indicates the packet should be dropped. + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_send_packet() and av_bsf_receive_packet() from the + * new bitstream filtering API (using AVBSFContext). */ attribute_deprecated int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe); - /** - * Release bitstream filter context. - * - * @param bsf the bitstream filter context created with - * av_bitstream_filter_init(), can be NULL + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_free() from the new bitstream filtering API (using + * AVBSFContext). */ attribute_deprecated void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); - /** - * If f is NULL, return the first registered bitstream filter, - * if f is non-NULL, return the next registered bitstream filter - * after f, or NULL if f is the last one. - * - * This function can be used to iterate over all registered bitstream - * filters. + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_iterate() from the new bitstream filtering API (using + * AVBSFContext). */ attribute_deprecated -AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f); +const AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f); #endif /** @@ -6092,7 +5840,11 @@ const AVBitStreamFilter *av_bsf_get_by_name(const char *name); * @return the next registered bitstream filter or NULL when the iteration is * finished */ +const AVBitStreamFilter *av_bsf_iterate(void **opaque); +#if FF_API_NEXT +attribute_deprecated const AVBitStreamFilter *av_bsf_next(void **opaque); +#endif /** * Allocate a context for a given bitstream filter. The caller must fill in the @@ -6157,6 +5909,11 @@ int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt); */ int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt); +/** + * Reset the internal bitstream filter state / flush internal buffers. + */ +void av_bsf_flush(AVBSFContext *ctx); + /** * Free a bitstream filter context and everything associated with it; write NULL * into the supplied pointer. @@ -6282,51 +6039,32 @@ void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size); */ unsigned int av_xiphlacing(unsigned char *s, unsigned int v); -#if FF_API_MISSING_SAMPLE -/** - * Log a generic warning message about a missing feature. This function is - * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) - * only, and would normally not be used by applications. - * @param[in] avc a pointer to an arbitrary struct of which the first field is - * a pointer to an AVClass struct - * @param[in] feature string containing the name of the missing feature - * @param[in] want_sample indicates if samples are wanted which exhibit this feature. - * If want_sample is non-zero, additional verbiage will be added to the log - * message which tells the user how to report samples to the development - * mailing list. - * @deprecated Use avpriv_report_missing_feature() instead. - */ -attribute_deprecated -void av_log_missing_feature(void *avc, const char *feature, int want_sample); - -/** - * Log a generic warning message asking for a sample. This function is - * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) - * only, and would normally not be used by applications. - * @param[in] avc a pointer to an arbitrary struct of which the first field is - * a pointer to an AVClass struct - * @param[in] msg string containing an optional message, or NULL if no message - * @deprecated Use avpriv_request_sample() instead. - */ -attribute_deprecated -void av_log_ask_for_sample(void *avc, const char *msg, ...) av_printf_format(2, 3); -#endif /* FF_API_MISSING_SAMPLE */ - +#if FF_API_USER_VISIBLE_AVHWACCEL /** * Register the hardware accelerator hwaccel. + * + * @deprecated This function doesn't do anything. */ +attribute_deprecated void av_register_hwaccel(AVHWAccel *hwaccel); /** * If hwaccel is NULL, returns the first registered hardware accelerator, * if hwaccel is non-NULL, returns the next registered hardware accelerator * after hwaccel, or NULL if hwaccel is the last one. + * + * @deprecated AVHWaccel structures contain no user-serviceable parts, so + * this function should not be used. */ +attribute_deprecated AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel); +#endif - +#if FF_API_LOCKMGR /** * Lock operation used by lockmgr + * + * @deprecated Deprecated together with av_lockmgr_register(). */ enum AVLockOp { AV_LOCK_CREATE, ///< Create a mutex @@ -6357,8 +6095,13 @@ enum AVLockOp { * mechanism (i.e. do not use a single static object to * implement your lock manager). If cb is set to NULL the * lockmgr will be unregistered. + * + * @deprecated This function does nothing, and always returns 0. Be sure to + * build with thread support to get basic thread safety. */ +attribute_deprecated int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)); +#endif /** * Get the type of the given codec. diff --git a/third-party/FFmpeg-iOS/include/libavcodec/mediacodec.h b/third-party/FFmpeg-iOS/include/libavcodec/mediacodec.h index 87bcfeb2d6..a12c366983 100644 --- a/third-party/FFmpeg-iOS/include/libavcodec/mediacodec.h +++ b/third-party/FFmpeg-iOS/include/libavcodec/mediacodec.h @@ -85,4 +85,17 @@ typedef struct MediaCodecBuffer AVMediaCodecBuffer; */ int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render); +/** + * Release a MediaCodec buffer and render it at the given time to the surface + * that is associated with the decoder. The timestamp must be within one second + * of the current java/lang/System#nanoTime() (which is implemented using + * CLOCK_MONOTONIC on Android). See the Android MediaCodec documentation + * of android/media/MediaCodec#releaseOutputBuffer(int,long) for more details. + * + * @param buffer the buffer to render + * @param time timestamp in nanoseconds of when to render the buffer + * @return 0 on success, < 0 otherwise + */ +int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time); + #endif /* AVCODEC_MEDIACODEC_H */ diff --git a/third-party/FFmpeg-iOS/include/libavcodec/vaapi.h b/third-party/FFmpeg-iOS/include/libavcodec/vaapi.h index 0c1879e596..ea9e0591a4 100644 --- a/third-party/FFmpeg-iOS/include/libavcodec/vaapi.h +++ b/third-party/FFmpeg-iOS/include/libavcodec/vaapi.h @@ -77,115 +77,6 @@ struct attribute_deprecated vaapi_context { * - decoding: Set by user */ uint32_t context_id; - -#if FF_API_VAAPI_CONTEXT - /** - * VAPictureParameterBuffer ID - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - uint32_t pic_param_buf_id; - - /** - * VAIQMatrixBuffer ID - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - uint32_t iq_matrix_buf_id; - - /** - * VABitPlaneBuffer ID (for VC-1 decoding) - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - uint32_t bitplane_buf_id; - - /** - * Slice parameter/data buffer IDs - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - uint32_t *slice_buf_ids; - - /** - * Number of effective slice buffer IDs to send to the HW - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - unsigned int n_slice_buf_ids; - - /** - * Size of pre-allocated slice_buf_ids - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - unsigned int slice_buf_ids_alloc; - - /** - * Pointer to VASliceParameterBuffers - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - void *slice_params; - - /** - * Size of a VASliceParameterBuffer element - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - unsigned int slice_param_size; - - /** - * Size of pre-allocated slice_params - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - unsigned int slice_params_alloc; - - /** - * Number of slices currently filled in - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - unsigned int slice_count; - - /** - * Pointer to slice data buffer base - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - const uint8_t *slice_data; - - /** - * Current size of slice data - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - attribute_deprecated - uint32_t slice_data_size; -#endif }; /* @} */ diff --git a/third-party/FFmpeg-iOS/include/libavcodec/vda.h b/third-party/FFmpeg-iOS/include/libavcodec/vda.h deleted file mode 100644 index 275ff8386f..0000000000 --- a/third-party/FFmpeg-iOS/include/libavcodec/vda.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * VDA HW acceleration - * - * copyright (c) 2011 Sebastien Zwickert - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VDA_H -#define AVCODEC_VDA_H - -/** - * @file - * @ingroup lavc_codec_hwaccel_vda - * Public libavcodec VDA header. - */ - -#include "../libavcodec/avcodec.h" - -#include - -// emmintrin.h is unable to compile with -std=c99 -Werror=missing-prototypes -// http://openradar.appspot.com/8026390 -#undef __GNUC_STDC_INLINE__ - -#define Picture QuickdrawPicture -#include -#undef Picture - -#include "../libavcodec/version.h" - -// extra flags not defined in VDADecoder.h -enum { - kVDADecodeInfo_Asynchronous = 1UL << 0, - kVDADecodeInfo_FrameDropped = 1UL << 1 -}; - -/** - * @defgroup lavc_codec_hwaccel_vda VDA - * @ingroup lavc_codec_hwaccel - * - * @{ - */ - -/** - * This structure is used to provide the necessary configurations and data - * to the VDA FFmpeg HWAccel implementation. - * - * The application must make it available as AVCodecContext.hwaccel_context. - */ -struct vda_context { - /** - * VDA decoder object. - * - * - encoding: unused - * - decoding: Set/Unset by libavcodec. - */ - VDADecoder decoder; - - /** - * The Core Video pixel buffer that contains the current image data. - * - * encoding: unused - * decoding: Set by libavcodec. Unset by user. - */ - CVPixelBufferRef cv_buffer; - - /** - * Use the hardware decoder in synchronous mode. - * - * encoding: unused - * decoding: Set by user. - */ - int use_sync_decoding; - - /** - * The frame width. - * - * - encoding: unused - * - decoding: Set/Unset by user. - */ - int width; - - /** - * The frame height. - * - * - encoding: unused - * - decoding: Set/Unset by user. - */ - int height; - - /** - * The frame format. - * - * - encoding: unused - * - decoding: Set/Unset by user. - */ - int format; - - /** - * The pixel format for output image buffers. - * - * - encoding: unused - * - decoding: Set/Unset by user. - */ - OSType cv_pix_fmt_type; - - /** - * unused - */ - uint8_t *priv_bitstream; - - /** - * unused - */ - int priv_bitstream_size; - - /** - * unused - */ - int priv_allocated_size; - - /** - * Use av_buffer to manage buffer. - * When the flag is set, the CVPixelBuffers returned by the decoder will - * be released automatically, so you have to retain them if necessary. - * Not setting this flag may cause memory leak. - * - * encoding: unused - * decoding: Set by user. - */ - int use_ref_buffer; -}; - -/** Create the video decoder. */ -int ff_vda_create_decoder(struct vda_context *vda_ctx, - uint8_t *extradata, - int extradata_size); - -/** Destroy the video decoder. */ -int ff_vda_destroy_decoder(struct vda_context *vda_ctx); - -/** - * This struct holds all the information that needs to be passed - * between the caller and libavcodec for initializing VDA decoding. - * Its size is not a part of the public ABI, it must be allocated with - * av_vda_alloc_context() and freed with av_free(). - */ -typedef struct AVVDAContext { - /** - * VDA decoder object. Created and freed by the caller. - */ - VDADecoder decoder; - - /** - * The output callback that must be passed to VDADecoderCreate. - * Set by av_vda_alloc_context(). - */ - VDADecoderOutputCallback output_callback; - - /** - * CVPixelBuffer Format Type that VDA will use for decoded frames; set by - * the caller. - */ - OSType cv_pix_fmt_type; -} AVVDAContext; - -/** - * Allocate and initialize a VDA context. - * - * This function should be called from the get_format() callback when the caller - * selects the AV_PIX_FMT_VDA format. The caller must then create the decoder - * object (using the output callback provided by libavcodec) that will be used - * for VDA-accelerated decoding. - * - * When decoding with VDA is finished, the caller must destroy the decoder - * object and free the VDA context using av_free(). - * - * @return the newly allocated context or NULL on failure - */ -AVVDAContext *av_vda_alloc_context(void); - -/** - * This is a convenience function that creates and sets up the VDA context using - * an internal implementation. - * - * @param avctx the corresponding codec context - * - * @return >= 0 on success, a negative AVERROR code on failure - */ -int av_vda_default_init(AVCodecContext *avctx); - -/** - * This is a convenience function that creates and sets up the VDA context using - * an internal implementation. - * - * @param avctx the corresponding codec context - * @param vdactx the VDA context to use - * - * @return >= 0 on success, a negative AVERROR code on failure - */ -int av_vda_default_init2(AVCodecContext *avctx, AVVDAContext *vdactx); - -/** - * This function must be called to free the VDA context initialized with - * av_vda_default_init(). - * - * @param avctx the corresponding codec context - */ -void av_vda_default_free(AVCodecContext *avctx); - -/** - * @} - */ - -#endif /* AVCODEC_VDA_H */ diff --git a/third-party/FFmpeg-iOS/include/libavcodec/vdpau.h b/third-party/FFmpeg-iOS/include/libavcodec/vdpau.h index afcda19a04..61d295de69 100644 --- a/third-party/FFmpeg-iOS/include/libavcodec/vdpau.h +++ b/third-party/FFmpeg-iOS/include/libavcodec/vdpau.h @@ -57,15 +57,6 @@ #include "avcodec.h" #include "version.h" -#if FF_API_BUFS_VDPAU -union AVVDPAUPictureInfo { - VdpPictureInfoH264 h264; - VdpPictureInfoMPEG1Or2 mpeg; - VdpPictureInfoVC1 vc1; - VdpPictureInfoMPEG4Part2 mpeg4; -}; -#endif - struct AVCodecContext; struct AVFrame; @@ -102,40 +93,6 @@ typedef struct AVVDPAUContext { */ VdpDecoderRender *render; -#if FF_API_BUFS_VDPAU - /** - * VDPAU picture information - * - * Set by libavcodec. - */ - attribute_deprecated - union AVVDPAUPictureInfo info; - - /** - * Allocated size of the bitstream_buffers table. - * - * Set by libavcodec. - */ - attribute_deprecated - int bitstream_buffers_allocated; - - /** - * Useful bitstream buffers in the bitstream buffers table. - * - * Set by libavcodec. - */ - attribute_deprecated - int bitstream_buffers_used; - - /** - * Table of bitstream buffers. - * The user is responsible for freeing this buffer using av_freep(). - * - * Set by libavcodec. - */ - attribute_deprecated - VdpBitstreamBuffer *bitstream_buffers; -#endif AVVDPAU_Render2 render2; } AVVDPAUContext; @@ -214,40 +171,6 @@ attribute_deprecated int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile); #endif -#if FF_API_CAP_VDPAU -/** @brief The videoSurface is used for rendering. */ -#define FF_VDPAU_STATE_USED_FOR_RENDER 1 - -/** - * @brief The videoSurface is needed for reference/prediction. - * The codec manipulates this. - */ -#define FF_VDPAU_STATE_USED_FOR_REFERENCE 2 - -/** - * @brief This structure is used as a callback between the FFmpeg - * decoder (vd_) and presentation (vo_) module. - * This is used for defining a video frame containing surface, - * picture parameter, bitstream information etc which are passed - * between the FFmpeg decoder and its clients. - */ -struct vdpau_render_state { - VdpVideoSurface surface; ///< Used as rendered surface, never changed. - - int state; ///< Holds FF_VDPAU_STATE_* values. - - /** picture parameter information for all supported codecs */ - union AVVDPAUPictureInfo info; - - /** Describe size/location of the compressed video data. - Set to 0 when freeing bitstream_buffers. */ - int bitstream_buffers_allocated; - int bitstream_buffers_used; - /** The user is responsible for freeing this buffer using av_freep(). */ - VdpBitstreamBuffer *bitstream_buffers; -}; -#endif - /* @}*/ #endif /* AVCODEC_VDPAU_H */ diff --git a/third-party/FFmpeg-iOS/include/libavcodec/version.h b/third-party/FFmpeg-iOS/include/libavcodec/version.h index 3c884f1db6..68317a645c 100644 --- a/third-party/FFmpeg-iOS/include/libavcodec/version.h +++ b/third-party/FFmpeg-iOS/include/libavcodec/version.h @@ -27,8 +27,8 @@ #include "../libavutil/version.h" -#define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 107 +#define LIBAVCODEC_VERSION_MAJOR 58 +#define LIBAVCODEC_VERSION_MINOR 35 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ @@ -51,136 +51,18 @@ * at once through the bump. This improves the git bisect-ability of the change. */ -#ifndef FF_API_VIMA_DECODER -#define FF_API_VIMA_DECODER (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_AUDIO_CONVERT -#define FF_API_AUDIO_CONVERT (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_AVCODEC_RESAMPLE -#define FF_API_AVCODEC_RESAMPLE FF_API_AUDIO_CONVERT -#endif -#ifndef FF_API_MISSING_SAMPLE -#define FF_API_MISSING_SAMPLE (LIBAVCODEC_VERSION_MAJOR < 58) -#endif #ifndef FF_API_LOWRES -#define FF_API_LOWRES (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_CAP_VDPAU -#define FF_API_CAP_VDPAU (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_BUFS_VDPAU -#define FF_API_BUFS_VDPAU (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_VOXWARE -#define FF_API_VOXWARE (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_SET_DIMENSIONS -#define FF_API_SET_DIMENSIONS (LIBAVCODEC_VERSION_MAJOR < 58) +#define FF_API_LOWRES (LIBAVCODEC_VERSION_MAJOR < 59) #endif #ifndef FF_API_DEBUG_MV #define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 58) #endif -#ifndef FF_API_AC_VLC -#define FF_API_AC_VLC (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_OLD_MSMPEG4 -#define FF_API_OLD_MSMPEG4 (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_ASPECT_EXTENDED -#define FF_API_ASPECT_EXTENDED (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_ARCH_ALPHA -#define FF_API_ARCH_ALPHA (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_XVMC -#define FF_API_XVMC (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_ERROR_RATE -#define FF_API_ERROR_RATE (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_QSCALE_TYPE -#define FF_API_QSCALE_TYPE (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_MB_TYPE -#define FF_API_MB_TYPE (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_MAX_BFRAMES -#define FF_API_MAX_BFRAMES (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_NEG_LINESIZES -#define FF_API_NEG_LINESIZES (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_EMU_EDGE -#define FF_API_EMU_EDGE (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_ARCH_SH4 -#define FF_API_ARCH_SH4 (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_ARCH_SPARC -#define FF_API_ARCH_SPARC (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_UNUSED_MEMBERS -#define FF_API_UNUSED_MEMBERS (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_IDCT_XVIDMMX -#define FF_API_IDCT_XVIDMMX (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_INPUT_PRESERVED -#define FF_API_INPUT_PRESERVED (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_NORMALIZE_AQP -#define FF_API_NORMALIZE_AQP (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_GMC -#define FF_API_GMC (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_MV0 -#define FF_API_MV0 (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_CODEC_NAME -#define FF_API_CODEC_NAME (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_AFD -#define FF_API_AFD (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_VISMV -/* XXX: don't forget to drop the -vismv documentation */ -#define FF_API_VISMV (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_AUDIOENC_DELAY -#define FF_API_AUDIOENC_DELAY (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_VAAPI_CONTEXT -#define FF_API_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_MERGE_SD -#define FF_API_MERGE_SD (LIBAVCODEC_VERSION_MAJOR < 58) -#endif #ifndef FF_API_AVCTX_TIMEBASE #define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59) #endif -#ifndef FF_API_MPV_OPT -#define FF_API_MPV_OPT (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_STREAM_CODEC_TAG -#define FF_API_STREAM_CODEC_TAG (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_QUANT_BIAS -#define FF_API_QUANT_BIAS (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_RC_STRATEGY -#define FF_API_RC_STRATEGY (LIBAVCODEC_VERSION_MAJOR < 59) -#endif #ifndef FF_API_CODED_FRAME #define FF_API_CODED_FRAME (LIBAVCODEC_VERSION_MAJOR < 59) #endif -#ifndef FF_API_MOTION_EST -#define FF_API_MOTION_EST (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_WITHOUT_PREFIX -#define FF_API_WITHOUT_PREFIX (LIBAVCODEC_VERSION_MAJOR < 59) -#endif #ifndef FF_API_SIDEDATA_ONLY_PKT #define FF_API_SIDEDATA_ONLY_PKT (LIBAVCODEC_VERSION_MAJOR < 59) #endif @@ -238,6 +120,18 @@ #ifndef FF_API_GETCHROMA #define FF_API_GETCHROMA (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_CODEC_GET_SET +#define FF_API_CODEC_GET_SET (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_USER_VISIBLE_AVHWACCEL +#define FF_API_USER_VISIBLE_AVHWACCEL (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_LOCKMGR +#define FF_API_LOCKMGR (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_NEXT +#define FF_API_NEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif #endif /* AVCODEC_VERSION_H */ diff --git a/third-party/FFmpeg-iOS/include/libavformat/avformat.h b/third-party/FFmpeg-iOS/include/libavformat/avformat.h index 23c82b477c..1cd840a16e 100644 --- a/third-party/FFmpeg-iOS/include/libavformat/avformat.h +++ b/third-party/FFmpeg-iOS/include/libavformat/avformat.h @@ -437,19 +437,6 @@ int av_get_packet(AVIOContext *s, AVPacket *pkt, int size); */ int av_append_packet(AVIOContext *s, AVPacket *pkt, int size); -#if FF_API_LAVF_FRAC -/*************************************************/ -/* fractional numbers for exact pts handling */ - -/** - * The exact value of the fractional number is: 'val + num / den'. - * num is assumed to be 0 <= num < den. - */ -typedef struct AVFrac { - int64_t val, num, den; -} AVFrac; -#endif - /*************************************************/ /* input/output formats */ @@ -478,10 +465,6 @@ typedef struct AVProbeData { #define AVFMT_NOFILE 0x0001 #define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */ #define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */ -#if FF_API_LAVF_FMT_RAWPICTURE -#define AVFMT_RAWPICTURE 0x0020 /**< Format wants AVPicture structure for - raw picture data. @deprecated Not used anymore */ -#endif #define AVFMT_GLOBALHEADER 0x0040 /**< Format wants global header. */ #define AVFMT_NOTIMESTAMPS 0x0080 /**< Format does not need / have any timestamps. */ #define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */ @@ -802,9 +785,9 @@ enum AVStreamParseType { AVSTREAM_PARSE_HEADERS, /**< Only parse headers, do not repack. */ AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */ AVSTREAM_PARSE_FULL_ONCE, /**< full parsing and repack of the first frame only, only implemented for H.264 currently */ - AVSTREAM_PARSE_FULL_RAW=MKTAG(0,'R','A','W'), /**< full parsing and repack with timestamp and position generation by parser for raw - this assumes that each packet in the file contains no demuxer level headers and - just codec level data, otherwise position generation would fail */ + AVSTREAM_PARSE_FULL_RAW, /**< full parsing and repack with timestamp and position generation by parser for raw + this assumes that each packet in the file contains no demuxer level headers and + just codec level data, otherwise position generation would fail */ }; typedef struct AVIndexEntry { @@ -862,6 +845,8 @@ typedef struct AVStreamInternal AVStreamInternal; #define AV_DISPOSITION_CAPTIONS 0x10000 #define AV_DISPOSITION_DESCRIPTIONS 0x20000 #define AV_DISPOSITION_METADATA 0x40000 +#define AV_DISPOSITION_DEPENDENT 0x80000 ///< dependent audio stream (mix_type=0 in mpegts) +#define AV_DISPOSITION_STILL_IMAGE 0x100000 ///< still images in video stream (still_picture_flag=1 in mpegts) /** * Options for behavior on timestamp wrap detection. @@ -894,14 +879,6 @@ typedef struct AVStream { #endif void *priv_data; -#if FF_API_LAVF_FRAC - /** - * @deprecated this field is unused - */ - attribute_deprecated - struct AVFrac pts; -#endif - /** * This is the fundamental unit of time (in seconds) in terms * of which frame timestamps are represented. @@ -1001,6 +978,39 @@ typedef struct AVStream { int event_flags; #define AVSTREAM_EVENT_FLAG_METADATA_UPDATED 0x0001 ///< The call resulted in updated metadata. + /** + * Real base framerate of the stream. + * This is the lowest framerate with which all timestamps can be + * represented accurately (it is the least common multiple of all + * framerates in the stream). Note, this value is just a guess! + * For example, if the time base is 1/90000 and all frames have either + * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1. + */ + AVRational r_frame_rate; + +#if FF_API_LAVF_FFSERVER + /** + * String containing pairs of key and values describing recommended encoder configuration. + * Pairs are separated by ','. + * Keys are separated from values by '='. + * + * @deprecated unused + */ + attribute_deprecated + char *recommended_encoder_configuration; +#endif + + /** + * Codec parameters associated with this stream. Allocated and freed by + * libavformat in avformat_new_stream() and avformat_free_context() + * respectively. + * + * - demuxing: filled by libavformat on stream creation or in + * avformat_find_stream_info() + * - muxing: filled by the caller before avformat_write_header() + */ + AVCodecParameters *codecpar; + /***************************************************************** * All fields below this line are not part of the public API. They * may not be used outside of libavformat and can be changed and @@ -1011,10 +1021,10 @@ typedef struct AVStream { ***************************************************************** */ +#define MAX_STD_TIMEBASES (30*12+30+3+6) /** * Stream information used internally by avformat_find_stream_info() */ -#define MAX_STD_TIMEBASES (30*12+30+3+6) struct { int64_t last_dts; int64_t duration_gcd; @@ -1023,6 +1033,7 @@ typedef struct AVStream { double (*duration_error)[2][MAX_STD_TIMEBASES]; int64_t codec_info_duration; int64_t codec_info_duration_fields; + int frame_delay_evidence; /** * 0 -> decoder has not been searched for yet. @@ -1085,19 +1096,6 @@ typedef struct AVStream { int nb_index_entries; unsigned int index_entries_allocated_size; - /** - * Real base framerate of the stream. - * This is the lowest framerate with which all timestamps can be - * represented accurately (it is the least common multiple of all - * framerates in the stream). Note, this value is just a guess! - * For example, if the time base is 1/90000 and all frames have either - * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1. - * - * Code outside avformat should access this field using: - * av_stream_get/set_r_frame_rate(stream) - */ - AVRational r_frame_rate; - /** * Stream Identifier * This is the MPEG-TS stream identifier +1 @@ -1105,6 +1103,13 @@ typedef struct AVStream { */ int stream_identifier; + /** + * Details of the MPEG-TS program which created this stream. + */ + int program_num; + int pmt_version; + int pmt_stream_idx; + int64_t interleaver_chunk_size; int64_t interleaver_chunk_duration; @@ -1203,19 +1208,6 @@ typedef struct AVStream { */ int inject_global_side_data; - /***************************************************************** - * All fields above this line are not part of the public API. - * Fields below are part of the public API and ABI again. - ***************************************************************** - */ - - /** - * String containing paris of key and values describing recommended encoder configuration. - * Paris are separated by ','. - * Keys are separated from values by '='. - */ - char *recommended_encoder_configuration; - /** * display aspect ratio (0 if unknown) * - encoding: unused @@ -1223,31 +1215,31 @@ typedef struct AVStream { */ AVRational display_aspect_ratio; - struct FFFrac *priv_pts; - /** * An opaque field for libavformat internal usage. * Must not be accessed in any way by callers. */ AVStreamInternal *internal; - - /* - * Codec parameters associated with this stream. Allocated and freed by - * libavformat in avformat_new_stream() and avformat_free_context() - * respectively. - * - * - demuxing: filled by libavformat on stream creation or in - * avformat_find_stream_info() - * - muxing: filled by the caller before avformat_write_header() - */ - AVCodecParameters *codecpar; } AVStream; +#if FF_API_FORMAT_GET_SET +/** + * Accessors for some AVStream fields. These used to be provided for ABI + * compatibility, and do not need to be used anymore. + */ +attribute_deprecated AVRational av_stream_get_r_frame_rate(const AVStream *s); +attribute_deprecated void av_stream_set_r_frame_rate(AVStream *s, AVRational r); -struct AVCodecParserContext *av_stream_get_parser(const AVStream *s); +#if FF_API_LAVF_FFSERVER +attribute_deprecated char* av_stream_get_recommended_encoder_configuration(const AVStream *s); +attribute_deprecated void av_stream_set_recommended_encoder_configuration(AVStream *s, char *configuration); +#endif +#endif + +struct AVCodecParserContext *av_stream_get_parser(const AVStream *s); /** * Returns the pts of the last muxed packet + its duration @@ -1275,6 +1267,7 @@ typedef struct AVProgram { int program_num; int pmt_pid; int pcr_pid; + int pmt_version; /***************************************************************** * All fields below this line are not part of the public API. They @@ -1292,6 +1285,11 @@ typedef struct AVProgram { #define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present (streams are added dynamically) */ +#define AVFMTCTX_UNSEEKABLE 0x0002 /**< signal that the stream is definitely + not seekable, and attempts to call the + seek function will fail. For some + network protocols (e.g. HLS), this can + change dynamically at runtime. */ typedef struct AVChapter { int id; ///< unique ID to identify the chapter @@ -1406,13 +1404,33 @@ typedef struct AVFormatContext { */ AVStream **streams; +#if FF_API_FORMAT_FILENAME /** * input or output filename * * - demuxing: set by avformat_open_input() * - muxing: may be set by the caller before avformat_write_header() + * + * @deprecated Use url instead. */ + attribute_deprecated char filename[1024]; +#endif + + /** + * input or output URL. Unlike the old filename field, this field has no + * length restriction. + * + * - demuxing: set by avformat_open_input(), initialized to an empty + * string if url parameter was NULL in avformat_open_input(). + * - muxing: may be set by the caller before calling avformat_write_header() + * (or avformat_init_output() if that is called first) to a string + * which is freeable by av_free(). Set to an empty string if it + * was NULL in avformat_init_output(). + * + * Freed by libavformat in avformat_free_context(). + */ + char *url; /** * Position of the first frame of the component, in @@ -1465,15 +1483,17 @@ typedef struct AVFormatContext { * This flag is mainly intended for testing. */ #define AVFMT_FLAG_BITEXACT 0x0400 -#define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload +#if FF_API_LAVF_MP4A_LATM +#define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Deprecated, does nothing. +#endif #define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down) #define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted) #if FF_API_LAVF_KEEPSIDE_FLAG -#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Don't merge side data but keep it separate. Deprecated, will be the default. +#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Deprecated, does nothing. #endif #define AVFMT_FLAG_FAST_SEEK 0x80000 ///< Enable fast, but inaccurate seeks for some formats #define AVFMT_FLAG_SHORTEST 0x100000 ///< Stop muxing when the shortest stream stops. -#define AVFMT_FLAG_AUTO_BSF 0x200000 ///< Wait for packet data before writing a header, and add bitstream filters as requested by the muxer +#define AVFMT_FLAG_AUTO_BSF 0x200000 ///< Add bitstream filters as requested by the muxer /** * Maximum size of the data read from input for determining @@ -1876,7 +1896,7 @@ typedef struct AVFormatContext { */ char *protocol_whitelist; - /* + /** * A callback for opening new IO streams. * * Whenever a muxer or a demuxer needs to open an IO stream (typically from @@ -1917,31 +1937,55 @@ typedef struct AVFormatContext { * - decoding: set by user */ int max_streams; + + /** + * Skip duration calcuation in estimate_timings_from_pts. + * - encoding: unused + * - decoding: set by user + */ + int skip_estimate_duration_from_pts; } AVFormatContext; +#if FF_API_FORMAT_GET_SET /** * Accessors for some AVFormatContext fields. These used to be provided for ABI * compatibility, and do not need to be used anymore. */ +attribute_deprecated int av_format_get_probe_score(const AVFormatContext *s); +attribute_deprecated AVCodec * av_format_get_video_codec(const AVFormatContext *s); +attribute_deprecated void av_format_set_video_codec(AVFormatContext *s, AVCodec *c); +attribute_deprecated AVCodec * av_format_get_audio_codec(const AVFormatContext *s); +attribute_deprecated void av_format_set_audio_codec(AVFormatContext *s, AVCodec *c); +attribute_deprecated AVCodec * av_format_get_subtitle_codec(const AVFormatContext *s); +attribute_deprecated void av_format_set_subtitle_codec(AVFormatContext *s, AVCodec *c); +attribute_deprecated AVCodec * av_format_get_data_codec(const AVFormatContext *s); +attribute_deprecated void av_format_set_data_codec(AVFormatContext *s, AVCodec *c); +attribute_deprecated int av_format_get_metadata_header_padding(const AVFormatContext *s); +attribute_deprecated void av_format_set_metadata_header_padding(AVFormatContext *s, int c); +attribute_deprecated void * av_format_get_opaque(const AVFormatContext *s); +attribute_deprecated void av_format_set_opaque(AVFormatContext *s, void *opaque); +attribute_deprecated av_format_control_message av_format_get_control_message_cb(const AVFormatContext *s); +attribute_deprecated void av_format_set_control_message_cb(AVFormatContext *s, av_format_control_message callback); #if FF_API_OLD_OPEN_CALLBACKS attribute_deprecated AVOpenCallback av_format_get_open_cb(const AVFormatContext *s); attribute_deprecated void av_format_set_open_cb(AVFormatContext *s, AVOpenCallback callback); #endif +#endif /** * This function will cause global side data to be injected in the next packet @@ -1986,6 +2030,7 @@ const char *avformat_configuration(void); */ const char *avformat_license(void); +#if FF_API_NEXT /** * Initialize libavformat and register all the muxers, demuxers and * protocols. If you do not call this function, then you can select @@ -1994,31 +2039,44 @@ const char *avformat_license(void); * @see av_register_input_format() * @see av_register_output_format() */ +attribute_deprecated void av_register_all(void); +attribute_deprecated void av_register_input_format(AVInputFormat *format); +attribute_deprecated void av_register_output_format(AVOutputFormat *format); +#endif /** - * Do global initialization of network components. This is optional, - * but recommended, since it avoids the overhead of implicitly - * doing the setup for each session. + * Do global initialization of network libraries. This is optional, + * and not recommended anymore. * - * Calling this function will become mandatory if using network - * protocols at some major version bump. + * This functions only exists to work around thread-safety issues + * with older GnuTLS or OpenSSL libraries. If libavformat is linked + * to newer versions of those libraries, or if you do not use them, + * calling this function is unnecessary. Otherwise, you need to call + * this function before any other threads using them are started. + * + * This function will be deprecated once support for older GnuTLS and + * OpenSSL libraries is removed, and this function has no purpose + * anymore. */ int avformat_network_init(void); /** - * Undo the initialization done by avformat_network_init. + * Undo the initialization done by avformat_network_init. Call it only + * once for each time you called avformat_network_init. */ int avformat_network_deinit(void); +#if FF_API_NEXT /** * If f is NULL, returns the first registered input format, * if f is non-NULL, returns the next registered input format after f * or NULL if f is the last one. */ +attribute_deprecated AVInputFormat *av_iformat_next(const AVInputFormat *f); /** @@ -2026,7 +2084,31 @@ AVInputFormat *av_iformat_next(const AVInputFormat *f); * if f is non-NULL, returns the next registered output format after f * or NULL if f is the last one. */ +attribute_deprecated AVOutputFormat *av_oformat_next(const AVOutputFormat *f); +#endif + +/** + * Iterate over all registered muxers. + * + * @param opaque a pointer where libavformat will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered muxer or NULL when the iteration is + * finished + */ +const AVOutputFormat *av_muxer_iterate(void **opaque); + +/** + * Iterate over all registered demuxers. + * + * @param opaque a pointer where libavformat will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered demuxer or NULL when the iteration is + * finished + */ +const AVInputFormat *av_demuxer_iterate(void **opaque); /** * Allocate an AVFormatContext. @@ -2103,13 +2185,8 @@ uint8_t *av_stream_new_side_data(AVStream *stream, * @param size pointer for side information size to store (optional) * @return pointer to data if present or NULL otherwise */ -#if FF_API_NOCONST_GET_SIDE_DATA -uint8_t *av_stream_get_side_data(AVStream *stream, - enum AVPacketSideDataType type, int *size); -#else uint8_t *av_stream_get_side_data(const AVStream *stream, enum AVPacketSideDataType type, int *size); -#endif AVProgram *av_new_program(AVFormatContext *s, int id); diff --git a/third-party/FFmpeg-iOS/include/libavformat/avio.h b/third-party/FFmpeg-iOS/include/libavformat/avio.h index b4eeffcb50..f32e23cfbf 100644 --- a/third-party/FFmpeg-iOS/include/libavformat/avio.h +++ b/third-party/FFmpeg-iOS/include/libavformat/avio.h @@ -236,7 +236,6 @@ typedef struct AVIOContext { int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); int64_t (*seek)(void *opaque, int64_t offset, int whence); int64_t pos; /**< position in the file of the current buffer */ - int must_flush; /**< unused */ int eof_reached; /**< true if eof reached */ int write_flag; /**< true if open for writing */ int max_packet_size; @@ -452,6 +451,8 @@ void avio_free_directory_entry(AVIODirEntry **entry); * @param write_flag Set to 1 if the buffer should be writable, 0 otherwise. * @param opaque An opaque pointer to user-specific data. * @param read_packet A function for refilling the buffer, may be NULL. + * For stream protocols, must never return 0 but rather + * a proper AVERROR code. * @param write_packet A function for writing the buffer contents, may be NULL. * The function may not change the input buffers content. * @param seek A function for seeking to specified byte position, may be NULL. @@ -569,13 +570,6 @@ int64_t avio_size(AVIOContext *s); * @return non zero if and only if end of file */ int avio_feof(AVIOContext *s); -#if FF_API_URL_FEOF -/** - * @deprecated use avio_feof() - */ -attribute_deprecated -int url_feof(AVIOContext *s); -#endif /** @warning Writes up to 4 KiB per call */ int avio_printf(AVIOContext *s, const char *fmt, ...) av_printf_format(2, 3); diff --git a/third-party/FFmpeg-iOS/include/libavformat/version.h b/third-party/FFmpeg-iOS/include/libavformat/version.h index c2f33f84ae..f103584c2c 100644 --- a/third-party/FFmpeg-iOS/include/libavformat/version.h +++ b/third-party/FFmpeg-iOS/include/libavformat/version.h @@ -31,8 +31,8 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here -#define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 83 +#define LIBAVFORMAT_VERSION_MAJOR 58 +#define LIBAVFORMAT_VERSION_MINOR 20 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ @@ -55,47 +55,53 @@ * at once through the bump. This improves the git bisect-ability of the change. * */ -#ifndef FF_API_LAVF_BITEXACT -#define FF_API_LAVF_BITEXACT (LIBAVFORMAT_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_LAVF_FRAC -#define FF_API_LAVF_FRAC (LIBAVFORMAT_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_LAVF_CODEC_TB -#define FF_API_LAVF_CODEC_TB (LIBAVFORMAT_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_URL_FEOF -#define FF_API_URL_FEOF (LIBAVFORMAT_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_LAVF_FMT_RAWPICTURE -#define FF_API_LAVF_FMT_RAWPICTURE (LIBAVFORMAT_VERSION_MAJOR < 58) -#endif #ifndef FF_API_COMPUTE_PKT_FIELDS2 -#define FF_API_COMPUTE_PKT_FIELDS2 (LIBAVFORMAT_VERSION_MAJOR < 58) +#define FF_API_COMPUTE_PKT_FIELDS2 (LIBAVFORMAT_VERSION_MAJOR < 59) #endif #ifndef FF_API_OLD_OPEN_CALLBACKS -#define FF_API_OLD_OPEN_CALLBACKS (LIBAVFORMAT_VERSION_MAJOR < 58) +#define FF_API_OLD_OPEN_CALLBACKS (LIBAVFORMAT_VERSION_MAJOR < 59) #endif #ifndef FF_API_LAVF_AVCTX -#define FF_API_LAVF_AVCTX (LIBAVFORMAT_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_NOCONST_GET_SIDE_DATA -#define FF_API_NOCONST_GET_SIDE_DATA (LIBAVFORMAT_VERSION_MAJOR < 58) +#define FF_API_LAVF_AVCTX (LIBAVFORMAT_VERSION_MAJOR < 59) #endif #ifndef FF_API_HTTP_USER_AGENT -#define FF_API_HTTP_USER_AGENT (LIBAVFORMAT_VERSION_MAJOR < 58) +#define FF_API_HTTP_USER_AGENT (LIBAVFORMAT_VERSION_MAJOR < 59) #endif #ifndef FF_API_HLS_WRAP -#define FF_API_HLS_WRAP (LIBAVFORMAT_VERSION_MAJOR < 58) +#define FF_API_HLS_WRAP (LIBAVFORMAT_VERSION_MAJOR < 59) #endif -#ifndef FF_API_LAVF_MERGE_SD -#define FF_API_LAVF_MERGE_SD (LIBAVFORMAT_VERSION_MAJOR < 58) +#ifndef FF_API_HLS_USE_LOCALTIME +#define FF_API_HLS_USE_LOCALTIME (LIBAVFORMAT_VERSION_MAJOR < 59) #endif #ifndef FF_API_LAVF_KEEPSIDE_FLAG -#define FF_API_LAVF_KEEPSIDE_FLAG (LIBAVFORMAT_VERSION_MAJOR < 58) +#define FF_API_LAVF_KEEPSIDE_FLAG (LIBAVFORMAT_VERSION_MAJOR < 59) #endif #ifndef FF_API_OLD_ROTATE_API -#define FF_API_OLD_ROTATE_API (LIBAVFORMAT_VERSION_MAJOR < 58) +#define FF_API_OLD_ROTATE_API (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_FORMAT_GET_SET +#define FF_API_FORMAT_GET_SET (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OLD_AVIO_EOF_0 +#define FF_API_OLD_AVIO_EOF_0 (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_LAVF_FFSERVER +#define FF_API_LAVF_FFSERVER (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_FORMAT_FILENAME +#define FF_API_FORMAT_FILENAME (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OLD_RTSP_OPTIONS +#define FF_API_OLD_RTSP_OPTIONS (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_NEXT +#define FF_API_NEXT (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_DASH_MIN_SEG_DURATION +#define FF_API_DASH_MIN_SEG_DURATION (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_LAVF_MP4A_LATM +#define FF_API_LAVF_MP4A_LATM (LIBAVFORMAT_VERSION_MAJOR < 59) #endif diff --git a/third-party/FFmpeg-iOS/include/libavutil/aes_ctr.h b/third-party/FFmpeg-iOS/include/libavutil/aes_ctr.h index f596fa6a46..e4aae126a7 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/aes_ctr.h +++ b/third-party/FFmpeg-iOS/include/libavutil/aes_ctr.h @@ -67,10 +67,15 @@ const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR *a); void av_aes_ctr_set_random_iv(struct AVAESCTR *a); /** - * Forcefully change the iv + * Forcefully change the 8-byte iv */ void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv); +/** + * Forcefully change the "full" 16-byte iv, including the counter + */ +void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t* iv); + /** * Increment the top 64 bit of the iv (performed after each frame) */ diff --git a/third-party/FFmpeg-iOS/include/libavutil/attributes.h b/third-party/FFmpeg-iOS/include/libavutil/attributes.h index 54d1901116..ced108aa2c 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/attributes.h +++ b/third-party/FFmpeg-iOS/include/libavutil/attributes.h @@ -66,19 +66,19 @@ # define av_noinline #endif -#if AV_GCC_VERSION_AT_LEAST(3,1) +#if AV_GCC_VERSION_AT_LEAST(3,1) || defined(__clang__) # define av_pure __attribute__((pure)) #else # define av_pure #endif -#if AV_GCC_VERSION_AT_LEAST(2,6) +#if AV_GCC_VERSION_AT_LEAST(2,6) || defined(__clang__) # define av_const __attribute__((const)) #else # define av_const #endif -#if AV_GCC_VERSION_AT_LEAST(4,3) +#if AV_GCC_VERSION_AT_LEAST(4,3) || defined(__clang__) # define av_cold __attribute__((cold)) #else # define av_cold @@ -138,19 +138,19 @@ # define av_used #endif -#if AV_GCC_VERSION_AT_LEAST(3,3) +#if AV_GCC_VERSION_AT_LEAST(3,3) || defined(__clang__) # define av_alias __attribute__((may_alias)) #else # define av_alias #endif -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__INTEL_COMPILER) # define av_uninit(x) x=x #else # define av_uninit(x) x #endif -#ifdef __GNUC__ +#if defined(__GNUC__) || defined(__clang__) # define av_builtin_constant_p __builtin_constant_p # define av_printf_format(fmtpos, attrpos) __attribute__((__format__(__printf__, fmtpos, attrpos))) #else @@ -158,7 +158,7 @@ # define av_printf_format(fmtpos, attrpos) #endif -#if AV_GCC_VERSION_AT_LEAST(2,5) +#if AV_GCC_VERSION_AT_LEAST(2,5) || defined(__clang__) # define av_noreturn __attribute__((noreturn)) #else # define av_noreturn diff --git a/third-party/FFmpeg-iOS/include/libavutil/avassert.h b/third-party/FFmpeg-iOS/include/libavutil/avassert.h index 46f3fea580..9abeadea4a 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/avassert.h +++ b/third-party/FFmpeg-iOS/include/libavutil/avassert.h @@ -66,7 +66,7 @@ #endif /** - * Assert that floating point opperations can be executed. + * Assert that floating point operations can be executed. * * This will av_assert0() that the cpu is not in MMX state on X86 */ diff --git a/third-party/FFmpeg-iOS/include/libavutil/avconfig.h b/third-party/FFmpeg-iOS/include/libavutil/avconfig.h index f10aa6186b..c289fbb551 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/avconfig.h +++ b/third-party/FFmpeg-iOS/include/libavutil/avconfig.h @@ -1,4 +1,4 @@ -/* Generated by ffconf */ +/* Generated by ffmpeg configure */ #ifndef AVUTIL_AVCONFIG_H #define AVUTIL_AVCONFIG_H #define AV_HAVE_BIGENDIAN 0 diff --git a/third-party/FFmpeg-iOS/include/libavutil/common.h b/third-party/FFmpeg-iOS/include/libavutil/common.h index c9b3f21a44..d95c3382f3 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/common.h +++ b/third-party/FFmpeg-iOS/include/libavutil/common.h @@ -158,7 +158,7 @@ static av_always_inline av_const int64_t av_clip64_c(int64_t a, int64_t amin, in */ static av_always_inline av_const uint8_t av_clip_uint8_c(int a) { - if (a&(~0xFF)) return (-a)>>31; + if (a&(~0xFF)) return (~a)>>31; else return a; } @@ -180,7 +180,7 @@ static av_always_inline av_const int8_t av_clip_int8_c(int a) */ static av_always_inline av_const uint16_t av_clip_uint16_c(int a) { - if (a&(~0xFFFF)) return (-a)>>31; + if (a&(~0xFFFF)) return (~a)>>31; else return a; } @@ -228,7 +228,7 @@ static av_always_inline av_const int av_clip_intp2_c(int a, int p) */ static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p) { - if (a & ~((1<> 31 & ((1<> 31 & ((1< +#include + +typedef struct AVSubsampleEncryptionInfo { + /** The number of bytes that are clear. */ + unsigned int bytes_of_clear_data; + + /** + * The number of bytes that are protected. If using pattern encryption, + * the pattern applies to only the protected bytes; if not using pattern + * encryption, all these bytes are encrypted. + */ + unsigned int bytes_of_protected_data; +} AVSubsampleEncryptionInfo; + +/** + * This describes encryption info for a packet. This contains frame-specific + * info for how to decrypt the packet before passing it to the decoder. + * + * The size of this struct is not part of the public ABI. + */ +typedef struct AVEncryptionInfo { + /** The fourcc encryption scheme, in big-endian byte order. */ + uint32_t scheme; + + /** + * Only used for pattern encryption. This is the number of 16-byte blocks + * that are encrypted. + */ + uint32_t crypt_byte_block; + + /** + * Only used for pattern encryption. This is the number of 16-byte blocks + * that are clear. + */ + uint32_t skip_byte_block; + + /** + * The ID of the key used to encrypt the packet. This should always be + * 16 bytes long, but may be changed in the future. + */ + uint8_t *key_id; + uint32_t key_id_size; + + /** + * The initialization vector. This may have been zero-filled to be the + * correct block size. This should always be 16 bytes long, but may be + * changed in the future. + */ + uint8_t *iv; + uint32_t iv_size; + + /** + * An array of subsample encryption info specifying how parts of the sample + * are encrypted. If there are no subsamples, then the whole sample is + * encrypted. + */ + AVSubsampleEncryptionInfo *subsamples; + uint32_t subsample_count; +} AVEncryptionInfo; + +/** + * This describes info used to initialize an encryption key system. + * + * The size of this struct is not part of the public ABI. + */ +typedef struct AVEncryptionInitInfo { + /** + * A unique identifier for the key system this is for, can be NULL if it + * is not known. This should always be 16 bytes, but may change in the + * future. + */ + uint8_t* system_id; + uint32_t system_id_size; + + /** + * An array of key IDs this initialization data is for. All IDs are the + * same length. Can be NULL if there are no known key IDs. + */ + uint8_t** key_ids; + /** The number of key IDs. */ + uint32_t num_key_ids; + /** + * The number of bytes in each key ID. This should always be 16, but may + * change in the future. + */ + uint32_t key_id_size; + + /** + * Key-system specific initialization data. This data is copied directly + * from the file and the format depends on the specific key system. This + * can be NULL if there is no initialization data; in that case, there + * will be at least one key ID. + */ + uint8_t* data; + uint32_t data_size; + + /** + * An optional pointer to the next initialization info in the list. + */ + struct AVEncryptionInitInfo *next; +} AVEncryptionInitInfo; + +/** + * Allocates an AVEncryptionInfo structure and sub-pointers to hold the given + * number of subsamples. This will allocate pointers for the key ID, IV, + * and subsample entries, set the size members, and zero-initialize the rest. + * + * @param subsample_count The number of subsamples. + * @param key_id_size The number of bytes in the key ID, should be 16. + * @param iv_size The number of bytes in the IV, should be 16. + * + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size); + +/** + * Allocates an AVEncryptionInfo structure with a copy of the given data. + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_clone(const AVEncryptionInfo *info); + +/** + * Frees the given encryption info object. This MUST NOT be used to free the + * side-data data pointer, that should use normal side-data methods. + */ +void av_encryption_info_free(AVEncryptionInfo *info); + +/** + * Creates a copy of the AVEncryptionInfo that is contained in the given side + * data. The resulting object should be passed to av_encryption_info_free() + * when done. + * + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_get_side_data(const uint8_t *side_data, size_t side_data_size); + +/** + * Allocates and initializes side data that holds a copy of the given encryption + * info. The resulting pointer should be either freed using av_free or given + * to av_packet_add_side_data(). + * + * @return The new side-data pointer, or NULL. + */ +uint8_t *av_encryption_info_add_side_data( + const AVEncryptionInfo *info, size_t *side_data_size); + + +/** + * Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the + * given sizes. This will allocate pointers and set all the fields. + * + * @return The new AVEncryptionInitInfo structure, or NULL on error. + */ +AVEncryptionInitInfo *av_encryption_init_info_alloc( + uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size); + +/** + * Frees the given encryption init info object. This MUST NOT be used to free + * the side-data data pointer, that should use normal side-data methods. + */ +void av_encryption_init_info_free(AVEncryptionInitInfo* info); + +/** + * Creates a copy of the AVEncryptionInitInfo that is contained in the given + * side data. The resulting object should be passed to + * av_encryption_init_info_free() when done. + * + * @return The new AVEncryptionInitInfo structure, or NULL on error. + */ +AVEncryptionInitInfo *av_encryption_init_info_get_side_data( + const uint8_t* side_data, size_t side_data_size); + +/** + * Allocates and initializes side data that holds a copy of the given encryption + * init info. The resulting pointer should be either freed using av_free or + * given to av_packet_add_side_data(). + * + * @return The new side-data pointer, or NULL. + */ +uint8_t *av_encryption_init_info_add_side_data( + const AVEncryptionInitInfo *info, size_t *side_data_size); + +#endif /* AVUTIL_ENCRYPTION_INFO_H */ diff --git a/third-party/FFmpeg-iOS/include/libavutil/ffversion.h b/third-party/FFmpeg-iOS/include/libavutil/ffversion.h index 78d9a7ed41..e2474e9039 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/ffversion.h +++ b/third-party/FFmpeg-iOS/include/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "3.4" +#define FFMPEG_VERSION "4.1" #endif /* AVUTIL_FFVERSION_H */ diff --git a/third-party/FFmpeg-iOS/include/libavutil/file.h b/third-party/FFmpeg-iOS/include/libavutil/file.h index 8666c7b1d5..3ef4a6022c 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/file.h +++ b/third-party/FFmpeg-iOS/include/libavutil/file.h @@ -33,6 +33,8 @@ * allocated buffer or map it with mmap() when available. * In case of success set *bufptr to the read or mmapped buffer, and * *size to the size in bytes of the buffer in *bufptr. + * Unlike mmap this function succeeds with zero sized files, in this + * case *bufptr will be set to NULL and *size will be set to 0. * The returned buffer must be released with av_file_unmap(). * * @param log_offset loglevel offset used for logging diff --git a/third-party/FFmpeg-iOS/include/libavutil/frame.h b/third-party/FFmpeg-iOS/include/libavutil/frame.h index abe4f4fd17..e2a292980f 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/frame.h +++ b/third-party/FFmpeg-iOS/include/libavutil/frame.h @@ -141,6 +141,31 @@ enum AVFrameSideDataType { * metadata key entry "name". */ AV_FRAME_DATA_ICC_PROFILE, + +#if FF_API_FRAME_QP + /** + * Implementation-specific description of the format of AV_FRAME_QP_TABLE_DATA. + * The contents of this side data are undocumented and internal; use + * av_frame_set_qp_table() and av_frame_get_qp_table() to access this in a + * meaningful way instead. + */ + AV_FRAME_DATA_QP_TABLE_PROPERTIES, + + /** + * Raw QP table data. Its format is described by + * AV_FRAME_DATA_QP_TABLE_PROPERTIES. Use av_frame_set_qp_table() and + * av_frame_get_qp_table() to access this instead. + */ + AV_FRAME_DATA_QP_TABLE_DATA, +#endif + + /** + * Timecode which conforms to SMPTE ST 12-1. The data is an array of 4 uint32_t + * where the first uint32_t describes how many (1-3) of the other timecodes are used. + * The timecode format is described in the av_timecode_get_smpte_from_framenum() + * function in libavutil/timecode.c. + */ + AV_FRAME_DATA_S12M_TIMECODE, }; enum AVActiveFormatDescription { @@ -529,6 +554,7 @@ typedef struct AVFrame { attribute_deprecated int qscale_type; + attribute_deprecated AVBufferRef *qp_table_buf; #endif /** @@ -563,39 +589,77 @@ typedef struct AVFrame { /** * @} */ + + /** + * AVBufferRef for internal use by a single libav* library. + * Must not be used to transfer data between libraries. + * Has to be NULL when ownership of the frame leaves the respective library. + * + * Code outside the FFmpeg libs should never check or change the contents of the buffer ref. + * + * FFmpeg calls av_buffer_unref() on it when the frame is unreferenced. + * av_frame_copy_props() calls create a new reference with av_buffer_ref() + * for the target frame's private_ref field. + */ + AVBufferRef *private_ref; } AVFrame; +#if FF_API_FRAME_GET_SET /** * Accessors for some AVFrame fields. These used to be provided for ABI * compatibility, and do not need to be used anymore. */ +attribute_deprecated int64_t av_frame_get_best_effort_timestamp(const AVFrame *frame); +attribute_deprecated void av_frame_set_best_effort_timestamp(AVFrame *frame, int64_t val); +attribute_deprecated int64_t av_frame_get_pkt_duration (const AVFrame *frame); +attribute_deprecated void av_frame_set_pkt_duration (AVFrame *frame, int64_t val); +attribute_deprecated int64_t av_frame_get_pkt_pos (const AVFrame *frame); +attribute_deprecated void av_frame_set_pkt_pos (AVFrame *frame, int64_t val); +attribute_deprecated int64_t av_frame_get_channel_layout (const AVFrame *frame); +attribute_deprecated void av_frame_set_channel_layout (AVFrame *frame, int64_t val); +attribute_deprecated int av_frame_get_channels (const AVFrame *frame); +attribute_deprecated void av_frame_set_channels (AVFrame *frame, int val); +attribute_deprecated int av_frame_get_sample_rate (const AVFrame *frame); +attribute_deprecated void av_frame_set_sample_rate (AVFrame *frame, int val); +attribute_deprecated AVDictionary *av_frame_get_metadata (const AVFrame *frame); +attribute_deprecated void av_frame_set_metadata (AVFrame *frame, AVDictionary *val); +attribute_deprecated int av_frame_get_decode_error_flags (const AVFrame *frame); +attribute_deprecated void av_frame_set_decode_error_flags (AVFrame *frame, int val); +attribute_deprecated int av_frame_get_pkt_size(const AVFrame *frame); +attribute_deprecated void av_frame_set_pkt_size(AVFrame *frame, int val); -AVDictionary **avpriv_frame_get_metadatap(AVFrame *frame); #if FF_API_FRAME_QP +attribute_deprecated int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type); +attribute_deprecated int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int type); #endif +attribute_deprecated enum AVColorSpace av_frame_get_colorspace(const AVFrame *frame); +attribute_deprecated void av_frame_set_colorspace(AVFrame *frame, enum AVColorSpace val); +attribute_deprecated enum AVColorRange av_frame_get_color_range(const AVFrame *frame); +attribute_deprecated void av_frame_set_color_range(AVFrame *frame, enum AVColorRange val); +#endif /** * Get the name of a colorspace. @@ -762,6 +826,22 @@ AVFrameSideData *av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, int size); +/** + * Add a new side data to a frame from an existing AVBufferRef + * + * @param frame a frame to which the side data should be added + * @param type the type of the added side data + * @param buf an AVBufferRef to add as side data. The ownership of + * the reference is transferred to the frame. + * + * @return newly added side data on success, NULL on error. On failure + * the frame is unchanged and the AVBufferRef remains owned by + * the caller. + */ +AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, + enum AVFrameSideDataType type, + AVBufferRef *buf); + /** * @return a pointer to the side data of a given type on success, NULL if there * is no side data with such type in this frame. diff --git a/third-party/FFmpeg-iOS/include/libavutil/hash.h b/third-party/FFmpeg-iOS/include/libavutil/hash.h index a20b8934f1..7693e6bf0d 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/hash.h +++ b/third-party/FFmpeg-iOS/include/libavutil/hash.h @@ -29,6 +29,8 @@ #include +#include "version.h" + /** * @defgroup lavu_hash Hash Functions * @ingroup lavu_crypto @@ -179,7 +181,11 @@ void av_hash_init(struct AVHashContext *ctx); * @param[in] src Data to be added to the hash context * @param[in] len Size of the additional data */ +#if FF_API_CRYPTO_SIZE_T void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, int len); +#else +void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, size_t len); +#endif /** * Finalize a hash context and compute the actual hash value. diff --git a/third-party/FFmpeg-iOS/include/libavutil/hmac.h b/third-party/FFmpeg-iOS/include/libavutil/hmac.h index 576a0a4fb9..412e950719 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/hmac.h +++ b/third-party/FFmpeg-iOS/include/libavutil/hmac.h @@ -35,7 +35,7 @@ enum AVHMACType { AV_HMAC_SHA1, AV_HMAC_SHA224, AV_HMAC_SHA256, - AV_HMAC_SHA384 = 12, + AV_HMAC_SHA384, AV_HMAC_SHA512, }; diff --git a/third-party/FFmpeg-iOS/include/libavutil/hwcontext.h b/third-party/FFmpeg-iOS/include/libavutil/hwcontext.h index 03334e20e0..f5a4b62387 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/hwcontext.h +++ b/third-party/FFmpeg-iOS/include/libavutil/hwcontext.h @@ -25,15 +25,17 @@ #include "pixfmt.h" enum AVHWDeviceType { + AV_HWDEVICE_TYPE_NONE, AV_HWDEVICE_TYPE_VDPAU, AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_DXVA2, AV_HWDEVICE_TYPE_QSV, AV_HWDEVICE_TYPE_VIDEOTOOLBOX, - AV_HWDEVICE_TYPE_NONE, AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DRM, + AV_HWDEVICE_TYPE_OPENCL, + AV_HWDEVICE_TYPE_MEDIACODEC, }; typedef struct AVHWDeviceInternal AVHWDeviceInternal; diff --git a/third-party/FFmpeg-iOS/include/libavutil/hwcontext_cuda.h b/third-party/FFmpeg-iOS/include/libavutil/hwcontext_cuda.h index 12dae8449e..81a0552cab 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/hwcontext_cuda.h +++ b/third-party/FFmpeg-iOS/include/libavutil/hwcontext_cuda.h @@ -41,6 +41,7 @@ typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal; */ typedef struct AVCUDADeviceContext { CUcontext cuda_ctx; + CUstream stream; AVCUDADeviceContextInternal *internal; } AVCUDADeviceContext; diff --git a/third-party/FFmpeg-iOS/include/libavutil/hwcontext_d3d11va.h b/third-party/FFmpeg-iOS/include/libavutil/hwcontext_d3d11va.h index 98db7ce343..9f91e9b1b6 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/hwcontext_d3d11va.h +++ b/third-party/FFmpeg-iOS/include/libavutil/hwcontext_d3d11va.h @@ -37,6 +37,7 @@ */ #include +#include /** * This struct is allocated as AVHWDeviceContext.hwctx diff --git a/third-party/FFmpeg-iOS/include/libavutil/hwcontext_drm.h b/third-party/FFmpeg-iOS/include/libavutil/hwcontext_drm.h index 2e225451e1..42709f215e 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/hwcontext_drm.h +++ b/third-party/FFmpeg-iOS/include/libavutil/hwcontext_drm.h @@ -58,6 +58,9 @@ typedef struct AVDRMObjectDescriptor { size_t size; /** * Format modifier applied to the object (DRM_FORMAT_MOD_*). + * + * If the format modifier is unknown then this should be set to + * DRM_FORMAT_MOD_INVALID. */ uint64_t format_modifier; } AVDRMObjectDescriptor; diff --git a/third-party/FFmpeg-iOS/include/libavutil/hwcontext_mediacodec.h b/third-party/FFmpeg-iOS/include/libavutil/hwcontext_mediacodec.h new file mode 100644 index 0000000000..101a9806d5 --- /dev/null +++ b/third-party/FFmpeg-iOS/include/libavutil/hwcontext_mediacodec.h @@ -0,0 +1,36 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_MEDIACODEC_H +#define AVUTIL_HWCONTEXT_MEDIACODEC_H + +/** + * MediaCodec details. + * + * Allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVMediaCodecDeviceContext { + /** + * android/view/Surface handle, to be filled by the user. + * + * This is the default surface used by decoders on this device. + */ + void *surface; +} AVMediaCodecDeviceContext; + +#endif /* AVUTIL_HWCONTEXT_MEDIACODEC_H */ diff --git a/third-party/FFmpeg-iOS/include/libavutil/intreadwrite.h b/third-party/FFmpeg-iOS/include/libavutil/intreadwrite.h index e3403cc035..efac444bc2 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/intreadwrite.h +++ b/third-party/FFmpeg-iOS/include/libavutil/intreadwrite.h @@ -215,7 +215,7 @@ typedef union { * by per-arch headers. */ -#if defined(__GNUC__) && !defined(__TI_COMPILER_VERSION__) +#if defined(__GNUC__) union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias; union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias; @@ -224,12 +224,7 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; # define AV_RN(s, p) (((const union unaligned_##s *) (p))->l) # define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v)) -#elif defined(__DECC) - -# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) -# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) - -#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_X64)) && AV_HAVE_FAST_UNALIGNED +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_X64) || defined(_M_ARM64)) && AV_HAVE_FAST_UNALIGNED # define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) # define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) diff --git a/third-party/FFmpeg-iOS/include/libavutil/log.h b/third-party/FFmpeg-iOS/include/libavutil/log.h index f0a57385df..d9554e609d 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/log.h +++ b/third-party/FFmpeg-iOS/include/libavutil/log.h @@ -334,20 +334,6 @@ void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl, int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl, char *line, int line_size, int *print_prefix); -#if FF_API_DLOG -/** - * av_dlog macros - * @deprecated unused - * Useful to print debug messages that shouldn't get compiled in normally. - */ - -#ifdef DEBUG -# define av_dlog(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__) -#else -# define av_dlog(pctx, ...) do { if (0) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0) -#endif -#endif /* FF_API_DLOG */ - /** * Skip repeated messages, this requires the user app to use av_log() instead of * (f)printf as the 2 would otherwise interfere and lead to diff --git a/third-party/FFmpeg-iOS/include/libavutil/lzo.h b/third-party/FFmpeg-iOS/include/libavutil/lzo.h deleted file mode 100644 index c03403992d..0000000000 --- a/third-party/FFmpeg-iOS/include/libavutil/lzo.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * LZO 1x decompression - * copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_LZO_H -#define AVUTIL_LZO_H - -/** - * @defgroup lavu_lzo LZO - * @ingroup lavu_crypto - * - * @{ - */ - -#include - -/** @name Error flags returned by av_lzo1x_decode - * @{ */ -/// end of the input buffer reached before decoding finished -#define AV_LZO_INPUT_DEPLETED 1 -/// decoded data did not fit into output buffer -#define AV_LZO_OUTPUT_FULL 2 -/// a reference to previously decoded data was wrong -#define AV_LZO_INVALID_BACKPTR 4 -/// a non-specific error in the compressed bitstream -#define AV_LZO_ERROR 8 -/** @} */ - -#define AV_LZO_INPUT_PADDING 8 -#define AV_LZO_OUTPUT_PADDING 12 - -/** - * @brief Decodes LZO 1x compressed data. - * @param out output buffer - * @param outlen size of output buffer, number of bytes left are returned here - * @param in input buffer - * @param inlen size of input buffer, number of bytes left are returned here - * @return 0 on success, otherwise a combination of the error flags above - * - * Make sure all buffers are appropriately padded, in must provide - * AV_LZO_INPUT_PADDING, out must provide AV_LZO_OUTPUT_PADDING additional bytes. - */ -int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen); - -/** - * @} - */ - -#endif /* AVUTIL_LZO_H */ diff --git a/third-party/FFmpeg-iOS/include/libavutil/mastering_display_metadata.h b/third-party/FFmpeg-iOS/include/libavutil/mastering_display_metadata.h index 847b0b62c6..c23b07c3cd 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/mastering_display_metadata.h +++ b/third-party/FFmpeg-iOS/include/libavutil/mastering_display_metadata.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2016 Neil Birkbeck * * This file is part of FFmpeg. diff --git a/third-party/FFmpeg-iOS/include/libavutil/mem.h b/third-party/FFmpeg-iOS/include/libavutil/mem.h index 527cd03191..7e0b12a8a7 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/mem.h +++ b/third-party/FFmpeg-iOS/include/libavutil/mem.h @@ -73,6 +73,19 @@ * @param v Name of the variable */ +/** + * @def DECLARE_ASM_ALIGNED(n,t,v) + * Declare an aligned variable appropriate for use in inline assembly code. + * + * @code{.c} + * DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + /** * @def DECLARE_ASM_CONST(n,t,v) * Declare a static constant aligned variable appropriate for use in inline @@ -89,25 +102,23 @@ #if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C) #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v -#elif defined(__TI_COMPILER_VERSION__) - #define DECLARE_ALIGNED(n,t,v) \ - AV_PRAGMA(DATA_ALIGN(v,n)) \ - t __attribute__((aligned(n))) v - #define DECLARE_ASM_CONST(n,t,v) \ - AV_PRAGMA(DATA_ALIGN(v,n)) \ - static const t __attribute__((aligned(n))) v #elif defined(__DJGPP__) #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v #elif defined(__GNUC__) || defined(__clang__) #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (n))) v #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v #elif defined(_MSC_VER) #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_ALIGNED(n,t,v) __declspec(align(n)) t v #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v #else #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_ALIGNED(n,t,v) t v #define DECLARE_ASM_CONST(n,t,v) static const t v #endif @@ -206,12 +217,7 @@ void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1); * be allocated * @see av_malloc() */ -av_alloc_size(1, 2) static inline void *av_malloc_array(size_t nmemb, size_t size) -{ - if (!size || nmemb >= INT_MAX / size) - return NULL; - return av_malloc(nmemb * size); -} +av_alloc_size(1, 2) void *av_malloc_array(size_t nmemb, size_t size); /** * Allocate a memory block for an array with av_mallocz(). @@ -226,12 +232,7 @@ av_alloc_size(1, 2) static inline void *av_malloc_array(size_t nmemb, size_t siz * @see av_mallocz() * @see av_malloc_array() */ -av_alloc_size(1, 2) static inline void *av_mallocz_array(size_t nmemb, size_t size) -{ - if (!size || nmemb >= INT_MAX / size) - return NULL; - return av_mallocz(nmemb * size); -} +av_alloc_size(1, 2) void *av_mallocz_array(size_t nmemb, size_t size); /** * Non-inlined equivalent of av_mallocz_array(). diff --git a/third-party/FFmpeg-iOS/include/libavutil/murmur3.h b/third-party/FFmpeg-iOS/include/libavutil/murmur3.h index 6a1694c08d..1b09175c1e 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/murmur3.h +++ b/third-party/FFmpeg-iOS/include/libavutil/murmur3.h @@ -29,6 +29,8 @@ #include +#include "version.h" + /** * @defgroup lavu_murmur3 Murmur3 * @ingroup lavu_hash @@ -97,7 +99,11 @@ void av_murmur3_init(struct AVMurMur3 *c); * @param[in] src Input data to update hash with * @param[in] len Number of bytes to read from `src` */ +#if FF_API_CRYPTO_SIZE_T void av_murmur3_update(struct AVMurMur3 *c, const uint8_t *src, int len); +#else +void av_murmur3_update(struct AVMurMur3 *c, const uint8_t *src, size_t len); +#endif /** * Finish hashing and output digest value. diff --git a/third-party/FFmpeg-iOS/include/libavutil/opt.h b/third-party/FFmpeg-iOS/include/libavutil/opt.h index 0d893795de..39f4a8dda0 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/opt.h +++ b/third-party/FFmpeg-iOS/include/libavutil/opt.h @@ -229,15 +229,15 @@ enum AVOptionType{ AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length AV_OPT_TYPE_DICT, AV_OPT_TYPE_UINT64, - AV_OPT_TYPE_CONST = 128, - AV_OPT_TYPE_IMAGE_SIZE = MKBETAG('S','I','Z','E'), ///< offset must point to two consecutive integers - AV_OPT_TYPE_PIXEL_FMT = MKBETAG('P','F','M','T'), - AV_OPT_TYPE_SAMPLE_FMT = MKBETAG('S','F','M','T'), - AV_OPT_TYPE_VIDEO_RATE = MKBETAG('V','R','A','T'), ///< offset must point to AVRational - AV_OPT_TYPE_DURATION = MKBETAG('D','U','R',' '), - AV_OPT_TYPE_COLOR = MKBETAG('C','O','L','R'), - AV_OPT_TYPE_CHANNEL_LAYOUT = MKBETAG('C','H','L','A'), - AV_OPT_TYPE_BOOL = MKBETAG('B','O','O','L'), + AV_OPT_TYPE_CONST, + AV_OPT_TYPE_IMAGE_SIZE, ///< offset must point to two consecutive integers + AV_OPT_TYPE_PIXEL_FMT, + AV_OPT_TYPE_SAMPLE_FMT, + AV_OPT_TYPE_VIDEO_RATE, ///< offset must point to AVRational + AV_OPT_TYPE_DURATION, + AV_OPT_TYPE_COLOR, + AV_OPT_TYPE_CHANNEL_LAYOUT, + AV_OPT_TYPE_BOOL, }; /** @@ -275,9 +275,6 @@ typedef struct AVOption { int flags; #define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding #define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding -#if FF_API_OPT_TYPE_METADATA -#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ... -#endif #define AV_OPT_FLAG_AUDIO_PARAM 8 #define AV_OPT_FLAG_VIDEO_PARAM 16 #define AV_OPT_FLAG_SUBTITLE_PARAM 32 @@ -290,7 +287,9 @@ typedef struct AVOption { * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set. */ #define AV_OPT_FLAG_READONLY 128 +#define AV_OPT_FLAG_BSF_PARAM (1<<8) ///< a generic parameter which can be set by the user for bit stream filtering #define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering +#define AV_OPT_FLAG_DEPRECATED (1<<17) ///< set if option is deprecated, users should refer to AVOption.help text for more information //FIXME think about enc-audio, ... style flags /** diff --git a/third-party/FFmpeg-iOS/include/libavutil/pixdesc.h b/third-party/FFmpeg-iOS/include/libavutil/pixdesc.h index fc3737c4ad..c055810ae8 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/pixdesc.h +++ b/third-party/FFmpeg-iOS/include/libavutil/pixdesc.h @@ -154,17 +154,21 @@ typedef struct AVPixFmtDescriptor { * in some cases be simpler. Or the data can be interpreted purely based on * the pixel format without using the palette. * An example of a pseudo-paletted format is AV_PIX_FMT_GRAY8 + * + * @deprecated This flag is deprecated, and will be removed. When it is removed, + * the extra palette allocation in AVFrame.data[1] is removed as well. Only + * actual paletted formats (as indicated by AV_PIX_FMT_FLAG_PAL) will have a + * palette. Starting with FFmpeg versions which have this flag deprecated, the + * extra "pseudo" palette is already ignored, and API users are not required to + * allocate a palette for AV_PIX_FMT_FLAG_PSEUDOPAL formats (it was required + * before the deprecation, though). */ #define AV_PIX_FMT_FLAG_PSEUDOPAL (1 << 6) /** * The pixel format has an alpha channel. This is set on all formats that - * support alpha in some way. The exception is AV_PIX_FMT_PAL8, which can - * carry alpha as part of the palette. Details are explained in the - * AVPixelFormat enum, and are also encoded in the corresponding - * AVPixFmtDescriptor. - * - * The alpha is always straight, never pre-multiplied. + * support alpha in some way, including AV_PIX_FMT_PAL8. The alpha is always + * straight, never pre-multiplied. * * If a codec or a filter does not support alpha, it should set all alpha to * opaque, or use the equivalent pixel formats without alpha component, e.g. @@ -225,11 +229,6 @@ enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc); * Utility function to access log2_chroma_w log2_chroma_h from * the pixel format AVPixFmtDescriptor. * - * See av_get_chroma_sub_sample() for a function that asserts a - * valid pixel format instead of returning an error code. - * Its recommended that you use avcodec_get_chroma_sub_sample unless - * you do check the return code! - * * @param[in] pix_fmt the pixel format * @param[out] h_shift store log2_chroma_w (horizontal/width shift) * @param[out] v_shift store log2_chroma_h (vertical/height shift) @@ -344,7 +343,13 @@ char *av_get_pix_fmt_string(char *buf, int buf_size, * format writes the values corresponding to the palette * component c in data[1] to dst, rather than the palette indexes in * data[0]. The behavior is undefined if the format is not paletted. + * @param dst_element_size size of elements in dst array (2 or 4 byte) */ +void av_read_image_line2(void *dst, const uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int read_pal_component, + int dst_element_size); + void av_read_image_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4], const AVPixFmtDescriptor *desc, int x, int y, int c, int w, int read_pal_component); @@ -362,7 +367,12 @@ void av_read_image_line(uint16_t *dst, const uint8_t *data[4], * @param y the vertical coordinate of the first pixel to write * @param w the width of the line to write, that is the number of * values to write to the image line + * @param src_element_size size of elements in src array (2 or 4 byte) */ +void av_write_image_line2(const void *src, uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int src_element_size); + void av_write_image_line(const uint16_t *src, uint8_t *data[4], const int linesize[4], const AVPixFmtDescriptor *desc, int x, int y, int c, int w); diff --git a/third-party/FFmpeg-iOS/include/libavutil/pixfmt.h b/third-party/FFmpeg-iOS/include/libavutil/pixfmt.h index 02591fcad3..ed0fbcbfd3 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/pixfmt.h +++ b/third-party/FFmpeg-iOS/include/libavutil/pixfmt.h @@ -42,6 +42,10 @@ * This is stored as BGRA on little-endian CPU architectures and ARGB on * big-endian CPUs. * + * @note + * If the resolution is not a multiple of the chroma subsampling factor + * then the chroma plane resolution must be rounded up. + * * @par * When the pixel format is palettized RGB32 (AV_PIX_FMT_PAL8), the palettized * image data is stored in AVFrame.data[0]. The palette is transported in @@ -74,11 +78,6 @@ enum AVPixelFormat { AV_PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting color_range AV_PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting color_range AV_PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting color_range -#if FF_API_XVMC - AV_PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing - AV_PIX_FMT_XVMC_MPEG2_IDCT, - AV_PIX_FMT_XVMC = AV_PIX_FMT_XVMC_MPEG2_IDCT, -#endif /* FF_API_XVMC */ AV_PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 AV_PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) @@ -100,13 +99,6 @@ enum AVPixelFormat { AV_PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) AV_PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range AV_PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) -#if FF_API_VDPAU - AV_PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - AV_PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - AV_PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - AV_PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - AV_PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers -#endif AV_PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian AV_PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian @@ -142,9 +134,6 @@ enum AVPixelFormat { AV_PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian AV_PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian AV_PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian -#if FF_API_VDPAU - AV_PIX_FMT_VDPAU_MPEG4, ///< MPEG-4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers -#endif AV_PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer AV_PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), little-endian, X=unused/undefined @@ -176,7 +165,6 @@ enum AVPixelFormat { AV_PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian AV_PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian AV_PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian - AV_PIX_FMT_VDA_VLD, ///< hardware decoding through VDA AV_PIX_FMT_GBRP, ///< planar GBR 4:4:4 24bpp AV_PIX_FMT_GBR24P = AV_PIX_FMT_GBRP, // alias for #AV_PIX_FMT_GBRP AV_PIX_FMT_GBRP9BE, ///< planar GBR 4:4:4 27bpp, big-endian @@ -221,8 +209,6 @@ enum AVPixelFormat { AV_PIX_FMT_YVYU422, ///< packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb - AV_PIX_FMT_VDA, ///< HW acceleration through VDA, data[3] contains a CVPixelBufferRef - AV_PIX_FMT_YA16BE, ///< 16 bits gray, 16 bits alpha (big-endian) AV_PIX_FMT_YA16LE, ///< 16 bits gray, 16 bits alpha (little-endian) @@ -248,7 +234,7 @@ enum AVPixelFormat { */ AV_PIX_FMT_CUDA, - AV_PIX_FMT_0RGB=0x123+4,///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined + AV_PIX_FMT_0RGB, ///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined AV_PIX_FMT_RGB0, ///< packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined AV_PIX_FMT_0BGR, ///< packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined AV_PIX_FMT_BGR0, ///< packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined @@ -283,9 +269,9 @@ enum AVPixelFormat { AV_PIX_FMT_BAYER_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian */ AV_PIX_FMT_BAYER_GRBG16LE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, little-endian */ AV_PIX_FMT_BAYER_GRBG16BE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, big-endian */ -#if !FF_API_XVMC + AV_PIX_FMT_XVMC,///< XVideo Motion Acceleration via common packet passing -#endif /* !FF_API_XVMC */ + AV_PIX_FMT_YUV440P10LE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian AV_PIX_FMT_YUV440P10BE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian AV_PIX_FMT_YUV440P12LE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian @@ -340,6 +326,19 @@ enum AVPixelFormat { * data[0] points to an AVDRMFrameDescriptor. */ AV_PIX_FMT_DRM_PRIME, + /** + * Hardware surfaces for OpenCL. + * + * data[i] contain 2D image objects (typed in C as cl_mem, used + * in OpenCL as image2d_t) for each plane of the surface. + */ + AV_PIX_FMT_OPENCL, + + AV_PIX_FMT_GRAY14BE, ///< Y , 14bpp, big-endian + AV_PIX_FMT_GRAY14LE, ///< Y , 14bpp, little-endian + + AV_PIX_FMT_GRAYF32BE, ///< IEEE-754 single precision Y, 32bpp, big-endian + AV_PIX_FMT_GRAYF32LE, ///< IEEE-754 single precision Y, 32bpp, little-endian AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -360,6 +359,7 @@ enum AVPixelFormat { #define AV_PIX_FMT_GRAY9 AV_PIX_FMT_NE(GRAY9BE, GRAY9LE) #define AV_PIX_FMT_GRAY10 AV_PIX_FMT_NE(GRAY10BE, GRAY10LE) #define AV_PIX_FMT_GRAY12 AV_PIX_FMT_NE(GRAY12BE, GRAY12LE) +#define AV_PIX_FMT_GRAY14 AV_PIX_FMT_NE(GRAY14BE, GRAY14LE) #define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE) #define AV_PIX_FMT_YA16 AV_PIX_FMT_NE(YA16BE, YA16LE) #define AV_PIX_FMT_RGB48 AV_PIX_FMT_NE(RGB48BE, RGB48LE) @@ -408,6 +408,8 @@ enum AVPixelFormat { #define AV_PIX_FMT_GBRPF32 AV_PIX_FMT_NE(GBRPF32BE, GBRPF32LE) #define AV_PIX_FMT_GBRAPF32 AV_PIX_FMT_NE(GBRAPF32BE, GBRAPF32LE) +#define AV_PIX_FMT_GRAYF32 AV_PIX_FMT_NE(GRAYF32BE, GRAYF32LE) + #define AV_PIX_FMT_YUVA420P9 AV_PIX_FMT_NE(YUVA420P9BE , YUVA420P9LE) #define AV_PIX_FMT_YUVA422P9 AV_PIX_FMT_NE(YUVA422P9BE , YUVA422P9LE) #define AV_PIX_FMT_YUVA444P9 AV_PIX_FMT_NE(YUVA444P9BE , YUVA444P9LE) diff --git a/third-party/FFmpeg-iOS/include/libavutil/ripemd.h b/third-party/FFmpeg-iOS/include/libavutil/ripemd.h index 6d6bb3208f..0db6858ff3 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/ripemd.h +++ b/third-party/FFmpeg-iOS/include/libavutil/ripemd.h @@ -66,7 +66,11 @@ int av_ripemd_init(struct AVRIPEMD* context, int bits); * @param data input data to update hash with * @param len input data length */ +#if FF_API_CRYPTO_SIZE_T void av_ripemd_update(struct AVRIPEMD* context, const uint8_t* data, unsigned int len); +#else +void av_ripemd_update(struct AVRIPEMD* context, const uint8_t* data, size_t len); +#endif /** * Finish hashing and output digest value. diff --git a/third-party/FFmpeg-iOS/include/libavutil/stereo3d.h b/third-party/FFmpeg-iOS/include/libavutil/stereo3d.h index 54f4c4c5c7..d421aac2a2 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/stereo3d.h +++ b/third-party/FFmpeg-iOS/include/libavutil/stereo3d.h @@ -141,6 +141,25 @@ enum AVStereo3DType { AV_STEREO3D_COLUMNS, }; +/** + * List of possible view types. + */ +enum AVStereo3DView { + /** + * Frame contains two packed views. + */ + AV_STEREO3D_VIEW_PACKED, + + /** + * Frame contains only the left view. + */ + AV_STEREO3D_VIEW_LEFT, + + /** + * Frame contains only the right view. + */ + AV_STEREO3D_VIEW_RIGHT, +}; /** * Inverted views, Right/Bottom represents the left view. @@ -164,6 +183,11 @@ typedef struct AVStereo3D { * Additional information about the frame packing. */ int flags; + + /** + * Determines which views are packed. + */ + enum AVStereo3DView view; } AVStereo3D; /** diff --git a/third-party/FFmpeg-iOS/include/libavutil/threadmessage.h b/third-party/FFmpeg-iOS/include/libavutil/threadmessage.h index 8480a0a3db..42ce655f36 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/threadmessage.h +++ b/third-party/FFmpeg-iOS/include/libavutil/threadmessage.h @@ -95,6 +95,14 @@ void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, void av_thread_message_queue_set_free_func(AVThreadMessageQueue *mq, void (*free_func)(void *msg)); +/** + * Return the current number of messages in the queue. + * + * @return the current number of messages or AVERROR(ENOSYS) if lavu was built + * without thread support + */ +int av_thread_message_queue_nb_elems(AVThreadMessageQueue *mq); + /** * Flush the message queue * diff --git a/third-party/FFmpeg-iOS/include/libavutil/version.h b/third-party/FFmpeg-iOS/include/libavutil/version.h index f594dc0691..8f6da6ae42 100644 --- a/third-party/FFmpeg-iOS/include/libavutil/version.h +++ b/third-party/FFmpeg-iOS/include/libavutil/version.h @@ -78,9 +78,8 @@ * @{ */ - -#define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 78 +#define LIBAVUTIL_VERSION_MAJOR 56 +#define LIBAVUTIL_VERSION_MINOR 22 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ @@ -106,38 +105,29 @@ * @{ */ -#ifndef FF_API_VDPAU -#define FF_API_VDPAU (LIBAVUTIL_VERSION_MAJOR < 56) -#endif -#ifndef FF_API_XVMC -#define FF_API_XVMC (LIBAVUTIL_VERSION_MAJOR < 56) -#endif -#ifndef FF_API_OPT_TYPE_METADATA -#define FF_API_OPT_TYPE_METADATA (LIBAVUTIL_VERSION_MAJOR < 56) -#endif -#ifndef FF_API_DLOG -#define FF_API_DLOG (LIBAVUTIL_VERSION_MAJOR < 56) -#endif #ifndef FF_API_VAAPI -#define FF_API_VAAPI (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_VAAPI (LIBAVUTIL_VERSION_MAJOR < 57) #endif #ifndef FF_API_FRAME_QP -#define FF_API_FRAME_QP (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_FRAME_QP (LIBAVUTIL_VERSION_MAJOR < 57) #endif #ifndef FF_API_PLUS1_MINUS1 -#define FF_API_PLUS1_MINUS1 (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_PLUS1_MINUS1 (LIBAVUTIL_VERSION_MAJOR < 57) #endif #ifndef FF_API_ERROR_FRAME -#define FF_API_ERROR_FRAME (LIBAVUTIL_VERSION_MAJOR < 56) -#endif -#ifndef FF_API_CRC_BIG_TABLE -#define FF_API_CRC_BIG_TABLE (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_ERROR_FRAME (LIBAVUTIL_VERSION_MAJOR < 57) #endif #ifndef FF_API_PKT_PTS -#define FF_API_PKT_PTS (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_PKT_PTS (LIBAVUTIL_VERSION_MAJOR < 57) #endif #ifndef FF_API_CRYPTO_SIZE_T -#define FF_API_CRYPTO_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_CRYPTO_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_FRAME_GET_SET +#define FF_API_FRAME_GET_SET (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_PSEUDOPAL +#define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) #endif diff --git a/third-party/FFmpeg-iOS/include/libswresample/version.h b/third-party/FFmpeg-iOS/include/libswresample/version.h index 7e7fb6abd5..12351cd2bd 100644 --- a/third-party/FFmpeg-iOS/include/libswresample/version.h +++ b/third-party/FFmpeg-iOS/include/libswresample/version.h @@ -28,8 +28,8 @@ #include "../libavutil/avutil.h" -#define LIBSWRESAMPLE_VERSION_MAJOR 2 -#define LIBSWRESAMPLE_VERSION_MINOR 9 +#define LIBSWRESAMPLE_VERSION_MAJOR 3 +#define LIBSWRESAMPLE_VERSION_MINOR 3 #define LIBSWRESAMPLE_VERSION_MICRO 100 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ diff --git a/third-party/FFmpeg-iOS/lib/libavcodec.a b/third-party/FFmpeg-iOS/lib/libavcodec.a index f316b10040..e1997f7a3d 100644 Binary files a/third-party/FFmpeg-iOS/lib/libavcodec.a and b/third-party/FFmpeg-iOS/lib/libavcodec.a differ diff --git a/third-party/FFmpeg-iOS/lib/libavdevice.a b/third-party/FFmpeg-iOS/lib/libavdevice.a deleted file mode 100644 index c6b0364df8..0000000000 Binary files a/third-party/FFmpeg-iOS/lib/libavdevice.a and /dev/null differ diff --git a/third-party/FFmpeg-iOS/lib/libavfilter.a b/third-party/FFmpeg-iOS/lib/libavfilter.a deleted file mode 100644 index 2b4a0459fe..0000000000 Binary files a/third-party/FFmpeg-iOS/lib/libavfilter.a and /dev/null differ diff --git a/third-party/FFmpeg-iOS/lib/libavformat.a b/third-party/FFmpeg-iOS/lib/libavformat.a index f5f72dae63..f41d5c4c0e 100644 Binary files a/third-party/FFmpeg-iOS/lib/libavformat.a and b/third-party/FFmpeg-iOS/lib/libavformat.a differ diff --git a/third-party/FFmpeg-iOS/lib/libavutil.a b/third-party/FFmpeg-iOS/lib/libavutil.a index a491219fc3..fc4542f730 100644 Binary files a/third-party/FFmpeg-iOS/lib/libavutil.a and b/third-party/FFmpeg-iOS/lib/libavutil.a differ diff --git a/third-party/FFmpeg-iOS/lib/libswresample.a b/third-party/FFmpeg-iOS/lib/libswresample.a index d7587b0a8d..1df9158c48 100644 Binary files a/third-party/FFmpeg-iOS/lib/libswresample.a and b/third-party/FFmpeg-iOS/lib/libswresample.a differ diff --git a/third-party/FFmpeg-iOS/lib/libswscale.a b/third-party/FFmpeg-iOS/lib/libswscale.a deleted file mode 100644 index e0538fa521..0000000000 Binary files a/third-party/FFmpeg-iOS/lib/libswscale.a and /dev/null differ