Advertisement
Guest User

Untitled

a guest
Dec 23rd, 2015
385
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.75 KB | None | 0 0
  1. bool VideoDecoder::decodeFrame(int width, int height, int maxTextureSize, const boost::shared_ptr<CodedFrame>& frame) {
  2.     if (!width || !height) {
  3.         //LOGDEBUG("zero width or height for decoding %s frame", getDecoderStream()->streamDescription());
  4.         return false;
  5.     }
  6.     AVFormatContext* formatContext = avformat_alloc_context();
  7.     const double current_time = now_ms();
  8.     boost::mutex::scoped_lock frame_lock(frame_guard);
  9.     if (needDecoding() && pFrame == NULL) {
  10.         //LOGDEBUG("New decoding %s", getDecoderStream()->streamDescription());
  11.         if (MPEG4_CODEC == frame->codec_type)
  12.             codec = avcodec_find_decoder(AV_CODEC_ID_MPEG4);
  13.         else if (H264_CODEC == frame->codec_type)
  14.             codec = avcodec_find_decoder(AV_CODEC_ID_H264);
  15.         else if (MJPEG_CODEC == frame->codec_type)
  16.             codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
  17.         if (codec == NULL) {
  18.             LOGDEBUG("Codec was not found. Codec = %d", frame->codec_type);
  19.             return false;
  20.         }
  21.         //LOGDEBUG("Finish avcodec_find_decoder");
  22.         codec_context = avcodec_alloc_context3(codec);
  23.         if (codec_context == NULL) {
  24.             LOGDEBUG("avcodec_alloc_context fault");
  25.             return false;
  26.         }
  27.         codec_context->flags2 |= CODEC_FLAG2_CHUNKS;
  28.         //LOGDEBUG("Finish avcodec_alloc_context3");
  29.         if (codec->capabilities & CODEC_CAP_TRUNCATED) {
  30.             codec_context->flags |= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
  31.             LOGDEBUG("CODEC_FLAG_TRUNCATED");
  32.         }
  33.  
  34.         int r = avcodec_open2(codec_context, codec, 0);
  35.         if (r < 0) {
  36.             LOGDEBUG("Codec was not open");
  37.             if (codec_context != NULL) {
  38.                 if (avcodec_is_open(codec_context)) {
  39.                     avcodec_close(codec_context);
  40.                 }
  41.                 av_free(codec_context);
  42.             }
  43.             codec_context = NULL;
  44.             decoded_frame_number = 0;
  45.             return false;
  46.         }
  47.         LOGDEBUG("Finish avcodec_open2");
  48.         pFrame = avcodec_alloc_frame();
  49.     }
  50.     if (!frame) {
  51.         LOGDEBUG("Coded frame is null");
  52.         return false;
  53.     }
  54.     AVPacket packet;
  55.     av_init_packet(&packet);
  56.     packet.data = (uint8_t*) frame->data;
  57.     packet.size = frame->size;
  58.     int decode_count = 0;
  59.     bool pushed = false;
  60. //  while(av_read_frame(formatContext, &packet) >= 0) {
  61.         //decode_ret = avcodec_decode_video2(codec_context, pFrame, &got_picture, &packet);
  62.     //}
  63.     LOGDEBUG("Frame len: %d", packet.size);
  64.     while (packet.size > 0) {
  65.         decode_count++;
  66.         int got_picture;
  67.         int decode_ret = 0;
  68. //      LOGDEBUG("Decoding [%d] (%d/%d, %d/%d) %d", getDecoderId(), codec_context->width, width, codec_context->height, height, packet.size);
  69.  
  70.         try {
  71.             decode_ret = avcodec_decode_video2(codec_context, pFrame, &got_picture, &packet);
  72.             LOGDEBUG("Decoding frame size decode_ret: %d, got_picture: %d, width: %d, height: %d", decode_ret, got_picture, codec_context->width, codec_context->height);
  73.             decoded_frame_number = frame->index;
  74.             if (decode_ret < 0) {
  75.                 LOGDEBUG("Decoding error %d", decode_ret);
  76.                 return false;
  77.             }
  78.         } catch (...) {
  79.             LOGDEBUG("Error decoding");
  80.             return false;
  81.         }
  82.         if (packet.data) {
  83.             packet.size -= decode_ret;
  84.             packet.data += decode_ret;
  85.         }
  86.         if (!got_picture) {
  87.             LOGDEBUG("Waiting for full picture");
  88.             std::string packet_flags = "";
  89.             if (packet.flags & AV_PKT_FLAG_KEY) {
  90.                 packet_flags += "AV_PKT_FLAG_KEY";
  91.             }
  92.             if (packet.flags & AV_PKT_FLAG_CORRUPT) {
  93.                 packet_flags += " | AV_PKT_FLAG_CORRUPT";
  94.             }
  95. //          LOGDEBUG("Decoding %d frame[%ld] not complete (%d, %d) flags %s packetsize %d/%d keyframe %d for %d",
  96. //                  decode_ret, frame->index, codec_context->width,
  97. //                  codec_context->height, packet_flags.c_str(), packet.size, frame->size,
  98. //                  pFrame->key_frame, decode_count);
  99.             continue;
  100.         }
  101.  
  102.         {
  103.             const bool is_frame_size_changed = (coded_frame_w && coded_frame_h) && (coded_frame_w != codec_context->width || coded_frame_h != codec_context->height);
  104.             if (is_frame_size_changed) {
  105.                 LOGDEBUG("Detect frame size changed and ignore one frame.\n"
  106.                      "Old frame(%d,%d) was ignore by new frame(%d, %d)", coded_frame_w, coded_frame_h, codec_context->width, codec_context->height);
  107.             }
  108.             coded_frame_w = codec_context->width;
  109.             coded_frame_h = codec_context->height;
  110.  
  111.             if (is_frame_size_changed) {
  112.                 if (img_preview_ctx != NULL)
  113.                     sws_freeContext(img_preview_ctx);
  114.                 img_preview_ctx = NULL;
  115.                 if (pFramePreview != NULL)
  116.                     av_free(pFramePreview);
  117.                 pFramePreview = NULL;
  118.                 //break;
  119.  
  120.             }
  121.  
  122.             if (!pFrame->linesize[0]) {
  123.                 LOGDEBUG("Decoding linesize 0");
  124.                 return false;
  125.             }
  126.  
  127.             bool need_fix2cif = false;
  128.             if ((codec_context->width == 704 && codec_context->height == 288)
  129.                     || (codec_context->width == 720
  130.                             && codec_context->height == 288)
  131.                     || (codec_context->width == 640
  132.                             && codec_context->height == 240)) {
  133.                 need_fix2cif = true;
  134.             }
  135.  
  136.             if (pFrame->linesize[0] > maxTextureSize || need_fix2cif) {
  137.                 float ratio = (float) codec_context->width / (float) codec_context->height;
  138.                 height = width / ratio;
  139.                 if (need_fix2cif) {
  140.                     height *= 2;
  141.                 }
  142.                 if (img_resize_ctx == NULL) {
  143.                     LOGDEBUG("Resize frame(%d, %d) to screen(%d, %d)",
  144.                             codec_context->width, codec_context->height,
  145.                             width, height);
  146.                     img_resize_ctx = sws_getContext(codec_context->width,
  147.                             codec_context->height, codec_context->pix_fmt,
  148.                             width, height, codec_context->pix_fmt,
  149.                             SWS_FAST_BILINEAR, NULL, NULL, NULL);
  150.  
  151.                     if (img_resize_ctx == NULL) {
  152.                         LOGDEBUG(
  153.                                 "could not initialize conversion context");
  154.                         return false;
  155.                     }
  156.                     pFrameResized = avcodec_alloc_frame();
  157.                     //int numBytes = avpicture_get_size(codec_context->pix_fmt, width, height);
  158.                     //LOGDEBUG("av_malloc[%d] %d", getDecoderId(), numBytes);
  159.                     //uint8_t *buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
  160.                     //avpicture_fill((AVPicture *)pFrameResized, buffer, codec_context->pix_fmt,
  161.                     //      width, height);
  162.                     avpicture_alloc((AVPicture *) pFrameResized, codec_context->pix_fmt, width, height);
  163.                 }
  164.                 int scale_ret = sws_scale(img_resize_ctx, pFrame->data,
  165.                         pFrame->linesize, 0, codec_context->height,
  166.                         pFrameResized->data, pFrameResized->linesize);
  167. //              LOGDEBUG("Scale ret = %d linesize %d", scale_ret, pFrameResized->linesize[0]);
  168.                 pushDecodedFrame(pFrameResized, width, height, frame->index);
  169.                 pushed = true;
  170.             } else {
  171. //              LOGDEBUG("Without scale %d", frame->index);
  172.                 pushDecodedFrame(pFrame, codec_context->width,
  173.                         codec_context->height, frame->index);
  174.                 pushed = true;
  175.             }
  176.         }
  177.     }
  178.  
  179. //  if (!pushed) {
  180. //      pushDecodedFrame(pFrame, codec_context->width,
  181. //                       codec_context->height, frame->index);
  182. //  }
  183.  
  184.     LOGDEBUG("Decoding frame out");
  185.     calculateFps(current_time);
  186.     decoding_per_sec_time += long(now_ms() - current_time);
  187.     decoding_per_sec_counter++;
  188.     decode_frame_counter++;
  189.     return true;
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement