blob: dd158cc833825dfbae07e2edfd68cde0569dda94 [file] [log] [blame]
Song Zhao1b237602020-02-13 10:58:57 -08001/*
2 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
3 *
4 * This source code is subject to the terms and conditions defined in the
5 * file 'LICENSE' which is part of this source code package.
6 *
7 * Description:
8 */
9#include <pthread.h>
10#include <stdbool.h>
11#include <libavformat/avformat.h>
12#include "demux.h"
13
14#define H2645(format) ((format) == AV_CODEC_ID_H264 || (format) == AV_CODEC_ID_H265)
15#define WORD_BE(p) ((p[0]<<8) | p[1])
16
17#define HEVC_NAL_TYPE(b) ((b>>1)&0x3F)
18#define HEVC_NAL_VPS 32
19#define HEVC_NAL_SPS 33
20#define HEVC_NAL_PPS 34
21
22extern int ffmpeg_log;
23/* ffmpeg data structure */
24static AVStream *video_stream = NULL;
25static AVFormatContext *fmt_ctx = NULL;
26static int video_stream_idx = -1;
27
28/* for h264/265 */
29static int raw_stream;
30static int nal_size;
31static uint8_t s_nal_3[3] = {0,0,1};
32static uint8_t s_nal_4[4] = {0,0,0,1};
33
34static struct dmx_cb *dec_cb;
35static pthread_t dmx_t;
36static int thread_quit;
37static struct dmx_v_data v_data;
38static int video_frame_count = 0;
39
40static void dump(const char* path, uint8_t *data, int size) {
41 FILE* fd = fopen(path, "wb");
42 if (!fd)
43 return;
44 fwrite(data, 1, size, fd);
45 fflush(fd);
46 fclose(fd);
47}
48
49static int insert_nal() {
50 int size;
51 if (nal_size == 3) {
52 dec_cb->write(s_nal_3, sizeof(s_nal_3));
53 size = 3;
54 } else {
55 dec_cb->write(s_nal_4, sizeof(s_nal_4));
56 size = 4;
57 }
58 return size;
59}
60
61#if 0
62static bool check_nal(uint8_t *data, int size) {
63 if (size < 4)
64 return false;
65 if (nal_size == 3 && data[0] == 0 &&
66 data[1] == 0 && data[2] == 1)
67 return true;
68 if (nal_size == 4 && data[0] == 0 &&
69 data[1] == 0 && data[2] == 0 && data[3] == 1)
70 return true;
71 return false;
72}
73#endif
74
75static int demux_packet(AVPacket* pkt)
76{
77 int decoded = pkt->size;
78
79 if (pkt->stream_index != video_stream_idx)
80 return decoded;
81
82 /* video frame */
83 video_frame_count++;
84#ifdef DEBUG_FRAME
85 printf("video_frame n:%d pts:%llx size:%x\n",
86 video_frame_count,
87 pkt->pts, pkt->size);
88#endif
89
90 /* refer to ffmpeg hevc_mp4toannexb_filter()
91 * and h264_extradata_to_annexb()
92 */
93 if (H2645(video_stream->codecpar->codec_id)) {
94 uint8_t *p = pkt->data;
95 int length_size = nal_size;
96 int nalu_size = 0;
97 int processed = 0;
98
99 /* From raw ES */
100 if (raw_stream) {
101 dec_cb->write(pkt->data, pkt->size);
102 processed = pkt->size;
103 //printf("raw es frame\n");
104 }
105
106 /* data inside pkt->data is like:
107 * len0 + data0 + len1 + data1 ... + lenN + dataN
108 * lenX depends on the nal_size
109 */
110 while (processed < pkt->size) {
111 int i;
112
113 for (i = 0; i < length_size; i++)
114 nalu_size = (nalu_size << 8) | (*p++);
115 processed += length_size;
116
117 insert_nal();
118 dec_cb->write(p, nalu_size);
119
120#ifdef DEBUG_FRAME
121 printf("nalu_size(%04x) %02x %02x %02x %02x",
122 nalu_size, p[0], p[1], p[2], p[3]);
123#endif
124
125 p += nalu_size;
126 processed += nalu_size;
127
128#ifdef DEBUG_FRAME
129 printf(" ... %02x %02x %02x %02x\n",
130 *(p-3), *(p-2), *(p-1), *p);
131#endif
132 }
133 } else {
134 dec_cb->write(pkt->data, pkt->size);
135 }
136 dec_cb->frame_done();
137
138 return decoded;
139}
140
141static int open_codec_context(int *stream_idx,
142 AVFormatContext *fmt_ctx, enum AVMediaType type)
143{
144 int ret, stream_index;
145
146 ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
147 if (ret < 0) {
148 return ret;
149 } else {
150 stream_index = ret;
151 *stream_idx = stream_index;
152 }
153
154 return 0;
155}
156
157/*
158 * Refer to h264_parse.c ff_h264_decode_extradata()
159 * parse AVCDecoderConfigurationRecord
160 * See MPEG-4 Part 15 "Advanced Video Coding (AVC) file format" section 5.2.4.1 for details.
161 * data will be release outside
162 */
163static int h264_header_parse(uint8_t *data, int size,
164 uint8_t **o_data, int *o_size, int *nal_size) {
165 int i, cnt, nalsize;
166 const uint8_t *p = data;
167 int cur_size = 0;
168
169 if (!data || size <= 0)
170 return -1;
171
172 if (data[0] != 1) {
173 if (size < 7) return -1;
174 if (data[0] == 0 && data[1] == 0 && data[2] == 1)
175 *nal_size = 3;
176 else if (data[0] == 0 && data[1] == 0 && data[3] == 0 && data[4] == 1)
177 *nal_size = 4;
178 else {
179 printf("wrong header\n");
180 return -1;
181 }
182
183 raw_stream = 1;
184 *o_data = (uint8_t *)malloc(4096);
185 if (!*o_data) {
186 printf("oom");
187 return -1;
188 }
189 memcpy(*o_data, data, size);
190 *o_size = size;
191 return 0;
192 }
193
194 if (size < 7) {
195 printf("avcC %d too short\n", size);
196 return -1;
197 }
198
199 *o_data = (uint8_t *)malloc(4096);
200 if (!*o_data) {
201 printf("oom");
202 return -1;
203 }
204
205 // Store right nal length size that will be used to parse all other nals
206 *nal_size = (data[4] & 0x03) + 1;
207
208 // Decode sps from avcC
209 cnt = *(p + 5) & 0x1f; // Number of sps
210 printf("sps cnt:%d\n", cnt);
211
212 //NAL
213 if (cnt) {
214 if (*nal_size == 3) {
215 memcpy(*o_data + cur_size, s_nal_3, 3);
216 cur_size += 3;
217 } else if (*nal_size == 4) {
218 memcpy(*o_data + cur_size, s_nal_4, 4);
219 cur_size += 4;
220 } else {
221 printf("invalid nal size:%d\n", *nal_size);
222 goto err_exit;
223 }
224 }
225
226 p += 6;
227 for (i = 0; i < cnt; i++) {
228 nalsize = WORD_BE(p);
229 p += 2;
230 if (nalsize > size - (p - data))
231 goto err_exit;
232 memcpy(*o_data + cur_size, p, nalsize);
233 p += nalsize;
234 cur_size += nalsize;
235 }
236 // Decode pps from avcC
237 cnt = *(p++); // Number of pps
238 printf("pps cnt:%d\n", cnt);
239
240 //NAL
241 if (cnt) {
242 if (*nal_size == 3) {
243 memcpy(*o_data + cur_size, s_nal_3, 3);
244 cur_size += 3;
245 } else if (*nal_size == 4) {
246 memcpy(*o_data + cur_size, s_nal_4, 4);
247 cur_size += 4;
248 } else {
249 printf("invalid nal size:%d\n", *nal_size);
250 goto err_exit;
251 }
252 }
253
254 for (i = 0; i < cnt; i++) {
255 nalsize = WORD_BE(p);
256 p += 2;
257 if (nalsize > size - (p - data))
258 goto err_exit;
259 memcpy(*o_data + cur_size, p, nalsize);
260 p += nalsize;
261 cur_size += nalsize;
262 }
263 printf("header parse done. cur_size:%d\n", cur_size);
264 *o_size = cur_size;
265 return 0;
266err_exit:
267 free(*o_data);
268 return -2;
269}
270
271/*
272 * Refer to hevc_parse.c ff_hevc_decode_extradata()
273 * hvcC
274 * data will be release outside
275 */
276static int h265_header_parse(uint8_t *data, int size,
277 uint8_t **o_data, int *o_size, int *nal_size) {
278 const uint8_t *p = data;
279 int i, cur_size = 0;
280 int num_arrays;
281
282 if (!data || size <= 0)
283 return -1;
284
285 if (size < 7) {
286 printf("header %d too short\n", size);
287 return -1;
288 }
289
290 *o_data = (uint8_t *)malloc(4096);
291 if (!*o_data) {
292 printf("oom");
293 return -1;
294 }
295
296 if ((!data[0] && !data[1] && data[2] == 1) ||
297 (!data[0] && !data[1] && !data[2] && data[3] == 1)) {
298 /* not hvcC format */
299 *o_size = 0;
300 *nal_size = 4;
301 raw_stream = 1;
302 printf("raw header parse done");
303 return 0;
304 }
305 // Store right nal length size that will be used to parse all other nals
306 p += 21;
307 *nal_size = (*p & 0x03) + 1;
308 p++;
309 num_arrays = *p;
310 p++;
311
312 printf("array cnt:%d nal_size:%d\n", num_arrays, *nal_size);
313 // Decode nal units from hvcC
314 for (i = 0; i < num_arrays; i++) {
315 uint8_t nal_type;
316 uint16_t numNalus;
317 int j;
318
319 nal_type = *p & 0x3F;
320 p++;
321 numNalus = WORD_BE(p);
322 p += 2;
323 for (j = 0; j < numNalus; j++) {
324 uint16_t nalsize = WORD_BE(p);
325 p += 2;
326 //printf("%d: len:%u\n", j, nalsize);
327 if (nal_type == HEVC_NAL_VPS || nal_type == HEVC_NAL_SPS ||
328 nal_type == HEVC_NAL_PPS) {
329 //NAL header
330 if (*nal_size == 3) {
331 memcpy(*o_data + cur_size, s_nal_3, 3);
332 cur_size += 3;
333 } else if (*nal_size == 4) {
334 memcpy(*o_data + cur_size, s_nal_4, 4);
335 cur_size += 4;
336 } else {
337 printf("invalid nal size:%d\n", *nal_size);
338 goto err_exit;
339 }
340
341 memcpy(*o_data + cur_size, p, nalsize);
342 cur_size += nalsize;
343 }
344 p += nalsize;
345 }
346 }
347 printf("header parse done. cur_size:%d\n", cur_size);
348 *o_size = cur_size;
349 return 0;
350err_exit:
351 free(*o_data);
352 dump("cur.dat", data, size);
353 return -2;
354}
355
356static void* dmx_thread_func (void *arg) {
357 AVPacket pkt;
358
359 /* initialize packet, set data to NULL, let the demuxer fill it */
360 av_init_packet(&pkt);
361 pkt.data = NULL;
362 pkt.size = 0;
363
364 /* read frames from the file */
365 while (av_read_frame(fmt_ctx, &pkt) >= 0) {
366 if (thread_quit)
367 break;
368 demux_packet(&pkt);
369 av_packet_unref(&pkt);
370 }
371
372 if (!thread_quit)
373 dec_cb->eos();
374
375 printf("dmx done, total vframe:%d\n", video_frame_count);
376 return NULL;
377}
378
379static void log_callback(void *ptr, int level,
380 const char *fmt, va_list vargs)
381{
382 if (ffmpeg_log)
383 vprintf(fmt, vargs);
384}
385
386int demux_init(const char *file, struct dmx_cb *cb)
387{
388 int ret = 0;
389 AVCodecParameters *dec_ctx = NULL;
390
391 if (!file || !cb) {
392 printf("null pointer\n");
393 return 1;
394 }
395
396 dec_cb = cb;
397
398 av_log_set_level(AV_LOG_ERROR);
399 //av_log_set_level(AV_LOG_DEBUG);
400 av_log_set_callback(log_callback);
401
402 fmt_ctx = avformat_alloc_context();
403 /* open input file, and allocate format context */
404 ret = avformat_open_input(&fmt_ctx, file, NULL, NULL);
405 if (ret) {
406 printf("Could not open source file %s ret:%d %s\n", file, ret, av_err2str(ret));
407 return 2;
408 }
409
410 /* retrieve stream information */
411 if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
412 printf("Could not find stream information\n");
413 ret = 3;
414 goto end;
415 }
416
417 if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
418 uint8_t *header;
419 int h_size;
420
421 video_stream = fmt_ctx->streams[video_stream_idx];
422 dec_ctx = video_stream->codecpar;
423
424 /* allocate image where the decoded image will be put */
425 v_data.width = dec_ctx->width;
426 v_data.height = dec_ctx->height;
427 if (dec_ctx->codec_id == AV_CODEC_ID_H264)
428 v_data.type = VIDEO_TYPE_H264;
429 else if (dec_ctx->codec_id == AV_CODEC_ID_H265)
430 v_data.type = VIDEO_TYPE_H265;
431 else if (dec_ctx->codec_id == AV_CODEC_ID_MPEG2VIDEO)
432 v_data.type = VIDEO_TYPE_MPEG2;
433 else if (dec_ctx->codec_id == AV_CODEC_ID_VP9)
434 v_data.type = VIDEO_TYPE_VP9;
435 else if (dec_ctx->codec_id == AV_CODEC_ID_AV1)
436 v_data.type = VIDEO_TYPE_AV1;
437 else {
438 printf("format not supported %d\n", dec_ctx->codec_id);
439 ret = 3;
440 goto end;
441 }
442
443
444 //printf("AV_CODEC_ID_H264:%d AV_CODEC_ID_H265:%d\n", AV_CODEC_ID_H264, AV_CODEC_ID_H265);
445 printf("video stream: format:%d %dx%d\n",
446 dec_ctx->codec_id, v_data.width, v_data.height);
447
448 dec_cb->meta_done(&v_data);
449
450 printf("video header:%d\n", dec_ctx->extradata_size);
451 h_size = dec_ctx->extradata_size;
452 if (dec_ctx->codec_id == AV_CODEC_ID_H264 &&
453 dec_ctx->extradata_size) {
454 if(h264_header_parse(dec_ctx->extradata,
455 dec_ctx->extradata_size,
456 &header, &h_size, &nal_size)) {
457 printf("parse header fail\n");
458 ret = 5;
459 goto end;
460 }
461 dec_cb->write(header, h_size);
462 free(header);
463 } else if (dec_ctx->codec_id == AV_CODEC_ID_H265 &&
464 dec_ctx->extradata_size) {
465 if(h265_header_parse(dec_ctx->extradata,
466 dec_ctx->extradata_size,
467 &header, &h_size, &nal_size)) {
468 printf("parse header fail\n");
469 ret = 6;
470 goto end;
471 }
472 if (h_size)
473 dec_cb->write(header, h_size);
474 free(header);
475 } else if (dec_ctx->extradata_size) {
476 dec_cb->write(dec_ctx->extradata, dec_ctx->extradata_size);
477 }
478 }
479
480 /* dump input information to stderr */
481 av_dump_format(fmt_ctx, 0, file, 0);
482
483 if (!video_stream) {
484 printf("Could not find audio or video stream in the input, aborting\n");
485 ret = 7;
486 goto end;
487 }
488
489 if (pthread_create(&dmx_t, NULL, dmx_thread_func, NULL)) {
490 printf("Could not create thread, aborting\n");
491 ret = 8;
492 goto end;
493 }
494
495 return 0;
496
497end:
498 avformat_close_input(&fmt_ctx);
499 return ret;
500}
501
502int dmx_destroy() {
503 thread_quit = true;
504 pthread_join(dmx_t, NULL);
505 avformat_close_input(&fmt_ctx);
506 if (fmt_ctx)
507 avformat_free_context(fmt_ctx);
508 return 0;
509}