]> git.sesse.net Git - nageru/blob - h264encode.h
5409d17421c3fb8b047c94911908c2243864d7f4
[nageru] / h264encode.h
1 // Hardware H.264 encoding via VAAPI. Heavily modified based on example
2 // code by Intel. Intel's original copyright and license is reproduced below:
3 //
4 // Copyright (c) 2007-2013 Intel Corporation. All Rights Reserved.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a
7 // copy of this software and associated documentation files (the
8 // "Software"), to deal in the Software without restriction, including
9 // without limitation the rights to use, copy, modify, merge, publish,
10 // distribute, sub license, and/or sell copies of the Software, and to
11 // permit persons to whom the Software is furnished to do so, subject to
12 // the following conditions:
13 // 
14 // The above copyright notice and this permission notice (including the
15 // next paragraph) shall be included in all copies or substantial portions
16 // of the Software.
17 // 
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 // IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
22 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 #ifndef _H264ENCODE_H
27 #define _H264ENCODE_H
28
29 extern "C" {
30 #include <libavformat/avformat.h>
31 }
32 #include <epoxy/egl.h>
33 #include <atomic>
34 #include <map>
35 #include <memory>
36 #include <mutex>
37 #include <thread>
38 #include <thread>
39 #include <thread>
40 #include <thread>
41 #include <condition_variable>
42
43 #include "pbo_frame_allocator.h"
44 #include "context.h"
45
46 #define SURFACE_NUM 16 /* 16 surfaces for source YUV */
47
48 class H264Encoder {
49 public:
50         H264Encoder(QSurface *surface, int width, int height, const char *output_filename);
51         ~H264Encoder();
52         //void add_frame(FrameAllocator::Frame frame, GLsync fence);
53
54 #if 0
55         struct Frame {
56         public:
57                 GLuint fbo;
58                 GLuint y_tex, cbcr_tex; 
59
60         private:
61                 //int surface_subnum;
62         };
63         void 
64 #endif
65         bool begin_frame(GLuint *y_tex, GLuint *cbcr_tex);
66         void end_frame(GLsync fence, const std::vector<FrameAllocator::Frame> &input_frames_to_release);
67
68 private:
69         struct storage_task {
70                 unsigned long long display_order;
71                 unsigned long long encode_order;
72                 int frame_type;
73         };
74
75         void copy_thread_func();
76         void storage_task_thread();
77         void storage_task_enqueue(unsigned long long display_order, unsigned long long encode_order, int frame_type);
78         int save_codeddata(unsigned long long display_order, unsigned long long encode_order, int frame_type);
79
80         std::thread copy_thread, storage_thread;
81
82         std::mutex storage_task_queue_mutex;
83         std::condition_variable storage_task_queue_changed;
84         int srcsurface_status[SURFACE_NUM];  // protected by storage_task_queue_mutex
85         std::queue<storage_task> storage_task_queue;  // protected by storage_task_queue_mutex
86         bool storage_thread_should_quit = false;  // protected by storage_task_queue_mutex
87
88         std::mutex frame_queue_mutex;
89         std::condition_variable frame_queue_nonempty;
90         bool copy_thread_should_quit = false;  // under frame_queue_mutex
91
92         //int frame_width, frame_height;
93         //int ;
94         int current_storage_frame;
95
96         struct PendingFrame {
97                 GLsync fence;
98                 std::vector<FrameAllocator::Frame> input_frames_to_release;
99         };
100         std::map<int, PendingFrame> pending_frames;
101         QSurface *surface;
102
103         AVFormatContext *avctx;
104         AVStream *avstream;
105 };
106
107 #endif