Advertisement
Guest User

Untitled

a guest
Oct 12th, 2024
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.29 KB | None | 0 0
  1. extern "C" {
  2. #include <libavformat/avformat.h>
  3. #include <libswscale/swscale.h>
  4. #include <libavutil/imgutils.h>
  5. }
  6.  
  7. int error;
  8.  
  9. AVFormatContext* inputFormatContext = NULL;
  10. AVFormatContext* outputFormatContext = NULL;
  11.  
  12. AVCodecContext* encoderContext;
  13. AVCodecContext* decoderContext;
  14.  
  15. SwsContext *swsCtx = nullptr;
  16.  
  17. AVCodec* decoderCodec;
  18.  
  19. AVPacket* decodePacket;
  20. AVPacket* encodePacket;
  21.  
  22. AVFrame* inputFrame;
  23. AVFrame* outputFrame;
  24.  
  25. int main(int argc, char **argv) {
  26.  
  27. if (argc < 3) {
  28. puts("2 arguments are required, input file and output file.");
  29. return 0;
  30. }
  31.  
  32. //av_log_set_level(AV_LOG_ERROR);
  33.  
  34. char* inputFile = argv[1];
  35. char* outputFile = argv[2];
  36.  
  37. error = avformat_open_input(&inputFormatContext, inputFile, NULL, NULL);
  38.  
  39. if (error) {
  40. return 1;
  41. }
  42.  
  43. error = avformat_find_stream_info(inputFormatContext, NULL);
  44.  
  45. if (error) {
  46. return 1;
  47. }
  48.  
  49. int streamIndex = av_find_best_stream(inputFormatContext, AVMEDIA_TYPE_VIDEO,
  50. -1, -1, nullptr, 0);
  51.  
  52. if (streamIndex < 0) {
  53. error = AVERROR_UNKNOWN;
  54. return 1;
  55. }
  56.  
  57. AVStream* stream = inputFormatContext->streams[streamIndex];
  58.  
  59. AVCodecParameters* codecParameters = stream->codecpar;
  60.  
  61. if (!codecParameters->codec_id) {
  62. error = AVERROR_UNKNOWN;
  63. return 1;
  64. }
  65.  
  66. //Opening input
  67. decoderCodec = avcodec_find_decoder(codecParameters->codec_id);
  68.  
  69. decoderContext = avcodec_alloc_context3(decoderCodec);
  70. if (!decoderContext) {
  71. error = AVERROR_UNKNOWN;
  72. return 1;
  73. }
  74.  
  75. error = avcodec_parameters_to_context(decoderContext, codecParameters);
  76.  
  77. if (error) {
  78. return 1;
  79. }
  80.  
  81. decoderContext->thread_count = 0;
  82. error = avcodec_open2(decoderContext, decoderCodec, nullptr);
  83.  
  84. if (error) {
  85. return 1;
  86. }
  87. //Opened input
  88.  
  89. //init frames
  90.  
  91. inputFrame = av_frame_alloc();
  92.  
  93. if (!inputFrame) {
  94. error = AVERROR_UNKNOWN;
  95. return 1;
  96. }
  97.  
  98. outputFrame = av_frame_alloc();
  99.  
  100. if (!outputFrame) {
  101. error = AVERROR_UNKNOWN;
  102. return 1;
  103. }
  104.  
  105. decodePacket = av_packet_alloc();
  106.  
  107. if (!decodePacket) {
  108. error = AVERROR_UNKNOWN;
  109. return 1;
  110. }
  111.  
  112. encodePacket = av_packet_alloc();
  113.  
  114. if (!encodePacket) {
  115. error = AVERROR_UNKNOWN;
  116. return 1;
  117. }
  118.  
  119. avformat_alloc_output_context2(&outputFormatContext, NULL, NULL, outputFile);
  120.  
  121. outputFormatContext->video_codec_id = av_guess_codec(
  122. outputFormatContext->oformat, NULL, outputFile, NULL, AVMEDIA_TYPE_VIDEO);
  123.  
  124. outputFormatContext->video_codec = avcodec_find_encoder(
  125. outputFormatContext->video_codec_id);
  126.  
  127. if (!outputFormatContext->video_codec) {
  128. error = AVERROR_UNKNOWN;
  129. return 1;
  130. }
  131.  
  132. encoderContext = avcodec_alloc_context3(outputFormatContext->video_codec);
  133.  
  134. if (!encoderContext) {
  135. error = AVERROR_UNKNOWN;
  136. return 1;
  137. }
  138.  
  139. encoderContext->width = 100;
  140. encoderContext->height = 100;
  141.  
  142. encoderContext->pix_fmt = avcodec_find_best_pix_fmt_of_list(
  143. outputFormatContext->video_codec->pix_fmts, decoderContext->pix_fmt, true,
  144. NULL);
  145.  
  146. if (stream->avg_frame_rate.den) {
  147. encoderContext->time_base = av_make_q(1,
  148. (stream->avg_frame_rate.num + (stream->avg_frame_rate.den / 2))
  149. / stream->avg_frame_rate.den);
  150. } else {
  151. encoderContext->time_base = av_make_q(1, 1);
  152. }
  153.  
  154. error = avcodec_open2(encoderContext, outputFormatContext->video_codec,
  155. nullptr);
  156.  
  157. if (error) {
  158. return 1;
  159. }
  160. //init encoder
  161.  
  162. swsCtx = sws_getContext(decoderContext->width, decoderContext->height,
  163. decoderContext->pix_fmt, encoderContext->width, encoderContext->height,
  164. encoderContext->pix_fmt, 0, nullptr, nullptr, nullptr);
  165.  
  166. if (!swsCtx) {
  167. error = AVERROR_UNKNOWN;
  168. return 1;
  169. }
  170.  
  171. outputFrame->format = encoderContext->pix_fmt;
  172. outputFrame->width = encoderContext->width;
  173. outputFrame->height = encoderContext->height;
  174.  
  175. //error = av_frame_get_buffer(outputFrame, 0);
  176. error = av_image_alloc(outputFrame->data, outputFrame->linesize,
  177. encoderContext->width, encoderContext->height, encoderContext->pix_fmt,
  178. 32);
  179.  
  180. if (error < 0) {
  181. return 1;
  182. }
  183.  
  184. AVStream* out_stream = avformat_new_stream(outputFormatContext, NULL);
  185.  
  186. error = avcodec_parameters_from_context(out_stream->codecpar, decoderContext);
  187.  
  188. if (error) {
  189. return 1;
  190. }
  191.  
  192. if (!(outputFormatContext->oformat->flags & AVFMT_NOFILE)) {
  193. error = avio_open(&outputFormatContext->pb, outputFile, AVIO_FLAG_WRITE);
  194. if (error < 0) {
  195. return 1;
  196. }
  197. }
  198.  
  199. AVDictionary *opts;
  200.  
  201. av_dict_set(&opts, "loop", "0", 0);
  202.  
  203. error = avformat_write_header(outputFormatContext, &opts);
  204.  
  205. if (error) {
  206. return 1;
  207. }
  208.  
  209. while (true) {
  210.  
  211. // av_frame_unref(inputFrame);
  212. //av_packet_unref(decodePacket);
  213.  
  214. //probably ended frames
  215. if (av_read_frame(inputFormatContext, decodePacket) < 0) {
  216. error = 0;
  217. break;
  218. }
  219.  
  220. //different stream. ignore.
  221. if (decodePacket->stream_index != streamIndex) {
  222. continue;
  223. }
  224.  
  225. //send packet
  226. error = avcodec_send_packet(decoderContext, decodePacket);
  227.  
  228. if (error < 0) {
  229.  
  230. //get next one
  231. if (error == AVERROR(EAGAIN)) {
  232. continue;
  233. } else {
  234. return 1;
  235. }
  236. }
  237.  
  238. //send frame
  239. error = avcodec_receive_frame(decoderContext, inputFrame);
  240.  
  241. if (error < 0) {
  242.  
  243. //get next one
  244. if (error == AVERROR(EAGAIN)) {
  245. continue;
  246. } else {
  247. return 1;
  248. }
  249. }
  250.  
  251. if (!sws_scale(swsCtx, inputFrame->data, inputFrame->linesize, 0,
  252. inputFrame->height, outputFrame->data, outputFrame->linesize)) {
  253. return 1;
  254. }
  255.  
  256. error = avcodec_send_frame(encoderContext, outputFrame);
  257.  
  258. if (error) {
  259. return 1;
  260. }
  261.  
  262. error = avcodec_receive_packet(encoderContext, encodePacket);
  263.  
  264. if (error) {
  265. return 1;
  266. }
  267.  
  268. encodePacket->pts = av_rescale_q_rnd(decodePacket->pts, stream->time_base,
  269. out_stream->time_base,
  270. static_cast<AVRounding>(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
  271. encodePacket->dts = av_rescale_q_rnd(decodePacket->dts, stream->time_base,
  272. out_stream->time_base,
  273. static_cast<AVRounding>(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
  274. encodePacket->duration = av_rescale_q(decodePacket->duration,
  275. stream->time_base, out_stream->time_base);
  276. encodePacket->pos = -1;
  277.  
  278. error = av_interleaved_write_frame(outputFormatContext, encodePacket);
  279.  
  280. if (error < 0) {
  281. return 1;
  282. }
  283.  
  284. }
  285.  
  286. error = av_write_trailer(outputFormatContext);
  287.  
  288. if (error) {
  289. return 1;
  290. }
  291.  
  292. puts("Finished conversion.");
  293.  
  294. if (!(outputFormatContext->oformat->flags & AVFMT_NOFILE)) {
  295. avio_closep(&outputFormatContext->pb);
  296. }
  297.  
  298. av_packet_unref(encodePacket);
  299. av_packet_unref(decodePacket);
  300.  
  301. avcodec_send_packet(decoderContext, nullptr);
  302. avcodec_send_packet(encoderContext, nullptr);
  303.  
  304. av_freep(&outputFrame->data);
  305.  
  306. av_frame_free(&inputFrame);
  307. av_frame_free(&outputFrame);
  308.  
  309. sws_freeContext(swsCtx);
  310.  
  311. av_packet_free(&encodePacket);
  312. av_packet_free(&decodePacket);
  313.  
  314. avcodec_free_context(&encoderContext);
  315. avcodec_free_context(&decoderContext);
  316.  
  317. avformat_close_input(&inputFormatContext);
  318. avformat_free_context(outputFormatContext);
  319.  
  320. return 0;
  321. }
  322.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement