av_decode.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. //
  2. // Created by 阳坤 on 2022/3/1.
  3. //
  4. #include "av_decode.h"
  5. static int
  6. openFFmpegDecoderContext(AVFormatContext *fmtCtx, enum AVMediaType type, int *streamIdx, AVCodecContext **decCtx,
  7. enum AVCodecID codecId) {
  8. if (!fmtCtx)return -1;
  9. int ret = -1;
  10. int streamIndex = *streamIdx;
  11. AVCodecContext *ctx = NULL;
  12. AVCodecParameters *parameters = fmtCtx->streams[streamIndex]->codecpar;;
  13. AVCodec *codec = avcodec_find_decoder(codecId);
  14. if (codec == NULL) {
  15. if (codecId == AV_CODEC_ID_PNG)
  16. LOGE("openFFmpegDecoderContext avcodec_find_decoder png not found. \n");
  17. LOGE("openFFmpegDecoderContext avcodec_find_decoder=%d not found. \n", codecId);
  18. return -1;
  19. }
  20. ctx = avcodec_alloc_context3(codec);
  21. if (!ctx || !parameters || !codec) {
  22. LOGE("openFFmpegDecoderContext init error %d ctx==null=%d parameters==null=%d codec==null=%d \n", codecId,
  23. ctx == NULL, parameters == NULL, codec == NULL);
  24. return -1;
  25. }
  26. if ((ret = avcodec_parameters_to_context(ctx, parameters)) != 0) {
  27. Log("Failed to copy %s codec parameters to decoder context.", av_get_media_type_string(type));
  28. return -1;
  29. }
  30. switch (type) {
  31. case AVMEDIA_TYPE_VIDEO:
  32. ctx->framerate = av_guess_frame_rate(fmtCtx, fmtCtx->streams[streamIndex],
  33. NULL);
  34. break;
  35. case AVMEDIA_TYPE_AUDIO:
  36. break;
  37. }
  38. ctx->thread_count = 3;
  39. if ((ret = avcodec_open2(ctx, codec, NULL)) != 0) {
  40. char buf[512];
  41. av_strerror(ret, buf, 512);
  42. LOGE("Failed to open %s codec. error=%s \n", av_get_media_type_string(type), buf);
  43. return -1;
  44. }
  45. *decCtx = ctx;
  46. avcodec_flush_buffers(ctx);
  47. ret = 0;
  48. return ret;
  49. }
  50. static int av_decode(struct DecoderContext *pContext, AVPacket *pPacket, enum AVMediaType type) {
  51. AVCodecContext *ctx = NULL;
  52. switch (type) {
  53. case AVMEDIA_TYPE_VIDEO:
  54. ctx = pContext->videoCodecContext;
  55. break;
  56. case AVMEDIA_TYPE_AUDIO:
  57. ctx = pContext->audioCodecContext;
  58. break;
  59. }
  60. if (!ctx)return -1;
  61. int ret = 0;
  62. if (pPacket)
  63. ret = avcodec_send_packet(ctx, pPacket);
  64. else ret = avcodec_send_packet(ctx, NULL);
  65. if (ret != 0) {
  66. return -1;
  67. }
  68. while (1) {
  69. AVFrame *out_frame = av_frame_alloc();
  70. ret = avcodec_receive_frame(ctx, out_frame);
  71. if (ret != 0) {
  72. av_frame_free(&out_frame);
  73. break;
  74. }
  75. int64_t pts = -1;
  76. if (pPacket)
  77. pts = out_frame->pts * (1000 *
  78. (av_q2d(pContext->avformatContext->streams[(pPacket)->stream_index]->time_base)));
  79. else
  80. pts = out_frame->pts * (1000 *
  81. (av_q2d(pContext->avformatContext->streams[pContext->st_index[type]]->time_base)));
  82. // int64_t offset = 0;
  83. // if (pContext->offset != AV_NOPTS_VALUE) {
  84. // offset += pContext->offset / 1000;
  85. // pts -= offset;
  86. // }
  87. if (pContext->end_time > 0 && pts > pContext->end_time && type == AVMEDIA_TYPE_VIDEO) {
  88. av_frame_free(&out_frame);
  89. return -4;
  90. }
  91. if (pContext->end_time > 0 && pts > pContext->end_time && type == AVMEDIA_TYPE_AUDIO) {
  92. av_frame_free(&out_frame);
  93. return 0;
  94. }
  95. // LOGE("decode is video=%d pts=%lld \n",pPacket->stream_index == pContext->st_index[AVMEDIA_TYPE_VIDEO],pts);
  96. if (pts>=14000)
  97. {
  98. // LOGE("decode is video=%d pts=%lld \n",pPacket->stream_index == pContext->st_index[AVMEDIA_TYPE_VIDEO],pts);
  99. }
  100. if (pts < pContext->start_time && pContext->start_time >= 0 && pContext->force_Iframe != 1) {
  101. av_frame_free(&out_frame);
  102. continue;
  103. }
  104. double def_frame_delay =
  105. (double) (1000.0 / pContext->fps);
  106. //如果持续时间很短,那么就用每帧固定延迟时间
  107. if (out_frame->pkt_duration < 10) {
  108. pContext->decode_frame_ms += (long) def_frame_delay;
  109. } else {//使用更加精准的帧延迟时间
  110. //根据每帧的延迟时间来相加,更加精准,有些 pkt_duration 持续时长是 0
  111. pContext->decode_frame_ms += (int64_t) (out_frame->pkt_duration *
  112. ((AV_TIME_BASE *
  113. (av_q2d(pContext->avformatContext->streams[pContext->st_index[AVMEDIA_TYPE_VIDEO]]->time_base))))) /
  114. 1000;
  115. }
  116. out_frame->pts = pts;
  117. out_frame->pkt_dts = pts;
  118. switch (type) {
  119. case AVMEDIA_TYPE_VIDEO:
  120. pContext->video_queue->PushBack(out_frame);
  121. break;
  122. case AVMEDIA_TYPE_AUDIO:
  123. pContext->audio_queue->PushBack(out_frame);
  124. break;
  125. }
  126. }
  127. return ret;
  128. }
  129. /**
  130. * 初始化解码器
  131. * @param url
  132. * @param outVideoFormat
  133. * @param force_Iframe
  134. * @param end_time
  135. * @return
  136. */
  137. long initDecoder(const char *url, int force_Iframe, DisableMediaType disableMediaType) {
  138. struct DecoderContext *dctx = (struct DecoderContext *) malloc(sizeof(struct DecoderContext));
  139. if (!dctx) {
  140. LOGE("DecoderContext create fail.");
  141. return -1;
  142. }
  143. memset(dctx, 0, sizeof(struct DecoderContext));
  144. dctx->url = strdup(url);
  145. dctx->force_Iframe = force_Iframe;
  146. dctx->ffthread_count = 0;
  147. dctx->start_time = 0;
  148. dctx->end_time = -1;
  149. dctx->disableType = disableMediaType;
  150. char err_info[512] = {0};
  151. avformat_network_init();
  152. int ret = avformat_open_input(&(dctx->avformatContext), dctx->url, NULL, NULL);
  153. if (ret != 0) {
  154. av_strerror(ret, err_info, 512);
  155. Log("avformat_open_input failed %d %s. path=%s \n", ret, err_info, dctx->url);
  156. close_decoder((long) dctx);
  157. return ret;
  158. }
  159. ret = avformat_find_stream_info(dctx->avformatContext, 0);
  160. if (ret < 0) {
  161. av_strerror(ret, err_info, 512);
  162. Log("Failed to retrieve input stream information msg=%s\n", err_info);
  163. close_decoder((long) dctx);
  164. return ret;
  165. }
  166. dctx->st_index[AVMEDIA_TYPE_VIDEO] =
  167. av_find_best_stream(dctx->avformatContext, AVMEDIA_TYPE_VIDEO,
  168. dctx->st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
  169. if (dctx->st_index[AVMEDIA_TYPE_VIDEO] < 0) {
  170. for (int i = 0; i < dctx->avformatContext->nb_streams; ++i) {
  171. if (dctx->avformatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
  172. dctx->st_index[AVMEDIA_TYPE_VIDEO] = i;
  173. }
  174. }
  175. if (dctx->st_index[AVMEDIA_TYPE_VIDEO] <0)
  176. {
  177. LOGE("video stream not found.");
  178. // return -1;
  179. }
  180. dctx->st_index[AVMEDIA_TYPE_AUDIO] = av_find_best_stream(dctx->avformatContext,
  181. AVMEDIA_TYPE_AUDIO,
  182. -1,
  183. -1,
  184. NULL, 0);
  185. if (dctx->st_index[AVMEDIA_TYPE_AUDIO] < 0) {
  186. for (int i = 0; i < dctx->avformatContext->nb_streams; ++i) {
  187. if (dctx->avformatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
  188. dctx->st_index[AVMEDIA_TYPE_AUDIO] = i;
  189. }
  190. }
  191. if (dctx->st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
  192. AVStream *as = dctx->avformatContext->streams[dctx->st_index[AVMEDIA_TYPE_VIDEO]];
  193. dctx->v_codec_id = as->codecpar->codec_id;
  194. dctx->vformat = as->codecpar->format;
  195. dctx->width = as->codecpar->width;
  196. dctx->height = as->codecpar->height;
  197. dctx->v_bit_rate = as->codecpar->bit_rate;
  198. if (dctx->v_bit_rate <= 0 && dctx->avformatContext->bit_rate > 0) {
  199. dctx->v_bit_rate = dctx->avformatContext->bit_rate;
  200. } else if (dctx->v_bit_rate <= 0) {
  201. dctx->v_bit_rate = dctx->width * dctx->height * 3;
  202. }
  203. dctx->fps = av_q2d(as->avg_frame_rate);//拿到视频码率
  204. dctx->rotate = getVideoRotate(as->metadata);
  205. LOGE("找到视频流 width=%d height=%d bit_rate=%d fps=%d rotate=%d\n", dctx->width,
  206. dctx->height, dctx->v_bit_rate, dctx->fps,
  207. dctx->rotate);
  208. }
  209. if (dctx->st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
  210. AVStream *as = dctx->avformatContext->streams[dctx->st_index[AVMEDIA_TYPE_AUDIO]];
  211. dctx->a_codec_id = as->codecpar->codec_id;
  212. dctx->sampleRate = as->codecpar->sample_rate;
  213. dctx->channels = as->codecpar->channels;
  214. dctx->a_bit_rate = as->codecpar->bit_rate;
  215. dctx->aformat = as->codecpar->format;
  216. dctx->channels_layout = as->codecpar->channel_layout;
  217. LOGE("找到音频流 sampleRate=%d channels=%d bit_rate=%d aformat=%d channels_layout=%d\n",
  218. dctx->sampleRate, dctx->channels, dctx->a_bit_rate,
  219. dctx->aformat, dctx->channels_layout);
  220. }
  221. dctx->totalMs = dctx->avformatContext->duration / (AV_TIME_BASE / 1000);
  222. if (dctx->start_time > dctx->totalMs) {
  223. LOGE("媒体总时长 totalMs=%lld start_time=%lld \n", dctx->totalMs, dctx->start_time);
  224. return -1;
  225. }
  226. LOGE("媒体总时长 totalMs=%lld \n", dctx->totalMs);
  227. if (dctx->avformatContext->start_time != AV_NOPTS_VALUE)
  228. dctx->offset = dctx->avformatContext->start_time;
  229. if (dctx->st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
  230. ret = openFFmpegDecoderContext(dctx->avformatContext, AVMEDIA_TYPE_AUDIO,
  231. &dctx->st_index[AVMEDIA_TYPE_AUDIO],
  232. &dctx->audioCodecContext, dctx->a_codec_id);
  233. if (ret != 0) {
  234. LOGE("audio openFFmpegDecoderContext error!");
  235. close_decoder((long) dctx);
  236. return ret;
  237. }
  238. }
  239. if (dctx->st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
  240. ret = openFFmpegDecoderContext(dctx->avformatContext, AVMEDIA_TYPE_VIDEO,
  241. &dctx->st_index[AVMEDIA_TYPE_VIDEO],
  242. &dctx->videoCodecContext, dctx->v_codec_id);
  243. if (ret != 0) {
  244. LOGE("video openFFmpegDecoderContext error!");
  245. close_decoder((long) dctx);
  246. return ret;
  247. }
  248. // dctx->audio_queue = new BlockQueue<AVFrame *>(dctx->fps);
  249. }
  250. dctx->video_queue = new BlockQueue<AVFrame *>(MAX(10,dctx->fps));
  251. seekToMs(dctx, dctx->offset);
  252. return ret == 0 ? (long) dctx : ret;
  253. }
  254. static int is_realtime(AVFormatContext *s) {
  255. if (!strcmp(s->iformat->name, "rtp")
  256. || !strcmp(s->iformat->name, "rtsp")
  257. || !strcmp(s->iformat->name, "sdp")
  258. || !strcmp(s->iformat->name, "hls")
  259. )
  260. return 1;
  261. // if (s->pb && (!strncmp(s->url, "rtp:", 4)
  262. // || !strncmp(s->url, "udp:", 4)
  263. // )
  264. // )
  265. // return 1;
  266. return 0;
  267. }
  268. void seekToMs(DecoderContext *dctx, int64_t offset) {
  269. int64_t timestamp = dctx->start_time * 1000;
  270. if (offset != AV_NOPTS_VALUE)
  271. timestamp += offset;
  272. if (timestamp > 0) {
  273. avformat_flush(dctx->avformatContext);
  274. int re = is_realtime(dctx->avformatContext);
  275. int64_t tartget_pos = re ? MAX(0, timestamp - 10000000) : timestamp;
  276. int ret = avformat_seek_file(dctx->avformatContext, -1, INT64_MIN, tartget_pos,
  277. tartget_pos,
  278. AVSEEK_FLAG_BACKWARD);
  279. if (ret >= 0) {
  280. if (dctx->videoCodecContext)
  281. avcodec_flush_buffers(dctx->videoCodecContext);
  282. if (dctx->audioCodecContext)
  283. avcodec_flush_buffers(dctx->audioCodecContext);
  284. }
  285. }
  286. }
  287. void close_decoder(long decodec_id) {
  288. LOGE("close_decoder \n");
  289. if (decodec_id > 0) {
  290. struct DecoderContext *ctx = (struct DecoderContext *) decodec_id;
  291. if (ctx->url) {
  292. free((void *) ctx->url);
  293. ctx->url = NULL;
  294. }
  295. if (ctx->avformatContext) {
  296. avformat_network_deinit();
  297. avformat_flush(ctx->avformatContext);
  298. avformat_close_input(&(ctx->avformatContext));
  299. avformat_free_context(ctx->avformatContext);
  300. ctx->avformatContext = NULL;
  301. }
  302. if (ctx->audioCodecContext) {
  303. avcodec_flush_buffers(ctx->audioCodecContext);
  304. avcodec_free_context(&(ctx->audioCodecContext));
  305. avcodec_close(ctx->audioCodecContext);
  306. ctx->audioCodecContext = NULL;
  307. }
  308. if (ctx->videoCodecContext) {
  309. avcodec_flush_buffers(ctx->videoCodecContext);
  310. avcodec_free_context(&(ctx->videoCodecContext));
  311. avcodec_close(ctx->videoCodecContext);
  312. ctx->videoCodecContext = NULL;
  313. }
  314. if (ctx->audio_queue) {
  315. AVFrame *frame = NULL;
  316. do {
  317. if (ctx->audio_queue->Size() > 0) {
  318. ctx->audio_queue->PopBack(frame);
  319. }
  320. av_frame_free(&frame);
  321. } while (frame != NULL);
  322. ctx->audio_queue->Close();
  323. }
  324. if (ctx->video_queue) {
  325. AVFrame *frame = NULL;
  326. do {
  327. if (ctx->video_queue->Size() > 0) {
  328. ctx->video_queue->PopBack(frame);
  329. }
  330. av_frame_free(&frame);
  331. } while (frame != NULL);
  332. ctx->video_queue->Close();
  333. }
  334. free(ctx);
  335. ctx = NULL;
  336. }
  337. LOGE("close_decoder out\n");
  338. }
  339. int av_read_decode_frame(long decodec_id) {
  340. auto *ctx = (DecoderContext *) decodec_id;
  341. pthread_create(&ctx->thread_id, 0, av_read_decode_thread, ctx);
  342. }
  343. void *av_read_decode_thread(void *pVoid) {
  344. int ret = 0;
  345. if (pVoid) {
  346. auto *ctx = (struct DecoderContext *) pVoid;
  347. if (ctx && ctx->avformatContext) {
  348. for (const auto &cur_item : ctx->vs_decodes) {
  349. //init
  350. ctx->decode_frame_ms = 0;
  351. if (cur_item->startTimeMs > 0) {
  352. ctx->start_time = cur_item->startTimeMs;
  353. seekToMs(ctx, ctx->offset);
  354. }
  355. if (cur_item->endTimeMs > 0)
  356. ctx->end_time = cur_item->endTimeMs;
  357. while (1) {
  358. if (ctx->decode_frame_ms > ctx->end_time && ctx->end_time > 0)
  359. break;
  360. AVPacket *pkg = av_packet_alloc();
  361. ret = av_read_frame(ctx->avformatContext, pkg);
  362. if (ret == AVERROR_EOF) {
  363. LOGE("startDecoder flush \n");
  364. av_decode(ctx, NULL, AVMEDIA_TYPE_VIDEO);
  365. av_decode(ctx, NULL, AVMEDIA_TYPE_AUDIO);
  366. av_packet_free(&pkg);
  367. LOGE("av_read_frame eof!\n");
  368. break;
  369. }
  370. enum AVMediaType type = ctx->avformatContext->streams[pkg->stream_index]->codecpar->codec_type;
  371. switch (type) {
  372. case AVMEDIA_TYPE_AUDIO:
  373. if (ctx->disableType == AUDIO) {
  374. av_packet_free(&pkg);
  375. continue;
  376. }
  377. break;
  378. case AVMEDIA_TYPE_VIDEO:
  379. if (ctx->disableType == VIDEO) {
  380. av_packet_free(&pkg);
  381. continue;
  382. }
  383. break;
  384. default:
  385. break;
  386. }
  387. //对 pts ,dts 校准,因为有偏移
  388. if (pkg->dts != AV_NOPTS_VALUE && ctx->avformatContext->start_time > 0)
  389. pkg->dts += av_rescale_q(-ctx->avformatContext->start_time, AV_TIME_BASE_Q,
  390. ctx->avformatContext->streams[pkg->stream_index]->time_base);
  391. if (pkg->pts != AV_NOPTS_VALUE && ctx->avformatContext->start_time > 0)
  392. pkg->pts += av_rescale_q(-ctx->avformatContext->start_time, AV_TIME_BASE_Q,
  393. ctx->avformatContext->streams[pkg->stream_index]->time_base);
  394. if (ctx->force_Iframe && pkg->flags != AV_PKT_FLAG_KEY &&
  395. ctx->avformatContext->streams[pkg->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
  396. av_packet_free(&pkg);
  397. continue;
  398. } else {
  399. ret = av_decode(ctx, pkg, type);
  400. if (ret == -4) {
  401. av_packet_free(&pkg);
  402. break;
  403. }
  404. }
  405. av_packet_free(&pkg);
  406. }
  407. }
  408. }
  409. if (ctx->audio_queue){
  410. LOGE("push empty packet audio !\n");
  411. ctx->audio_queue->PushBack(NULL);
  412. }
  413. LOGE("push empty packet video !\n");
  414. ctx->video_queue->PushBack(NULL);
  415. }
  416. LOGE("read thread exit !\n");
  417. pthread_exit(NULL);
  418. }