av_decode.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  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. if (pContext->end_time > 0 && pts > pContext->end_time && type == AVMEDIA_TYPE_VIDEO)return -4;
  83. if (pContext->end_time > 0 && pts > pContext->end_time && type == AVMEDIA_TYPE_AUDIO)return 0;
  84. // LOGE("decode is video=%d pts=%lld \n",pPacket->stream_index == pContext->st_index[AVMEDIA_TYPE_VIDEO],pts);
  85. if (pts < pContext->start_time && pContext->start_time >= 0 && pContext->force_Iframe != 1) {
  86. continue;
  87. }
  88. double def_frame_delay =
  89. (double) (1000.0 / pContext->fps);
  90. //如果持续时间很短,那么就用每帧固定延迟时间
  91. if (out_frame->pkt_duration < 10) {
  92. pContext->decode_frame_ms += (long) def_frame_delay;
  93. } else {//使用更加精准的帧延迟时间
  94. //根据每帧的延迟时间来相加,更加精准,有些 pkt_duration 持续时长是 0
  95. pContext->decode_frame_ms += (int64_t) (out_frame->pkt_duration *
  96. ((AV_TIME_BASE *
  97. (av_q2d(pContext->avformatContext->streams[pContext->st_index[AVMEDIA_TYPE_VIDEO]]->time_base))))) /
  98. 1000;
  99. }
  100. out_frame->pts = pts;
  101. out_frame->pkt_dts = pts;
  102. switch (type) {
  103. case AVMEDIA_TYPE_VIDEO:
  104. pContext->video_queue->PushBack(out_frame);
  105. break;
  106. case AVMEDIA_TYPE_AUDIO:
  107. pContext->audio_queue->PushBack(out_frame);
  108. break;
  109. }
  110. }
  111. return ret;
  112. }
  113. /**
  114. * 初始化解码器
  115. * @param url
  116. * @param outVideoFormat
  117. * @param force_Iframe
  118. * @param end_time
  119. * @return
  120. */
  121. long initDecoder(const char *url, int force_Iframe, DisableMediaType disableMediaType) {
  122. struct DecoderContext *dctx = (struct DecoderContext *) malloc(sizeof(struct DecoderContext));
  123. if (!dctx) {
  124. LOGE("DecoderContext create fail.");
  125. return -1;
  126. }
  127. memset(dctx, 0, sizeof(struct DecoderContext));
  128. dctx->url = strdup(url);
  129. dctx->force_Iframe = force_Iframe;
  130. dctx->ffthread_count = 0;
  131. dctx->start_time = 0;
  132. dctx->end_time = -1;
  133. dctx->disableType = disableMediaType;
  134. char err_info[512] = {0};
  135. int ret = avformat_open_input(&(dctx->avformatContext), dctx->url, NULL, NULL);
  136. if (ret != 0) {
  137. av_strerror(ret, err_info, 512);
  138. Log("avformat_open_input failed %d %s. path=%s \n", ret, err_info, dctx->url);
  139. close_decoder((long) dctx);
  140. return ret;
  141. }
  142. ret = avformat_find_stream_info(dctx->avformatContext, 0);
  143. if (ret < 0) {
  144. av_strerror(ret, err_info, 512);
  145. Log("Failed to retrieve input stream information msg=%s\n", err_info);
  146. close_decoder((long) dctx);
  147. return ret;
  148. }
  149. dctx->st_index[AVMEDIA_TYPE_VIDEO] =
  150. av_find_best_stream(dctx->avformatContext, AVMEDIA_TYPE_VIDEO,
  151. dctx->st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
  152. if (dctx->st_index[AVMEDIA_TYPE_VIDEO] < 0) {
  153. for (int i = 0; i < dctx->avformatContext->nb_streams; ++i) {
  154. if (dctx->avformatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
  155. dctx->st_index[AVMEDIA_TYPE_VIDEO] = i;
  156. }
  157. }
  158. dctx->st_index[AVMEDIA_TYPE_AUDIO] = av_find_best_stream(dctx->avformatContext,
  159. AVMEDIA_TYPE_AUDIO,
  160. -1,
  161. -1,
  162. NULL, 0);
  163. if (dctx->st_index[AVMEDIA_TYPE_AUDIO] < 0) {
  164. for (int i = 0; i < dctx->avformatContext->nb_streams; ++i) {
  165. if (dctx->avformatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
  166. dctx->st_index[AVMEDIA_TYPE_AUDIO] = i;
  167. }
  168. }
  169. if (dctx->st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
  170. AVStream *as = dctx->avformatContext->streams[dctx->st_index[AVMEDIA_TYPE_VIDEO]];
  171. dctx->v_codec_id = as->codecpar->codec_id;
  172. dctx->vformat = as->codecpar->format;
  173. dctx->width = as->codecpar->width;
  174. dctx->height = as->codecpar->height;
  175. dctx->v_bit_rate = as->codecpar->bit_rate;
  176. if (dctx->v_bit_rate <= 0 && dctx->avformatContext->bit_rate > 0) {
  177. dctx->v_bit_rate = dctx->avformatContext->bit_rate;
  178. } else if (dctx->v_bit_rate <= 0) {
  179. dctx->v_bit_rate = dctx->width * dctx->height * 3;
  180. }
  181. dctx->fps = av_q2d(as->avg_frame_rate);//拿到视频码率
  182. dctx->rotate = getVideoRotate(as->metadata);
  183. LOGE("找到视频流 width=%d height=%d bit_rate=%d fps=%d rotate=%d\n", dctx->width,
  184. dctx->height, dctx->v_bit_rate, dctx->fps,
  185. dctx->rotate);
  186. }
  187. if (dctx->st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
  188. AVStream *as = dctx->avformatContext->streams[dctx->st_index[AVMEDIA_TYPE_AUDIO]];
  189. dctx->a_codec_id = as->codecpar->codec_id;
  190. dctx->sampleRate = as->codecpar->sample_rate;
  191. dctx->channels = as->codecpar->channels;
  192. dctx->a_bit_rate = as->codecpar->bit_rate;
  193. dctx->aformat = as->codecpar->format;
  194. dctx->channels_layout = as->codecpar->channel_layout;
  195. LOGE("找到音频流 sampleRate=%d channels=%d bit_rate=%d aformat=%d channels_layout=%d\n",
  196. dctx->sampleRate, dctx->channels, dctx->a_bit_rate,
  197. dctx->aformat, dctx->channels_layout);
  198. }
  199. dctx->totalMs = dctx->avformatContext->duration / (AV_TIME_BASE / 1000);
  200. if (dctx->start_time > dctx->totalMs) {
  201. LOGE("媒体总时长 totalMs=%lld start_time=%lld \n", dctx->totalMs, dctx->start_time);
  202. return -1;
  203. }
  204. LOGE("媒体总时长 totalMs=%lld \n", dctx->totalMs);
  205. if (dctx->avformatContext->start_time != AV_NOPTS_VALUE)
  206. dctx->offset = dctx->avformatContext->start_time;
  207. if (dctx->st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
  208. ret = openFFmpegDecoderContext(dctx->avformatContext, AVMEDIA_TYPE_AUDIO,
  209. &dctx->st_index[AVMEDIA_TYPE_AUDIO],
  210. &dctx->audioCodecContext, dctx->a_codec_id);
  211. if (ret != 0) {
  212. LOGE("audio openFFmpegDecoderContext error!");
  213. close_decoder((long) dctx);
  214. return ret;
  215. }
  216. }
  217. if (dctx->st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
  218. ret = openFFmpegDecoderContext(dctx->avformatContext, AVMEDIA_TYPE_VIDEO,
  219. &dctx->st_index[AVMEDIA_TYPE_VIDEO],
  220. &dctx->videoCodecContext, dctx->v_codec_id);
  221. if (ret != 0) {
  222. LOGE("video openFFmpegDecoderContext error!");
  223. close_decoder((long) dctx);
  224. return ret;
  225. }
  226. dctx->audio_queue = new BlockQueue<AVFrame *>(dctx->fps);
  227. dctx->video_queue = new BlockQueue<AVFrame *>(dctx->fps);
  228. }
  229. seekToMs(dctx);
  230. return ret == 0 ? (long) dctx : ret;
  231. }
  232. void seekToMs(DecoderContext *dctx) {
  233. int64_t timestamp = dctx->start_time * 1000;
  234. if (dctx->offset != AV_NOPTS_VALUE)
  235. timestamp += dctx->offset;
  236. if (timestamp > 0) {
  237. avformat_flush(dctx->avformatContext);
  238. int ret = avformat_seek_file(dctx->avformatContext, -1, INT64_MIN, timestamp,
  239. INT64_MAX,
  240. AVSEEK_FLAG_BACKWARD);
  241. if (ret >= 0) {
  242. if (dctx->videoCodecContext)
  243. avcodec_flush_buffers(dctx->videoCodecContext);
  244. if (dctx->audioCodecContext)
  245. avcodec_flush_buffers(dctx->audioCodecContext);
  246. }
  247. }
  248. }
  249. void close_decoder(long decodec_id) {
  250. if (decodec_id > 0) {
  251. struct DecoderContext *ctx = (struct DecoderContext *) decodec_id;
  252. if (ctx->url) {
  253. free((void *) ctx->url);
  254. ctx->url = NULL;
  255. }
  256. if (ctx->avformatContext) {
  257. avformat_network_deinit();
  258. avformat_flush(ctx->avformatContext);
  259. avformat_close_input(&(ctx->avformatContext));
  260. avformat_free_context(ctx->avformatContext);
  261. ctx->avformatContext = NULL;
  262. }
  263. if (ctx->audioCodecContext) {
  264. avcodec_flush_buffers(ctx->audioCodecContext);
  265. avcodec_free_context(&(ctx->audioCodecContext));
  266. avcodec_close(ctx->audioCodecContext);
  267. ctx->audioCodecContext = NULL;
  268. }
  269. if (ctx->videoCodecContext) {
  270. avcodec_flush_buffers(ctx->videoCodecContext);
  271. avcodec_free_context(&(ctx->videoCodecContext));
  272. avcodec_close(ctx->videoCodecContext);
  273. ctx->videoCodecContext = NULL;
  274. }
  275. if (ctx->audio_queue) {
  276. AVFrame *frame = NULL;
  277. do {
  278. if (ctx->audio_queue->Size() > 0) {
  279. ctx->audio_queue->PopBack(frame);
  280. }
  281. av_frame_free(&frame);
  282. } while (frame != NULL);
  283. ctx->audio_queue->Close();
  284. }
  285. if (ctx->video_queue) {
  286. AVFrame *frame = NULL;
  287. do {
  288. if (ctx->video_queue->Size() > 0) {
  289. ctx->video_queue->PopBack(frame);
  290. }
  291. av_frame_free(&frame);
  292. } while (frame != NULL);
  293. ctx->video_queue->Close();
  294. }
  295. free(ctx);
  296. ctx = NULL;
  297. }
  298. }
  299. int av_read_decode_frame(long decodec_id) {
  300. auto *ctx = (DecoderContext *) decodec_id;
  301. pthread_create(&ctx->thread_id, 0, av_read_decode_thread, ctx);
  302. }
  303. void *av_read_decode_thread(void *pVoid) {
  304. int ret = 0;
  305. if (pVoid) {
  306. auto *ctx = (struct DecoderContext *) pVoid;
  307. if (ctx && ctx->avformatContext) {
  308. for (const auto &cur_item : ctx->vs_decodes) {
  309. //init
  310. ctx->decode_frame_ms = 0;
  311. if (cur_item->startTimeMs > 0) {
  312. ctx->start_time = cur_item->startTimeMs;
  313. seekToMs(ctx);
  314. }
  315. if (cur_item->endTimeMs > 0)
  316. ctx->end_time = cur_item->endTimeMs;
  317. while (1) {
  318. if (ctx->decode_frame_ms > ctx->end_time && ctx->end_time > 0)
  319. break;
  320. AVPacket *pkg = av_packet_alloc();
  321. ret = av_read_frame(ctx->avformatContext, pkg);
  322. if (ret == AVERROR_EOF) {
  323. LOGE("startDecoder flush \n");
  324. av_decode(ctx, NULL, AVMEDIA_TYPE_VIDEO);
  325. av_decode(ctx, NULL, AVMEDIA_TYPE_AUDIO);
  326. av_packet_free(&pkg);
  327. LOGE("av_read_frame eof!\n");
  328. break;
  329. }
  330. enum AVMediaType type = ctx->avformatContext->streams[pkg->stream_index]->codecpar->codec_type;
  331. switch (type) {
  332. case AVMEDIA_TYPE_AUDIO:
  333. if (ctx->disableType == AUDIO) {
  334. av_packet_free(&pkg);
  335. continue;
  336. }
  337. break;
  338. case AVMEDIA_TYPE_VIDEO:
  339. if (ctx->disableType == VIDEO) {
  340. av_packet_free(&pkg);
  341. continue;
  342. }
  343. break;
  344. default:
  345. break;
  346. }
  347. //对 pts ,dts 校准,因为有偏移
  348. if (pkg->dts != AV_NOPTS_VALUE && ctx->avformatContext->start_time > 0)
  349. pkg->dts += av_rescale_q(-ctx->avformatContext->start_time, AV_TIME_BASE_Q,
  350. ctx->avformatContext->streams[pkg->stream_index]->time_base);
  351. if (pkg->pts != AV_NOPTS_VALUE && ctx->avformatContext->start_time > 0)
  352. pkg->pts += av_rescale_q(-ctx->avformatContext->start_time, AV_TIME_BASE_Q,
  353. ctx->avformatContext->streams[pkg->stream_index]->time_base);
  354. if (ctx->force_Iframe && pkg->flags != AV_PKT_FLAG_KEY &&
  355. ctx->avformatContext->streams[pkg->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
  356. av_packet_free(&pkg);
  357. continue;
  358. } else {
  359. ret = av_decode(ctx, pkg, type);
  360. if (ret == -4) {
  361. break;
  362. }
  363. }
  364. av_packet_free(&pkg);
  365. }
  366. }
  367. }
  368. ctx->audio_queue->PushBack(NULL);
  369. ctx->video_queue->PushBack(NULL);
  370. }
  371. pthread_exit(NULL);
  372. }