Advertisement
Guest User

Untitled

a guest
Oct 6th, 2011
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.36 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include <libavformat/avformat.h>
  4. #include <libavcodec/avcodec.h>
  5.  
  6. int main(int argc, char *argv[]) {
  7. int i;
  8. int r;
  9. int video_s_ind = -1, audio_s_ind = -1;
  10. AVFormatContext *avInputFmtCtx = NULL;
  11. AVFormatContext *avOutputFmtCtx = NULL;
  12. AVCodec *avInputVideoDecoder = NULL;
  13. AVCodec *avOutputVideoEncoder = NULL;
  14. AVCodecContext *avInputVideoDecoderCtx = NULL;
  15. AVCodecContext *avOutputVideoEncoderCtx = NULL;
  16.  
  17. if (argc < 3) {
  18. fprintf(stderr, "Usage: %s <http stream URL> <output file>\n", argv[0]);
  19. return 1;
  20. }
  21.  
  22. av_register_all();
  23. av_log_set_level(AV_LOG_DEBUG);
  24.  
  25. r = avformat_open_input(&avInputFmtCtx, argv[1], NULL, NULL);
  26. assert(r == 0);
  27.  
  28. avInputFmtCtx->max_analyze_duration = 10 * 1000 * 1000;
  29. r = avformat_find_stream_info(avInputFmtCtx, NULL);
  30. assert(r >= 0);
  31.  
  32. av_dump_format(avInputFmtCtx, 0, argv[1], 0);
  33.  
  34. avOutputFmtCtx = avformat_alloc_context();
  35. assert(avOutputFmtCtx);
  36.  
  37. avOutputFmtCtx->oformat = av_guess_format("mpegts", NULL, NULL);
  38. assert(avOutputFmtCtx->oformat);
  39.  
  40. for (i = 0; i < avInputFmtCtx->nb_streams; i++) {
  41. AVStream *inputStream;
  42. AVStream *newStream;
  43. inputStream = avInputFmtCtx->streams[i];
  44. newStream = av_new_stream(avOutputFmtCtx, inputStream->id);
  45. assert(newStream);
  46. newStream->sample_aspect_ratio = (AVRational){1, 1};
  47.  
  48. newStream->codec->codec_type = inputStream->codec->codec_type;
  49. avcodec_get_context_defaults2(newStream->codec, newStream->codec->codec_type);
  50. newStream->codec->codec_id = inputStream->codec->codec_id;
  51. newStream->codec->codec_tag = 0;
  52. newStream->codec->bit_rate = inputStream->codec->bit_rate;
  53. newStream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
  54. newStream->codec->time_base = inputStream->codec->time_base;
  55. newStream->time_base = inputStream->time_base;
  56.  
  57. /* copy extradata if exists */
  58. newStream->codec->extradata_size = inputStream->codec->extradata_size;
  59. if (inputStream->codec->extradata_size > 0) {
  60. newStream->codec->extradata = av_mallocz(inputStream->codec->extradata_size);
  61. if (!newStream->codec->extradata) {
  62. printf("failed to alloc space for extradata\n");
  63. assert(0);
  64. }
  65. memcpy(newStream->codec->extradata, inputStream->codec->extradata,
  66. inputStream->codec->extradata_size);
  67. }
  68.  
  69. switch (inputStream->codec->codec_type) {
  70. case AVMEDIA_TYPE_VIDEO:
  71. video_s_ind = i;
  72. newStream->codec->width = inputStream->codec->width;
  73. newStream->codec->height = inputStream->codec->height;
  74.  
  75. printf("input frame rate = %f\n", av_q2d(inputStream->r_frame_rate));
  76. newStream->r_frame_rate = inputStream->r_frame_rate;
  77. newStream->avg_frame_rate = inputStream->avg_frame_rate;
  78. break;
  79.  
  80. case AVMEDIA_TYPE_AUDIO:
  81. audio_s_ind = i;
  82. newStream->codec->channels = inputStream->codec->channels;
  83. newStream->codec->sample_rate =
  84. inputStream->codec->sample_rate;
  85. newStream->codec->frame_size =
  86. inputStream->codec->frame_size;
  87. newStream->codec->block_align =
  88. inputStream->codec->block_align;
  89. break;
  90. default:
  91. printf("stream of unknown type %d\n", inputStream->codec->codec_type);
  92. assert(0);
  93. }
  94. }
  95. if (audio_s_ind == -1) {
  96. printf("Audio stream absent, fail\n");
  97. assert(0);
  98. }
  99. if (video_s_ind == -1) {
  100. printf("Video stream absent, fail\n");
  101. assert(0);
  102. }
  103.  
  104. avInputVideoDecoder = avcodec_find_decoder(avInputFmtCtx->streams[video_s_ind]->codec->codec_id);
  105. assert(avInputVideoDecoder);
  106. avInputVideoDecoderCtx = avInputFmtCtx->streams[video_s_ind]->codec;
  107. r = avcodec_open2(avInputVideoDecoderCtx, avInputVideoDecoder, NULL);
  108. assert(r == 0);
  109.  
  110. avOutputVideoEncoder = avcodec_find_encoder(avOutputFmtCtx->streams[video_s_ind]->codec->codec_id);
  111. assert(avOutputVideoEncoder);
  112. avOutputVideoEncoderCtx = avOutputFmtCtx->streams[video_s_ind]->codec;
  113. r = avcodec_copy_context(avOutputVideoEncoderCtx, avInputVideoDecoderCtx);
  114. assert(r == 0);
  115.  
  116. avOutputVideoEncoderCtx->qmin = -1;
  117. avOutputVideoEncoderCtx->qmax = -1;
  118.  
  119. r = avcodec_open2(avOutputVideoEncoderCtx, avOutputVideoEncoder, NULL);
  120. assert(r == 0);
  121.  
  122. r = avio_open(&avOutputFmtCtx->pb, argv[2], AVIO_FLAG_WRITE);
  123. assert(r == 0);
  124. if (!avOutputFmtCtx->pb) {
  125. printf("av_alloc_put_byte failed\n");
  126. assert(0);
  127. }
  128.  
  129. av_dump_format(avOutputFmtCtx, 0, avOutputFmtCtx->filename, 1);
  130.  
  131. r = avformat_write_header(avOutputFmtCtx, NULL);
  132. if (r) {
  133. printf("Could not write header for output file");
  134. assert(0);
  135. }
  136.  
  137. int64_t start_pts = 0;
  138.  
  139. for (i = 0; i < 1000; i++) {
  140. AVPacket pkt;
  141. r = av_read_frame(avInputFmtCtx, &pkt);
  142. assert(r == 0);
  143.  
  144. if (start_pts == 0) {
  145. start_pts = pkt.pts;
  146. }
  147. pkt.pts -= start_pts - 2 * 90000; /* add 2 secs to avoid negative pts in another AVStream */
  148. pkt.dts = pkt.pts;
  149.  
  150. if (pkt.stream_index == video_s_ind) {
  151. AVFrame *frame;
  152. int got_picture_ptr;
  153. uint8_t video_outbuf[1024 * 1024];
  154. int video_outbuf_size = sizeof(video_outbuf);
  155.  
  156. frame = avcodec_alloc_frame();
  157.  
  158. r = avcodec_decode_video2(avInputVideoDecoderCtx, frame, &got_picture_ptr, &pkt);
  159. assert(r >= 0);
  160.  
  161. frame->pts = pkt.pts;
  162. r = avpicture_alloc((AVPicture*)frame,
  163. avOutputVideoEncoderCtx->pix_fmt,
  164. avOutputVideoEncoderCtx->width,
  165. avOutputVideoEncoderCtx->height);
  166. assert(r == 0);
  167.  
  168. r = avcodec_encode_video(avOutputVideoEncoderCtx, video_outbuf, video_outbuf_size, frame);
  169. assert(r >= 0);
  170. if (r > 0) {
  171. video_outbuf_size = r;
  172. AVPacket x_pkt; // transcoded packet
  173. av_init_packet(&x_pkt);
  174. x_pkt.stream_index = video_s_ind;
  175. x_pkt.pts = avOutputVideoEncoderCtx->coded_frame->pts;
  176. x_pkt.dts = x_pkt.pts;
  177. x_pkt.data = video_outbuf;
  178. x_pkt.size = video_outbuf_size;
  179. if(avOutputVideoEncoderCtx->coded_frame->key_frame)
  180. x_pkt.flags |= AV_PKT_FLAG_KEY;
  181. printf("writing transcoded video frame with pts %"PRId64", size %d\n",
  182. x_pkt.pts, video_outbuf_size);
  183. r = av_interleaved_write_frame(avOutputFmtCtx, &x_pkt);
  184. assert(r == 0);
  185. }
  186. av_free(frame);
  187. } else {
  188. printf("writing audio frame with pts %"PRId64"\n",
  189. pkt.pts);
  190. r = av_interleaved_write_frame(avOutputFmtCtx, &pkt);
  191. assert(r == 0);
  192. }
  193. }
  194.  
  195. r = av_write_trailer(avOutputFmtCtx);
  196.  
  197. // TODO close contexts
  198. return 0;
  199. }
  200.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement