1e0e9324cSopenharmony_ci/*
2e0e9324cSopenharmony_ci * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3e0e9324cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e0e9324cSopenharmony_ci * you may not use this file except in compliance with the License.
5e0e9324cSopenharmony_ci * You may obtain a copy of the License at
6e0e9324cSopenharmony_ci *
7e0e9324cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e0e9324cSopenharmony_ci *
9e0e9324cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e0e9324cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e0e9324cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e0e9324cSopenharmony_ci * See the License for the specific language governing permissions and
13e0e9324cSopenharmony_ci * limitations under the License.
14e0e9324cSopenharmony_ci */
15e0e9324cSopenharmony_ci
16e0e9324cSopenharmony_ci#ifndef OHOS_SHARING_H264_FRAME_H
17e0e9324cSopenharmony_ci#define OHOS_SHARING_H264_FRAME_H
18e0e9324cSopenharmony_ci
19e0e9324cSopenharmony_ci#include <cstdlib>
20e0e9324cSopenharmony_ci#include <memory>
21e0e9324cSopenharmony_ci#include <string>
22e0e9324cSopenharmony_ci#include "frame.h"
23e0e9324cSopenharmony_ci
24e0e9324cSopenharmony_cinamespace OHOS {
25e0e9324cSopenharmony_cinamespace Sharing {
26e0e9324cSopenharmony_ci
27e0e9324cSopenharmony_ci#define H264_TYPE(v) ((uint8_t)(v)&0x1F)
28e0e9324cSopenharmony_ci
29e0e9324cSopenharmony_cisize_t PrefixSize(const char *ptr, size_t len);
30e0e9324cSopenharmony_civoid SplitH264(const char *ptr, size_t len, size_t prefix, const std::function<void(const char *, size_t, size_t)> &cb);
31e0e9324cSopenharmony_ci// template <typename Parent>
32e0e9324cSopenharmony_ciclass H264Frame : public FrameImpl {
33e0e9324cSopenharmony_cipublic:
34e0e9324cSopenharmony_ci    using Ptr = std::shared_ptr<H264Frame>;
35e0e9324cSopenharmony_ci
36e0e9324cSopenharmony_ci    enum {
37e0e9324cSopenharmony_ci        NAL_IDR = 5,
38e0e9324cSopenharmony_ci        NAL_SEI = 6,
39e0e9324cSopenharmony_ci        NAL_SPS = 7,
40e0e9324cSopenharmony_ci        NAL_PPS = 8,
41e0e9324cSopenharmony_ci        NAL_AUD = 9,
42e0e9324cSopenharmony_ci        NAL_B_P = 1,
43e0e9324cSopenharmony_ci    };
44e0e9324cSopenharmony_ci
45e0e9324cSopenharmony_ci    H264Frame()
46e0e9324cSopenharmony_ci    {
47e0e9324cSopenharmony_ci        this->codecId_ = CODEC_H264;
48e0e9324cSopenharmony_ci    }
49e0e9324cSopenharmony_ci
50e0e9324cSopenharmony_ci    explicit H264Frame(DataBuffer &&dataBuffer) : FrameImpl(std::move(dataBuffer))
51e0e9324cSopenharmony_ci    {
52e0e9324cSopenharmony_ci        this->codecId_ = CODEC_H264;
53e0e9324cSopenharmony_ci    }
54e0e9324cSopenharmony_ci
55e0e9324cSopenharmony_ci    H264Frame(uint8_t *ptr, size_t size, uint32_t dts, uint32_t pts = 0, size_t prefix_size = 0)
56e0e9324cSopenharmony_ci    {
57e0e9324cSopenharmony_ci        this->Assign((char *)ptr, (int32_t)size);
58e0e9324cSopenharmony_ci        dts_ = dts;
59e0e9324cSopenharmony_ci        pts_ = pts;
60e0e9324cSopenharmony_ci        prefixSize_ = prefix_size;
61e0e9324cSopenharmony_ci        this->codecId_ = CODEC_H264;
62e0e9324cSopenharmony_ci    }
63e0e9324cSopenharmony_ci
64e0e9324cSopenharmony_ci    ~H264Frame() override {};
65e0e9324cSopenharmony_ci
66e0e9324cSopenharmony_ci    bool KeyFrame() override
67e0e9324cSopenharmony_ci    {
68e0e9324cSopenharmony_ci        auto nalPtr = (uint8_t *)this->Data() + this->PrefixSize();
69e0e9324cSopenharmony_ci        return H264_TYPE(*nalPtr) == NAL_IDR && DecodeAble();
70e0e9324cSopenharmony_ci    }
71e0e9324cSopenharmony_ci
72e0e9324cSopenharmony_ci    bool ConfigFrame() override
73e0e9324cSopenharmony_ci    {
74e0e9324cSopenharmony_ci        auto nalPtr = (uint8_t *)this->Data() + this->PrefixSize();
75e0e9324cSopenharmony_ci        switch (H264_TYPE(*nalPtr)) {
76e0e9324cSopenharmony_ci            case NAL_SPS: // fall-through
77e0e9324cSopenharmony_ci            case NAL_PPS:
78e0e9324cSopenharmony_ci                return true;
79e0e9324cSopenharmony_ci            default:
80e0e9324cSopenharmony_ci                return false;
81e0e9324cSopenharmony_ci        }
82e0e9324cSopenharmony_ci    }
83e0e9324cSopenharmony_ci
84e0e9324cSopenharmony_ci    bool DropAble() override
85e0e9324cSopenharmony_ci    {
86e0e9324cSopenharmony_ci        auto nalPtr = (uint8_t *)this->Data() + this->PrefixSize();
87e0e9324cSopenharmony_ci        switch (H264_TYPE(*nalPtr)) {
88e0e9324cSopenharmony_ci            case NAL_SEI: // fall-through
89e0e9324cSopenharmony_ci            case NAL_AUD:
90e0e9324cSopenharmony_ci                return true;
91e0e9324cSopenharmony_ci            default:
92e0e9324cSopenharmony_ci                return false;
93e0e9324cSopenharmony_ci        }
94e0e9324cSopenharmony_ci    }
95e0e9324cSopenharmony_ci
96e0e9324cSopenharmony_ci    bool DecodeAble() override
97e0e9324cSopenharmony_ci    {
98e0e9324cSopenharmony_ci        auto nalPtr = (uint8_t *)this->Data() + this->PrefixSize();
99e0e9324cSopenharmony_ci        auto type = H264_TYPE(*nalPtr);
100e0e9324cSopenharmony_ci
101e0e9324cSopenharmony_ci        return type >= NAL_B_P && type <= NAL_IDR && (nalPtr[1] & 0x80);
102e0e9324cSopenharmony_ci    }
103e0e9324cSopenharmony_ci};
104e0e9324cSopenharmony_ci} // namespace Sharing
105e0e9324cSopenharmony_ci} // namespace OHOS
106e0e9324cSopenharmony_ci#endif